From d7e948ea32e8503c0b8fb6e86912c6dfdb66c4ff Mon Sep 17 00:00:00 2001 From: DHDAXCW Date: Sat, 29 Jun 2024 14:15:52 +0800 Subject: [PATCH] sync --- config/Config-build.in | 15 + config/Config-images.in | 2 +- config/Config-kernel.in | 17 +- include/kernel-5.10 | 4 +- include/kernel-5.15 | 4 +- include/kernel-5.4 | 4 +- include/package.mk | 49 +- include/target.mk | 2 +- include/u-boot.mk | 35 +- .../arm-trusted-firmware-mediatek/Makefile | 33 +- ...01-mediatek-snfi-FM35Q1GA-is-x4-only.patch | 23 + ...just-pin-drive-strength-for-Fidelix-.patch | 99 + ...just-drive-strength-to-12mA-like-old.patch | 135 + .../boot/arm-trusted-firmware-tools/Makefile | 4 +- package/boot/uboot-amlogic/Makefile | 57 + package/boot/uboot-envtools/files/ramips | 10 +- ...support-for-MediaTek-SPI-NAND-flash-.patch | 2 +- package/boot/uboot-sunxi/Makefile | 10 + package/devel/tmon/Makefile | 106 +- package/firmware/ath11k-firmware/Makefile | 24 +- package/firmware/ath11k-wifi/Makefile | 94 - .../firmware/ath11k-wifi/board-2.bin.IPQ6018 | Bin 787208 -> 0 bytes .../board-edgecore-eap102.bin.IPQ8074 | Bin 131072 -> 0 bytes .../ath11k-wifi/board-gl-ax1800.bin.IPQ6018 | Bin 787208 -> 0 bytes .../ath11k-wifi/board-gl-axt1800.bin.IPQ6018 | Bin 787208 -> 0 bytes .../ath11k-wifi/qdss_trace_config.bin | 99 - package/firmware/b43legacy-firmware/Makefile | 72 - package/firmware/cypress-firmware/Makefile | 285 +- package/firmware/cypress-nvram/Makefile | 96 +- .../files/brcmfmac4339-sdio.AP6335.txt | 99 + package/firmware/ipq-wifi/Makefile | 56 +- .../ipq-wifi/board-8dev_habanero-dvk.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-aruba_ap-303.qca4019 | Bin 24316 -> 0 bytes .../ipq-wifi/board-asus_rt-acrh17.qca4019 | Bin 12164 -> 0 bytes .../board-avm_fritzrepeater-1200.qca4019 | Bin 24332 -> 0 bytes .../board-buffalo_wtr-m2133hp.qca4019 | Bin 24332 -> 0 bytes .../board-buffalo_wtr-m2133hp.qca9984 | Bin 12172 -> 0 bytes .../ipq-wifi/board-cellc_rtl30vw.qca4019 | Bin 24316 -> 0 bytes .../ipq-wifi/board-century_wr142ac.qca4019 | Bin 24308 -> 0 bytes .../board-devolo_magic-2-wifi-next.qca4019 | Bin 24340 -> 0 bytes .../ipq-wifi/board-dlink_dap2610.qca4019 | Bin 24316 -> 0 bytes .../ipq-wifi/board-edgecore_ecw5410.qca9984 | Bin 24324 -> 0 bytes .../ipq-wifi/board-edgecore_oap100.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-engenius_eap2200.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-engenius_eap2200.qca9888 | Bin 12172 -> 0 bytes .../ipq-wifi/board-engenius_emd1.qca4019 | Bin 24316 -> 0 bytes .../ipq-wifi/board-engenius_emr3500.qca4019 | Bin 24324 -> 0 bytes .../board-ezviz_cs-w3-wd1200g-eup.qca4019 | Bin 24340 -> 0 bytes .../ipq-wifi/board-glinet_gl-a1300.qca4019 | Bin 24308 -> 0 bytes .../ipq-wifi/board-glinet_gl-ap1300.qca4019 | Bin 48596 -> 0 bytes .../ipq-wifi/board-glinet_gl-s1300.qca4019 | Bin 24276 -> 0 bytes .../ipq-wifi/board-hiwifi_c526a.qca4019 | Bin 24300 -> 0 bytes .../ipq-wifi/board-linksys_ea8300.qca4019 | Bin 97236 -> 0 bytes .../ipq-wifi/board-linksys_ea8300.qca9888 | Bin 48628 -> 0 bytes .../ipq-wifi/board-linksys_mr8300-v0.qca4019 | Bin 97268 -> 0 bytes .../ipq-wifi/board-linksys_mr8300-v0.qca9888 | Bin 48644 -> 0 bytes .../ipq-wifi/board-luma_wrtq-329acn.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-mikrotik_hap-ac2.qca4019 | Bin 24324 -> 0 bytes .../board-mikrotik_sxtsq-5-ac.qca4019 | Bin 12176 -> 0 bytes .../board-mobipromo_cm520-79f.qca4019 | Bin 24308 -> 0 bytes .../ipq-wifi/board-nec_wg2600hp3.qca9984 | Bin 24332 -> 0 bytes .../ipq-wifi/board-netgear_sxr80.ipq8074 | Bin 131176 -> 0 bytes .../ipq-wifi/board-p2w_r619ac.qca4019 | Bin 24300 -> 0 bytes .../ipq-wifi/board-plasmacloud_pa1200.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-plasmacloud_pa2200.qca4019 | Bin 24324 -> 0 bytes .../ipq-wifi/board-plasmacloud_pa2200.qca9888 | Bin 12172 -> 0 bytes .../firmware/ipq-wifi/board-qnap_301w.ipq8074 | Bin 131172 -> 0 bytes .../ipq-wifi/board-qxwlan_e2600ac.qca4019 | Bin 36464 -> 0 bytes .../firmware/ipq-wifi/board-redmi_ax6.ipq8074 | Bin 131172 -> 0 bytes .../ipq-wifi/board-tplink_xtr10890.ipq8074 | Bin 131176 -> 0 bytes .../ipq-wifi/board-xiaomi_ax3600.ipq8074 | Bin 131176 -> 0 bytes .../ipq-wifi/board-xiaomi_ax3600.qca9889 | Bin 2260 -> 0 bytes .../ipq-wifi/board-xiaomi_ax9000.ipq8074 | Bin 131176 -> 0 bytes .../firmware/ipq-wifi/board-zte_mf263.qca4019 | Bin 24308 -> 0 bytes .../firmware/ipq-wifi/board-zte_mf269.ipq8074 | Bin 131172 -> 0 bytes .../src/board-jdcloud_ax1800pro.ipq6018 | Bin 0 -> 65644 bytes .../ipq-wifi/src/board-jdcloud_ax6600.ipq6018 | Bin 0 -> 65644 bytes .../ipq-wifi/src/board-qihoo_360v6.ipq6018 | Bin 0 -> 65620 bytes .../src/board-redmi_ax5-jdcloud.ipq6018 | Bin 0 -> 65644 bytes .../ipq-wifi/src/board-xiaomi_rm1800.ipq6018 | Bin 0 -> 65620 bytes .../src/board-zn_m2.ipq6018} | Bin 787208 -> 787208 bytes package/firmware/linux-firmware/Makefile | 4 +- package/firmware/linux-firmware/airoha.mk | 8 + .../ap6236/brcmfmac43430-sdio.bin | Bin .../ap6236/brcmfmac43430-sdio.txt | 0 .../brcmfmac4356-sdio.rongpin,king3399.bin | Bin 580258 -> 0 bytes .../brcmfmac4356-sdio.rongpin,king3399.txt | 125 - package/firmware/linux-firmware/broadcom.mk | 158 +- package/firmware/linux-firmware/intel.mk | 15 + package/firmware/linux-firmware/marvell.mk | 3 +- package/firmware/linux-firmware/mellanox.mk | 9 + package/firmware/linux-firmware/realtek.mk | 8 +- package/firmware/photonicat-firmware/Makefile | 28 + .../photonicat-firmware/files/board.bin | Bin 0 -> 8124 bytes .../files/firmware-sdio-5.bin | Bin 0 -> 616352 bytes .../src/gpio-button-hotplug.c | 2 +- package/kernel/linux/modules/block.mk | 12 + package/kernel/linux/modules/video.mk | 1 + package/kernel/mac80211/Makefile | 8 +- package/kernel/mac80211/ath.mk | 58 +- package/kernel/mac80211/broadcom.mk | 7 +- .../files/lib/netifd/wireless/mac80211.sh | 95 +- .../mac80211/files/lib/wifi/mac80211.sh | 179 +- ...isable-caldata-prefetch-for-sdio-bus.patch | 12 + ...21-ath10k_init_devices_synchronously.patch | 5 +- ...rolling-support-for-various-chipsets.patch | 2 +- .../ath10k/985-ath10k-allow-vht-on-2g.patch | 10 + ...k-always-use-mac80211-loss-detection.patch | 28 + ...ix-memory-leak-in-WMI-firmware-stats.patch | 51 + ...ath11k-Add-missing-check-for-ioremap.patch | 38 + ...dd-missing-ops-config-for-IPQ5018-in.patch | 30 + ...firmware-after-cold-boot-calibration.patch | 47 + ...missing-hw_ops-get_ring_selector-for.patch | 58 + ...ert-wifi-ath11k-Enable-threaded-NAPI.patch | 44 + ...-Split-coldboot-calibration-hw_param.patch | 180 + ...coldboot-calibration-support-for-QCN.patch | 176 + ...k-Remove-cal_done-check-during-probe.patch | 33 + ...-add-a-warning-message-for-MHI_CB_EE.patch | 34 + ...chip-id-board-name-while-searching-b.patch | 214 + ...fix-boot-failure-with-one-MSI-vector.patch | 103 + ...i-ath11k-use-unique-QRTR-instance-ID.patch | 4 +- ...ci-fix-compilation-in-5.16-and-older.patch | 2 +- ...ble-coldboot-calibration-for-IPQ8074.patch | 8 +- ...upport-setting-FW-memory-mode-via-DT.patch | 7 +- ...ble-coldboot-calibration-for-IPQ6018.patch | 13 + .../ath9k/500-ath9k_eeprom_debugfs.patch | 7 +- .../ath9k/512-ath9k_channelbw_debugfs.patch | 4 +- .../patches/ath9k/530-ath9k_extra_leds.patch | 4 +- .../ath9k/542-ath9k_debugfs_diag.patch | 4 +- ...-register-wiphy-s-during-module_init.patch | 64 + ...d-alternative-firmware-names-from-DT.patch | 6 +- .../patches/build/050-lib80211_option.patch | 34 + .../patches/build/099-netlink-range.patch | 91 + .../build/990-add_kernel_6.6_support.patch | 113 + ...ace-condition-when-doing-H2C-command.patch | 73 - ...-enable-BT-device-recovery-mechanism.patch | 100 - ...-print-firmware-type-in-info-message.patch | 56 - ...rtw_fw_beacon_filter_config-with-rtw.patch | 30 - .../rtl/005-wifi-rtw88-Drop-rf_lock.patch | 132 - .../rtl/006-wifi-rtw88-Drop-h2c.lock.patch | 110 - .../rtl/007-wifi-rtw88-Drop-coex-mutex.patch | 81 - ...ate-over-vif-sta-list-non-atomically.patch | 204 - ...fi-rtw88-Add-common-USB-chip-support.patch | 1155 - ...-rtw88-Add-rtw8821cu-chipset-support.patch | 197 - ...-rtw88-Add-rtw8822bu-chipset-support.patch | 194 - ...-rtw88-Add-rtw8822cu-chipset-support.patch | 160 - ...-rtw88-Add-rtw8723du-chipset-support.patch | 187 - ...ackports-rtw88-21cu-22cu-22bu-8723du.patch | 70 - ...register-access-from-rtw_bf_assoc-ou.patch | 72 - ...tw_iterate_vifs-for-rtw_vif_watch_do.patch | 39 - ...on-atomic-sta-iterator-in-rtw_ra_mas.patch | 47 - ...se-enum-type-for-rtw_hw_queue_mappin.patch | 48 - ...hange-queue-datatype-to-enum-rtw_tx_.patch | 89 - ...enum-rtw_tx_queue_type-mapping-code-.patch | 140 - ...se-existing-macros-in-rtw_pwr_seq_pa.patch | 34 - ...dd-support-for-the-SDIO-HCI-in-rtw_p.patch | 29 - ...dd-SDIO-HCI-support-in-the-TX-page-t.patch | 40 - ...21c-Implement-RTL8821CS-SDIO-efuse-p.patch | 66 - ...22b-Implement-RTL8822BS-SDIO-efuse-p.patch | 69 - ...22c-Implement-RTL8822CS-SDIO-efuse-p.patch | 69 - ...eturn-the-original-error-from-rtw_pw.patch | 30 - ...eturn-the-original-error-from-rtw_ma.patch | 41 - ...w88-fix-memory-leak-in-rtw_usb_probe.patch | 29 - ...e-unused-rtw_pci_get_tx_desc-functio.patch | 36 - ...88-Remove-redundant-pci_clear_master.patch | 42 - ...-RTW_FLAG_POWERON-early-in-rtw_mac_p.patch | 60 - ...Add-HCI-implementation-for-SDIO-base.patch | 1719 -- ...upport-SDIO-specific-bits-in-the-pow.patch | 119 - ...Add-the-cpwm-rpwm-_addr-for-SDIO-bas.patch | 38 - ...Reserve-8-bytes-of-extra-TX-headroom.patch | 38 - ...upport-for-the-SDIO-based-RTL8822BS-.patch | 94 - ...upport-for-the-SDIO-based-RTL8822CS-.patch | 92 - ...upport-for-the-SDIO-based-RTL8821CS-.patch | 93 - ...add-bitmap-for-dynamic-port-settings.patch | 108 - ...fi-rtw88-add-port-switch-for-AP-mode.patch | 126 - ...88-8822c-extend-reserved-page-number.patch | 84 - ...ifi-rtw88-disallow-PS-during-AP-mode.patch | 73 - ...efine-reserved-page-flow-for-AP-mode.patch | 50 - ...8-prevent-scan-abort-with-other-VIFs.patch | 73 - ...e-station-mode-concurrent-scan-with-.patch | 154 - ...fi-rtw88-8822c-add-iface-combination.patch | 58 - ...ix-priority-queue-to-endpoint-mappin.patch | 140 - ...-rtw8821c-Fix-rfe_option-field-width.patch | 58 - ...kg_type-correctly-for-specific-rtw88.patch | 66 - ...rtw8821c_switch_rf_set-according-to-.patch | 73 - ...i-rtw88-Fix-memory-leak-in-rtw88_usb.patch | 56 - ...wifi-rtw88-Update-spelling-in-main.h.patch | 46 - ...ncorrect-error-codes-in-rtw_debugfs_.patch | 35 - ...ncorrect-error-codes-in-rtw_debugfs_.patch | 173 - ...k-on-error-path-in-rtw_ops_add_inter.patch | 31 - ...ork-to-update-rate-to-avoid-RCU-warn.patch | 132 - ...rtw88-correct-qsel_to_ep-type-as-int.patch | 35 - ...Always-use-two-consecutive-bytes-for.patch | 60 - ...Check-the-HISR-RX_REQUEST-bit-in-rtw.patch | 84 - ...23d-Implement-RTL8723DS-SDIO-efuse-p.patch | 66 - ...upport-for-the-SDIO-based-RTL8723DS-.patch | 96 - ...b-silence-log-flooding-error-message.patch | 41 - ...ct-PS-calculation-for-SUPPORTS_DYNAM.patch | 145 - ...issing-unwind-goto-for-__rtw_downloa.patch | 41 - ...ction-frame-transmission-fail-before.patch | 40 - ...ss-VO-packets-without-workqueue-to-a.patch | 85 - ...truct-instead-of-macros-to-set-TX-de.patch | 317 - ...-Fix-AP-mode-incorrect-DTIM-behavior.patch | 96 - ...i-rtw88-Skip-high-queue-in-hci_flush.patch | 32 - ...fi-rtw88-Stop-high-queue-during-scan.patch | 46 - ...88-refine-register-based-H2C-command.patch | 93 - ...-not-entering-PS-mode-after-AP-stops.patch | 139 - .../mac80211/patches/rtl/200-add-rtw89.patch | 12 - ...89-8852b-add-BB-and-RF-tables-1-of-2.patch | 13309 ------------ ...89-8852b-add-BB-and-RF-tables-2-of-2.patch | 9655 --------- ...-wifi-rtw89-8852b-add-tables-for-RFK.patch | 879 - ...make-generic-txpwr-setting-functions.patch | 669 - ...w89-debug-txpwr_table-considers-sign.patch | 53 - ...i-rtw89-8852b-add-chip_ops-set_txpwr.patch | 303 - ...w89-8852b-add-chip_ops-to-read-efuse.patch | 228 - ...9-8852b-add-chip_ops-to-read-phy-cap.patch | 253 - ...fi-rtw89-8852be-add-8852BE-PCI-entry.patch | 110 - ...-correct-set-of-IQK-backup-registers.patch | 30 - ...c-rfk-correct-miscoding-delay-of-DPK.patch | 27 - ...89-8852c-update-BB-parameters-to-v28.patch | 1440 -- ...ignore-warning-of-bb-gain-cfg_type-4.patch | 39 - ...-set-pin-MUX-to-enable-BT-firmware-l.patch | 42 - ...89-add-to-dump-TX-FIFO-0-1-for-8852C.patch | 88 - ...dd-wake_tx_queue-callback-to-drivers.patch | 29 - ...ltek-remove-duplicated-wake_tx_queue.patch | 25 - ...move-chip_ops-btc_bt_aci_imp-to-a-ge.patch | 114 - ...-PHY-status-only-when-PPDU-is-to_sel.patch | 30 - ...-set-proper-configuration-before-loa.patch | 59 - ...ifi-rtw89-8852b-add-HFC-quota-arrays.patch | 63 - ...generic-functions-to-convert-subband.patch | 138 - ...rtw89-8852b-add-chip_ops-set_channel.patch | 1082 - ...fi-rtw89-correct-6-GHz-scan-behavior.patch | 103 - ...-wrong-bandwidth-settings-after-scan.patch | 27 - ...-8852b-add-chip_ops-set_channel_help.patch | 125 - ...w89-8852b-add-power-on-off-functions.patch | 313 - ...89-8852b-add-basic-baseband-chip_ops.patch | 75 - ...89-8852b-add-chip_ops-to-get-thermal.patch | 49 - ...-add-chip_ops-related-to-BT-coexiste.patch | 365 - ...w89-8852b-add-chip_ops-to-query-PPDU.patch | 62 - ...-add-chip_ops-to-configure-TX-RX-pat.patch | 176 - ...-add-functions-to-control-BB-to-assi.patch | 388 - ...2b-add-basic-attributes-of-chip_info.patch | 300 - ....2-035-wifi-rtw89-8852b-rfk-add-DACK.patch | 537 - ...6.2-036-wifi-rtw89-8852b-rfk-add-RCK.patch | 86 - ...-037-wifi-rtw89-8852b-rfk-add-RX-DCK.patch | 132 - ...6.2-038-wifi-rtw89-8852b-rfk-add-IQK.patch | 1199 -- ....2-039-wifi-rtw89-8852b-rfk-add-TSSI.patch | 1407 -- ...6.2-040-wifi-rtw89-8852b-rfk-add-DPK.patch | 1330 -- ...-add-chip_ops-related-to-RF-calibrat.patch | 75 - ...dd-dummy-C2H-handler-to-avoid-warnin.patch | 50 - ...b-add-8852be-to-Makefile-and-Kconfig.patch | 69 - ...apt-to-new-firmware-format-of-dynami.patch | 108 - ...w89-declare-support-bands-with-const.patch | 46 - ...8852c-make-table-of-RU-mask-constant.patch | 31 - ...W-info-for-both-TX-and-RX-in-phy_inf.patch | 61 - ...-if-sta-s-mac_id-is-valid-under-AP-T.patch | 28 - ...ct-and-send-RF-parameters-to-firmwar.patch | 102 - ...enable_cpu-disable_cpu-into-fw_downl.patch | 79 - ...unction-to-adjust-and-restore-PLE-qu.patch | 110 - ...fi-rtw89-add-drop-tx-packet-function.patch | 258 - ...tw89-add-related-H2C-for-WoWLAN-mode.patch | 509 - ...fi-rtw89-add-WoWLAN-function-support.patch | 1158 - ...w89-add-WoWLAN-pattern-match-support.patch | 498 - ...-Fix-spelling-mistake-KIP_RESOTRE-KI.patch | 27 - ...-dump-dispatch-status-via-debug-port.patch | 704 - ...e-D-MAC-and-C-MAC-dump-to-diagnose-S.patch | 1375 -- ...-change-debug-mask-of-message-of-no-.patch | 54 - ...ome-error-handling-path-in-rtw89_wow.patch | 47 - ...-correct-TX-power-controlled-by-BT-c.patch | 63 - ...CFO-from-FD-or-preamble-CFO-field-of.patch | 93 - ...h-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch | 302 - ...-inaccessible-IO-operations-during-d.patch | 73 - ...e-mac80211-virtual-monitor-interface.patch | 47 - ...w89-add-HE-radiotap-for-monitor-mode.patch | 102 - ...-turn-off-PoP-function-in-monitor-mo.patch | 53 - ...ename-rtw89_mcc_info-to-rtw89_rfk_mc.patch | 140 - ...9-check-if-atomic-before-queuing-c2h.patch | 146 - ...duce-helpers-to-wait-complete-on-con.patch | 136 - ...fi-rtw89-mac-process-MCC-related-C2H.patch | 382 - ...i-rtw89-fw-implement-MCC-related-H2C.patch | 741 - ...89-link-rtw89_vif-and-chanctx-stuffs.patch | 193 - ...-request-partial-firmware-if-SECURIT.patch | 119 - ...st-full-firmware-only-once-if-it-s-e.patch | 159 - ...wifi-rtw89-add-mac-TSF-sync-function.patch | 117 - ...-stop-mac-port-function-when-stop_ap.patch | 80 - ...-fix-unsuccessful-interface_add-flow.patch | 34 - ...-add-join-info-upon-create-interface.patch | 29 - ...89-consider-ER-SU-as-a-TX-capability.patch | 104 - ...apt-to-new-firmware-format-of-securi.patch | 96 - ...w89-8852c-rfk-recover-RX-DCK-failure.patch | 394 - ...add-BTC-format-version-derived-from-.patch | 191 - ...use-new-introduction-BTC-version-for.patch | 390 - ...Enable-Bluetooth-report-when-show-de.patch | 80 - ...Update-BTC-firmware-report-bitmap-de.patch | 225 - ...Add-v2-BT-AFH-report-and-related-var.patch | 209 - ...refactor-_chk_btc_report-to-extend-m.patch | 509 - ...Change-TDMA-related-logic-to-version.patch | 162 - ...2b-update-BSS-color-mapping-register.patch | 98 - ...w89-refine-6-GHz-scanning-dwell-time.patch | 49 - ...-rfk-refine-AGC-tuning-flow-of-DPK-f.patch | 117 - ...fi-rtw89-Fix-a-typo-in-debug-message.patch | 26 - ...Remove-le32-to-CPU-translator-at-fir.patch | 326 - ...Rename-BTC-firmware-cycle-report-by-.patch | 303 - ...Add-v4-version-firmware-cycle-report.patch | 336 - ...Change-firmware-control-report-to-ve.patch | 243 - ...-coex-Add-v5-firmware-control-report.patch | 242 - ...only-read-Bluetooth-counter-of-repor.patch | 34 - ...oex-Update-WiFi-role-info-H2C-report.patch | 154 - ...Add-version-code-for-Wi-Fi-firmware-.patch | 40 - ...Change-Wi-Fi-Null-data-report-to-ver.patch | 177 - ...Change-firmware-steps-report-to-vers.patch | 289 - ...coex-refactor-debug-log-of-slot-list.patch | 96 - ...Packet-traffic-arbitration-hardware-.patch | 63 - ...x-Change-RTL8852B-use-v1-TDMA-policy.patch | 29 - ...Change-Wi-Fi-role-info-related-logic.patch | 197 - ...ull-vif-pointer-when-get-management-.patch | 30 - ...he-correct-mac_id-for-management-fra.patch | 72 - ...ct-register-definitions-of-digital-C.patch | 61 - ...8852c-rfk-correct-ADC-clock-settings.patch | 177 - ...9-fix-assignation-of-TX-BD-RAM-table.patch | 139 - ...-fill-the-missing-configuration-abou.patch | 29 - ...Update-Wi-Fi-external-control-TDMA-p.patch | 112 - ...Clear-Bluetooth-HW-PTA-counter-when-.patch | 37 - ...Force-to-update-TDMA-parameter-when-.patch | 42 - ...fi-rtw89-coex-Refine-coexistence-log.patch | 281 - ...Set-Bluetooth-background-scan-PTA-re.patch | 30 - ...x-Correct-A2DP-exist-variable-source.patch | 29 - ...Fix-test-fail-when-coexist-with-rasp.patch | 32 - ...Update-Wi-Fi-Bluetooth-coexistence-v.patch | 30 - ...ct-unit-for-port-offset-and-refine-m.patch | 46 - ...-out-generic-part-of-rtw89_mac_port_.patch | 95 - ...fi-rtw89-mac-add-function-to-get-TSF.patch | 72 - ...33-wifi-rtw89-deal-with-RXI300-error.patch | 67 - ...rtw89-fix-parsing-offset-for-MCC-C2H.patch | 85 - ...wifi-rtw89-refine-MCC-C2H-debug-logs.patch | 94 - ...low-enter-PS-mode-after-create-TDLS-.patch | 64 - ...otential-wrong-mapping-for-pkt-offlo.patch | 68 - ...ifi-rtw89-refine-packet-offload-flow.patch | 297 - ...se-of-pkt_list-offload-to-debug-entr.patch | 96 - ...2b-reset-IDMEM-mode-to-default-value.patch | 54 - ...-don-t-support-LPS-PG-mode-after-fir.patch | 68 - ...-try-to-use-NORMAL_CE-type-firmware-.patch | 138 - ...52be-enable-CLKREQ-of-PCI-capability.patch | 26 - ...-passed-channel-in-set_tx_shape_dfir.patch | 78 - ...-correct-register-mask-name-of-TX-po.patch | 29 - ...et-TX-power-according-to-RF-path-num.patch | 72 - ...eadable-return-0-in-rtw89_mac_cfg_pp.patch | 50 - ...H2C-of-del_pkt_offload-before-pollin.patch | 38 - ...P-mode-authentication-transmission-f.patch | 109 - .../201-v6.3-150-add-realtek-rtl8852be.patch | 44 - ...rtw89-add-RNR-support-for-6-GHz-scan.patch | 305 - ...i-rtw89-add-tx_wake-notify-for-8852B.patch | 27 - ...nfigure-CRASH_TRIGGER-feature-for-88.patch | 29 - ...t-channel-encoding-to-common-functio.patch | 207 - ...52b-add-channel-encoding-for-hw_scan.patch | 56 - ...i-rtw89-8852b-enable-hw_scan-support.patch | 24 - ...e-FW-feature-judgement-on-packet-dro.patch | 90 - ...SER-L1-might-stop-entering-LPS-issue.patch | 42 - ...se-RX-standby-timer-of-beamformee-CS.patch | 99 - ...Add-more-error_map-and-counter-to-lo.patch | 347 - ...ifi-rtw89-coex-Add-WiFi-role-info-v2.patch | 671 - ...x-Add-traffic-TX-RX-info-and-its-H2C.patch | 403 - ...Add-register-monitor-report-v2-forma.patch | 283 - ...Fix-wrong-structure-assignment-at-nu.patch | 28 - ...tw89-coex-Add-v2-Bluetooth-scan-info.patch | 226 - ...-Add-v5-firmware-cycle-status-report.patch | 375 - ...Add-LPS-protocol-radio-state-for-RTL.patch | 62 - ...Not-to-enable-firmware-report-when-W.patch | 35 - ...Update-RTL8852B-LNA2-hardware-parame.patch | 168 - ...coex-Add-report-control-v5-variation.patch | 241 - ...Update-Wi-Fi-Bluetooth-coexistence-v.patch | 46 - ...d-counters-of-register-based-H2C-C2H.patch | 160 - ...ata-lowest-rate-according-to-AP-supp.patch | 80 - ...-remove-superfluous-H2C-of-join_info.patch | 47 - ...ncorrect-channel-info-during-scan-du.patch | 42 - ...g-EDCCA-threshold-during-scan-to-pre.patch | 139 - ...otential-race-condition-between-napi.patch | 127 - ...89-Remove-redundant-pci_clear_master.patch | 42 - ...2c-add-beacon-filter-and-CQM-support.patch | 411 - ...unction-to-wait-for-completion-of-TX.patch | 177 - ...-add-ieee80211-remain_on_channel-ops.patch | 666 - ...rtw89-add-flag-check-for-power-state.patch | 65 - ...-fix-authentication-fail-during-scan.patch | 79 - ...e-generic-flow-to-set-check-features.patch | 140 - ...se-schedule_work-to-request-firmware.patch | 225 - ...irmware-format-version-to-backward-c.patch | 273 - ...support-parameter-tables-by-RFE-type.patch | 532 - ...-hardware-CFO-to-improve-performance.patch | 169 - ...tw89-read-version-of-analog-hardware.patch | 72 - ...-fix-TX-path-to-path-A-for-one-RF-pa.patch | 40 - ...update-MAC-settings-to-support-8851b.patch | 143 - ...pdate-PCI-related-settings-to-suppor.patch | 136 - ...89-8851b-add-BB-and-RF-tables-1-of-2.patch | 6819 ------ ...89-8851b-add-BB-and-RF-tables-2-of-2.patch | 8087 ------- ...-wifi-rtw89-8851b-add-tables-for-RFK.patch | 596 - ...ifi-rtw89-correct-5-MHz-mask-setting.patch | 75 - ...rash-due-to-null-pointer-of-sta-in-A.patch | 58 - ...rtw89-support-WoWLAN-mode-for-8852be.patch | 79 - ...x-power-save-function-in-WoWLAN-mode.patch | 77 - ...Enable-Wi-Fi-RX-gain-control-for-fre.patch | 59 - ...Add-path-control-register-to-monitor.patch | 44 - ...Update-function-to-get-BT-RSSI-and-h.patch | 55 - ...send-more-hardware-module-info-to-fi.patch | 256 - ...89-prohibit-enter-IPS-during-HW-scan.patch | 30 - ...9-refine-scan-function-after-chanctx.patch | 222 - ...truct-instead-of-macros-to-set-H2C-c.patch | 215 - ...e-statistics-to-FW-for-fine-tuning-p.patch | 116 - ...low-power-save-with-multiple-station.patch | 30 - ...rtw89-add-support-of-concurrent-mode.patch | 59 - ...se-regular-int-as-return-type-of-DLE.patch | 121 - ...truct-rtw89_phy_sts_ie0-instead-of-m.patch | 76 - ...t-capability-of-TX-antenna-diversity.patch | 113 - ...SSI-statistics-for-the-case-of-anten.patch | 92 - ...dd-EVM-and-SNR-statistics-to-debugfs.patch | 179 - ...ialize-antenna-for-antenna-diversity.patch | 149 - ...w89-add-RSSI-based-antenna-diversity.patch | 345 - ...-rtw89-add-EVM-for-antenna-diversity.patch | 87 - ...se-bit-in-rtw89_fw_h2c_del_pkt_offlo.patch | 62 - ...e-packet-offload-delete-flow-of-6-GH.patch | 152 - ...-packet-offload-wait-for-FW-response.patch | 269 - ...andle-C2H-receive-done-ACK-in-interr.patch | 58 - ...89-scan-offload-wait-for-FW-done-ACK.patch | 182 - ...tw89-8851b-add-8851B-basic-chip_info.patch | 140 - ...e-add-8851BE-PCI-entry-and-fill-PCI-.patch | 106 - ...wifi-rtw89-8851b-add-NCTL-post-table.patch | 101 - ...FO-XTAL-registers-field-to-support-8.patch | 175 - ...hip_info-small_fifo_size-to-choose-d.patch | 87 - ...e-naming-of-BA-CAM-from-V1-to-V0_EXT.patch | 164 - ...89-8851b-add-support-WoWLAN-to-8851B.patch | 56 - ...tw89-8851b-add-DLE-mem-and-HFC-quota.patch | 105 - ...-wifi-rtw89-8851b-add-set_channel_rf.patch | 277 - ....4-082-wifi-rtw89-8851b-rfk-add-AACK.patch | 103 - ...6.4-083-wifi-rtw89-8851b-rfk-add-RCK.patch | 83 - ....4-084-wifi-rtw89-8851b-rfk-add-DACK.patch | 432 - ...6.4-085-wifi-rtw89-8851b-rfk-add-IQK.patch | 1203 -- ...tw89_read_chip_ver-for-RTL8852B-and-.patch | 32 - ...89-introduce-realtek-ACPI-DSM-method.patch | 114 - ...judge-UNII-4-according-to-BIOS-and-c.patch | 173 - ...upport-U-NII-4-channels-on-5GHz-band.patch | 62 - ...ix-interrupt-enable-mask-for-HALT-C2.patch | 58 - ...ser-L1-add-pre-M0-and-post-M0-states.patch | 207 - ...ess-the-log-for-specific-SER-called-.patch | 82 - ...-adjust-quota-to-avoid-SER-L1-caused.patch | 118 - ...-add-to-read-efuse-version-to-recogn.patch | 61 - ...-configure-GPIO-according-to-RFE-typ.patch | 194 - ...-add-BT-coexistence-support-function.patch | 421 - ...89-8851b-add-basic-power-on-function.patch | 452 - ...rtw89-8851b-add-set-channel-function.patch | 812 - ...w89-8851b-add-to-parse-efuse-content.patch | 311 - ...-100-wifi-rtw89-8851b-rfk-add-RX-DCK.patch | 172 - ...6.4-101-wifi-rtw89-8851b-rfk-add-DPK.patch | 1196 -- ....4-102-wifi-rtw89-8851b-rfk-add-TSSI.patch | 684 - ...eset-total_sta_assoc-and-tdls_peer-w.patch | 39 - ...weak-H2C-TX-waiting-function-for-SER.patch | 78 - ...ne-packet-offload-handling-under-SER.patch | 60 - ...8851b-add-TX-power-related-functions.patch | 306 - ...-fill-BB-related-capabilities-to-chi.patch | 278 - ...-add-MAC-configurations-to-chip_info.patch | 142 - ...fi-rtw89-8851b-add-RF-configurations.patch | 102 - ...ge-supported-length-of-read_reg-debu.patch | 72 - ...i-rtw89-add-tx_wake-notify-for-8851B.patch | 27 - ...b-add-8851be-to-Makefile-and-Kconfig.patch | 65 - ...hip_ops-query_rxdesc-and-rxd_len-as-.patch | 151 - ...truct-and-le32_get_bits-to-access-RX.patch | 102 - ...truct-and-le32_get_bits-to-access-re.patch | 197 - ...truct-and-le32_get_bits-to-access-RX.patch | 160 - ...truct-to-access-register-based-H2C-C.patch | 246 - ...-rfk-Fix-spelling-mistake-KIP_RESOTR.patch | 27 - ...lexible-array-member-in-rtw89_btc_bt.patch | 37 - ...ct-PS-calculation-for-SUPPORTS_DYNAM.patch | 117 - ...move-redundant-check-of-entering-LPS.patch | 28 - ...i-rtw89-8851b-enable-hw_scan-support.patch | 40 - ...-txpwr-table-access-only-valid-page-.patch | 103 - ...X-power-without-precondition-during-.patch | 62 - ...-configure-CRASH_TRIGGER-feature-for.patch | 29 - ...e-clearing-supported-bands-to-check-.patch | 36 - ...judge-6-GHz-according-to-chip-and-BI.patch | 84 - ...egd-update-regulatory-map-to-R64-R40.patch | 279 - ...cess-regulatory-for-6-GHz-power-type.patch | 314 - ...-update-TX-power-tables-to-R63-with-.patch | 8045 ------- ...-update-TX-power-tables-to-R63-with-.patch | 11308 ---------- ...-update-TX-power-tables-to-R63-with-.patch | 8532 -------- ...-update-RF-radio-A-B-parameters-to-R.patch | 7787 ------- ...tw89-cleanup-private-data-structures.patch | 158 - ...anup-rtw89_iqk_info-and-related-code.patch | 218 - ...-spelling-typo-of-IQK-debug-messages.patch | 50 - ...-update-RF-radio-A-parameters-to-R28.patch | 74 - ...-8851b-update-TX-power-tables-to-R28.patch | 740 - ...9-wifi-rtw89-8851b-rfk-add-LCK-track.patch | 154 - ...-8851b-rfk-update-IQK-to-version-0x8.patch | 253 - ...-configure-to-force-1-TX-power-value.patch | 60 - ...wer-stuffs-replace-confusing-naming-.patch | 264 - ...-use-struct-to-parse-firmware-header.patch | 263 - ...esh-fast-tx-cache-into-local-proxied.patch | 219 + ...1-always-use-mac80211-loss-detection.patch | 36 - .../subsys/401-mac80211-allow-vht-on-2g.patch | 36 + .../500-mac80211_configure_antenna_gain.patch | 4 +- .../780-avoid-crashing-missing-band.patch | 34 + .../subsys/800-rework-eth_hw_addr_set.patch | 11 + package/kernel/mac80211/realtek.mk | 194 +- package/kernel/rtw88-usb/Makefile | 105 + .../patches/001-fix-merge-error.patch | 96 + .../rtw88-usb/patches/101-wireless-6.1.patch | 432 + .../rtw88-usb/patches/102-disable-pcie.patch | 69 + package/lean/autocore/Makefile | 1 + package/lean/autocore/files/arm/index.htm | 20 +- package/lean/autocore/files/arm/sbin/usage | 14 + package/lean/cpufreq/Makefile | 30 + package/lean/cpufreq/files/cpufreq.config | 5 + package/lean/cpufreq/files/cpufreq.init | 58 + package/lean/cpufreq/files/cpufreq.uci | 75 + package/lean/csstidy/Makefile | 39 - package/lean/default-settings/Makefile | 7 +- .../files/zzz-default-settings | 14 +- .../lean/default-settings/po/zh-cn/default.po | 9 +- .../lean/default-settings/po/zh-cn/more.po | 1035 - package/lean/r8125/Makefile | 6 +- package/lean/r8125/patches/010-config.patch | 8 +- .../r8125/patches/011-ignore-rss-log.patch | 11 + .../patches/020-fixes-build-werror.patch | 28 - .../030-add-LED-configuration-from-OF.patch | 10 +- ...40-add-devname-configuration-from-OF.patch | 8 +- package/lean/r8126/Makefile | 34 + package/lean/r8126/patches/010-config.patch | 11 + package/lean/r8126/src/Makefile | 209 + package/lean/r8126/src/Makefile_linux24x | 75 + package/lean/r8126/src/r8126.h | 2789 +++ package/lean/r8126/src/r8126_dash.h | 261 + package/lean/r8126/src/r8126_firmware.c | 264 + package/lean/r8126/src/r8126_firmware.h | 68 + package/lean/r8126/src/r8126_n.c | 17425 ++++++++++++++++ package/lean/r8126/src/r8126_ptp.c | 619 + package/lean/r8126/src/r8126_ptp.h | 81 + package/lean/r8126/src/r8126_realwow.h | 118 + package/lean/r8126/src/r8126_rss.c | 491 + package/lean/r8126/src/r8126_rss.h | 69 + package/lean/r8126/src/rtl_eeprom.c | 289 + package/lean/r8126/src/rtl_eeprom.h | 58 + package/lean/r8126/src/rtltool.c | 260 + package/lean/r8126/src/rtltool.h | 86 + package/lean/r8168/Makefile | 4 +- .../100-add-LED-configuration-from-OF.patch | 4 +- package/lean/vsftpd-alt/Makefile | 6 +- package/libs/elfutils/Makefile | 5 + package/libs/gettext-full/Makefile | 1 + .../gettext-full/patches/020-fix_clang.patch | 11 + package/libs/libjson-c/Makefile | 6 +- .../patches/001-dont-build-docs.patch | 2 +- package/libs/libnl-tiny/Makefile | 6 +- package/libs/libubox/Makefile | 14 +- package/libs/libusb/Makefile | 2 +- package/libs/openssl/Makefile | 4 +- package/network/config/firewall/Makefile | 4 +- .../config/firewall/files/firewall.config | 2 +- .../config/firewall/files/firewall.init | 4 +- package/network/ipv6/ipip6/Makefile | 39 + package/network/ipv6/ipip6/files/ipip6.sh | 105 + package/network/ipv6/map/Makefile | 2 +- package/network/services/bridger/Makefile | 8 +- .../network/services/dnsmasq/files/dhcp.conf | 1 - .../services/dnsmasq/files/dnsmasq.init | 2 +- package/network/services/fullconenat/Makefile | 3 +- package/network/services/hostapd/Config.in | 5 + package/network/services/hostapd/Makefile | 12 +- package/network/services/hostapd/README.md | 419 - .../network/services/hostapd/files/hostapd.sh | 6 +- .../hostapd/files/wpa_supplicant-basic.config | 2 +- .../hostapd/files/wpa_supplicant-full.config | 2 +- .../hostapd/files/wpa_supplicant-mini.config | 2 +- .../hostapd/files/wpa_supplicant-p2p.config | 2 +- ...hannels-to-be-selected-if-dfs-is-ena.patch | 85 +- ...erministic-channel-on-channel-switch.patch | 6 +- ...ix-sta-add-after-previous-connection.patch | 4 +- ...use-of-uninitialized-stack-variables.patch | 2 +- ...ewrite-neigh-code-to-not-depend-on-l.patch | 14 +- ...ssing-authentication-frames-in-block.patch | 2 +- .../hostapd/patches/050-build_fix.patch | 2 +- ...edtls-TLS-crypto-option-initial-port.patch | 22 +- .../patches/120-mbedtls-fips186_2_prf.patch | 2 +- ...efile-make-run-tests-with-CONFIG_TLS.patch | 78 +- ...hecks-encountered-during-tests-hwsim.patch | 2 +- ...-dpp_pkex-EC-point-mul-w-value-prime.patch | 2 +- ...70-DPP-fix-memleak-of-intro.peer_key.patch | 32 + ...ix-compiling-without-IEEE8021X_EAPOL.patch | 41 - .../hostapd/patches/200-multicall.patch | 48 +- .../services/hostapd/patches/300-noscan.patch | 4 +- .../hostapd/patches/301-mesh-noscan.patch | 52 +- .../patches/310-rescan_immediately.patch | 2 +- .../patches/330-nl80211_fix_set_freq.patch | 2 +- .../patches/340-reload_freq_change.patch | 10 +- .../341-mesh-ctrl-iface-channel-switch.patch | 2 +- .../patches/350-nl80211_del_beacon_bss.patch | 23 +- .../patches/360-ctrl_iface_reload.patch | 10 +- .../hostapd/patches/370-ap_sta_support.patch | 59 +- .../patches/380-disable_ctrl_iface_mib.patch | 82 +- .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 2 +- .../patches/390-wpa_ie_cap_workaround.patch | 4 +- .../patches/410-limit_debug_messages.patch | 22 +- .../patches/420-indicate-features.patch | 4 +- .../patches/430-hostapd_cli_ifdef.patch | 12 +- .../hostapd/patches/432-missing-typedef.patch | 10 + .../hostapd/patches/450-scan_wait.patch | 6 +- ...dd-new-config-params-to-be-used-with.patch | 10 +- ...-use-new-parameters-during-ibss-join.patch | 59 + .../patches/463-add-mcast_rate-to-11s.patch | 6 +- .../patches/464-fix-mesh-obss-check.patch | 22 +- ...tapd-config-support-random-BSS-color.patch | 2 +- .../patches/470-survey_data_fallback.patch | 15 +- .../patches/500-lto-jobserver-support.patch | 6 +- .../patches/590-rrm-wnm-statistics.patch | 12 +- .../hostapd/patches/600-ubus_support.patch | 89 +- .../hostapd/patches/700-wifi-reload.patch | 72 +- .../hostapd/patches/710-vlan_no_bridge.patch | 2 +- .../patches/711-wds_bridge_force.patch | 6 +- .../patches/720-iface_max_num_sta.patch | 10 +- .../hostapd/patches/730-ft_iface.patch | 6 +- .../hostapd/patches/740-snoop_iface.patch | 8 +- ...750-qos_map_set_without_interworking.patch | 18 +- .../751-qos_map_ignore_when_unsupported.patch | 2 +- .../hostapd/patches/760-dynamic_own_ip.patch | 4 +- .../hostapd/patches/761-shared_das_port.patch | 2 +- ...-indoor-channel-on-outdoor-operation.patch | 58 + ..._AP-functions-dependant-on-CONFIG_AP.patch | 4 +- .../services/hostapd/patches/991-s8-u8.patch | 23 - .../patches/992-openssl-include-rsa.patch | 32 + .../patches/993-fix-mbo-module-build.patch | 10 + package/network/services/unetd/Makefile | 113 + .../services/unetd/files/unet-dht.init | 24 + .../network/services/unetd/files/unetd.init | 17 + package/network/services/unetd/files/unetd.sh | 99 + package/network/utils/iwinfo/Makefile | 8 +- .../utils/iwinfo/patches/001-ralink.patch | 39 - .../utils/uqmi/files/lib/netifd/proto/qmi.sh | 2 +- package/qca/nss-firmware/Makefile | 88 + package/qca/qca-mcs/Makefile | 68 + .../patches/0001-kernel-5.10-compat.patch | 40 + package/qca/qca-nss-cfi/Makefile | 82 + ...yptoapi-v2.0-fix-SHA1-header-include.patch | 62 + ...ptoapi-v2.0-make-ablkcipher-optional.patch | 116 + ...emove-setting-crypto_ahash_type-for-.patch | 137 + ...ead-add-downstream-crypto_tfm_alg_fl.patch | 28 + ...-cryptoapi-v2.0-remove-dropped-flags.patch | 97 + ...6-cryptoapi-v2.0-convert-to-skcipher.patch | 1199 ++ package/qca/qca-nss-clients/Makefile | 612 + .../qca/qca-nss-clients/files/qca-nss-ipsec | 231 + .../qca-nss-clients/files/qca-nss-mirred.init | 28 + .../files/qca-nss-netlink.init | 31 + .../qca-nss-clients/files/qca-nss-ovpn.init | 69 + .../0001-kernel-5.15-support-qdisc.patch | 162 + .../patches/0002-kernel-5.4-support-gre.patch | 31 + .../0003-kernel-5.4-support-ipsec.patch | 29 + .../0004-kernel-5.4-support-dtls.patch | 11 + .../0005-vlanmgr-fix-compile-error.patch | 59 + .../0006-match-fix-compile-error.patch | 25 + .../0007-bridge-fix-compile-error.patch | 29 + .../0008-profiler-fix-compile-error.patch | 61 + .../patches/0009-gre-fix-compile-error.patch | 17 + .../patches/0010-fix-portifmgr.patch | 35 + ...lsmgr-fix-SHA-header-include-in-5.15.patch | 48 + ...0012-dtlsmgr-fix-debug-print-in-5.15.patch | 36 + ...lsmgr-fix-SHA-header-include-in-5.15.patch | 32 + ...pnmgr-fix-SHA-header-include-in-5.15.patch | 32 + ...5-tunipip6-fix-compile-error-in-5.15.patch | 11 + ...6-vxlanmgr-fix-compile-error-in-5.15.patch | 11 + .../0017-tlsmgr-fix-debug-print-in-5.15.patch | 34 + .../patches/0018-kernel-6.1-support.patch | 301 + package/qca/qca-nss-crypto/Makefile | 68 + ...1-nss-crypto-fix-SHA1-header-include.patch | 27 + ...replace-ioremap_nocache-with-ioremap.patch | 94 + ...rypto-fix-SHA-header-include-in-5.15.patch | 44 + package/qca/qca-nss-drv/Config.in | 184 + package/qca/qca-nss-drv/Makefile | 275 + .../qca/qca-nss-drv/files/qca-nss-drv.conf | 6 + .../qca/qca-nss-drv/files/qca-nss-drv.debug | 26 + .../qca/qca-nss-drv/files/qca-nss-drv.hotplug | 70 + .../qca/qca-nss-drv/files/qca-nss-drv.init | 50 + .../qca/qca-nss-drv/files/qca-nss-drv.sysctl | 3 + ...replace-ioremap_nocache-with-ioremap.patch | 207 + ...-nss-drv-add-support-for-kernel-5.15.patch | 62 + ...0003-DMA-Fix-NULL-pointer-exceptions.patch | 28 + ...-rework-NSS_CORE_DMA_CACHE_MAINT-ops.patch | 558 + ...ork-getting-the-reserved-memory-size.patch | 114 + ...ts-enum-int-compilation-error-GCC-13.patch | 11 + ...s_wifili_if-compilation-error-GCC-13.patch | 11 + .../patches/0008-add-kernel-6.1-support.patch | 250 + package/qca/qca-nss-ecm/Makefile | 161 + .../files/disable_offloads.hotplug | 187 + .../qca/qca-nss-ecm/files/disable_offloads.sh | 189 + package/qca/qca-nss-ecm/files/ecm_dump.sh | 95 + package/qca/qca-nss-ecm/files/on-demand-down | 6 + .../qca-nss-ecm/files/qca-nss-ecm.defaults | 28 + .../qca-nss-ecm/files/qca-nss-ecm.firewall | 11 + .../qca/qca-nss-ecm/files/qca-nss-ecm.init | 137 + .../qca/qca-nss-ecm/files/qca-nss-ecm.sysctl | 1 + package/qca/qca-nss-ecm/files/qca-nss-ecm.uci | 8 + ...de-componentize-the-module-even-more.patch | 361 + ...eewide-rework-ipv6_dev_find_and_hold.patch | 63 + ...olve-the-cpu-high-load-regarding-ecm.patch | 55 + ...se-of-static-be_liberal-and-no_windo.patch | 88 + ...tagram-drop-static-for-EXPORT_SYMBOL.patch | 50 + ...dp_get_timeouts-and-use-standard-ups.patch | 63 + ...-ppp-generic-function-calls-for-5.15.patch | 20 + ...reewide-export-ipv4-and-ipv6-symbols.patch | 99 + .../1000-fix-missing-include-header.patch | 10 + ...-ecm-fix-a-memcpy-overflow-in-ecm_db.patch | 61 + package/qca/qca-ssdk-shell/Makefile | 48 + ...al_port_cdt-compilation-error-GCC-13.patch | 10 + scripts/download.pl | 66 +- target/linux/{meson => amlogic}/Makefile | 10 +- target/linux/amlogic/config-5.15 | 46 + .../arch/arm/boot/dts/meson8b-onecloud.dts | 0 target/linux/amlogic/image/Makefile | 91 + target/linux/amlogic/image/aml_autoscript.cmd | 10 + target/linux/amlogic/image/amlogic.bootscript | 34 + .../linux/{meson => amlogic}/image/boot.txt | 0 .../linux/amlogic/image/emmc_autoscript.cmd | 8 + .../image/gen_aml_emmc_img.sh | 0 .../linux/amlogic/image/gen_amlogic_image.sh | 60 + target/linux/amlogic/image/meson8b.mk | 18 + target/linux/amlogic/image/mesongx.mk | 19 + .../linux/amlogic/image/s905_autoscript.cmd | 16 + .../meson8b}/base-files/etc/inittab | 0 .../meson8b}/base-files/etc/rc.local | 0 .../base-files/lib/preinit/79_move_config | 0 .../base-files/lib/upgrade/platform.sh | 0 .../meson8b}/base-files/root/resize.sh | 0 .../{meson => amlogic}/meson8b/config-6.1 | 0 .../{meson => amlogic}/meson8b/target.mk | 0 .../mesongx/base-files/etc/board.d/02_network | 59 + .../uci-defaults/12_enable-netifd-smp-tune | 7 + .../base-files/lib/preinit/79_move_config | 16 + .../base-files/lib/upgrade/platform.sh | 84 + .../base-files/usr/sbin/install-to-emmc.sh | 144 + target/linux/amlogic/mesongx/config-5.15 | 710 + target/linux/amlogic/mesongx/target.mk | 12 + target/linux/amlogic/modules.mk | 15 + .../001-dts-s905d-fix-high-load.patch | 16 + .../002-dts-improve-phicomm-n1-support.patch | 48 + .../902-use-system-LED-for-OpenWrt.patch | 0 .../903-add-dts-and-identify-emmc.patch | 0 ...n-modify-and-simplify-calculation-in.patch | 0 ...d-initialise-an-orientation-field-to.patch | 2 +- ...epare_upstream_first-flag-to-drm_pan.patch | 2 +- ...8-drm-vc4-Support-zpos-on-all-planes.patch | 4 +- ...-Make-use-of-chroma-siting-parameter.patch | 2 +- ...-2-and-4-4-4-4-RGB-RGBX-RGBA-formats.patch | 2 +- ...net-Request-APD-DLL-disable-and-IDDQ.patch | 2 +- ...smsx95xx-fix-crimes-against-truesize.patch | 47 - ...ental-Enable-turbo_mode-and-packetsi.patch | 8 +- ...ow-mac-address-to-be-set-in-smsc95xx.patch | 6 +- .../950-0106-Add-dwc_otg-driver.patch | 2 +- ...111-MMC-added-alternative-MMC-driver.patch | 6 +- ...irmware-bcm2835-Support-ARCH_BCM270x.patch | 8 +- ...ds-Add-the-input-trigger-for-pwr_led.patch | 2 +- ...all-the-downstream-rpi-sound-card-dr.patch | 2 +- ...pberrypi-Notify-firmware-of-a-reboot.patch | 6 +- ...rypi-Add-backward-compatible-get_thr.patch | 8 +- ...rypi-Report-the-fw-variant-during-pr.patch | 6 +- ...chiq-Avoid-use-of-bool-in-structures.patch | 2 +- ...chiq-Add-support-for-event-callbacks.patch | 16 +- ...iq-Free-the-event-context-for-contro.patch | 2 +- ...-vchiq-Fix-memory-leak-in-error-path.patch | 8 +- ...Better-coalescing-parameter-defaults.patch | 4 +- ...-link-energy-detect-powerdown-for-ex.patch | 2 +- ...-for-updating-interrupt-endpoint-int.patch | 8 +- ...hci_fixup_endpoint-for-interval-adju.patch | 4 +- ...t-Workaround-2-for-Pi4-Ethernet-fail.patch | 4 +- ...ore-event-ring-segment-table-entries.patch | 6 +- ...lise-rpi-firmware-before-clk-bcm2835.patch | 2 +- ...CS_HIGH-if-GPIO-descriptors-are-used.patch | 4 +- ...et-bcmgenet-Reset-RBUF-on-first-open.patch | 70 - ...iq-Use-vc-sm-cma-to-support-zero-cop.patch | 6 +- .../950-0281-gpio-Add-gpio-fsm-driver.patch | 2 +- ...rypi-Add-support-for-tryonce-reboot-.patch | 4 +- ...und-for-bogus-SET_DEQ_PENDING-endpoi.patch | 2 +- ...-Add-a-timing-for-the-Raspberry-Pi-7.patch | 4 +- ...iq-Add-module-parameter-to-enable-lo.patch | 22 +- ...iq-Reset-buffers_with_vpu-on-port_en.patch | 2 +- ...-quirks-add-link-TRB-quirk-for-VL805.patch | 6 +- ...t-TRBS_PER_SEGMENT-define-in-runtime.patch | 8 +- ...usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch | 4 +- ...nel-simple-add-Geekworm-MZP280-Panel.patch | 2 +- ...uirk-for-Superspeed-bulk-OUT-transfe.patch | 10 +- ...ework-XHCI_VLI_SS_BULK_OUT_BUG-quirk.patch | 6 +- ...do-single-sector-reads-during-recove.patch | 2 +- ...-for-num_trbs_free-when-invalidating.patch | 12 +- ...rypi-Introduce-rpi_firmware_find_nod.patch | 4 +- ...rypi-Provide-a-helper-to-query-a-clo.patch | 2 +- ...hdmi-Fix-hdmi_enable_4kp60-detection.patch | 2 +- ...ork-hdmi_enable_4kp60-detection-code.patch | 2 +- ...9-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch | 10 +- ...et-bcmgenet-Add-eee-module-parameter.patch | 2 +- ...HCI_VLI_HUB_TT_QUIRK-to-old-firmware.patch | 4 +- ...mple-Add-Innolux-AT056tN53V1-5.6-VGA.patch | 2 +- ...d-add-the-endpoint-context-in-xhci_f.patch | 2 +- ...al-8250-Add-NOMSI-bug-for-bcm2835aux.patch | 6 +- ...-phys-addresses-for-slave-DMA-config.patch | 8 +- ...7xx-Read-modem-line-state-at-startup.patch | 2 +- ...ow-mac-address-to-be-set-in-smsc95xx.patch | 4 +- ...d-NULL-pointer-dereference-in-f2fs_i.patch | 4 +- .../950-0860-sdhci-Add-SD-Express-hook.patch | 6 +- ...wc3-Set-DMA-and-coherent-masks-early.patch | 22 +- ...vc4-Introduce-generation-number-enum.patch | 4 +- ...0963-drm-vc4-hvs-Support-BCM2712-HVS.patch | 4 +- ...-Alter-the-timing-for-the-Pi-7-DSI-d.patch | 2 +- ...mc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch | 2 +- .../950-1182-drm-panel-add-panel-dsi.patch | 6 +- ...n-t-check-if-plane-state-fb-state-fb.patch | 93 - .../209-b44-register-adm-switch.patch | 6 +- .../bcm47xx/patches-5.4/210-b44_phy_fix.patch | 2 +- ...SSC-helper-should-use-its-own-config.patch | 140 - ...ve-ifdef-CONFIG_NFSD-from-client-SSC.patch | 84 - .../630-v5.15-page_pool_frag_support.patch | 16 +- ...e-between-coalescing-and-releasing-S.patch | 2 +- ...the-dst-buffer-to-of_get_mac_address.patch | 4 +- ...net-usb-ax88179_178a-add-TSO-feature.patch | 4 +- ...declar-their-reliance-on-msi-domains.patch | 4 +- ...dd-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch | 4 +- ...-v6.1-05-mm-multi-gen-LRU-groundwork.patch | 2 +- ...xhci-mvebu-make-USB-3.0-PHY-optional.patch | 2 +- ...g-MTD-device-associated-with-a-speci.patch | 2 +- ...uce-tagger-owned-storage-for-private.patch | 12 +- ...ocols-connect-to-individual-switches.patch | 10 +- ...ek-mt7622-add-support-for-coherent-D.patch | 30 - ...ek-mt7622-introduce-nodes-for-Wirele.patch | 62 - ..._eth_soc-use-standard-property-for-c.patch | 2 +- ...terate-using-dsa_switch_for_each_use.patch | 4 +- ...opulate-supported_interfaces-and-mac.patch | 18 +- ...t-dsa-mt7530-remove-interface-checks.patch | 18 +- ...rop-use-of-phylink_helper_basex_spee.patch | 2 +- ...nly-indicate-linkmodes-that-can-be-s.patch | 8 +- ...-switch-to-use-phylink_get_linkmodes.patch | 12 +- ...530-partially-convert-to-phylink_pcs.patch | 38 +- ...ove-autoneg-handling-to-PCS-validati.patch | 6 +- ...19-net-dsa-mt7530-mark-as-non-legacy.patch | 2 +- ...mt753x-fix-pcs-conversion-regression.patch | 4 +- ...t7530-rework-mt7530_hw_vlan_-add-del.patch | 6 +- ...et-cpu-port-via-dp-cpu_dp-instead-of.patch | 16 +- ..._eth_soc-fix-resource-leak-in-error-.patch | 35 + ..._eth_soc-fix-memory-leak-in-error-pa.patch | 107 + ..._eth_soc-align-reset-procedure-to-ve.patch | 4 +- ..._eth_soc-avoid-port_mg-assignment-on.patch | 4 +- ...iatek-ppe-assign-per-port-queues-for.patch | 2 +- ..._eth_soc-compile-out-netsys-v2-code-.patch | 28 - ..._eth_soc-fix-VLAN-rx-hardware-accele.patch | 2 +- ...ii-ensure-the-SGMII-PHY-is-powered-d.patch | 2 +- ...t-mtk_eth_soc-add-support-for-MT7981.patch | 8 +- ..._eth_soc-switch-to-external-PCS-driv.patch | 10 +- ...eth_soc-add-missing-ppe-cache-flush.patch} | 2 +- ..._eth_soc-use-WO-firmware-for-MT7981.patch} | 0 ...eth_soc-fix-NULL-pointer-dereferenc.patch} | 0 ...eth_soc-ppe-add-support-for-flow-ac.patch} | 26 +- ...atek-fix-ppe-flow-accounting-for-v1.patch} | 4 +- ...eth_soc-drop-generic-vlan-rx-offloa.patch} | 0 ..._eth_soc-always-mtk_get_ib1_pkt_type.patch | 31 + ...lter-flowtable-validate-pppoe-header.patch | 85 - ...lter-flowtable-incorrect-pppoe-tuple.patch | 24 - ..._ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch | 78 + ..._eth_soc-remove-incorrect-PLL-config.patch | 141 + ..._eth_soc-remove-mac_pcs_get_state-an.patch | 81 + ..._eth_soc-add-version-in-mtk_soc_data.patch | 550 + ...t-mtk_eth_soc-increase-MAX_DEVS-to-3.patch | 29 + ...eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch} | 109 +- ...eth_soc-add-NETSYS_V3-version-suppo.patch} | 177 +- ...eth_soc-convert-caps-in-mtk_soc_dat.patch} | 26 +- ..._eth_soc-convert-clock-bitmap-to-u64.patch | 132 + ..._eth_soc-add-basic-support-for-MT798.patch | 477 + ..._eth_soc-enable-page_pool-support-fo.patch | 27 + ..._eth_soc-enable-nft-hw-flowtable_off.patch | 135 + ..._eth_soc-support-per-flow-accounting.patch | 78 + ..._eth_soc-fix-NULL-pointer-on-hw-rese.patch | 52 + ..._eth_soc-fix-register-definitions-fo.patch | 44 + ...tk_eth_soc-add-reset-bits-for-MT7988.patch | 188 + ..._eth_soc-add-support-for-in-SoC-SRAM.patch | 254 + ..._eth_soc-support-36-bit-DMA-addressi.patch | 166 + ...l_mutex-when-calling-dsa_master_-set.patch | 6 +- ...t-up-shared-ports-then-non-shared-po.patch | 8 +- ...xt-net-dsa-setup-master-before-ports.patch | 10 +- ...switch-operations-for-tracking-the-m.patch | 4 +- ...aster-state-events-in-dsa_tree_-setu.patch | 4 +- ...eck-correct-variable-in-qca8k_phy_et.patch | 28 + ...dsa-qca8k-fix-noderef.cocci-warnings.patch | 34 + ...8k-drop-MTU-tracking-from-qca8k_priv.patch | 79 + ...-qca8k-drop-port_sts-from-qca8k_priv.patch | 116 + ...8k-rework-and-simplify-mdiobus-logic.patch | 173 + ...-drop-dsa_switch_ops-from-qca8k_priv.patch | 39 + ...a8k-correctly-handle-mdio-read-error.patch | 33 + ...ify-bus-id-naming-with-legacy-and-OF.patch | 44 + ...net-dsa-qca8k-move-driver-to-qca-dir.patch | 7389 +++++++ ...-cache-match-data-to-speed-up-access.patch | 157 + ...k-make-mib-autocast-feature-optional.patch | 77 + ...qca8k-move-mib-struct-to-common-code.patch | 6532 ++++++ ...ve-qca8k-read-write-rmw-and-reg-tabl.patch | 135 + ...ve-qca8k-bulk-read-write-helper-to-c.patch | 145 + ...ove-mib-init-function-to-common-code.patch | 137 + ...ve-port-set-status-eee-ethtool-stats.patch | 281 + ...move-bridge-functions-to-common-code.patch | 237 + ...ve-set-age-MTU-port-enable-disable-f.patch | 227 + ...ve-port-FDB-MDB-function-to-common-c.patch | 704 + ...ve-port-mirror-functions-to-common-c.patch | 232 + ...ve-port-VLAN-functions-to-common-cod.patch | 448 + ...ve-port-LAG-functions-to-common-code.patch | 384 + ...ve-read_switch_id-function-to-common.patch | 102 + ...x-NULL-pointer-dereference-for-of_de.patch | 29 + ...-add-support-for-in-band-link-status.patch | 14 +- ...t-dsa-mt7530-use-external-PCS-driver.patch | 24 +- ...a-mt7530-refactor-SGMII-PCS-creation.patch | 4 +- ...mt7530-use-unlocked-regmap-accessors.patch | 6 +- ...se-regmap-to-access-switch-register-.patch | 14 +- ...ove-SGMII-PCS-creation-to-mt7530_pro.patch | 6 +- ...t-dsa-mt7530-introduce-mutex-helpers.patch | 28 +- ...ove-p5_intf_modes-function-to-mt7530.patch | 4 +- ...ntroduce-mt7530_probe_common-helper-.patch | 6 +- ...ntroduce-mt7530_remove_common-helper.patch | 4 +- ...t7530-introduce-separate-MDIO-driver.patch | 18 +- ...ntroduce-driver-for-MT7988-built-in-.patch | 26 +- ...-dsa-mt7530-fix-support-for-MT7531BE.patch | 8 +- ...ble-PCS-polling-over-major-configura.patch | 81 + ...NULL-pl-pcs-dereference-during-phyli.patch | 38 + ...k-add-pcs_enable-pcs_disable-methods.patch | 172 + ...t-pcs-lynxi-implement-pcs_disable-op.patch | 44 + ...net-usb-ax88179_178a-add-TSO-feature.patch | 4 +- ...it_default_state_get-to-the-global-h.patch | 39 + ...a8k-move-qca8k_port_to_phy-to-header.patch | 67 + ...net-dsa-qca8k-add-LEDs-basic-support.patch | 435 + ...dsa-qca8k-add-LEDs-blink_set-support.patch | 74 + ...bs-for-when-CLASS_LED-NEW_LEDS-are-d.patch | 59 + ...5-net-phy-Add-a-binding-for-PHY-LEDs.patch | 191 + ...ce-Call-into-the-PHY-driver-to-set-L.patch | 97 + ...ell-Add-software-control-of-the-LEDs.patch | 112 + ...ce-Call-into-the-PHY-driver-to-set-L.patch | 73 + ...-phy-marvell-Implement-led_blink_set.patch | 104 + ...Fix-inconsistent-indenting-in-led_bl.patch | 38 + ...dev-Drop-NETDEV_LED_MODE_LINKUP-from.patch | 87 + ...dev-Rename-add-namespace-to-netdev-t.patch | 149 + ...-netdev-Convert-device-attr-to-macro.patch | 82 + ...etdev-Use-mutex-instead-of-spinlocks.patch | 106 + ...01-leds-add-APIs-for-LEDs-hw-control.patch | 74 + ...get-attached-device-for-LED-hw-contr.patch | 37 + ...ds-leds-class-Document-new-Hardware-.patch | 113 + ...dev-refactor-code-setting-device-nam.patch | 69 + ...dev-introduce-check-for-possible-hw-.patch | 54 + ...dev-add-basic-check-for-hw-control-s.patch | 42 + ...dev-reject-interval-store-for-hw_con.patch | 28 + ...etdev-add-support-for-LED-hw-control.patch | 107 + ...er-netdev-validate-configured-netdev.patch | 58 + ...dev-init-mode-if-hw-control-already-.patch | 53 + ...dev-expose-netdev-trigger-modes-in-l.patch | 54 + ...t-dsa-qca8k-implement-hw_control-ops.patch | 200 + ...dsa-qca8k-add-op-to-get-ports-netdev.patch | 70 + ...Support-public-address-configuration.patch | 4 +- ...Fix-application-of-sizeof-to-pointer.patch | 2 +- ...Add-a-new-PID-VID-13d3-3567-for-MT79.patch | 2 +- ...Add-a-new-PID-VID-0489-e0c8-for-MT79.patch | 2 +- ...Add-a-new-VID-PID-0e8d-0608-for-MT79.patch | 2 +- ...spinand-winbond-fix-flash-detection.patch} | 0 ....2-mtd-spinand-winbond-add-W25N02KV.patch} | 0 ...xxx-Split-monitor-port-configuration.patch | 2 +- ...e6xxx-Add-support-for-port-mirroring.patch | 8 +- ...x-fix-broken-if-statement-because-of.patch | 2 +- ...the-dst-buffer-to-of_get_mac_address.patch | 12 +- ..._eth_soc-compile-out-netsys-v2-code-.patch | 28 - ..._eth_soc-fix-VLAN-rx-hardware-accele.patch | 2 +- ...ii-ensure-the-SGMII-PHY-is-powered-d.patch | 2 +- ...t-mtk_eth_soc-add-support-for-MT7981.patch | 10 +- ..._eth_soc-switch-to-external-PCS-driv.patch | 8 +- ...eth_soc-ppe-add-support-for-flow-ac.patch} | 99 +- ...atek-fix-ppe-flow-accounting-for-v1.patch} | 19 +- ...eth_soc-drop-generic-vlan-rx-offloa.patch} | 0 ..._eth_soc-always-mtk_get_ib1_pkt_type.patch | 31 + ..._ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch | 78 + ..._eth_soc-remove-incorrect-PLL-config.patch | 141 + ..._eth_soc-remove-mac_pcs_get_state-an.patch | 81 + ..._eth_soc-add-version-in-mtk_soc_data.patch | 550 + ...t-mtk_eth_soc-increase-MAX_DEVS-to-3.patch | 29 + ...eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch} | 109 +- ...eth_soc-add-NETSYS_V3-version-suppo.patch} | 177 +- ...eth_soc-convert-caps-in-mtk_soc_dat.patch} | 26 +- ..._eth_soc-convert-clock-bitmap-to-u64.patch | 132 + ..._eth_soc-add-basic-support-for-MT798.patch | 477 + ..._eth_soc-enable-page_pool-support-fo.patch | 27 + ..._eth_soc-enable-nft-hw-flowtable_off.patch | 135 + ..._eth_soc-support-per-flow-accounting.patch | 78 + ..._eth_soc-fix-NULL-pointer-on-hw-rese.patch | 52 + ..._eth_soc-fix-register-definitions-fo.patch | 44 + ...tk_eth_soc-add-reset-bits-for-MT7988.patch | 188 + ..._eth_soc-add-support-for-in-SoC-SRAM.patch | 254 + ..._eth_soc-support-36-bit-DMA-addressi.patch | 166 + ...ntroduce-driver-for-MT7988-built-in-.patch | 4 +- ...k-add-pcs_enable-pcs_disable-methods.patch | 172 + ...t-pcs-lynxi-implement-pcs_disable-op.patch | 44 + ...it_default_state_get-to-the-global-h.patch | 39 + ...a8k-move-qca8k_port_to_phy-to-header.patch | 67 + ...net-dsa-qca8k-add-LEDs-basic-support.patch | 435 + ...dsa-qca8k-add-LEDs-blink_set-support.patch | 74 + ...bs-for-when-CLASS_LED-NEW_LEDS-are-d.patch | 59 + ...5-net-phy-Add-a-binding-for-PHY-LEDs.patch | 191 + ...ce-Call-into-the-PHY-driver-to-set-L.patch | 97 + ...ell-Add-software-control-of-the-LEDs.patch | 112 + ...ce-Call-into-the-PHY-driver-to-set-L.patch | 73 + ...-phy-marvell-Implement-led_blink_set.patch | 104 + ...Fix-inconsistent-indenting-in-led_bl.patch | 38 + ...dev-Drop-NETDEV_LED_MODE_LINKUP-from.patch | 87 + ...dev-Rename-add-namespace-to-netdev-t.patch | 149 + ...-netdev-Convert-device-attr-to-macro.patch | 82 + ...etdev-Use-mutex-instead-of-spinlocks.patch | 106 + ...01-leds-add-APIs-for-LEDs-hw-control.patch | 74 + ...get-attached-device-for-LED-hw-contr.patch | 37 + ...ds-leds-class-Document-new-Hardware-.patch | 113 + ...dev-refactor-code-setting-device-nam.patch | 69 + ...dev-introduce-check-for-possible-hw-.patch | 54 + ...dev-add-basic-check-for-hw-control-s.patch | 42 + ...dev-reject-interval-store-for-hw_con.patch | 28 + ...etdev-add-support-for-LED-hw-control.patch | 107 + ...er-netdev-validate-configured-netdev.patch | 58 + ...dev-init-mode-if-hw-control-already-.patch | 53 + ...dev-expose-netdev-trigger-modes-in-l.patch | 54 + ...t-dsa-qca8k-implement-hw_control-ops.patch | 200 + ...dsa-qca8k-add-op-to-get-ports-netdev.patch | 70 + ...dev-add-additional-specific-link-spe.patch | 242 + ...dev-add-additional-specific-link-dup.patch | 138 + ...dev-expose-hw_control-status-via-sys.patch | 45 + ...fix-circular-LEDS_CLASS-dependencies.patch | 65 + ...net-phy-Fix-reading-LED-reg-property.patch | 43 + ...emove-LEDs-to-ensure-correct-orderin.patch | 67 + ...dev-Remove-NULL-check-before-dev_-pu.patch | 44 + ...dev-uninitialized-variable-in-netdev.patch | 31 + ...netdev-Fix-requesting-offload-device.patch | 57 + ...ce-Call-into-the-PHY-driver-to-set-L.patch | 149 + ...Add-support-for-offloading-LED-blink.patch | 344 + ...-Disable-offload-on-deactivation-of-.patch | 31 + target/linux/generic/config-5.10 | 4 +- target/linux/generic/config-5.15 | 1 + target/linux/generic/config-5.4 | 14 +- .../generic/hack-5.10/204-module_strip.patch | 4 +- .../721-net-add-packet-mangeling.patch | 10 +- .../generic/hack-5.10/902-debloat_proc.patch | 4 +- ...-linux-kernel-to-support-shortcut-fe.patch | 4 +- .../hack-5.15/250-netfilter_depends.patch | 2 +- ...rans-call-add-disks-after-mtd-device.patch | 2 +- .../hack-5.15/600-bridge_offload.patch | 6 +- ...of_net-add-mac-address-ascii-support.patch | 4 +- .../640-bridge-only-accept-EAP-locally.patch | 4 +- ...-netfilter-add-xt_FLOWOFFLOAD-target.patch | 4 +- .../700-swconfig_switch_drivers.patch | 2 +- ...-dsa-mv88e6xxx-disable-ATU-violation.patch | 2 +- .../721-net-add-packet-mangeling.patch | 4 +- .../780-usb-net-MeigLink_modem_support.patch | 4 +- .../795-backport-phylink_pcs-helpers.patch | 8 +- .../generic/hack-5.15/902-debloat_proc.patch | 2 +- ...-linux-kernel-to-support-shortcut-fe.patch | 2 +- .../550-loop-Report-EOPNOTSUPP-properly.patch | 4 +- .../generic/hack-5.4/721-phy_packets.patch | 4 +- .../generic/hack-5.4/902-debloat_proc.patch | 2 +- .../995-usb-serial-option-add-ec200a.patch | 4 +- .../700-swconfig_switch_drivers.patch | 2 +- ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 2 +- ...etfilter_match_bypass_default_checks.patch | 2 +- .../pending-5.10/630-packet_socket_type.patch | 6 +- .../pending-5.10/655-increase_skb_pad.patch | 2 +- ...ng-with-source-address-failed-policy.patch | 26 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 29 +- ...ek-mt7622-add-support-for-coherent-D.patch | 30 - ...ek-mt7622-introduce-nodes-for-Wirele.patch | 62 - ...pool-and-page-referenced-frags-in-GR.patch | 2 +- .../810-pci_disable_common_quirks.patch | 8 +- .../pending-5.10/920-mangle_bootargs.patch | 2 +- ...ge_allow_receiption_on_disabled_port.patch | 4 +- ...-mtd-core-add-get_mtd_device_by_node.patch | 2 +- .../pending-5.15/630-packet_socket_type.patch | 6 +- .../pending-5.15/655-increase_skb_pad.patch | 2 +- ...ng-with-source-address-failed-policy.patch | 26 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 27 +- ...ow_offload-handle-netdevice-events-f.patch | 32 +- ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 6 +- ...detach-callback-to-struct-phy_driver.patch | 4 +- ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 2 +- ...e-all-MACs-are-powered-down-before-r.patch | 11 +- ..._eth_soc-compile-out-netsys-v2-code-.patch | 44 + ..._eth_soc-work-around-issue-with-send.patch | 12 +- ...rnet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch | 2 +- ..._eth_soc-fix-remaining-throughput-re.patch | 4 +- ..._eth_soc-ppe-fix-L2-offloading-with-.patch | 2 +- ..._eth_soc-add-code-for-offloading-flo.patch | 6 +- ...iatek-mtk_ppe-prefer-newly-added-l2-.patch | 2 +- ..._eth_soc-improve-keeping-track-of-of.patch | 22 +- ...iatek-fix-ppe-flow-accounting-for-L2.patch | 57 +- ..._eth_soc-add-MTK_NETSYS_V1-capabilit.patch | 223 - ..._eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch | 181 - ...k_eth_soc-add-support-for-MT7988-SoC.patch | 495 - ..._eth_soc-add-paths-and-SerDes-modes-.patch | 1867 -- ..._eth_soc-add-paths-and-SerDes-modes-.patch | 1604 ++ ...pool-and-page-referenced-frags-in-GR.patch | 2 +- ...ional-threading-for-backlog-processi.patch | 4 +- ...760-net-dsa-mv88e6xxx-fix-vlan-setup.patch | 2 +- ...equest-assisted-learning-on-CPU-port.patch | 2 +- ...gister-OF-node-for-internal-MDIO-bus.patch | 4 +- ...rack-busclk-state-to-avoid-bus-error.patch | 61 + .../901-usb-add-more-modem-support.patch | 25 +- .../pending-5.15/920-mangle_bootargs.patch | 2 +- ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 2 +- .../pending-5.4/630-packet_socket_type.patch | 6 +- ...w_table-add-hardware-offload-support.patch | 6 +- .../pending-5.4/655-increase_skb_pad.patch | 2 +- ...ng-with-source-address-failed-policy.patch | 26 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 17 +- ...equest-assisted-learning-on-CPU-port.patch | 2 +- ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 2 +- ...detach-callback-to-struct-phy_driver.patch | 4 +- ..._eth_soc-compile-out-netsys-v2-code-.patch | 44 + ..._eth_soc-work-around-issue-with-send.patch | 12 +- ...rnet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch | 2 +- ..._eth_soc-fix-remaining-throughput-re.patch | 4 +- ..._eth_soc-ppe-fix-L2-offloading-with-.patch | 2 +- ..._eth_soc-add-code-for-offloading-flo.patch | 11 +- ...iatek-mtk_ppe-prefer-newly-added-l2-.patch | 2 +- ..._eth_soc-improve-keeping-track-of-of.patch | 25 +- ...iatek-fix-ppe-flow-accounting-for-L2.patch | 55 +- ..._eth_soc-add-MTK_NETSYS_V1-capabilit.patch | 223 - ..._eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch | 181 - ...k_eth_soc-add-support-for-MT7988-SoC.patch | 495 - ..._eth_soc-add-paths-and-SerDes-modes-.patch | 1867 -- ..._eth_soc-add-paths-and-SerDes-modes-.patch | 1604 ++ ...rack-busclk-state-to-avoid-bus-error.patch | 61 + ...Mangle-bootloader-s-kernel-arguments.patch | 2 +- ...-nvmem-Introduce-cpufreq-for-ipq95xx.patch | 2 +- .../0001-MIPS-lantiq-add-pcie-driver.patch | 2 +- ...02-phy-Add-2.5G-SGMII-interface-mode.patch | 4 +- target/linux/meson/image/Makefile | 57 - .../cortexa72/base-files/etc/board.d/01_leds | 2 + .../base-files/etc/board.d/02_network | 2 + .../base-files/lib/upgrade/emmc-puzzle.sh | 2 + .../base-files/lib/upgrade/platform.sh | 6 + .../arm64/boot/dts/marvell/cn9131-db-A.dts | 404 + .../boot/dts/marvell/cn9131-puzzle-m901.dts | 1 + .../arm64/boot/dts/marvell/cn9132-db-A.dts | 565 + .../boot/dts/marvell/cn9132-puzzle-m902.dts | 1 + target/linux/mvebu/image/Makefile | 10 + target/linux/mvebu/image/cortexa72.mk | 12 + ...Mangle-bootloader-s-kernel-arguments.patch | 2 +- ...Mangle-bootloader-s-kernel-arguments.patch | 4 +- ...r-Gateworks-PLX-PEX860x-switch-with-.patch | 2 +- ...Mangle-bootloader-s-kernel-arguments.patch | 2 +- .../001-add-phytium-support.patch | 18 +- target/linux/qualcommax/Makefile | 8 +- .../base-files/lib/upgrade/mmc.sh | 0 .../arm64/boot/dts/qcom/ipq6000-360v6.dts | 7 +- .../arch/arm64/boot/dts/qcom/ipq6000-ax18.dts | 2 +- .../arm64/boot/dts/qcom/ipq6000-gl-ax1800.dts | 4 + .../boot/dts/qcom/ipq6000-gl-axt1800.dts | 4 + .../arm64/boot/dts/qcom/ipq6000-glinet.dtsi | 2 +- .../arm64/boot/dts/qcom/ipq6000-mr7350.dts | 4 +- .../arm64/boot/dts/qcom/ipq6000-re-ss-01.dts | 217 + .../arm64/boot/dts/qcom/ipq6000-xiaomi.dtsi | 3 +- .../arm64/boot/dts/qcom/ipq6010-re-cs-02.dts | 276 + .../arch/arm64/boot/dts/qcom/ipq6018-nss.dtsi | 192 + .../arm64/boot/dts/qcom/ipq8070-cax1800.dts | 1 + .../arm64/boot/dts/qcom/ipq8070-rm2-6.dts | 1 + .../arm64/boot/dts/qcom/ipq8071-ax3600.dtsi | 1 + .../arm64/boot/dts/qcom/ipq8071-eap102.dts | 1 + .../arm64/boot/dts/qcom/ipq8071-mf269.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-301w.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-aw1000.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-ax9000.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8072-haze.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wax218.dts | 2 +- .../arm64/boot/dts/qcom/ipq8072-wax620.dts | 1 + .../arm64/boot/dts/qcom/ipq8072-wpq873.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts | 1 + .../arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi | 271 + .../arm64/boot/dts/qcom/ipq8074-rax120v2.dts | 1 + .../arm64/boot/dts/qcom/ipq8074-wax630.dts | 1 + .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 1 + .../netfilter/nf_conntrack_dscpremark_ext.h | 95 + .../include/uapi/linux/tc_act/tc_nss_mirred.h | 36 + .../netfilter/nf_conntrack_dscpremark_ext.c | 61 + target/linux/qualcommax/image/ipq60xx.mk | 32 +- .../ipq60xx/base-files/etc/board.d/02_network | 2 + .../etc/hotplug.d/firmware/11-ath11k-caldata | 12 +- .../base-files/lib/preinit/81_fix_eeprom | 19 + .../base-files/lib/upgrade/platform.sh | 12 +- target/linux/qualcommax/ipq60xx/target.mk | 2 +- target/linux/qualcommax/ipq807x/target.mk | 2 +- ...-qcom-ipq8074-convert-to-parent-data.patch | 436 +- ...pq8074-add-missing-networking-resets.patch | 2 +- ...074-populate-fw_name-for-all-parents.patch | 20 +- ...om-Add-support-for-IPQ8074-Gen3-port.patch | 2 +- ...q8074-populate-fw_name-for-usb3phy-s.patch | 4 +- ...q-qcom-nvmem-add-support-for-IPQ6018.patch | 8 +- ...q-qcom-nvmem-add-support-for-IPQ8074.patch | 8 +- ...pq6018-Use-floor-ops-for-sdcc-clocks.patch | 2 +- ...lk-qcom-gcc-ipq6018-update-UBI32-PLL.patch | 2 +- ...pq6018-remove-duplicate-initializers.patch | 2 +- ...-qcom-gcc-ipq6018-add-QUP6-I2C-clock.patch | 4 +- ...8074-rework-nss_port5-6-clock-to-mul.patch | 8 +- ...ts-ipq8074-add-reserved-memory-nodes.patch | 2 +- .../0118-clk-qcom-Add-WCSSAON-reset.patch | 2 +- ...ts-ipq6018-add-reserved-memory-nodes.patch | 7 +- ...dts-qcom-ipq6018-add-LDOA2-regulator.patch | 15 - ...4-dts-qcom-ipq6018-enable-sdhci-node.patch | 2 +- ...4-dts-qcom-ipq6018-add-thermal-nodes.patch | 4 +- ...rm64-dts-qcom-ipq6018-rework-cpufreq.patch | 218 +- .../0139-clk-ipq6018-Add-missing-clocks.patch | 20 +- .../0600-1-qca-nss-ecm-support-CORE.patch | 781 + ...-2-qca-nss-ecm-support-PPPOE-offload.patch | 588 + ...00-3-qca-nss-ecm-support-net-bonding.patch | 81 + ...nss-ecm-support-net-bonding-over-LAG.patch | 668 + .../0600-5-qca-nss-ecm-support-macvlan.patch | 96 + ...nss-ecm-support-netfilter-DSCPREMARK.patch | 69 + ...-qca-nss-ecm-add-missing-net-defines.patch | 35 + ...00-8-qca-nss-ecm-support-MLO-bonding.patch | 536 + .../0601-qca-add-nss-bridge-mgr-support.patch | 94 + .../0602-qca-nss-drv-add-qdisc-support.patch | 44 + ...-1-qca-nss-clients-add-qdisc-support.patch | 444 + ...3-2-qca-nss-clients-add-l2tp-support.patch | 46 + ...3-3-qca-nss-clients-add-PPTP-support.patch | 478 + ...qca-nss-clients-add-iptunnel-support.patch | 77 + ...-5-qca-nss-clients-add-vxlan-support.patch | 103 + ...-clients-add-l2tp-offloading-support.patch | 368 + ...a-nss-clients-iptunnel-lock-this-cpu.patch | 22 + ...-qca-nss-clients-add-tls-mgr-support.patch | 24 + .../0605-qca-nss-cfi-support.patch | 111 + ...l-pointer-dereference-in-ipv6-output.patch | 80 + .../ramips/dts/mt7621_glinet_gl-mt1300.dts | 4 +- .../ramips/dts/mt7621_h3c_tx1800-plus.dts | 8 + .../ramips/dts/mt7621_h3c_tx1801-plus.dts | 8 + target/linux/ramips/dts/mt7621_h3c_tx1806.dts | 8 + .../linux/ramips/dts/mt7621_h3c_tx180x.dtsi | 170 + .../ramips/dts/mt7621_jdcloud_re-cp-02.dts | 160 + .../linux/ramips/dts/mt7621_leigod_a7000.dts | 10 +- .../dts/mt7621_mediatek_ap-mt7621a-v60.dts | 25 +- .../linux/ramips/dts/mt7621_openfi_5pro.dts | 153 + target/linux/ramips/image/mt7621.mk | 67 +- .../mt7621/base-files/etc/board.d/02_network | 12 + .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 7 + .../mt7621/base-files/etc/init.d/bootcount | 3 + .../mt7621/base-files/lib/upgrade/platform.sh | 6 +- ...hnat-fix-pskb-expand-head-limitation.patch | 4 +- ...ethernet-mediatek-support-net-labels.patch | 4 +- ...y-simplify-phy_link_change-arguments.patch | 6 +- .../721-NET-no-auto-carrier-off-support.patch | 2 +- .../patches-5.4/993-spi-nor-w25q512jv.patch | 25 + ...e-unmatched-update-regulators-values.patch | 4 +- target/linux/sunxi/Makefile | 5 +- target/linux/sunxi/arm926ejs/config-6.1 | 54 + target/linux/sunxi/arm926ejs/target.mk | 11 + .../sunxi/base-files/etc/board.d/02_network | 2 +- target/linux/sunxi/config-6.1 | 2 - target/linux/sunxi/config-6.6 | 526 + target/linux/sunxi/cortexa53/config-6.1 | 1 + target/linux/sunxi/cortexa53/config-6.6 | 108 + target/linux/sunxi/cortexa53/target.mk | 1 + target/linux/sunxi/cortexa7/config-6.1 | 2 + target/linux/sunxi/cortexa7/config-6.6 | 28 + target/linux/sunxi/cortexa7/target.mk | 1 + target/linux/sunxi/cortexa8/config-6.1 | 2 + target/linux/sunxi/cortexa8/config-6.6 | 12 + target/linux/sunxi/cortexa8/target.mk | 1 + target/linux/sunxi/image/Makefile | 5 +- target/linux/sunxi/image/arm926ejs.mk | 24 + target/linux/sunxi/image/cortexa53.mk | 14 + target/linux/sunxi/image/cortexa7.mk | 2 + target/linux/sunxi/image/cortexa8.mk | 4 +- ...inner-h616-Split-Orange-Pi-Zero-2-DT.patch | 305 + ...inner-h616-Add-OrangePi-Zero-3-board.patch | 140 + ...inner-h616-update-emac-for-Orange-Pi.patch | 36 + ...lwinner-h616-Add-SID-controller-node.patch | 31 + ...am-export-register-0-for-THS-on-H616.patch | 98 + ...-Add-D1-T113s-THS-controller-support.patch | 47 + ...8i-Explain-unknown-H6-register-value.patch | 79 + ...i-Extend-H6-calibration-to-support-4.patch | 74 + ...-sun8i-Add-SRAM-register-access-code.patch | 126 + ...-Add-support-for-H616-THS-controller.patch | 50 + ...Dont-fail-probe-due-to-zone-registra.patch | 68 + ...er-h616-Add-thermal-sensor-and-zones.patch | 138 + ...-get_soc_chipid-and-sunxi_get_serial.patch | 53 + ...s-suniv-add-USB-related-device-nodes.patch | 35 + ...iv-add-device-tree-for-PopStick-v1_1.patch | 123 + ...M-dts-suniv-licheepi-nano-enable-USB.patch | 55 + .../patches-6.1/463-f1c100s-sram-driver.patch | 33 + .../464-f1c100s-watchdog-compat.patch | 18 + ...16-Add-cpu-frequency-scaling-support.patch | 270 + ...arm64-dts-allwinner-h616-Add-cpufreq.patch | 53 + ...lwinner-h616-Add-SID-controller-node.patch | 31 + ...am-export-register-0-for-THS-on-H616.patch | 98 + ...-Add-D1-T113s-THS-controller-support.patch | 47 + ...8i-Explain-unknown-H6-register-value.patch | 79 + ...i-Extend-H6-calibration-to-support-4.patch | 74 + ...-sun8i-Add-SRAM-register-access-code.patch | 126 + ...-Add-support-for-H616-THS-controller.patch | 50 + ...Dont-fail-probe-due-to-zone-registra.patch | 68 + ...er-h616-Add-thermal-sensor-and-zones.patch | 138 + ...OF-node-for-USB-eth-on-NanoPi-R1S-H5.patch | 16 + ...angepi_pc2_usb_otg_to_host_key_power.patch | 20 + ...a64-sopine-Add-Sopine-flash-partitio.patch | 46 + .../410-sunxi-add-bananapi-p2-zero.patch | 292 + ...ner-a64-olinuxino-add-status-LED-ali.patch | 32 + ...m64-dts-orangepi-one-plus-enable-PWM.patch | 10 + ...m64-dts-enable-wifi-on-pine64-boards.patch | 72 + ...16-Add-cpu-frequency-scaling-support.patch | 270 + ...arm64-dts-allwinner-h616-Add-cpufreq.patch | 53 + target/linux/x86/64/config-6.6 | 1 + target/linux/x86/Makefile | 2 +- target/linux/x86/config-5.10 | 4 +- target/linux/x86/config-5.15 | 2 +- target/linux/x86/config-5.4 | 4 +- target/linux/x86/config-6.1 | 7 +- target/linux/x86/config-6.6 | 14 +- target/linux/x86/generic/config-6.6 | 1 + target/linux/x86/legacy/config-6.6 | 1 + ...to-enable-disable-tcp_collapse-logic.patch | 2 +- ...to-enable-disable-tcp_collapse-logic.patch | 2 +- toolchain/gcc/Config.version | 2 +- toolchain/gcc/common.mk | 4 +- .../300-mips_Os_cpu_rtx_cost_model.patch | 2 +- .../970-macos_arm64-building-fix.patch | 2 +- ...-add-renameat2-linux-syscall-wrapper.patch | 61 + .../001-fix_ax_c_float_words_bigendian.patch | 90 + tools/automake/Makefile | 27 +- tools/automake/patches/000-relocatable.patch | 80 +- ...clocal-skip-not-existing-directories.patch | 2 +- .../patches/101-do-not-require-files.patch | 29 + .../200-other-V-values-for-verbosity.patch | 59 + tools/b43-tools/Makefile | 2 +- tools/coreutils/Makefile | 4 +- tools/cpio/Makefile | 4 +- .../patches/001-duplicate-program-name.patch | 18 - tools/cpio/patches/010-clang.patch | 11 - tools/xz/Makefile | 4 +- 1330 files changed, 84370 insertions(+), 147598 deletions(-) create mode 100644 package/boot/arm-trusted-firmware-mediatek/patches/0001-mediatek-snfi-FM35Q1GA-is-x4-only.patch create mode 100644 package/boot/arm-trusted-firmware-mediatek/patches/0002-mediatek-snfi-adjust-pin-drive-strength-for-Fidelix-.patch create mode 100644 package/boot/arm-trusted-firmware-mediatek/patches/0003-mediatek-snfi-adjust-drive-strength-to-12mA-like-old.patch create mode 100644 package/boot/uboot-amlogic/Makefile delete mode 100644 package/firmware/ath11k-wifi/Makefile delete mode 100644 package/firmware/ath11k-wifi/board-2.bin.IPQ6018 delete mode 100644 package/firmware/ath11k-wifi/board-edgecore-eap102.bin.IPQ8074 delete mode 100644 package/firmware/ath11k-wifi/board-gl-ax1800.bin.IPQ6018 delete mode 100644 package/firmware/ath11k-wifi/board-gl-axt1800.bin.IPQ6018 delete mode 100644 package/firmware/ath11k-wifi/qdss_trace_config.bin delete mode 100755 package/firmware/b43legacy-firmware/Makefile create mode 100644 package/firmware/cypress-nvram/files/brcmfmac4339-sdio.AP6335.txt delete mode 100644 package/firmware/ipq-wifi/board-8dev_habanero-dvk.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-asus_rt-acrh17.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-avm_fritzrepeater-1200.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca9984 delete mode 100644 package/firmware/ipq-wifi/board-cellc_rtl30vw.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-century_wr142ac.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-devolo_magic-2-wifi-next.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-dlink_dap2610.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-edgecore_ecw5410.qca9984 delete mode 100644 package/firmware/ipq-wifi/board-edgecore_oap100.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-engenius_eap2200.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-engenius_eap2200.qca9888 delete mode 100644 package/firmware/ipq-wifi/board-engenius_emd1.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-engenius_emr3500.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-ezviz_cs-w3-wd1200g-eup.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-glinet_gl-a1300.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-glinet_gl-ap1300.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-glinet_gl-s1300.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-hiwifi_c526a.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-linksys_ea8300.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-linksys_ea8300.qca9888 delete mode 100644 package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca9888 delete mode 100644 package/firmware/ipq-wifi/board-luma_wrtq-329acn.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-mikrotik_hap-ac2.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-mikrotik_sxtsq-5-ac.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-mobipromo_cm520-79f.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-nec_wg2600hp3.qca9984 delete mode 100644 package/firmware/ipq-wifi/board-netgear_sxr80.ipq8074 delete mode 100644 package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-plasmacloud_pa1200.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-plasmacloud_pa2200.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-plasmacloud_pa2200.qca9888 delete mode 100644 package/firmware/ipq-wifi/board-qnap_301w.ipq8074 delete mode 100644 package/firmware/ipq-wifi/board-qxwlan_e2600ac.qca4019 delete mode 100644 package/firmware/ipq-wifi/board-redmi_ax6.ipq8074 delete mode 100755 package/firmware/ipq-wifi/board-tplink_xtr10890.ipq8074 delete mode 100644 package/firmware/ipq-wifi/board-xiaomi_ax3600.ipq8074 delete mode 100644 package/firmware/ipq-wifi/board-xiaomi_ax3600.qca9889 delete mode 100644 package/firmware/ipq-wifi/board-xiaomi_ax9000.ipq8074 delete mode 100755 package/firmware/ipq-wifi/board-zte_mf263.qca4019 delete mode 100755 package/firmware/ipq-wifi/board-zte_mf269.ipq8074 create mode 100644 package/firmware/ipq-wifi/src/board-jdcloud_ax1800pro.ipq6018 create mode 100644 package/firmware/ipq-wifi/src/board-jdcloud_ax6600.ipq6018 create mode 100644 package/firmware/ipq-wifi/src/board-qihoo_360v6.ipq6018 create mode 100644 package/firmware/ipq-wifi/src/board-redmi_ax5-jdcloud.ipq6018 create mode 100644 package/firmware/ipq-wifi/src/board-xiaomi_rm1800.ipq6018 rename package/firmware/{ath11k-wifi/board-qihoo_360v6.bin.IPQ6018 => ipq-wifi/src/board-zn_m2.ipq6018} (86%) create mode 100644 package/firmware/linux-firmware/airoha.mk mode change 100644 => 100755 package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.bin mode change 100644 => 100755 package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.txt delete mode 100644 package/firmware/linux-firmware/brcm_firmware/ap6356s/brcmfmac4356-sdio.rongpin,king3399.bin delete mode 100644 package/firmware/linux-firmware/brcm_firmware/ap6356s/brcmfmac4356-sdio.rongpin,king3399.txt create mode 100644 package/firmware/linux-firmware/mellanox.mk create mode 100644 package/firmware/photonicat-firmware/Makefile create mode 100644 package/firmware/photonicat-firmware/files/board.bin create mode 100644 package/firmware/photonicat-firmware/files/firmware-sdio-5.bin create mode 100644 package/kernel/mac80211/patches/ath10k/911-ath10k-disable-caldata-prefetch-for-sdio-bus.patch create mode 100644 package/kernel/mac80211/patches/ath10k/985-ath10k-allow-vht-on-2g.patch create mode 100644 package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0085-wifi-ath11k-fix-memory-leak-in-WMI-firmware-stats.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0086-wifi-ath11k-Add-missing-check-for-ioremap.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0087-wifi-ath11k-Add-missing-ops-config-for-IPQ5018-in.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0088-wifi-ath11k-Restart-firmware-after-cold-boot-calibration.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0089-wifi-ath11k-Add-missing-hw_ops-get_ring_selector-for.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0090-Revert-wifi-ath11k-Enable-threaded-NAPI.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0091-wifi-ath11k-Split-coldboot-calibration-hw_param.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0092-wifi-ath11k-Add-coldboot-calibration-support-for-QCN.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0093-wifi-ath11k-Remove-cal_done-check-during-probe.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0094-wifi-ath11k-mhi-add-a-warning-message-for-MHI_CB_EE.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0095-wifi-ath11k-add-chip-id-board-name-while-searching-b.patch create mode 100644 package/kernel/mac80211/patches/ath11k/0096-wifi-ath11k-fix-boot-failure-with-one-MSI-vector.patch create mode 100644 package/kernel/mac80211/patches/ath11k/906-ath11k-Disable-coldboot-calibration-for-IPQ6018.patch create mode 100644 package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch create mode 100644 package/kernel/mac80211/patches/build/050-lib80211_option.patch create mode 100644 package/kernel/mac80211/patches/build/099-netlink-range.patch create mode 100644 package/kernel/mac80211/patches/build/990-add_kernel_6.6_support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/001-wifi-rtw88-fix-race-condition-when-doing-H2C-command.patch delete mode 100644 package/kernel/mac80211/patches/rtl/002-wifi-rtw88-8821c-enable-BT-device-recovery-mechanism.patch delete mode 100644 package/kernel/mac80211/patches/rtl/003-wifi-rtw88-print-firmware-type-in-info-message.patch delete mode 100644 package/kernel/mac80211/patches/rtl/004-wifi-rtw88-Call-rtw_fw_beacon_filter_config-with-rtw.patch delete mode 100644 package/kernel/mac80211/patches/rtl/005-wifi-rtw88-Drop-rf_lock.patch delete mode 100644 package/kernel/mac80211/patches/rtl/006-wifi-rtw88-Drop-h2c.lock.patch delete mode 100644 package/kernel/mac80211/patches/rtl/007-wifi-rtw88-Drop-coex-mutex.patch delete mode 100644 package/kernel/mac80211/patches/rtl/008-wifi-rtw88-iterate-over-vif-sta-list-non-atomically.patch delete mode 100644 package/kernel/mac80211/patches/rtl/009-wifi-rtw88-Add-common-USB-chip-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/010-wifi-rtw88-Add-rtw8821cu-chipset-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/011-wifi-rtw88-Add-rtw8822bu-chipset-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/012-wifi-rtw88-Add-rtw8822cu-chipset-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/013-wifi-rtw88-Add-rtw8723du-chipset-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/014-backports-rtw88-21cu-22cu-22bu-8723du.patch delete mode 100644 package/kernel/mac80211/patches/rtl/015-wifi-rtw88-Move-register-access-from-rtw_bf_assoc-ou.patch delete mode 100644 package/kernel/mac80211/patches/rtl/016-wifi-rtw88-Use-rtw_iterate_vifs-for-rtw_vif_watch_do.patch delete mode 100644 package/kernel/mac80211/patches/rtl/017-wifi-rtw88-Use-non-atomic-sta-iterator-in-rtw_ra_mas.patch delete mode 100644 package/kernel/mac80211/patches/rtl/018-wifi-rtw88-pci-Use-enum-type-for-rtw_hw_queue_mappin.patch delete mode 100644 package/kernel/mac80211/patches/rtl/019-wifi-rtw88-pci-Change-queue-datatype-to-enum-rtw_tx_.patch delete mode 100644 package/kernel/mac80211/patches/rtl/020-wifi-rtw88-Move-enum-rtw_tx_queue_type-mapping-code-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-49-wifi-rtw88-mac-Use-existing-macros-in-rtw_pwr_seq_pa.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-54-wifi-rtw88-mac-Add-support-for-the-SDIO-HCI-in-rtw_p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-55-wifi-rtw88-mac-Add-SDIO-HCI-support-in-the-TX-page-t.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-56-wifi-rtw88-rtw8821c-Implement-RTL8821CS-SDIO-efuse-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-57-wifi-rtw88-rtw8822b-Implement-RTL8822BS-SDIO-efuse-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-58-wifi-rtw88-rtw8822c-Implement-RTL8822CS-SDIO-efuse-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-59-wifi-rtw88-mac-Return-the-original-error-from-rtw_pw.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-60-wifi-rtw88-mac-Return-the-original-error-from-rtw_ma.patch delete mode 100644 package/kernel/mac80211/patches/rtl/021-wifi-rtw88-fix-memory-leak-in-rtw_usb_probe.patch delete mode 100644 package/kernel/mac80211/patches/rtl/022-wifi-rtw88-remove-unused-rtw_pci_get_tx_desc-functio.patch delete mode 100644 package/kernel/mac80211/patches/rtl/023-wifi-rtw88-Remove-redundant-pci_clear_master.patch delete mode 100644 package/kernel/mac80211/patches/rtl/024-wifi-rtw88-Clear-RTW_FLAG_POWERON-early-in-rtw_mac_p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/025-wifi-rtw88-sdio-Add-HCI-implementation-for-SDIO-base.patch delete mode 100644 package/kernel/mac80211/patches/rtl/026-wifi-rtw88-mac-Support-SDIO-specific-bits-in-the-pow.patch delete mode 100644 package/kernel/mac80211/patches/rtl/027-wifi-rtw88-main-Add-the-cpwm-rpwm-_addr-for-SDIO-bas.patch delete mode 100644 package/kernel/mac80211/patches/rtl/028-wifi-rtw88-main-Reserve-8-bytes-of-extra-TX-headroom.patch delete mode 100644 package/kernel/mac80211/patches/rtl/029-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822BS-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/030-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822CS-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/031-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8821CS-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/032-wifi-rtw88-add-bitmap-for-dynamic-port-settings.patch delete mode 100644 package/kernel/mac80211/patches/rtl/033-wifi-rtw88-add-port-switch-for-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/034-wifi-rtw88-8822c-extend-reserved-page-number.patch delete mode 100644 package/kernel/mac80211/patches/rtl/035-wifi-rtw88-disallow-PS-during-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/036-wifi-rtw88-refine-reserved-page-flow-for-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/037-wifi-rtw88-prevent-scan-abort-with-other-VIFs.patch delete mode 100644 package/kernel/mac80211/patches/rtl/038-wifi-rtw88-handle-station-mode-concurrent-scan-with-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/039-wifi-rtw88-8822c-add-iface-combination.patch delete mode 100644 package/kernel/mac80211/patches/rtl/040-wifi-rtw88-usb-fix-priority-queue-to-endpoint-mappin.patch delete mode 100644 package/kernel/mac80211/patches/rtl/041-wifi-rtw88-rtw8821c-Fix-rfe_option-field-width.patch delete mode 100644 package/kernel/mac80211/patches/rtl/042-wifi-rtw88-set-pkg_type-correctly-for-specific-rtw88.patch delete mode 100644 package/kernel/mac80211/patches/rtl/043-wifi-rtw88-call-rtw8821c_switch_rf_set-according-to-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/044-wifi-rtw88-Fix-memory-leak-in-rtw88_usb.patch delete mode 100644 package/kernel/mac80211/patches/rtl/045-wifi-rtw88-Update-spelling-in-main.h.patch delete mode 100644 package/kernel/mac80211/patches/rtl/046-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch delete mode 100644 package/kernel/mac80211/patches/rtl/047-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch delete mode 100644 package/kernel/mac80211/patches/rtl/048-wifi-rtw88-unlock-on-error-path-in-rtw_ops_add_inter.patch delete mode 100644 package/kernel/mac80211/patches/rtl/049-wifi-rtw88-use-work-to-update-rate-to-avoid-RCU-warn.patch delete mode 100644 package/kernel/mac80211/patches/rtl/050-wifi-rtw88-correct-qsel_to_ep-type-as-int.patch delete mode 100644 package/kernel/mac80211/patches/rtl/051-wifi-rtw88-sdio-Always-use-two-consecutive-bytes-for.patch delete mode 100644 package/kernel/mac80211/patches/rtl/052-wifi-rtw88-sdio-Check-the-HISR-RX_REQUEST-bit-in-rtw.patch delete mode 100644 package/kernel/mac80211/patches/rtl/053-wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/054-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/055-wifi-rtw88-usb-silence-log-flooding-error-message.patch delete mode 100644 package/kernel/mac80211/patches/rtl/056-wifi-rtw88-correct-PS-calculation-for-SUPPORTS_DYNAM.patch delete mode 100644 package/kernel/mac80211/patches/rtl/057-wifi-rtw88-add-missing-unwind-goto-for-__rtw_downloa.patch delete mode 100644 package/kernel/mac80211/patches/rtl/058-wifi-rtw88-Fix-action-frame-transmission-fail-before.patch delete mode 100644 package/kernel/mac80211/patches/rtl/059-wifi-rtw88-process-VO-packets-without-workqueue-to-a.patch delete mode 100644 package/kernel/mac80211/patches/rtl/060-wifi-rtw88-use-struct-instead-of-macros-to-set-TX-de.patch delete mode 100644 package/kernel/mac80211/patches/rtl/061-wifi-rtw88-Fix-AP-mode-incorrect-DTIM-behavior.patch delete mode 100644 package/kernel/mac80211/patches/rtl/062-wifi-rtw88-Skip-high-queue-in-hci_flush.patch delete mode 100644 package/kernel/mac80211/patches/rtl/063-wifi-rtw88-Stop-high-queue-during-scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/064-wifi-rtw88-refine-register-based-H2C-command.patch delete mode 100644 package/kernel/mac80211/patches/rtl/065-wifi-rtw88-fix-not-entering-PS-mode-after-AP-stops.patch delete mode 100644 package/kernel/mac80211/patches/rtl/200-add-rtw89.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-003-wifi-rtw89-8852b-add-tables-for-RFK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-005-wifi-rtw89-debug-txpwr_table-considers-sign.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-016-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-017-wifi-realtek-remove-duplicated-wake_tx_queue.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-018-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-019-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-020-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-021-wifi-rtw89-8852b-add-HFC-quota-arrays.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-022-wifi-rtw89-make-generic-functions-to-convert-subband.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-023-wifi-rtw89-8852b-add-chip_ops-set_channel.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-024-wifi-rtw89-correct-6-GHz-scan-behavior.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-025-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-026-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-027-wifi-rtw89-8852b-add-power-on-off-functions.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-028-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-029-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-030-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-031-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-032-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-033-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-034-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-035-wifi-rtw89-8852b-rfk-add-DACK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-036-wifi-rtw89-8852b-rfk-add-RCK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-037-wifi-rtw89-8852b-rfk-add-RX-DCK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-038-wifi-rtw89-8852b-rfk-add-IQK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-039-wifi-rtw89-8852b-rfk-add-TSSI.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-040-wifi-rtw89-8852b-rfk-add-DPK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-041-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-042-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-043-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-044-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-045-wifi-rtw89-declare-support-bands-with-const.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-046-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-047-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-048-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-049-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-050-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-051-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-052-wifi-rtw89-add-drop-tx-packet-function.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-053-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-054-wifi-rtw89-add-WoWLAN-function-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-055-wifi-rtw89-add-WoWLAN-pattern-match-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-056-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-057-wifi-rtw89-dump-dispatch-status-via-debug-port.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-058-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-060-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-061-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-063-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-064-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-065-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-066-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-068-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-069-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-070-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-071-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-072-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-073-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-074-wifi-rtw89-mac-process-MCC-related-C2H.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-075-wifi-rtw89-fw-implement-MCC-related-H2C.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-076-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-077-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-078-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-079-wifi-rtw89-add-mac-TSF-sync-function.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-080-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-081-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.2-082-wifi-rtw89-add-join-info-upon-create-interface.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-083-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-084-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-087-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-088-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-089-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-090-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-091-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-092-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-093-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-094-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-095-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-096-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-097-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-098-wifi-rtw89-Fix-a-typo-in-debug-message.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-099-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-100-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-101-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-102-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-103-wifi-rtw89-coex-Add-v5-firmware-control-report.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-104-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-105-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-108-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-109-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-110-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-111-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-112-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-113-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-114-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-115-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-116-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-117-wifi-rtw89-correct-register-definitions-of-digital-C.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-118-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-119-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-120-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-121-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-122-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-123-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-124-wifi-rtw89-coex-Refine-coexistence-log.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-125-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-126-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-127-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-128-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-129-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-130-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-131-wifi-rtw89-mac-add-function-to-get-TSF.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-133-wifi-rtw89-deal-with-RXI300-error.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-134-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-135-wifi-rtw89-refine-MCC-C2H-debug-logs.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-136-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-137-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-138-wifi-rtw89-refine-packet-offload-flow.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-139-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-140-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-141-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-142-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-143-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-144-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-145-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-146-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-147-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-148-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-149-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch delete mode 100644 package/kernel/mac80211/patches/rtl/201-v6.3-150-add-realtek-rtl8852be.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-001-wifi-rtw89-add-RNR-support-for-6-GHz-scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-002-wifi-rtw89-add-tx_wake-notify-for-8852B.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-003-wifi-rtw89-fw-configure-CRASH_TRIGGER-feature-for-88.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-004-wifi-rtw89-adjust-channel-encoding-to-common-functio.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-005-wifi-rtw89-8852b-add-channel-encoding-for-hw_scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-006-wifi-rtw89-8852b-enable-hw_scan-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-007-wifi-rtw89-refine-FW-feature-judgement-on-packet-dro.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-008-wifi-rtw89-fix-SER-L1-might-stop-entering-LPS-issue.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-009-wifi-rtw89-release-RX-standby-timer-of-beamformee-CS.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-010-wifi-rtw89-coex-Add-more-error_map-and-counter-to-lo.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-011-wifi-rtw89-coex-Add-WiFi-role-info-v2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-012-wifi-rtw89-coex-Add-traffic-TX-RX-info-and-its-H2C.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-013-wifi-rtw89-coex-Add-register-monitor-report-v2-forma.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-014-wifi-rtw89-coex-Fix-wrong-structure-assignment-at-nu.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-015-wifi-rtw89-coex-Add-v2-Bluetooth-scan-info.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-016-wifi-rtw89-coex-Add-v5-firmware-cycle-status-report.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-017-wifi-rtw89-coex-Add-LPS-protocol-radio-state-for-RTL.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-018-wifi-rtw89-coex-Not-to-enable-firmware-report-when-W.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-019-wifi-rtw89-coex-Update-RTL8852B-LNA2-hardware-parame.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-020-wifi-rtw89-coex-Add-report-control-v5-variation.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-021-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-022-wifi-rtw89-add-counters-of-register-based-H2C-C2H.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-023-wifi-rtw89-set-data-lowest-rate-according-to-AP-supp.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-024-wifi-rtw89-remove-superfluous-H2C-of-join_info.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-025-wifi-rtw89-fix-incorrect-channel-info-during-scan-du.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-026-wifi-rtw89-config-EDCCA-threshold-during-scan-to-pre.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-027-wifi-rtw89-fix-potential-race-condition-between-napi.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-028-wifi-rtw89-Remove-redundant-pci_clear_master.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-029-wifi-rtw89-8852c-add-beacon-filter-and-CQM-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-030-wifi-rtw89-add-function-to-wait-for-completion-of-TX.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-031-wifi-rtw89-add-ieee80211-remain_on_channel-ops.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-032-wifi-rtw89-add-flag-check-for-power-state.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-033-wifi-rtw89-fix-authentication-fail-during-scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-034-wifi-rtw89-fw-use-generic-flow-to-set-check-features.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-035-wifi-rtw89-use-schedule_work-to-request-firmware.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-036-wifi-rtw89-add-firmware-format-version-to-backward-c.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-037-wifi-rtw89-support-parameter-tables-by-RFE-type.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-038-wifi-rtw89-use-hardware-CFO-to-improve-performance.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-039-wifi-rtw89-read-version-of-analog-hardware.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-040-wifi-rtw89-8851b-fix-TX-path-to-path-A-for-one-RF-pa.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-041-wifi-rtw89-mac-update-MAC-settings-to-support-8851b.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-042-wifi-rtw89-pci-update-PCI-related-settings-to-suppor.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-043-wifi-rtw89-8851b-add-BB-and-RF-tables-1-of-2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-044-wifi-rtw89-8851b-add-BB-and-RF-tables-2-of-2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-045-wifi-rtw89-8851b-add-tables-for-RFK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-046-wifi-rtw89-correct-5-MHz-mask-setting.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-047-wifi-rtw89-fix-crash-due-to-null-pointer-of-sta-in-A.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-048-wifi-rtw89-support-WoWLAN-mode-for-8852be.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-049-wifi-rtw89-fix-power-save-function-in-WoWLAN-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-050-wifi-rtw89-coex-Enable-Wi-Fi-RX-gain-control-for-fre.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-051-wifi-rtw89-coex-Add-path-control-register-to-monitor.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-052-wifi-rtw89-coex-Update-function-to-get-BT-RSSI-and-h.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-053-wifi-rtw89-coex-send-more-hardware-module-info-to-fi.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-054-wifi-rtw89-prohibit-enter-IPS-during-HW-scan.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-055-wifi-rtw89-refine-scan-function-after-chanctx.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-056-wifi-rtw89-use-struct-instead-of-macros-to-set-H2C-c.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-057-wifi-rtw89-update-statistics-to-FW-for-fine-tuning-p.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-058-wifi-rtw89-Disallow-power-save-with-multiple-station.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-059-wifi-rtw89-add-support-of-concurrent-mode.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-060-wifi-rtw89-mac-use-regular-int-as-return-type-of-DLE.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-061-wifi-rtw89-use-struct-rtw89_phy_sts_ie0-instead-of-m.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-062-wifi-rtw89-set-capability-of-TX-antenna-diversity.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-063-wifi-rtw89-add-RSSI-statistics-for-the-case-of-anten.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-064-wifi-rtw89-add-EVM-and-SNR-statistics-to-debugfs.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-065-wifi-rtw89-initialize-antenna-for-antenna-diversity.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-066-wifi-rtw89-add-RSSI-based-antenna-diversity.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-067-wifi-rtw89-add-EVM-for-antenna-diversity.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-068-wifi-rtw89-release-bit-in-rtw89_fw_h2c_del_pkt_offlo.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-069-wifi-rtw89-refine-packet-offload-delete-flow-of-6-GH.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-070-wifi-rtw89-packet-offload-wait-for-FW-response.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-071-wifi-rtw89-mac-handle-C2H-receive-done-ACK-in-interr.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-072-wifi-rtw89-scan-offload-wait-for-FW-done-ACK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-073-wifi-rtw89-8851b-add-8851B-basic-chip_info.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-074-wifi-rtw89-8851be-add-8851BE-PCI-entry-and-fill-PCI-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-075-wifi-rtw89-8851b-add-NCTL-post-table.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-076-wifi-rtw89-add-CFO-XTAL-registers-field-to-support-8.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-077-wifi-rtw89-use-chip_info-small_fifo_size-to-choose-d.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-078-wifi-rtw89-change-naming-of-BA-CAM-from-V1-to-V0_EXT.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-079-wifi-rtw89-8851b-add-support-WoWLAN-to-8851B.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-080-wifi-rtw89-8851b-add-DLE-mem-and-HFC-quota.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-081-wifi-rtw89-8851b-add-set_channel_rf.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-082-wifi-rtw89-8851b-rfk-add-AACK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-083-wifi-rtw89-8851b-rfk-add-RCK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-084-wifi-rtw89-8851b-rfk-add-DACK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-085-wifi-rtw89-8851b-rfk-add-IQK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-086-wifi-rtw89-fix-rtw89_read_chip_ver-for-RTL8852B-and-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-087-wifi-rtw89-introduce-realtek-ACPI-DSM-method.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-088-wifi-rtw89-regd-judge-UNII-4-according-to-BIOS-and-c.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-089-wifi-rtw89-support-U-NII-4-channels-on-5GHz-band.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-090-wifi-rtw89-pci-fix-interrupt-enable-mask-for-HALT-C2.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-091-wifi-rtw89-ser-L1-add-pre-M0-and-post-M0-states.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-092-wifi-rtw89-suppress-the-log-for-specific-SER-called-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-093-wifi-rtw89-8852b-adjust-quota-to-avoid-SER-L1-caused.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-094-wifi-rtw89-8851b-add-to-read-efuse-version-to-recogn.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-095-wifi-rtw89-8851b-configure-GPIO-according-to-RFE-typ.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-096-wifi-rtw89-8851b-add-BT-coexistence-support-function.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-097-wifi-rtw89-8851b-add-basic-power-on-function.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-098-wifi-rtw89-8851b-add-set-channel-function.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-099-wifi-rtw89-8851b-add-to-parse-efuse-content.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-100-wifi-rtw89-8851b-rfk-add-RX-DCK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-101-wifi-rtw89-8851b-rfk-add-DPK.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-102-wifi-rtw89-8851b-rfk-add-TSSI.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-103-wifi-rtw89-ser-reset-total_sta_assoc-and-tdls_peer-w.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-104-wifi-rtw89-tweak-H2C-TX-waiting-function-for-SER.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-105-wifi-rtw89-refine-packet-offload-handling-under-SER.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-106-wifi-rtw89-8851b-add-TX-power-related-functions.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-107-wifi-rtw89-8851b-fill-BB-related-capabilities-to-chi.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-108-wifi-rtw89-8851b-add-MAC-configurations-to-chip_info.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-109-wifi-rtw89-8851b-add-RF-configurations.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-110-wifi-rtw89-enlarge-supported-length-of-read_reg-debu.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-111-wifi-rtw89-add-tx_wake-notify-for-8851B.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-112-wifi-rtw89-8851b-add-8851be-to-Makefile-and-Kconfig.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-113-wifi-rtw89-add-chip_ops-query_rxdesc-and-rxd_len-as-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-114-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-115-wifi-rtw89-use-struct-and-le32_get_bits-to-access-re.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-116-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-117-wifi-rtw89-use-struct-to-access-register-based-H2C-C.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-118-wifi-rtw89-8851b-rfk-Fix-spelling-mistake-KIP_RESOTR.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-119-wifi-rtw89-use-flexible-array-member-in-rtw89_btc_bt.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-120-wifi-rtw89-correct-PS-calculation-for-SUPPORTS_DYNAM.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-121-wifi-rtw89-remove-redundant-check-of-entering-LPS.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-122-wifi-rtw89-8851b-enable-hw_scan-support.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-123-wifi-rtw89-debug-txpwr-table-access-only-valid-page-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-124-wifi-rtw89-set-TX-power-without-precondition-during-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-125-wifi-rtw89-8851b-configure-CRASH_TRIGGER-feature-for.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-126-wifi-rtw89-refine-clearing-supported-bands-to-check-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-127-wifi-rtw89-regd-judge-6-GHz-according-to-chip-and-BI.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-128-wifi-rtw89-regd-update-regulatory-map-to-R64-R40.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-129-wifi-rtw89-process-regulatory-for-6-GHz-power-type.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-130-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-131-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-132-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-133-wifi-rtw89-8852c-update-RF-radio-A-B-parameters-to-R.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-134-wifi-rtw89-cleanup-private-data-structures.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-135-wifi-rtw89-cleanup-rtw89_iqk_info-and-related-code.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-136-wifi-rtw89-fix-spelling-typo-of-IQK-debug-messages.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-137-wifi-rtw89-8851b-update-RF-radio-A-parameters-to-R28.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-138-wifi-rtw89-8851b-update-TX-power-tables-to-R28.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-139-wifi-rtw89-8851b-rfk-add-LCK-track.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-140-wifi-rtw89-8851b-rfk-update-IQK-to-version-0x8.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-141-wifi-rtw89-8851b-configure-to-force-1-TX-power-value.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-142-wifi-rtw89-TX-power-stuffs-replace-confusing-naming-.patch delete mode 100644 package/kernel/mac80211/patches/rtl/202-v6.4-143-wifi-rtw89-use-struct-to-parse-firmware-header.patch create mode 100644 package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch delete mode 100644 package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch create mode 100644 package/kernel/mac80211/patches/subsys/401-mac80211-allow-vht-on-2g.patch create mode 100644 package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch create mode 100644 package/kernel/mac80211/patches/subsys/800-rework-eth_hw_addr_set.patch create mode 100644 package/kernel/rtw88-usb/Makefile create mode 100644 package/kernel/rtw88-usb/patches/001-fix-merge-error.patch create mode 100644 package/kernel/rtw88-usb/patches/101-wireless-6.1.patch create mode 100644 package/kernel/rtw88-usb/patches/102-disable-pcie.patch create mode 100755 package/lean/autocore/files/arm/sbin/usage create mode 100644 package/lean/cpufreq/Makefile create mode 100644 package/lean/cpufreq/files/cpufreq.config create mode 100755 package/lean/cpufreq/files/cpufreq.init create mode 100644 package/lean/cpufreq/files/cpufreq.uci delete mode 100644 package/lean/csstidy/Makefile delete mode 100644 package/lean/default-settings/po/zh-cn/more.po create mode 100644 package/lean/r8125/patches/011-ignore-rss-log.patch delete mode 100644 package/lean/r8125/patches/020-fixes-build-werror.patch create mode 100644 package/lean/r8126/Makefile create mode 100644 package/lean/r8126/patches/010-config.patch create mode 100644 package/lean/r8126/src/Makefile create mode 100644 package/lean/r8126/src/Makefile_linux24x create mode 100644 package/lean/r8126/src/r8126.h create mode 100644 package/lean/r8126/src/r8126_dash.h create mode 100644 package/lean/r8126/src/r8126_firmware.c create mode 100644 package/lean/r8126/src/r8126_firmware.h create mode 100644 package/lean/r8126/src/r8126_n.c create mode 100644 package/lean/r8126/src/r8126_ptp.c create mode 100644 package/lean/r8126/src/r8126_ptp.h create mode 100644 package/lean/r8126/src/r8126_realwow.h create mode 100644 package/lean/r8126/src/r8126_rss.c create mode 100644 package/lean/r8126/src/r8126_rss.h create mode 100644 package/lean/r8126/src/rtl_eeprom.c create mode 100644 package/lean/r8126/src/rtl_eeprom.h create mode 100644 package/lean/r8126/src/rtltool.c create mode 100644 package/lean/r8126/src/rtltool.h create mode 100644 package/libs/gettext-full/patches/020-fix_clang.patch create mode 100644 package/network/ipv6/ipip6/Makefile create mode 100755 package/network/ipv6/ipip6/files/ipip6.sh delete mode 100644 package/network/services/hostapd/README.md create mode 100644 package/network/services/hostapd/patches/170-DPP-fix-memleak-of-intro.peer_key.patch delete mode 100644 package/network/services/hostapd/patches/170-wpa_supplicant-fix-compiling-without-IEEE8021X_EAPOL.patch create mode 100644 package/network/services/hostapd/patches/432-missing-typedef.patch create mode 100644 package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch create mode 100644 package/network/services/hostapd/patches/800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch delete mode 100644 package/network/services/hostapd/patches/991-s8-u8.patch create mode 100644 package/network/services/hostapd/patches/992-openssl-include-rsa.patch create mode 100644 package/network/services/hostapd/patches/993-fix-mbo-module-build.patch create mode 100644 package/network/services/unetd/Makefile create mode 100644 package/network/services/unetd/files/unet-dht.init create mode 100644 package/network/services/unetd/files/unetd.init create mode 100644 package/network/services/unetd/files/unetd.sh create mode 100644 package/qca/nss-firmware/Makefile create mode 100644 package/qca/qca-mcs/Makefile create mode 100644 package/qca/qca-mcs/patches/0001-kernel-5.10-compat.patch create mode 100644 package/qca/qca-nss-cfi/Makefile create mode 100644 package/qca/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch create mode 100644 package/qca/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch create mode 100644 package/qca/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch create mode 100644 package/qca/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch create mode 100644 package/qca/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch create mode 100644 package/qca/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch create mode 100644 package/qca/qca-nss-clients/Makefile create mode 100755 package/qca/qca-nss-clients/files/qca-nss-ipsec create mode 100644 package/qca/qca-nss-clients/files/qca-nss-mirred.init create mode 100644 package/qca/qca-nss-clients/files/qca-nss-netlink.init create mode 100644 package/qca/qca-nss-clients/files/qca-nss-ovpn.init create mode 100644 package/qca/qca-nss-clients/patches/0001-kernel-5.15-support-qdisc.patch create mode 100644 package/qca/qca-nss-clients/patches/0002-kernel-5.4-support-gre.patch create mode 100644 package/qca/qca-nss-clients/patches/0003-kernel-5.4-support-ipsec.patch create mode 100644 package/qca/qca-nss-clients/patches/0004-kernel-5.4-support-dtls.patch create mode 100644 package/qca/qca-nss-clients/patches/0005-vlanmgr-fix-compile-error.patch create mode 100644 package/qca/qca-nss-clients/patches/0006-match-fix-compile-error.patch create mode 100644 package/qca/qca-nss-clients/patches/0007-bridge-fix-compile-error.patch create mode 100644 package/qca/qca-nss-clients/patches/0008-profiler-fix-compile-error.patch create mode 100644 package/qca/qca-nss-clients/patches/0009-gre-fix-compile-error.patch create mode 100644 package/qca/qca-nss-clients/patches/0010-fix-portifmgr.patch create mode 100644 package/qca/qca-nss-clients/patches/0011-dtlsmgr-fix-SHA-header-include-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0012-dtlsmgr-fix-debug-print-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0013-tlsmgr-fix-SHA-header-include-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0014-ovpnmgr-fix-SHA-header-include-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0015-tunipip6-fix-compile-error-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0016-vxlanmgr-fix-compile-error-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0017-tlsmgr-fix-debug-print-in-5.15.patch create mode 100644 package/qca/qca-nss-clients/patches/0018-kernel-6.1-support.patch create mode 100644 package/qca/qca-nss-crypto/Makefile create mode 100644 package/qca/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch create mode 100644 package/qca/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch create mode 100644 package/qca/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch create mode 100644 package/qca/qca-nss-drv/Config.in create mode 100644 package/qca/qca-nss-drv/Makefile create mode 100644 package/qca/qca-nss-drv/files/qca-nss-drv.conf create mode 100644 package/qca/qca-nss-drv/files/qca-nss-drv.debug create mode 100644 package/qca/qca-nss-drv/files/qca-nss-drv.hotplug create mode 100644 package/qca/qca-nss-drv/files/qca-nss-drv.init create mode 100644 package/qca/qca-nss-drv/files/qca-nss-drv.sysctl create mode 100644 package/qca/qca-nss-drv/patches/0001-nss-drv-replace-ioremap_nocache-with-ioremap.patch create mode 100644 package/qca/qca-nss-drv/patches/0002-nss-drv-add-support-for-kernel-5.15.patch create mode 100644 package/qca/qca-nss-drv/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch create mode 100644 package/qca/qca-nss-drv/patches/0004-nss-drv-rework-NSS_CORE_DMA_CACHE_MAINT-ops.patch create mode 100644 package/qca/qca-nss-drv/patches/0005-nss-drv-rework-getting-the-reserved-memory-size.patch create mode 100644 package/qca/qca-nss-drv/patches/0006-nss-drv-Fix-nss_clmap_stats-enum-int-compilation-error-GCC-13.patch create mode 100644 package/qca/qca-nss-drv/patches/0007-nss-drv-Fix-nss_wifili_if-compilation-error-GCC-13.patch create mode 100644 package/qca/qca-nss-drv/patches/0008-add-kernel-6.1-support.patch create mode 100644 package/qca/qca-nss-ecm/Makefile create mode 100755 package/qca/qca-nss-ecm/files/disable_offloads.hotplug create mode 100755 package/qca/qca-nss-ecm/files/disable_offloads.sh create mode 100755 package/qca/qca-nss-ecm/files/ecm_dump.sh create mode 100644 package/qca/qca-nss-ecm/files/on-demand-down create mode 100644 package/qca/qca-nss-ecm/files/qca-nss-ecm.defaults create mode 100644 package/qca/qca-nss-ecm/files/qca-nss-ecm.firewall create mode 100644 package/qca/qca-nss-ecm/files/qca-nss-ecm.init create mode 100644 package/qca/qca-nss-ecm/files/qca-nss-ecm.sysctl create mode 100644 package/qca/qca-nss-ecm/files/qca-nss-ecm.uci create mode 100644 package/qca/qca-nss-ecm/patches/0001-treewide-componentize-the-module-even-more.patch create mode 100644 package/qca/qca-nss-ecm/patches/0002-treewide-rework-ipv6_dev_find_and_hold.patch create mode 100644 package/qca/qca-nss-ecm/patches/0003-qca-nss-ecm-resolve-the-cpu-high-load-regarding-ecm.patch create mode 100644 package/qca/qca-nss-ecm/patches/0005-frontends-drop-use-of-static-be_liberal-and-no_windo.patch create mode 100644 package/qca/qca-nss-ecm/patches/0006-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch create mode 100644 package/qca/qca-nss-ecm/patches/0007-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch create mode 100644 package/qca/qca-nss-ecm/patches/0008-ecm_interface-fix-ppp-generic-function-calls-for-5.15.patch create mode 100644 package/qca/qca-nss-ecm/patches/0009-treewide-export-ipv4-and-ipv6-symbols.patch create mode 100644 package/qca/qca-nss-ecm/patches/1000-fix-missing-include-header.patch create mode 100644 package/qca/qca-nss-ecm/patches/900-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch create mode 100644 package/qca/qca-ssdk-shell/Makefile create mode 100644 package/qca/qca-ssdk-shell/patches/0001-qca-ssdk-shell-Fix-fal_port_cdt-compilation-error-GCC-13.patch rename target/linux/{meson => amlogic}/Makefile (71%) create mode 100644 target/linux/amlogic/config-5.15 rename target/linux/{meson => amlogic}/files/arch/arm/boot/dts/meson8b-onecloud.dts (100%) create mode 100644 target/linux/amlogic/image/Makefile create mode 100644 target/linux/amlogic/image/aml_autoscript.cmd create mode 100644 target/linux/amlogic/image/amlogic.bootscript rename target/linux/{meson => amlogic}/image/boot.txt (100%) create mode 100755 target/linux/amlogic/image/emmc_autoscript.cmd rename target/linux/{meson => amlogic}/image/gen_aml_emmc_img.sh (100%) create mode 100755 target/linux/amlogic/image/gen_amlogic_image.sh create mode 100644 target/linux/amlogic/image/meson8b.mk create mode 100644 target/linux/amlogic/image/mesongx.mk create mode 100755 target/linux/amlogic/image/s905_autoscript.cmd rename target/linux/{meson => amlogic/meson8b}/base-files/etc/inittab (100%) rename target/linux/{meson => amlogic/meson8b}/base-files/etc/rc.local (100%) rename target/linux/{meson => amlogic/meson8b}/base-files/lib/preinit/79_move_config (100%) rename target/linux/{meson => amlogic/meson8b}/base-files/lib/upgrade/platform.sh (100%) rename target/linux/{meson => amlogic/meson8b}/base-files/root/resize.sh (100%) rename target/linux/{meson => amlogic}/meson8b/config-6.1 (100%) rename target/linux/{meson => amlogic}/meson8b/target.mk (100%) create mode 100755 target/linux/amlogic/mesongx/base-files/etc/board.d/02_network create mode 100755 target/linux/amlogic/mesongx/base-files/etc/uci-defaults/12_enable-netifd-smp-tune create mode 100644 target/linux/amlogic/mesongx/base-files/lib/preinit/79_move_config create mode 100644 target/linux/amlogic/mesongx/base-files/lib/upgrade/platform.sh create mode 100755 target/linux/amlogic/mesongx/base-files/usr/sbin/install-to-emmc.sh create mode 100644 target/linux/amlogic/mesongx/config-5.15 create mode 100644 target/linux/amlogic/mesongx/target.mk create mode 100644 target/linux/amlogic/modules.mk create mode 100644 target/linux/amlogic/patches-5.15/001-dts-s905d-fix-high-load.patch create mode 100644 target/linux/amlogic/patches-5.15/002-dts-improve-phicomm-n1-support.patch rename target/linux/{meson => amlogic}/patches-6.1/902-use-system-LED-for-OpenWrt.patch (100%) rename target/linux/{meson => amlogic}/patches-6.1/903-add-dts-and-identify-emmc.patch (100%) rename target/linux/{meson => amlogic}/patches-6.1/905-pwm-meson-modify-and-simplify-calculation-in.patch (100%) delete mode 100644 target/linux/bcm27xx/patches-6.1/950-0081-smsx95xx-fix-crimes-against-truesize.patch delete mode 100644 target/linux/bcm27xx/patches-6.1/950-0270-net-bcmgenet-Reset-RBUF-on-first-open.patch delete mode 100644 target/linux/bcm27xx/patches-6.1/950-1235-drm-vc4-don-t-check-if-plane-state-fb-state-fb.patch delete mode 100644 target/linux/generic/backport-5.10/350-v5.12-NFSv4_2-SSC-helper-should-use-its-own-config.patch delete mode 100644 target/linux/generic/backport-5.10/351-v5.13-NFSv4_2-Remove-ifdef-CONFIG_NFSD-from-client-SSC.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch create mode 100644 target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch create mode 100644 target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch delete mode 100644 target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch rename target/linux/generic/{pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch => backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch} (90%) rename target/linux/generic/backport-5.15/{733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch => 733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch} (100%) rename target/linux/generic/backport-5.15/{733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch => 733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch} (100%) rename target/linux/generic/{pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch => backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch} (94%) rename target/linux/generic/{pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch => backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch} (92%) rename target/linux/generic/{pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch => backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch} (100%) create mode 100644 target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch delete mode 100644 target/linux/generic/backport-5.15/741-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch delete mode 100644 target/linux/generic/backport-5.15/741-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch rename target/linux/generic/{pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch => backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch} (50%) rename target/linux/generic/{pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch => backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch} (63%) rename target/linux/generic/{pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch => backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch} (89%) create mode 100644 target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch create mode 100644 target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch create mode 100644 target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch create mode 100644 target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch create mode 100644 target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch create mode 100644 target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch create mode 100644 target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch create mode 100644 target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch create mode 100644 target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch create mode 100644 target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch create mode 100644 target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch create mode 100644 target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch create mode 100644 target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch create mode 100644 target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch create mode 100644 target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch create mode 100644 target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch create mode 100644 target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch create mode 100644 target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch create mode 100644 target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch create mode 100644 target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch rename target/linux/generic/backport-5.15/{890-v6.1-mtd-spinand-winbond-fix-flash-detection.patch => 890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch} (100%) rename target/linux/generic/backport-5.15/{891-v6.1-mtd-spinand-winbond-add-W25N02KV.patch => 891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch} (100%) delete mode 100644 target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch rename target/linux/generic/{pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch => backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch} (78%) rename target/linux/generic/{pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch => backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch} (63%) rename target/linux/generic/{pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch => backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch} (100%) create mode 100644 target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch rename target/linux/generic/{pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch => backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch} (50%) rename target/linux/generic/{pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch => backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch} (63%) rename target/linux/generic/{pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch => backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch} (89%) create mode 100644 target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch create mode 100644 target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch create mode 100644 target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch create mode 100644 target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch create mode 100644 target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch create mode 100644 target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch create mode 100644 target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch create mode 100644 target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch create mode 100644 target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch create mode 100644 target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch create mode 100644 target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch create mode 100644 target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch create mode 100644 target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch create mode 100644 target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch create mode 100644 target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch create mode 100644 target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch create mode 100644 target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch create mode 100644 target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch create mode 100644 target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch create mode 100644 target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch create mode 100644 target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch create mode 100644 target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch create mode 100644 target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch create mode 100644 target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch delete mode 100644 target/linux/generic/pending-5.10/701-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch delete mode 100644 target/linux/generic/pending-5.10/701-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch create mode 100644 target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch delete mode 100644 target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch delete mode 100644 target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch delete mode 100644 target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch delete mode 100644 target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch create mode 100644 target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch create mode 100644 target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch create mode 100644 target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch delete mode 100644 target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch delete mode 100644 target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch delete mode 100644 target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch delete mode 100644 target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch create mode 100644 target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch create mode 100644 target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch delete mode 100644 target/linux/meson/image/Makefile create mode 100644 target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-db-A.dts create mode 100644 target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-db-A.dts rename target/linux/qualcommax/{ipq807x => }/base-files/lib/upgrade/mmc.sh (100%) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-re-ss-01.dts create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-re-cs-02.dts create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-nss.dtsi create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi create mode 100644 target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h create mode 100644 target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h create mode 100644 target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c create mode 100644 target/linux/qualcommax/ipq60xx/base-files/lib/preinit/81_fix_eeprom delete mode 100644 target/linux/qualcommax/patches-6.1/0134-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-add-missing-net-defines.patch create mode 100644 target/linux/qualcommax/patches-6.1/0600-8-qca-nss-ecm-support-MLO-bonding.patch create mode 100644 target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch create mode 100644 target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch create mode 100644 target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch create mode 100644 target/linux/ramips/dts/mt7621_h3c_tx1800-plus.dts create mode 100644 target/linux/ramips/dts/mt7621_h3c_tx1801-plus.dts create mode 100644 target/linux/ramips/dts/mt7621_h3c_tx1806.dts create mode 100644 target/linux/ramips/dts/mt7621_h3c_tx180x.dtsi create mode 100644 target/linux/ramips/dts/mt7621_jdcloud_re-cp-02.dts create mode 100644 target/linux/ramips/dts/mt7621_openfi_5pro.dts create mode 100644 target/linux/ramips/patches-5.4/993-spi-nor-w25q512jv.patch create mode 100644 target/linux/sunxi/arm926ejs/config-6.1 create mode 100644 target/linux/sunxi/arm926ejs/target.mk create mode 100644 target/linux/sunxi/config-6.6 create mode 100644 target/linux/sunxi/cortexa53/config-6.6 create mode 100644 target/linux/sunxi/cortexa7/config-6.6 create mode 100644 target/linux/sunxi/cortexa8/config-6.6 create mode 100644 target/linux/sunxi/image/arm926ejs.mk create mode 100644 target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch create mode 100644 target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch create mode 100644 target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch create mode 100644 target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch create mode 100644 target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch create mode 100644 target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch create mode 100644 target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch create mode 100644 target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch create mode 100644 target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch create mode 100644 target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch create mode 100644 target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch create mode 100644 target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch create mode 100644 target/linux/sunxi/patches-6.1/101-sunxi-add-get_soc_chipid-and-sunxi_get_serial.patch create mode 100644 target/linux/sunxi/patches-6.1/460-ARM-dts-suniv-add-USB-related-device-nodes.patch create mode 100644 target/linux/sunxi/patches-6.1/461-ARM-dts-suniv-add-device-tree-for-PopStick-v1_1.patch create mode 100644 target/linux/sunxi/patches-6.1/462-ARM-dts-suniv-licheepi-nano-enable-USB.patch create mode 100644 target/linux/sunxi/patches-6.1/463-f1c100s-sram-driver.patch create mode 100644 target/linux/sunxi/patches-6.1/464-f1c100s-watchdog-compat.patch create mode 100644 target/linux/sunxi/patches-6.1/501-h616-Add-cpu-frequency-scaling-support.patch create mode 100644 target/linux/sunxi/patches-6.1/502-arm64-dts-allwinner-h616-Add-cpufreq.patch create mode 100644 target/linux/sunxi/patches-6.6/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch create mode 100644 target/linux/sunxi/patches-6.6/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch create mode 100644 target/linux/sunxi/patches-6.6/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch create mode 100644 target/linux/sunxi/patches-6.6/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch create mode 100644 target/linux/sunxi/patches-6.6/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch create mode 100644 target/linux/sunxi/patches-6.6/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch create mode 100644 target/linux/sunxi/patches-6.6/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch create mode 100644 target/linux/sunxi/patches-6.6/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch create mode 100644 target/linux/sunxi/patches-6.6/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch create mode 100644 target/linux/sunxi/patches-6.6/102-sunxi-add-OF-node-for-USB-eth-on-NanoPi-R1S-H5.patch create mode 100644 target/linux/sunxi/patches-6.6/301-orangepi_pc2_usb_otg_to_host_key_power.patch create mode 100644 target/linux/sunxi/patches-6.6/400-arm64-allwinner-a64-sopine-Add-Sopine-flash-partitio.patch create mode 100644 target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch create mode 100644 target/linux/sunxi/patches-6.6/430-arm64-dts-allwinner-a64-olinuxino-add-status-LED-ali.patch create mode 100644 target/linux/sunxi/patches-6.6/442-arm64-dts-orangepi-one-plus-enable-PWM.patch create mode 100644 target/linux/sunxi/patches-6.6/450-arm64-dts-enable-wifi-on-pine64-boards.patch create mode 100644 target/linux/sunxi/patches-6.6/501-h616-Add-cpu-frequency-scaling-support.patch create mode 100644 target/linux/sunxi/patches-6.6/502-arm64-dts-allwinner-h616-Add-cpufreq.patch create mode 100644 toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch create mode 100644 tools/autoconf-archive/patches/001-fix_ax_c_float_words_bigendian.patch create mode 100644 tools/automake/patches/101-do-not-require-files.patch create mode 100644 tools/automake/patches/200-other-V-values-for-verbosity.patch delete mode 100644 tools/cpio/patches/001-duplicate-program-name.patch delete mode 100644 tools/cpio/patches/010-clang.patch diff --git a/config/Config-build.in b/config/Config-build.in index c2303637c..49f40bb00 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -152,6 +152,21 @@ menu "Global build settings" default n help Adds -g3 to the CFLAGS. + + config USE_GC_SECTIONS + bool + prompt "Dead code and data elimination for all packages (EXPERIMENTAL)" + help + Places functions and data items into its own sections to use the linker's + garbage collection capabilites. + Packages can choose to opt-out via setting PKG_BUILD_FLAGS:=no-gc-sections + + config USE_LTO + bool + prompt "Use the link-time optimizer for all packages (EXPERIMENTAL)" + help + Adds LTO flags to the CFLAGS and LDFLAGS. + Packages can choose to opt-out via setting PKG_BUILD_FLAGS:=no-lto config IPV6 def_bool y diff --git a/config/Config-images.in b/config/Config-images.in index e59318bba..f0627874e 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -303,7 +303,7 @@ menu "Target Images" default 8 if TARGET_apm821xx_sata default 64 if TARGET_bcm27xx default 32 if TARGET_rockchip - default 32 if TARGET_x86 + default 128 if TARGET_armvirt default 16 config TARGET_ROOTFS_PARTSIZE diff --git a/config/Config-kernel.in b/config/Config-kernel.in index ae845b66f..2b904b57f 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -50,6 +50,15 @@ config KERNEL_ARM_PMU default n depends on (arm || aarch64) +config KERNEL_RISCV_PMU + bool + select KERNEL_RISCV_PMU_SBI + depends on riscv64 + +config KERNEL_RISCV_PMU_SBI + bool + depends on riscv64 + config KERNEL_X86_VSYSCALL_EMULATION bool "Enable vsyscall emulation" default n @@ -72,6 +81,7 @@ config KERNEL_PERF_EVENTS bool "Compile the kernel with performance events and counters" default n select KERNEL_ARM_PMU if (arm || aarch64) + select KERNEL_RISCV_PMU if riscv64 config KERNEL_PROFILING bool "Compile the kernel with profiling enabled" @@ -1135,13 +1145,6 @@ config KERNEL_NET_L3_MASTER_DEV This module provides glue between core networking code and device drivers to support L3 master devices like VRF. -config KERNEL_XDP_SOCKETS - bool "XDP sockets support" - default y if KERNEL_DEBUG_INFO_BTF - help - XDP sockets allows a channel between XDP programs and - userspace applications. - config KERNEL_PAGE_POOL def_bool n diff --git a/include/kernel-5.10 b/include/kernel-5.10 index ee8bf19a0..90467d65a 100644 --- a/include/kernel-5.10 +++ b/include/kernel-5.10 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.10 = .213 -LINUX_KERNEL_HASH-5.10.213 = 84cf30223239ec3333a5f7b2a7fba2042bba70d1582a139f7543956af871ad80 +LINUX_VERSION-5.10 = .220 +LINUX_KERNEL_HASH-5.10.220 = 7cc3aff924e9707a5dbf1200c79a7f01617e097b9b175d02bda8ca762aeee19b diff --git a/include/kernel-5.15 b/include/kernel-5.15 index 5436913e0..a03ed80f9 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .156 -LINUX_KERNEL_HASH-5.15.156 = 9f0465d14c93691056f5f94de647601f94f083ad8ce2e5d306564394b13e7778 +LINUX_VERSION-5.15 = .161 +LINUX_KERNEL_HASH-5.15.161 = d629f78680dc4b65e3d78b61406fb7757b960c83c206e63ad8c2606b3e3c474c diff --git a/include/kernel-5.4 b/include/kernel-5.4 index a17e792d2..82c8c7418 100644 --- a/include/kernel-5.4 +++ b/include/kernel-5.4 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.4 = .272 -LINUX_KERNEL_HASH-5.4.272 = 3599d5959a403e64be407d7f05e56cb270d6ddd154e89a596609919ab1e2e366 +LINUX_VERSION-5.4 = .278 +LINUX_KERNEL_HASH-5.4.278 = e5a00606115545f444ef2766af5652f5539e3c96f46a9778bede89b98ffb8588 diff --git a/include/package.mk b/include/package.mk index 368bf0d7c..75aa8aefe 100644 --- a/include/package.mk +++ b/include/package.mk @@ -11,8 +11,6 @@ include $(INCLUDE_DIR)/download.mk PKG_BUILD_DIR ?= $(BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION)) PKG_INSTALL_DIR ?= $(PKG_BUILD_DIR)/ipkg-install PKG_BUILD_PARALLEL ?= -PKG_USE_MIPS16 ?= 1 -PKG_IREMAP ?= 1 PKG_SKIP_DOWNLOAD=$(USE_SOURCE_DIR)$(USE_GIT_TREE)$(USE_GIT_SRC_CHECKOUT) MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) $(if $(filter 3.% 4.0 4.1,$(MAKE_VERSION)),-j)) @@ -24,17 +22,52 @@ PKG_JOBS?=-j1 else PKG_JOBS?=$(if $(PKG_BUILD_PARALLEL),$(MAKE_J),-j1) endif -ifdef CONFIG_USE_MIPS16 - ifeq ($(strip $(PKG_USE_MIPS16)),1) - TARGET_ASFLAGS_DEFAULT = $(filter-out -mips16 -minterlink-mips16,$(TARGET_CFLAGS)) - TARGET_CFLAGS += -mips16 -minterlink-mips16 - endif + +PKG_BUILD_FLAGS?= +# TODO remove this when all packages moved to PKG_BUILD_FLAGS=no-mips16 +PKG_USE_MIPS16?=1 +ifneq ($(strip $(PKG_USE_MIPS16)),1) + PKG_BUILD_FLAGS+=no-mips16 endif -ifeq ($(strip $(PKG_IREMAP)),1) + +__unknown_flags=$(filter-out no-iremap no-mips16 gc-sections no-gc-sections lto no-lto no-mold,$(PKG_BUILD_FLAGS)) +ifneq ($(__unknown_flags),) + $(error unknown PKG_BUILD_FLAGS: $(__unknown_flags)) +endif + +# $1=flagname, $2=default (0/1) +define pkg_build_flag +$(if $(filter no-$(1),$(PKG_BUILD_FLAGS)),0,$(if $(filter $(1),$(PKG_BUILD_FLAGS)),1,$(2))) +endef + +ifeq ($(call pkg_build_flag,iremap,1),1) IREMAP_CFLAGS = $(call iremap,$(PKG_BUILD_DIR),$(notdir $(PKG_BUILD_DIR))) TARGET_CFLAGS += $(IREMAP_CFLAGS) endif +ifdef CONFIG_USE_MIPS16 + ifeq ($(call pkg_build_flag,mips16,1),1) + TARGET_ASFLAGS_DEFAULT = $(filter-out -mips16 -minterlink-mips16,$(TARGET_CFLAGS)) + TARGET_CFLAGS += -mips16 -minterlink-mips16 + TARGET_CXXFLAGS += -mips16 -minterlink-mips16 + endif +endif +ifeq ($(call pkg_build_flag,gc-sections,$(if $(CONFIG_USE_GC_SECTIONS),1,0)),1) + TARGET_CFLAGS+= -ffunction-sections -fdata-sections + TARGET_CXXFLAGS+= -ffunction-sections -fdata-sections + TARGET_LDFLAGS+= -Wl,--gc-sections +endif +ifeq ($(call pkg_build_flag,lto,$(if $(CONFIG_USE_LTO),1,0)),1) + TARGET_CFLAGS+= -flto=auto -fno-fat-lto-objects + TARGET_CXXFLAGS+= -flto=auto -fno-fat-lto-objects + TARGET_LDFLAGS+= -flto=auto -fuse-linker-plugin +endif +ifdef CONFIG_USE_MOLD + ifeq ($(call pkg_build_flag,mold,1),1) + TARGET_LINKER:=mold + endif +endif + include $(INCLUDE_DIR)/hardening.mk include $(INCLUDE_DIR)/prereq.mk include $(INCLUDE_DIR)/unpack.mk diff --git a/include/target.mk b/include/target.mk index 426801b92..e5c064759 100644 --- a/include/target.mk +++ b/include/target.mk @@ -55,7 +55,7 @@ DEFAULT_PACKAGES.nas:=\ DEFAULT_PACKAGES.router:=\ dnsmasq-full firewall iptables ppp ppp-mod-pppoe \ block-mount coremark kmod-nf-nathelper kmod-nf-nathelper-extra kmod-ipt-raw kmod-tun \ - iptables-mod-tproxy iptables-mod-extra ipset ip-full default-settings luci luci-newapi \ + iptables-mod-tproxy iptables-mod-extra ipset ip-full default-settings luci \ ddns-scripts_aliyun ddns-scripts_dnspod luci-app-ddns luci-app-upnp luci-app-autoreboot \ luci-app-arpbind luci-app-filetransfer luci-app-vsftpd luci-app-ssr-plus luci-app-vlmcsd \ luci-app-accesscontrol luci-app-nlbwmon luci-app-turboacc luci-app-wol curl ca-certificates diff --git a/include/u-boot.mk b/include/u-boot.mk index 454880989..d824d97ff 100644 --- a/include/u-boot.mk +++ b/include/u-boot.mk @@ -1,5 +1,3 @@ -include $(INCLUDE_DIR)/prereq.mk - PKG_NAME ?= u-boot ifndef PKG_SOURCE_PROTO @@ -20,31 +18,6 @@ PKG_LICENSE_FILES:=Licenses/README PKG_BUILD_PARALLEL ?= 1 -ifdef UBOOT_USE_BINMAN - $(eval $(call TestHostCommand,python3-pyelftools, \ - Please install the Python3 elftools module, \ - $(STAGING_DIR_HOST)/bin/python3 -c 'import elftools')) -endif - -ifdef UBOOT_USE_INTREE_DTC - $(eval $(call TestHostCommand,python3-dev, \ - Please install the python3-dev package, \ - python3.11-config --includes 2>&1 | grep 'python3', \ - python3.10-config --includes 2>&1 | grep 'python3', \ - python3.9-config --includes 2>&1 | grep 'python3', \ - python3.8-config --includes 2>&1 | grep 'python3', \ - python3.7-config --includes 2>&1 | grep 'python3', \ - python3-config --includes 2>&1 | grep -E 'python3\.([7-9]|[0-9][0-9])\.?')) - - $(eval $(call TestHostCommand,python3-setuptools, \ - Please install the Python3 setuptools module, \ - $(STAGING_DIR_HOST)/bin/python3 -c 'import setuptools')) - - $(eval $(call TestHostCommand,swig, \ - Please install the swig package, \ - swig -version)) -endif - export GCC_HONOUR_COPTS=s define Package/u-boot/install/default @@ -69,7 +42,6 @@ endef TARGET_DEP = TARGET_$(BUILD_TARGET)$(if $(BUILD_SUBTARGET),_$(BUILD_SUBTARGET)) UBOOT_MAKE_FLAGS = \ - PATH=$(STAGING_DIR_HOST)/bin:$(PATH) \ HOSTCC="$(HOSTCC)" \ HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS) -std=gnu11" \ HOSTLDFLAGS="$(HOST_LDFLAGS)" \ @@ -111,14 +83,9 @@ endef define Build/Configure/U-Boot +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config - $(if $(strip $(UBOOT_CUSTOMIZE_CONFIG)), - $(PKG_BUILD_DIR)/scripts/config --file $(PKG_BUILD_DIR)/.config $(UBOOT_CUSTOMIZE_CONFIG) - +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) oldconfig) endef -ifndef UBOOT_USE_INTREE_DTC - DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc) -endif +DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc) define Build/Compile/U-Boot +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ diff --git a/package/boot/arm-trusted-firmware-mediatek/Makefile b/package/boot/arm-trusted-firmware-mediatek/Makefile index f77f30591..d226a655d 100644 --- a/package/boot/arm-trusted-firmware-mediatek/Makefile +++ b/package/boot/arm-trusted-firmware-mediatek/Makefile @@ -13,9 +13,9 @@ PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/mtk-openwrt/arm-trusted-firmware.git -PKG_SOURCE_DATE:=2023-07-24 -PKG_SOURCE_VERSION:=00ac6db375b76e57e1f5e9e9bffa033e907c3581 -PKG_MIRROR_HASH:=74fc18395532c4292f530da8d00fa1873ada4e05e600c0077a7b7f85ace0d913 +PKG_SOURCE_DATE:=2024-01-17 +PKG_SOURCE_VERSION:=bacca82a8cac369470df052a9d801a0ceb9b74ca +PKG_MIRROR_HASH:=d035c1b63a9bd71d752c90540361b66d290e7cf42dcca73259d0950af3569c79 PKG_MAINTAINER:=Daniel Golle @@ -94,6 +94,30 @@ define Trusted-Firmware-A/mt7622-sdmmc-2ddr DDR3_FLYBY:=1 endef +define Trusted-Firmware-A/mt7981-nor-ddr4 + NAME:=MediaTek MT7981 (SPI-NOR, DDR4) + BOOT_DEVICE:=nor + BUILD_SUBTARGET:=filogic + PLAT:=mt7981 + DDR_TYPE:=ddr4 +endef + +define Trusted-Firmware-A/mt7981-emmc-ddr4 + NAME:=MediaTek MT7981 (eMMC, DDR4) + BOOT_DEVICE:=emmc + BUILD_SUBTARGET:=filogic + PLAT:=mt7981 + DDR_TYPE:=ddr4 +endef + +define Trusted-Firmware-A/mt7981-spim-nand-ddr4 + NAME:=MediaTek MT7981 (SPI-NAND via SPIM, DDR4) + BOOT_DEVICE:=spim-nand + BUILD_SUBTARGET:=filogic + PLAT:=mt7981 + DDR_TYPE:=ddr4 +endef + define Trusted-Firmware-A/mt7981-nor-ddr3 NAME:=MediaTek MT7981 (SPI-NOR, DDR3) BOOT_DEVICE:=nor @@ -349,6 +373,9 @@ TFA_TARGETS:= \ mt7981-sdmmc-ddr3 \ mt7981-snand-ddr3 \ mt7981-spim-nand-ddr3 \ + mt7981-emmc-ddr4 \ + mt7981-nor-ddr4 \ + mt7981-spim-nand-ddr4 \ mt7986-emmc-ddr3 \ mt7986-nor-ddr3 \ mt7986-sdmmc-ddr3 \ diff --git a/package/boot/arm-trusted-firmware-mediatek/patches/0001-mediatek-snfi-FM35Q1GA-is-x4-only.patch b/package/boot/arm-trusted-firmware-mediatek/patches/0001-mediatek-snfi-FM35Q1GA-is-x4-only.patch new file mode 100644 index 000000000..d8ea1fa40 --- /dev/null +++ b/package/boot/arm-trusted-firmware-mediatek/patches/0001-mediatek-snfi-FM35Q1GA-is-x4-only.patch @@ -0,0 +1,23 @@ +From fb2a2b669ec9bbf5c448d4b56499bc83de075c93 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 29 Feb 2024 18:01:08 +0000 +Subject: [PATCH 1/3] mediatek: snfi: FM35Q1GA is x4-only + +Dont allow x2 read and cache read operations on FM35Q1GA. + +Signed-off-by: Daniel Golle +--- + plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c ++++ b/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c +@@ -423,7 +423,7 @@ static const struct snand_flash_info sna + + SNAND_INFO("FM35Q1GA", SNAND_ID(SNAND_ID_DYMMY, 0xe5, 0x71), + SNAND_MEMORG_1G_2K_64, +- &snand_cap_read_from_cache_x4, ++ &snand_cap_read_from_cache_x4_only, + &snand_cap_program_load_x4), + + SNAND_INFO("PN26G01A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe1), diff --git a/package/boot/arm-trusted-firmware-mediatek/patches/0002-mediatek-snfi-adjust-pin-drive-strength-for-Fidelix-.patch b/package/boot/arm-trusted-firmware-mediatek/patches/0002-mediatek-snfi-adjust-pin-drive-strength-for-Fidelix-.patch new file mode 100644 index 000000000..95e3c139f --- /dev/null +++ b/package/boot/arm-trusted-firmware-mediatek/patches/0002-mediatek-snfi-adjust-pin-drive-strength-for-Fidelix-.patch @@ -0,0 +1,99 @@ +From 6470986f037880ce76960c369d6e5a5270e7ce32 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 10 Mar 2024 15:39:07 +0000 +Subject: [PATCH 2/3] mediatek: snfi: adjust pin drive strength for Fidelix + SPI-NAND + +It seems like we might need to adjust the pin driver strength to 12mA +for Fidelix SPI-NAND chip on MT7622 to avoid SPI data corruption on +some devices. + +Signed-off-by: Daniel Golle +--- + .../apsoc_common/drivers/snfi/mtk-snand-def.h | 7 +++++ + .../apsoc_common/drivers/snfi/mtk-snand-ids.c | 4 ++- + .../apsoc_common/drivers/snfi/mtk-snand.c | 30 +++++++++++++++++++ + 3 files changed, 40 insertions(+), 1 deletion(-) + +--- a/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-def.h ++++ b/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-def.h +@@ -86,6 +86,12 @@ struct snand_mem_org { + + typedef int (*snand_select_die_t)(struct mtk_snand *snf, uint32_t dieidx); + ++enum snand_drv { ++ SNAND_DRV_NO_CHANGE = 0, ++ SNAND_DRV_8mA = 8, ++ SNAND_DRV_12mA = 12, ++}; ++ + struct snand_flash_info { + const char *model; + struct snand_id id; +@@ -93,6 +99,7 @@ struct snand_flash_info { + const struct snand_io_cap *cap_rd; + const struct snand_io_cap *cap_pl; + snand_select_die_t select_die; ++ enum snand_drv drv; + }; + + #define SNAND_INFO(_model, _id, _memorg, _cap_rd, _cap_pl, ...) \ +--- a/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c ++++ b/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c +@@ -424,7 +424,9 @@ static const struct snand_flash_info sna + SNAND_INFO("FM35Q1GA", SNAND_ID(SNAND_ID_DYMMY, 0xe5, 0x71), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4_only, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + + SNAND_INFO("PN26G01A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe1), + SNAND_MEMORG_1G_2K_128, +--- a/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand.c ++++ b/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand.c +@@ -1845,6 +1845,33 @@ static int mtk_snand_id_probe(struct mtk + return -EINVAL; + } + ++#define MT7622_GPIO_BASE (void *)0x10211000 ++#define MT7622_GPIO_DRIV(x) (MT7622_GPIO_BASE + 0x900 + 0x10 * x) ++ ++void mtk_mt7622_snand_adjust_drive(void *dev, enum snand_drv drv) ++{ ++ uint32_t e4, e8; ++ ++ e4 = readl(MT7622_GPIO_DRIV(6)) & ~(0x3f00); ++ e8 = readl(MT7622_GPIO_DRIV(7)) & ~(0x3f00); ++ ++ switch (drv) { ++ case SNAND_DRV_8mA: ++ e4 |= 0x3f00; ++ break; ++ case SNAND_DRV_12mA: ++ e8 |= 0x3f00; ++ break; ++ default: ++ return; ++ } ++ ++ snand_log_chip(dev, "adjusting SPI-NAND pin drive strength to %umA\n", drv); ++ ++ writel(e4, MT7622_GPIO_DRIV(6)); ++ writel(e8, MT7622_GPIO_DRIV(7)); ++} ++ + int mtk_snand_init(void *dev, const struct mtk_snand_platdata *pdata, + struct mtk_snand **psnf) + { +@@ -1888,6 +1915,9 @@ int mtk_snand_init(void *dev, const stru + if (ret) + return ret; + ++ if (pdata->soc == SNAND_SOC_MT7622 && snand_info->drv) ++ mtk_mt7622_snand_adjust_drive(dev, snand_info->drv); ++ + rawpage_size = snand_info->memorg.pagesize + + snand_info->memorg.sparesize; + diff --git a/package/boot/arm-trusted-firmware-mediatek/patches/0003-mediatek-snfi-adjust-drive-strength-to-12mA-like-old.patch b/package/boot/arm-trusted-firmware-mediatek/patches/0003-mediatek-snfi-adjust-drive-strength-to-12mA-like-old.patch new file mode 100644 index 000000000..57de88f8c --- /dev/null +++ b/package/boot/arm-trusted-firmware-mediatek/patches/0003-mediatek-snfi-adjust-drive-strength-to-12mA-like-old.patch @@ -0,0 +1,135 @@ +From 40a3661bebb3d738ab95b7de66e9d8382d5b9ab1 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 10 Mar 2024 17:48:09 +0000 +Subject: [PATCH 3/3] mediatek: snfi: adjust drive strength to 12mA like old + loader does + +In addition to FM35X1GA, also change the driver strength to 12mA for +all chips where this is done by the old/legacy U-Boot: + * Winbond 512Mb + * Winbond 1Gb + * Winbond 2Gb + * GD5F4GQ4UBYIG + * GD5F4GQ4UAYIG + * GD5F1GQ4UX + * GD5F1GQ4UE + * GD5F2GQ4UX + * GD5F2GQ4UE + +Signed-off-by: Daniel Golle +--- + .../apsoc_common/drivers/snfi/mtk-snand-ids.c | 59 ++++++++++++++----- + 1 file changed, 44 insertions(+), 15 deletions(-) + +--- a/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c ++++ b/plat/mediatek/apsoc_common/drivers/snfi/mtk-snand-ids.c +@@ -80,65 +80,94 @@ static const struct snand_flash_info sna + SNAND_INFO("W25N512GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x20), + SNAND_MEMORG_512M_2K_64, + &snand_cap_read_from_cache_quad, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("W25N01GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x21), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("W25M02GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xab, 0x21), + SNAND_MEMORG_2G_2K_64_2D, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4, +- mtk_snand_winbond_select_die), ++ mtk_snand_winbond_select_die, ++ SNAND_DRV_12mA), + SNAND_INFO("W25N02KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x22), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + + SNAND_INFO("GD5F1GQ4UAWxx", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x10), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F1GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd1), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F1GQ4UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd9), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F1GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf1), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F2GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd2), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F2GQ5UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x32), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_a8d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F2GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf2), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F4GQ4UBxIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd4), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F4GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf4), + SNAND_MEMORG_4G_2K_64, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F2GQ5UExxG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x52), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_a8d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + SNAND_INFO("GD5F4GQ4UCxIG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0xb4), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, +- &snand_cap_program_load_x4), ++ &snand_cap_program_load_x4, ++ NULL, ++ SNAND_DRV_12mA), + + SNAND_INFO("MX35LF1GE4AB", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x12), + SNAND_MEMORG_1G_2K_64, diff --git a/package/boot/arm-trusted-firmware-tools/Makefile b/package/boot/arm-trusted-firmware-tools/Makefile index 81c8a99cb..209e945a0 100644 --- a/package/boot/arm-trusted-firmware-tools/Makefile +++ b/package/boot/arm-trusted-firmware-tools/Makefile @@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=arm-trusted-firmware-tools -PKG_VERSION:=2.7 +PKG_VERSION:=2.9 PKG_RELEASE:=1 -PKG_HASH:=53422dc649153838e03820330ba17cb10afe3e330ecde0db11e4d5f1361a33e6 +PKG_HASH:=76a66a1de0c01aeb83dfc7b72b51173fe62c6e51d6fca17cc562393117bed08b PKG_MAINTAINER:=Daniel Golle PKG_HOST_ONLY:=1 diff --git a/package/boot/uboot-amlogic/Makefile b/package/boot/uboot-amlogic/Makefile new file mode 100644 index 000000000..93e8f3bdb --- /dev/null +++ b/package/boot/uboot-amlogic/Makefile @@ -0,0 +1,57 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_VERSION:=20240315 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_PROTO:=default +PKG_SOURCE:=ophub-uboot-prebuilt-git-$(PKG_VERSION).tar.gz +PKG_SOURCE_VERSION:=abe491ab386607f9ab0d66728e5766bc5d7e8a20 +PKG_SOURCE_URL_FILE:=$(PKG_SOURCE_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/ophub/u-boot/archive/ +PKG_HASH:=3f98f5728f48d13f33cf4fd21fb6032a625ad3c61aa2e8073dda821f71f067ec + +PKG_MAINTAINER:=ophub + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk + +TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS) +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) + +define U-Boot/Default + BUILD_TARGET:=amlogic + UENV:=default + HIDDEN:=1 + DEFAULT:=y +endef + +define U-Boot/phicomm-n1 + NAME:=Phicomm N1 + OVERLAY:=u-boot-n1.bin + BUILD_SUBTARGET:=mesongx + BUILD_DEVICES:=phicomm_n1 +endef + +UBOOT_TARGETS := phicomm-n1 + +define Build/Configure + true +endef + +define Build/Compile + true +endef + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(CP) $(PKG_BUILD_DIR)/u-boot/amlogic/overload/$(OVERLAY) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot-overlay.bin +endef + +define Package/u-boot/install/default +endef + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips index 4323a2574..f2bc3555f 100644 --- a/package/boot/uboot-envtools/files/ramips +++ b/package/boot/uboot-envtools/files/ramips @@ -42,16 +42,18 @@ zbtlink,zbt-wg2626|\ zte,mf283plus) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000" ;; +h3c,tx1800-plus|\ +h3c,tx1801-plus|\ +h3c,tx1806|\ +jcg,q20) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" + ;; hootoo,ht-tm05|\ ravpower,rp-wd03) idx="$(find_mtd_index u-boot-env)" [ -n "$idx" ] && \ ubootenv_add_uci_config "/dev/mtd$idx" "0x4000" "0x1000" "0x1000" ;; -c-life,xg1|\ -jcg,q20) - ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" - ;; linksys,ea7300-v1|\ linksys,ea7500-v2|\ linksys,ea8100-v1|\ diff --git a/package/boot/uboot-mediatek/patches/100-02-drivers-mtd-add-support-for-MediaTek-SPI-NAND-flash-.patch b/package/boot/uboot-mediatek/patches/100-02-drivers-mtd-add-support-for-MediaTek-SPI-NAND-flash-.patch index 05138d984..42908621c 100644 --- a/package/boot/uboot-mediatek/patches/100-02-drivers-mtd-add-support-for-MediaTek-SPI-NAND-flash-.patch +++ b/package/boot/uboot-mediatek/patches/100-02-drivers-mtd-add-support-for-MediaTek-SPI-NAND-flash-.patch @@ -1213,7 +1213,7 @@ Signed-off-by: Weijie Gao + + SNAND_INFO("FM35Q1GA", SNAND_ID(SNAND_ID_DYMMY, 0xe5, 0x71), + SNAND_MEMORG_1G_2K_64, -+ &snand_cap_read_from_cache_x4, ++ &snand_cap_read_from_cache_x4_only, + &snand_cap_program_load_x4), + + SNAND_INFO("PN26G01A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe1), diff --git a/package/boot/uboot-sunxi/Makefile b/package/boot/uboot-sunxi/Makefile index 15593399d..19731ed40 100644 --- a/package/boot/uboot-sunxi/Makefile +++ b/package/boot/uboot-sunxi/Makefile @@ -337,6 +337,15 @@ define U-Boot/orangepi_zero2 ATF:=h616 endef +define U-Boot/orangepi_zero3 + BUILD_SUBTARGET:=cortexa53 + NAME:=Xunlong Orange Pi Zero3 + BUILD_DEVICES:=xunlong_orangepi-zero3 + DEPENDS:=+PACKAGE_u-boot-orangepi_zero3:trusted-firmware-a-sunxi-h616 + UENV:=h616 + ATF:=h616 +endef + define U-Boot/Bananapi_M2_Ultra BUILD_SUBTARGET:=cortexa7 NAME:=Bananapi M2 Ultra @@ -400,6 +409,7 @@ UBOOT_TARGETS := \ orangepi_2 \ orangepi_pc2 \ orangepi_zero2 \ + orangepi_zero3 \ pangolin \ pine64_plus \ Sinovoip_BPI_M3 \ diff --git a/package/devel/tmon/Makefile b/package/devel/tmon/Makefile index f0ad9dc57..6f9182ce9 100644 --- a/package/devel/tmon/Makefile +++ b/package/devel/tmon/Makefile @@ -1,53 +1,53 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=tmon -PKG_VERSION:=$(LINUX_VERSION) -PKG_RELEASE:=1 - -PKG_MAINTAINER:=Florian Eckert -PKG_LICENSE:=GPL-2.0-only - -include $(INCLUDE_DIR)/package.mk - -define Package/tmon - SECTION:=devel - CATEGORY:=Development - TITLE:=Thermal monitoring and testing tool - VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE) - URL:=http://www.kernel.org - DEPENDS:=+libncursesw -endef - -define Package/tmon/description - As hardware vendors cope with the thermal constraints on their products, - more and more sensors are added, new cooling capabilities are introduced. - To expose such relationship to the userspace, Linux generic thermal layer - introduced sysfs entry at /sys/class/thermal with a matrix of symbolic - links, trip point bindings, and device instances. To traverse such - matrix by hand is not a trivial task. - 'TMON' is conceived as a tool to help visualize, tune, and test the - complex thermal subsystem. -endef - -MAKE_FLAGS = \ - ARCH="$(LINUX_KARCH)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - CC="$(TARGET_CC)" \ - CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ - LDFLAGS="$(TARGET_LDFLAGS)" - -define Build/Compile - -$(MAKE) clean \ - -C $(LINUX_DIR)/tools/thermal/tmon - +$(MAKE_FLAGS) $(MAKE) \ - -C $(LINUX_DIR)/tools/thermal/tmon -endef - -define Package/tmon/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(LINUX_DIR)/tools/thermal/tmon/tmon \ - $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,tmon)) +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=tmon +PKG_VERSION:=$(LINUX_VERSION) +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Florian Eckert +PKG_LICENSE:=GPL-2.0-only + +include $(INCLUDE_DIR)/package.mk + +define Package/tmon + SECTION:=devel + CATEGORY:=Development + TITLE:=Thermal monitoring and testing tool + VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE) + URL:=http://www.kernel.org + DEPENDS:=+libncursesw +endef + +define Package/tmon/description + As hardware vendors cope with the thermal constraints on their products, + more and more sensors are added, new cooling capabilities are introduced. + To expose such relationship to the userspace, Linux generic thermal layer + introduced sysfs entry at /sys/class/thermal with a matrix of symbolic + links, trip point bindings, and device instances. To traverse such + matrix by hand is not a trivial task. + 'TMON' is conceived as a tool to help visualize, tune, and test the + complex thermal subsystem. +endef + +MAKE_FLAGS = \ + ARCH="$(LINUX_KARCH)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" + +define Build/Compile + -$(MAKE) clean \ + -C $(LINUX_DIR)/tools/thermal/tmon + +$(MAKE_FLAGS) $(MAKE) \ + -C $(LINUX_DIR)/tools/thermal/tmon +endef + +define Package/tmon/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(LINUX_DIR)/tools/thermal/tmon/tmon \ + $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,tmon)) diff --git a/package/firmware/ath11k-firmware/Makefile b/package/firmware/ath11k-firmware/Makefile index ea4977aa6..0e1c548e2 100644 --- a/package/firmware/ath11k-firmware/Makefile +++ b/package/firmware/ath11k-firmware/Makefile @@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ath11k-firmware -PKG_SOURCE_DATE:=2023-08-22 -PKG_SOURCE_VERSION:=d8f82a98ff1aef330d65d8b5660b46d1a9809ee3 -PKG_MIRROR_HASH:=3dba19449758c3b17f117990d7ad4086554e012b579f1de16e9d9196a7fbaaa7 +PKG_SOURCE_DATE:=2023-03-31 +PKG_SOURCE_VERSION:=a039049a9349722fa5c74185452ab04644a0d351 +PKG_MIRROR_HASH:=ed401e3f6e91d70565b3396139193f7e815f410db93700697205ac8ed1b828c5 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git @@ -32,6 +32,11 @@ define Package/ath11k-firmware-default DEPENDS:= endef +define Package/ath11k-firmware-ipq6018 +$(Package/ath11k-firmware-default) + TITLE:=IPQ6018 ath11k firmware +endef + define Package/ath11k-firmware-ipq8074 $(Package/ath11k-firmware-default) TITLE:=IPQ8074 ath11k firmware @@ -57,21 +62,30 @@ define Download/qcn9074-board endef $(eval $(call Download,qcn9074-board)) +define Package/ath11k-firmware-ipq6018/install + $(INSTALL_DIR) $(1)/lib/firmware/IPQ6018 + $(INSTALL_DIR) $(1)/lib/firmware/ath11k/IPQ6018/hw1.0 + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/ath11k-firmware/IPQ6018/hw1.0/2.5.0.1/WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1/* \ + $(1)/lib/firmware/IPQ6018/ +endef + define Package/ath11k-firmware-ipq8074/install $(INSTALL_DIR) $(1)/lib/firmware/IPQ8074 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/IPQ8074/hw2.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/IPQ8074/ endef define Package/ath11k-firmware-qcn9074/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/2.9.0.1/WLAN.HK.2.9.0.1-01890-QCAHKSWPL_SILICONZ-1/* \ + $(PKG_BUILD_DIR)/ath11k-firmware/QCN9074/hw1.0/testing/2.9.0.1/WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1/* \ $(1)/lib/firmware/ath11k/QCN9074/hw1.0/ $(INSTALL_BIN) \ $(DL_DIR)/$(QCN9074_BOARD_FILE) $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin endef +$(eval $(call BuildPackage,ath11k-firmware-ipq6018)) $(eval $(call BuildPackage,ath11k-firmware-ipq8074)) $(eval $(call BuildPackage,ath11k-firmware-qcn9074)) diff --git a/package/firmware/ath11k-wifi/Makefile b/package/firmware/ath11k-wifi/Makefile deleted file mode 100644 index 2c33df970..000000000 --- a/package/firmware/ath11k-wifi/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/version.mk - -PKG_NAME:=ath11k-wifi -PKG_RELEASE:=1 -PKG_FLAGS:=nonshared - -include $(INCLUDE_DIR)/package.mk - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) -endef - -define Build/Compile -endef - -# Use ath10k-bdencoder from https://github.com/qca/qca-swiss-army-knife.git -# to generate the board-* files here. -# -# This is intended to be used on an interim basis until device-specific -# board data for new devices is available through the upstream compilation -# -# Please send a mail with your device-specific board files upstream. -# You can find instructions and examples on the linux-wireless wiki: -# - -ALLWIFIBOARDS:= \ - edgecore-eap102 \ - gl-ax1800 \ - gl-axt1800 \ - qihoo_v6 - -ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ath11k-wifi-$(BOARD)) - -define Package/ath11k-wifi-default - SUBMENU:=ath11k Board-Specific Overrides - SECTION:=firmware - CATEGORY:=Firmware - DEPENDS:=@TARGET_ipq60xx - TITLE:=Custom Board -endef - -define ath11k-wifi-install-one-to - $(INSTALL_DIR) $(2)/lib/firmware/ath11k/$(3)/ - $(INSTALL_DATA) $(1) $(2)/lib/firmware/ath11k/$(3)/board-2.bin -endef - -define ath11k-wifi-install-one - $(if $(filter $(suffix $(1)),.IPQ6018 .ipq6018),\ - $(call ath11k-wifi-install-one-to,$(1),$(2),IPQ6018/hw1.0),\ - $(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\ - ) - -endef -# Blank line required at end of above define due to foreach context - -define generate-ath11k-wifi-package - define Package/ath11k-wifi-$(1) - $(call Package/ath11k-wifi-default) - TITLE:=board-2.bin Overrides for $(2) - CONFLICTS:=$(PREV_BOARD) - endef - - define Package/ath11k-wifi-$(1)/description -The $(2) requires board-specific, reference ("cal") data -that is not yet present in the upstream wireless firmware distribution. - -This package supplies board-2.bin file(s) that, in the interim, -overwrite those supplied by the ath10k-firmware-* packages. - -This is package is only necessary for the $(2). - -Do not install it for any other device! - endef - - define Package/ath11k-wifi-$(1)/install-overlay - $$$$(foreach IPQ_WIFI_BOARD_FILE,$$$$(wildcard board-$(1).*),\ - $$$$(call ath11k-wifi-install-one,$$$$(IPQ_WIFI_BOARD_FILE),$$(1))) - endef - - PREV_BOARD+=ath11k-wifi-$(1) -endef - -# Add board name to ALLWIFIBOARDS -# Place files in this directory as board-. -# Add $(eval $(call generate-ath11k-wifi-package,,)) - -$(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102)) -$(eval $(call generate-ath11k-wifi-package,gl-ax1800,Gl.iNET AX1800)) -$(eval $(call generate-ath11k-wifi-package,gl-axt1800,Gl.iNET AXT1800)) -$(eval $(call generate-ath11k-wifi-package,qihoo_v6,QIHOO 360V6)) - - -$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE)))) diff --git a/package/firmware/ath11k-wifi/board-2.bin.IPQ6018 b/package/firmware/ath11k-wifi/board-2.bin.IPQ6018 deleted file mode 100644 index 8c384dc89b367f1aab745d0e004bbd29c767432a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 787208 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�PGEB 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 diff --git a/package/firmware/ath11k-wifi/board-edgecore-eap102.bin.IPQ8074 b/package/firmware/ath11k-wifi/board-edgecore-eap102.bin.IPQ8074 deleted file mode 100644 index 211b995352b2e3992825da0f1e3f64e3fc07f651..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 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 T0tx|zfI>hapb$_9L=pJ^wl@k( diff --git a/package/firmware/ath11k-wifi/board-gl-ax1800.bin.IPQ6018 b/package/firmware/ath11k-wifi/board-gl-ax1800.bin.IPQ6018 deleted file mode 100644 index 9ee8d0a756d70b33321ed5da30e7d43501d533fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 787208 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�PGEB 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≪$jj3NLn_#-o#x3KO3P=T{0vEFaGw6A3cq<3a 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�PGEB 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 Mqykcb;S~7)0R(CGkpKVy diff --git a/package/firmware/ath11k-wifi/qdss_trace_config.bin b/package/firmware/ath11k-wifi/qdss_trace_config.bin deleted file mode 100644 index c212560df..000000000 --- a/package/firmware/ath11k-wifi/qdss_trace_config.bin +++ /dev/null @@ -1,99 +0,0 @@ -//This comment and parser will ignore -//Tracer scenario(or commands) always -//starts with start keyword -//Below commands to enable Event traces on UMAC,MAC0,MAC1 -//seq_start; -//seq_type:mem_req; -//memory size always given in KB. beow example reserves 3 buffers segments of 16 KB. -//sink:etr_ddr,0x1,0x1000; -//seq_end; -//Below commands to enable Event traces on UMAC,MAC0,MAC1 -seq_start; -seq_type:mac_event_trace; -sink:etr_ddr; -subsys_cfg_start:mac0; -hwsch:0x1, 0x000FFFF1,0x1036052C,0x0,0x0; -rxdma:0x2, 0x3400,0x8000,0x0,0x0; -crypto:0x3, 0xF79B3770,0x0,0x0,0x0; -txpcu:0x4, 0xD687F4E7,0x20000092,0x0,0x0; -txole:0x5, 0x640F0622,0x2,0x0,0x0; -pdg:0x6, 0x3C800706,0x0,0x0,0x0; -subsys_cfg_end:mac0; -subsys_cfg_start:mac1; -hwsch:0x7, 0x000FFFF1,0x1036052C,0x0,0x0; -rxdma:0x8, 0x3400,0x8000,0x0,0x0; -crypto:0x9, 0xF79B3770,0x0,0x0,0x0; -txpcu:0xA, 0xD687F4E7,0x20000092,0x0,0x0; -txole:0xB, 0x640F0622,0x2,0x0,0x0; -pdg:0xC, 0x3C800706,0x0,0x0,0x0; -subsys_cfg_end:mac1; -swap:0xFFFFFFFF; -trigger_start:trc; -wfi:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -ts0:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -ts1:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -ts2:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -ts3:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -ts4:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -trigger_end:trc; -memw:0xFFFFFFFF,0xFFFFFFFF; -seq_end; -// Below commands to enable obo trace on the mac0 -//seq_start; -//seq_type:mac_obo_trace; -//sink:etb_wcss; -//subsys_cfg_start:mac0; -//hwsch:0x1,0xABCDABCD; -//subsys_cfg_end:mac0; -//swap:0xABCDABCD; -//trigger_start:trc; -//wfi:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//ts0:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//ts1:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//ts2:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//ts3:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//ts4:0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF; -//trigger_end:trc; -//memw:0xFFFFFFFF,0xFFFFFFFF; -//seq_end; -// Below commands to enable TLV trace on the mac0 -//seq_start; -//seq_type:mac_tlv_trace; -//sink:etb_wcss; -//subsys_cfg_start:mac0; -//tlv_port:PDG_TXDMA_TLV; -//subsys_cfg_end:mac0; -//seq_end; -// Below commands to enable q6 etm -//seq_start; -//seq_type:q6_etm_trace; -//sink:etr_ddr; -//seq_end; -// Below commands to enable umac noc traces -//seq_start; -//seq_type:umac_noc_trace; -//sink:etb_wcss; -//ctrl:0x12; -//port_sel:0x4; -//lut:0xA; -//routeid_base:0x01000000; -//routeid_mask:0x01c00000; -//addr_lo:0x0; -//addr_hi:0x0; -//win_size:0x25; -//req_opcode:0x3; -//res_status:0x3; -//fltr_len:0xF; -//async_period:0xC; -//seq_end; -// Below commands to enable umac noc traces -//seq_start; -//seq_type:phy_tlv_trace; -//sink:etr_ddr; -//seq_end; -//seq_start; -//seq_type:phy_event_trace; -//sink:etr_ddr; -//phya:0x1,0x1; -//phyb:0x1,0x1; -//seq_end; diff --git a/package/firmware/b43legacy-firmware/Makefile b/package/firmware/b43legacy-firmware/Makefile deleted file mode 100755 index b7f325e13..000000000 --- a/package/firmware/b43legacy-firmware/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright (C) 2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=b43legacy-firmware -PKG_VERSION:=3.130.20.0 -PKG_RELEASE:=1 - -PKG_SOURCE:=wl_apsta-$(PKG_VERSION).o -PKG_SOURCE_URL:=@OPENWRT -PKG_HASH:=7dba610b1d96dd14e901bcbce14cd6ecd1b1ac6f5c0035b0d6b6dc46a7c3ef90 - -include $(INCLUDE_DIR)/package.mk - -define Package/b43legacy-firmware - SECTION:=firmware - CATEGORY:=Firmware - URL:=$(PKG_SOURCE_URL) - TITLE:=Broadcom bcm43xx b43legacy firmware -endef - -define Package/b43legacy-firmware/config - if PACKAGE_b43legacy-firmware - - config B43LEGACY_FW_SQUASH - bool "Remove unnecessary firmware files" - default y - help - This options allows you to remove unnecessary b43legacy firmware files - from the final rootfs image. This can reduce the rootfs size by - up to 50k. - - If unsure, say Y. - - config B43LEGACY_FW_SQUASH_COREREVS - string "Core revisions to include" - depends on B43LEGACY_FW_SQUASH - default "1,2,3,4" - help - This is a comma separated list of core revision numbers. - - Example (keep files for rev4 only): - 4 - - Example (keep files for rev2 and rev4): - 2,4 - - endif -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) -endef - -define Build/Compile - -endef - -define Package/b43legacy-firmware/install - $(INSTALL_DIR) $(1)/lib/firmware - b43-fwcutter --unsupported -w $(1)/lib/firmware/ $(DL_DIR)/$(PKG_SOURCE) - ifneq ($(CONFIG_B43LEGACY_FW_SQUASH),) - b43-fwsquash.py "G" "$(CONFIG_B43LEGACY_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43legacy" - endif -endef - -$(eval $(call BuildPackage,b43legacy-firmware)) diff --git a/package/firmware/cypress-firmware/Makefile b/package/firmware/cypress-firmware/Makefile index c5f41e0cb..6a14ff993 100644 --- a/package/firmware/cypress-firmware/Makefile +++ b/package/firmware/cypress-firmware/Makefile @@ -1,19 +1,14 @@ -# -# Copyright (C) 2019-2020 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# +# SPDX-License-Identifier: GPL-2.0-or-later include $(TOPDIR)/rules.mk PKG_NAME:=cypress-firmware -PKG_VERSION:=5.4.18-2021_0812 +PKG_VERSION:=5.10.9-2022_0909 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/Infineon/ifx-linux-firmware/ -PKG_MIRROR_HASH:=ac882b482dd401b53cdecc6004cd2bd3d65e888c19206dcf10931a28033ada4d +PKG_MIRROR_HASH:=944faae3a80013f1a963b6692d7f50a38c97edcf91fd163de521df755e6922b5 PKG_SOURCE_VERSION:=release-v$(PKG_VERSION) PKG_MAINTAINER:=Álvaro Fernández Rojas @@ -38,12 +33,19 @@ define Package/cypress-firmware-43012-sdio endef define Package/cypress-firmware-43012-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43012-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac43012-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43012-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43012-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac43012-sdio.bin + $(LN) \ + ../cypress/cyfmac43012-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac43012-sdio.clm_blob endef @@ -56,9 +58,13 @@ define Package/cypress-firmware-43340-sdio endef define Package/cypress-firmware-43340-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43340-sdio.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43340-sdio.bin \ $(1)/lib/firmware/brcm/brcmfmac43340-sdio.bin endef @@ -73,9 +79,13 @@ define Package/cypress-firmware-43362-sdio endef define Package/cypress-firmware-43362-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43362-sdio.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43362-sdio.bin \ $(1)/lib/firmware/brcm/brcmfmac43362-sdio.bin endef @@ -85,12 +95,18 @@ $(eval $(call BuildPackage,cypress-firmware-43362-sdio)) define Package/cypress-firmware-4339-sdio $(Package/cypress-firmware-default) TITLE:=CYW4339 FullMac SDIO firmware + PROVIDES:=brcmfmac-firmware-4339-sdio + CONFLICTS:=brcmfmac-firmware-4339-sdio endef define Package/cypress-firmware-4339-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4339-sdio.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4339-sdio.bin \ $(1)/lib/firmware/brcm/brcmfmac4339-sdio.bin endef @@ -105,17 +121,49 @@ define Package/cypress-firmware-43430-sdio endef define Package/cypress-firmware-43430-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43430-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac43430-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43430-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43430-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac43430-sdio.bin + $(LN) \ + ../cypress/cyfmac43430-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac43430-sdio.clm_blob endef $(eval $(call BuildPackage,cypress-firmware-43430-sdio)) +# Cypress 43439 SDIO Firmware +define Package/cypress-firmware-43439-sdio + $(Package/cypress-firmware-default) + TITLE:=CYW43439 FullMac SDIO firmware +endef + +define Package/cypress-firmware-43439-sdio/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac43439-sdio.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac43439-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43439-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac43439-sdio.bin + $(LN) \ + ../cypress/cyfmac43439-sdio.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac43439-sdio.clm_blob +endef + +$(eval $(call BuildPackage,cypress-firmware-43439-sdio)) + # Cypress 43455 SDIO Firmware define Package/cypress-firmware-43455-sdio $(Package/cypress-firmware-default) @@ -125,12 +173,19 @@ define Package/cypress-firmware-43455-sdio endef define Package/cypress-firmware-43455-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43455-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac43455-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43455-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43455-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac43455-sdio.bin + $(LN) \ + ../cypress/cyfmac43455-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.clm_blob endef @@ -143,12 +198,19 @@ define Package/cypress-firmware-4354-sdio endef define Package/cypress-firmware-4354-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4354-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac4354-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4354-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4354-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac4354-sdio.bin + $(LN) \ + ../cypress/cyfmac4354-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac4354-sdio.clm_blob endef @@ -161,12 +223,19 @@ define Package/cypress-firmware-4356-pcie endef define Package/cypress-firmware-4356-pcie/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4356-pcie.bin \ - $(1)/lib/firmware/brcm/brcmfmac4356-pcie.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4356-pcie.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4356-pcie.bin \ + $(1)/lib/firmware/brcm/brcmfmac4356-pcie.bin + $(LN) \ + ../cypress/cyfmac4356-pcie.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac4356-pcie.clm_blob endef @@ -179,12 +248,19 @@ define Package/cypress-firmware-4356-sdio endef define Package/cypress-firmware-4356-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4356-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac4356-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4356-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4356-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac4356-sdio.bin + $(LN) \ + ../cypress/cyfmac4356-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac4356-sdio.clm_blob endef @@ -197,17 +273,49 @@ define Package/cypress-firmware-43570-pcie endef define Package/cypress-firmware-43570-pcie/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43570-pcie.bin \ - $(1)/lib/firmware/brcm/brcmfmac43570-pcie.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac43570-pcie.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac43570-pcie.bin \ + $(1)/lib/firmware/brcm/brcmfmac43570-pcie.bin + $(LN) \ + ../cypress/cyfmac43570-pcie.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac43570-pcie.clm_blob endef $(eval $(call BuildPackage,cypress-firmware-43570-pcie)) +# Cypress 4373 PCIe Firmware +define Package/cypress-firmware-4373-pcie + $(Package/cypress-firmware-default) + TITLE:=CYW4373 FullMac PCIe firmware +endef + +define Package/cypress-firmware-4373-pcie/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac4373-pcie.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac4373-pcie.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4373-pcie.bin \ + $(1)/lib/firmware/brcm/brcmfmac4373-pcie.bin + $(LN) \ + ../cypress/cyfmac4373-pcie.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac4373-pcie.clm_blob +endef + +$(eval $(call BuildPackage,cypress-firmware-4373-pcie)) + # Cypress 4373 SDIO Firmware define Package/cypress-firmware-4373-sdio $(Package/cypress-firmware-default) @@ -215,12 +323,19 @@ define Package/cypress-firmware-4373-sdio endef define Package/cypress-firmware-4373-sdio/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4373-sdio.bin \ - $(1)/lib/firmware/brcm/brcmfmac4373-sdio.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4373-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4373-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac4373-sdio.bin + $(LN) \ + ../cypress/cyfmac4373-sdio.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac4373-sdio.clm_blob endef @@ -233,12 +348,19 @@ define Package/cypress-firmware-4373-usb endef define Package/cypress-firmware-4373-usb/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4373-usb.bin \ - $(1)/lib/firmware/brcm/brcmfmac4373-usb.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac4373.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac4373-usb.bin \ + $(1)/lib/firmware/brcm/brcmfmac4373-usb.bin + $(LN) \ + ../cypress/cyfmac4373.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac4373.clm_blob endef @@ -251,13 +373,114 @@ define Package/cypress-firmware-54591-pcie endef define Package/cypress-firmware-54591-pcie/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DIR) $(1)/lib/firmware/cypress $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac54591-pcie.bin \ - $(1)/lib/firmware/brcm/brcmfmac54591-pcie.bin + $(1)/lib/firmware/cypress/ $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/firmware/cyfmac54591-pcie.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac54591-pcie.bin \ + $(1)/lib/firmware/brcm/brcmfmac54591-pcie.bin + $(LN) \ + ../cypress/cyfmac54591-pcie.clm_blob \ $(1)/lib/firmware/brcm/brcmfmac54591-pcie.clm_blob endef $(eval $(call BuildPackage,cypress-firmware-54591-pcie)) + +# Cypress 54591 SDIO Firmware +define Package/cypress-firmware-54591-sdio + $(Package/cypress-firmware-default) + TITLE:=CYW54591 FullMac SDIO firmware +endef + +define Package/cypress-firmware-54591-sdio/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac54591-sdio.bin \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac54591-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac54591-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac54591-sdio.bin + $(LN) \ + ../cypress/cyfmac54591-sdio.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac54591-sdio.clm_blob +endef + +$(eval $(call BuildPackage,cypress-firmware-54591-sdio)) + +# Cypress 55560 PCIe Firmware +define Package/cypress-firmware-55560-pcie + $(Package/cypress-firmware-default) + TITLE:=CYW55560 FullMac PCIe firmware +endef + +define Package/cypress-firmware-55560-pcie/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac55560-pcie.trxse \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac55560-pcie.trxse \ + $(1)/lib/firmware/brcm/brcmfmac55560-pcie.trxse +endef + +$(eval $(call BuildPackage,cypress-firmware-55560-pcie)) + +# Cypress 55572 PCIe Firmware +define Package/cypress-firmware-55572-pcie + $(Package/cypress-firmware-default) + TITLE:=CYW55572 FullMac PCIe firmware +endef + +define Package/cypress-firmware-55572-pcie/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac55572-pcie.trxse \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac55572-pcie.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac55572-pcie.trxse \ + $(1)/lib/firmware/brcm/brcmfmac55572-pcie.trxse + $(LN) \ + ../cypress/cyfmac55572-pcie.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac55572-pcie.clm_blob +endef + +$(eval $(call BuildPackage,cypress-firmware-55572-pcie)) + +# Cypress 55572 SDIO Firmware +define Package/cypress-firmware-55572-sdio + $(Package/cypress-firmware-default) + TITLE:=CYW55572 FullMac SDIO firmware +endef + +define Package/cypress-firmware-55572-sdio/install + $(INSTALL_DIR) $(1)/lib/firmware/cypress + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac55572-sdio.trxse \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/firmware/cyfmac55572-sdio.clm_blob \ + $(1)/lib/firmware/cypress/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../cypress/cyfmac55572-sdio.trxse \ + $(1)/lib/firmware/brcm/brcmfmac55572-sdio.trxse + $(LN) \ + ../cypress/cyfmac55572-sdio.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac55572-sdio.clm_blob +endef + +$(eval $(call BuildPackage,cypress-firmware-55572-sdio)) diff --git a/package/firmware/cypress-nvram/Makefile b/package/firmware/cypress-nvram/Makefile index 806bfa2d9..dcf09d959 100644 --- a/package/firmware/cypress-nvram/Makefile +++ b/package/firmware/cypress-nvram/Makefile @@ -1,108 +1,38 @@ -# -# Copyright (C) 2019 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# +# SPDX-License-Identifier: GPL-2.0-or-later include $(TOPDIR)/rules.mk PKG_NAME:=cypress-nvram -PKG_SOURCE_DATE:=2019-09-03 -PKG_SOURCE_VERSION:=e7b78df22f2a0c5f56abb7b5880661611de35e5f -PKG_MIRROR_HASH:=1cb20a749696852be0a512d51961365dd9c031362af0af1a2b9f5a3fb894885f -PKG_RELEASE:=2 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/openwrt/cypress-nvram.git +PKG_RELEASE:=7 PKG_MAINTAINER:=Álvaro Fernández Rojas -PKG_FLAGS:=nonshared - include $(INCLUDE_DIR)/package.mk define Package/cypress-nvram-default SECTION:=firmware CATEGORY:=Firmware - URL:=https://community.cypress.com/community/linux endef define Build/Compile true endef -# Cypress 43430 SDIO Raspberry Pi 3B NVRAM -define Package/cypress-nvram-43430-sdio-rpi-3b +# Cypress 4339 SDIO NVRAM +define Package/cypress-nvram-4339-sdio $(Package/cypress-nvram-default) - TITLE:=CYW43430 NVRAM for Raspberry Pi 3B - DEPENDS:=@TARGET_bcm27xx - PROVIDES:=brcmfmac-firmware-43430-sdio-rpi-3b - CONFLICTS:=brcmfmac-firmware-43430-sdio-rpi-3b + TITLE:=BCM4339 SDIO NVRAM + CONFLICTS:=brcmfmac-nvram-4339-sdio endef -define Package/cypress-nvram-43430-sdio-rpi-3b/install +define Package/cypress-nvram-4339-sdio/install $(INSTALL_DIR) $(1)/lib/firmware/brcm $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/brcmfmac43430-sdio.raspberrypi,3-model-b.txt \ - $(1)/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt + ./files/brcmfmac4339-sdio.AP6335.txt \ + $(1)/lib/firmware/brcm/ + $(LN) \ + brcmfmac4339-sdio.AP6335.txt \ + $(1)/lib/firmware/brcm/brcmfmac4339-sdio.technexion,imx7d-pico-pi.txt endef -$(eval $(call BuildPackage,cypress-nvram-43430-sdio-rpi-3b)) - -# Cypress 43430 SDIO Raspberry Pi Zero W NVRAM -define Package/cypress-nvram-43430-sdio-rpi-zero-w - $(Package/cypress-nvram-default) - TITLE:=CYW43430 NVRAM for Raspberry Pi Zero W - DEPENDS:=@TARGET_bcm27xx - PROVIDES:=brcmfmac-firmware-43430-sdio-rpi-zero-w - CONFLICTS:=brcmfmac-firmware-43430-sdio-rpi-zero-w -endef - -define Package/cypress-nvram-43430-sdio-rpi-zero-w/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/brcmfmac43430-sdio.raspberrypi,model-zero-w.txt \ - $(1)/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-w.txt -endef - -$(eval $(call BuildPackage,cypress-nvram-43430-sdio-rpi-zero-w)) - -# Cypress 43455 SDIO Raspberry Pi 3B+ NVRAM -define Package/cypress-nvram-43455-sdio-rpi-3b-plus - $(Package/cypress-nvram-default) - TITLE:=CYW43455 NVRAM for Raspberry Pi 3B+ - DEPENDS:=@TARGET_bcm27xx - PROVIDES:=brcmfmac-firmware-43455-sdio-rpi-3b-plus - CONFLICTS:=brcmfmac-firmware-43455-sdio-rpi-3b-plus -endef - -define Package/cypress-nvram-43455-sdio-rpi-3b-plus/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt \ - $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt -endef - -$(eval $(call BuildPackage,cypress-nvram-43455-sdio-rpi-3b-plus)) - -# Cypress 43455 SDIO Raspberry Pi 4B NVRAM -define Package/cypress-nvram-43455-sdio-rpi-4b - $(Package/cypress-nvram-default) - TITLE:=CYW43455 NVRAM for Raspberry Pi 4B - DEPENDS:=@TARGET_bcm27xx - PROVIDES:=brcmfmac-firmware-43455-sdio-rpi-4b - CONFLICTS:=brcmfmac-firmware-43455-sdio-rpi-4b -endef - -define Package/cypress-nvram-43455-sdio-rpi-4b/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ - $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,4-model-b.txt - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ - $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,4-compute-module.txt -endef - -$(eval $(call BuildPackage,cypress-nvram-43455-sdio-rpi-4b)) +$(eval $(call BuildPackage,cypress-nvram-4339-sdio)) diff --git a/package/firmware/cypress-nvram/files/brcmfmac4339-sdio.AP6335.txt b/package/firmware/cypress-nvram/files/brcmfmac4339-sdio.AP6335.txt new file mode 100644 index 000000000..1ddd92950 --- /dev/null +++ b/package/firmware/cypress-nvram/files/brcmfmac4339-sdio.AP6335.txt @@ -0,0 +1,99 @@ +#AP6335_NVRAM_V1.5_03112014 +NVRAMRev=$Rev: 410316 $ +sromrev=11 +boardrev=0x1203 +boardtype=0x06c5 +boardflags=0x00000c01 +boardflags2=0x00002000 +boardflags3=0x101188 +macaddr=00:90:4c:c5:12:38 +ccode=0 +regrev=0 +antswitch=0 +pdgain2g=7 +pdgain5g=7 +tworangetssi2g=0 +tworangetssi5g=0 +femctrl=7 +pcieingress_war=15 +vendid=0x14e4 +devid=0x43ae +manfid=0x2d0 +nocrc=1 +otpimagesize=502 +xtalfreq=37400 +extpagain2g=2 +pdetrange2g=2 +extpagain5g=2 +pdetrange5g=2 +rxgains2gelnagaina0=0 +rxgains2gtrisoa0=7 +rxgains2gtrelnabypa0=0 +rxgains5gelnagaina0=0 +rxgains5gtrisoa0=11 +rxgains5gtrelnabypa0=0 +rxchain=1 +txchain=1 +aa2g=1 +aa5g=1 +tssipos5g=0 +tssipos2g=0 +pa2ga0=-161,6269,-723 +pa2gccka0=-116,7568,-852 +pa5ga0=0xFF61,0x163C,0xFD55,0xFF5D,0x1671,0xFD4F,0xFF5F,0x16CA,0xFD45,0xFF60,0x1676,0xFD4D +pa5gbw40a0=0xFF61,0x163C,0xFD55,0xFF5D,0x1671,0xFD4F,0xFF5F,0x16CA,0xFD45,0xFF60,0x1676,0xFD4D +pa5gbw80a0=0xFF61,0x163C,0xFD55,0xFF5D,0x1671,0xFD4F,0xFF5F,0x16CA,0xFD45,0xFF60,0x1676,0xFD4D +pdoffset40ma0=0 +pdoffset80ma0=0 +pdoffsetcckma0=0 +maxp2ga0=75 +maxp5ga0=64,64,72,72 +cckbw202gpo=0x0000 +cckbw20ul2gpo=0x0 +mcsbw202gpo=0x99445533 +mcsbw402gpo=0x99775533 +dot11agofdmhrbw202gpo=0x2233 +ofdmlrbw202gpo=0x0000 +tssifloor2g=500 +mcsbw205glpo=0x66333330 +mcsbw405glpo=0x66665530 +mcsbw805glpo=0xAA555530 +mcsbw1605glpo=0x99555530 +mcsbw205gmpo=0x99BB5530 +mcsbw405gmpo=0x99BB5530 +mcsbw805gmpo=0xEE555530 +mcsbw1605gmpo=0x99555530 +mcsbw205ghpo=0x99995530 +mcsbw405ghpo=0x99BB5530 +mcsbw805ghpo=0xEE555530 +mcsbw1605ghpo=0x99555530 +mcslr5glpo=0x0000 +mcslr5gmpo=0x0000 +mcslr5ghpo=0x0000 +sb20in40hrrpo=0x0 +sb20in80and160hr5glpo=0x0 +sb40and80hr5glpo=0x0 +sb20in80and160hr5gmpo=0x0 +sb40and80hr5gmpo=0x0 +sb20in80and160hr5ghpo=0x0 +sb40and80hr5ghpo=0x0 +sb20in40lrpo=0x0 +sb20in80and160lr5glpo=0x0 +sb40and80lr5glpo=0x0 +sb20in80and160lr5gmpo=0x0 +sb40and80lr5gmpo=0x0 +sb20in80and160lr5ghpo=0x0 +sb40and80lr5ghpo=0x0 +dot11agduphrpo=0x0 +dot11agduplrpo=0x0 +phycal_tempdelta=25 +cckdigfilttype=2 +pacalidx2g=65 +dacrate2g=160 +swctrlmap_5g=0x00000008,0x00000010,0x00000008,0x000000,0x038 +swctrlmap_2g=0x00000001,0x00000002,0x00000001,0x040002,0x0ff +swctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x000 +swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x000 +rssicorrnorm_c0=3,3 +rssicorrnorm5g_c0=2,3,4,2,3,3,0,1,2,0,1,2 +muxenab=0x10 diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index 3729ee65f..b79ccf647 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/version.mk PKG_NAME:=ipq-wifi -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git -PKG_SOURCE_DATE:=2023-06-03 -PKG_SOURCE_VERSION:=cd9c30ca47b8e5388b770c523a7f6b8b969e2f92 -PKG_MIRROR_HASH:=45e623fcc512b514ade0f22e217275536aa8de4afba7dfdb11696482b8fa71a2 +PKG_SOURCE_DATE:=2024-04-16 +PKG_SOURCE_VERSION:=1d51799e6768a304da7840b8346e7487efd77f49 +PKG_MIRROR_HASH:=9cf0917532283c1a1708643022a5ed1ec4af6bb9ebaff57fc2f0f2c229f2469e PKG_FLAGS:=nonshared @@ -28,21 +28,38 @@ endef # ALLWIFIBOARDS:= \ + arcadyan_aw1000 \ buffalo_wxr-5950ax12 \ compex_wpq873 \ dynalink_dl-wrx36 \ edgecore_eap102 \ edimax_cax1800 \ + glinet_gl-ax1800 \ + glinet_gl-axt1800 \ + jdcloud_ax1800pro \ + jdcloud_ax6600 \ + linksys_mr7350 \ + linksys_mx4200 \ + linksys_mx5300 \ + netgear_lbr20 \ netgear_rax120v2 \ + netgear_wax214 \ netgear_wax218 \ - p2w_r619ac \ + netgear_wax620 \ + netgear_wax630 \ prpl_haze \ + qihoo_360v6 \ qnap_301w \ + redmi_ax5-jdcloud \ redmi_ax6 \ wallys_dr40x9 \ xiaomi_ax3600 \ xiaomi_ax9000 \ - zte_mf289f \ + xiaomi_rm1800 \ + yuncore_ax880 \ + yuncore_fap650 \ + zte_mf269 \ + zte_mf287 \ zte_mf287plus \ zyxel_nbg7815 @@ -52,7 +69,7 @@ define Package/ipq-wifi-default SUBMENU:=ath10k Board-Specific Overrides SECTION:=firmware CATEGORY:=Firmware - DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x) + DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_qualcommax) TITLE:=Custom Board endef @@ -77,12 +94,14 @@ define ipq-wifi-install-one $(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\ $(if $(filter $(suffix $(1)),.QCA99X0 .qca99x0),\ $(call ipq-wifi-install-one-to,$(1),$(2),QCA99X0/hw2.0),\ + $(if $(filter $(suffix $(1)),.IPQ6018 .ipq6018),\ + $(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ6018/hw1.0),\ $(if $(filter $(suffix $(1)),.IPQ8074 .ipq8074),\ $(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ8074/hw2.0),\ $(if $(filter $(suffix $(1)),.QCN9074 .qcn9074),\ $(call ipq-wifi-install-ath11-one-to,$(1),$(2),QCN9074/hw1.0),\ $(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\ - ))))))) + )))))))) endef # Blank line required at end of above define due to foreach context @@ -118,21 +137,38 @@ endef # Place files in this directory as board-. # Add $(eval $(call generate-ipq-wifi-package,,)) +$(eval $(call generate-ipq-wifi-package,arcadyan_aw1000,Arcadyan AW1000)) $(eval $(call generate-ipq-wifi-package,buffalo_wxr-5950ax12,Buffalo WXR-5950AX12)) $(eval $(call generate-ipq-wifi-package,compex_wpq873,Compex WPQ-873)) $(eval $(call generate-ipq-wifi-package,dynalink_dl-wrx36,Dynalink DL-WRX36)) $(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102)) $(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800)) +$(eval $(call generate-ipq-wifi-package,glinet_gl-ax1800,GL.iNet GL-AX1800)) +$(eval $(call generate-ipq-wifi-package,glinet_gl-axt1800,GL.iNet GL-AXT1800)) +$(eval $(call generate-ipq-wifi-package,jdcloud_ax1800pro,JDCloud AX1800 Pro)) +$(eval $(call generate-ipq-wifi-package,jdcloud_ax6600,JDCloud AX6600)) +$(eval $(call generate-ipq-wifi-package,linksys_mr7350,Linksys MR7350)) +$(eval $(call generate-ipq-wifi-package,linksys_mx4200,Linksys MX4200)) +$(eval $(call generate-ipq-wifi-package,linksys_mx5300,Linksys MX5300)) +$(eval $(call generate-ipq-wifi-package,netgear_lbr20,Netgear LBR20)) $(eval $(call generate-ipq-wifi-package,netgear_rax120v2,Netgear RAX120v2)) +$(eval $(call generate-ipq-wifi-package,netgear_wax214,Netgear WAX214)) $(eval $(call generate-ipq-wifi-package,netgear_wax218,Netgear WAX218)) -$(eval $(call generate-ipq-wifi-package,p2w_r619ac,P&W R619AC)) +$(eval $(call generate-ipq-wifi-package,netgear_wax620,Netgear WAX620)) +$(eval $(call generate-ipq-wifi-package,netgear_wax630,Netgear WAX630)) +$(eval $(call generate-ipq-wifi-package,qihoo_360v6,Qihoo 360V6)) $(eval $(call generate-ipq-wifi-package,qnap_301w,QNAP 301w)) $(eval $(call generate-ipq-wifi-package,prpl_haze,prpl Haze)) +$(eval $(call generate-ipq-wifi-package,redmi_ax5-jdcloud,Redmi AX5 JDCloud)) $(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6)) $(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax9000,Xiaomi AX9000)) -$(eval $(call generate-ipq-wifi-package,zte_mf289f,ZTE MF289F)) +$(eval $(call generate-ipq-wifi-package,xiaomi_rm1800,Xiaomi RM1800)) +$(eval $(call generate-ipq-wifi-package,yuncore_ax880,Yuncore AX880)) +$(eval $(call generate-ipq-wifi-package,yuncore_fap650,Yuncore FAP650)) +$(eval $(call generate-ipq-wifi-package,zte_mf269,ZTE MF269)) +$(eval $(call generate-ipq-wifi-package,zte_mf287,ZTE MF287)) $(eval $(call generate-ipq-wifi-package,zte_mf287plus,ZTE MF287Plus)) $(eval $(call generate-ipq-wifi-package,zyxel_nbg7815,Zyxel NBG7815)) diff --git a/package/firmware/ipq-wifi/board-8dev_habanero-dvk.qca4019 b/package/firmware/ipq-wifi/board-8dev_habanero-dvk.qca4019 deleted file mode 100644 index 9048239cf9f59bbc4df70251b73adfe93382ae62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24324 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 diff --git a/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 b/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 deleted file mode 100644 index 4848115cfbe3a4a0ed6b17cac929731ecbd7968c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24316 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 NIrrxNmNc!u{{!hMI2Hf^ diff --git a/package/firmware/ipq-wifi/board-asus_rt-acrh17.qca4019 b/package/firmware/ipq-wifi/board-asus_rt-acrh17.qca4019 deleted file mode 100644 index d45d16af7f7bc8de104558f09fccb34619557071..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12164 zcmWG^cGPtY@h~*-)^+lC402(}&CO*1f((5S$-rO^#7U*awuu=@I!U>iy2%-t1-h9j zwgzBcQhs7l3W#fDpi`Dul$n@UVjC2q>*yThVQ8Mq2-K?pG)Fk9)_8L29OC3 zpzE6ev5Db75CG+%JgBNA=&E6SeuhQ`M+Qe176t(*gvo&12xB8?d-7e3Fa*frg4?UW z0D(Y31!N^6LdZOO5q5TVR#sMKB*4J17vxhSfhbTNG8O~!kuj0Rz?Ja>0h}|$83lc7 zK*V)F^LHi+!7CPp-_33h{K>w`z8KS5ao5r`f*MKvr>Pkf-SnAUJwl zQ=MVo+Sy%|Nl~6a$qln7RAxp6c-rk-2~q|WvjA%7?kbP+@w5hOIH9h^uy5n+UZ4%W zo|gO812trUH7o-fk`d)?p#d~*Qe{C@kc9zMgF34F2=FR_fPfNI=}`@+;enku96|}Z z&xV%hlJ3NE%T)C+8Sg`ri|XBS_2NaH_O2?N>DI1MB#|(4b@WWjc75AMGc&MSW`hFu6%7#v5+`Z{jO0{Qlz~W9Nl{T*Nl{5DjD-WOO#*Y$ zC{4oUCQ&N%#+VK7Rr}zKuMh1F1S|9;1Ljx=|NW{P%KqCa@1O*-C z90d*K3|*SP>-3ItUzKSnG5r#jSbw#!-gp=C;U!WP+Cq}Puj;>&iS3Qptqd2p0|&& zobfwjL2Ef{J!>Cu+JL4ANZc&e)?U3@13w84HAsL_M1qoSLFe2x$XJy^fK;_$Wuj#j zinzm}O*-laVv@jUD2;{^ju0448aM(5MR-Jp5=sb+az;a7Gz3ONU^E0qLtr!nMsNs- z8;J|b3%MJ)3;GM08<`8*3vs{zLr~JBMVk&Ili;I@TWb+}C!lrlas89iIhGB5z?ik<~q&Z5(Lx;i>KS{f<}a)Xlvbexu! zh8oa)gOmky9@KqnZ0oUiq16Kp70GC230WpZ4AY{m( zq$DGwga)Pn#W6*dlwu~UFxXfyGJMHrV3@)#$mn3gz@Wh)$Y8@@!;-)z$iO7Z#1#Xi z1q8s8jz}&UWe&Fx_`iWigo!ByI0FHkU1nn8m<|LBfdJ;u9Y8>dm`?<-a9yzFBraNA zO;u$eF=XZrGFJzgo%0C@iHJ!^$>^CdWyYKZOIEDeuw}>IgGW!EC0&An4eF+n*YHzPMeKOr+CGeJ9{s97M0sTo$!!RVpT#Q^|dOd@#z diff --git a/package/firmware/ipq-wifi/board-avm_fritzrepeater-1200.qca4019 b/package/firmware/ipq-wifi/board-avm_fritzrepeater-1200.qca4019 deleted file mode 100644 index d78a49d4dbf3fc22c40a83d052fc7c55542ff8e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24332 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 F{|7QKi|GIW diff --git a/package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca4019 b/package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca4019 deleted file mode 100644 index 8305ba0166a2c07054d0789f1abaf3119c7c31bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24332 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 S+N+$ubtLzGvG1Cu$NxVG<{kV1 diff --git a/package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca9984 b/package/firmware/ipq-wifi/board-buffalo_wtr-m2133hp.qca9984 deleted file mode 100644 index 656cb99cbb2b6de86639ae8dc8eee73c5c7cb490..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12172 zcmeHMYfuwc6ut={h*+{oL=CvSb$k#Zp@14*ks_5_udf5lX@?4@DwWdTYFAyIniscvQ<%#zn3`Yg@ zbGN;V(mE0m-#j)dm`52i+B=W;y}`$>^TD}u^8sz_fR|_likKteh9X35lX#|^o12S^ z3xz^~wN(JXdcLf^~g`f-1y zvLqud4NHyzG@8elbIi)n;GiIX*!%03pPrA7E`plXMi`&}`h@E0`nScG0w6xiiudwz z9mD74WeBad7cYJvv(08BYm?Qr!GN-3b!|i;Vh7I=nT`hpMUX@^5s5$}5Lxk&W0fcB z&YYd90N$8%JEhQ3I-CB0j<8S`n}yL(8nOiCqkK010Uz0nZf0-B63_%B1?8X|Hs=8c zS&yz~ugAjCa3lsDpM?6-^y>JWc)amhk?NG^GZRV}DB~#u@kM>vzSu@|Boa^+F5fGP z9~soQs=k!(5v?Ntr-%^@Cbd>kCEX`TGTbLL@vf9ueV@9$v`U* zuhhxq$}1^?4kSw?OAZ(yUkwMuykvHorI*lThhzYp?91umU0&JbbG*{<$yIIxsz792 zCfSWGEvssMOIy1o*EgwGR4*yk4;;O-<(gk5B5%2Kpq*aM zaoe`$)zz$$#{S*k#p(QU`jPts{EI7apU=GW)!mZzC{=(0DZJ2?-x{g(FQer*4@>Vv zYXg)>>A=t??JDJxQrdof->&xP^Zr$gVp%)?TxjLuq6Nb0q4ciR%}Y-%EV?pu;C7V8 z{}fW(a4%K2s(wkC_r7m?cD6<~EIUdstmxU%5!%2!<|U~##%Y7SYFMP zdF|;p#We*h82i04Zw!}oZ@v~#OFw+ZnB20wmRaPLJ=C|MDX;>OdWu?ZORk33vJQKT zHN%JQ32ua6WR@!oyz>E-A4omZ+f0%UcKy<_g*j*LWq0tJS>+$>BVQqs0g{2a%Yd8v z`~?fW5yqm$OMREwt;~onv0nH$ai1*H(4Z;LN(dM_D&U}@p&{@L4hjqi4h#$m6uNoX za+K4+W@w^NUEHXE>f$=j-33CZ?(>LkHg|U_Y~0;lhz7jcXEA3n;!oei*@SGPM{}Z) zc)Ev8z>e(tOE-Hb*S4jL=)2}F)YB0QAG z=3$Yuw!WSi)fvr)GDowHrn(QooUe?~Zr diff --git a/package/firmware/ipq-wifi/board-cellc_rtl30vw.qca4019 b/package/firmware/ipq-wifi/board-cellc_rtl30vw.qca4019 deleted file mode 100644 index 2fff2bf5fc7ce41c624ef14f5ed5d5f2df2015b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24316 zcmeHPTTl~O8a`mSsHk)J_&hB&GIg&!COSJ(mYbTN4k{}v0Tgug+CwoSH~@q_~r$+S+i@Q|5SLh)WnsWRQ8?2DHV(<=&0DuR&fhw$y-?ci8bW1%83GXlD{G?psT z;jml1ZO}DaB6u>^d%01g$d^P7WmoX`_@q1>s5+Ze zE-VVbp5JNwCik4ECb0C|k$U}}3z7AlqtC8unlg^?G8u_a2di4Ls>1g9q~E@!?3TCv zsy?9n;aFW?)Ttm1qj+_pL}hD6z|CXh<}KS02Fuq!ATY@Mi9g#CpRu!I_Ofc>1rY!) zF0QVwE=0XygPWV1`?Porbu<*qU!2YpFhfH4@F$cP9L(nh^LPa`PcVIjVl^ApSy2Q! zI_m27?!_`BVDn~ocQTYj7|Q4If?$W~@t^k}KCqxh+6ZHymxn8j_FvOb7hubuoMq)| z%_zJcfzxYFwT}{oh$NVnunQ6go;5(O=RLHp&*UF>llx@k3>(OeA|LL$c5; zQ5KehrXX@ujEY6#mtrIlO%x?!(P%UxL1&UM4A@p@a*|4CvZB;^$HyK>7%1Z{0|`I_ zL;+YDn)Wsg$wsq9*;p(Z`!*IyLX$*E7E7w$>!{*>lF_Kq{IQBqa!XpP&%gDE7PsO69G~nrKJD_{Pn4@8GsnTM<9<1 z5^s2r&too9XqUMOU&}m%e}jc+O~spr0FP!j?ht(c&Fi1RPe1)^Y6+bvl&oC@e!1(# zbfuNS9S8tiTxp))K)C_Myy6E?mSV#S;fHJg_>T*<;bEa6pR$lUcjR6jxjTpD?JYc5 zTvo2@xYB*Ce{g8@?)ZbpfBNCaSB}47v5)82mFub*4NUu>7`@fJ6KdK6#bmAKT~O2h zCnjz+?|?cE;({J)AKg`R8mz5E?b$QVDL8brz3cidd}8u13+ZbMmD$xWKQIvv$`Nre zCP@E~j$kMz!mxA@_aP3EqEe9*i(9t)>)EJ|Xg*>e1f^$)Gmsp5yf_}&MOX9?ulaMB zzvs;DYPrR6lyjf(QO>qr1BH|L(nk%)m>1+vY3UlGo|9dRAu+ye%KVY6^J96%H=FE2;R z#*HhnIdr~(+MxwRiHF54*^6d$IiIn?L ztdMxn{rHu|?S++U>-WXdHg(>p#xX;Tjx*J2tiZDkVqM_mgrQ4&yeLBwI(ZKt)M-^k z5)ScqV%NIE1z@Vv*oZ3(DZ0q1t41w;z#!8_;p2vWm8vL55;6Hl!)0w{kxarR91QyK za4^+lJcA!I9OYQsKlB>t_gOI0mTmx!T5r&eutxULTu0yyjVI;-_vJ zJMjixp-PHR>UveR^4$VIQ-liD0Wu{+50R3=*oIeV(~Cl;28@^RYTZ87F8n*4UR5WT z3j!t|7_OR93L;Xv-Xnk!x{Y7qrP^I`Hgs*pm0FoR0RMxbPgN;Tl|&i8!v}PYs{Il+ z;n3G33awGObkZ4-?UAPZVWKgvJTHM^~-Nm4}cKgfOK`#s<7l zE0!~-zBZo36;MNr5Ahoi%M=Ov=Kkb0L%k|Z?oUR5Yj8xI@KT>j$({p9p+upy00L{_ z)L39?lzH7EFmb-=x4UB^IsWc9Th#{>#KD1EJ!`u%T7<{hC0-fd4<5O=Q_DZ*TlDA7 z21RmY7|YM?{?(?6ESWee!0%FjL3_+eu4-G(^E>LxDb1mk{)b-lDDx7+!+ZgF(sxoV zPZLE320j=%-j#A%SWVyebXeJ$+{{<|9eUPRQ!I-Q<@k9$x~V=Um!mvyhORf~OiV3n z|CZek@046lJjJbG9e8X|AIwXS2tjD$19jEA#h^qk1?`u4OR6dweYK%hi+fel%yx|IUHus*JVd`XGMrv?2GOD zzl>Ay4$xEX4cA=DxhSajJF;$19BSbd0&4()rTzyF4@Z>HRPF57=G;-9?9mr9nP@Dq1yTBzTMse;}`djn=&;LIU C>x%IJ diff --git a/package/firmware/ipq-wifi/board-century_wr142ac.qca4019 b/package/firmware/ipq-wifi/board-century_wr142ac.qca4019 deleted file mode 100644 index d4efac2816cb81a13218f324d2be3b4cad0246b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24308 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 H&A^OYaxqRxxu}Q{ z8BvCd5wuWI@T{wpt23+2u8!+$Y0BN&s(JHe-{wK8tgS6y*4gfJI3bZlh={}G{GtE; z`~LTLI_K6O`64qTCS#K(E;cVly)mOO3shBA0VtKLkp>_YhSGzzYj>8HMweFUV|JD6 zjWPPNwXtNXw0dVv8A`?_M%V4E(eK=MU~O5YeqTj&*-m4OGBGaJ1GX2yz67hK|MKtv zOOCJ-wxE8a`k^WTV3}_KGys5F7!PAV_;Dt3c|7V0fcW_M|Ga(;QaL{0&A-p2(P0V4 zS*xk@1i<6TyS3V>k-#rd-Ys*TUS%r^fU`j#T9A*lJrSol_4uwEBT{`WBfWj}%pVBG zKNDk67Kde@<9yr)Zj6g&W*^uvjRJo>z{o9GzI^3Mw;DL9EOe6hYh)SQhS9Pa7e^0X z4&H2SHRyA6X)kZ~wltRM@^aQZywQ82wMPF%PU6EMXw~WqbAIy%%I&*yDR_0`=CRfa z{RUn7%c0)mjpaIRPU^$!sG2S(M+F<4YORNPDO3Y#6nHgo^KfI4E;%O}Hf?U)rOSfV zuJ*RVrg$@$FYSMKBfim!4F zv0H=EhA-B(B$Y*O=H@-PvA;X}gsdi{qbp0bimB)Cd3@1$ID5A+hn@Urpt?D?TCzDP>)KU)m!|cz zdS3bcn{|DwkAxf9CG!g<##Ca}(o2?jdwctgi|=52Ly6|;(E=GqEEd7PNMS^TNEjg$Zt?O186CB_FzIppL5L#3o$_(@O_4M-kA6eA{IBQS!GJD!M z4DUx^_r@b_!ziGUWDX)03UDgp<5&_g-QP?tXQ*I!D4v1m;BojG+<5TNk>-ua`9Y6t~MP{$27PS zS1OdxlvpyJtVq_z;<1=&!W+wFn?DXFh?L0WQJ+Q0WwL8CHziWKvq9&k7>b0Hff<`u zQ4eBqB$O-8O|DIPY!=sr$+5{fo5is=r|f}^vtO|>9?nznw3&G3t4u5p&r{@Sd&^Zd!AFxt{aIKzafIW)|jwHXz!^<8$M&%nyUyt5mOafPue1k~aYm2Sga; zQ9^^KrtBtyfEO~O?c7m&b=2;hwqR4y z_L8!4bNjij3;hFw!?#B6J^0HHKR$QA07$6q(#hKW0vr#6!sAh=P-<(9)b1CA;gn2r z%l!gC?t^MsE%Z((xd*CMx6r$w5t*+TDtx(}ku7C<^_0^=F;tN>1~8*|Dds^Ws(F?&#lK*#bLXW@3kjN08l4 zp&?9CX~cVV7|B7QH07(krt*W7K^V@;R%T=QtVCrZwvMIiL7&Ob_4IX)j_1oGj=P-u zq$xS~)-OFgAmP5Don(Lq_CrKU00{J@kb$?8B%nR5@h2WfQpP|iIZ z<$K4G0GJ8q9&z8_<=i75(HOYHK+d`EAHcb{_3DyyZ>xa}=i|D=xd&`E+i8H;7=VJm zzrQC)Nc+^2K;IWL_4e}e-oE)zpTLoUlE7r|6nL(HGgCZ;xz;H*X)1 z&=#Q=-4CAIJzhANQ=L4bj(o(rSNf{Bg((gcLcC&mxx70uT`+?o3*P29ogNy&# z(V$C^9&9`+ro z)MP4R!ouzi?(a-LDz9N}esn|Mk=7)t4B7FxueL;;7|9Ru|MQi~y&4TJ3}Bmk^N+!JuXXEN)*X!6%g(zxSlyG-EUMw`xOT=^nw28r^Eo|Vm+fAk8?6lF zo^IRvRf0jdjg@};M(u_C)3W-I-HUeNFcW7GSO5sj^cOgM?ZpWm{Vhg~szH~klto6u zXHhZy^$me2B0?Ck#e2^D0tdsncXHsEti_GMbO|3HyWZkP9dYd$&iyR%_2(wje!{D{ zzWfIvm!9IjV++Y-8(+YftC@ntXdSHp9868MZKH zIQMp7Q0Awg@6R)8y-RmL1-0Jg8001^RFjUN`vnZ=o&pgeN5g4vGo1U`zG}X||NjGr C`f|_! diff --git a/package/firmware/ipq-wifi/board-edgecore_ecw5410.qca9984 b/package/firmware/ipq-wifi/board-edgecore_ecw5410.qca9984 deleted file mode 100644 index 2c1992001d86268e0483b9e53ed4b563e224ada4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24324 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 diff --git a/package/firmware/ipq-wifi/board-edgecore_oap100.qca4019 b/package/firmware/ipq-wifi/board-edgecore_oap100.qca4019 deleted file mode 100644 index 9f1b5c93b5ebc7561987aa86f138e86c00d954b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24324 zcmeHPdr(tX8b5>p>f*u;0TJ*LLU;rrK%g2Vypi%qfubS-76AoGYUE{j7`kA`2Ze|T z)`B5|mO*(mMPw{KAQo$DXO!7L_K%(YqwUP@_K$UkcGa17W_NYZy~%|TLP;P@dE75K z_k8EO-#OtK`8;TX)zh`Kq8R5MC-QEvPtx6}dtFRRtBIg5xJ5_8vJ}bhxylh>;eP9vl<|+p~ae zFkpL(!0`hX7QnKe7Mh8*?bib=Kt2FlY_JjlbO7u_aE*#@^*3xb6Ke{9kdTm9FJ4&i z>DJ(vzg>tTk|k_liSkgtUaO`j@CFLpr!8r-UVU$(YzIy;Vn9qh71(QE#2ze0LZ8i} zmLBnJBT(Bi(=P*PUeL(Ub)nOAOHp(i8yhPtD@z>#U>qB%k>UvbbdwV->n0mVJ#iQp-Y9fo+nMl}u=oc^MDEKm6MVtROZGCi2gOzI}$oP>yl%vT

Lr@;^)g^v2cU0H)0|&IF;nZdjd(iO-*jid5$vA7dbKKpmzX5LeWd<0^RHaE#8#|`W4?|bGPh6<&bXjTBhjyv=~$keO{Jo zTMy@?kwsE&1?zFeL zZzE~6-Q3+s6m1hBAfvGD`p6^QEph2@T0Xyz&4ie(j}3eX$)THwz{`1JVgoDXuB9t1 z+PtxTi#D{n90a)~^3i7iz`RD@Gx|(F=LGos`@=ik40LsBFgQOyUvC)SD%D_k+W1zb zwz_8H{Ai*90vvu|HvkX}yde|F9VV7N08E&$yp5{1p=-vQ>dFhhH?!GG2k&M%drWv z;FoL9=r;@HKHgre-!f@d?lfz4n$=DKFQ0lp3@pfwUJq4*l8AhwZM1;y7t1>8nr1=Ms97p$@V(OomsV0{H@%$jj( zW?pg2<*R+FJL<0&($^O%v!kKErXy~s8^=vR2l21t5dkXT2n6vU^mQo0NBJDSAk=Kv z*R#EvqB(J$5R{g{O+Zp@~j);&+b7*UBZ1sl5AOqj>inUKSRRbYIho zv%npDfF;JeceH81;ejkBJDhh9NoWLKx;b08V!Zp?y8U4Kuk!BoooC96^X^e(#u+La z{=1E}r4@CC0T00F8{_Esqcc2tgS>m)j8{2$P!&%2*~uHoHh?$1cq@b+K5_-WewTzo^k`@ldB2TRy`19s<}iLX2? zU-RFI--u_zl>)P9hNc$DyVqQ0KA64O+<>Yv_fT{h_Zl6COoP^nZ?Uc0kCP8dhDDmx?olJk_YOM=Tbm^8D4GE8AoeVJweS5I< z@;b3l$XBW53h{}=y}r(P5ATU{G$E-cVMtSVRSM-PxkS8IeM@y+*#s-6s_x4>#Z`%k zzOL#qJ8ahaoAIXXNEFq3V{hTP#V8;RR0JS6!FaiVyN! zG!@w1*cjTBC*{SmRJil1yhfZZ41|Gn%A~>+9((GJ>WaKVoR-MKDts}?hA7=ucPcC8 zd9wJaF}Sl*mMcz%VP1n+M)Od(w@XWtXU|_iVljs)Tx@{$LMe3R0 z6OISB?!DVz*tVyh@t$MOmv?0YX$qfHP7>8E>Gkj?W)v-0WYwz1aR>|M1bCgf`Ym zdU40V@vBiy-Zk`s8=a!YNU7gZhm^jXrB}jFdsfi%uJjjl#x#3W((*3#iLUU^dR98* zo^Lt$eyEt4LyI06sO(BT?_2F$v|%R>IdBqzb%4NfpTYs3g*7V%@EC5)=h@>=;qdZe z!8d#Y2gB3DgXxh8R?Sm5=5yi++WjW8t=Z4-gP`4SHd`MC;3rKa0tOM7N4tNi=VmPF z!`yy)VQjSGqP%tw!27Yaf@@Ki?tW9x|aY&V4U@>Lkk+Cdh(` zhCKW&z3c`oB~Q-gIG3J6)pF^9MLgu~`-QQ}SN}N42=x)bc=1%oi_hw~`FJIG@%sIl zySxzJp0NLxoO`Tql6Q}oLwhy;Z;!2ObQ z&UYT)Ip6u+M{aU{Id5)=366O?AuKd0I5s6FH4bSs8U&ITf@6dtA!KU{*JtHqi?cPV z;CFLWdBLh(>qAYs?EP5{759?;jR!04-fzG$rC3zdp`R4 zFQ=mD-~t`Ipxhd5cbXarJp+Nd;oRs}qw`DAVQvhHiE~Bn!!No8_L0^{(x?~rc%&21 z7MaK8BI;#T4H-7evLuS_=H@nU-aHozLFgu)sh#2p?JR>A%4A@0qOv$$k+{xea6d2z^V`8Yk&aO+i__MzYg0_GV{(L;P`Jfp=y@*Y<`r$GL?bS#6bB+BMmNw^k(HIGtO% zQ6=8)8TnO5$tNktC50>Az1CIS@WzSYV$PnvlQ{#bP&SSJ(eRyQOfzM(m$Hef)@O`|@5r zzlXeTcpiZ!d1Y1IIN;Vivv9d2$>I3;@OX}>jW;ubB#0O?h6p3Wh&=6~BOg}Pw|0Y4 z23k$Mxdi6e$`f~s+uMc0cA>OaYBb7+<%U^dv8v%+TU+hzT@UZZ#(EaXlCU1I2p`f% z;-hdU-3f0pmW-9eK8PhYk((r&6wzcfkw8jGsYLofN~|TFY!aYqfMW5ye_S3rfwdZtcBm8JoUqPdXYq#zI=AY>YX42$`u* z5`m{CBg8MX^@c5B^^@(=YoQS0`Sj4 zHE?g(KZn$&>#~}vexnhAJiZr|BNT=Nz|Ro?8;B27C>{iyo@Rx?Dh7vRUaT2bYN32= zDUY|KhL7Z8C-mcfglgRgr|1ZTgbN5HM{?K9`2=$IbY8RrQg?SJd+!WWHC3jcUl@UB zJ&W1SuDf6b0#=uuT^D=;at?%c;|j>jlqt5s&9$ZP8(V3hAb|gC25RMwTC1a0=M)d=+tOzV9Al=z9%2(5k|W_L z*eGr&j!=*ai9!*FB8DOeIVqRO6%kYR{d&ycb`^L@y$F&OFO4UXS*xV0h)7m?BYurF zra$NCbf!G;OqO>aW*6_Cy~4=}NcRU%n^@qUEr3cU@VDJ4bb!V5eBQls+IaVuC=W*B z>Ehj!#K;&3QT%te`7ZNZ%?x;iE@&2e)yia>DOM_R9 zO@_mIje6t2MPsX>5{#3L*YyqRqJ#vY@4ywq$0nCnVwY~+6^al{^{nxfL95RMmkfrZ z`h1dnd!aHK(}RVK+q zgO`ns`T})I0v{XPz9RyZE)6so3iTPfxWOw>S*Y8g-UM!*11zIuB-Az=iq#tumYWRj z!5k(d4*00gxMa@(WKd#IvVp*CI5licjVYe92-NrHUWlp1STTr#3 zRIKqzz5n^96XKHPd)&8n^z3bkujU_O@2T(1Jrh+aILOYr(4eY_)CTSKNNQ`}-?;9G ze*rtAu_LP?=7e7%E2Fke)hIvaU+A&pWYyO9BhbIq@{@e!-Nj*^eEA zrrj@`vN6VipDAJx7#D#twEL%{n%PVGnCf<;+?Z?GiFo&pxz`Ni)l}^Q1Q@@)w;Km7BtsBdLi?@9a9vrAJP2z~c{E!_Rkj z4MT3_i@4UomFwtu%q9OYFWwb+@!RU#?@b3Ue!8)=#kZ%+e@)Ik9{ZQ!-Q!)ds6WHt z?X-kK0loTW`X7=I3*JUcA`#OSc(*NTCn>zC7ToLU3dc$vf_IOR#R&8Hcz-bqbf>Ta zA0m9Pf`ahIWflhtA0&LRND_Y>SsbXzS2)(8ox9%Hvu13IYj0VO5yTtbktAO@TF1NJ v@%cd#T#mQD^Y$i9m$)q*w{sMEQQkeiNaS*Soyz5Si$LpmDrYyldH4SZO~~I9 diff --git a/package/firmware/ipq-wifi/board-engenius_eap2200.qca9888 b/package/firmware/ipq-wifi/board-engenius_eap2200.qca9888 deleted file mode 100644 index 2e938f4785c5cf4dd088028bfe37c5985c3a9a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12172 zcmeHNZBSEJ8a_c>z=f52312ZDLqu{(A%x(rS3U$Ht|_@-uz?!t2VZKqg^-F+Fn;cA zYvNpztcYJF7E@(xi&>__?AY$^xE-g{c1E54=#S3qpZ)1Cf4Gj*KTGzUTrUQa)MSgh zc6*M(jbwL8{0;_B#xb3hq4X;hTcv>0sxr+BvoJ`Y2^xBEJb%Wz@Y%BsHk}S z=n<%v{sIJp!CE1$kS_IzyZ-m3ExnsV#PWH8`mNiu#6RG#50RFyJxbYCaLB z1hpU~C1vHxmC4D;5{ZNt0JxPvk9@RMlH#N^aOqMSFiH3;ycaAlrlxjrb!p>x>RDM? z04D)CIXM6)0qN=K0H-*SmKJBjpFlIbXP)6dAMhwbLf)c7JamaHy%3h-2`aV`84wu| z8Az0Y>mCV6l}M73Q_%+r@%S?xJ)HNOZ@vvR6oUE5)w#AYRJ1JA%ilF zjLC$VL>|;by+(gmPc*_tO(RnW>j(qXL7hf-S4ULBN=+rBg<67!3w`^Zjc1X#FsAD2 zg;9xO#QMZTNfyj{m_@9CYcy+^t#IqZt%MO8HAbcaRy?dAs$i9-is9EIJP&onQ~$#A zXnXg^>X=>DXD=2}r02!w0_<7KFx`@;cKF!|gOzU0E8%XiPD>x%NR|6OcDPuFVJBVp zJpxcsD!~1b9mfvTCdYO5f@KsrsJWZ$m}P)AQd-XM@UW*0W?CO|ps<6VJ#DekO_YxN zi1i>>bKWaR;w*!-iTbtgrsE8I)bQFfQw^U zqeUBXP*cUvTc$;J@pWYp9Wg2*OEHL9q!w9PL`RH@$WjbqM77Ak4=`}y{ex%AhS%;V zS|%s9jg(mPThpt5cm8!J)tA5LSB;k^cf0hCwVl~JKYo93TsI86$(EZJjH8-^^45&a z*CyW_(+tS>W*R^9+dQwHQtX$Sulm_@#?yti+&vQ>!*JO_xjCb9_VQ7#apqc{lmmnMsSg_S8D7)G|FW=-Omc?#*HD`1iO<2ju&Rrmtp4ea-H&W2?=RQ$3!l z<0?C8{_^6WlNl*^BinfHvc*|*1hw07=VtR*nPZKWY=6(+IbM09=q*4Aguh_C%KmBC%gR*zv;mj`ImHpo8V=5bI;#_-1solAat2dvX*!3W`?|e9I3| zE1EkA5$1#KV|pNyJ1>?gfbvw!>M9}gZph%$mGA(vg1tIH+Uk=u3Ki5=u7-6o=z zOceljcAfQqawj|&Ui}j*Bl}1buxx!SJ27Iw|62y0JbCi?@#BAnVaZhE`g=9sY0#XhY%uGVv#O{8=4;I>(sIyLNZ_& zpbY60PC`Rxpp4!roPvhVKN+1s7$ z5)(H>#QupYV(zPDG$g)7WA5FUhIr15o7?staG$?29r)AjFJsB_q9VDll;N@x{SSqp z&rv9Ho+k_TA6tgs^Wk#%EsyVWp`V!Yyp)hbxkk=NLBo6l!9YgCFb!bi{6?Z0R%@!6 yjZxmO<#HTXsl<6sXwKm|*2V|^dyD^)l1i~pc+SU&{55O8jIYQZB3r)vntuZV+o7WX diff --git a/package/firmware/ipq-wifi/board-engenius_emd1.qca4019 b/package/firmware/ipq-wifi/board-engenius_emd1.qca4019 deleted file mode 100644 index 3a2d77597df2899722962245a3832e45b9f3bfa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24316 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 M-<$he(lmSj12G&o9smFU diff --git a/package/firmware/ipq-wifi/board-glinet_gl-a1300.qca4019 b/package/firmware/ipq-wifi/board-glinet_gl-a1300.qca4019 deleted file mode 100644 index d8695c983641b25f4e059f65a0ce8b4f2501338c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24308 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 diff --git a/package/firmware/ipq-wifi/board-linksys_ea8300.qca4019 b/package/firmware/ipq-wifi/board-linksys_ea8300.qca4019 deleted file mode 100644 index 0a1f6ebd4785369593653491d70efc358c1238a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97236 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 L2*fwBdH4Sh_9QQ4 diff --git a/package/firmware/ipq-wifi/board-linksys_ea8300.qca9888 b/package/firmware/ipq-wifi/board-linksys_ea8300.qca9888 deleted file mode 100644 index e3c2039924f483ecc3679ee005c0a1f73c6bbcc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48628 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 Y3=Rt&nS*)vCPAN`MyjX(-@N<(0qkJ6aR2}S diff --git a/package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca4019 b/package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca4019 deleted file mode 100644 index 689d9c481dbe84def37a9d9a22c4bae4ef59e452..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97268 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 RT3s&UvhIO<@8A1^{|8J-1^oa3 diff --git a/package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca9888 b/package/firmware/ipq-wifi/board-linksys_mr8300-v0.qca9888 deleted file mode 100644 index 90b6bac08ca6b2f05d4a6ba60b7c09422bbad2eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48644 zcmeHQ>r)e17QaDU(UFl30Tr=DL`Y%?Az{ZBqC8|ZOIk!HxP3(IE~pN-;CYP%gFQ&SJTiWsO#ewY9Y$rfR?JU*HGVvgXT@y`8opq!URbV1}F% zy8GPI=iJBd-VS~H{%Ce>%}vcU8PYYz)V!U!yYo?PZ7srbEREYEl!v#9Z;8eXR4yU{Ad-I)aq1CyB-%sjfTH*wUC<2Y0EgL|j$~ z>2$hRFJB^~Y$l8U@K0Ai&-&eonk|ti!WN@z*A}B93IB1Amn;&Zbh6iQYz`sHljSyf>v-zb-Lx4Nk}wz5aQ8JO*pLjWe!Z zx+p9>{D0WC2;aQo_%c2|GBWH<{Gmgodw5%1Ty!*_XCU_tgAMJ2IKzfB?StIL<()Ap zT8&zzlqY3myipSIsi3iW!hs+OBA3i1(#dq9;rNL&f3&q<>Jus5+$4dMKkM|ojJ`SQ z#fpnbN=ntzXHp`Lj8n(aQDhXcg3KfH)OpYHhyt=eT|noMIfQ}Kl3KO)nU=^TGu4^2 zhSU%gDO94{K2e{kDpCk_&?`Kvnh6Jug0DZ`d+}9H_$pn(loMf-=O^2zpD$`O8T}%f zSVgWg5RsOTJ7C5R|~H@ zQ5~K6-qYBfsg3RG9l1X?Ik#}vrpuolVlJASs9h_R);^}oV4;dvsMrCf)m%dr$kXlL zS#6Bfu$#*H84F60ry%xw<`Nem-)OzfTs61g03~~eX*1VTM!AOVvvx4&3??ei86f8Z z`k3?PI%JHd>c|y(9j^; ziBA?$8eD>nX)zQ~n}%+)Uoh32?fKx)pV%5^hgr)9DCKCVA6Mxp&Mn=3%i4xZD5SC; z^x19J8s>n3dVYJz#xji2tZ@b?<%;RLY07z+u1tZ$O9D{x0?ZUMpfm*zF9|@&3ou{? z1m1$c)vpd;Olw+wkl5AJ^_ymuWo7YF{qL{*u2o*Ma^Hsq*L(Kb@~o@NV|IV{RpTXX z6Im(Ub?2(FMSVEFIC9gio+EAQ`uP1(#vl6XI(~aD;h@ZPvyZuKJfBpzd|y|Gp(*Wf zyeTqs`1(mUvoWb6rl{*i>4of*@s-k#FZ7t(v(K%u$jtp+jkb+-iTh*eM}7NjsrB&( zh#gOcTkM7HX{VN%dU~rmvQDQoNKHR>H@4EvYd?uGUcPQ_-FyQ3?R<2nur1BH$|5cO zvakG7=9%PA3De2;U8mO_h}{vn<=U53Y>st9T}<&`@3wrM_BnYhs=|KbV5k06N}aTb zwe4$>?_FN7Y}5I!k}s&^^6KcKzYTt7*PJ42q@O(Ouk6@zR&i8Xe5IfIyHV5VjzE;jb1&EMD@#(#Q{&MG?|ySxoGT zxK+X|jl2E#B)&FlxV542xHe(k+O>&m_n-)FWi&yqp>hmGC1sX| z=CiGx-Ms_D_x}Fm$rGV`U(1<^-*WA8VvTgWb~~|Cx>384$d*P3f_7J2?7REObwBY0 z!!Jc##$rJNR>n*)fY{JN;Pva*uU@_SuZy^~->2u*I4013Zq*32B)!+dj*KCMkIiiF z$e8<4c+#CLJpE2iOaL2Tpq!&|5Ng*Ww09B#$M8~FcvuxG=^l72!SuJQSZ-nwJnmtc ziA~67wvKcO{&MXddFt($lDt0YeQx~99lut`ug=j$rjos7RTj4Ma(7Sft%1Sek$d+a zK7Kmp{|U4KFR~?KNpcbAx?4KFk(Fanx`^}M)@y`ccfNDxjGXJBw6s-N33aZ4(s`}I zDyVb)lh(EhE1>>^=rzJSx?Vx_|AhY?<$oD-)>}}JPYC$3W?Z;u|DpCPH~NSE^592r zxs{^Mbe}3chfcC_84*v$tK(@I${)`sXp&abbUw-$&mi=q zUahAyJj}0CI4o3ZuHAZG7w-erh*)hbK}xr2w-JTXkF*~VTcoAexsN#i+4{XV+xZ5P zdw=jaaPPVP!q305xg&7zITWzCaq)qB&%@%nhc#eVG`#76k~d^r?X!=PYiXbZ0)PM@ z5GVwId;ji80{5PunT-k)G_f*CNFN36{RBKg&C~bgISO#^-M=+}dk@@u_c4Lc?9UCL z1TpGj3!o&%L~H?+#F&UJvyYOvOt6GD0>Hfo?tN%q0nqwTMgX|?2#I;|0`)$^!@9lj zNXEaTxD0`Mzc^rJgz`9sw)=+waPR%YYp%S3d#_T$-xUNe26J^CKsmvO0C4YTmzxjV zd;jjK-MoQ&@A6j_NzOm30Pelp82QB|eOWX1#7p=PiL6Dxt%@-->Tp zX8PXyLzR{A-g}HAaPQy#9(>^5i{}TkzkUiOh*1|?03|UdU;zXG0YG4G5CHD|yWw$Y8oc#{m`{3oB!~YjZ zObE`a25L1I2mtpUxc5#<_vD&ZFloTO2kw0^jmLo0#g{c>SB||m9k}+y*lT^3N5t3mtLO_DEZP(@Bst>0YJcC1b}<*FJhDa zz`f@u?xVu|U9152egYHV-aCg0kH?JmlUHEiG`6dELK23MfDn%a2pmL+5(2UTMnDevh@J#yVBXN( zZ};@u@7vFGl9}m;>`qA*CFd!lqcTN`?Bv{3pw(&t6kQ~d1F!?8(qlE-OUg?lO0{ay zfpWD@q%PYYWvP``l~k7z)#$j0+LCH@$>&G6W5={5qJrGK-J%%Dw&av7t=0vO!Gq)R zB02wbaRF;iFkRql@&IrD zaUqFHYgo3dKHSCwE>GX@)lPZ>KSO!{*!=ZP(}#TEY={>nM2wU^QzqGrc-#Sx=gjhCH zVjaP&!O_-MjXGVG^lG%HrJ+ofnZE7OP|umxYW42)xJScKt5N5s|N1SIJLAGI@Oo(U zRBMHLmrDL>xaV|3xe7~{J-S77Q>CX%p~1P`EclnG3`uvwSTd3c&~BW8D0&u+Cb)n!p3!4A&WVofFk@4?Vf6YfL-HPiH1P9;j;0sM@l}FZJdPb(gaB zS9P57`=hnJktc$5%;M#R5*;mtfV=0~^&2)JOyA7`oWLOJ6Mv>8K4WKuva%}S1rY!) zF0QVwE=0a&jk~+M$CP*uw$~RcpPkGJXN80a;9n>|I9R|B=JWI2yuj2Iiq&XzWl0fe zZ?CP*%fr&7VEuXz57L!X7%JfNgJ6Z_`R}*y-uXg}Y$F;2y**vs-2Q9n>H=)plcOwM zt{Z{ZBXD@#iMA0U5uP|x!Y2epQ8s&VH13qJ*)tj(-XdJC4gZd!;r~*}p70(q&2AUzxz~rbLQKAx5 zB9=UtAPH!KI01`7qYx=N9fYahwmKb?Og0@Atxz~21!H{#fcbs5@zQXS0waHo)c?Vch)pAJB5Cv%zU%h)@;3B7TUHFu1V=R z*mL%2lxURZL4aNw^8jPjyed($LV&K&2+#=72+#=72+#l>248+9`O8ZoKX{rqO zLVyg&+~fcOe|;=$0w5X)5Xhr~#2Y^3^H50!+ZFD@mkLke-(Vt2OY(6;fM=6CZx9}T z_3|h1z)#bxD&_Dfw?`UVC^Zjar2_^0oGc;WbgS^Id7UAZos z-oUaCiZNQKolwgjD5hwkc0n!spO~bD+5vSO#Ca`NKDx_h8LX^8?b$QV%HMyet@G*) ze0<_B^XV%Km6_SF-mwra$`x}l7D#=UieM-v#;{Zn`z{udp)#=yi(Rz)>lv?(Xnqnu z1ZAX2(vU1hoFop}!BBM*ueoDT-*Z&CTyAk3<=w~I#k>DcrHczB-PgBUSm3^W5S3y8 zd_75Y;3cJncMpJ@8`)x=3w|?~cMtgoNmN=W?;d*j&e{_Ii_N6m^(>it z+}@T|xt&W-+Mea%gech)HrJ)rK+eo3Ku_tWUuLw~0r{lE9M=NZau#yzQ9!X+oT$1 zp3S)@^pB+7hhl}q!|sPKX5C&`sUQ0Am^^E)#4%H}fjik^uD~-*5<}p`xT#Zrq$o`q zI&lXdFz7W!QZDhoVpqDt!og&RxdB(17rg+ zq>%Cm1Cuc<3`};LPvM76Ifm_%z2>ucrD=~|gnwh`)Kn`|r4ne+p|7M2t{TIH0Cqc% z>kPS?xXJ704!qt_sFC3lh91pP<<4+_i-!u$UNR(8HxZJ_+=^G|Q;R|-`^^{dYQrAQ z4*Xk#QB$i_hI1zFnJ!yG3L-+f+8qu(beX@z59oI&+0e8FSL+o@4*myIuSTm(mPVSt z#rq8nngS`CFzD?TZUK{><|e#YpP&qwG@6_7GQCV000S}Vj}>J~h30X*+fc2^R)&xs zgfOHF=6bwPFHy24zcL@kRZv6B_wj2GOSu$%b$8;5sZNuk3?MzgIXEItc&Sf^WX}nt zQKC_r2Z5EaH0GHa-MnfM7(d(i+nv!OZh*)2mdbtclHkCNUPn9AnuSN$rQT`Z4IDhb zT`xGix#-Uw^{OP%7GHn&yO$d)G8B?Xj{k+e{I=-hJk6%8r?)CE%9}#90sEhIt8?PR zwrmFAQSb3eWr|o77Xyu$r;w@sPSBsYy`jzyC>ZO|c>_l)6(5i<*5b;91c8JhBm@Xe0tBiNP#{E3LPlXJB1CKXrjkIG7!bs;N6!`& zFd{1}OMnQ=!Ebz-Qsq$HRk79G?w+GL{R{l1zms-PPmeu4#lFcTkc0%2Wsv}LlQ-|a zH}B59?=vsVWbTK2oR`bbEs>_C$ob;J++qo&R;wW(nq+(nK?gvoI@`FvvbKs>rB?E* zYn2+lvSxpZrB&5Xsjb1Ase5?Mm0D%xCr$egDeJTiCCWN}ZEg|2vRbHC`+;LH!SR^M z{YF1OKmTn3fkF7OlbB#r0YN*0K@B7nywgCv9lTr#mz#zk3WCzo(*E`1k5Cph2zvYX z>)E!ljq1wEqrT_Pqk0HW&^sW```ov8E$#{hv%z0B!DF=POLex(h-ba2>e&5`i>grM{Ws2-KQ-d9?H43?G-?Q<-D_vUU$Fe=oCVASx zu4lHfdS8yzeOjPOIU1fld8@HwZw=>2l>F)V8AJY+L~TTcVd9u!-xX$KSmom(Wt+T? zeJDKV@o2;4%vx?a9sTZp>z9RB1dY+vUr)3c4qfH9FiyR^rD@AQ$&!U-ycla}FKCEA z5-z!WN7*m!`c(_P_VHBnaPoy1O<2XoLWzvlhCpEOFMhdm7aT_09Z8RlvHitgs{iXC zHYW#mQgRNStN;=v z5+yeXkW0f2Fb>^Y5+w%&$Oef3i2#WJi2#WJi2#WJi2#WJiNJaz;Aw`y({bxPA20o* z$7}U7uOSH3=ky~pubpe(eCEA@qDooJ9{8l@<#PGp!zB>xm$Z+O`@tQP4mUjl@1{ej z{sA>00|Bzj{sG&+1o9OS+r%FMSxp~W2L8B?%>3Z4PKf8kt!E)JcSNp^$j+ffC1uAe zYHIa8U-S=+jNO}@o_X~2&)@#=+WQ@Lc|2S4YLnHFB@c>HI&7IxOAZtjci6I^mi#9w z?674(y$8{)#pXwMlP#8wG96EH#)nH!oa*kobqAZB`>Q*Bqs-UaIH?O%n1L_^43r8< z79=o=paK+?KNo`)I_T zcTZyi{3;-bX64<(R^C0dJ;WvPp8cEUynDbu$hMVL@b2$8pUKtm?s5LRGw&Xc5%*yw zYgyg7=D!2py~q4_;y?uN9@pLS?yVk)%C%p>yZ2nER4Qa&7z_qvUqV7cATP?#%e!}; zMhQz)T3iK%Tw-o3ykR@Oa>X?ue1TbirIL-Ov4Z>~?4 zzQArl)str^_KbT%w?IaqwdPxV?b>thaebAvdk$KLKkR<`+V1OxgX-$@V&7-(G}U9M zF;&kncbMuhxlyQ(o|`rH>CTkri#T%+ura+(RW4%S|C2k^pO6TddrhsF!kDAyn{S$Q z*fFD6pN!2IM^viv!y?|?pNuzj>TySz;p>aZ7kC7HxHXSv3lbX9UuEz z->1?_B_bg(=+)KR3~m_`xDXh24b$k0ReQ|0O}*GTeVHl?o6`@fnxqF4BP<^3RL6*r zj01Q`MpGA7r<0V&nMY06F|GcH>HzkQ-k@rhN)zdGkBm1hA;sV!-5N*)9{Nqc$EtM) zq*1`M15@h6QabiWP-g zX(R~5pgUVG7jaFq*nnQEDwM_%9=IT+>!x#9nNBFBnm;$4#}q(=O^>m!0G2r-K!GCkt@NNIQK zd8TUD;qUI(-^jVhQAeKmen45YHz9sE1U(x*UoXuQ@S~$2-8<8l^BGr5Ir3s$*_(Zl zT_17c<#1z#cn^mW5%T1A{b{KbVTFe22M=FLZK56BdGPW5sv8*>n02&cPmT4*izK`_ zIACV9S$j~*N~A?~8453_H%F9*NFPr8?xyIo7&Yz0On+0g>;R7)7Bp^bZj_-y5sf}G ztnJQgvXEgPC#Oyy-6w-ra-{z9dSf)-TMS zPZOKCc{Kt}EQCXQNbl%$$>=cMZqL3_?%K^s%fglpzx;6AQU%iiqjg?_1&Eg61 zy_FDz^$j&~?b@|a<}fzyo(WPIr*)W5Kw5`e(1i~OVi8{BQ3{Vua3*4uf}y;|BfulT zBe3xhXl$(CUsFSr8G%q3ALrknQIoDxDpTM<9Q)tj=I13)^V>LMvLJR-boBpxu2JCZ z+3rSvd|ce72mbh@M+0k0rSO^Rv6FM!IW!Gdb)FiU=9o*MUnFg2rdpkrrc|KMrWOhe z1VxZyv=}j<2E=*1_f-Gj(D3M51(+7;>xdK~D%1<_2oWhN)k}$ZG#*JrEvQ9rxnn`f z(Q1sTB?dy*Ib|VKq5j#_eF>d zmFZEI<2F`Jw;A&)mK19Hgh0bNcTjqPCTq zn7Ms7_;#^U3-x(fZu1VZc7~u0l-xVOwlNhnMkUY9(j)GUx-w(>+zsY3D9GY4r4mBq}^6C_zzY1GbrPM>o->MTYD7eJ3?WB{*+eTO+l zS5pPvadwcg)BD^y=1XdXbm3Mb1_OrO_CUbJu?!7>Zl@V1wU^xEy}}MNJyb1eV&cBX!c#E&26nq^G>p77#FpVEM&f-#>j3QSIg#Z(dT_7rEn!( z^r&HmQTA=-u)7eK!q5T6=CiFiN?AagSyf@Q$#3Ortvw zPx6kj{Y;D7geSp5#@xs2DvTO-mhn(7vI6e9lVyVg7w{(q^^=mq$&4RLTFCRHw;8q<=sQYfXr@lzHOOhCK^Zd!SatoFv zOFT2Nf5_0QAa_*$^ojkPxi8(3)bO*%R-K!%D*=FS#(V8}iC&kSd~2#>#Qc`VCEWM@ zRoie;pUR%t@WXg#qh(LJJW=rV75gz9N0sp+>ch%+3|*1~aiw2;(tIxOl%h>?@HTBf zRBhF!A<;9F-L6txsg_9J9jp3VPIqFR0Ka+d_4CHJQXG5Sg~v0G zi7GytYWL*#t6buSkIy)pt@$dsTs z)6?LON|~xqrKT!V_s47ji~Y(FVNcYQfF&R)!k4g@kSbv=mWvb#w*(06Z9X@749;zhM;!PznJsL%FSA(`N++kolsr*v}~)nJ@bIQhc-l z#P-D~{Jd>Z#wbkC-x902XNl4L3o<9~apR}FJwE+I5Lmb_5JyM1fZEZiAEP!!Z}|Yy zB}jpgTabQ_EwIiXC5c-2%XMPrmvAy;S9;phWPj(*->dU?=ZNZ>+Cz;kt<>4~M=wlV zo|?WsbL;j$e*EQb$UzJn zvGLJ;Zf=8(Rp@$p#+CaUjt-4n{D_&I`)4?PW1$ke9ju0TJ*LLVyHAfPfk#%2OI3f<;9FECN*|sZkz=hoK90d{Bsp zKrI*|Xc?48Q$)ta2gG7+?ToVf$NsUif3%%_bZ6FG+tKc{GrNm>?hSz?B$`N=2Do21 z=X~e8=R4;+znmoZ-t*(Wofsb)zef-eo)(&r5ucd^q*5t>QWA#c0BnJ&NLI0}u%w7x zBo&9gQz9-66(86Zj@OEg7M35ts@!mPWnsCv@W`=ki90uO!$Y@3Cre4tmj?Txg$YVX zB;Zg-iORzI4C#Sc0RU^A-Jk*h6@WJ*am{qbV$rd#0Emo?{PEc{5}&#X{QQ@5vAW~{ zJ9tgGXYALa9SOXE0*}qqW?Ji={d{J3Bc!Ip_%hg zU~rai+GJaKU9yz3-y>mspsX|b471#;pmQ*{Gx`jz!o9Gsu}~IW6tsIo%H5VDwL8S@ zT#xNv^w)fpafVZ|;ho!qRh>JVLaTg>N6(g2Z$HS&LZa`$c1aRWuKV_@ec}#5Bwimg8!pa}r%hM7f9vWM^ll)9HS2 zgr9zT_WkrUb_T>_1qNts|NZ_?-|5@1h8tX*$&QZygY8`58#d?v{Q1)-+O~@rF5Y$N z5Ii4&T4`PL5SB0_M_)pi3& z$q$;_I_4{YKO=XoQYa{eLwQ6&yisqCx6loBL%h%gG=Y=wC;>@DQ#q-^I5Z9spj?#8 z;XdLbThXnYt-^3L9O0p}L8z{nR%c`4^Jk+X)OqiZC6KtI?oZtjAJm8ABTPgSpC%${ zXc{L?7>PzcjYMM57*32(`zGk;_)uEt7d^+8ZRrQ9A^jA%K+*eYF{v7TR2EcS4(FuA z94uJ^1WE)-W)L8jh8bWC%qtQl0|bZ)fdGL3fdGL3fdGNP3PxZZcOBwKd5ilNl0n(R z-GanYR_g?07PVd(xv!t=F8!@5=Z~>QCpH^n1;2&F)U8C|`8=_*gT-oY$XYNzilyz$ z_h6Stgn1>3(Z>M5vRctI`q;SSgtFOec&D3&+NTDC3khKc!T9V{gW=7@XP25?E=s+i z;s65Nzhl({5CMW9KgSQUff$eqMTZG1TPP8LPWSbt8%aB~&$rU)d2I~9=aImVM*(Pe zMo4i{05Df0fDibN1*;H1_8_m#gQc4rzUinJ385}G1YQigP|4&2a0deJE|VQse+1<+ z6x}?>pe)2D%!XgCJ)>WlD}#dq8NX!G?%Zkj>a@Fa!d-i^^9l}>C|cS(x_WxA4GoWu zjeqvwtH;(K(A&qe?#y+`v)+88uts@+ zSY^gFj@m>0J@uXk&2yJ$z31>;lxEr+oByem&yDSd^{%d|sjeOu7egwHVH;~|D{>o` zn6xEJ#12uiBy8KXK^g$q4ZomeUSx3f4Nhl7)|Z9*V=ArK%CSaAr<@#RhN?f>(Szkd78H-ChvXgT;8-~PqF{{H7D zPyPmN=J@t}epI-YuRlHg?;mW>!8gUX4-4aPu!QY1V0X;v_>RNEHTFjQ20R_^5ZFXB zwZI6zz4q$z?%YM@3REq*ccRa<*XlTATC^5D$JVYs*B;XsNVg9ZW@9(G#~&MBVa(M` zeO~l!Uyo?oRh9BAQP|hFG)h&iJYU4q+*DnVmx+>jftnF@uR<;n@qDrW5xaXYmxA`zwY*qYy}TIEtv0*{6{j86s!1H73;o+Zzkx~=X~ z$RxW(ThzA|7bN9^Bpw$!w8;MN>7=$x*;qv(`W3It3a&6w&#JS0CXq2U9J`v(7S`Y+8yPNErJmpT z8=s@+da{}$j?*Nr>0k68ZjGxCl&;TL4Dapco%gGyNE-U{ySS%O8Kr3KTG@rT_gUqX zz4r&iZL#$MhrRM^2lrkIZSbyqvv6Rz>f^X(X6?EXg);qA#4(S3Z|u0$U(~v_j`prc z?&r7U0~yNT6P{A_b=j4eMtUV>e`9CH>8MICk&EEQ;QkMJ@B2wT^83`{?xb@x8B)+c zSfS#dqL;aeM!UmNSUlibQUPA%>jIC3erF{qkac(qg9 zuw52%$UUv^+R=+KCj-i<`4{^OJL8-DD=7Kxed3G!(*YIkd1ssVy%!~+=ThQE1}eJJ z&oZmL4zAdRLrk1NU>P8=(5G*}XJE~V2|R`y3V3e#(>DSG8SoE2d4m?Gl&Gzc&kD;U6ud&$}Cg3Mb1Og@zm`AsNZq&?DvWKnP8HKUZs;}hRy$dGs2EZ@1eCE-)~HZ*S{gN$dLiKO*im(f|Me diff --git a/package/firmware/ipq-wifi/board-nec_wg2600hp3.qca9984 b/package/firmware/ipq-wifi/board-nec_wg2600hp3.qca9984 deleted file mode 100644 index f95ccd251e785d4db96b9953b655801e95b02431..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24332 zcmeHPYfuwe7Vd-~_*&`khS2hI2nZnrA1$CfbTp6#0tPhk#Y;?Dgb0X)_?+1p2-5^c zL_vrmgRBo=*(qwuaYw8v%N?gmsr|7(rfO?<+^U^FJGEBLthMV_xn^&t)8s)S$pAAT zeLCIu+|%dWd;3e1+`i`v1=}+dGG*cUs+RotS({CF3~2T zP%KSmfp)?{o8gK0P8N&1p}4Vw+X8I<&%mJslzZ5u3&eq-)kacbdwP(Cy@a5o3y|dG zcATMH!HQ*5{YqKXW*^{ZV@S8H+MIK- z!u9oqtoML`0LXfGu^HNJIS^W3>?L{6SmdW)jRuHY(M*6Va4{&&3remu%J?t{FbFUR zxQoDzb{6E#VzD{i-~|*{;<1tnqT`Q$`iAuV#yAG%RQHU2U?(>^zTTK+oHUjgS3u)X zKiFtl0gV|ifxQ^`4jC^@`FC_QC}c8hCkpxac$=Nk*mY5nk!wNi-+%kd%h#{{fkxR# zUy93)4OgJmEYuow{`B7x|M2u?v#1Syyh5yB`kH3-9iV|8jwX=ziVV$^Bx zk1LS)BEHXk;ZP)05Q=R_wm;tvOAv`bf+Zu#&y(R)Bvp`#QE!6v(bN?M{k$I?-Mh23 zVSANC|M>l6i?j5TjW(}4nN6oN2|lN;zBgz zB@ifv9|IA;#XHFW{$}kB{IXmF0^*1fyiHz%O87!zK--R=7t7ErQvja~7{Ht5)o3nX zMBK*PL8vTfJm9l@l)d6=7883K4iG5)ytJ)IX|8l!gU}N<0pYebf5>& z$mkfM$7|#=GjfsN{ z14Ji&oD3kYYxVdUaW1-T^fp1@)$$@#^xzZ22ShzC6Z5HSh>3wlhlvhwQi=*e4?0{U z&Ox_~-XK22Ritflc=ThU3eS~`sDL;=G&%%^R0~>5G7M_lKo5Cn>VpA;PFsZ^5~Gth zMs);^OXNaRKpa1IrnkxFJoC6>1Ba6egOU?qY|IQwHgGtpFeo_zhB3bp0XDUaZR6wG zvx-f~qODxMcH}~0L)c-sps(xQ#&~6L(WZ{kkk|SgC*EoojWS zq6Va#TQG82q7fY76|LSf*mtx|P{TXuBe^$F-JX3u{IH+w`T%}W(i~kKc%Z9Y+>m&L zCtIB|cI6b2QWst3FYUUjXiY!GE9dTR?UU=%&#zVb$%ne?bepRq4+dZl2M*{GYIuj> z+{a@YL!LhI^cq=Te?@!hnHV)!_EmRX3)UF1&tG!!io9iO6Y$G_IFi?vs0~$e6}RWul6tc{8P;*i60>KK4pfhhda_v$5eBrgzkWb zzdtZ%&6eh_y&s|{_$puN?}twsgr|`z?!GUF%G>7r4Yt*s5tfGK!Kvdt4Z1w7 zsEWI*z3ZqhvndV_mM_{jo*6iU0D}PJwS493HL$OLU~p*ITH6ORQ;nSdze&8T#Q~n( z=St9^$ET$tWZk-G@QR9z2#<=0h>R$Pynk}$bE+S<2ZzIgJiu|8X=%#KlU!!=@}iEO z95$%U>=P&ogx7L+iFU#H+|8oRa5~qU7O1f7!oa5wt&jAhzkB8MKFI8$N#?ANDOebV zL0|?1Uc7kmFI%w-aB007#LTsy-7uC~72B^Q#-BnEC>z1D*;D&6Y?|UKNeayzT)b4lYdKV7@#<5j?98LwaxBKQJGOu|V z$aNs}72E|f8ynrue3jT<@Zs7&{uTC z2>4i|R_sQF6GOeN8l^%4`WorI0BnUQMFfcjR16yumR=pKyp;YP|3qNf7CJ7>_#7kPX`ODf`pl=*H)YyPAJ|}SXqp_d*nqeJ$mMJg5Abcg z%q(90=SnidP1!cv$z5bIXAZJ$j<0DUT1oCb36F_;Pfc289H#m+i;EOWvsA1!k(F+( zPFnHpt?ht2-$3!?SFT*Pj5=fC-oN_C-=BT^ElKvbaPOD@=ZAlO|NVEswgx-~IEuG! ze?D}EdvAU+`+|N#dy~R&@2Ajlg#u4Q`m_7GvW{ZSx~Fv0aH$KN_v3v0Ez{pC&dRy$ zb4gBOnTvMi7Gh9hP;!C*b89#O#>V_Mpk#AFOoc&!L4ZMkL4ZMkL0}0ZFr61qQ}4a! zEN?%(4>R)~{QE9zWR$?azYZogUwQq1$f?RUnxr|rKa@1E?N;oiG5 z+nwgiaPOx9h?TZ};XX9tM_kd+JMa8!x%-dCM`B?7p_MJ@x{twDM Bvkw3O diff --git a/package/firmware/ipq-wifi/board-netgear_sxr80.ipq8074 b/package/firmware/ipq-wifi/board-netgear_sxr80.ipq8074 deleted file mode 100644 index 446876c00371eb4cfb097ac593bd2a128590c6c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131176 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 T76FTZMZh9p5wHk+-U$4EL<2qz diff --git a/package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 b/package/firmware/ipq-wifi/board-p2w_r619ac.qca4019 deleted file mode 100644 index a1b1166f6f9dd713fd5d45bbf50767a03703e902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24300 zcmeHPT~HHQ7QVsoqvA*>0UY-!5feV8|2_H7=d%G%oUWu3h@orVC(ND#&VeZuK` z?(KW-Irr-(>F)a_pQWcor|nS2#b!s#bJOw_pt7d4H0sVsE7{M|B3Slt7niH&q z0yJJ^A7FrD0M@yCp(=n|UOX&4;LDZ>h4E-80OI50|MTVzkaFC>+kan3rF0F)me>2+ zf&t^{>|X6;B=9qo+57C*H%{&Hg0n#{N>GlJJzb{S%y`^^h~!x7%*Es9o}k5rd`-t7 zEe^}N#dh3>4#Z`{;gF&kBK5Io04$L@DxRL7eB!9j?Ebvj4Iimq-8O}2 zYpYh1sZM=0+SAfls?N^b{Aj4>Olytiv&_Ut!_cbL8vmO?s2M1t1?qsJQy)ybJr(6za7zghvi-RNnB zuGtd7qtTv=jn(RWNvy>oVrG8tsWn1*PnVgyX@{A3*siSvlx)vzd9^<2EB_)(8@tOV zb>wPoOHygrPHy(Yp~HrZGlCl5V#Dxm!{#%=wd{TOuV{{Em-Dy#$nN)7olYqe7Wu25 z-fH|h_l&4EaQ`>M^@i=|qU!?=KDkjy*K&!2L@5^_|qkNkDV6EYeoq#hyY+PTwGij zXuD>OtE;PE7sd+-;qyXxyaJ{Nymq4HS4N<{y{>M@4poK( ztY7cuMh2G%!}vU25UgM_IaU^$5Hkfx}my zXd6L_BE^bCB1)s8A_WoQsJ18;8iX8g5iDD%U^s@Q;b~YL9*0#QJ$9n`Y+FayTmwig z^1va3g|kGg=PZnib46U07w(1m;&NOrl0TPYS$LKxOC`f)m=YJ`Vv+c{7)!>JMaimI zJQkDSQ%M;6ZJSd$Nu^U+(dL}vGapFUIQuml^T+)~{;G65{dGE)jc1FpRq=TI>v${$ zPZ6c4$b(?LHHRXhU-B(FcdO4DN31pM17-S?#kOVZ|7D?VE8&`yp2K{OK8+HMk{tx- zQ^O80Gn!W=N;43kD>MQ$0yF|N0yF|N0;?E-P2x>h5bIO%r&um4Nt}eGvOFjO`6Ux5NQn&t&m2+dPrDV}!tl~pRPkp5zFy9q|`Sx38xTyA&>Bn9G0Lun_-`I=UrTLk6 z(Fo`o@dptM`cOO{gLfdMIy zGGzb*e}61&0w50XG03BWgc}~@^H3^YOTXN8z60(lUMfrLHS|1A`;C$L>A+%lALLaD0c=I-X-!uFIx3Ft3BE zSS{2_sCf-kC2yftLCx!*Dsc<70_r%3c0E=;y36J?SXqhAXU#aLVDG`U&Z{?w@rl3L zvsV@>)3f2c<6r@JfG9x40g87DOogjNDwP5xyi35OxKt!nB`n(g^>kE6EFZBChO;un z8CVW0QJjcvWvRQ-Ywj4-=Nwfoms=c1x%NqRx%T243`$M?)i1V&skS}Unlq0fns=-{^=DaVI zYmbHuw!CJ9ft8u0e%o;!;o1W(muuG9f$Y`cy#zo?$*lSYDAcZnmiD>!GEN`o_C5btgXZW$5~xh+6pzg?i$)LIRQ|Qcx@=ihetM{GH za}#TpJ!zZMB`3J#Tl8;i&9g`L2U6|BRE6jP_rn)fw-+P@r}MyTccD+ z#L%HbS3x;kHADyj>~@~0*5_*zC$F12hz5P3R!U6hd$dQC+XTMm2<6({WJ<tyHE-Vocu>{rX1jE(sSo^mYrw!DOeYi73`3EBz)7re>m4Csq2vL=3v4 zMcEReX`JZR*JyKeDIB=K#_u(J0wLU?rRycBV!*uUZ7g&mRB%wz%j3Key{G6?>AzA%UNG z9O=wx79Qr7cxHSzaNztF9skg#qQ7=Ds8gfEy?tHpUOrx)B^Sr|`(EfPXp1`*tlgON z^j5`1SyNc0-`;24n!Kcl@J#?b>OEGWOczB52HqPy+$lRLtYPhZJf!JJZQ@t>?tRi* zTP#lu3-I-PaJ}M?Qi=1t*!rHFQ*lSUcWu~q|5nMx}9sa{*$;qHf@4aJPNA_oKjpDQ2hKzN!nJTfw+kdRLrY-$= zRHaY;vp;5?i)!>c=(X#1=P_-rLdave4H&9E&)X55;Lp2h(6nql8hMDFePghyJEfUl z!`XZDLUoBEg&z>W>Hezpz_zR?u{Za8+paGXw7lIc*`1->%{^}YvI?TJHAoJL>; zAn>8Tyy0#wHt^_csa8rF)Kak^EG!iM!C&17=7)svLJC}+=9f3-^57||y~m=h)6b1T zQSH|*S_~WT(@iu23qxSOM32Spx3FwijMw|Q_9TNH{nCsxS{4R7B(poIW&S2W1mfB| zrRD4=@*w2Ulbme7`P0;1q0gzyMLfIu}!l&6$OiWC(Ix(L(>q9S>~8;9_t>s_PJ7Po>dw94lAD(#np7V5 zgPHl}oB3wG`DI9M?)}d2ZjRxEfFyjlL2}E=P8Ylr^p@$b%1u*xD!!-t;n`b;82OA22xVX4yPoB_3 zta;#H}EyIBdNpF;;3?$84VDKE+qhQr}n>MDxzg)tKjVW#m-QLBS8MHka%%E1&5 z>$TZ{lJ%9%ENl0%(%OXWVFdv>cUr3sWXSnjeNu1rSGH#y4X^SmX&>0!o^X_1?Ooc_ zRH{fQ3thh~Yvkna`nA%?%|2_s>Z?1m?kK-{+50yJYTMsE7F8RtWB7RazBSu<1xUh8 z*e_ki-|W5SQjhd(X4CRo|MKgf)trw$5Ln?|GP6*kq9qV;_gL_ow-zDZK8u(5FC*UY zNhS6k`!a#!zzZTQqtod$EO&E*AItM5#G|*NFvjoxhj{{&%MFIVA)KI~U``N+Q^1%H zubn9Ql@TZ`%+KX;0^zJb|NP{~=g+Y#AR#X#*kJqbkAL}rY{NP(^YoxI82^L)7Qq+H z=>PQTlYblfx_Su}I(R(-C#g8ltiuvEUu0xt#6*gW2oDYAa$(I0T0}TL7>C1gj%E!T z1VxY(GzE!8W04BQ{sV_TZf-qmsQ?`&dOV*{L=!SHsi-Z4i8A@j2TWusx|F|E?1g$E zerPJ1%1?ceie#hN{A_VDnv7(k0#v{kJP;tO&{h0Z;utgr5u%epXuGVdpo<7c*EOX| z1St|t#%rn?N9ZQ0Q@XjTgT?`wG6w5ok=(pd@5kPVKkCo-7pI|VkJFGGG>4xfjzi-f z$03PmB0o`VcoE2X$EQ#_$T>dbh@-hi3q?cDEl0riZpFu19XW-(rjR~btg6=jUS8EU z8?H&IHQ4j&Qz%g=*+78W8a9A2G0#bqOc07go7M;Egoa%VWJGn~$e^EMQ2DcM%8I(ho6rn9?O zH#mIl)))7_dFXfpaQKpSra1uo98}C~Bu+x{Gf;7ABXJ6fpMQ!4jl>D4;~?7fnEmL^ zwB0aE;UsV(e`YSX^4_NVLPV}(g?tM_y(=;qk~I-qT%TXERTFo z1N*pi(66I|fuHE$;Wan#Si}H}ZZSa8YIlJ6xVd{cCj@E~3IPg%IfsCeH*bx1|DS*U z{rm5}`!hskbz;Iwc&ilh?&r^A&>ube2eg^I^w{}ad~3Y> z=x9D4OW1h>cITXfpFF(27P%b15zm1q1y0edZ7_Rz_r!Ox5r-7l^6rUHObPUq6-Qvi z5ghEfheBrD8+6hh2JcdL{#i7){BU$K$fVc`Hev}zT~jS~L&p#GF< zk1Ssz)DLSrWim;wFmmh<+7_i;k}70l4!7=vg#o;qOj)2T7{8&{s1&mGl9l=!sy10w zX1Y)S9a@#U2#3)-VLUKCqVG`Ez;WLm8`NJ^)ypIjk$z02mhH`48}5hC@PTZzA*8W8 zFr@M8dbReTN-kSFc3I!0ZGz6Z`kShDSxshUxc}HS?I(Chfmlel?}qaLTu{E@4_p5d&b75nLYM(4m5)A`s zS1KeqLf-gQ{W(>YY+WW7bNJ#852AEstX*5JDpsbCUxSU+$}O^N80H0tWwH>3tr~5u zEG=^h?r;yT!4a8;m-q5SR^H!^YAm^PENC?9lE@NvES4{cA4hf2U4A z5mvus_ujUQL%hnRWu6(gySE=-tqk6|SaM-#@1@k%=th6V(BKYj_NnE+_uq4(v!FS4 zKU=ma_p82LEy)cb@+HNp!HwsIrvmGlvc|q*jo=8XV3u9$t!zvFh*!njc(-5Ln$!@y z%dfb8U}HyA{iHCx#SjFf1O50P81ywVPPxnaAiH-zUdv7`3yy?Su8D}#yd8ofylY2b8)^Gcq z-8j_3DFkK#0nJ5ITB49zge`?mvUebrN`YZ7k2X+u#|nrSmNAyI%9%6 z4`}I-w;z$ft(^Yrq#`s&0OQ3oATPe~Z0|i+@Z!zqb9UVp-=46)NzOesw`+O#y#oUS z#?vZ;hCfovW`lWeSJbgbL0KKwW`otN1XC rOFySJ_OYeE8t)#TTxZBN*d$#RxehZ=C5A;9at+>@oEz-3n|J?zwKcxt diff --git a/package/firmware/ipq-wifi/board-plasmacloud_pa2200.qca4019 b/package/firmware/ipq-wifi/board-plasmacloud_pa2200.qca4019 deleted file mode 100644 index d1db0f5f4b8b734c0c43df38d9eedb0b84f72109..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24324 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 diff --git a/package/firmware/ipq-wifi/board-qnap_301w.ipq8074 b/package/firmware/ipq-wifi/board-qnap_301w.ipq8074 deleted file mode 100644 index 6b8f8b9ce8470b4d141ac5547361176cc25542fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131172 zcmeHw33OD~ndV=wN~HxMgea-1K!Btw2|;W(#%7ZQNCJT{k`UTAKnQHW1}rukW6Ta_ z5vzp3j^hyGCCA6z?Kn>2Gbgr5oMqBU=Je^)lS$m^EZxo|-P6;Fj|G)pe@9I5j#loWdi)u`8}DDcVPpIK8`sU7u5)cquGzMZ?2MT+?|W*^wvB7H?3lNrqNwuz zho(RHv_r2!6Nk85dUF59Pkb(M?n`;NPXD)F|F=Q^w^9GMN&mN5FO7fB&S2_c{$o_e z6vA0>T11YK-^0JHJ>-qBtQ5ys{WH@sU;pGg^7PLF$87yGKlDAkkPGjEY&c&5pZ5x$PDzY_ zWB^n&pjGVuEBTwN|8@UQ3;$kzb@h|pSA8iIdM|lv35PGvc{j&f_dNO)m!uo}g6Kt~ zmvA`#fMujRMwb}AC0xMac5yh3ysWaOp`~@*hK{pcmtMa7>X+Vn``!26|K@kT|DziQ z>55B;XGlm$h~u}5|GE)xDAxzJsSh$rBsu~yagA$`C+#W z4_T|KA%(!;AP_4)~ zv&6nt(z~8mI@RZ7oc!=53b*e*e(B0v*F!-h<71HtABgx~6Y(4b9xWmXIMj-rfP2LM zbvLHQ1$&mji8}dIDNk{wsS3~kRUmGOb3GiT=+LagT-kzeSgS1|j3`P{)U%I*u3^jLHKBew!F@4CsTO814^YFt-;N zKnFSoZvcbCq4s-&!Oub%ypHxMZ(@+rOAJgqIBL`p#^73X95aETj=>i#dNeWk=jieo z#E^DiV$cXXfFAAI!DQMo?ErQ(?tsz%c%0D2rUQfDMQ=ZB2POs~ThcKYk2?N$^g4*a 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 SvE1>Q568KurQ3I$`+ot*{f0IG diff --git a/package/firmware/ipq-wifi/board-redmi_ax6.ipq8074 b/package/firmware/ipq-wifi/board-redmi_ax6.ipq8074 deleted file mode 100644 index 98ed9c6f65961ad496025053b64b5c340bda8d36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131172 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 diff --git a/package/firmware/ipq-wifi/board-tplink_xtr10890.ipq8074 b/package/firmware/ipq-wifi/board-tplink_xtr10890.ipq8074 deleted file mode 100755 index 2815a4d661471ac403d9c0f38258aa8cd95a266f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131176 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 CPBuUQ diff --git a/package/firmware/ipq-wifi/board-xiaomi_ax3600.ipq8074 b/package/firmware/ipq-wifi/board-xiaomi_ax3600.ipq8074 deleted file mode 100644 index db8ef4cefbb50a6df27ebe3554e2d27cb72a88ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131176 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 diff --git a/package/firmware/ipq-wifi/board-xiaomi_ax3600.qca9889 b/package/firmware/ipq-wifi/board-xiaomi_ax3600.qca9889 deleted file mode 100644 index af4405cd53cb9ca94b9fd2b75856bf84ac0d22cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2260 zcmWG^cGPtY@h~*-)^+lC402(}&CO*1f*l+nl7S%+h?7c-Z3~h!b;?rnQu2#z4b3c) zby8BxGLutn4Gc^Tbc#!piYtptQgd~oDhz-CNffRYC|Z_Sl$n@UVjGc}n4g=e>lk5d zW?%rclM!f-3(!s%4wgC=#-6_)BzG-hV3239_he#l(E&L|9*6~j7z8R97y=+H3=)?( zhC)&V_!$(K6c_{r85sf?L6CvLNO9}dt^ABX|FZLvVh|10axuc(sK5Y%AUB>ncaDZO z5;9tfkr5QFU?2ixfauiJWMnQW?6V9E4h5Zy7`Oy78QM@a{wQbQ zWNL0@!@y8bI(HEaSJh9R0b)bwH9HDQm#+cgs(O$b1dUDHrpCsG8kpG7Q<0YuQIV4s zQIeAvQ6&N}F!)4dOjxn^=vh|I2vDv^0{?zjFtBhWFf=2HF)%&SX9U%9>C>ktlep7ax}AxW>FHrQnVzIi#+vVYuU_eu z1k@8+K;qu|FLl5B?)u&T{`bDC_o$VNitZ|^ExYHQ<#!dYD5@@zO`A3eT)Alcl6?5~ z9oq`lZfL)A%ch6#TDRfhj=LUSUy!4t_Q%$4T~9b?PR^Z=uig6a+RfVw8XsQ!7*ZBB z&dBPd{8Saj|r9ad9#HcJW^~e4lhT0Gn?hkIE96fhf7$yIyedHPH1#k&9I+6ayp1 zfLngptHUE!tExybFgy%Ii_f?_cQ|D4mG=`CW>{RpCz`|Iu=?d}MFJdCi8wq_jsi== zu2Bd|&@BGO3K>{SERDM1V2u3md1mf->ez*gZ}bG6Na{x-Q{ENvy&~c{06tnp;&7-H zJq7oO|EnireW^bdnf9KD|Ds6pLFC7VW8A$WF*A_=H#YMBL}V)J_rDy>kMp&0_alEQ z^8XJT`G1D?UkbLL^{+zv=ZLr`BLBZd&i^D_>OY{2_kv{{HaHlU3l97?Iba{q20uC6 z7vy06064%H=p4KT4h{wD9|#9O4RY`*>SunFgQNj+VCumUql^#-S0eM61`c%&zGN9k zlY`$z&YwySsRt$pP0$03qg_3iK|Q7(K#wNvH`*UN8)G;X9Q-bF{UJRtISA^K&cS4q z@xLRNK@O&|4?zwRSECQmBYiH|;lR`b&V{~u@Gp_;*EzT>;>CH+B+g~jKTr;4U>tON zfIdv3E>oAFi_zrZM)iOka6a4MAPu@4vIiyyrXCEIgWpHyka{p=9AG{s)1J_#!KUhZ zV8f>A9DFlq6HN~CFa}<5cq1HO3c!g5Je23NLm^NHMD8IO8fd($07`||gt zZ%oGhkm;U#xvjf^?X&cQ{YCq>Tia)pm$k`SUe^~|Pv`GVf7D|s5AD;-^H|2stV?|> z25tre9mg(4zFE5&4O4aAk_=pW|3mXo^Qzy0_eIj*7MXqy_tlSxq|}Hc;e2QU&dB0z z^eF2)B7v{ty!1Jok8H#_6Y_g-&Y75uGF*`h$oig0#+xED&LID0&)bevE6k>7)Jp@c-7t=MQk_pWq-@1qQi!}MoS#$(Wf2I#?DaENh;kBU4Fndn2t zTjr!syG=bneq9fc-;ewr^gm(T0QCU#G5s6R1I#Bso-9tmd`yBqO-O+rxFU}O z=W_u0Q!fPPb1m8d9utw@&V1JO;46LfV8IROL03=@RvJ7cPDcH)k=vjBkA@y_9CbZt z#yGJ5oX`I=@;K=B0P|7T1L%>L`7sXqe75m-m&~7lf9NvxU<$@D1$)_vu!rNRNB22`X4Lx`i%D|k8C|j8tnSCGZ=>sw4>2z#{|22fOUoId&nNt4bUE7E~KM= zT@PT_Q&yt>9E@Wc`hqzT$z^^A^?z-M^Z?`FZ32%R2dqhU*7upPC%PV846g4ON8O$z zA-@fKpzFaUi#=F{{&QWhX%F=J-wWC!*b{w!LOrG)+Ss3%dJy<7#^LK22h1lw_IW9_ zXvcjhCmHk68EF)ZJ&L(MnDQ9rLp}5W`j`kknh* zjf>=TdoUP1_$WA^FpkrnLHjwMVAr`fu`{2;)`i1pzqzj1)B`<#a2$2J-eTyXzQ3?z zPiW7W|Fz)$g7$>#niuW2vA?*g9&mqvaY({A+SUW>e1u)s?K0+*UAr8b&(A^+poiX? zpk1GeHrTN1nWi2wKicnw9*6YE#=~B^U23?K>rhHS8eWDR%d1q5Zx!KX}md+qmDzMEf(o(Z`h5ym2t<33Bj?*fnJK9Tpm z37pTrj?5$VNS}|dSk?vDW!BFs0qr{11sl&Nh1MlY{klE(*we$19$-GF!>&%p zIE1YWD96s5Bcb_t-ZGzaF%F#1Htf22exUC!pohLX=n=+2zu$008bxC+rGEu_Z~^sW zUGml=e*yBRqJG%+NG_xYn2*yjANBh#=y3vU$v7L&H0bsK^Kl09oAYrX_kDW)%Z5GB z&ktyi=Ai8ZSy#AEq#hhV|C?bCW(V`zd_IV}(C-|ny0;t~W>p5Q2k1lKtLVo$?3ZzV z;H$zjCbTE8%Ql8lx2gL1Ltj0ZF+e@|670b~=)r2}5$utEe()=s_JDSo>jKB272`;I z!2N}tb>SaiPq0ta$I)Wf$0s7cjrCpEBj#uQ`%%BCN8m5c#xq_ad+r?Mg3Tp^!rY>A3WG;|169{ zCgx*0=F@cW=x>4^aDPC%{ILx^;5eFka40wq$gkhG*%*hgb%lC_`8*JNpr3=iXW8FS zk717|p!0V2H>Muw`?R-V*Sh=Ib?(<~5E)vZ`|i`GBfpLHdFFR84%nZhA^+5k7zeBi z$@jq~O@U1qNd3>D{hPrf*OdY64|F}iIHtoMOvilG*9FwibLnxP*wBNY1owH!KkW$g zcooKx_9O}8U}L{O(~_U-3eSNip?k-Cr#(9i`^&H3M{y^7*uR#xxe=73(YoQ1C4nPl}M^`;RVEs1kH)eeVJ?x_g$r#5( z*n@F4)`hV1Jj`eR8jK^_pO9>C9Q6Fw`3!r&b1?3$;%w|s^!A(fjQbntp$GO**JB&| z+>jn%ea`p_#u0XXN(c0*9_8GRa{OqEo%?^@Z@h{8oR8S&h3?zz+Jo<7J|TZ9>Ys}F z>~DY`p#CJ-qeL4UgwTB_^eA-S3A<=_pW0UsCWA-n;Y5#3J-~eCJx|&fVGpn_g!UK6 zA7|rSSD()qN9%p7t_QU11JQ$*Vb2Dk2YuIPe;E;$ebgtWlakzo|#w_UJ zVD^dnedk-y!*i$~`wRW=Tx>t}*v5V5ER16o=3_c}A{#DUfZ2hdSIKXF`ZE9!I&Oi+nrN-V4JEjolxn)m>yo+ol|;Xo2oILQ0c*# z9$wp>Q+i;Vsxh5V>A{#DUfZ2hdSIKXF`ZE9!I&Oi+nrN-V4JEjolxn)m>yo+ol|;X zo2oILQ0c*#9$wp>Q+i;Vsxh6=)Pu91Yd)U)bmk*`PS$k04^?enxG}rcS8m3L?0sha z-i4b}>r={l;|_JMKTx2_LV=Yh4+Yo3>vE)5-x_Qss z&4E?k3Nw|+p<_+E@;7I+cq@D3o_%rE$^6|jH}SbZ)9pE2wWDxz_G-T+@8?gq?_JoD zy(ZaG$7j1%?a$ki)y{W+On0Vx&EfnVSr76(4%2m=SoQS$M*__$OU)RO3*BoD`?|YY56s^hSZn3};ECF&=WWhd zm15y#|Ap$K_dk*PP%@r_Gu^%;D<3b~JfqIa-;tyBPtJWfy~(P7FLbvZEZCO4j{oO{ z>CT^DeK>DNpq=kqo9^(@nwmR+Y-QHNGr$M;xw_vdZRT+8R? zOxJy4)l<2TWHwv*JK5EEaPGGBwS4~GbZ5`CKwkoDJr@2>bT=QKzawLvRbNgWZ$Wt( zO}=GjPLUTo*FIgiF}uZY;oya5S0BpTKJx)9SI?el*^^5SEOned-uz_2qv?&-`Pm;^FeFgQ>Pks!$z#J>i7xhAM;wrgZyEhhw=CPdA%*`tekdrtvQ&tEi+7C zp6gt*D}Q5Vi`D)eJ5u-fya&_ke2dLqh#Wj!v-keTQdcKi=38e_hf*whb@EvCTTcA)Af7jK9;uH%GLg3tM=q=&RWg)LQMC<$@bj~HqLCd&aG2j&4=c1&s=Yv=cms% z9h$d2V?CceHr>gy&6wvIZB|YXV7|@XkiEuZv2|ZKvHHpUhi5kVE$c`3vDW?bw`R6k zZP?ipO;62(?po(U*Rj=4=E6REEqRZhY1}urBYky>h5JLNoA%G!lChTW$eZr)iTYi0 zH>R~%=l;RND|g)YKz6HVk(o;5`6I2{^Vet9rIhr>ojBRFJ9l&XDyuy>a-?}@!N!b6 zpT#B~Khn5k?gN<(*1U&KHSf>g2HS3F-_bKI2XeQ&uu7i`I1YaNdZC)%Da zcr>foZ>i&Rhg-Mhugj|SS=zkkMAg#^VgFJr={k?p@5tSd9%hHSj@Ip%|4^VIY<`?> z*gI!4=Bjm`pKaKiw>5o@b^U$*%n7juyH$awtnCJkEO4%>R)dQR7f$P7*Gr-1{4E| z0mXn~KrwLh8K`bQck!+Fdm_Jhck`R7TA&zE3@8Q^1BwB~fMP%~pcqgLCa^)IQq$5idf=iXID-z4 zq)Lv=lR_zzDruB9*&rRVQ})SGIU^V3CHbf880X4cH?S$Eu8eV8>XJ3A}O>_F$~hkI4J**(|))V6hAc=^psA6!4x?4E(9o7dC(dFt4OI|gb% z;>G1*`yVu%`5lD)zt*?6wVAP@aBFjOV|{IHzj#DkEzNqk_Fy?-;l{?s`d~R>@z(Tq z(pb|6!)I6YRcZfy*H_4}@_Ubf7<77VwwwpLXwUc6vIpLiD2c&n$W zg{!J6FJHX4u&{r)tgN^=KfiyxHNBB$HG10$t5sFCY+3*CvSlSD3l{W`x2C@}(-`!W zm9hQ(!zCq!g*rc=@cL=4-*+nyMi{!J+i8AXUmuqbkv>*c1*^KLI%`MQ?4-Fq-?yf& z*=cis9klA*t)P$BvX3Ptee`RD?Bn3{+K#T-Nn>YhM`N0st&jZ{a225#Pz)#r6a$I@ z#eia9fDDY6Pr8`JsfjqWc!xvN;2jQ!6Je+3xL$D%H`2I~*p2kj2uDXqAA>Y8NFRgr zu?WXrKYho=-r76fxO#Zu7cg^o~17o2%FW2#|H;Wc=d7HMp6xJDzR z7K3_YP%m^ti;a)gBIw2-s|#hno#*>Cl}}x;&43g06qD46sp)WHp2E8cLJBra0Vn3E z6Z6!GdFsSGh1cL+&S9RXPRvs$=BX3&)QNfO9HDvo)CGgcr-JLV`E7fkRKh_qFidJZ z3SGi*?+Kb=-?}+&e<+xY}=zkqL8?y5Yk-^P^%ki;!Pt|Rost(8yY~B>9$~?pR%Zk5oO@EP_kQ~lOsB)gQ)Blpen2h zgXoINI>Zcw4U7Vc0Sf~|tZJ&bK`>w$78O(sgfTD(wNhD!n1Qf?Q9vRJ%QOqr9+ZS%L94o`}!0+ATi@<%K=_3T)%~SG&cRw_f`2 zYH7aaf$)OfMP%~pcqgL3>yPZ?8D(d4S#nFaoBsqyWn?@WL4AzY^SpC2F#u=;|XRz=t_?>Q?!NR-UW8@6hjWbv`&S2d* zgLUH!){Qe*cn#hK9|NBV-{!^{EIi`l5kGp*VBI)_b>j@yjWbv`&S2d*gLUH!);&hg zV4I&8G5swz)y8adLYoj37!n4?tfHunjR*rnqJ+13AtN$Ss*)jN;5Jv+A?f~*4TdUc zL>L&7LBGul8Igffl?)jJx4F6wsQW`k`VbZ5#XBJI8oUes5BUH8f#WCi{ssW9R9G=E+8LN2t{C>A=WpUYnrppu923D0`G`wm40+TwQwqyB`c2S7W3OQ+L$2Vn8vV7*Gt{nhYd}%Qx7T{W12Bu`Hu# zT+z7R@3fdS>@dd1j>k3rTj{QJJE9%YgRM)|q4fVe@c+L0=~q8( z>al*3rT=HJbzAfQc~Ae3^|~2;O=|GDBkW_eH9WtWUVSSD6a$KZ+nIr#6EDP{n%F*` z-YyTus$i@HhULF@PQ&sV*A4q@SmbNxP*)TKiUGxdVn8vV7*Gr-1{4E|0mXn~;C5pm zG59>d?bdJAU&Vl8Krx^gPz)#rL?+6{5v3tXY8|YwQTy?b*SlBi8S*lRqn*Q1=A__$ zF17ON6uhH9sd4pdDpoO|7*Gr-1{4E|fzi!?M_g0c1DDK|qQ#W#mqh*`c~aC!A&TL( zatcwrG)svtM2V6sMKu&64^x&6D*Ns7xTM6;z@ic2U&_eq)*7gLBjP-Za_ zHvy%}JfczxuhmL{6gN|d^3mJk3JOsnQ`S<5N+ec_S5Sx+^I8#ws2or46{7)0Z`+u% zlEQ22nQ{q*sNRV_ET#}`$F=2U6r!C#iz+BYyTJCMA_~z_^nG~~g{Tu~(PBz=HpT(@ zYD*}*c0oRtMdcKt7o6m6u1i)>h&}=;T|^<8?VKZ}ODIG?LtAR< zDMY_PnWd!^qF)o$Qi%Q)Xz_9i(Qk=XP>BAWXeov0KZvR+M4tjJSxh0)9CM{=F@?wl zRJ)i$6c4ndltSbIDk-H9rGlj;WfY&Rz)Go z=e0TtQ6aC@Qiv8hftFB+${a}6L?J3izOq^hQKch8$|@*CRVbyth(c70R+m*$h#HBO zQ;1rTvaF6m)CRP)hC;O7u|<|vQiwJGf zBTLIEM7x->mO^yM@v$tcpb!-z-?CB)(HTdvEL%Y#I^{Sj%bO`g-Hw^Eyp%%pyaN-g znnLsz4Ung2hA$o_XmO}JbM0FIRcTq~k3JTFo zw7OzBh3I=oS&6ry5YTR|ZbpcNGqqGej0 zR4u0vEk&7C4HTjk+JBd-A_`HxmM2w9C`64!O%$S5qEZS`8&MgBXanl2DyI-_B&wwl zJT)^ej;MA_~!SNLjI%Li9XPRRx9UMWFgc6r!!r`Gy(_SEq~ULrn#R*Iq?i zYHBG&uWR>6O%a9YFSL)PrjkPRCd#a?p%A^xd`l=qDY#bCNFjQUXgP)GTSQAKMBhWc z<{}Ew-{V?o4Tb1qrmUtAoxvJjzMMkz2{fc;8HMNyQh+5H>x@HPd0DY*h zqY$ljrb~S(h3GP`RZ?j6tDU)0zm%ev0^3u+ghI5DIBYgqmpp9FiE1Y zFL!GmaZ8Fsi(g_fJL6#S#=+tzXmen*b7UgyOp>-hCTRijXqnitW?^@qjrloKys%b2 z%x}L|Et6qICr6da6s=ySL>0*tcQNdGi%ip2$#iYC%+ShYhHH_`h+ZS9+6uI4rKD@k zlA$#~|C%II>yRvMlVnBxT4qN5LT0+RNOsh(WENJDJG6h2&qN)NJ6)fZyPQYmF4r-+ z+x6e%&s;y39M>=99#@;(8@Cp|9e$n6j(q@rz08hzQ0|R+82%x-H+BR3Bk&vHV!!Ob1s+$P)?$^w3+lnidKf=@{30)f>F(ffk8; zHuleB8PX7XD;Rn`_FaU$xGyt89^6%4-`zcF&m^O~ay`TrygKQhf^oAw2Rv1n3Ao?T zLu`Q&VhfBATWW;(nxqj*3WbnPGvbg}4;dUVPOlenf9H8g?}rg$9S0Csg?_{YL!MA5 zDHNI>3iak-Ta3KE&{gth#IeohRWro)g=*77Y@elGJ&rAn38fQlYjS(aOTs#g5J$lX zu?6N;GsN$>@raS*N6A&eRxxC> zg&}gVHTm0m9P3C5wLU9UFGEIop9a$&5nQ=jkca?|7B|7j!>EcYt4Hj=; zR~U9lbn=W~0$#VaH&HY<_%O2zuSX&M-E)j6VwbqB`LT8r8-MyUu16=&USKo;8b&W}a#pZ^Ia(A;Ob9~ZbxmSuW_6bXopy<9 zQd%g#juY+(wl7DE!}Zvy*(-wSbsRtKuAs4JdAuGdG_MoKP0lE_Vpl@u;&7Z%7Q|?c z1ABJU<>+{s387DHuWP;;Ve~I5F)tXAsP`u+R6t=A`FAA*f;n>Z@o*(&Eip0xqkZG1 z%nI^nl;^r&JBmN;F-e(-_}7&FfdeNbS-Rj1)}okk6Re zr4ZUn{h&Rh>p}UNj4v>dft@lwH56f9P~TT&px2UJ^|Fdo3@8Q^1AQ1s#$USV^7HeD z)TiJtMWfky9PBEYu z81)QHm5zC%z7whgiUGxdVn8vV7*Gr-1{4E|0mXn~Krx^gPz)#r6a$I@#eiZ!F`yVw z3@8Q^1BwB~fMP%~pcqgLC0kK$HJEP40v48CB%(k6?hPR!ByGZD8sL86 zob#P?&v(vue)o{vo9~zVMtp2g?7pPXkkp{K^w^99AeBl1l#*a92Ve(Gg|doW1to=n zg;H_QnM7z_K88LRfsc^U;Pov z!_PT>VB$k%Q*B{(GCVk}Y^@b%?@5lD=*POjHa;|HZmP}}CP(51kNg6_#0}+HIK%77 z5fdLl0|{=>2L~z1PUZW<;o53TvorW1GX{Qh{rj0(EtH?>GWRfHFc%Ngwbg)<>6NXl z*52lV>WCu0Oh)QtdwG4LlzY%MZhWAuGx3anxm$kcU`}Vm8D@n`L0?mWETYhN@7Cmd ztw-y2ivx39qdx1eeLwvSw_@v?cLu9FUvCboW)zQ}Evbnr;$$KbcVWK-2{*?j>RO+; zBdKXywMWVA539O^>pe?d@>dp0gts~b>>W1zYLgS<;<|Z@$5!1NzCnq-$NrSSao`0J zmXXP15|-Q9!H?y2GvaW)AuGh~(c61?D4XpK|9n_pUfwJ(7AupoUUyBR^MxpvAAzi_ zj5HR@6HfHQ56{1yp2n_#_#7W^ZQFmp{lhngZCJ;xjt*oB<$tiB6Fgyh`xh^s|4Z9< zxxFqOg4ZK(lG6H?AuM6@vGl@Zq9}twXX2&1n;RV-vY9qh*dQo^#Gn~C%8u8c ze7B{&W4;0eGjh)=g^E(S)W=lB9d+lr3!PDC#0`x@a0%!!K_z=I`8~g0*MRi^2`PCKs~q~!gw_PSv-=8 zrgBq-VQAR1FeDO<^Zh~OW#!u877}aior*VN!8T<%R<{$!!;?f z220L9ff9j|83c%}VFs8v&1({+IS3FH0s#U60s#U60s#VnHH^S!-e$y;`Wo*wB%Qj0 zw*!f$uGb03C~Uhr^1v|H-TGTs&Yxq0PL^zrHGB$*rCW)>i+N(@0L#@K3oTe8miDt` zEF0=0%q>xjJ^=uhHHx0mC&nc=C@?TEz@N=TZBv8J1qAr}LjP=3gYM1vXOo%@ZAFu= z!~g`ie8Xt~AQbpQCXgpgY-bpqfe9;Hsi81Z!(ixxHCpWgY@grCV&%58fq+i}-yZ`Y ze;oqIuH=omuyl6DgN!D9AR1RE0xyRhX=L&t7=eJ%Win;``%tbx(XDn2%3|7tS@6xZ zXY>nmrJt`4`y9n zjeN-4c4&YK&fk7T%eTj?^D>TT+4%N1jVCkW+Z!J?Q`b_)G2Xj5zCDTs?(_Q(Zldj&rFnbNg6RTa#g2V$qgt z5gSCw61SJ857G$0Uibzrb0dRmza!!4G%QblO#(G+G8h;lgTe2};K`UBcqX6#r*R61 z-enIES3CQepLQ*cBg7~K0t5nU2mw7`-W1>dKY#zr*I#}0dx(dYgOBm;U;guNe|q}# zudvOSZ~yG6mTxZ*gokMP`qR_@{%+|x_@?;w!NFWEmasSj_Ki6Uk2ow|3*3f(0ndUF zf+f*RZ7qUtuf4mxr@zTugQ_LpoftChwK@)&7OiE^vAt`^wa4^D((QeOS=g7{<4@+^ zVd!h7{$C8+z8uk9P*uq@MZsU*)+kkV@;nh=b4ztmUM5Q9`)Eegy$ZQR#Ajf?5xaNa z&mTa8c9l%NU&NgnR-acKlVpha>QPmXL?TM#2Wmc6waKNTI6f0I7@zd>19&%yJX4-I zbw}N$kV*E6cBtdT5MIPR;OVf6=!I*CXmP-_%Q zNoCS*e>Z%FwVJ_?U^sj4OMNn3D(hj0znhz(xq6E0bD0tu7|l*}No8n%X+r4h|*7J-hD zqt~J@1T}h8T~Ys9nQ+dpZp+cii-{*WW$uNJiT8Vp&hCoMM$Zi$=T4TjJ{irSyzPAEh)0)@~_wKF~jWxF@lVeVkU@F>v&9bdzrl zt>9XxxG_o=aM&fa@A|Pzkte;&X?d6W3p!()y(*}A7y87P1gE_#TyoF09C$li!pfn> zj0{wCrJeP!b}L%58;4jpfxs$2V6ji%fX~3viwQi28}s?j_|rFheAw_0K6!)b?d8St z$^{)JIDOUWKf-OtF4wO0K( zzCBy}Xc-2>9pf>>$IiIByAf@x2Ls#R?~rE?nNS$lz86x5*p4tk7EBD}-*4>YG+-%Z zQeWa6dNO5(Lk~y^kgp#Q!7j7?brK#LBY^SYDU?GXtK<5^<>12`&$rZdb3A)p`!C70 v$L1#Z_IRvop&7xqUnp{foy{U(NzB+B$KJ5rW*4|f#|XatQh!QXH{SmN?KK!Y diff --git a/package/firmware/ipq-wifi/board-zte_mf269.ipq8074 b/package/firmware/ipq-wifi/board-zte_mf269.ipq8074 deleted file mode 100755 index 050b1259cca44d8d1bc5079fe3494ed9d466e2e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131172 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 dpcGIFC0A literal 0 HcmV?d00001 diff --git a/package/firmware/ipq-wifi/src/board-xiaomi_rm1800.ipq6018 b/package/firmware/ipq-wifi/src/board-xiaomi_rm1800.ipq6018 new file mode 100644 index 0000000000000000000000000000000000000000..8a5c47b282350c29f32565678928063c8dddc6ac GIT binary patch literal 65620 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 Mdd3Lov7(;;4s?Eq?f?J) delta 23171 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 NXY$>iGx>@#{{zBN#x(!{ diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile index ef6cd075d..d056140f4 100644 --- a/package/firmware/linux-firmware/Makefile +++ b/package/firmware/linux-firmware/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=linux-firmware -PKG_VERSION:=20230804 +PKG_VERSION:=20240220 PKG_RELEASE:=1 PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_HASH:=88d46c543847ee3b03404d4941d91c92974690ee1f6fdcbee9cef3e5f97db688 +PKG_HASH:=bf0f239dc0801e9d6bf5d5fb3e2f549575632cf4688f4348184199cb02c2bcd7 PKG_MAINTAINER:=Felix Fietkau diff --git a/package/firmware/linux-firmware/airoha.mk b/package/firmware/linux-firmware/airoha.mk new file mode 100644 index 000000000..627541ba9 --- /dev/null +++ b/package/firmware/linux-firmware/airoha.mk @@ -0,0 +1,8 @@ +Package/en8811h-firmware = $(call Package/firmware-default,Airoha EN8811H PHY firmware) +define Package/en8811h-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/airoha + $(CP) \ + $(PKG_BUILD_DIR)/airoha/*.bin \ + $(1)/lib/firmware/airoha +endef +$(eval $(call BuildPackage,en8811h-firmware)) diff --git a/package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.bin b/package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.bin old mode 100644 new mode 100755 diff --git a/package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.txt b/package/firmware/linux-firmware/brcm_firmware/ap6236/brcmfmac43430-sdio.txt old mode 100644 new mode 100755 diff --git a/package/firmware/linux-firmware/brcm_firmware/ap6356s/brcmfmac4356-sdio.rongpin,king3399.bin b/package/firmware/linux-firmware/brcm_firmware/ap6356s/brcmfmac4356-sdio.rongpin,king3399.bin deleted file mode 100644 index 63896b607c4450238190cefc8b17f98bc7d01ebb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 580258 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 lbz} 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�dQLkdL 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®T-+QFIL@Ox&od1Les#m{?$ZlKaF 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

>v<7#z9XWyf|&{9_ug_BD(rg$ta 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

    ^UEr43WpY!@B-hv^{> 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 literal 0 HcmV?d00001 diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c index 45a20f1c3..c9c4fc5d6 100644 --- a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c +++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c @@ -540,7 +540,7 @@ static int gpio_keys_button_probe(struct platform_device *pdev, #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) bdata->gpiod = devm_fwnode_gpiod_get(dev, - of_fwnode_handle(child), "gpios", GPIOD_IN, + of_fwnode_handle(child), NULL, GPIOD_IN, desc); #else bdata->gpiod = devm_gpiod_get_from_of_node(dev, diff --git a/package/kernel/linux/modules/block.mk b/package/kernel/linux/modules/block.mk index ff3a7df22..7773624a5 100644 --- a/package/kernel/linux/modules/block.mk +++ b/package/kernel/linux/modules/block.mk @@ -89,6 +89,18 @@ endef $(eval $(call KernelPackage,ata-artop)) +define KernelPackage/ata-ahci-dwc + TITLE:=Synopsys DWC AHCI SATA + KCONFIG:= \ + CONFIG_AHCI_DWC \ + CONFIG_SATA_HOST=y + FILES:=$(LINUX_DIR)/drivers/ata/ahci_dwc.ko + DEPENDS:=+kmod-ata-ahci-platform + AUTOLOAD:=$(call AutoLoad,41,ahci_dwc,1) + $(call AddDepends/ata,@TARGET_rockchip) +endef + +$(eval $(call KernelPackage,ata-ahci-dwc)) define KernelPackage/ata-nvidia-sata TITLE:=Nvidia Serial ATA support diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk index 9704bb7ee..d6412ffad 100644 --- a/package/kernel/linux/modules/video.mk +++ b/package/kernel/linux/modules/video.mk @@ -79,6 +79,7 @@ define KernelPackage/fb DEPENDS:=@DISPLAY_SUPPORT KCONFIG:= \ CONFIG_FB \ + CONFIG_FB_DEVICE=y \ CONFIG_FB_MXS=n \ CONFIG_FB_SM750=n \ CONFIG_FRAMEBUFFER_CONSOLE=y \ diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index a7472ee77..e2d4aeff5 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2007-2015 OpenWrt.org +# Copyright (C) 2007-2023 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.1.24 -PKG_RELEASE:=4 +PKG_RELEASE:=3 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648 @@ -180,7 +180,7 @@ endef define KernelPackage/rsi91x $(call KernelPackage/mac80211/Default) TITLE:=Redpine Signals Inc 91x WLAN driver support - DEPENDS+= +kmod-mac80211 +rs9113-firmware + DEPENDS+= +kmod-mac80211 +rs9113-firmware +@DRIVER_11N_SUPPORT FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko endef @@ -204,7 +204,7 @@ endef define KernelPackage/wlcore $(call KernelPackage/mac80211/Default) TITLE:=TI common driver part - DEPENDS+= +kmod-mmc +kmod-mac80211 + DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index c75630a8b..6f5d17cef 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -1,6 +1,7 @@ PKG_DRIVERS += \ - ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \ - ath11k ath11k-ahb ath11k-pci carl9170 owl-loader ar5523 wil6210 + ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc \ + ath10k ath10k-pci ath10k-sdio ath10k-smallbuffers ath11k ath11k-ahb \ + ath11k-pci ar5523 carl9170 owl-loader wil6210 PKG_CONFIG_DEPENDS += \ CONFIG_PACKAGE_ATH_DEBUG \ @@ -58,8 +59,11 @@ config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL config-$(CONFIG_ATH11K_THERMAL) += ATH11K_THERMAL config-$(call config_package,ath9k-htc) += ATH9K_HTC -config-$(call config_package,ath10k) += ATH10K ATH10K_PCI +config-$(call config_package,ath10k) += ATH10K +config-$(call config_package,ath10k-pci) += ATH10K_PCI +config-$(call config_package,ath10k-sdio) += ATH10K_SDIO config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS + config-$(call config_package,ath11k) += ATH11K config-$(call config_package,ath11k-ahb) += ATH11K_AHB config-$(call config_package,ath11k-pci) += ATH11K_PCI @@ -98,7 +102,7 @@ define KernelPackage/ath/config bool "Atheros wireless debugging" help Say Y, if you want to debug atheros wireless drivers. - Only ath9k & ath10k make use of this. + Only ath9k & ath10k & ath11k make use of this. config PACKAGE_ATH_DFS bool "Enable DFS support" @@ -161,7 +165,7 @@ define KernelPackage/ath6kl TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb) URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl HIDDEN:=1 - DEPENDS+= +kmod-ath + DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko endef @@ -262,20 +266,17 @@ define KernelPackage/ath10k $(call KernelPackage/mac80211/Default) TITLE:=Atheros 802.11ac wireless cards support URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k - DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11AC_SUPPORT \ + DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT \ +ATH10K_THERMAL:kmod-hwmon-core +ATH10K_THERMAL:kmod-thermal FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko - AUTOLOAD:=$(call AutoProbe,ath10k_core ath10k_pci) + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko + AUTOLOAD:=$(call AutoProbe,ath10k_core) MODPARAMS.ath10k_core:=frame_mode=2 - VARIANT:=regular endef define KernelPackage/ath10k/description This module adds support for wireless adapters based on -Atheros IEEE 802.11ac family of chipsets. For now only -PCI is supported. +Atheros IEEE 802.11ac family of chipsets. endef define KernelPackage/ath10k/config @@ -287,12 +288,42 @@ define KernelPackage/ath10k/config config ATH10K_THERMAL bool "Enable thermal sensors and throttling support" + default y depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers endef +define KernelPackage/ath10k-pci + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11ac PCIE wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k + DEPENDS+= @PCI_SUPPORT kmod-ath10k + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko + AUTOLOAD:=$(call AutoProbe,ath10k_pci) + VARIANT:=regular +endef + +define KernelPackage/ath10k-pci/description +This module adds support for wireless adapters based on +Atheros IEEE 802.11ac family of chipsets with PCIE bus. +endef + +define KernelPackage/ath10k-sdio + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11ac SDIO wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k + DEPENDS+= kmod-ath10k +kmod-mmc + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_sdio.ko + AUTOLOAD:=$(call AutoProbe,ath10k_sdio) +endef + +define KernelPackage/ath10k-sdio/description +This module adds support for wireless adapters based on +Atheros IEEE 802.11ac family of chipsets with SDIO bus. +endef + define KernelPackage/ath10k-smallbuffers - $(call KernelPackage/ath10k) + $(call KernelPackage/ath10k-pci) TITLE+= (small buffers for low-RAM devices) VARIANT:=smallbuffers endef @@ -305,6 +336,7 @@ define KernelPackage/ath11k +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko + MODPARAMS.ath11k:=frame_mode=2 endef define KernelPackage/ath11k/description diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk index cf80ad2d3..a36f92477 100644 --- a/package/kernel/mac80211/broadcom.mk +++ b/package/kernel/mac80211/broadcom.mk @@ -245,11 +245,11 @@ config PACKAGE_B43_USE_BCMA This allows choosing buses that b43 should support. config PACKAGE_B43_BUSES_BCMA_AND_SSB - depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx && !TARGET_bmips + depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx bool "BCMA and SSB" config PACKAGE_B43_BUSES_BCMA - depends on !TARGET_bcm47xx_legacy && !TARGET_bmips_bcm6358 && !TARGET_bmips_bcm6368 + depends on !TARGET_bcm47xx_legacy bool "BCMA only" config PACKAGE_B43_BUSES_SSB @@ -430,8 +430,9 @@ define KernelPackage/brcmfmac/config config BRCMFMAC_SDIO bool "Enable SDIO bus interface support" default y if TARGET_bcm27xx - default y if TARGET_imx_cortexa7 default y if TARGET_sunxi + default y if TARGET_rockchip + default y if TARGET_amlogic default n help Enable support for cards attached to an SDIO bus. diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 5aaba9af2..469d4264a 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -140,8 +140,8 @@ mac80211_hostapd_setup_base() { [ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && append base_cfg "acs_exclude_dfs=1" "$N" - json_get_vars noscan ht_coex min_tx_power:0 tx_burst - json_get_values ht_capab_list ht_capab + json_get_vars noscan ht_coex vendor_vht min_tx_power:0 + json_get_values ht_capab_list ht_capab tx_burst json_get_values channel_list channels [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ @@ -293,7 +293,7 @@ mac80211_hostapd_setup_base() { } [ "$hwmode" = "a" ] || enable_ac=0 - if [ "$enable_ac" != "0" ]; then + if [ "$enable_ac" != "0" -o "$vendor_vht" = "1" ]; then json_get_vars \ rxldpc:1 \ short_gi_80:1 \ @@ -581,77 +581,15 @@ mac80211_generate_mac() { $(( (0x$6 + $id) % 0x100 )) } -get_board_phy_name() ( - local path="$1" - local fallback_phy="" - - __check_phy() { - local val="$1" - local key="$2" - local ref_path="$3" - - json_select "$key" - json_get_values path - json_select .. - - [ "${ref_path%+*}" = "$path" ] && fallback_phy=$key - [ "$ref_path" = "$path" ] || return 0 - - echo "$key" - exit - } - - json_load_file /etc/board.json - json_for_each_item __check_phy wlan "$path" - [ -n "$fallback_phy" ] && echo "${fallback_phy}.${path##*+}" -) - -rename_board_phy_by_path() { - local path="$1" - - local new_phy="$(get_board_phy_name "$path")" - [ -z "$new_phy" -o "$new_phy" = "$phy" ] && return - - iw "$phy" set name "$new_phy" && phy="$new_phy" -} - -rename_board_phy_by_name() ( - local phy="$1" - local suffix="${phy##*.}" - [ "$suffix" = "$phy" ] && suffix= - - json_load_file /etc/board.json - json_select wlan - json_select "${phy%.*}" || return 0 - json_get_values path - - prev_phy="$(iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")" - [ -n "$prev_phy" ] || return 0 - - [ "$prev_phy" = "$phy" ] && return 0 - - iw "$prev_phy" set name "$phy" -) - find_phy() { - [ -n "$phy" ] && { - rename_board_phy_by_name "$phy" - [ -d /sys/class/ieee80211/$phy ] && return 0 - } + [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 [ -n "$path" ] && { phy="$(iwinfo nl80211 phyname "path=$path")" - [ -n "$phy" ] && { - rename_board_phy_by_path "$path" - return 0 - } + [ -n "$phy" ] && return 0 } [ -n "$macaddr" ] && { for phy in $(ls /sys/class/ieee80211 2>/dev/null); do - grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { - path="$(iwinfo nl80211 path "$phy")" - rename_board_phy_by_path "$path" - return 0 - } + grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0 done } return 1 @@ -729,28 +667,13 @@ mac80211_iw_interface_add() { return $rc } -mac80211_set_ifname() { - local phy="$1" - local prefix="$2" - eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" -} - mac80211_prepare_vif() { json_select config json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file - [ -n "$ifname" ] || { - local prefix; - - case "$mode" in - ap|sta|mesh) prefix=$mode;; - adhoc) prefix=ibss;; - monitor) prefix=mon;; - esac - - mac80211_set_ifname "$phy" "$prefix" - } + [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" + if_idx=$((${if_idx:-0} + 1)) set_default wds 0 set_default powersave 0 @@ -1033,7 +956,7 @@ mac80211_setup_vif() { mesh) wireless_vif_parse_encryption [ -z "$htmode" ] && htmode="NOHT"; - if wpa_supplicant -vmesh || [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then + if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then mac80211_setup_supplicant $vif_enable || failed=1 else mac80211_setup_mesh $vif_enable diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 7ed914b6a..4c5981850 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -2,48 +2,60 @@ append DRIVERS "mac80211" -check_mac80211_device() { - local device="$1" - local path="$2" - local macaddr="$3" - - [ -n "$found" ] && return 0 - - phy_path= - config_get phy "$device" phy - json_select wlan - [ -n "$phy" ] && case "$phy" in - phy*) - [ -d /sys/class/ieee80211/$phy ] && \ - phy_path="$(iwinfo nl80211 path "$dev")" - ;; - *) - if json_is_a "$phy" object; then - json_select "$phy" - json_get_var phy_path path - json_select .. - elif json_is_a "${phy%.*}" object; then - json_select "${phy%.*}" - json_get_var phy_path path - json_select .. - phy_path="$phy_path+${phy##*.}" - fi - ;; - esac - json_select .. - [ -n "$phy_path" ] || config_get phy_path "$device" path - [ -n "$path" -a "$phy_path" = "$path" ] && { - found=1 - return 0 +lookup_phy() { + [ -n "$phy" ] && { + [ -d /sys/class/ieee80211/$phy ] && return } - config_get dev_macaddr "$device" macaddr + local devpath + config_get devpath "$device" path + [ -n "$devpath" ] && { + phy="$(iwinfo nl80211 phyname "path=$devpath")" + [ -n "$phy" ] && return + } - [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 + local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')" + [ -n "$macaddr" ] && { + for _phy in /sys/class/ieee80211/*; do + [ -e "$_phy" ] || continue + + [ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue + phy="${_phy##*/}" + return + done + } + phy= + return +} + +find_mac80211_phy() { + local device="$1" + + config_get phy "$device" phy + lookup_phy + [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || { + echo "PHY for wifi device $1 not found" + return 1 + } + config_set "$device" phy "$phy" + + config_get macaddr "$device" macaddr + [ -z "$macaddr" ] && { + config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)" + } return 0 } +check_mac80211_device() { + config_get phy "$1" phy + [ -z "$phy" ] && { + find_mac80211_phy "$1" >/dev/null || return 0 + config_get phy "$1" phy + } + [ "$phy" = "$dev" ] && found=1 +} + __get_band_defaults() { local phy="$1" @@ -123,41 +135,24 @@ get_band_defaults() { done } -check_devidx() { - case "$1" in - radio[0-9]*) - local idx="${1#radio}" - [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) - ;; - esac -} - -check_board_phy() { - local name="$2" - - json_select "$name" - json_get_var phy_path path - json_select .. - - if [ "$path" = "$phy_path" ]; then - board_dev="$name" - elif [ "${path%+*}" = "$phy_path" ]; then - fallback_board_dev="$name.${path#*+}" - fi -} - detect_mac80211() { devidx=0 config_load wireless - config_foreach check_devidx wifi-device - - json_load_file /etc/board.json + while :; do + config_get type "radio$devidx" type + [ -n "$type" ] || break + devidx=$(($devidx + 1)) + done for _dev in /sys/class/ieee80211/*; do [ -e "$_dev" ] || continue dev="${_dev##*/}" + found=0 + config_foreach check_mac80211_device wifi-device + [ "$found" -gt 0 ] && continue + mode_band="" channel="" htmode="" @@ -166,53 +161,31 @@ detect_mac80211() { get_band_defaults "$dev" path="$(iwinfo nl80211 path "$dev")" - macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" - - # work around phy rename related race condition - [ -n "$path" -o -n "$macaddr" ] || continue - - board_dev= - fallback_board_dev= - json_for_each_item check_board_phy wlan - [ -n "$board_dev" ] || board_dev="$fallback_board_dev" - [ -n "$board_dev" ] && dev="$board_dev" - - found= - config_foreach check_mac80211_device wifi-device "$path" "$macaddr" - [ -n "$found" ] && continue - - name="radio${devidx}" - devidx=$(($devidx + 1)) - case "$dev" in - phy*) - if [ -n "$path" ]; then - dev_id="set wireless.${name}.path='$path'" - else - dev_id="set wireless.${name}.macaddr='$macaddr'" - fi - ;; - *) - dev_id="set wireless.${name}.phy='$dev'" - ;; - esac + if [ -n "$path" ]; then + dev_id="set wireless.radio${devidx}.path='$path'" + else + dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)" + fi uci -q batch <<-EOF - set wireless.${name}=wifi-device - set wireless.${name}.type=mac80211 + set wireless.radio${devidx}=wifi-device + set wireless.radio${devidx}.type=mac80211 ${dev_id} - set wireless.${name}.channel=${channel} - set wireless.${name}.band=${mode_band} - set wireless.${name}.htmode=$htmode - set wireless.${name}.disabled=0 - set wireless.${name}.country=US + set wireless.radio${devidx}.channel=${channel} + set wireless.radio${devidx}.band=${mode_band} + set wireless.radio${devidx}.htmode=$htmode + set wireless.radio${devidx}.disabled=0 + set wireless.radio${devidx}.country=US - set wireless.default_${name}=wifi-iface - set wireless.default_${name}.device=${name} - set wireless.default_${name}.network=lan - set wireless.default_${name}.mode=ap - set wireless.default_${name}.ssid=OpenWrt - set wireless.default_${name}.encryption=none + set wireless.default_radio${devidx}=wifi-iface + set wireless.default_radio${devidx}.device=radio${devidx} + set wireless.default_radio${devidx}.network=lan + set wireless.default_radio${devidx}.mode=ap + set wireless.default_radio${devidx}.ssid=OpenWrt + set wireless.default_radio${devidx}.encryption=none EOF uci -q commit wireless + + devidx=$(($devidx + 1)) done } diff --git a/package/kernel/mac80211/patches/ath10k/911-ath10k-disable-caldata-prefetch-for-sdio-bus.patch b/package/kernel/mac80211/patches/ath10k/911-ath10k-disable-caldata-prefetch-for-sdio-bus.patch new file mode 100644 index 000000000..8ca8f3b55 --- /dev/null +++ b/package/kernel/mac80211/patches/ath10k/911-ath10k-disable-caldata-prefetch-for-sdio-bus.patch @@ -0,0 +1,12 @@ +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -1260,6 +1260,9 @@ static int ath10k_debug_cal_data_fetch(s + if (ar->hw_params.cal_data_len == 0) + return -EOPNOTSUPP; + ++ if (ar->hif.bus == ATH10K_BUS_SDIO) ++ return -EINVAL; ++ + hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); + + ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr)); diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch index 7a38cf3e4..f5e702195 100644 --- a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch @@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -3516,6 +3516,16 @@ int ath10k_core_register(struct ath10k * +@@ -3516,6 +3516,17 @@ int ath10k_core_register(struct ath10k * queue_work(ar->workqueue, &ar->register_work); @@ -26,7 +26,8 @@ Signed-off-by: Sven Eckelmann + * Forcing the work to be done immediately works around this problem + * but may also delay the boot when firmware images cannot be found. + */ -+ flush_workqueue(ar->workqueue); ++ if (ar->hif.bus != ATH10K_BUS_SDIO) ++ flush_workqueue(ar->workqueue); + return 0; } diff --git a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch index 1c1630c05..fd5b44811 100644 --- a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -202,7 +202,7 @@ v13: err_spectral_destroy: ath10k_spectral_destroy(ar); err_debug_destroy: -@@ -3537,6 +3556,8 @@ void ath10k_core_unregister(struct ath10 +@@ -3538,6 +3557,8 @@ void ath10k_core_unregister(struct ath10 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; diff --git a/package/kernel/mac80211/patches/ath10k/985-ath10k-allow-vht-on-2g.patch b/package/kernel/mac80211/patches/ath10k/985-ath10k-allow-vht-on-2g.patch new file mode 100644 index 000000000..3fb26bff9 --- /dev/null +++ b/package/kernel/mac80211/patches/ath10k/985-ath10k-allow-vht-on-2g.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -5034,6 +5034,7 @@ static void ath10k_mac_setup_ht_vht_cap( + if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) { + band = &ar->mac.sbands[NL80211_BAND_2GHZ]; + band->ht_cap = ht_cap; ++ band->vht_cap = vht_cap; + } + if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) { + band = &ar->mac.sbands[NL80211_BAND_5GHZ]; diff --git a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch new file mode 100644 index 000000000..f4b1ded15 --- /dev/null +++ b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch @@ -0,0 +1,28 @@ +From f7d6edafe4358e3880a26775cfde4cd5c71ba063 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Wed, 5 Jul 2023 01:30:29 +0200 +Subject: [PATCH] ath10k: always use mac80211 loss detection + +ath10k does not report excessive loss in case of broken block-ack +sessions. The loss is communicated to the host-os, but ath10k does not +trigger a low-ack events by itself. + +The mac80211 framework for loss detection however detects this +circumstance well in case of ath10k. So use it regardless of ath10k's +own loss detection mechanism. + +Signed-off-by: David Bauer +--- + drivers/net/wireless/ath/ath10k/mac.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -10081,7 +10081,6 @@ int ath10k_mac_register(struct ath10k *a + ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); + ieee80211_hw_set(ar->hw, QUEUE_CONTROL); + ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); +- ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); + + if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) + ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL); diff --git a/package/kernel/mac80211/patches/ath11k/0085-wifi-ath11k-fix-memory-leak-in-WMI-firmware-stats.patch b/package/kernel/mac80211/patches/ath11k/0085-wifi-ath11k-fix-memory-leak-in-WMI-firmware-stats.patch new file mode 100644 index 000000000..dde30b962 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0085-wifi-ath11k-fix-memory-leak-in-WMI-firmware-stats.patch @@ -0,0 +1,51 @@ +From 6aafa1c2d3e3fea2ebe84c018003f2a91722e607 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Tue, 6 Jun 2023 14:41:28 +0530 +Subject: [PATCH] wifi: ath11k: fix memory leak in WMI firmware stats + +Memory allocated for firmware pdev, vdev and beacon statistics +are not released during rmmod. + +Fix it by calling ath11k_fw_stats_free() function before hardware +unregister. + +While at it, avoid calling ath11k_fw_stats_free() while processing +the firmware stats received in the WMI event because the local list +is getting spliced and reinitialised and hence there are no elements +in the list after splicing. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: P Praneesh +Signed-off-by: Aditya Kumar Singh +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230606091128.14202-1-quic_adisi@quicinc.com +--- + drivers/net/wireless/ath/ath11k/mac.c | 1 + + drivers/net/wireless/ath/ath11k/wmi.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9792,6 +9792,7 @@ void ath11k_mac_destroy(struct ath11k_ba + if (!ar) + continue; + ++ ath11k_fw_stats_free(&ar->fw_stats); + ieee80211_free_hw(ar->hw); + pdev->ar = NULL; + } +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -8119,6 +8119,11 @@ complete: + rcu_read_unlock(); + spin_unlock_bh(&ar->data_lock); + ++ /* Since the stats's pdev, vdev and beacon list are spliced and reinitialised ++ * at this point, no need to free the individual list. ++ */ ++ return; ++ + free: + ath11k_fw_stats_free(&stats); + } diff --git a/package/kernel/mac80211/patches/ath11k/0086-wifi-ath11k-Add-missing-check-for-ioremap.patch b/package/kernel/mac80211/patches/ath11k/0086-wifi-ath11k-Add-missing-check-for-ioremap.patch new file mode 100644 index 000000000..e536c3bd6 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0086-wifi-ath11k-Add-missing-check-for-ioremap.patch @@ -0,0 +1,38 @@ +From 16e0077e14a73866e9b0f4a6bf4ad3d4a5cb0f2a Mon Sep 17 00:00:00 2001 +From: Jiasheng Jiang +Date: Tue, 13 Jun 2023 12:19:40 +0300 +Subject: [PATCH] wifi: ath11k: Add missing check for ioremap + +Add check for ioremap() and return the error if it fails in order to +guarantee the success of ioremap(), same as in +ath11k_qmi_load_file_target_mem(). + +Fixes: 6ac04bdc5edb ("ath11k: Use reserved host DDR addresses from DT for PCI devices") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230608022858.27405-1-jiasheng@iscas.ac.cn +--- + drivers/net/wireless/ath/ath11k/qmi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2061,6 +2061,9 @@ static int ath11k_qmi_assign_target_mem_ + ab->qmi.target_mem[idx].iaddr = + ioremap(ab->qmi.target_mem[idx].paddr, + ab->qmi.target_mem[i].size); ++ if (!ab->qmi.target_mem[idx].iaddr) ++ return -EIO; ++ + ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; + host_ddr_sz = ab->qmi.target_mem[i].size; + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; +@@ -2086,6 +2089,8 @@ static int ath11k_qmi_assign_target_mem_ + ab->qmi.target_mem[idx].iaddr = + ioremap(ab->qmi.target_mem[idx].paddr, + ab->qmi.target_mem[i].size); ++ if (!ab->qmi.target_mem[idx].iaddr) ++ return -EIO; + } else { + ab->qmi.target_mem[idx].paddr = + ATH11K_QMI_CALDB_ADDRESS; diff --git a/package/kernel/mac80211/patches/ath11k/0087-wifi-ath11k-Add-missing-ops-config-for-IPQ5018-in.patch b/package/kernel/mac80211/patches/ath11k/0087-wifi-ath11k-Add-missing-ops-config-for-IPQ5018-in.patch new file mode 100644 index 000000000..fa539ef45 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0087-wifi-ath11k-Add-missing-ops-config-for-IPQ5018-in.patch @@ -0,0 +1,30 @@ +From 469ddb20cae61cad9c4f208a4c8682305905a511 Mon Sep 17 00:00:00 2001 +From: Ziyang Huang +Date: Thu, 15 Jun 2023 14:41:47 +0300 +Subject: [PATCH] wifi: ath11k: Add missing ops config for IPQ5018 in + ath11k_ahb_probe() + +Without this patch, the IPQ5018 WiFi will fail and print the following +logs: + + [ 11.033179] ath11k c000000.wifi: unsupported device type 7 + [ 11.033223] ath11k: probe of c000000.wifi failed with error -95 + +Fixes: 25edca7bb18a ("wifi: ath11k: add ipq5018 device support") +Signed-off-by: Ziyang Huang +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYZPR01MB5556D7AA10ABEDDDD2D8F39EC953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com +--- + drivers/net/wireless/ath/ath11k/ahb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -1127,6 +1127,7 @@ static int ath11k_ahb_probe(struct platf + switch (hw_rev) { + case ATH11K_HW_IPQ8074: + case ATH11K_HW_IPQ6018_HW10: ++ case ATH11K_HW_IPQ5018_HW10: + hif_ops = &ath11k_ahb_hif_ops_ipq8074; + pci_ops = NULL; + break; diff --git a/package/kernel/mac80211/patches/ath11k/0088-wifi-ath11k-Restart-firmware-after-cold-boot-calibration.patch b/package/kernel/mac80211/patches/ath11k/0088-wifi-ath11k-Restart-firmware-after-cold-boot-calibration.patch new file mode 100644 index 000000000..4a9385218 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0088-wifi-ath11k-Restart-firmware-after-cold-boot-calibration.patch @@ -0,0 +1,47 @@ +From 80c5390e1f5e5b16d820512265530ef26073d8e0 Mon Sep 17 00:00:00 2001 +From: Ziyang Huang +Date: Thu, 15 Jun 2023 14:41:48 +0300 +Subject: [PATCH] wifi: ath11k: Restart firmware after cold boot calibration + for IPQ5018 + +Restart is required after cold boot calibration on IPQ5018. Otherwise, +we get the following exception: + + [ 14.412829] qcom-q6-mpd cd00000.remoteproc: fatal error received: err_smem_ver.2.1: + [ 14.412829] QC Image Version : QC_IMAGE_VERSION_STRING=WLAN.HK.2.6.0.1-00974-QCAHKSWPL_SILICONZ-1 + [ 14.412829] Image Variant : IMAGE_VARIANT_STRING=5018.wlanfw2.map_spr_spr_evalQ + [ 14.412829] DALSysLogEvent.c:174 Assertion 0 failed param0 :zero,param1 :zero,param2 :zero + [ 14.412829] Thread ID : 0x00000048 Thread name : WLAN RT0 Process ID : 0x00000001 Process name :wlan0 + [ 14.412829] + [ 14.412829] Registers: + [ 14.412829] SP : 0x4c81c120 + [ 14.412829] FP : 0x4c81c138 + [ 14.412829] PC : 0xb022c590 + [ 14.412829] SSR : 0x00000000 + [ 14.412829] BADVA : 0x00000000 + [ 14.412829] LR : 0xb0008490 + [ 14.412829] + [ 14.412829] StackDump + [ 14.412829] from:0x4c81c120 + [ 14.412829] to: 0x00000000: + [ 14.412829] + [ 14.463006] remoteproc remoteproc0: crash detected in cd00000.remoteproc: type fatal error + +Fixes: 8dfe875aa24a ("wifi: ath11k: update hw params for IPQ5018") +Signed-off-by: Ziyang Huang +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYZPR01MB55566969818BD4B49E770445C953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com +--- + drivers/net/wireless/ath/ath11k/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -668,6 +668,7 @@ static const struct ath11k_hw_params ath + .hal_params = &ath11k_hw_hal_params_ipq8074, + .single_pdev_only = false, + .cold_boot_calib = true, ++ .cbcal_restart_fw = true, + .fix_l1ss = true, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = true, diff --git a/package/kernel/mac80211/patches/ath11k/0089-wifi-ath11k-Add-missing-hw_ops-get_ring_selector-for.patch b/package/kernel/mac80211/patches/ath11k/0089-wifi-ath11k-Add-missing-hw_ops-get_ring_selector-for.patch new file mode 100644 index 000000000..cb6667f14 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0089-wifi-ath11k-Add-missing-hw_ops-get_ring_selector-for.patch @@ -0,0 +1,58 @@ +From ce282d8de71f07f0056ea319541141152c65f552 Mon Sep 17 00:00:00 2001 +From: Ziyang Huang +Date: Thu, 15 Jun 2023 14:41:48 +0300 +Subject: [PATCH] wifi: ath11k: Add missing hw_ops->get_ring_selector() for + IPQ5018 + +During sending data after clients connected, hw_ops->get_ring_selector() +will be called. But for IPQ5018, this member isn't set, and the +following NULL pointer exception will be occurred: + + [ 38.840478] 8<--- cut here --- + [ 38.840517] Unable to handle kernel NULL pointer dereference at virtual address 00000000 + ... + [ 38.923161] PC is at 0x0 + [ 38.927930] LR is at ath11k_dp_tx+0x70/0x730 [ath11k] + ... + [ 39.063264] Process hostapd (pid: 1034, stack limit = 0x801ceb3d) + [ 39.068994] Stack: (0x856a9a68 to 0x856aa000) + ... + [ 39.438467] [<7f323804>] (ath11k_dp_tx [ath11k]) from [<7f314e6c>] (ath11k_mac_op_tx+0x80/0x190 [ath11k]) + [ 39.446607] [<7f314e6c>] (ath11k_mac_op_tx [ath11k]) from [<7f17dbe0>] (ieee80211_handle_wake_tx_queue+0x7c/0xc0 [mac80211]) + [ 39.456162] [<7f17dbe0>] (ieee80211_handle_wake_tx_queue [mac80211]) from [<7f174450>] (ieee80211_probereq_get+0x584/0x704 [mac80211]) + [ 39.467443] [<7f174450>] (ieee80211_probereq_get [mac80211]) from [<7f178c40>] (ieee80211_tx_prepare_skb+0x1f8/0x248 [mac80211]) + [ 39.479334] [<7f178c40>] (ieee80211_tx_prepare_skb [mac80211]) from [<7f179e28>] (__ieee80211_subif_start_xmit+0x32c/0x3d4 [mac80211]) + [ 39.491053] [<7f179e28>] (__ieee80211_subif_start_xmit [mac80211]) from [<7f17af08>] (ieee80211_tx_control_port+0x19c/0x288 [mac80211]) + [ 39.502946] [<7f17af08>] (ieee80211_tx_control_port [mac80211]) from [<7f0fc704>] (nl80211_tx_control_port+0x174/0x1d4 [cfg80211]) + [ 39.515017] [<7f0fc704>] (nl80211_tx_control_port [cfg80211]) from [<808ceac4>] (genl_rcv_msg+0x154/0x340) + [ 39.526814] [<808ceac4>] (genl_rcv_msg) from [<808cdb74>] (netlink_rcv_skb+0xb8/0x11c) + [ 39.536446] [<808cdb74>] (netlink_rcv_skb) from [<808ce1d0>] (genl_rcv+0x28/0x34) + [ 39.544344] [<808ce1d0>] (genl_rcv) from [<808cd234>] (netlink_unicast+0x174/0x274) + [ 39.551895] [<808cd234>] (netlink_unicast) from [<808cd510>] (netlink_sendmsg+0x1dc/0x440) + [ 39.559362] [<808cd510>] (netlink_sendmsg) from [<808596e0>] (____sys_sendmsg+0x1a8/0x1fc) + [ 39.567697] [<808596e0>] (____sys_sendmsg) from [<8085b1a8>] (___sys_sendmsg+0xa4/0xdc) + [ 39.575941] [<8085b1a8>] (___sys_sendmsg) from [<8085b310>] (sys_sendmsg+0x44/0x74) + [ 39.583841] [<8085b310>] (sys_sendmsg) from [<80300060>] (ret_fast_syscall+0x0/0x40) + ... + [ 39.620734] Code: bad PC value + [ 39.625869] ---[ end trace 8aef983ad3cbc032 ]--- + +Fixes: ba60f2793d3a ("wifi: ath11k: initialize hw_ops for IPQ5018") +Signed-off-by: Ziyang Huang +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/TYZPR01MB5556D6E3F63EAB5129D11420C953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com +--- + drivers/net/wireless/ath/ath11k/hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -1178,7 +1178,7 @@ const struct ath11k_hw_ops ipq5018_ops = + .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, + .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, +- ++ .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + }; + + #define ATH11K_TX_RING_MASK_0 BIT(0) diff --git a/package/kernel/mac80211/patches/ath11k/0090-Revert-wifi-ath11k-Enable-threaded-NAPI.patch b/package/kernel/mac80211/patches/ath11k/0090-Revert-wifi-ath11k-Enable-threaded-NAPI.patch new file mode 100644 index 000000000..313c18c55 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0090-Revert-wifi-ath11k-Enable-threaded-NAPI.patch @@ -0,0 +1,44 @@ +From d265ebe41c911314bd273c218a37088835959fa1 Mon Sep 17 00:00:00 2001 +From: Kalle Valo +Date: Thu, 20 Jul 2023 18:14:44 +0300 +Subject: [PATCH] Revert "wifi: ath11k: Enable threaded NAPI" + +This reverts commit 13aa2fb692d3717767303817f35b3e650109add3. + +This commit broke QCN9074 initialisation: + +[ 358.960477] ath11k_pci 0000:04:00.0: ce desc not available for wmi command 36866 +[ 358.960481] ath11k_pci 0000:04:00.0: failed to send WMI_STA_POWERSAVE_PARAM_CMDID +[ 358.960484] ath11k_pci 0000:04:00.0: could not set uapsd params -105 + +As there's no fix available let's just revert it to get QCN9074 working again. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217536 +Signed-off-by: Kalle Valo +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230720151444.2016637-1-kvalo@kernel.org +--- + drivers/net/wireless/ath/ath11k/ahb.c | 1 - + drivers/net/wireless/ath/ath11k/pcic.c | 1 - + 2 files changed, 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -376,7 +376,6 @@ static void ath11k_ahb_ext_irq_enable(st + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + if (!irq_grp->napi_enabled) { +- dev_set_threaded(&irq_grp->napi_ndev, true); + napi_enable(&irq_grp->napi); + irq_grp->napi_enabled = true; + } +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -466,7 +466,6 @@ void ath11k_pcic_ext_irq_enable(struct a + struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + + if (!irq_grp->napi_enabled) { +- dev_set_threaded(&irq_grp->napi_ndev, true); + napi_enable(&irq_grp->napi); + irq_grp->napi_enabled = true; + } diff --git a/package/kernel/mac80211/patches/ath11k/0091-wifi-ath11k-Split-coldboot-calibration-hw_param.patch b/package/kernel/mac80211/patches/ath11k/0091-wifi-ath11k-Split-coldboot-calibration-hw_param.patch new file mode 100644 index 000000000..470535468 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0091-wifi-ath11k-Split-coldboot-calibration-hw_param.patch @@ -0,0 +1,180 @@ +From 011e5a3052a22d3758d17442bf0c04c68bf79bea Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Wed, 26 Jul 2023 19:40:30 +0530 +Subject: [PATCH 3/5] wifi: ath11k: Split coldboot calibration hw_param + +QCN9074 enables coldboot calibration only in Factory Test Mode (FTM). +Hence, split cold_boot_calib to two hw_params for mission and FTM +mode. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Raj Kumar Bhagat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230726141032.3061-2-quic_rajkbhag@quicinc.com +--- + drivers/net/wireless/ath/ath11k/ahb.c | 3 +-- + drivers/net/wireless/ath/ath11k/core.c | 36 ++++++++++++++++++++------ + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/hw.h | 3 ++- + drivers/net/wireless/ath/ath11k/qmi.c | 6 ++--- + 5 files changed, 35 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -422,8 +422,7 @@ static int ath11k_ahb_fwreset_from_cold_ + { + int timeout; + +- if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done || +- ab->hw_params.cold_boot_calib == 0 || ++ if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done || + ab->hw_params.cbcal_restart_fw == 0) + return 0; + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -86,7 +86,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = false, + .idle_ps = false, + .supports_sta_ps = false, +- .cold_boot_calib = true, ++ .coldboot_cal_mm = true, ++ .coldboot_cal_ftm = true, + .cbcal_restart_fw = true, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -167,7 +168,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = false, + .idle_ps = false, + .supports_sta_ps = false, +- .cold_boot_calib = true, ++ .coldboot_cal_mm = true, ++ .coldboot_cal_ftm = true, + .cbcal_restart_fw = true, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -248,7 +250,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, +- .cold_boot_calib = false, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -332,7 +335,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = false, + .idle_ps = false, + .supports_sta_ps = false, +- .cold_boot_calib = false, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 2, + .num_vdevs = 8, +@@ -413,7 +417,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, +- .cold_boot_calib = false, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -495,7 +500,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, +- .cold_boot_calib = false, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -578,7 +584,8 @@ static const struct ath11k_hw_params ath + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, +- .cold_boot_calib = true, ++ .coldboot_cal_mm = true, ++ .coldboot_cal_ftm = true, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, +@@ -667,7 +674,8 @@ static const struct ath11k_hw_params ath + .supports_suspend = false, + .hal_params = &ath11k_hw_hal_params_ipq8074, + .single_pdev_only = false, +- .cold_boot_calib = true, ++ .coldboot_cal_mm = true, ++ .coldboot_cal_ftm = true, + .cbcal_restart_fw = true, + .fix_l1ss = true, + .supports_dynamic_smps_6ghz = false, +@@ -749,6 +757,18 @@ void ath11k_fw_stats_free(struct ath11k_ + ath11k_fw_stats_bcn_free(&stats->bcn); + } + ++bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab) ++{ ++ if (!ath11k_cold_boot_cal) ++ return false; ++ ++ if (ath11k_ftm_mode) ++ return ab->hw_params.coldboot_cal_ftm; ++ ++ else ++ return ab->hw_params.coldboot_cal_mm; ++} ++ + int ath11k_core_suspend(struct ath11k_base *ab) + { + int ret; +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -1186,6 +1186,7 @@ void ath11k_core_halt(struct ath11k *ar) + int ath11k_core_resume(struct ath11k_base *ab); + int ath11k_core_suspend(struct ath11k_base *ab); + void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab); ++bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab); + + const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, + const char *filename); +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -187,7 +187,8 @@ struct ath11k_hw_params { + bool supports_shadow_regs; + bool idle_ps; + bool supports_sta_ps; +- bool cold_boot_calib; ++ bool coldboot_cal_mm; ++ bool coldboot_cal_ftm; + bool cbcal_restart_fw; + int fw_mem_mode; + u32 num_vdevs; +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2082,7 +2082,7 @@ static int ath11k_qmi_assign_target_mem_ + return -EINVAL; + } + +- if (ath11k_cold_boot_cal && ab->hw_params.cold_boot_calib) { ++ if (ath11k_core_coldboot_cal_support(ab)) { + if (hremote_node) { + ab->qmi.target_mem[idx].paddr = + res.start + host_ddr_sz; +@@ -3212,8 +3212,8 @@ static void ath11k_qmi_driver_event_work + break; + } + +- if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 && +- ab->hw_params.cold_boot_calib) { ++ if (ab->qmi.cal_done == 0 && ++ ath11k_core_coldboot_cal_support(ab)) { + ath11k_qmi_process_coldboot_calibration(ab); + } else { + clear_bit(ATH11K_FLAG_CRASH_FLUSH, diff --git a/package/kernel/mac80211/patches/ath11k/0092-wifi-ath11k-Add-coldboot-calibration-support-for-QCN.patch b/package/kernel/mac80211/patches/ath11k/0092-wifi-ath11k-Add-coldboot-calibration-support-for-QCN.patch new file mode 100644 index 000000000..31b11ddee --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0092-wifi-ath11k-Add-coldboot-calibration-support-for-QCN.patch @@ -0,0 +1,176 @@ +From bdfc967bf5fcd762473a01d39edb81f1165ba290 Mon Sep 17 00:00:00 2001 +From: Anilkumar Kolli +Date: Wed, 26 Jul 2023 19:40:31 +0530 +Subject: [PATCH 4/5] wifi: ath11k: Add coldboot calibration support for + QCN9074 + +QCN9074 supports 6 GHz, which has increased number of channels +compared to 5 GHz/2 GHz. So, to support coldboot calibration in +QCN9074 ATH11K_COLD_BOOT_FW_RESET_DELAY extended to 60 seconds. To +avoid code redundancy, fwreset_from_cold_boot moved to QMI and made +common for both ahb and pci. Coldboot calibration is enabled only in +FTM mode for QCN9074. QCN9074 requires firmware restart after coldboot, +hence enable cbcal_restart_fw in hw_params. + +This support can be enabled/disabled using hw params for different +hardware. Currently it is not enabled for QCA6390. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Anilkumar Kolli +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Raj Kumar Bhagat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230726141032.3061-3-quic_rajkbhag@quicinc.com +--- + drivers/net/wireless/ath/ath11k/ahb.c | 28 ++------------------------ + drivers/net/wireless/ath/ath11k/core.c | 4 ++-- + drivers/net/wireless/ath/ath11k/pci.c | 2 ++ + drivers/net/wireless/ath/ath11k/qmi.c | 28 ++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/qmi.h | 3 ++- + 5 files changed, 36 insertions(+), 29 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -14,6 +14,7 @@ + #include "ahb.h" + #include "debug.h" + #include "hif.h" ++#include "qmi.h" + #include + #include "pcic.h" + #include +@@ -418,31 +419,6 @@ static void ath11k_ahb_power_down(struct + rproc_shutdown(ab_ahb->tgt_rproc); + } + +-static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab) +-{ +- int timeout; +- +- if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done || +- ab->hw_params.cbcal_restart_fw == 0) +- return 0; +- +- ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n"); +- timeout = wait_event_timeout(ab->qmi.cold_boot_waitq, +- (ab->qmi.cal_done == 1), +- ATH11K_COLD_BOOT_FW_RESET_DELAY); +- if (timeout <= 0) { +- ath11k_cold_boot_cal = 0; +- ath11k_warn(ab, "Coldboot Calibration failed timed out\n"); +- } +- +- /* reset the firmware */ +- ath11k_ahb_power_down(ab); +- ath11k_ahb_power_up(ab); +- +- ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n"); +- return 0; +-} +- + static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab) + { + struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; +@@ -1225,7 +1201,7 @@ static int ath11k_ahb_probe(struct platf + goto err_ce_free; + } + +- ath11k_ahb_fwreset_from_cold_boot(ab); ++ ath11k_qmi_fwreset_from_cold_boot(ab); + + return 0; + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -336,8 +336,8 @@ static const struct ath11k_hw_params ath + .idle_ps = false, + .supports_sta_ps = false, + .coldboot_cal_mm = false, +- .coldboot_cal_ftm = false, +- .cbcal_restart_fw = false, ++ .coldboot_cal_ftm = true, ++ .cbcal_restart_fw = true, + .fw_mem_mode = 2, + .num_vdevs = 8, + .num_peers = 128, +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -15,6 +15,7 @@ + #include "mhi.h" + #include "debug.h" + #include "pcic.h" ++#include "qmi.h" + + #define ATH11K_PCI_BAR_NUM 0 + #define ATH11K_PCI_DMA_MASK 32 +@@ -897,6 +898,7 @@ unsupported_wcn6855_soc: + ath11k_err(ab, "failed to init core: %d\n", ret); + goto err_irq_affinity_cleanup; + } ++ ath11k_qmi_fwreset_from_cold_boot(ab); + return 0; + + err_irq_affinity_cleanup: +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -9,6 +9,7 @@ + #include "qmi.h" + #include "core.h" + #include "debug.h" ++#include "hif.h" + #include + #include + #include +@@ -2842,6 +2843,33 @@ int ath11k_qmi_firmware_start(struct ath + return 0; + } + ++int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab) ++{ ++ int timeout; ++ ++ if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done || ++ ab->hw_params.cbcal_restart_fw == 0) ++ return 0; ++ ++ ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n"); ++ ++ timeout = wait_event_timeout(ab->qmi.cold_boot_waitq, ++ (ab->qmi.cal_done == 1), ++ ATH11K_COLD_BOOT_FW_RESET_DELAY); ++ ++ if (timeout <= 0) { ++ ath11k_warn(ab, "Coldboot Calibration timed out\n"); ++ return -ETIMEDOUT; ++ } ++ ++ /* reset the firmware */ ++ ath11k_hif_power_down(ab); ++ ath11k_hif_power_up(ab); ++ ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n"); ++ return 0; ++} ++EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot); ++ + static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab) + { + int timeout; +--- a/drivers/net/wireless/ath/ath11k/qmi.h ++++ b/drivers/net/wireless/ath/ath11k/qmi.h +@@ -37,7 +37,7 @@ + + #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144 + #define ATH11K_FIRMWARE_MODE_OFF 4 +-#define ATH11K_COLD_BOOT_FW_RESET_DELAY (40 * HZ) ++#define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ) + + #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 + +@@ -519,5 +519,6 @@ void ath11k_qmi_msg_recv_work(struct wor + void ath11k_qmi_deinit_service(struct ath11k_base *ab); + int ath11k_qmi_init_service(struct ath11k_base *ab); + void ath11k_qmi_free_resource(struct ath11k_base *ab); ++int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab); + + #endif diff --git a/package/kernel/mac80211/patches/ath11k/0093-wifi-ath11k-Remove-cal_done-check-during-probe.patch b/package/kernel/mac80211/patches/ath11k/0093-wifi-ath11k-Remove-cal_done-check-during-probe.patch new file mode 100644 index 000000000..513ea3f0b --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0093-wifi-ath11k-Remove-cal_done-check-during-probe.patch @@ -0,0 +1,33 @@ +From 13329d0cb7212b058bd8451a99d215a8f97645ea Mon Sep 17 00:00:00 2001 +From: Seevalamuthu Mariappan +Date: Wed, 26 Jul 2023 19:40:32 +0530 +Subject: [PATCH] wifi: ath11k: Remove cal_done check during probe + +In some race conditions, calibration done QMI message is received even +before host wait starts for calibration to be done. +Due to this, resetting firmware was not performed after calibration. + +Hence, remove cal_done check in ath11k_qmi_fwreset_from_cold_boot() +as this is called only from probe. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Seevalamuthu Mariappan +Signed-off-by: Raj Kumar Bhagat +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230726141032.3061-4-quic_rajkbhag@quicinc.com +--- + drivers/net/wireless/ath/ath11k/qmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2847,7 +2847,7 @@ int ath11k_qmi_fwreset_from_cold_boot(st + { + int timeout; + +- if (!ath11k_core_coldboot_cal_support(ab) || ab->qmi.cal_done || ++ if (!ath11k_core_coldboot_cal_support(ab) || + ab->hw_params.cbcal_restart_fw == 0) + return 0; + diff --git a/package/kernel/mac80211/patches/ath11k/0094-wifi-ath11k-mhi-add-a-warning-message-for-MHI_CB_EE.patch b/package/kernel/mac80211/patches/ath11k/0094-wifi-ath11k-mhi-add-a-warning-message-for-MHI_CB_EE.patch new file mode 100644 index 000000000..e1286c953 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0094-wifi-ath11k-mhi-add-a-warning-message-for-MHI_CB_EE.patch @@ -0,0 +1,34 @@ +From 4a93b554cf9fa64faa7cf164c0d32fc3ce67108b Mon Sep 17 00:00:00 2001 +From: Arowa Suliman +Date: Sat, 26 Aug 2023 08:42:42 +0300 +Subject: [PATCH] wifi: ath11k: mhi: add a warning message for MHI_CB_EE_RDDM + crash + +Currently, the ath11k driver does not print a crash signature when a +MHI_CB_EE_RDDM crash happens. Checked by triggering a simulated crash using the +command and checking dmesg for logs: + +echo assert > /sys/kernel/debug/ath11k/../simulate_fw_crash + +Add a warning when firmware crash MHI_CB_EE_RDDM happens. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 + +Signed-off-by: Arowa Suliman +Reviewed-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230714001126.463127-1-arowa@chromium.org +--- + drivers/net/wireless/ath/ath11k/mhi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath11k/mhi.c ++++ b/drivers/net/wireless/ath/ath11k/mhi.c +@@ -333,6 +333,7 @@ static void ath11k_mhi_op_status_cb(stru + ath11k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n"); + break; + case MHI_CB_EE_RDDM: ++ ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n"); + if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) + queue_work(ab->workqueue_aux, &ab->reset_work); + break; diff --git a/package/kernel/mac80211/patches/ath11k/0095-wifi-ath11k-add-chip-id-board-name-while-searching-b.patch b/package/kernel/mac80211/patches/ath11k/0095-wifi-ath11k-add-chip-id-board-name-while-searching-b.patch new file mode 100644 index 000000000..662e28f4e --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0095-wifi-ath11k-add-chip-id-board-name-while-searching-b.patch @@ -0,0 +1,214 @@ +From 1133af5aea588a58043244a4ecb5ce511b310356 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Wed, 30 Aug 2023 02:02:26 -0400 +Subject: [PATCH] wifi: ath11k: add chip id board name while searching + board-2.bin for WCN6855 + +Sometimes board-2.bin does not have the board data which matched the +parameters such as bus type, vendor, device, subsystem-vendor, +subsystem-device, qmi-chip-id and qmi-board-id, then wlan will load fail. + +Hence add another type which only matches the bus type and qmi-chip-id, +then the ratio of missing board data reduced. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 + +Signed-off-by: Wen Gong +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230830060226.18664-1-quic_wgong@quicinc.com +--- + drivers/net/wireless/ath/ath11k/core.c | 108 ++++++++++++++++++++----- + 1 file changed, 87 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -985,9 +985,15 @@ int ath11k_core_check_dt(struct ath11k_b + return 0; + } + ++enum ath11k_bdf_name_type { ++ ATH11K_BDF_NAME_FULL, ++ ATH11K_BDF_NAME_BUS_NAME, ++ ATH11K_BDF_NAME_CHIP_ID, ++}; ++ + static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name, + size_t name_len, bool with_variant, +- bool bus_type_mode) ++ enum ath11k_bdf_name_type name_type) + { + /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ + char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 }; +@@ -998,11 +1004,8 @@ static int __ath11k_core_create_board_na + + switch (ab->id.bdf_search) { + case ATH11K_BDF_SEARCH_BUS_AND_BOARD: +- if (bus_type_mode) +- scnprintf(name, name_len, +- "bus=%s", +- ath11k_bus_str(ab->hif.bus)); +- else ++ switch (name_type) { ++ case ATH11K_BDF_NAME_FULL: + scnprintf(name, name_len, + "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", + ath11k_bus_str(ab->hif.bus), +@@ -1012,6 +1015,19 @@ static int __ath11k_core_create_board_na + ab->qmi.target.chip_id, + ab->qmi.target.board_id, + variant); ++ break; ++ case ATH11K_BDF_NAME_BUS_NAME: ++ scnprintf(name, name_len, ++ "bus=%s", ++ ath11k_bus_str(ab->hif.bus)); ++ break; ++ case ATH11K_BDF_NAME_CHIP_ID: ++ scnprintf(name, name_len, ++ "bus=%s,qmi-chip-id=%d", ++ ath11k_bus_str(ab->hif.bus), ++ ab->qmi.target.chip_id); ++ break; ++ } + break; + default: + scnprintf(name, name_len, +@@ -1030,19 +1046,29 @@ static int __ath11k_core_create_board_na + static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, + size_t name_len) + { +- return __ath11k_core_create_board_name(ab, name, name_len, true, false); ++ return __ath11k_core_create_board_name(ab, name, name_len, true, ++ ATH11K_BDF_NAME_FULL); + } + + static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name, + size_t name_len) + { +- return __ath11k_core_create_board_name(ab, name, name_len, false, false); ++ return __ath11k_core_create_board_name(ab, name, name_len, false, ++ ATH11K_BDF_NAME_FULL); + } + + static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name, + size_t name_len) + { +- return __ath11k_core_create_board_name(ab, name, name_len, false, true); ++ return __ath11k_core_create_board_name(ab, name, name_len, false, ++ ATH11K_BDF_NAME_BUS_NAME); ++} ++ ++static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name, ++ size_t name_len) ++{ ++ return __ath11k_core_create_board_name(ab, name, name_len, false, ++ ATH11K_BDF_NAME_CHIP_ID); + } + + const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, +@@ -1289,16 +1315,21 @@ int ath11k_core_fetch_board_data_api_1(s + #define BOARD_NAME_SIZE 200 + int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) + { +- char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE]; ++ char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL; + char *filename, filepath[100]; +- int ret; ++ int ret = 0; + + filename = ATH11K_BOARD_API2_FILE; ++ boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL); ++ if (!boardname) { ++ ret = -ENOMEM; ++ goto exit; ++ } + +- ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname)); ++ ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); + if (ret) { + ath11k_err(ab, "failed to create board name: %d", ret); +- return ret; ++ goto exit; + } + + ab->bd_api = 2; +@@ -1307,13 +1338,19 @@ int ath11k_core_fetch_bdf(struct ath11k_ + ATH11K_BD_IE_BOARD_NAME, + ATH11K_BD_IE_BOARD_DATA); + if (!ret) +- goto success; ++ goto exit; ++ ++ fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL); ++ if (!fallback_boardname) { ++ ret = -ENOMEM; ++ goto exit; ++ } + + ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname, +- sizeof(fallback_boardname)); ++ BOARD_NAME_SIZE); + if (ret) { + ath11k_err(ab, "failed to create fallback board name: %d", ret); +- return ret; ++ goto exit; + } + + ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname, +@@ -1321,7 +1358,28 @@ int ath11k_core_fetch_bdf(struct ath11k_ + ATH11K_BD_IE_BOARD_NAME, + ATH11K_BD_IE_BOARD_DATA); + if (!ret) +- goto success; ++ goto exit; ++ ++ chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL); ++ if (!chip_id_boardname) { ++ ret = -ENOMEM; ++ goto exit; ++ } ++ ++ ret = ath11k_core_create_chip_id_board_name(ab, chip_id_boardname, ++ BOARD_NAME_SIZE); ++ if (ret) { ++ ath11k_err(ab, "failed to create chip id board name: %d", ret); ++ goto exit; ++ } ++ ++ ret = ath11k_core_fetch_board_data_api_n(ab, bd, chip_id_boardname, ++ ATH11K_BD_IE_BOARD, ++ ATH11K_BD_IE_BOARD_NAME, ++ ATH11K_BD_IE_BOARD_DATA); ++ ++ if (!ret) ++ goto exit; + + ab->bd_api = 1; + ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); +@@ -1334,14 +1392,22 @@ int ath11k_core_fetch_bdf(struct ath11k_ + ath11k_err(ab, "failed to fetch board data for %s from %s\n", + fallback_boardname, filepath); + ++ ath11k_err(ab, "failed to fetch board data for %s from %s\n", ++ chip_id_boardname, filepath); ++ + ath11k_err(ab, "failed to fetch board.bin from %s\n", + ab->hw_params.fw.dir); +- return ret; + } + +-success: +- ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api); +- return 0; ++exit: ++ kfree(boardname); ++ kfree(fallback_boardname); ++ kfree(chip_id_boardname); ++ ++ if (!ret) ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api); ++ ++ return ret; + } + + int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) diff --git a/package/kernel/mac80211/patches/ath11k/0096-wifi-ath11k-fix-boot-failure-with-one-MSI-vector.patch b/package/kernel/mac80211/patches/ath11k/0096-wifi-ath11k-fix-boot-failure-with-one-MSI-vector.patch new file mode 100644 index 000000000..9101a1ea1 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/0096-wifi-ath11k-fix-boot-failure-with-one-MSI-vector.patch @@ -0,0 +1,103 @@ +From 39564b475ac5a589e6c22c43a08cbd283c295d2c Mon Sep 17 00:00:00 2001 +From: Baochen Qiang +Date: Thu, 7 Sep 2023 09:56:06 +0800 +Subject: [PATCH] wifi: ath11k: fix boot failure with one MSI vector + +Commit 5b32b6dd96633 ("ath11k: Remove core PCI references from +PCI common code") breaks with one MSI vector because it moves +affinity setting after IRQ request, see below log: + +[ 1417.278835] ath11k_pci 0000:02:00.0: failed to receive control response completion, polling.. +[ 1418.302829] ath11k_pci 0000:02:00.0: Service connect timeout +[ 1418.302833] ath11k_pci 0000:02:00.0: failed to connect to HTT: -110 +[ 1418.303669] ath11k_pci 0000:02:00.0: failed to start core: -110 + +The detail is, if do affinity request after IRQ activated, +which is done in request_irq(), kernel caches that request and +returns success directly. Later when a subsequent MHI interrupt is +fired, kernel will do the real affinity setting work, as a result, +changs the MSI vector. However at that time host has configured +old vector to hardware, so host never receives CE or DP interrupts. + +Fix it by setting affinity before registering MHI controller +where host is, for the first time, doing IRQ request. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 +Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01160-QCAMSLSWPLZ-1 + +Fixes: 5b32b6dd9663 ("ath11k: Remove core PCI references from PCI common code") +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230907015606.16297-1-quic_bqiang@quicinc.com +--- + drivers/net/wireless/ath/ath11k/pci.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -852,10 +852,16 @@ unsupported_wcn6855_soc: + if (ret) + goto err_pci_disable_msi; + ++ ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); ++ if (ret) { ++ ath11k_err(ab, "failed to set irq affinity %d\n", ret); ++ goto err_pci_disable_msi; ++ } ++ + ret = ath11k_mhi_register(ab_pci); + if (ret) { + ath11k_err(ab, "failed to register mhi: %d\n", ret); +- goto err_pci_disable_msi; ++ goto err_irq_affinity_cleanup; + } + + ret = ath11k_hal_srng_init(ab); +@@ -876,12 +882,6 @@ unsupported_wcn6855_soc: + goto err_ce_free; + } + +- ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); +- if (ret) { +- ath11k_err(ab, "failed to set irq affinity %d\n", ret); +- goto err_free_irq; +- } +- + /* kernel may allocate a dummy vector before request_irq and + * then allocate a real vector when request_irq is called. + * So get msi_data here again to avoid spurious interrupt +@@ -890,20 +890,17 @@ unsupported_wcn6855_soc: + ret = ath11k_pci_config_msi_data(ab_pci); + if (ret) { + ath11k_err(ab, "failed to config msi_data: %d\n", ret); +- goto err_irq_affinity_cleanup; ++ goto err_free_irq; + } + + ret = ath11k_core_init(ab); + if (ret) { + ath11k_err(ab, "failed to init core: %d\n", ret); +- goto err_irq_affinity_cleanup; ++ goto err_free_irq; + } + ath11k_qmi_fwreset_from_cold_boot(ab); + return 0; + +-err_irq_affinity_cleanup: +- ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); +- + err_free_irq: + ath11k_pcic_free_irq(ab); + +@@ -916,6 +913,9 @@ err_hal_srng_deinit: + err_mhi_unregister: + ath11k_mhi_unregister(ab_pci); + ++err_irq_affinity_cleanup: ++ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); ++ + err_pci_disable_msi: + ath11k_pci_free_msi(ab_pci); + diff --git a/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch b/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch index 39d5a61d5..30472b322 100644 --- a/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch +++ b/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch @@ -93,7 +93,7 @@ Signed-off-by: Robert Marko default: return "UNKNOWN"; } -@@ -336,27 +366,14 @@ static void ath11k_mhi_op_status_cb(stru +@@ -337,27 +367,14 @@ static void ath11k_mhi_op_status_cb(stru if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) queue_work(ab->workqueue_aux, &ab->reset_work); break; @@ -138,7 +138,7 @@ Signed-off-by: Robert Marko int ath11k_mhi_register(struct ath11k_pci *ar_pci); --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -370,13 +370,20 @@ static void ath11k_pci_sw_reset(struct a +@@ -371,13 +371,20 @@ static void ath11k_pci_sw_reset(struct a static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) { struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; diff --git a/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch b/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch index 721565638..9a0ca8009 100644 --- a/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch +++ b/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch @@ -15,7 +15,7 @@ Signed-off-by: Robert Marko --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -458,7 +458,11 @@ static int ath11k_pci_alloc_msi(struct a +@@ -459,7 +459,11 @@ static int ath11k_pci_alloc_msi(struct a pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, &ab->pci.msi.addr_lo); diff --git a/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch b/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch index 5454fa75e..0c92fa914 100644 --- a/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch +++ b/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch @@ -13,12 +13,14 @@ Signed-off-by: Robert Marko --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -86,7 +86,7 @@ static const struct ath11k_hw_params ath +@@ -86,8 +86,8 @@ static const struct ath11k_hw_params ath .supports_shadow_regs = false, .idle_ps = false, .supports_sta_ps = false, -- .cold_boot_calib = true, -+ .cold_boot_calib = false, +- .coldboot_cal_mm = true, +- .coldboot_cal_ftm = true, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, .cbcal_restart_fw = true, .fw_mem_mode = 0, .num_vdevs = 16 + 1, diff --git a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch index 22c2493ca..71373b213 100644 --- a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch +++ b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch @@ -31,7 +31,7 @@ Signed-off-by: Robert Marko { .hw_rev = ATH11K_HW_IPQ8074, .name = "ipq8074 hw2.0", -@@ -1953,7 +1953,8 @@ static void ath11k_core_reset(struct wor +@@ -2040,7 +2040,8 @@ static void ath11k_core_reset(struct wor static int ath11k_init_hw_params(struct ath11k_base *ab) { const struct ath11k_hw_params *hw_params = NULL; @@ -41,7 +41,7 @@ Signed-off-by: Robert Marko for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { hw_params = &ath11k_hw_params[i]; -@@ -1969,7 +1970,30 @@ static int ath11k_init_hw_params(struct +@@ -2056,7 +2057,31 @@ static int ath11k_init_hw_params(struct ab->hw_params = *hw_params; @@ -62,7 +62,8 @@ Signed-off-by: Robert Marko + ab->hw_params.fw_mem_mode = 2; + ab->hw_params.num_vdevs = 8; + ab->hw_params.num_peers = 128; -+ ab->hw_params.cold_boot_calib = false; ++ ab->hw_params.coldboot_cal_mm = false; ++ ab->hw_params.coldboot_cal_ftm = false; + } else + ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode); + } diff --git a/package/kernel/mac80211/patches/ath11k/906-ath11k-Disable-coldboot-calibration-for-IPQ6018.patch b/package/kernel/mac80211/patches/ath11k/906-ath11k-Disable-coldboot-calibration-for-IPQ6018.patch new file mode 100644 index 000000000..39a11d722 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/906-ath11k-Disable-coldboot-calibration-for-IPQ6018.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -168,8 +168,8 @@ static struct ath11k_hw_params ath11k_hw + .supports_shadow_regs = false, + .idle_ps = false, + .supports_sta_ps = false, +- .coldboot_cal_mm = true, +- .coldboot_cal_ftm = true, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .cbcal_restart_fw = true, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, diff --git a/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch index 2f5e75be8..e2bbb4a1b 100644 --- a/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch +++ b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1413,6 +1413,54 @@ void ath9k_deinit_debug(struct ath_softc +@@ -1413,6 +1413,53 @@ void ath9k_deinit_debug(struct ath_softc ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); } @@ -39,8 +39,7 @@ + } else { + bytes = 2; + } -+ if (copy_to_user(user_buf, from, bytes)) -+ return -EFAULT; ++ copy_to_user(user_buf, from, bytes); + user_buf += bytes; + } + return *ppos - pos; @@ -55,7 +54,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1432,6 +1480,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1432,6 +1479,8 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_tx99_init_debug(sc); ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); diff --git a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch index a871e458a..0c8b6920c 100644 --- a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch +++ b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1461,6 +1461,52 @@ static const struct file_operations fops +@@ -1460,6 +1460,52 @@ static const struct file_operations fops .owner = THIS_MODULE }; @@ -53,7 +53,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1482,6 +1528,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1481,6 +1527,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_eeprom); diff --git a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch index 74506657e..1fe004102 100644 --- a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch @@ -192,7 +192,7 @@ #endif --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1506,6 +1506,61 @@ static const struct file_operations fops +@@ -1505,6 +1505,61 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -254,7 +254,7 @@ int ath9k_init_debug(struct ath_hw *ah) { -@@ -1530,6 +1585,10 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1529,6 +1584,10 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_eeprom); debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_chanbw); diff --git a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch index e09bbc08e..70f7ee365 100644 --- a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1562,6 +1562,50 @@ static const struct file_operations fops +@@ -1561,6 +1561,50 @@ static const struct file_operations fops #endif @@ -51,7 +51,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1589,6 +1633,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1588,6 +1632,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("gpio_led", S_IWUSR, sc->debug.debugfs_phy, sc, &fops_gpio_led); #endif diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch new file mode 100644 index 000000000..9d0f3e20b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -0,0 +1,64 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 8 Jun 2015 16:11:40 +0200 +Subject: [PATCH] brcmfmac: register wiphy(s) during module_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is needed by OpenWrt which expects all PHYs to be created after +module loads successfully. + +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -459,6 +459,7 @@ struct brcmf_fw { + u32 curpos; + unsigned int board_index; + void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); ++ struct completion *completion; + }; + + #ifdef CONFIG_EFI +@@ -686,6 +687,8 @@ static void brcmf_fw_request_done(const + fwctx->req = NULL; + } + fwctx->done(fwctx->dev, ret, fwctx->req); ++ if (fwctx->completion) ++ complete(fwctx->completion); + kfree(fwctx); + } + +@@ -751,6 +754,8 @@ int brcmf_fw_get_firmwares(struct device + { + struct brcmf_fw_item *first = &req->items[0]; + struct brcmf_fw *fwctx; ++ struct completion completion; ++ unsigned long time_left; + char *alt_path = NULL; + int ret; + +@@ -768,6 +773,9 @@ int brcmf_fw_get_firmwares(struct device + fwctx->dev = dev; + fwctx->req = req; + fwctx->done = fw_cb; ++ ++ init_completion(&completion); ++ fwctx->completion = &completion; + + /* First try alternative board-specific path if any */ + if (fwctx->req->board_types[0]) +@@ -787,6 +795,12 @@ int brcmf_fw_get_firmwares(struct device + if (ret < 0) + brcmf_fw_request_done(NULL, fwctx); + ++ ++ time_left = wait_for_completion_timeout(&completion, ++ msecs_to_jiffies(5000)); ++ if (!time_left && fwctx) ++ fwctx->completion = NULL; ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch index 8df285f8b..8ed81f600 100644 --- a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch +++ b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch @@ -65,26 +65,22 @@ Signed-off-by: Phil Elwell +} --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -@@ -5,9 +5,20 @@ +@@ -5,9 +5,16 @@ #ifdef CONFIG_OF void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, struct brcmf_mp_device *settings); -+#ifdef CPTCFG_BRCMFMAC_SDIO +struct brcmf_firmware_mapping * +brcmf_of_fwnames(struct device *dev, u32 *map_count); -+#endif #else static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, struct brcmf_mp_device *settings) { } -+#ifdef CPTCFG_BRCMFMAC_SDIO +static struct brcmf_firmware_mapping * +brcmf_of_fwnames(struct device *dev, u32 *map_count) +{ + return NULL; +} -+#endif #endif /* CONFIG_OF */ --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c diff --git a/package/kernel/mac80211/patches/build/050-lib80211_option.patch b/package/kernel/mac80211/patches/build/050-lib80211_option.patch new file mode 100644 index 000000000..c1b1bc757 --- /dev/null +++ b/package/kernel/mac80211/patches/build/050-lib80211_option.patch @@ -0,0 +1,34 @@ +--- a/net/wireless/Kconfig ++++ b/net/wireless/Kconfig +@@ -188,7 +188,7 @@ config CFG80211_WEXT_EXPORT + endif # CFG80211 + + config LIB80211 +- tristate ++ tristate "lib80211" + depends on m + default n + help +@@ -198,19 +198,19 @@ config LIB80211 + Drivers should select this themselves if needed. + + config LIB80211_CRYPT_WEP +- tristate ++ tristate "lib80211 WEP support" + depends on m + select BPAUTO_CRYPTO_LIB_ARC4 + + config LIB80211_CRYPT_CCMP +- tristate ++ tristate "lib80211 CCMP support" + depends on m + depends on CRYPTO + depends on CRYPTO_AES + depends on CRYPTO_CCM + + config LIB80211_CRYPT_TKIP +- tristate ++ tristate "lib80211 TKIP support" + depends on m + select BPAUTO_CRYPTO_LIB_ARC4 + diff --git a/package/kernel/mac80211/patches/build/099-netlink-range.patch b/package/kernel/mac80211/patches/build/099-netlink-range.patch new file mode 100644 index 000000000..0df2b38fa --- /dev/null +++ b/package/kernel/mac80211/patches/build/099-netlink-range.patch @@ -0,0 +1,91 @@ +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -421,8 +421,13 @@ static const struct nla_policy + nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = { + [NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000), + [NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000), ++#if LINUX_VERSION_IS_GEQ(5,10,0) + [NL80211_FILS_DISCOVERY_ATTR_TMPL] = + NLA_POLICY_BINARY_RANGE(NL80211_FILS_DISCOVERY_TMPL_MIN_LEN, IEEE80211_MAX_DATA_LEN), ++#else ++ [NL80211_FILS_DISCOVERY_ATTR_TMPL] = { .type = NLA_BINARY, ++ .len = IEEE80211_MAX_DATA_LEN }, ++#endif + }; + + static const struct nla_policy +@@ -533,7 +538,11 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT, + + /* allow 3 for NUL-termination, we used to declare this NLA_STRING */ ++#if LINUX_VERSION_IS_GEQ(5,10,0) + [NL80211_ATTR_REG_ALPHA2] = NLA_POLICY_BINARY_RANGE(2, 3), ++#else ++ [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, ++#endif + [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED }, + + [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 }, +@@ -679,14 +688,24 @@ static const struct nla_policy nl80211_p + * The value of the Length field of the Supported Operating + * Classes element is between 2 and 253. + */ ++#if LINUX_VERSION_IS_GEQ(5,10,0) + [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = + NLA_POLICY_BINARY_RANGE(2, 253), ++#else ++ [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = ++ { .type = NLA_BINARY }, ++#endif + [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, + [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 }, + [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 }, + [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, + [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, ++#if LINUX_VERSION_IS_GEQ(5,10,0) + [NL80211_ATTR_QOS_MAP] = NLA_POLICY_BINARY_RANGE(IEEE80211_QOS_MAP_LEN_MIN, IEEE80211_QOS_MAP_LEN_MAX), ++#else ++ [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY, ++ .len = IEEE80211_QOS_MAP_LEN_MAX }, ++#endif + [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN), + [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, + [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, +@@ -741,9 +760,14 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 }, + [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 }, + [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 }, ++#if LINUX_VERSION_IS_GEQ(5,10,0) + [NL80211_ATTR_HE_CAPABILITY] = + NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa, + NL80211_HE_MAX_CAPABILITY_LEN), ++#else ++ [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY, ++ .len = NL80211_HE_MAX_CAPABILITY_LEN }, ++#endif + [NL80211_ATTR_FTM_RESPONDER] = + NLA_POLICY_NESTED(nl80211_ftm_responder_policy), + [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1), +@@ -16392,9 +16416,11 @@ static const struct genl_ops nl80211_ops + /* can be retrieved by unprivileged users */ + .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY), + }, ++#if LINUX_VERSION_IS_GEQ(5,10,0) + }; + + static const struct genl_small_ops nl80211_small_ops[] = { ++#endif + { + .cmd = NL80211_CMD_SET_WIPHY, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, +@@ -17231,8 +17257,10 @@ static struct genl_family nl80211_fam __ + .module = THIS_MODULE, + .ops = nl80211_ops, + .n_ops = ARRAY_SIZE(nl80211_ops), ++#if LINUX_VERSION_IS_GEQ(5,10,0) + .small_ops = nl80211_small_ops, + .n_small_ops = ARRAY_SIZE(nl80211_small_ops), ++#endif + #if LINUX_VERSION_IS_GEQ(6,1,0) + .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1, + #endif diff --git a/package/kernel/mac80211/patches/build/990-add_kernel_6.6_support.patch b/package/kernel/mac80211/patches/build/990-add_kernel_6.6_support.patch new file mode 100644 index 000000000..2ced0316d --- /dev/null +++ b/package/kernel/mac80211/patches/build/990-add_kernel_6.6_support.patch @@ -0,0 +1,113 @@ +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -148,12 +148,21 @@ static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, w + #define WIPHY_PM_OPS NULL + #endif + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++static const void *wiphy_namespace(const struct device *d) ++{ ++ struct wiphy *wiphy = container_of(d, struct wiphy, dev); ++ ++ return wiphy_net(wiphy); ++} ++#else + static const void *wiphy_namespace(struct device *d) + { + struct wiphy *wiphy = container_of(d, struct wiphy, dev); + + return wiphy_net(wiphy); + } ++#endif + + struct class ieee80211_class = { + .name = "ieee80211", +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -16158,8 +16158,14 @@ static u32 nl80211_internal_flags[] = { + #undef SELECTOR + }; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++static int nl80211_pre_doit(const struct genl_split_ops *ops, ++ struct sk_buff *skb, ++ struct genl_info *info) ++#else + static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) ++#endif + { + struct cfg80211_registered_device *rdev = NULL; + struct wireless_dev *wdev = NULL; +@@ -16259,8 +16265,14 @@ out_unlock: + return err; + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++static void nl80211_post_doit(const struct genl_split_ops *ops, ++ struct sk_buff *skb, ++ struct genl_info *info) ++#else + static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) ++#endif + { + u32 internal_flags = nl80211_internal_flags[ops->internal_flags]; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -27,6 +27,10 @@ + #include + #include + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++#include ++#endif ++ + #include "ieee80211_i.h" + #include "driver-ops.h" + #include "led.h" +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -10,6 +10,10 @@ + #include + #include + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++#include ++#endif ++ + #include "iwl-trans.h" + #include "iwl-eeprom-parse.h" + #include "mvm.h" +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1435,6 +1435,7 @@ enum mac80211_rx_encoding { + RX_ENC_HT, + RX_ENC_VHT, + RX_ENC_HE, ++ RX_ENC_EHT, + }; + + /** +@@ -1497,8 +1498,18 @@ struct ieee80211_rx_status { + u32 flag; + u16 freq: 13, freq_offset: 1; + u8 enc_flags; +- u8 encoding:2, bw:3, he_ru:3; +- u8 he_gi:2, he_dcm:1; ++ u8 encoding:3, bw:4; ++ union { ++ struct { ++ u8 he_ru:3; ++ u8 he_gi:2; ++ u8 he_dcm:1; ++ }; ++ struct { ++ u8 ru:4; ++ u8 gi:2; ++ } eht; ++ }; + u8 rate_idx; + u8 nss; + u8 rx_flags; diff --git a/package/kernel/mac80211/patches/rtl/001-wifi-rtw88-fix-race-condition-when-doing-H2C-command.patch b/package/kernel/mac80211/patches/rtl/001-wifi-rtw88-fix-race-condition-when-doing-H2C-command.patch deleted file mode 100644 index 2c7cdf852..000000000 --- a/package/kernel/mac80211/patches/rtl/001-wifi-rtw88-fix-race-condition-when-doing-H2C-command.patch +++ /dev/null @@ -1,73 +0,0 @@ -From dee121b45dd1eef42b5da093bf1ebeb80a7955bb Mon Sep 17 00:00:00 2001 -From: Ji-Pin Jou -Date: Thu, 24 Nov 2022 14:44:42 +0800 -Subject: [PATCH 01/13] wifi: rtw88: fix race condition when doing H2C command - -For SDIO/USB interface, since the tranferring speed is slower than -that in PCIE, it may have race condition when the driver sets down -H2C command to the FW. - -In the function rtw_fw_send_h2c_command, before the patch, box_reg -is written first, then box_ex_reg is written. FW starts to work and -fetch the value of box_ex_reg, when the most significant byte of -box_reg(4 bytes) is written. Meanwhile, for SDIO/USB interface, -since the transferring speed is slow, the driver is still in writing -the new value of box_ex_reg through the bus, and FW may get the -wrong value of box_ex_reg at the moment. - -To prevent the above driver/FW racing situation, box_ex_reg is -written first then box_reg. Furthermore, it is written in 4 bytes at -a time, instead of written in one byte one by one. It can increase -the speed for SDIO/USB interface. - -Signed-off-by: Ji-Pin Jou -Signed-off-by: Ping-Ke Shih -Tested-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221124064442.28042-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 8 +++----- - drivers/net/wireless/realtek/rtw88/fw.h | 5 +++++ - 2 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -311,10 +311,10 @@ EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); - static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, - u8 *h2c) - { -+ struct rtw_h2c_cmd *h2c_cmd = (struct rtw_h2c_cmd *)h2c; - u8 box; - u8 box_state; - u32 box_reg, box_ex_reg; -- int idx; - int ret; - - rtw_dbg(rtwdev, RTW_DBG_FW, -@@ -356,10 +356,8 @@ static void rtw_fw_send_h2c_command(stru - goto out; - } - -- for (idx = 0; idx < 4; idx++) -- rtw_write8(rtwdev, box_reg + idx, h2c[idx]); -- for (idx = 0; idx < 4; idx++) -- rtw_write8(rtwdev, box_ex_reg + idx, h2c[idx + 4]); -+ rtw_write32(rtwdev, box_ex_reg, le32_to_cpu(h2c_cmd->msg_ext)); -+ rtw_write32(rtwdev, box_reg, le32_to_cpu(h2c_cmd->msg)); - - if (++rtwdev->h2c.last_box_num >= 4) - rtwdev->h2c.last_box_num = 0; ---- a/drivers/net/wireless/realtek/rtw88/fw.h -+++ b/drivers/net/wireless/realtek/rtw88/fw.h -@@ -81,6 +81,11 @@ struct rtw_c2h_adaptivity { - u8 option; - } __packed; - -+struct rtw_h2c_cmd { -+ __le32 msg; -+ __le32 msg_ext; -+} __packed; -+ - enum rtw_rsvd_packet_type { - RSVD_BEACON, - RSVD_DUMMY, diff --git a/package/kernel/mac80211/patches/rtl/002-wifi-rtw88-8821c-enable-BT-device-recovery-mechanism.patch b/package/kernel/mac80211/patches/rtl/002-wifi-rtw88-8821c-enable-BT-device-recovery-mechanism.patch deleted file mode 100644 index 9149e989d..000000000 --- a/package/kernel/mac80211/patches/rtl/002-wifi-rtw88-8821c-enable-BT-device-recovery-mechanism.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 91759247856dc65b69f71812a0903f59680f9890 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 28 Nov 2022 15:56:53 +0800 -Subject: [PATCH 02/13] wifi: rtw88: 8821c: enable BT device recovery mechanism - -8821ce is a combo card, and BT is a USB device that could get card lost -during stress test, and need WiFi firmware to detect and recover it, so -driver sends a H2C to enable this mechanism. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221128075653.5221-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 10 ++++++++++ - drivers/net/wireless/realtek/rtw88/fw.h | 6 ++++++ - drivers/net/wireless/realtek/rtw88/mac.c | 18 +++++++++++++++++- - 3 files changed, 33 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -822,6 +822,16 @@ void rtw_fw_set_nlo_info(struct rtw_dev - rtw_fw_send_h2c_command(rtwdev, h2c_pkt); - } - -+void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev) -+{ -+ u8 h2c_pkt[H2C_PKT_SIZE] = {0}; -+ -+ SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RECOVER_BT_DEV); -+ SET_RECOVER_BT_DEV_EN(h2c_pkt, 1); -+ -+ rtw_fw_send_h2c_command(rtwdev, h2c_pkt); -+} -+ - void rtw_fw_set_pg_info(struct rtw_dev *rtwdev) - { - struct rtw_lps_conf *conf = &rtwdev->lps_conf; ---- a/drivers/net/wireless/realtek/rtw88/fw.h -+++ b/drivers/net/wireless/realtek/rtw88/fw.h -@@ -555,6 +555,8 @@ static inline void rtw_h2c_pkt_set_heade - #define H2C_CMD_AOAC_GLOBAL_INFO 0x82 - #define H2C_CMD_NLO_INFO 0x8C - -+#define H2C_CMD_RECOVER_BT_DEV 0xD1 -+ - #define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \ - le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0)) - -@@ -754,6 +756,9 @@ static inline void rtw_h2c_pkt_set_heade - #define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \ - le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) - -+#define SET_RECOVER_BT_DEV_EN(h2c_pkt, value) \ -+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) -+ - #define GET_FW_DUMP_LEN(_header) \ - le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(15, 0)) - #define GET_FW_DUMP_SEQ(_header) \ -@@ -843,6 +848,7 @@ void rtw_fw_set_aoac_global_info_cmd(str - u8 group_key_enc); - - void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable); -+void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev); - void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, - struct cfg80211_ssid *ssid); - void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable); ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -916,7 +916,8 @@ out: - return ret; - } - --int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) -+static -+int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) - { - if (rtw_chip_wcpu_11n(rtwdev)) - return __rtw_download_firmware_legacy(rtwdev, fw); -@@ -924,6 +925,21 @@ int rtw_download_firmware(struct rtw_dev - return __rtw_download_firmware(rtwdev, fw); - } - -+int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) -+{ -+ int ret; -+ -+ ret = _rtw_download_firmware(rtwdev, fw); -+ if (ret) -+ return ret; -+ -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && -+ rtwdev->chip->id == RTW_CHIP_TYPE_8821C) -+ rtw_fw_set_recover_bt_device(rtwdev); -+ -+ return 0; -+} -+ - static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) - { - const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn; diff --git a/package/kernel/mac80211/patches/rtl/003-wifi-rtw88-print-firmware-type-in-info-message.patch b/package/kernel/mac80211/patches/rtl/003-wifi-rtw88-print-firmware-type-in-info-message.patch deleted file mode 100644 index 2bc94f353..000000000 --- a/package/kernel/mac80211/patches/rtl/003-wifi-rtw88-print-firmware-type-in-info-message.patch +++ /dev/null @@ -1,56 +0,0 @@ -From a02233a1346132efe6dda33237a0b07771fbb09b Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:14 +0100 -Subject: [PATCH 03/13] wifi: rtw88: print firmware type in info message - -It's confusing to read two different firmware versions in the syslog -for the same device: - -rtw_8822cu 2-1:1.2: Firmware version 9.9.4, H2C version 15 -rtw_8822cu 2-1:1.2: Firmware version 9.9.11, H2C version 15 - -Print the firmware type in this message to make clear these are really -two different firmwares for different purposes: - -rtw_8822cu 1-1.4:1.2: WOW Firmware version 9.9.4, H2C version 15 -rtw_8822cu 1-1.4:1.2: Firmware version 9.9.11, H2C version 15 - -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-2-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/main.c | 4 +++- - drivers/net/wireless/realtek/rtw88/main.h | 1 + - 2 files changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -1731,7 +1731,8 @@ static void rtw_load_firmware_cb(const s - update_firmware_info(rtwdev, fw); - complete_all(&fw->completion); - -- rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n", -+ rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n", -+ fw->type == RTW_WOWLAN_FW ? "WOW " : "", - fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); - } - -@@ -1757,6 +1758,7 @@ static int rtw_load_firmware(struct rtw_ - return -ENOENT; - } - -+ fw->type = type; - fw->rtwdev = rtwdev; - init_completion(&fw->completion); - ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1851,6 +1851,7 @@ struct rtw_fw_state { - u16 h2c_version; - u32 feature; - u32 feature_ext; -+ enum rtw_fw_type type; - }; - - enum rtw_sar_sources { diff --git a/package/kernel/mac80211/patches/rtl/004-wifi-rtw88-Call-rtw_fw_beacon_filter_config-with-rtw.patch b/package/kernel/mac80211/patches/rtl/004-wifi-rtw88-Call-rtw_fw_beacon_filter_config-with-rtw.patch deleted file mode 100644 index cb78356f7..000000000 --- a/package/kernel/mac80211/patches/rtl/004-wifi-rtw88-Call-rtw_fw_beacon_filter_config-with-rtw.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ca6f02262c480ed49c5c6e41a0634c75b9a47dca Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:15 +0100 -Subject: [PATCH 04/13] wifi: rtw88: Call rtw_fw_beacon_filter_config() with - rtwdev->mutex held - -rtw_fw_beacon_filter_config() is called once with rtwdev->mutex held -and once without the mutex held. Call it consistently with rtwdev->mutex -held. - -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-3-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -487,8 +487,8 @@ static int rtw_ops_sta_remove(struct iee - { - struct rtw_dev *rtwdev = hw->priv; - -- rtw_fw_beacon_filter_config(rtwdev, false, vif); - mutex_lock(&rtwdev->mutex); -+ rtw_fw_beacon_filter_config(rtwdev, false, vif); - rtw_sta_remove(rtwdev, sta, true); - mutex_unlock(&rtwdev->mutex); - diff --git a/package/kernel/mac80211/patches/rtl/005-wifi-rtw88-Drop-rf_lock.patch b/package/kernel/mac80211/patches/rtl/005-wifi-rtw88-Drop-rf_lock.patch deleted file mode 100644 index 2c0ffd8f2..000000000 --- a/package/kernel/mac80211/patches/rtl/005-wifi-rtw88-Drop-rf_lock.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 293a0c7587a4dbfa700e23bc93f80dd2ad40ed59 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:16 +0100 -Subject: [PATCH 05/13] wifi: rtw88: Drop rf_lock - -The rtwdev->rf_lock spinlock protects the rf register accesses in -rtw_read_rf() and rtw_write_rf(). Most callers of these functions hold -rtwdev->mutex already with the exception of the callsites in the debugfs -code. The debugfs code doesn't justify an extra lock, so acquire the mutex -there as well before calling rf register accessors and drop the now -unnecessary spinlock. - -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-4-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/debug.c | 11 +++++++++++ - drivers/net/wireless/realtek/rtw88/hci.h | 9 +++------ - drivers/net/wireless/realtek/rtw88/main.c | 1 - - drivers/net/wireless/realtek/rtw88/main.h | 3 --- - 4 files changed, 14 insertions(+), 10 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -144,7 +144,9 @@ static int rtw_debugfs_get_rf_read(struc - addr = debugfs_priv->rf_addr; - mask = debugfs_priv->rf_mask; - -+ mutex_lock(&rtwdev->mutex); - val = rtw_read_rf(rtwdev, path, addr, mask); -+ mutex_unlock(&rtwdev->mutex); - - seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n", - path, addr, mask, val); -@@ -414,7 +416,9 @@ static ssize_t rtw_debugfs_set_rf_write( - return count; - } - -+ mutex_lock(&rtwdev->mutex); - rtw_write_rf(rtwdev, path, addr, mask, val); -+ mutex_unlock(&rtwdev->mutex); - rtw_dbg(rtwdev, RTW_DBG_DEBUGFS, - "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n", - path, addr, mask, val); -@@ -519,6 +523,8 @@ static int rtw_debug_get_rf_dump(struct - u32 addr, offset, data; - u8 path; - -+ mutex_lock(&rtwdev->mutex); -+ - for (path = 0; path < rtwdev->hal.rf_path_num; path++) { - seq_printf(m, "RF path:%d\n", path); - for (addr = 0; addr < 0x100; addr += 4) { -@@ -533,6 +539,8 @@ static int rtw_debug_get_rf_dump(struct - seq_puts(m, "\n"); - } - -+ mutex_unlock(&rtwdev->mutex); -+ - return 0; - } - -@@ -1026,6 +1034,8 @@ static void dump_gapk_status(struct rtw_ - dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+', - rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]); - -+ mutex_lock(&rtwdev->mutex); -+ - for (path = 0; path < rtwdev->hal.rf_path_num; path++) { - val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK); - seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val); -@@ -1035,6 +1045,7 @@ static void dump_gapk_status(struct rtw_ - txgapk->rf3f_fs[path][i], i); - seq_puts(m, "\n"); - } -+ mutex_unlock(&rtwdev->mutex); - } - - static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) ---- a/drivers/net/wireless/realtek/rtw88/hci.h -+++ b/drivers/net/wireless/realtek/rtw88/hci.h -@@ -166,12 +166,11 @@ static inline u32 - rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, - u32 addr, u32 mask) - { -- unsigned long flags; - u32 val; - -- spin_lock_irqsave(&rtwdev->rf_lock, flags); -+ lockdep_assert_held(&rtwdev->mutex); -+ - val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); -- spin_unlock_irqrestore(&rtwdev->rf_lock, flags); - - return val; - } -@@ -180,11 +179,9 @@ static inline void - rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, - u32 addr, u32 mask, u32 data) - { -- unsigned long flags; -+ lockdep_assert_held(&rtwdev->mutex); - -- spin_lock_irqsave(&rtwdev->rf_lock, flags); - rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); -- spin_unlock_irqrestore(&rtwdev->rf_lock, flags); - } - - static inline u32 ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2067,7 +2067,6 @@ int rtw_core_init(struct rtw_dev *rtwdev - skb_queue_head_init(&rtwdev->coex.queue); - skb_queue_head_init(&rtwdev->tx_report.queue); - -- spin_lock_init(&rtwdev->rf_lock); - spin_lock_init(&rtwdev->h2c.lock); - spin_lock_init(&rtwdev->txq_lock); - spin_lock_init(&rtwdev->tx_report.q_lock); ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1995,9 +1995,6 @@ struct rtw_dev { - /* ensures exclusive access from mac80211 callbacks */ - struct mutex mutex; - -- /* read/write rf register */ -- spinlock_t rf_lock; -- - /* watch dog every 2 sec */ - struct delayed_work watch_dog_work; - u32 watch_dog_cnt; diff --git a/package/kernel/mac80211/patches/rtl/006-wifi-rtw88-Drop-h2c.lock.patch b/package/kernel/mac80211/patches/rtl/006-wifi-rtw88-Drop-h2c.lock.patch deleted file mode 100644 index 9363596c0..000000000 --- a/package/kernel/mac80211/patches/rtl/006-wifi-rtw88-Drop-h2c.lock.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0c42222e7ba7fc209474ade5f8e082360ba17d13 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:17 +0100 -Subject: [PATCH 06/13] wifi: rtw88: Drop h2c.lock - -The h2c.lock spinlock is used in rtw_fw_send_h2c_command() and -rtw_fw_send_h2c_packet(). Most callers call this with rtwdev->mutex -held, except from one callsite in the debugfs code. The debugfs code -alone doesn't justify the extra lock, so acquire rtwdev->mutex in -debugfs and drop the now unnecessary spinlock. - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-5-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/debug.c | 2 ++ - drivers/net/wireless/realtek/rtw88/fw.c | 13 ++++--------- - drivers/net/wireless/realtek/rtw88/main.c | 1 - - drivers/net/wireless/realtek/rtw88/main.h | 2 -- - 4 files changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -392,7 +392,9 @@ static ssize_t rtw_debugfs_set_h2c(struc - return -EINVAL; - } - -+ mutex_lock(&rtwdev->mutex); - rtw_fw_h2c_cmd_dbg(rtwdev, param); -+ mutex_unlock(&rtwdev->mutex); - - return count; - } ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -322,7 +322,7 @@ static void rtw_fw_send_h2c_command(stru - h2c[3], h2c[2], h2c[1], h2c[0], - h2c[7], h2c[6], h2c[5], h2c[4]); - -- spin_lock(&rtwdev->h2c.lock); -+ lockdep_assert_held(&rtwdev->mutex); - - box = rtwdev->h2c.last_box_num; - switch (box) { -@@ -344,7 +344,7 @@ static void rtw_fw_send_h2c_command(stru - break; - default: - WARN(1, "invalid h2c mail box number\n"); -- goto out; -+ return; - } - - ret = read_poll_timeout_atomic(rtw_read8, box_state, -@@ -353,7 +353,7 @@ static void rtw_fw_send_h2c_command(stru - - if (ret) { - rtw_err(rtwdev, "failed to send h2c command\n"); -- goto out; -+ return; - } - - rtw_write32(rtwdev, box_ex_reg, le32_to_cpu(h2c_cmd->msg_ext)); -@@ -361,9 +361,6 @@ static void rtw_fw_send_h2c_command(stru - - if (++rtwdev->h2c.last_box_num >= 4) - rtwdev->h2c.last_box_num = 0; -- --out: -- spin_unlock(&rtwdev->h2c.lock); - } - - void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c) -@@ -375,15 +372,13 @@ static void rtw_fw_send_h2c_packet(struc - { - int ret; - -- spin_lock(&rtwdev->h2c.lock); -+ lockdep_assert_held(&rtwdev->mutex); - - FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq); - ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE); - if (ret) - rtw_err(rtwdev, "failed to send h2c packet\n"); - rtwdev->h2c.seq++; -- -- spin_unlock(&rtwdev->h2c.lock); - } - - void ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2067,7 +2067,6 @@ int rtw_core_init(struct rtw_dev *rtwdev - skb_queue_head_init(&rtwdev->coex.queue); - skb_queue_head_init(&rtwdev->tx_report.queue); - -- spin_lock_init(&rtwdev->h2c.lock); - spin_lock_init(&rtwdev->txq_lock); - spin_lock_init(&rtwdev->tx_report.q_lock); - ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -2020,8 +2020,6 @@ struct rtw_dev { - struct { - /* incicate the mail box to use with fw */ - u8 last_box_num; -- /* protect to send h2c to fw */ -- spinlock_t lock; - u32 seq; - } h2c; - diff --git a/package/kernel/mac80211/patches/rtl/007-wifi-rtw88-Drop-coex-mutex.patch b/package/kernel/mac80211/patches/rtl/007-wifi-rtw88-Drop-coex-mutex.patch deleted file mode 100644 index f2bdaaf20..000000000 --- a/package/kernel/mac80211/patches/rtl/007-wifi-rtw88-Drop-coex-mutex.patch +++ /dev/null @@ -1,81 +0,0 @@ -From aa3b7995ddabf832581c542fc198d1f2e7afac28 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:18 +0100 -Subject: [PATCH 07/13] wifi: rtw88: Drop coex mutex - -coex->mutex is used in rtw_coex_info_request() only. Most callers of this -function hold rtwdev->mutex already, except for one callsite in the -debugfs code. The debugfs code alone doesn't justify the extra lock, so -acquire rtwdev->mutex there as well and drop the now unnecessary -spinlock. - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-6-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/coex.c | 3 +-- - drivers/net/wireless/realtek/rtw88/debug.c | 2 ++ - drivers/net/wireless/realtek/rtw88/main.c | 2 -- - drivers/net/wireless/realtek/rtw88/main.h | 2 -- - 4 files changed, 3 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/coex.c -+++ b/drivers/net/wireless/realtek/rtw88/coex.c -@@ -633,7 +633,7 @@ static struct sk_buff *rtw_coex_info_req - struct rtw_coex *coex = &rtwdev->coex; - struct sk_buff *skb_resp = NULL; - -- mutex_lock(&coex->mutex); -+ lockdep_assert_held(&rtwdev->mutex); - - rtw_fw_query_bt_mp_info(rtwdev, req); - -@@ -650,7 +650,6 @@ static struct sk_buff *rtw_coex_info_req - } - - out: -- mutex_unlock(&coex->mutex); - return skb_resp; - } - ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -841,7 +841,9 @@ static int rtw_debugfs_get_coex_info(str - struct rtw_debugfs_priv *debugfs_priv = m->private; - struct rtw_dev *rtwdev = debugfs_priv->rtwdev; - -+ mutex_lock(&rtwdev->mutex); - rtw_coex_display_coex_info(rtwdev, m); -+ mutex_unlock(&rtwdev->mutex); - - return 0; - } ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2071,7 +2071,6 @@ int rtw_core_init(struct rtw_dev *rtwdev - spin_lock_init(&rtwdev->tx_report.q_lock); - - mutex_init(&rtwdev->mutex); -- mutex_init(&rtwdev->coex.mutex); - mutex_init(&rtwdev->hal.tx_power_mutex); - - init_waitqueue_head(&rtwdev->coex.wait); -@@ -2143,7 +2142,6 @@ void rtw_core_deinit(struct rtw_dev *rtw - } - - mutex_destroy(&rtwdev->mutex); -- mutex_destroy(&rtwdev->coex.mutex); - mutex_destroy(&rtwdev->hal.tx_power_mutex); - } - EXPORT_SYMBOL(rtw_core_deinit); ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1501,8 +1501,6 @@ struct rtw_coex_stat { - }; - - struct rtw_coex { -- /* protects coex info request section */ -- struct mutex mutex; - struct sk_buff_head queue; - wait_queue_head_t wait; - diff --git a/package/kernel/mac80211/patches/rtl/008-wifi-rtw88-iterate-over-vif-sta-list-non-atomically.patch b/package/kernel/mac80211/patches/rtl/008-wifi-rtw88-iterate-over-vif-sta-list-non-atomically.patch deleted file mode 100644 index a55ce7614..000000000 --- a/package/kernel/mac80211/patches/rtl/008-wifi-rtw88-iterate-over-vif-sta-list-non-atomically.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 392cb1f93f3b5bf702ac3b6b110bb4e33df7ae32 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:19 +0100 -Subject: [PATCH 08/13] wifi: rtw88: iterate over vif/sta list non-atomically - -The driver uses ieee80211_iterate_active_interfaces_atomic() -and ieee80211_iterate_stations_atomic() in several places and does -register accesses in the iterators. This doesn't cope with upcoming -USB support as registers can only be accessed non-atomically. - -Split these into a two stage process: First use the atomic iterator -functions to collect all active interfaces or stations on a list, then -iterate over the list non-atomically and call the iterator on each -entry. - -Signed-off-by: Sascha Hauer -Suggested-by: Ping-Ke shih -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-7-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/phy.c | 6 +- - drivers/net/wireless/realtek/rtw88/ps.c | 2 +- - drivers/net/wireless/realtek/rtw88/util.c | 103 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/util.h | 12 ++- - 4 files changed, 116 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/phy.c -+++ b/drivers/net/wireless/realtek/rtw88/phy.c -@@ -300,7 +300,7 @@ static void rtw_phy_stat_rssi(struct rtw - - data.rtwdev = rtwdev; - data.min_rssi = U8_MAX; -- rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data); -+ rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data); - - dm_info->pre_min_rssi = dm_info->min_rssi; - dm_info->min_rssi = data.min_rssi; -@@ -544,7 +544,7 @@ static void rtw_phy_ra_info_update(struc - if (rtwdev->watch_dog_cnt & 0x3) - return; - -- rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev); -+ rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev); - } - - static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx) -@@ -597,7 +597,7 @@ static void rtw_phy_rrsr_update(struct r - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - - dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX; -- rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev); -+ rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev); - rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min); - } - ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -61,7 +61,7 @@ int rtw_leave_ips(struct rtw_dev *rtwdev - return ret; - } - -- rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev); -+ rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - - rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - ---- a/drivers/net/wireless/realtek/rtw88/util.c -+++ b/drivers/net/wireless/realtek/rtw88/util.c -@@ -105,3 +105,106 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *m - *mcs = rate - DESC_RATEMCS0; - } - } -+ -+struct rtw_stas_entry { -+ struct list_head list; -+ struct ieee80211_sta *sta; -+}; -+ -+struct rtw_iter_stas_data { -+ struct rtw_dev *rtwdev; -+ struct list_head list; -+}; -+ -+static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta) -+{ -+ struct rtw_iter_stas_data *iter_stas = data; -+ struct rtw_stas_entry *stas_entry; -+ -+ stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC); -+ if (!stas_entry) -+ return; -+ -+ stas_entry->sta = sta; -+ list_add_tail(&stas_entry->list, &iter_stas->list); -+} -+ -+void rtw_iterate_stas(struct rtw_dev *rtwdev, -+ void (*iterator)(void *data, -+ struct ieee80211_sta *sta), -+ void *data) -+{ -+ struct rtw_iter_stas_data iter_data; -+ struct rtw_stas_entry *sta_entry, *tmp; -+ -+ /* &rtwdev->mutex makes sure no stations can be removed between -+ * collecting the stations and iterating over them. -+ */ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ iter_data.rtwdev = rtwdev; -+ INIT_LIST_HEAD(&iter_data.list); -+ -+ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter, -+ &iter_data); -+ -+ list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, -+ list) { -+ list_del_init(&sta_entry->list); -+ iterator(data, sta_entry->sta); -+ kfree(sta_entry); -+ } -+} -+ -+struct rtw_vifs_entry { -+ struct list_head list; -+ struct ieee80211_vif *vif; -+ u8 mac[ETH_ALEN]; -+}; -+ -+struct rtw_iter_vifs_data { -+ struct rtw_dev *rtwdev; -+ struct list_head list; -+}; -+ -+static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -+{ -+ struct rtw_iter_vifs_data *iter_stas = data; -+ struct rtw_vifs_entry *vifs_entry; -+ -+ vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC); -+ if (!vifs_entry) -+ return; -+ -+ vifs_entry->vif = vif; -+ ether_addr_copy(vifs_entry->mac, mac); -+ list_add_tail(&vifs_entry->list, &iter_stas->list); -+} -+ -+void rtw_iterate_vifs(struct rtw_dev *rtwdev, -+ void (*iterator)(void *data, u8 *mac, -+ struct ieee80211_vif *vif), -+ void *data) -+{ -+ struct rtw_iter_vifs_data iter_data; -+ struct rtw_vifs_entry *vif_entry, *tmp; -+ -+ /* &rtwdev->mutex makes sure no interfaces can be removed between -+ * collecting the interfaces and iterating over them. -+ */ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ iter_data.rtwdev = rtwdev; -+ INIT_LIST_HEAD(&iter_data.list); -+ -+ ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, -+ IEEE80211_IFACE_ITER_NORMAL, -+ rtw_collect_vif_iter, &iter_data); -+ -+ list_for_each_entry_safe(vif_entry, tmp, &iter_data.list, -+ list) { -+ list_del_init(&vif_entry->list); -+ iterator(data, vif_entry->mac, vif_entry->vif); -+ kfree(vif_entry); -+ } -+} ---- a/drivers/net/wireless/realtek/rtw88/util.h -+++ b/drivers/net/wireless/realtek/rtw88/util.h -@@ -7,9 +7,6 @@ - - struct rtw_dev; - --#define rtw_iterate_vifs(rtwdev, iterator, data) \ -- ieee80211_iterate_active_interfaces(rtwdev->hw, \ -- IEEE80211_IFACE_ITER_NORMAL, iterator, data) - #define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \ - ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \ - IEEE80211_IFACE_ITER_NORMAL, iterator, data) -@@ -20,6 +17,15 @@ struct rtw_dev; - #define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data) \ - ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data) - -+void rtw_iterate_vifs(struct rtw_dev *rtwdev, -+ void (*iterator)(void *data, u8 *mac, -+ struct ieee80211_vif *vif), -+ void *data); -+void rtw_iterate_stas(struct rtw_dev *rtwdev, -+ void (*iterator)(void *data, -+ struct ieee80211_sta *sta), -+ void *data); -+ - static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) - { - __le16 fc = hdr->frame_control; diff --git a/package/kernel/mac80211/patches/rtl/009-wifi-rtw88-Add-common-USB-chip-support.patch b/package/kernel/mac80211/patches/rtl/009-wifi-rtw88-Add-common-USB-chip-support.patch deleted file mode 100644 index 0f5942482..000000000 --- a/package/kernel/mac80211/patches/rtl/009-wifi-rtw88-Add-common-USB-chip-support.patch +++ /dev/null @@ -1,1155 +0,0 @@ -From 173bc31bc0189616c8b09edbbd919493632070ed Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:20 +0100 -Subject: [PATCH 09/13] wifi: rtw88: Add common USB chip support - -Add the common bits and pieces to add USB support to the RTW88 driver. -This is based on https://github.com/ulli-kroll/rtw88-usb.git which -itself is first written by Neo Jou. - -Signed-off-by: neo_jou -Signed-off-by: Hans Ulli Kroll -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-8-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 4 + - drivers/net/wireless/realtek/rtw88/Makefile | 3 + - drivers/net/wireless/realtek/rtw88/mac.c | 3 + - drivers/net/wireless/realtek/rtw88/main.c | 4 + - drivers/net/wireless/realtek/rtw88/main.h | 4 + - drivers/net/wireless/realtek/rtw88/reg.h | 1 + - drivers/net/wireless/realtek/rtw88/tx.h | 31 + - drivers/net/wireless/realtek/rtw88/usb.c | 911 ++++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/usb.h | 107 +++ - 9 files changed, 1068 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/usb.c - create mode 100644 drivers/net/wireless/realtek/rtw88/usb.h - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -19,6 +19,10 @@ config RTW88_PCI - tristate - depends on m - -+config RTW88_USB -+ tristate -+ depends on m -+ - config RTW88_8822B - tristate - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -46,3 +46,6 @@ rtw88_8821ce-objs := rtw8821ce.o - - obj-$(CPTCFG_RTW88_PCI) += rtw88_pci.o - rtw88_pci-objs := pci.o -+ -+obj-$(CPTCFG_RTW88_USB) += rtw88_usb.o -+rtw88_usb-objs := usb.o ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -1058,6 +1058,9 @@ static int txdma_queue_mapping(struct rt - if (rtw_chip_wcpu_11ac(rtwdev)) - rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); - -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) -+ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN); -+ - return 0; - } - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -1783,6 +1783,10 @@ static int rtw_chip_parameter_setup(stru - rtwdev->hci.rpwm_addr = 0x03d9; - rtwdev->hci.cpwm_addr = 0x03da; - break; -+ case RTW_HCI_TYPE_USB: -+ rtwdev->hci.rpwm_addr = 0xfe58; -+ rtwdev->hci.cpwm_addr = 0xfe57; -+ break; - default: - rtw_err(rtwdev, "unsupported hci type\n"); - return -EINVAL; ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -871,6 +871,10 @@ struct rtw_chip_ops { - bool is_tx2_path); - void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, - u8 rx_path, bool is_tx2_path); -+ /* for USB/SDIO only */ -+ void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc); - - /* for coex */ - void (*coex_set_init)(struct rtw_dev *rtwdev); ---- a/drivers/net/wireless/realtek/rtw88/reg.h -+++ b/drivers/net/wireless/realtek/rtw88/reg.h -@@ -184,6 +184,7 @@ - #define BIT_TXDMA_VIQ_MAP(x) \ - (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP) - #define REG_TXDMA_PQ_MAP 0x010C -+#define BIT_RXDMA_ARBBW_EN BIT(0) - #define BIT_SHIFT_TXDMA_BEQ_MAP 8 - #define BIT_MASK_TXDMA_BEQ_MAP 0x3 - #define BIT_TXDMA_BEQ_MAP(x) \ ---- a/drivers/net/wireless/realtek/rtw88/tx.h -+++ b/drivers/net/wireless/realtek/rtw88/tx.h -@@ -71,6 +71,14 @@ - le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) - #define SET_TX_DESC_BT_NULL(txdesc, value) \ - le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) -+#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ -+ le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) -+#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ -+ le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) -+#define GET_TX_DESC_PKT_OFFSET(txdesc) \ -+ le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) -+#define GET_TX_DESC_QSEL(txdesc) \ -+ le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) - - enum rtw_tx_desc_queue_select { - TX_DESC_QSEL_TID0 = 0, -@@ -123,4 +131,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev - struct rtw_tx_pkt_info *pkt_info, - u8 *buf, u32 size); - -+static inline -+void fill_txdesc_checksum_common(u8 *txdesc, size_t words) -+{ -+ __le16 chksum = 0; -+ __le16 *data = (__le16 *)(txdesc); -+ -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); -+ -+ while (words--) -+ chksum ^= *data++; -+ -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); -+} -+ -+static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc) -+{ -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ -+ chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc); -+} -+ - #endif ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -0,0 +1,899 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "debug.h" -+#include "reg.h" -+#include "tx.h" -+#include "rx.h" -+#include "fw.h" -+#include "ps.h" -+#include "usb.h" -+ -+#define RTW_USB_MAX_RXQ_LEN 512 -+ -+struct rtw_usb_txcb { -+ struct rtw_dev *rtwdev; -+ struct sk_buff_head tx_ack_queue; -+}; -+ -+static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, -+ struct sk_buff *skb, int agg_num) -+{ -+ struct rtw_dev *rtwdev = rtwusb->rtwdev; -+ struct rtw_tx_pkt_info pkt_info; -+ -+ SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); -+ pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); -+ rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); -+} -+ -+static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ struct usb_device *udev = rtwusb->udev; -+ __le32 *data; -+ unsigned long flags; -+ int idx, ret; -+ static int count; -+ -+ spin_lock_irqsave(&rtwusb->usb_lock, flags); -+ -+ idx = rtwusb->usb_data_index; -+ rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1); -+ -+ spin_unlock_irqrestore(&rtwusb->usb_lock, flags); -+ -+ data = &rtwusb->usb_data[idx]; -+ -+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), -+ RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr, -+ RTW_USB_VENQT_CMD_IDX, data, len, 1000); -+ if (ret < 0 && ret != -ENODEV && count++ < 4) -+ rtw_err(rtwdev, "read register 0x%x failed with %d\n", -+ addr, ret); -+ -+ return le32_to_cpu(*data); -+} -+ -+static u8 rtw_usb_read8(struct rtw_dev *rtwdev, u32 addr) -+{ -+ return (u8)rtw_usb_read(rtwdev, addr, 1); -+} -+ -+static u16 rtw_usb_read16(struct rtw_dev *rtwdev, u32 addr) -+{ -+ return (u16)rtw_usb_read(rtwdev, addr, 2); -+} -+ -+static u32 rtw_usb_read32(struct rtw_dev *rtwdev, u32 addr) -+{ -+ return (u32)rtw_usb_read(rtwdev, addr, 4); -+} -+ -+static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) -+{ -+ struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv; -+ struct usb_device *udev = rtwusb->udev; -+ unsigned long flags; -+ __le32 *data; -+ int idx, ret; -+ static int count; -+ -+ spin_lock_irqsave(&rtwusb->usb_lock, flags); -+ -+ idx = rtwusb->usb_data_index; -+ rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1); -+ -+ spin_unlock_irqrestore(&rtwusb->usb_lock, flags); -+ -+ data = &rtwusb->usb_data[idx]; -+ -+ *data = cpu_to_le32(val); -+ -+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -+ RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, -+ addr, 0, data, len, 30000); -+ if (ret < 0 && ret != -ENODEV && count++ < 4) -+ rtw_err(rtwdev, "write register 0x%x failed with %d\n", -+ addr, ret); -+} -+ -+static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) -+{ -+ rtw_usb_write(rtwdev, addr, val, 1); -+} -+ -+static void rtw_usb_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) -+{ -+ rtw_usb_write(rtwdev, addr, val, 2); -+} -+ -+static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) -+{ -+ rtw_usb_write(rtwdev, addr, val, 4); -+} -+ -+static int rtw_usb_parse(struct rtw_dev *rtwdev, -+ struct usb_interface *interface) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ struct usb_host_interface *host_interface = &interface->altsetting[0]; -+ struct usb_interface_descriptor *interface_desc = &host_interface->desc; -+ struct usb_endpoint_descriptor *endpoint; -+ struct usb_device *usbd = interface_to_usbdev(interface); -+ int num_out_pipes = 0; -+ int i; -+ u8 num; -+ -+ for (i = 0; i < interface_desc->bNumEndpoints; i++) { -+ endpoint = &host_interface->endpoint[i].desc; -+ num = usb_endpoint_num(endpoint); -+ -+ if (usb_endpoint_dir_in(endpoint) && -+ usb_endpoint_xfer_bulk(endpoint)) { -+ if (rtwusb->pipe_in) { -+ rtw_err(rtwdev, "IN pipes overflow\n"); -+ return -EINVAL; -+ } -+ -+ rtwusb->pipe_in = num; -+ } -+ -+ if (usb_endpoint_dir_in(endpoint) && -+ usb_endpoint_xfer_int(endpoint)) { -+ if (rtwusb->pipe_interrupt) { -+ rtw_err(rtwdev, "INT pipes overflow\n"); -+ return -EINVAL; -+ } -+ -+ rtwusb->pipe_interrupt = num; -+ } -+ -+ if (usb_endpoint_dir_out(endpoint) && -+ usb_endpoint_xfer_bulk(endpoint)) { -+ if (num_out_pipes >= ARRAY_SIZE(rtwusb->out_ep)) { -+ rtw_err(rtwdev, "OUT pipes overflow\n"); -+ return -EINVAL; -+ } -+ -+ rtwusb->out_ep[num_out_pipes++] = num; -+ } -+ } -+ -+ switch (usbd->speed) { -+ case USB_SPEED_LOW: -+ case USB_SPEED_FULL: -+ rtwusb->bulkout_size = RTW_USB_FULL_SPEED_BULK_SIZE; -+ break; -+ case USB_SPEED_HIGH: -+ rtwusb->bulkout_size = RTW_USB_HIGH_SPEED_BULK_SIZE; -+ break; -+ case USB_SPEED_SUPER: -+ rtwusb->bulkout_size = RTW_USB_SUPER_SPEED_BULK_SIZE; -+ break; -+ default: -+ rtw_err(rtwdev, "failed to detect usb speed\n"); -+ return -EINVAL; -+ } -+ -+ rtwdev->hci.bulkout_num = num_out_pipes; -+ -+ switch (num_out_pipes) { -+ case 4: -+ case 3: -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0; -+ break; -+ case 2: -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1; -+ break; -+ case 1: -+ break; -+ default: -+ rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void rtw_usb_write_port_tx_complete(struct urb *urb) -+{ -+ struct rtw_usb_txcb *txcb = urb->context; -+ struct rtw_dev *rtwdev = txcb->rtwdev; -+ struct ieee80211_hw *hw = rtwdev->hw; -+ -+ while (true) { -+ struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue); -+ struct ieee80211_tx_info *info; -+ struct rtw_usb_tx_data *tx_data; -+ -+ if (!skb) -+ break; -+ -+ info = IEEE80211_SKB_CB(skb); -+ tx_data = rtw_usb_get_tx_data(skb); -+ -+ /* enqueue to wait for tx report */ -+ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -+ rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); -+ continue; -+ } -+ -+ /* always ACK for others, then they won't be marked as drop */ -+ ieee80211_tx_info_clear_status(info); -+ if (info->flags & IEEE80211_TX_CTL_NO_ACK) -+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; -+ else -+ info->flags |= IEEE80211_TX_STAT_ACK; -+ -+ ieee80211_tx_status_irqsafe(hw, skb); -+ } -+ -+ kfree(txcb); -+} -+ -+static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel) -+{ -+ if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep)) -+ return 0; -+ -+ return rtwusb->qsel_to_ep[qsel]; -+} -+ -+static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *skb, -+ usb_complete_t cb, void *context) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ struct usb_device *usbd = rtwusb->udev; -+ struct urb *urb; -+ unsigned int pipe; -+ int ret; -+ int ep = qsel_to_ep(rtwusb, qsel); -+ -+ pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]); -+ urb = usb_alloc_urb(0, GFP_ATOMIC); -+ if (!urb) -+ return -ENOMEM; -+ -+ usb_fill_bulk_urb(urb, usbd, pipe, skb->data, skb->len, cb, context); -+ urb->transfer_flags |= URB_ZERO_PACKET; -+ ret = usb_submit_urb(urb, GFP_ATOMIC); -+ -+ usb_free_urb(urb); -+ -+ return ret; -+} -+ -+static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) -+{ -+ struct rtw_dev *rtwdev = rtwusb->rtwdev; -+ struct rtw_usb_txcb *txcb; -+ struct sk_buff *skb_head; -+ struct sk_buff *skb_iter; -+ int agg_num = 0; -+ unsigned int align_next = 0; -+ -+ if (skb_queue_empty(list)) -+ return false; -+ -+ txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC); -+ if (!txcb) -+ return false; -+ -+ txcb->rtwdev = rtwdev; -+ skb_queue_head_init(&txcb->tx_ack_queue); -+ -+ skb_iter = skb_dequeue(list); -+ -+ if (skb_queue_empty(list)) { -+ skb_head = skb_iter; -+ goto queue; -+ } -+ -+ skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ); -+ if (!skb_head) { -+ skb_head = skb_iter; -+ goto queue; -+ } -+ -+ while (skb_iter) { -+ unsigned long flags; -+ -+ skb_put(skb_head, align_next); -+ skb_put_data(skb_head, skb_iter->data, skb_iter->len); -+ -+ align_next = ALIGN(skb_iter->len, 8) - skb_iter->len; -+ -+ agg_num++; -+ -+ skb_queue_tail(&txcb->tx_ack_queue, skb_iter); -+ -+ spin_lock_irqsave(&list->lock, flags); -+ -+ skb_iter = skb_peek(list); -+ -+ if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ) -+ __skb_unlink(skb_iter, list); -+ else -+ skb_iter = NULL; -+ spin_unlock_irqrestore(&list->lock, flags); -+ } -+ -+ if (agg_num > 1) -+ rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num); -+ -+queue: -+ skb_queue_tail(&txcb->tx_ack_queue, skb_head); -+ -+ rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, -+ rtw_usb_write_port_tx_complete, txcb); -+ -+ return true; -+} -+ -+static void rtw_usb_tx_handler(struct work_struct *work) -+{ -+ struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work); -+ int i, limit; -+ -+ for (i = ARRAY_SIZE(rtwusb->tx_queue) - 1; i >= 0; i--) { -+ for (limit = 0; limit < 200; limit++) { -+ struct sk_buff_head *list = &rtwusb->tx_queue[i]; -+ -+ if (!rtw_usb_tx_agg_skb(rtwusb, list)) -+ break; -+ } -+ } -+} -+ -+static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) -+ skb_queue_purge(&rtwusb->tx_queue[i]); -+} -+ -+static void rtw_usb_write_port_complete(struct urb *urb) -+{ -+ struct sk_buff *skb = urb->context; -+ -+ dev_kfree_skb_any(skb); -+} -+ -+static int rtw_usb_write_data(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *buf) -+{ -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ struct sk_buff *skb; -+ unsigned int desclen, headsize, size; -+ u8 qsel; -+ int ret = 0; -+ -+ size = pkt_info->tx_pkt_size; -+ qsel = pkt_info->qsel; -+ desclen = chip->tx_pkt_desc_sz; -+ headsize = pkt_info->offset ? pkt_info->offset : desclen; -+ -+ skb = dev_alloc_skb(headsize + size); -+ if (unlikely(!skb)) -+ return -ENOMEM; -+ -+ skb_reserve(skb, headsize); -+ skb_put_data(skb, buf, size); -+ skb_push(skb, headsize); -+ memset(skb->data, 0, headsize); -+ rtw_tx_fill_tx_desc(pkt_info, skb); -+ rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); -+ -+ ret = rtw_usb_write_port(rtwdev, qsel, skb, -+ rtw_usb_write_port_complete, skb); -+ if (unlikely(ret)) -+ rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret); -+ -+ return ret; -+} -+ -+static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, -+ u32 size) -+{ -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ struct rtw_tx_pkt_info pkt_info = {0}; -+ -+ pkt_info.tx_pkt_size = size; -+ pkt_info.qsel = TX_DESC_QSEL_BEACON; -+ pkt_info.offset = chip->tx_pkt_desc_sz; -+ -+ return rtw_usb_write_data(rtwdev, &pkt_info, buf); -+} -+ -+static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) -+{ -+ struct rtw_tx_pkt_info pkt_info = {0}; -+ -+ pkt_info.tx_pkt_size = size; -+ pkt_info.qsel = TX_DESC_QSEL_H2C; -+ -+ return rtw_usb_write_data(rtwdev, &pkt_info, buf); -+} -+ -+static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb) -+{ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ __le16 fc = hdr->frame_control; -+ u8 qsel; -+ -+ if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) -+ qsel = TX_DESC_QSEL_MGMT; -+ else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) -+ qsel = skb->priority; -+ else -+ qsel = TX_DESC_QSEL_BEACON; -+ -+ return qsel; -+} -+ -+static int rtw_usb_tx_write(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ struct sk_buff *skb) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ struct rtw_usb_tx_data *tx_data; -+ u8 *pkt_desc; -+ int ep; -+ -+ pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb); -+ pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); -+ memset(pkt_desc, 0, chip->tx_pkt_desc_sz); -+ ep = qsel_to_ep(rtwusb, pkt_info->qsel); -+ rtw_tx_fill_tx_desc(pkt_info, skb); -+ rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); -+ tx_data = rtw_usb_get_tx_data(skb); -+ tx_data->sn = pkt_info->sn; -+ -+ skb_queue_tail(&rtwusb->tx_queue[ep], skb); -+ -+ return 0; -+} -+ -+static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ -+ queue_work(rtwusb->txwq, &rtwusb->tx_work); -+} -+ -+static void rtw_usb_rx_handler(struct work_struct *work) -+{ -+ struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); -+ struct rtw_dev *rtwdev = rtwusb->rtwdev; -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ struct rtw_rx_pkt_stat pkt_stat; -+ struct ieee80211_rx_status rx_status; -+ struct sk_buff *skb; -+ u32 pkt_desc_sz = chip->rx_pkt_desc_sz; -+ u32 pkt_offset; -+ u8 *rx_desc; -+ int limit; -+ -+ for (limit = 0; limit < 200; limit++) { -+ skb = skb_dequeue(&rtwusb->rx_queue); -+ if (!skb) -+ break; -+ -+ rx_desc = skb->data; -+ chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, -+ &rx_status); -+ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + -+ pkt_stat.shift; -+ -+ if (pkt_stat.is_c2h) { -+ skb_put(skb, pkt_stat.pkt_len + pkt_offset); -+ rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); -+ continue; -+ } -+ -+ if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { -+ rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); -+ dev_kfree_skb_any(skb); -+ continue; -+ } -+ -+ skb_put(skb, pkt_stat.pkt_len); -+ skb_reserve(skb, pkt_offset); -+ memcpy(skb->cb, &rx_status, sizeof(rx_status)); -+ ieee80211_rx_irqsafe(rtwdev->hw, skb); -+ } -+} -+ -+static void rtw_usb_read_port_complete(struct urb *urb); -+ -+static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb) -+{ -+ struct rtw_dev *rtwdev = rtwusb->rtwdev; -+ int error; -+ -+ rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC); -+ if (!rxcb->rx_skb) -+ return; -+ -+ usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, -+ usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in), -+ rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ, -+ rtw_usb_read_port_complete, rxcb); -+ -+ error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC); -+ if (error) { -+ kfree_skb(rxcb->rx_skb); -+ if (error != -ENODEV) -+ rtw_err(rtwdev, "Err sending rx data urb %d\n", -+ error); -+ } -+} -+ -+static void rtw_usb_read_port_complete(struct urb *urb) -+{ -+ struct rx_usb_ctrl_block *rxcb = urb->context; -+ struct rtw_dev *rtwdev = rxcb->rtwdev; -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ struct sk_buff *skb = rxcb->rx_skb; -+ -+ if (urb->status == 0) { -+ if (urb->actual_length >= RTW_USB_MAX_RECVBUF_SZ || -+ urb->actual_length < 24) { -+ rtw_err(rtwdev, "failed to get urb length:%d\n", -+ urb->actual_length); -+ if (skb) -+ dev_kfree_skb_any(skb); -+ } else { -+ skb_queue_tail(&rtwusb->rx_queue, skb); -+ queue_work(rtwusb->rxwq, &rtwusb->rx_work); -+ } -+ rtw_usb_rx_resubmit(rtwusb, rxcb); -+ } else { -+ switch (urb->status) { -+ case -EINVAL: -+ case -EPIPE: -+ case -ENODEV: -+ case -ESHUTDOWN: -+ case -ENOENT: -+ case -EPROTO: -+ case -EILSEQ: -+ case -ETIME: -+ case -ECOMM: -+ case -EOVERFLOW: -+ case -EINPROGRESS: -+ break; -+ default: -+ rtw_err(rtwdev, "status %d\n", urb->status); -+ break; -+ } -+ if (skb) -+ dev_kfree_skb_any(skb); -+ } -+} -+ -+static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb) -+{ -+ struct rx_usb_ctrl_block *rxcb; -+ int i; -+ -+ for (i = 0; i < RTW_USB_RXCB_NUM; i++) { -+ rxcb = &rtwusb->rx_cb[i]; -+ if (rxcb->rx_urb) -+ usb_kill_urb(rxcb->rx_urb); -+ } -+} -+ -+static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb) -+{ -+ struct rx_usb_ctrl_block *rxcb; -+ int i; -+ -+ for (i = 0; i < RTW_USB_RXCB_NUM; i++) { -+ rxcb = &rtwusb->rx_cb[i]; -+ if (rxcb->rx_urb) { -+ usb_kill_urb(rxcb->rx_urb); -+ usb_free_urb(rxcb->rx_urb); -+ } -+ } -+} -+ -+static int rtw_usb_alloc_rx_bufs(struct rtw_usb *rtwusb) -+{ -+ int i; -+ -+ for (i = 0; i < RTW_USB_RXCB_NUM; i++) { -+ struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; -+ -+ rxcb->n = i; -+ rxcb->rtwdev = rtwusb->rtwdev; -+ rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!rxcb->rx_urb) -+ goto err; -+ } -+ -+ return 0; -+err: -+ rtw_usb_free_rx_bufs(rtwusb); -+ return -ENOMEM; -+} -+ -+static int rtw_usb_setup(struct rtw_dev *rtwdev) -+{ -+ /* empty function for rtw_hci_ops */ -+ return 0; -+} -+ -+static int rtw_usb_start(struct rtw_dev *rtwdev) -+{ -+ return 0; -+} -+ -+static void rtw_usb_stop(struct rtw_dev *rtwdev) -+{ -+} -+ -+static void rtw_usb_deep_ps(struct rtw_dev *rtwdev, bool enter) -+{ -+ /* empty function for rtw_hci_ops */ -+} -+ -+static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter) -+{ -+ /* empty function for rtw_hci_ops */ -+} -+ -+static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev) -+{ -+ /* empty function for rtw_hci_ops */ -+} -+ -+static struct rtw_hci_ops rtw_usb_ops = { -+ .tx_write = rtw_usb_tx_write, -+ .tx_kick_off = rtw_usb_tx_kick_off, -+ .setup = rtw_usb_setup, -+ .start = rtw_usb_start, -+ .stop = rtw_usb_stop, -+ .deep_ps = rtw_usb_deep_ps, -+ .link_ps = rtw_usb_link_ps, -+ .interface_cfg = rtw_usb_interface_cfg, -+ -+ .write8 = rtw_usb_write8, -+ .write16 = rtw_usb_write16, -+ .write32 = rtw_usb_write32, -+ .read8 = rtw_usb_read8, -+ .read16 = rtw_usb_read16, -+ .read32 = rtw_usb_read32, -+ -+ .write_data_rsvd_page = rtw_usb_write_data_rsvd_page, -+ .write_data_h2c = rtw_usb_write_data_h2c, -+}; -+ -+static int rtw_usb_init_rx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ int i; -+ -+ rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq"); -+ if (!rtwusb->rxwq) { -+ rtw_err(rtwdev, "failed to create RX work queue\n"); -+ return -ENOMEM; -+ } -+ -+ skb_queue_head_init(&rtwusb->rx_queue); -+ -+ INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler); -+ -+ for (i = 0; i < RTW_USB_RXCB_NUM; i++) { -+ struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; -+ -+ rtw_usb_rx_resubmit(rtwusb, rxcb); -+ } -+ -+ return 0; -+} -+ -+static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ -+ skb_queue_purge(&rtwusb->rx_queue); -+ -+ flush_workqueue(rtwusb->rxwq); -+ destroy_workqueue(rtwusb->rxwq); -+} -+ -+static int rtw_usb_init_tx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ int i; -+ -+ rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq"); -+ if (!rtwusb->txwq) { -+ rtw_err(rtwdev, "failed to create TX work queue\n"); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) -+ skb_queue_head_init(&rtwusb->tx_queue[i]); -+ -+ INIT_WORK(&rtwusb->tx_work, rtw_usb_tx_handler); -+ -+ return 0; -+} -+ -+static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ -+ rtw_usb_tx_queue_purge(rtwusb); -+ flush_workqueue(rtwusb->txwq); -+ destroy_workqueue(rtwusb->txwq); -+} -+ -+static int rtw_usb_intf_init(struct rtw_dev *rtwdev, -+ struct usb_interface *intf) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf)); -+ int ret; -+ -+ rtwusb->udev = udev; -+ ret = rtw_usb_parse(rtwdev, intf); -+ if (ret) -+ return ret; -+ -+ rtwusb->usb_data = kcalloc(RTW_USB_MAX_RXTX_COUNT, sizeof(u32), -+ GFP_KERNEL); -+ if (!rtwusb->usb_data) -+ return -ENOMEM; -+ -+ usb_set_intfdata(intf, rtwdev->hw); -+ -+ SET_IEEE80211_DEV(rtwdev->hw, &intf->dev); -+ spin_lock_init(&rtwusb->usb_lock); -+ -+ return 0; -+} -+ -+static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev, -+ struct usb_interface *intf) -+{ -+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); -+ -+ usb_put_dev(rtwusb->udev); -+ usb_set_intfdata(intf, NULL); -+} -+ -+int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) -+{ -+ struct rtw_dev *rtwdev; -+ struct ieee80211_hw *hw; -+ struct rtw_usb *rtwusb; -+ int drv_data_size; -+ int ret; -+ -+ drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_usb); -+ hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops); -+ if (!hw) -+ return -ENOMEM; -+ -+ rtwdev = hw->priv; -+ rtwdev->hw = hw; -+ rtwdev->dev = &intf->dev; -+ rtwdev->chip = (struct rtw_chip_info *)id->driver_info; -+ rtwdev->hci.ops = &rtw_usb_ops; -+ rtwdev->hci.type = RTW_HCI_TYPE_USB; -+ -+ rtwusb = rtw_get_usb_priv(rtwdev); -+ rtwusb->rtwdev = rtwdev; -+ -+ ret = rtw_usb_alloc_rx_bufs(rtwusb); -+ if (ret) -+ return ret; -+ -+ ret = rtw_core_init(rtwdev); -+ if (ret) -+ goto err_release_hw; -+ -+ ret = rtw_usb_intf_init(rtwdev, intf); -+ if (ret) { -+ rtw_err(rtwdev, "failed to init USB interface\n"); -+ goto err_deinit_core; -+ } -+ -+ ret = rtw_usb_init_tx(rtwdev); -+ if (ret) { -+ rtw_err(rtwdev, "failed to init USB TX\n"); -+ goto err_destroy_usb; -+ } -+ -+ ret = rtw_usb_init_rx(rtwdev); -+ if (ret) { -+ rtw_err(rtwdev, "failed to init USB RX\n"); -+ goto err_destroy_txwq; -+ } -+ -+ ret = rtw_chip_info_setup(rtwdev); -+ if (ret) { -+ rtw_err(rtwdev, "failed to setup chip information\n"); -+ goto err_destroy_rxwq; -+ } -+ -+ ret = rtw_register_hw(rtwdev, rtwdev->hw); -+ if (ret) { -+ rtw_err(rtwdev, "failed to register hw\n"); -+ goto err_destroy_rxwq; -+ } -+ -+ return 0; -+ -+err_destroy_rxwq: -+ rtw_usb_deinit_rx(rtwdev); -+ -+err_destroy_txwq: -+ rtw_usb_deinit_tx(rtwdev); -+ -+err_destroy_usb: -+ rtw_usb_intf_deinit(rtwdev, intf); -+ -+err_deinit_core: -+ rtw_core_deinit(rtwdev); -+ -+err_release_hw: -+ ieee80211_free_hw(hw); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rtw_usb_probe); -+ -+void rtw_usb_disconnect(struct usb_interface *intf) -+{ -+ struct ieee80211_hw *hw = usb_get_intfdata(intf); -+ struct rtw_dev *rtwdev; -+ struct rtw_usb *rtwusb; -+ -+ if (!hw) -+ return; -+ -+ rtwdev = hw->priv; -+ rtwusb = rtw_get_usb_priv(rtwdev); -+ -+ rtw_usb_cancel_rx_bufs(rtwusb); -+ -+ rtw_unregister_hw(rtwdev, hw); -+ rtw_usb_deinit_tx(rtwdev); -+ rtw_usb_deinit_rx(rtwdev); -+ -+ if (rtwusb->udev->state != USB_STATE_NOTATTACHED) -+ usb_reset_device(rtwusb->udev); -+ -+ rtw_usb_free_rx_bufs(rtwusb); -+ -+ rtw_usb_intf_deinit(rtwdev, intf); -+ rtw_core_deinit(rtwdev); -+ ieee80211_free_hw(hw); -+} -+EXPORT_SYMBOL(rtw_usb_disconnect); -+ -+MODULE_AUTHOR("Realtek Corporation"); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless USB driver"); -+MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/usb.h -@@ -0,0 +1,107 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#ifndef __RTW_USB_H_ -+#define __RTW_USB_H_ -+ -+#define FW_8192C_START_ADDRESS 0x1000 -+#define FW_8192C_END_ADDRESS 0x5fff -+ -+#define RTW_USB_MAX_RXTX_COUNT 128 -+#define RTW_USB_VENQT_MAX_BUF_SIZE 254 -+#define MAX_USBCTRL_VENDORREQ_TIMES 10 -+ -+#define RTW_USB_CMD_READ 0xc0 -+#define RTW_USB_CMD_WRITE 0x40 -+#define RTW_USB_CMD_REQ 0x05 -+ -+#define RTW_USB_VENQT_CMD_IDX 0x00 -+ -+#define RTW_USB_SUPER_SPEED_BULK_SIZE 1024 -+#define RTW_USB_HIGH_SPEED_BULK_SIZE 512 -+#define RTW_USB_FULL_SPEED_BULK_SIZE 64 -+ -+#define RTW_USB_TX_SEL_HQ BIT(0) -+#define RTW_USB_TX_SEL_LQ BIT(1) -+#define RTW_USB_TX_SEL_NQ BIT(2) -+#define RTW_USB_TX_SEL_EQ BIT(3) -+ -+#define RTW_USB_BULK_IN_ADDR 0x80 -+#define RTW_USB_INT_IN_ADDR 0x81 -+ -+#define RTW_USB_HW_QUEUE_ENTRY 8 -+ -+#define RTW_USB_PACKET_OFFSET_SZ 8 -+#define RTW_USB_MAX_XMITBUF_SZ (1024 * 20) -+#define RTW_USB_MAX_RECVBUF_SZ 32768 -+ -+#define RTW_USB_RECVBUFF_ALIGN_SZ 8 -+ -+#define RTW_USB_RXAGG_SIZE 6 -+#define RTW_USB_RXAGG_TIMEOUT 10 -+ -+#define RTW_USB_RXCB_NUM 4 -+ -+#define RTW_USB_EP_MAX 4 -+ -+#define TX_DESC_QSEL_MAX 20 -+ -+#define RTW_USB_VENDOR_ID_REALTEK 0x0bda -+ -+static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev) -+{ -+ return (struct rtw_usb *)rtwdev->priv; -+} -+ -+struct rx_usb_ctrl_block { -+ struct rtw_dev *rtwdev; -+ struct urb *rx_urb; -+ struct sk_buff *rx_skb; -+ int n; -+}; -+ -+struct rtw_usb_tx_data { -+ u8 sn; -+}; -+ -+struct rtw_usb { -+ struct rtw_dev *rtwdev; -+ struct usb_device *udev; -+ -+ /* protects usb_data_index */ -+ spinlock_t usb_lock; -+ __le32 *usb_data; -+ unsigned int usb_data_index; -+ -+ u32 bulkout_size; -+ u8 pipe_interrupt; -+ u8 pipe_in; -+ u8 out_ep[RTW_USB_EP_MAX]; -+ u8 qsel_to_ep[TX_DESC_QSEL_MAX]; -+ u8 usb_txagg_num; -+ -+ struct workqueue_struct *txwq, *rxwq; -+ -+ struct sk_buff_head tx_queue[RTW_USB_EP_MAX]; -+ struct work_struct tx_work; -+ -+ struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM]; -+ struct sk_buff_head rx_queue; -+ struct work_struct rx_work; -+}; -+ -+static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ -+ BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) > -+ sizeof(info->status.status_driver_data)); -+ -+ return (struct rtw_usb_tx_data *)info->status.status_driver_data; -+} -+ -+int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); -+void rtw_usb_disconnect(struct usb_interface *intf); -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/010-wifi-rtw88-Add-rtw8821cu-chipset-support.patch b/package/kernel/mac80211/patches/rtl/010-wifi-rtw88-Add-rtw8821cu-chipset-support.patch deleted file mode 100644 index 17c9bb16b..000000000 --- a/package/kernel/mac80211/patches/rtl/010-wifi-rtw88-Add-rtw8821cu-chipset-support.patch +++ /dev/null @@ -1,197 +0,0 @@ -From ee542f62f5ba5cf88a21e638b387c9a3b85687a5 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:21 +0100 -Subject: [PATCH 10/13] wifi: rtw88: Add rtw8821cu chipset support - -Add support for the rtw8821cu chipset based on -https://github.com/ulli-kroll/rtw88-usb.git - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-9-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 11 ++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 18 +++++++ - drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++++++ - .../net/wireless/realtek/rtw88/rtw8821cu.c | 50 +++++++++++++++++++ - 5 files changed, 103 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cu.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -87,6 +87,17 @@ config RTW88_8821CE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8821CU -+ tristate "Realtek 8821CU USB wireless network adapter" -+ depends on USB -+ select RTW88_CORE -+ select RTW88_USB -+ select RTW88_8821C -+ help -+ Select this option will enable support for 8821CU chipset -+ -+ 802.11ac USB wireless network adapter -+ - config RTW88_DEBUG - bool "Realtek rtw88 debug support" - depends on RTW88_CORE ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -44,6 +44,9 @@ rtw88_8821c-objs := rtw8821c.o rtw8821c - obj-$(CPTCFG_RTW88_8821CE) += rtw88_8821ce.o - rtw88_8821ce-objs := rtw8821ce.o - -+obj-$(CPTCFG_RTW88_8821CU) += rtw88_8821cu.o -+rtw88_8821cu-objs := rtw8821cu.o -+ - obj-$(CPTCFG_RTW88_PCI) += rtw88_pci.o - rtw88_pci-objs := pci.o - ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -26,6 +26,12 @@ static void rtw8821ce_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->e.mac_addr); - } - -+static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8821c_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->u.mac_addr); -+} -+ - enum rtw8821ce_rf_set { - SWITCH_TO_BTG, - SWITCH_TO_WLG, -@@ -68,6 +74,9 @@ static int rtw8821c_read_efuse(struct rt - case RTW_HCI_TYPE_PCIE: - rtw8821ce_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_USB: -+ rtw8821cu_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; -@@ -1148,6 +1157,13 @@ static void rtw8821c_phy_cck_pd_set(stru - dm_info->cck_pd_default + new_lvl * 2); - } - -+static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc) -+{ -+ fill_txdesc_checksum_common(txdesc, 16); -+} -+ - static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { - {0x0086, - RTW_PWR_CUT_ALL_MSK, -@@ -1521,6 +1537,7 @@ static const struct rtw_rfe_def rtw8821c - [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), - [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), - [6] = RTW_DEF_RFE(8821c, 0, 0), -+ [34] = RTW_DEF_RFE(8821c, 0, 0), - }; - - static struct rtw_hw_reg rtw8821c_dig[] = { -@@ -1595,6 +1612,7 @@ static struct rtw_chip_ops rtw8821c_ops - .config_bfee = rtw8821c_bf_config_bfee, - .set_gid_table = rtw_bf_set_gid_table, - .cfg_csi_rate = rtw_bf_cfg_csi_rate, -+ .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, - - .coex_set_init = rtw8821c_coex_cfg_init, - .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch, ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h -@@ -9,6 +9,26 @@ - - #define RCR_VHT_ACK BIT(26) - -+struct rtw8821cu_efuse { -+ u8 res4[4]; /* 0xd0 */ -+ u8 usb_optional_function; -+ u8 res5[0x1e]; -+ u8 res6[2]; -+ u8 serial[0x0b]; /* 0xf5 */ -+ u8 vid; /* 0x100 */ -+ u8 res7; -+ u8 pid; -+ u8 res8[4]; -+ u8 mac_addr[ETH_ALEN]; /* 0x107 */ -+ u8 res9[2]; -+ u8 vendor_name[0x07]; -+ u8 res10[2]; -+ u8 device_name[0x14]; -+ u8 res11[0xcf]; -+ u8 package_type; /* 0x1fb */ -+ u8 res12[0x4]; -+}; -+ - struct rtw8821ce_efuse { - u8 mac_addr[ETH_ALEN]; /* 0xd0 */ - u8 vender_id[2]; -@@ -73,6 +93,7 @@ struct rtw8821c_efuse { - u8 res[3]; - union { - struct rtw8821ce_efuse e; -+ struct rtw8821cu_efuse u; - }; - }; - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c -@@ -0,0 +1,50 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include "main.h" -+#include "rtw8821c.h" -+#include "usb.h" -+ -+static const struct usb_device_id rtw_8821cu_id_table[] = { -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TOTOLINK A650UA v3 */ -+ {}, -+}; -+MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); -+ -+static int rtw_8821cu_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ return rtw_usb_probe(intf, id); -+} -+ -+static struct usb_driver rtw_8821cu_driver = { -+ .name = "rtw_8821cu", -+ .id_table = rtw_8821cu_id_table, -+ .probe = rtw_8821cu_probe, -+ .disconnect = rtw_usb_disconnect, -+}; -+module_usb_driver(rtw_8821cu_driver); -+ -+MODULE_AUTHOR("Hans Ulli Kroll "); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/011-wifi-rtw88-Add-rtw8822bu-chipset-support.patch b/package/kernel/mac80211/patches/rtl/011-wifi-rtw88-Add-rtw8822bu-chipset-support.patch deleted file mode 100644 index 6fe4e9749..000000000 --- a/package/kernel/mac80211/patches/rtl/011-wifi-rtw88-Add-rtw8822bu-chipset-support.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 02fbb82275b164606edd12fa03e10a3e5a070b02 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:22 +0100 -Subject: [PATCH 11/13] wifi: rtw88: Add rtw8822bu chipset support - -Add support for the rtw8822bu chipset based on -https://github.com/ulli-kroll/rtw88-usb.git - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-10-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 12 +++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 + - drivers/net/wireless/realtek/rtw88/rtw8822b.c | 19 ++++ - .../net/wireless/realtek/rtw88/rtw8822bu.c | 90 +++++++++++++++++++ - 4 files changed, 124 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bu.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -51,6 +51,18 @@ config RTW88_8822BE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8822BU -+ tristate "Realtek 8822BU USB wireless network adapter" -+ depends on m -+ depends on USB -+ select RTW88_CORE -+ select RTW88_USB -+ select RTW88_8822B -+ help -+ Select this option will enable support for 8822BU chipset -+ -+ 802.11ac USB wireless network adapter -+ - config RTW88_8822CE - tristate "Realtek 8822CE PCI wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -26,6 +26,9 @@ rtw88_8822b-objs := rtw8822b.o rtw8822b - obj-$(CPTCFG_RTW88_8822BE) += rtw88_8822be.o - rtw88_8822be-objs := rtw8822be.o - -+obj-$(CPTCFG_RTW88_8822BU) += rtw88_8822bu.o -+rtw88_8822bu-objs := rtw8822bu.o -+ - obj-$(CPTCFG_RTW88_8822C) += rtw88_8822c.o - rtw88_8822c-objs := rtw8822c.o rtw8822c_table.o - ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c -@@ -26,6 +26,12 @@ static void rtw8822be_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->e.mac_addr); - } - -+static void rtw8822bu_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8822b_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->u.mac_addr); -+} -+ - static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -56,6 +62,9 @@ static int rtw8822b_read_efuse(struct rt - case RTW_HCI_TYPE_PCIE: - rtw8822be_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_USB: -+ rtw8822bu_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; -@@ -1588,6 +1597,15 @@ static void rtw8822b_adaptivity(struct r - rtw_phy_set_edcca_th(rtwdev, l2h, h2l); - } - -+static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc) -+{ -+ size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ -+ -+ fill_txdesc_checksum_common(txdesc, words); -+} -+ - static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = { - {0x0086, - RTW_PWR_CUT_ALL_MSK, -@@ -2163,6 +2181,7 @@ static struct rtw_chip_ops rtw8822b_ops - .cfg_csi_rate = rtw_bf_cfg_csi_rate, - .adaptivity_init = rtw8822b_adaptivity_init, - .adaptivity = rtw8822b_adaptivity, -+ .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, - - .coex_set_init = rtw8822b_coex_cfg_init, - .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch, ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c -@@ -0,0 +1,90 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include "main.h" -+#include "rtw8822b.h" -+#include "usb.h" -+ -+static const struct usb_device_id rtw_8822bu_id_table[] = { -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ -+ {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ -+ {}, -+}; -+MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); -+ -+static int rtw8822bu_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ return rtw_usb_probe(intf, id); -+} -+ -+static struct usb_driver rtw_8822bu_driver = { -+ .name = "rtw_8822bu", -+ .id_table = rtw_8822bu_id_table, -+ .probe = rtw8822bu_probe, -+ .disconnect = rtw_usb_disconnect, -+}; -+module_usb_driver(rtw_8822bu_driver); -+ -+MODULE_AUTHOR("Realtek Corporation"); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/012-wifi-rtw88-Add-rtw8822cu-chipset-support.patch b/package/kernel/mac80211/patches/rtl/012-wifi-rtw88-Add-rtw8822cu-chipset-support.patch deleted file mode 100644 index 438127b9d..000000000 --- a/package/kernel/mac80211/patches/rtl/012-wifi-rtw88-Add-rtw8822cu-chipset-support.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 39c7486c66bd76d182c0ad02d440d7207bccb89e Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:23 +0100 -Subject: [PATCH 12/13] wifi: rtw88: Add rtw8822cu chipset support - -Add support for the rtw8822cu chipset based on -https://github.com/ulli-kroll/rtw88-usb.git - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-11-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 12 +++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - drivers/net/wireless/realtek/rtw88/rtw8822c.c | 24 ++++++++++ - .../net/wireless/realtek/rtw88/rtw8822cu.c | 44 +++++++++++++++++++ - 4 files changed, 83 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cu.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -75,6 +75,18 @@ config RTW88_8822CE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8822CU -+ tristate "Realtek 8822CU USB wireless network adapter" -+ depends on m -+ depends on USB -+ select RTW88_CORE -+ select RTW88_USB -+ select RTW88_8822C -+ help -+ Select this option will enable support for 8822CU chipset -+ -+ 802.11ac USB wireless network adapter -+ - config RTW88_8723DE - tristate "Realtek 8723DE PCI wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -35,6 +35,9 @@ rtw88_8822c-objs := rtw8822c.o rtw8822c - obj-$(CPTCFG_RTW88_8822CE) += rtw88_8822ce.o - rtw88_8822ce-objs := rtw8822ce.o - -+obj-$(CPTCFG_RTW88_8822CU) += rtw88_8822cu.o -+rtw88_8822cu-objs := rtw8822cu.o -+ - obj-$(CPTCFG_RTW88_8723D) += rtw88_8723d.o - rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o - ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c -@@ -29,6 +29,12 @@ static void rtw8822ce_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->e.mac_addr); - } - -+static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8822c_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->u.mac_addr); -+} -+ - static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -58,6 +64,9 @@ static int rtw8822c_read_efuse(struct rt - case RTW_HCI_TYPE_PCIE: - rtw8822ce_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_USB: -+ rtw8822cu_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; -@@ -4557,6 +4566,18 @@ static void rtw8822c_adaptivity(struct r - rtw_phy_set_edcca_th(rtwdev, l2h, h2l); - } - -+static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc) -+{ -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ size_t words; -+ -+ words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2; -+ -+ fill_txdesc_checksum_common(txdesc, words); -+} -+ - static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { - {0x0086, - RTW_PWR_CUT_ALL_MSK, -@@ -4895,6 +4916,8 @@ static const struct rtw_rfe_def rtw8822c - [0] = RTW_DEF_RFE(8822c, 0, 0), - [1] = RTW_DEF_RFE(8822c, 0, 0), - [2] = RTW_DEF_RFE(8822c, 0, 0), -+ [3] = RTW_DEF_RFE(8822c, 0, 0), -+ [4] = RTW_DEF_RFE(8822c, 0, 0), - [5] = RTW_DEF_RFE(8822c, 0, 5), - [6] = RTW_DEF_RFE(8822c, 0, 0), - }; -@@ -4978,6 +5001,7 @@ static struct rtw_chip_ops rtw8822c_ops - .cfo_track = rtw8822c_cfo_track, - .config_tx_path = rtw8822c_config_tx_path, - .config_txrx_mode = rtw8822c_config_trx_mode, -+ .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, - - .coex_set_init = rtw8822c_coex_cfg_init, - .coex_set_ant_switch = NULL, ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c -@@ -0,0 +1,44 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include "main.h" -+#include "rtw8822c.h" -+#include "usb.h" -+ -+static const struct usb_device_id rtw_8822cu_id_table[] = { -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */ -+ {}, -+}; -+MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table); -+ -+static int rtw8822bu_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ return rtw_usb_probe(intf, id); -+} -+ -+static struct usb_driver rtw_8822cu_driver = { -+ .name = "rtw_8822cu", -+ .id_table = rtw_8822cu_id_table, -+ .probe = rtw8822bu_probe, -+ .disconnect = rtw_usb_disconnect, -+}; -+module_usb_driver(rtw_8822cu_driver); -+ -+MODULE_AUTHOR("Realtek Corporation"); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/013-wifi-rtw88-Add-rtw8723du-chipset-support.patch b/package/kernel/mac80211/patches/rtl/013-wifi-rtw88-Add-rtw8723du-chipset-support.patch deleted file mode 100644 index b1ebdb3d8..000000000 --- a/package/kernel/mac80211/patches/rtl/013-wifi-rtw88-Add-rtw8723du-chipset-support.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 8f9245f0ac82177554d990f12d5a9071db6305e4 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Fri, 2 Dec 2022 09:12:24 +0100 -Subject: [PATCH 13/13] wifi: rtw88: Add rtw8723du chipset support - -Add support for the rtw8723du chipset based on -https://github.com/ulli-kroll/rtw88-usb.git - -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202081224.2779981-12-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 13 +++++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - drivers/net/wireless/realtek/rtw88/rtw8723d.c | 28 +++++++++++++++ - drivers/net/wireless/realtek/rtw88/rtw8723d.h | 13 ++++++- - .../net/wireless/realtek/rtw88/rtw8723du.c | 36 +++++++++++++++++++ - 5 files changed, 92 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723du.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -99,6 +99,18 @@ config RTW88_8723DE - - 802.11n PCIe wireless network adapter - -+config RTW88_8723DU -+ tristate "Realtek 8723DU USB wireless network adapter" -+ depends on m -+ depends on USB -+ select RTW88_CORE -+ select RTW88_USB -+ select RTW88_8723D -+ help -+ Select this option will enable support for 8723DU chipset -+ -+ 802.11n USB wireless network adapter -+ - config RTW88_8821CE - tristate "Realtek 8821CE PCI wireless network adapter" - depends on m -@@ -113,6 +125,7 @@ config RTW88_8821CE - - config RTW88_8821CU - tristate "Realtek 8821CU USB wireless network adapter" -+ depends on m - depends on USB - select RTW88_CORE - select RTW88_USB ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -44,6 +44,9 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d - obj-$(CPTCFG_RTW88_8723DE) += rtw88_8723de.o - rtw88_8723de-objs := rtw8723de.o - -+obj-$(CPTCFG_RTW88_8723DU) += rtw88_8723du.o -+rtw88_8723du-objs := rtw8723du.o -+ - obj-$(CPTCFG_RTW88_8821C) += rtw88_8821c.o - rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o - ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -@@ -210,6 +210,12 @@ static void rtw8723de_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->e.mac_addr); - } - -+static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8723d_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->u.mac_addr); -+} -+ - static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -239,6 +245,9 @@ static int rtw8723d_read_efuse(struct rt - case RTW_HCI_TYPE_PCIE: - rtw8723de_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_USB: -+ rtw8723du_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; -@@ -1945,6 +1954,24 @@ static void rtw8723d_pwr_track(struct rt - dm_info->pwr_trk_triggered = false; - } - -+static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ u8 *txdesc) -+{ -+ size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ -+ __le16 chksum = 0; -+ __le16 *data = (__le16 *)(txdesc); -+ -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); -+ -+ while (words--) -+ chksum ^= *data++; -+ -+ chksum = ~chksum; -+ -+ SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); -+} -+ - static struct rtw_chip_ops rtw8723d_ops = { - .phy_set_param = rtw8723d_phy_set_param, - .read_efuse = rtw8723d_read_efuse, -@@ -1965,6 +1992,7 @@ static struct rtw_chip_ops rtw8723d_ops - .config_bfee = NULL, - .set_gid_table = NULL, - .cfg_csi_rate = NULL, -+ .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum, - - .coex_set_init = rtw8723d_coex_cfg_init, - .coex_set_ant_switch = NULL, ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h -@@ -41,6 +41,14 @@ struct rtw8723de_efuse { - u8 sub_device_id[2]; - }; - -+struct rtw8723du_efuse { -+ u8 res4[48]; /* 0xd0 */ -+ u8 vender_id[2]; /* 0x100 */ -+ u8 product_id[2]; /* 0x102 */ -+ u8 usb_option; /* 0x104 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x107 */ -+}; -+ - struct rtw8723d_efuse { - __le16 rtl_id; - u8 rsvd[2]; -@@ -69,7 +77,10 @@ struct rtw8723d_efuse { - u8 rfe_option; - u8 country_code[2]; - u8 res[3]; -- struct rtw8723de_efuse e; -+ union { -+ struct rtw8723de_efuse e; -+ struct rtw8723du_efuse u; -+ }; - }; - - extern const struct rtw_chip_info rtw8723d_hw_spec; ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723du.c -@@ -0,0 +1,36 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include "main.h" -+#include "rtw8723d.h" -+#include "usb.h" -+ -+static const struct usb_device_id rtw_8723du_id_table[] = { -+ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd723, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* 8723DU 1*1 */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd611, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* Edimax EW-7611ULB V2 */ -+ { }, -+}; -+MODULE_DEVICE_TABLE(usb, rtw_8723du_id_table); -+ -+static int rtw8723du_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ return rtw_usb_probe(intf, id); -+} -+ -+static struct usb_driver rtw_8723du_driver = { -+ .name = "rtw_8723du", -+ .id_table = rtw_8723du_id_table, -+ .probe = rtw8723du_probe, -+ .disconnect = rtw_usb_disconnect, -+}; -+module_usb_driver(rtw_8723du_driver); -+ -+MODULE_AUTHOR("Hans Ulli Kroll "); -+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/014-backports-rtw88-21cu-22cu-22bu-8723du.patch b/package/kernel/mac80211/patches/rtl/014-backports-rtw88-21cu-22cu-22bu-8723du.patch deleted file mode 100644 index d453f05ad..000000000 --- a/package/kernel/mac80211/patches/rtl/014-backports-rtw88-21cu-22cu-22bu-8723du.patch +++ /dev/null @@ -1,70 +0,0 @@ ---- a/Kconfig.local -+++ b/Kconfig.local -@@ -1135,15 +1135,30 @@ config BACKPORTED_RTW88_CORE - config BACKPORTED_RTW88_PCI - tristate - default RTW88_PCI -+config BACKPORTED_RTW88_USB -+ tristate -+ default RTW88_USB -+config BACKPORTED_RTW88_8821CU -+ tristate -+ default RTW88_8821CU - config BACKPORTED_RTW88_8822B - tristate - default RTW88_8822B -+config BACKPORTED_RTW88_8822BU -+ tristate -+ default RTW88_8822BU - config BACKPORTED_RTW88_8822C - tristate - default RTW88_8822C -+config BACKPORTED_RTW88_8822CU -+ tristate -+ default RTW88_8822CU - config BACKPORTED_RTW88_8723D - tristate - default RTW88_8723D -+config BACKPORTED_RTW88_8723DU -+ tristate -+ default RTW88_8723DU - config BACKPORTED_RTW88_8821C - tristate - default RTW88_8821C ---- a/defconfigs/wifi -+++ b/defconfigs/wifi -@@ -120,9 +120,13 @@ CPTCFG_RTL8821AE=m - CPTCFG_RTL8XXXU=m - CPTCFG_RTLWIFI=m - CPTCFG_RTW88_8723DE=m -+CPTCFG_RTW88_8723DU=m - CPTCFG_RTW88_8821CE=m -+CPTCFG_RTW88_8821CU=m - CPTCFG_RTW88_8822BE=m -+CPTCFG_RTW88_8822BU=m - CPTCFG_RTW88_8822CE=m -+CPTCFG_RTW88_8822CU=m - CPTCFG_RTW88=m - CPTCFG_SSB=m - CPTCFG_SSB_PCMCIAHOST=y ---- a/local-symbols -+++ b/local-symbols -@@ -375,13 +375,18 @@ RTL8XXXU_UNTESTED= - RTW88= - RTW88_CORE= - RTW88_PCI= -+RTW88_USB= - RTW88_8822B= - RTW88_8822C= - RTW88_8723D= - RTW88_8821C= -+RTW88_8821CU= - RTW88_8822BE= -+RTW88_8822BU= - RTW88_8822CE= -+RTW88_8822CU= - RTW88_8723DE= -+RTW88_8723DU= - RTW88_8821CE= - RTW88_DEBUG= - RTW88_DEBUGFS= diff --git a/package/kernel/mac80211/patches/rtl/015-wifi-rtw88-Move-register-access-from-rtw_bf_assoc-ou.patch b/package/kernel/mac80211/patches/rtl/015-wifi-rtw88-Move-register-access-from-rtw_bf_assoc-ou.patch deleted file mode 100644 index e3edfe98d..000000000 --- a/package/kernel/mac80211/patches/rtl/015-wifi-rtw88-Move-register-access-from-rtw_bf_assoc-ou.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 8a1e2fd8e2da5c8b8c438e20ebffef6881cc9ab8 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 8 Jan 2023 22:13:22 +0100 -Subject: [PATCH] wifi: rtw88: Move register access from rtw_bf_assoc() outside - the RCU - -USB and (upcoming) SDIO support may sleep in the read/write handlers. -Shrink the RCU critical section so it only cover the call to -ieee80211_find_sta() and finding the ic_vht_cap/vht_cap based on the -found station. This moves the chip's BFEE configuration outside the -rcu_read_lock section and thus prevent "scheduling while atomic" or -"Voluntary context switch within RCU read-side critical section!" -warnings when accessing the registers using an SDIO card (which is -where this issue has been spotted in the real world - but it also -affects USB cards). - -Reviewed-by: Ping-Ke Shih -Tested-by: Sascha Hauer -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230108211324.442823-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/bf.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/bf.c -+++ b/drivers/net/wireless/realtek/rtw88/bf.c -@@ -49,19 +49,23 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev - - sta = ieee80211_find_sta(vif, bssid); - if (!sta) { -+ rcu_read_unlock(); -+ - rtw_warn(rtwdev, "failed to find station entry for bss %pM\n", - bssid); -- goto out_unlock; -+ return; - } - - ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; - vht_cap = &sta->deflink.vht_cap; - -+ rcu_read_unlock(); -+ - if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && - (vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { - if (bfinfo->bfer_mu_cnt >= chip->bfer_mu_max_num) { - rtw_dbg(rtwdev, RTW_DBG_BF, "mu bfer number over limit\n"); -- goto out_unlock; -+ return; - } - - ether_addr_copy(bfee->mac_addr, bssid); -@@ -75,7 +79,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev - (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { - if (bfinfo->bfer_su_cnt >= chip->bfer_su_max_num) { - rtw_dbg(rtwdev, RTW_DBG_BF, "su bfer number over limit\n"); -- goto out_unlock; -+ return; - } - - sound_dim = vht_cap->cap & -@@ -98,9 +102,6 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev - - rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true); - } -- --out_unlock: -- rcu_read_unlock(); - } - - void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, diff --git a/package/kernel/mac80211/patches/rtl/016-wifi-rtw88-Use-rtw_iterate_vifs-for-rtw_vif_watch_do.patch b/package/kernel/mac80211/patches/rtl/016-wifi-rtw88-Use-rtw_iterate_vifs-for-rtw_vif_watch_do.patch deleted file mode 100644 index f9a6fff21..000000000 --- a/package/kernel/mac80211/patches/rtl/016-wifi-rtw88-Use-rtw_iterate_vifs-for-rtw_vif_watch_do.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 313f6dc7c5ed723d0c5691553eff4c0090f16bb8 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 8 Jan 2023 22:13:23 +0100 -Subject: [PATCH] wifi: rtw88: Use rtw_iterate_vifs() for - rtw_vif_watch_dog_iter() - -USB and (upcoming) SDIO support may sleep in the read/write handlers. -Make rtw_watch_dog_work() use rtw_iterate_vifs() to prevent "scheduling -while atomic" or "Voluntary context switch within RCU read-side -critical section!" warnings when accessing the registers using an SDIO -card (which is where this issue has been spotted in the real world but -it also affects USB cards). - -Fixes: 78d5bf925f30 ("wifi: rtw88: iterate over vif/sta list non-atomically") -Suggested-by: Ping-Ke Shih -Reviewed-by: Ping-Ke Shih -Tested-by: Sascha Hauer -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230108211324.442823-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/main.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -241,8 +241,10 @@ static void rtw_watch_dog_work(struct wo - rtw_phy_dynamic_mechanism(rtwdev); - - data.rtwdev = rtwdev; -- /* use atomic version to avoid taking local->iflist_mtx mutex */ -- rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data); -+ /* rtw_iterate_vifs internally uses an atomic iterator which is needed -+ * to avoid taking local->iflist_mtx mutex -+ */ -+ rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); - - /* fw supports only one station associated to enter lps, if there are - * more than two stations associated to the AP, then we can not enter diff --git a/package/kernel/mac80211/patches/rtl/017-wifi-rtw88-Use-non-atomic-sta-iterator-in-rtw_ra_mas.patch b/package/kernel/mac80211/patches/rtl/017-wifi-rtw88-Use-non-atomic-sta-iterator-in-rtw_ra_mas.patch deleted file mode 100644 index 240742382..000000000 --- a/package/kernel/mac80211/patches/rtl/017-wifi-rtw88-Use-non-atomic-sta-iterator-in-rtw_ra_mas.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 2931978cd74f4a643deeea5b211523001d95aa44 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 8 Jan 2023 22:13:24 +0100 -Subject: [PATCH] wifi: rtw88: Use non-atomic sta iterator in - rtw_ra_mask_info_update() - -USB and (upcoming) SDIO support may sleep in the read/write handlers. -Use non-atomic rtw_iterate_stas() in rtw_ra_mask_info_update() because -the iterator function rtw_ra_mask_info_update_iter() needs to read and -write registers from within rtw_update_sta_info(). Using the non-atomic -iterator ensures that we can sleep during USB and SDIO register reads -and writes. This fixes "scheduling while atomic" or "Voluntary context -switch within RCU read-side critical section!" warnings as seen by SDIO -card users (but it also affects USB cards). - -Fixes: 78d5bf925f30 ("wifi: rtw88: iterate over vif/sta list non-atomically") -Suggested-by: Ping-Ke Shih -Reviewed-by: Ping-Ke Shih -Tested-by: Sascha Hauer -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230108211324.442823-4-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -737,7 +737,7 @@ static void rtw_ra_mask_info_update(stru - br_data.rtwdev = rtwdev; - br_data.vif = vif; - br_data.mask = mask; -- rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data); -+ rtw_iterate_stas(rtwdev, rtw_ra_mask_info_update_iter, &br_data); - } - - static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, -@@ -746,7 +746,9 @@ static int rtw_ops_set_bitrate_mask(stru - { - struct rtw_dev *rtwdev = hw->priv; - -+ mutex_lock(&rtwdev->mutex); - rtw_ra_mask_info_update(rtwdev, vif, mask); -+ mutex_unlock(&rtwdev->mutex); - - return 0; - } diff --git a/package/kernel/mac80211/patches/rtl/018-wifi-rtw88-pci-Use-enum-type-for-rtw_hw_queue_mappin.patch b/package/kernel/mac80211/patches/rtl/018-wifi-rtw88-pci-Use-enum-type-for-rtw_hw_queue_mappin.patch deleted file mode 100644 index 4cbd371d2..000000000 --- a/package/kernel/mac80211/patches/rtl/018-wifi-rtw88-pci-Use-enum-type-for-rtw_hw_queue_mappin.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6152b649a70861e72220de9f9abf2fe570967493 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 5 Feb 2023 00:29:58 +0100 -Subject: [PATCH] wifi: rtw88: pci: Use enum type for rtw_hw_queue_mapping() - and ac_to_hwq - -rtw_hw_queue_mapping() and ac_to_hwq[] hold values of type enum -rtw_tx_queue_type. Change their types to reflect this to make it easier -to understand this part of the code. - -While here, also change the array to be static const as it is not -supposed to be modified at runtime. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Simon Horman -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230204233001.1511643-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/pci.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -669,7 +669,7 @@ static void rtw_pci_deep_ps(struct rtw_d - spin_unlock_bh(&rtwpci->irq_lock); - } - --static u8 ac_to_hwq[] = { -+static const enum rtw_tx_queue_type ac_to_hwq[] = { - [IEEE80211_AC_VO] = RTW_TX_QUEUE_VO, - [IEEE80211_AC_VI] = RTW_TX_QUEUE_VI, - [IEEE80211_AC_BE] = RTW_TX_QUEUE_BE, -@@ -678,12 +678,12 @@ static u8 ac_to_hwq[] = { - - static_assert(ARRAY_SIZE(ac_to_hwq) == IEEE80211_NUM_ACS); - --static u8 rtw_hw_queue_mapping(struct sk_buff *skb) -+static enum rtw_tx_queue_type rtw_hw_queue_mapping(struct sk_buff *skb) - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - __le16 fc = hdr->frame_control; - u8 q_mapping = skb_get_queue_mapping(skb); -- u8 queue; -+ enum rtw_tx_queue_type queue; - - if (unlikely(ieee80211_is_beacon(fc))) - queue = RTW_TX_QUEUE_BCN; diff --git a/package/kernel/mac80211/patches/rtl/019-wifi-rtw88-pci-Change-queue-datatype-to-enum-rtw_tx_.patch b/package/kernel/mac80211/patches/rtl/019-wifi-rtw88-pci-Change-queue-datatype-to-enum-rtw_tx_.patch deleted file mode 100644 index 0dba4d8d1..000000000 --- a/package/kernel/mac80211/patches/rtl/019-wifi-rtw88-pci-Change-queue-datatype-to-enum-rtw_tx_.patch +++ /dev/null @@ -1,89 +0,0 @@ -From c90897960c19f5bad59fcd391901ac1b7787c50b Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 5 Feb 2023 00:29:59 +0100 -Subject: [PATCH] wifi: rtw88: pci: Change queue datatype to enum - rtw_tx_queue_type - -This makes it easier to understand which values are allowed for the -"queue" variable when using the enum instead of an u8. - -Acked-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Reviewed-by: Simon Horman -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230204233001.1511643-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/pci.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -30,7 +30,8 @@ static u32 rtw_pci_tx_queue_idx_addr[] = - [RTW_TX_QUEUE_H2C] = RTK_PCI_TXBD_IDX_H2CQ, - }; - --static u8 rtw_pci_get_tx_qsel(struct sk_buff *skb, u8 queue) -+static u8 rtw_pci_get_tx_qsel(struct sk_buff *skb, -+ enum rtw_tx_queue_type queue) - { - switch (queue) { - case RTW_TX_QUEUE_BCN: -@@ -542,7 +543,7 @@ static int rtw_pci_setup(struct rtw_dev - static void rtw_pci_dma_release(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) - { - struct rtw_pci_tx_ring *tx_ring; -- u8 queue; -+ enum rtw_tx_queue_type queue; - - rtw_pci_reset_trx_ring(rtwdev); - for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { -@@ -608,8 +609,8 @@ static void rtw_pci_deep_ps_enter(struct - { - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - struct rtw_pci_tx_ring *tx_ring; -+ enum rtw_tx_queue_type queue; - bool tx_empty = true; -- u8 queue; - - if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) - goto enter_deep_ps; -@@ -803,7 +804,8 @@ static void rtw_pci_flush_queues(struct - __rtw_pci_flush_queues(rtwdev, pci_queues, drop); - } - --static void rtw_pci_tx_kick_off_queue(struct rtw_dev *rtwdev, u8 queue) -+static void rtw_pci_tx_kick_off_queue(struct rtw_dev *rtwdev, -+ enum rtw_tx_queue_type queue) - { - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - struct rtw_pci_tx_ring *ring; -@@ -822,7 +824,7 @@ static void rtw_pci_tx_kick_off_queue(st - static void rtw_pci_tx_kick_off(struct rtw_dev *rtwdev) - { - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; -- u8 queue; -+ enum rtw_tx_queue_type queue; - - for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) - if (test_and_clear_bit(queue, rtwpci->tx_queued)) -@@ -831,7 +833,8 @@ static void rtw_pci_tx_kick_off(struct r - - static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev, - struct rtw_tx_pkt_info *pkt_info, -- struct sk_buff *skb, u8 queue) -+ struct sk_buff *skb, -+ enum rtw_tx_queue_type queue) - { - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - const struct rtw_chip_info *chip = rtwdev->chip; -@@ -949,9 +952,9 @@ static int rtw_pci_tx_write(struct rtw_d - struct rtw_tx_pkt_info *pkt_info, - struct sk_buff *skb) - { -+ enum rtw_tx_queue_type queue = rtw_hw_queue_mapping(skb); - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - struct rtw_pci_tx_ring *ring; -- u8 queue = rtw_hw_queue_mapping(skb); - int ret; - - ret = rtw_pci_tx_write_data(rtwdev, pkt_info, skb, queue); diff --git a/package/kernel/mac80211/patches/rtl/020-wifi-rtw88-Move-enum-rtw_tx_queue_type-mapping-code-.patch b/package/kernel/mac80211/patches/rtl/020-wifi-rtw88-Move-enum-rtw_tx_queue_type-mapping-code-.patch deleted file mode 100644 index 1bed8f454..000000000 --- a/package/kernel/mac80211/patches/rtl/020-wifi-rtw88-Move-enum-rtw_tx_queue_type-mapping-code-.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 7b6e9df91133e13ce7d980fcdb55cc7f26099106 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 5 Feb 2023 00:30:00 +0100 -Subject: [PATCH] wifi: rtw88: Move enum rtw_tx_queue_type mapping code to - tx.{c,h} - -This code is not specific to the PCIe bus type but can be re-used by USB -and SDIO bus types. Move it to tx.{c,h} to avoid code-duplication in the -future. While here, add checking of the ac argument in -rtw_tx_ac_to_hwq() so we're not accessing entries beyond the end of the -array. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Simon Horman -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230204233001.1511643-4-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/pci.c | 35 ++------------------ - drivers/net/wireless/realtek/rtw88/tx.c | 41 ++++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/tx.h | 3 ++ - 3 files changed, 46 insertions(+), 33 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -670,37 +670,6 @@ static void rtw_pci_deep_ps(struct rtw_d - spin_unlock_bh(&rtwpci->irq_lock); - } - --static const enum rtw_tx_queue_type ac_to_hwq[] = { -- [IEEE80211_AC_VO] = RTW_TX_QUEUE_VO, -- [IEEE80211_AC_VI] = RTW_TX_QUEUE_VI, -- [IEEE80211_AC_BE] = RTW_TX_QUEUE_BE, -- [IEEE80211_AC_BK] = RTW_TX_QUEUE_BK, --}; -- --static_assert(ARRAY_SIZE(ac_to_hwq) == IEEE80211_NUM_ACS); -- --static enum rtw_tx_queue_type rtw_hw_queue_mapping(struct sk_buff *skb) --{ -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -- __le16 fc = hdr->frame_control; -- u8 q_mapping = skb_get_queue_mapping(skb); -- enum rtw_tx_queue_type queue; -- -- if (unlikely(ieee80211_is_beacon(fc))) -- queue = RTW_TX_QUEUE_BCN; -- else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) -- queue = RTW_TX_QUEUE_MGMT; -- else if (is_broadcast_ether_addr(hdr->addr1) || -- is_multicast_ether_addr(hdr->addr1)) -- queue = RTW_TX_QUEUE_HI0; -- else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq))) -- queue = ac_to_hwq[IEEE80211_AC_BE]; -- else -- queue = ac_to_hwq[q_mapping]; -- -- return queue; --} -- - static void rtw_pci_release_rsvd_page(struct rtw_pci *rtwpci, - struct rtw_pci_tx_ring *ring) - { -@@ -798,7 +767,7 @@ static void rtw_pci_flush_queues(struct - } else { - for (i = 0; i < rtwdev->hw->queues; i++) - if (queues & BIT(i)) -- pci_queues |= BIT(ac_to_hwq[i]); -+ pci_queues |= BIT(rtw_tx_ac_to_hwq(i)); - } - - __rtw_pci_flush_queues(rtwdev, pci_queues, drop); -@@ -952,7 +921,7 @@ static int rtw_pci_tx_write(struct rtw_d - struct rtw_tx_pkt_info *pkt_info, - struct sk_buff *skb) - { -- enum rtw_tx_queue_type queue = rtw_hw_queue_mapping(skb); -+ enum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb); - struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - struct rtw_pci_tx_ring *ring; - int ret; ---- a/drivers/net/wireless/realtek/rtw88/tx.c -+++ b/drivers/net/wireless/realtek/rtw88/tx.c -@@ -682,3 +682,44 @@ void rtw_txq_cleanup(struct rtw_dev *rtw - list_del_init(&rtwtxq->list); - spin_unlock_bh(&rtwdev->txq_lock); - } -+ -+static const enum rtw_tx_queue_type ac_to_hwq[] = { -+ [IEEE80211_AC_VO] = RTW_TX_QUEUE_VO, -+ [IEEE80211_AC_VI] = RTW_TX_QUEUE_VI, -+ [IEEE80211_AC_BE] = RTW_TX_QUEUE_BE, -+ [IEEE80211_AC_BK] = RTW_TX_QUEUE_BK, -+}; -+ -+static_assert(ARRAY_SIZE(ac_to_hwq) == IEEE80211_NUM_ACS); -+ -+enum rtw_tx_queue_type rtw_tx_ac_to_hwq(enum ieee80211_ac_numbers ac) -+{ -+ if (WARN_ON(unlikely(ac >= IEEE80211_NUM_ACS))) -+ return RTW_TX_QUEUE_BE; -+ -+ return ac_to_hwq[ac]; -+} -+EXPORT_SYMBOL(rtw_tx_ac_to_hwq); -+ -+enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb) -+{ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ __le16 fc = hdr->frame_control; -+ u8 q_mapping = skb_get_queue_mapping(skb); -+ enum rtw_tx_queue_type queue; -+ -+ if (unlikely(ieee80211_is_beacon(fc))) -+ queue = RTW_TX_QUEUE_BCN; -+ else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) -+ queue = RTW_TX_QUEUE_MGMT; -+ else if (is_broadcast_ether_addr(hdr->addr1) || -+ is_multicast_ether_addr(hdr->addr1)) -+ queue = RTW_TX_QUEUE_HI0; -+ else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq))) -+ queue = ac_to_hwq[IEEE80211_AC_BE]; -+ else -+ queue = ac_to_hwq[q_mapping]; -+ -+ return queue; -+} -+EXPORT_SYMBOL(rtw_tx_queue_mapping); ---- a/drivers/net/wireless/realtek/rtw88/tx.h -+++ b/drivers/net/wireless/realtek/rtw88/tx.h -@@ -131,6 +131,9 @@ rtw_tx_write_data_h2c_get(struct rtw_dev - struct rtw_tx_pkt_info *pkt_info, - u8 *buf, u32 size); - -+enum rtw_tx_queue_type rtw_tx_ac_to_hwq(enum ieee80211_ac_numbers ac); -+enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb); -+ - static inline - void fill_txdesc_checksum_common(u8 *txdesc, size_t words) - { diff --git a/package/kernel/mac80211/patches/rtl/021-49-wifi-rtw88-mac-Use-existing-macros-in-rtw_pwr_seq_pa.patch b/package/kernel/mac80211/patches/rtl/021-49-wifi-rtw88-mac-Use-existing-macros-in-rtw_pwr_seq_pa.patch deleted file mode 100644 index 1770d70dc..000000000 --- a/package/kernel/mac80211/patches/rtl/021-49-wifi-rtw88-mac-Use-existing-macros-in-rtw_pwr_seq_pa.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 24d54855ff36c7c6256cb48b735a927090142a51 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 5 Feb 2023 00:30:01 +0100 -Subject: [PATCH 49/85] wifi: rtw88: mac: Use existing macros in - rtw_pwr_seq_parser() - -Replace the magic numbers for the intf_mask with their existing -RTW_PWR_INTF_PCI_MSK and RTW_PWR_INTF_USB_MSK macros to make the code -easier to understand. - -Acked-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Reviewed-by: Simon Horman -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230204233001.1511643-5-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -217,10 +217,10 @@ static int rtw_pwr_seq_parser(struct rtw - cut_mask = cut_version_to_mask(cut); - switch (rtw_hci_type(rtwdev)) { - case RTW_HCI_TYPE_PCIE: -- intf_mask = BIT(2); -+ intf_mask = RTW_PWR_INTF_PCI_MSK; - break; - case RTW_HCI_TYPE_USB: -- intf_mask = BIT(1); -+ intf_mask = RTW_PWR_INTF_USB_MSK; - break; - default: - return -EINVAL; diff --git a/package/kernel/mac80211/patches/rtl/021-54-wifi-rtw88-mac-Add-support-for-the-SDIO-HCI-in-rtw_p.patch b/package/kernel/mac80211/patches/rtl/021-54-wifi-rtw88-mac-Add-support-for-the-SDIO-HCI-in-rtw_p.patch deleted file mode 100644 index 0549207db..000000000 --- a/package/kernel/mac80211/patches/rtl/021-54-wifi-rtw88-mac-Add-support-for-the-SDIO-HCI-in-rtw_p.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 96c79da2e4d1a25e73916c656fe4ccf7fc8176ae Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Feb 2023 16:29:40 +0100 -Subject: [PATCH 54/85] wifi: rtw88: mac: Add support for the SDIO HCI in - rtw_pwr_seq_parser() - -rtw_pwr_seq_parser() needs to know about the HCI bus interface mask for -the SDIO bus so it can parse the chip state change sequences. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230218152944.48842-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -222,6 +222,9 @@ static int rtw_pwr_seq_parser(struct rtw - case RTW_HCI_TYPE_USB: - intf_mask = RTW_PWR_INTF_USB_MSK; - break; -+ case RTW_HCI_TYPE_SDIO: -+ intf_mask = RTW_PWR_INTF_SDIO_MSK; -+ break; - default: - return -EINVAL; - } diff --git a/package/kernel/mac80211/patches/rtl/021-55-wifi-rtw88-mac-Add-SDIO-HCI-support-in-the-TX-page-t.patch b/package/kernel/mac80211/patches/rtl/021-55-wifi-rtw88-mac-Add-SDIO-HCI-support-in-the-TX-page-t.patch deleted file mode 100644 index 074fcdc82..000000000 --- a/package/kernel/mac80211/patches/rtl/021-55-wifi-rtw88-mac-Add-SDIO-HCI-support-in-the-TX-page-t.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8599ea40582d49afe437badde76e31bd7429c607 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Feb 2023 16:29:41 +0100 -Subject: [PATCH 55/85] wifi: rtw88: mac: Add SDIO HCI support in the TX/page - table setup - -txdma_queue_mapping() and priority_queue_cfg() can use the first entry -of each chip's rqpn_table and page_table. Add this mapping so data -transmission is possible on SDIO based chipsets. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230218152944.48842-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -1043,6 +1043,9 @@ static int txdma_queue_mapping(struct rt - else - return -EINVAL; - break; -+ case RTW_HCI_TYPE_SDIO: -+ rqpn = &chip->rqpn_table[0]; -+ break; - default: - return -EINVAL; - } -@@ -1205,6 +1208,9 @@ static int priority_queue_cfg(struct rtw - else - return -EINVAL; - break; -+ case RTW_HCI_TYPE_SDIO: -+ pg_tbl = &chip->page_table[0]; -+ break; - default: - return -EINVAL; - } diff --git a/package/kernel/mac80211/patches/rtl/021-56-wifi-rtw88-rtw8821c-Implement-RTL8821CS-SDIO-efuse-p.patch b/package/kernel/mac80211/patches/rtl/021-56-wifi-rtw88-rtw8821c-Implement-RTL8821CS-SDIO-efuse-p.patch deleted file mode 100644 index c8f6f3c9d..000000000 --- a/package/kernel/mac80211/patches/rtl/021-56-wifi-rtw88-rtw8821c-Implement-RTL8821CS-SDIO-efuse-p.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 64e9d564653566812dfade36d20f1794407e6ca1 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Feb 2023 16:29:42 +0100 -Subject: [PATCH 56/85] wifi: rtw88: rtw8821c: Implement RTL8821CS (SDIO) efuse - parsing - -The efuse of the SDIO RTL8821CS chip has only one known member: the mac -address is at offset 0x11a. Add a struct rtw8821cs_efuse describing this -and use it for copying the mac address when the SDIO bus is used. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230218152944.48842-4-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw88/rtw8821c.h | 6 ++++++ - 2 files changed, 15 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -32,6 +32,12 @@ static void rtw8821cu_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->u.mac_addr); - } - -+static void rtw8821cs_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8821c_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->s.mac_addr); -+} -+ - enum rtw8821ce_rf_set { - SWITCH_TO_BTG, - SWITCH_TO_WLG, -@@ -77,6 +83,9 @@ static int rtw8821c_read_efuse(struct rt - case RTW_HCI_TYPE_USB: - rtw8821cu_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw8821cs_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h -@@ -65,6 +65,11 @@ struct rtw8821ce_efuse { - u8 res7; - }; - -+struct rtw8821cs_efuse { -+ u8 res4[0x4a]; /* 0xd0 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -+} __packed; -+ - struct rtw8821c_efuse { - __le16 rtl_id; - u8 res0[0x0e]; -@@ -94,6 +99,7 @@ struct rtw8821c_efuse { - union { - struct rtw8821ce_efuse e; - struct rtw8821cu_efuse u; -+ struct rtw8821cs_efuse s; - }; - }; - diff --git a/package/kernel/mac80211/patches/rtl/021-57-wifi-rtw88-rtw8822b-Implement-RTL8822BS-SDIO-efuse-p.patch b/package/kernel/mac80211/patches/rtl/021-57-wifi-rtw88-rtw8822b-Implement-RTL8822BS-SDIO-efuse-p.patch deleted file mode 100644 index 62704ac82..000000000 --- a/package/kernel/mac80211/patches/rtl/021-57-wifi-rtw88-rtw8822b-Implement-RTL8822BS-SDIO-efuse-p.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9e688784b8a13515ee186d0ee1cfab12b6d05241 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Feb 2023 16:29:43 +0100 -Subject: [PATCH 57/85] wifi: rtw88: rtw8822b: Implement RTL8822BS (SDIO) efuse - parsing - -The efuse of the SDIO RTL8822BS chip has only one known member: the mac -address is at offset 0x11a. Add a struct rtw8822bs_efuse describing this -and use it for copying the mac address when the SDIO bus is used. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230218152944.48842-5-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/rtw8822b.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw88/rtw8822b.h | 8 +++++++- - 2 files changed, 16 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c -@@ -32,6 +32,12 @@ static void rtw8822bu_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->u.mac_addr); - } - -+static void rtw8822bs_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8822b_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->s.mac_addr); -+} -+ - static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -65,6 +71,9 @@ static int rtw8822b_read_efuse(struct rt - case RTW_HCI_TYPE_USB: - rtw8822bu_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw8822bs_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h -@@ -65,6 +65,11 @@ struct rtw8822be_efuse { - u8 res7; - }; - -+struct rtw8822bs_efuse { -+ u8 res4[0x4a]; /* 0xd0 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -+} __packed; -+ - struct rtw8822b_efuse { - __le16 rtl_id; - u8 res0[0x0e]; -@@ -92,8 +97,9 @@ struct rtw8822b_efuse { - u8 country_code[2]; - u8 res[3]; - union { -- struct rtw8822bu_efuse u; - struct rtw8822be_efuse e; -+ struct rtw8822bu_efuse u; -+ struct rtw8822bs_efuse s; - }; - }; - diff --git a/package/kernel/mac80211/patches/rtl/021-58-wifi-rtw88-rtw8822c-Implement-RTL8822CS-SDIO-efuse-p.patch b/package/kernel/mac80211/patches/rtl/021-58-wifi-rtw88-rtw8822c-Implement-RTL8822CS-SDIO-efuse-p.patch deleted file mode 100644 index b09f16d9b..000000000 --- a/package/kernel/mac80211/patches/rtl/021-58-wifi-rtw88-rtw8822c-Implement-RTL8822CS-SDIO-efuse-p.patch +++ /dev/null @@ -1,69 +0,0 @@ -From ad0a677bce20c7fa2e8af3fd7f23c0686018202b Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Feb 2023 16:29:44 +0100 -Subject: [PATCH 58/85] wifi: rtw88: rtw8822c: Implement RTL8822CS (SDIO) efuse - parsing - -The efuse of the SDIO RTL8822CS chip has only one known member: the mac -address is at offset 0x16a. Add a struct rtw8822cs_efuse describing this -and use it for copying the mac address when the SDIO bus is used. - -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230218152944.48842-6-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/rtw8822c.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw88/rtw8822c.h | 8 +++++++- - 2 files changed, 16 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c -@@ -35,6 +35,12 @@ static void rtw8822cu_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->u.mac_addr); - } - -+static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8822c_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->s.mac_addr); -+} -+ - static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -67,6 +73,9 @@ static int rtw8822c_read_efuse(struct rt - case RTW_HCI_TYPE_USB: - rtw8822cu_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw8822cs_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h -@@ -16,6 +16,11 @@ struct rtw8822cu_efuse { - u8 res2[0x3d]; - }; - -+struct rtw8822cs_efuse { -+ u8 res0[0x4a]; /* 0x120 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x16a */ -+} __packed; -+ - struct rtw8822ce_efuse { - u8 mac_addr[ETH_ALEN]; /* 0x120 */ - u8 vender_id[2]; -@@ -91,8 +96,9 @@ struct rtw8822c_efuse { - u8 res9; - u8 res10[0x42]; - union { -- struct rtw8822cu_efuse u; - struct rtw8822ce_efuse e; -+ struct rtw8822cu_efuse u; -+ struct rtw8822cs_efuse s; - }; - }; - diff --git a/package/kernel/mac80211/patches/rtl/021-59-wifi-rtw88-mac-Return-the-original-error-from-rtw_pw.patch b/package/kernel/mac80211/patches/rtl/021-59-wifi-rtw88-mac-Return-the-original-error-from-rtw_pw.patch deleted file mode 100644 index 6417ea8ef..000000000 --- a/package/kernel/mac80211/patches/rtl/021-59-wifi-rtw88-mac-Return-the-original-error-from-rtw_pw.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b7ed9fa2cb76ca7a3c3cd4a6d35748fe1fbda9f6 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 26 Feb 2023 23:10:03 +0100 -Subject: [PATCH 59/85] wifi: rtw88: mac: Return the original error from - rtw_pwr_seq_parser() - -rtw_pwr_seq_parser() calls rtw_sub_pwr_seq_parser() which can either -return -EBUSY, -EINVAL or 0. Propagate the original error code instead -of unconditionally returning -EBUSY in case of an error. - -Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230226221004.138331-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -236,7 +236,7 @@ static int rtw_pwr_seq_parser(struct rtw - - ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd); - if (ret) -- return -EBUSY; -+ return ret; - - idx++; - } while (1); diff --git a/package/kernel/mac80211/patches/rtl/021-60-wifi-rtw88-mac-Return-the-original-error-from-rtw_ma.patch b/package/kernel/mac80211/patches/rtl/021-60-wifi-rtw88-mac-Return-the-original-error-from-rtw_ma.patch deleted file mode 100644 index c867fc403..000000000 --- a/package/kernel/mac80211/patches/rtl/021-60-wifi-rtw88-mac-Return-the-original-error-from-rtw_ma.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 15c8e267dfa62f207ee1db666c822324e3362b84 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sun, 26 Feb 2023 23:10:04 +0100 -Subject: [PATCH 60/85] wifi: rtw88: mac: Return the original error from - rtw_mac_power_switch() - -rtw_mac_power_switch() calls rtw_pwr_seq_parser() which can return --EINVAL, -EBUSY or 0. Propagate the original error code instead of -unconditionally returning -EINVAL in case of an error. - -Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230226221004.138331-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -250,6 +250,7 @@ static int rtw_mac_power_switch(struct r - const struct rtw_pwr_seq_cmd **pwr_seq; - u8 rpwm; - bool cur_pwr; -+ int ret; - - if (rtw_chip_wcpu_11ac(rtwdev)) { - rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); -@@ -273,8 +274,9 @@ static int rtw_mac_power_switch(struct r - return -EALREADY; - - pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; -- if (rtw_pwr_seq_parser(rtwdev, pwr_seq)) -- return -EINVAL; -+ ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); -+ if (ret) -+ return ret; - - if (pwr_on) - set_bit(RTW_FLAG_POWERON, rtwdev->flags); diff --git a/package/kernel/mac80211/patches/rtl/021-wifi-rtw88-fix-memory-leak-in-rtw_usb_probe.patch b/package/kernel/mac80211/patches/rtl/021-wifi-rtw88-fix-memory-leak-in-rtw_usb_probe.patch deleted file mode 100644 index dab0daa4a..000000000 --- a/package/kernel/mac80211/patches/rtl/021-wifi-rtw88-fix-memory-leak-in-rtw_usb_probe.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 48181d285623198c33bb9698992502687b258efa Mon Sep 17 00:00:00 2001 -From: Dongliang Mu -Date: Thu, 9 Mar 2023 10:16:36 +0800 -Subject: [PATCH] wifi: rtw88: fix memory leak in rtw_usb_probe() - -drivers/net/wireless/realtek/rtw88/usb.c:876 rtw_usb_probe() -warn: 'hw' from ieee80211_alloc_hw() not released on lines: 811 - -Fix this by modifying return to a goto statement. - -Signed-off-by: Dongliang Mu -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230309021636.528601-1-dzm91@hust.edu.cn ---- - drivers/net/wireless/realtek/rtw88/usb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -808,7 +808,7 @@ int rtw_usb_probe(struct usb_interface * - - ret = rtw_usb_alloc_rx_bufs(rtwusb); - if (ret) -- return ret; -+ goto err_release_hw; - - ret = rtw_core_init(rtwdev); - if (ret) diff --git a/package/kernel/mac80211/patches/rtl/022-wifi-rtw88-remove-unused-rtw_pci_get_tx_desc-functio.patch b/package/kernel/mac80211/patches/rtl/022-wifi-rtw88-remove-unused-rtw_pci_get_tx_desc-functio.patch deleted file mode 100644 index 1d1cf9d97..000000000 --- a/package/kernel/mac80211/patches/rtl/022-wifi-rtw88-remove-unused-rtw_pci_get_tx_desc-functio.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c9b6111a6f94bd186d1f0f7a04a9b37030a27738 Mon Sep 17 00:00:00 2001 -From: Tom Rix -Date: Mon, 20 Mar 2023 19:34:48 -0400 -Subject: [PATCH 22/45] wifi: rtw88: remove unused rtw_pci_get_tx_desc function - -clang with W=1 reports -drivers/net/wireless/realtek/rtw88/pci.c:92:21: error: - unused function 'rtw_pci_get_tx_desc' [-Werror,-Wunused-function] -static inline void *rtw_pci_get_tx_desc(struct rtw_pci_tx_ring *tx_ring, u8 idx) - ^ -This function is not used, so remove it. - -Signed-off-by: Tom Rix -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320233448.1729899-1-trix@redhat.com ---- - drivers/net/wireless/realtek/rtw88/pci.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -89,13 +89,6 @@ static void rtw_pci_write32(struct rtw_d - writel(val, rtwpci->mmap + addr); - } - --static inline void *rtw_pci_get_tx_desc(struct rtw_pci_tx_ring *tx_ring, u8 idx) --{ -- int offset = tx_ring->r.desc_size * idx; -- -- return tx_ring->r.head + offset; --} -- - static void rtw_pci_free_tx_ring_skbs(struct rtw_dev *rtwdev, - struct rtw_pci_tx_ring *tx_ring) - { diff --git a/package/kernel/mac80211/patches/rtl/023-wifi-rtw88-Remove-redundant-pci_clear_master.patch b/package/kernel/mac80211/patches/rtl/023-wifi-rtw88-Remove-redundant-pci_clear_master.patch deleted file mode 100644 index 790581b9f..000000000 --- a/package/kernel/mac80211/patches/rtl/023-wifi-rtw88-Remove-redundant-pci_clear_master.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e665c6d67e541ac7520fa8c5175ad2c0213f247e Mon Sep 17 00:00:00 2001 -From: Cai Huoqing -Date: Thu, 23 Mar 2023 19:26:12 +0800 -Subject: [PATCH 23/45] wifi: rtw88: Remove redundant pci_clear_master - -Remove pci_clear_master to simplify the code, -the bus-mastering is also cleared in do_pci_disable_device, -like this: -./drivers/pci/pci.c:2197 -static void do_pci_disable_device(struct pci_dev *dev) -{ - u16 pci_command; - - pci_read_config_word(dev, PCI_COMMAND, &pci_command); - if (pci_command & PCI_COMMAND_MASTER) { - pci_command &= ~PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, pci_command); - } - - pcibios_disable_device(dev); -}. -And dev->is_busmaster is set to 0 in pci_disable_device. - -Signed-off-by: Cai Huoqing -Reviewed-by: Simon Horman -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230323112613.7550-4-cai.huoqing@linux.dev ---- - drivers/net/wireless/realtek/rtw88/pci.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -1545,7 +1545,6 @@ static int rtw_pci_claim(struct rtw_dev - - static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) - { -- pci_clear_master(pdev); - pci_disable_device(pdev); - } - diff --git a/package/kernel/mac80211/patches/rtl/024-wifi-rtw88-Clear-RTW_FLAG_POWERON-early-in-rtw_mac_p.patch b/package/kernel/mac80211/patches/rtl/024-wifi-rtw88-Clear-RTW_FLAG_POWERON-early-in-rtw_mac_p.patch deleted file mode 100644 index 9df21636b..000000000 --- a/package/kernel/mac80211/patches/rtl/024-wifi-rtw88-Clear-RTW_FLAG_POWERON-early-in-rtw_mac_p.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 6a92566088b1a37c1cf2c4b6b5fb733dc5bdc6a6 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:21 +0200 -Subject: [PATCH 24/45] wifi: rtw88: Clear RTW_FLAG_POWERON early in - rtw_mac_power_switch() - -The SDIO HCI implementation needs to know when the MAC is powered on. -This is needed because 32-bit register access has to be split into 4x -8-bit register access when the MAC is not fully powered on or while -powering off. When the MAC is powered on 32-bit register access can be -used to reduce the number of transfers but splitting into 4x 8-bit -register access still works in that case. - -During the power on sequence is how RTW_FLAG_POWERON is only set when -the power on sequence has completed successfully. During power off -however RTW_FLAG_POWERON is set. This means that the upcoming SDIO HCI -implementation does not know that it has to use 4x 8-bit register -accessors. Clear the RTW_FLAG_POWERON flag early when powering off the -MAC so the whole power off sequence is processed with RTW_FLAG_POWERON -unset. This will make it possible to use the RTW_FLAG_POWERON flag in -the upcoming SDIO HCI implementation. - -Note that a failure in rtw_pwr_seq_parser() while applying -chip->pwr_off_seq can theoretically result in the RTW_FLAG_POWERON -flag being cleared while the chip is still powered on. However, -depending on when the failure occurs in the power off sequence the -chip may be on or off. Even the original approach of clearing -RTW_FLAG_POWERON only when the power off sequence has been applied -successfully could end up in some corner case where the chip is -powered off but RTW_FLAG_POWERON was not cleared. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -273,6 +273,9 @@ static int rtw_mac_power_switch(struct r - if (pwr_on == cur_pwr) - return -EALREADY; - -+ if (!pwr_on) -+ clear_bit(RTW_FLAG_POWERON, rtwdev->flags); -+ - pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; - ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); - if (ret) -@@ -280,8 +283,6 @@ static int rtw_mac_power_switch(struct r - - if (pwr_on) - set_bit(RTW_FLAG_POWERON, rtwdev->flags); -- else -- clear_bit(RTW_FLAG_POWERON, rtwdev->flags); - - return 0; - } diff --git a/package/kernel/mac80211/patches/rtl/025-wifi-rtw88-sdio-Add-HCI-implementation-for-SDIO-base.patch b/package/kernel/mac80211/patches/rtl/025-wifi-rtw88-sdio-Add-HCI-implementation-for-SDIO-base.patch deleted file mode 100644 index 9401f20ad..000000000 --- a/package/kernel/mac80211/patches/rtl/025-wifi-rtw88-sdio-Add-HCI-implementation-for-SDIO-base.patch +++ /dev/null @@ -1,1719 +0,0 @@ -From 65371a3f14e73979958aea0db1e3bb456a296149 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:22 +0200 -Subject: [PATCH 25/45] wifi: rtw88: sdio: Add HCI implementation for SDIO - based chipsets - -Add a sub-driver for SDIO based chipsets which implements the following -functionality: -- register accessors for 8, 16 and 32 bits for all states of the card - (including usage of 4x 8 bit access for one 32 bit buffer if the card - is not fully powered on yet - or if it's fully powered on then 1x 32 - bit access is used) -- checking whether there's space in the TX FIFO queue to transmit data -- transfers from the host to the device for actual network traffic, - reserved pages (for firmware download) and H2C (host-to-card) - transfers -- receiving data from the device -- deep power saving state - -The transmit path is optimized so DMA-capable SDIO host controllers can -directly use the buffers provided because the buffer's physical -addresses are 8 byte aligned. - -The receive path is prepared to support RX aggregation where the -chipset combines multiple MAC frames into one bigger buffer to reduce -SDIO transfer overhead. - -Co-developed-by: Jernej Skrabec -Signed-off-by: Jernej Skrabec -Reviewed-by: Ulf Hansson -Signed-off-by: Martin Blumenstingl -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 3 + - drivers/net/wireless/realtek/rtw88/Makefile | 3 + - drivers/net/wireless/realtek/rtw88/debug.h | 1 + - drivers/net/wireless/realtek/rtw88/mac.c | 1 + - drivers/net/wireless/realtek/rtw88/mac.h | 1 - - drivers/net/wireless/realtek/rtw88/reg.h | 12 + - drivers/net/wireless/realtek/rtw88/sdio.c | 1394 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/sdio.h | 178 +++ - 8 files changed, 1592 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/wireless/realtek/rtw88/sdio.c - create mode 100644 drivers/net/wireless/realtek/rtw88/sdio.h - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -19,6 +19,11 @@ config RTW88_PCI - tristate - depends on m - -+config RTW88_SDIO -+ tristate -+ depends on m -+ -+ - config RTW88_USB - tristate - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -59,5 +59,8 @@ rtw88_8821cu-objs := rtw8821cu.o - obj-$(CPTCFG_RTW88_PCI) += rtw88_pci.o - rtw88_pci-objs := pci.o - -+obj-$(CPTCFG_RTW88_SDIO) += rtw88_sdio.o -+rtw88_sdio-objs := sdio.o -+ - obj-$(CPTCFG_RTW88_USB) += rtw88_usb.o - rtw88_usb-objs := usb.o ---- a/drivers/net/wireless/realtek/rtw88/debug.h -+++ b/drivers/net/wireless/realtek/rtw88/debug.h -@@ -24,6 +24,7 @@ enum rtw_debug_mask { - RTW_DBG_ADAPTIVITY = 0x00008000, - RTW_DBG_HW_SCAN = 0x00010000, - RTW_DBG_STATE = 0x00020000, -+ RTW_DBG_SDIO = 0x00040000, - - RTW_DBG_ALL = 0xffffffff - }; ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -7,6 +7,7 @@ - #include "reg.h" - #include "fw.h" - #include "debug.h" -+#include "sdio.h" - - void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, - u8 primary_ch_idx) ---- a/drivers/net/wireless/realtek/rtw88/mac.h -+++ b/drivers/net/wireless/realtek/rtw88/mac.h -@@ -7,7 +7,6 @@ - - #define RTW_HW_PORT_NUM 5 - #define cut_version_to_mask(cut) (0x1 << ((cut) + 1)) --#define SDIO_LOCAL_OFFSET 0x10250000 - #define DDMA_POLLING_COUNT 1000 - #define C2H_PKT_BUF 256 - #define REPORT_BUF 128 ---- a/drivers/net/wireless/realtek/rtw88/reg.h -+++ b/drivers/net/wireless/realtek/rtw88/reg.h -@@ -87,6 +87,7 @@ - #define BIT_LTE_MUX_CTRL_PATH BIT(26) - #define REG_HCI_OPT_CTRL 0x0074 - #define BIT_USB_SUS_DIS BIT(8) -+#define BIT_SDIO_PAD_E5 BIT(18) - - #define REG_AFE_CTRL_4 0x0078 - #define BIT_CK320M_AFE_EN BIT(4) -@@ -185,6 +186,9 @@ - (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP) - #define REG_TXDMA_PQ_MAP 0x010C - #define BIT_RXDMA_ARBBW_EN BIT(0) -+#define BIT_RXSHFT_EN BIT(1) -+#define BIT_RXDMA_AGG_EN BIT(2) -+#define BIT_TXDMA_BW_EN BIT(3) - #define BIT_SHIFT_TXDMA_BEQ_MAP 8 - #define BIT_MASK_TXDMA_BEQ_MAP 0x3 - #define BIT_TXDMA_BEQ_MAP(x) \ -@@ -283,10 +287,18 @@ - #define REG_H2C_TAIL 0x0248 - #define REG_H2C_READ_ADDR 0x024C - #define REG_H2C_INFO 0x0254 -+#define REG_RXDMA_AGG_PG_TH 0x0280 -+#define BIT_RXDMA_AGG_PG_TH GENMASK(7, 0) -+#define BIT_DMA_AGG_TO_V1 GENMASK(15, 8) -+#define BIT_EN_PRE_CALC BIT(29) - #define REG_RXPKT_NUM 0x0284 - #define BIT_RXDMA_REQ BIT(19) - #define BIT_RW_RELEASE BIT(18) - #define BIT_RXDMA_IDLE BIT(17) -+#define REG_RXDMA_STATUS 0x0288 -+#define REG_RXDMA_DPR 0x028C -+#define REG_RXDMA_MODE 0x0290 -+#define BIT_DMA_MODE BIT(1) - #define REG_RXPKTNUM 0x02B0 - - #define REG_INT_MIG 0x0304 ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -0,0 +1,1394 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright (C) 2021 Martin Blumenstingl -+ * Copyright (C) 2021 Jernej Skrabec -+ * -+ * Based on rtw88/pci.c: -+ * Copyright(c) 2018-2019 Realtek Corporation -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "debug.h" -+#include "fw.h" -+#include "ps.h" -+#include "reg.h" -+#include "rx.h" -+#include "sdio.h" -+#include "tx.h" -+ -+#define RTW_SDIO_INDIRECT_RW_RETRIES 50 -+ -+static bool rtw_sdio_is_bus_addr(u32 addr) -+{ -+ return !!(addr & RTW_SDIO_BUS_MSK); -+} -+ -+static bool rtw_sdio_bus_claim_needed(struct rtw_sdio *rtwsdio) -+{ -+ return !rtwsdio->irq_thread || -+ rtwsdio->irq_thread != current; -+} -+ -+static u32 rtw_sdio_to_bus_offset(struct rtw_dev *rtwdev, u32 addr) -+{ -+ switch (addr & RTW_SDIO_BUS_MSK) { -+ case WLAN_IOREG_OFFSET: -+ addr &= WLAN_IOREG_REG_MSK; -+ addr |= FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_MAC_REG); -+ break; -+ case SDIO_LOCAL_OFFSET: -+ addr &= SDIO_LOCAL_REG_MSK; -+ addr |= FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_SDIO_REG); -+ break; -+ default: -+ rtw_warn(rtwdev, "Cannot convert addr 0x%08x to bus offset", -+ addr); -+ } -+ -+ return addr; -+} -+ -+static bool rtw_sdio_use_memcpy_io(struct rtw_dev *rtwdev, u32 addr, -+ u8 alignment) -+{ -+ return IS_ALIGNED(addr, alignment) && -+ test_bit(RTW_FLAG_POWERON, rtwdev->flags); -+} -+ -+static void rtw_sdio_writel(struct rtw_dev *rtwdev, u32 val, u32 addr, -+ int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u8 buf[4]; -+ int i; -+ -+ if (rtw_sdio_use_memcpy_io(rtwdev, addr, 4)) { -+ sdio_writel(rtwsdio->sdio_func, val, addr, err_ret); -+ return; -+ } -+ -+ *(__le32 *)buf = cpu_to_le32(val); -+ -+ for (i = 0; i < 4; i++) { -+ sdio_writeb(rtwsdio->sdio_func, buf[i], addr + i, err_ret); -+ if (*err_ret) -+ return; -+ } -+} -+ -+static void rtw_sdio_writew(struct rtw_dev *rtwdev, u16 val, u32 addr, -+ int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u8 buf[2]; -+ int i; -+ -+ if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2)) { -+ sdio_writew(rtwsdio->sdio_func, val, addr, err_ret); -+ return; -+ } -+ -+ *(__le16 *)buf = cpu_to_le16(val); -+ -+ for (i = 0; i < 2; i++) { -+ sdio_writeb(rtwsdio->sdio_func, buf[i], addr + i, err_ret); -+ if (*err_ret) -+ return; -+ } -+} -+ -+static u32 rtw_sdio_readl(struct rtw_dev *rtwdev, u32 addr, int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u8 buf[4]; -+ int i; -+ -+ if (rtw_sdio_use_memcpy_io(rtwdev, addr, 4)) -+ return sdio_readl(rtwsdio->sdio_func, addr, err_ret); -+ -+ for (i = 0; i < 4; i++) { -+ buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret); -+ if (*err_ret) -+ return 0; -+ } -+ -+ return le32_to_cpu(*(__le32 *)buf); -+} -+ -+static u16 rtw_sdio_readw(struct rtw_dev *rtwdev, u32 addr, int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u8 buf[2]; -+ int i; -+ -+ if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2)) -+ return sdio_readw(rtwsdio->sdio_func, addr, err_ret); -+ -+ for (i = 0; i < 2; i++) { -+ buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret); -+ if (*err_ret) -+ return 0; -+ } -+ -+ return le16_to_cpu(*(__le16 *)buf); -+} -+ -+static u32 rtw_sdio_to_io_address(struct rtw_dev *rtwdev, u32 addr, -+ bool direct) -+{ -+ if (!direct) -+ return addr; -+ -+ if (!rtw_sdio_is_bus_addr(addr)) -+ addr |= WLAN_IOREG_OFFSET; -+ -+ return rtw_sdio_to_bus_offset(rtwdev, addr); -+} -+ -+static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr) -+{ -+ return !rtw_sdio_is_sdio30_supported(rtwdev) || -+ rtw_sdio_is_bus_addr(addr); -+} -+ -+static int rtw_sdio_indirect_reg_cfg(struct rtw_dev *rtwdev, u32 addr, u32 cfg) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ unsigned int retry; -+ u32 reg_cfg; -+ int ret; -+ u8 tmp; -+ -+ reg_cfg = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_CFG); -+ -+ rtw_sdio_writel(rtwdev, addr | cfg | BIT_SDIO_INDIRECT_REG_CFG_UNK20, -+ reg_cfg, &ret); -+ if (ret) -+ return ret; -+ -+ for (retry = 0; retry < RTW_SDIO_INDIRECT_RW_RETRIES; retry++) { -+ tmp = sdio_readb(rtwsdio->sdio_func, reg_cfg + 2, &ret); -+ if (!ret && (tmp & BIT(4))) -+ return 0; -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static u8 rtw_sdio_indirect_read8(struct rtw_dev *rtwdev, u32 addr, -+ int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u32 reg_data; -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_READ); -+ if (*err_ret) -+ return 0; -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ return sdio_readb(rtwsdio->sdio_func, reg_data, err_ret); -+} -+ -+static int rtw_sdio_indirect_read_bytes(struct rtw_dev *rtwdev, u32 addr, -+ u8 *buf, int count) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < count; i++) { -+ buf[i] = rtw_sdio_indirect_read8(rtwdev, addr + i, &ret); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+ -+static u16 rtw_sdio_indirect_read16(struct rtw_dev *rtwdev, u32 addr, -+ int *err_ret) -+{ -+ u32 reg_data; -+ u8 buf[2]; -+ -+ if (!IS_ALIGNED(addr, 2)) { -+ *err_ret = rtw_sdio_indirect_read_bytes(rtwdev, addr, buf, 2); -+ if (*err_ret) -+ return 0; -+ -+ return le16_to_cpu(*(__le16 *)buf); -+ } -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_READ); -+ if (*err_ret) -+ return 0; -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ return rtw_sdio_readw(rtwdev, reg_data, err_ret); -+} -+ -+static u32 rtw_sdio_indirect_read32(struct rtw_dev *rtwdev, u32 addr, -+ int *err_ret) -+{ -+ u32 reg_data; -+ u8 buf[4]; -+ -+ if (!IS_ALIGNED(addr, 4)) { -+ *err_ret = rtw_sdio_indirect_read_bytes(rtwdev, addr, buf, 4); -+ if (*err_ret) -+ return 0; -+ -+ return le32_to_cpu(*(__le32 *)buf); -+ } -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_READ); -+ if (*err_ret) -+ return 0; -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ return rtw_sdio_readl(rtwdev, reg_data, err_ret); -+} -+ -+static u8 rtw_sdio_read8(struct rtw_dev *rtwdev, u32 addr) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ int ret; -+ u8 val; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ val = sdio_readb(rtwsdio->sdio_func, addr, &ret); -+ else -+ val = rtw_sdio_indirect_read8(rtwdev, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio read8 failed (0x%x): %d", addr, ret); -+ -+ return val; -+} -+ -+static u16 rtw_sdio_read16(struct rtw_dev *rtwdev, u32 addr) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ int ret; -+ u16 val; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ val = rtw_sdio_readw(rtwdev, addr, &ret); -+ else -+ val = rtw_sdio_indirect_read16(rtwdev, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio read16 failed (0x%x): %d", addr, ret); -+ -+ return val; -+} -+ -+static u32 rtw_sdio_read32(struct rtw_dev *rtwdev, u32 addr) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ u32 val; -+ int ret; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ val = rtw_sdio_readl(rtwdev, addr, &ret); -+ else -+ val = rtw_sdio_indirect_read32(rtwdev, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio read32 failed (0x%x): %d", addr, ret); -+ -+ return val; -+} -+ -+static void rtw_sdio_indirect_write8(struct rtw_dev *rtwdev, u8 val, u32 addr, -+ int *err_ret) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ u32 reg_data; -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ sdio_writeb(rtwsdio->sdio_func, val, reg_data, err_ret); -+ if (*err_ret) -+ return; -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_WRITE); -+} -+ -+static void rtw_sdio_indirect_write16(struct rtw_dev *rtwdev, u16 val, u32 addr, -+ int *err_ret) -+{ -+ u32 reg_data; -+ -+ if (!IS_ALIGNED(addr, 2)) { -+ addr = rtw_sdio_to_io_address(rtwdev, addr, true); -+ rtw_sdio_writew(rtwdev, val, addr, err_ret); -+ return; -+ } -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ rtw_sdio_writew(rtwdev, val, reg_data, err_ret); -+ if (*err_ret) -+ return; -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_WRITE | -+ BIT_SDIO_INDIRECT_REG_CFG_WORD); -+} -+ -+static void rtw_sdio_indirect_write32(struct rtw_dev *rtwdev, u32 val, -+ u32 addr, int *err_ret) -+{ -+ u32 reg_data; -+ -+ if (!IS_ALIGNED(addr, 4)) { -+ addr = rtw_sdio_to_io_address(rtwdev, addr, true); -+ rtw_sdio_writel(rtwdev, val, addr, err_ret); -+ return; -+ } -+ -+ reg_data = rtw_sdio_to_bus_offset(rtwdev, REG_SDIO_INDIRECT_REG_DATA); -+ rtw_sdio_writel(rtwdev, val, reg_data, err_ret); -+ -+ *err_ret = rtw_sdio_indirect_reg_cfg(rtwdev, addr, -+ BIT_SDIO_INDIRECT_REG_CFG_WRITE | -+ BIT_SDIO_INDIRECT_REG_CFG_DWORD); -+} -+ -+static void rtw_sdio_write8(struct rtw_dev *rtwdev, u32 addr, u8 val) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ int ret; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ sdio_writeb(rtwsdio->sdio_func, val, addr, &ret); -+ else -+ rtw_sdio_indirect_write8(rtwdev, val, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio write8 failed (0x%x): %d", addr, ret); -+} -+ -+static void rtw_sdio_write16(struct rtw_dev *rtwdev, u32 addr, u16 val) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ int ret; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ rtw_sdio_writew(rtwdev, val, addr, &ret); -+ else -+ rtw_sdio_indirect_write16(rtwdev, val, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio write16 failed (0x%x): %d", addr, ret); -+} -+ -+static void rtw_sdio_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool direct, bus_claim; -+ int ret; -+ -+ direct = rtw_sdio_use_direct_io(rtwdev, addr); -+ addr = rtw_sdio_to_io_address(rtwdev, addr, direct); -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ if (direct) -+ rtw_sdio_writel(rtwdev, val, addr, &ret); -+ else -+ rtw_sdio_indirect_write32(rtwdev, val, addr, &ret); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, "sdio write32 failed (0x%x): %d", addr, ret); -+} -+ -+static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size, -+ enum rtw_tx_queue_type queue) -+{ -+ u32 txaddr; -+ -+ switch (queue) { -+ case RTW_TX_QUEUE_BCN: -+ case RTW_TX_QUEUE_H2C: -+ case RTW_TX_QUEUE_HI0: -+ txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_TXFF_HIGH); -+ break; -+ case RTW_TX_QUEUE_VI: -+ case RTW_TX_QUEUE_VO: -+ txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_TXFF_NORMAL); -+ break; -+ case RTW_TX_QUEUE_BE: -+ case RTW_TX_QUEUE_BK: -+ txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_TXFF_LOW); -+ break; -+ case RTW_TX_QUEUE_MGMT: -+ txaddr = FIELD_PREP(REG_SDIO_CMD_ADDR_MSK, -+ REG_SDIO_CMD_ADDR_TXFF_EXTRA); -+ break; -+ default: -+ rtw_warn(rtwdev, "Unsupported queue for TX addr: 0x%02x\n", -+ queue); -+ return 0; -+ } -+ -+ txaddr += DIV_ROUND_UP(size, 4); -+ -+ return txaddr; -+}; -+ -+static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ u32 rxaddr = rtwsdio->rx_addr++; -+ int ret; -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, -+ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count); -+ if (ret) -+ rtw_warn(rtwdev, -+ "Failed to read %zu byte(s) from SDIO port 0x%08x", -+ count, rxaddr); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ return ret; -+} -+ -+static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue, -+ size_t count) -+{ -+ unsigned int pages_free, pages_needed; -+ -+ if (rtw_chip_wcpu_11n(rtwdev)) { -+ u32 free_txpg; -+ -+ free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); -+ -+ switch (queue) { -+ case RTW_TX_QUEUE_BCN: -+ case RTW_TX_QUEUE_H2C: -+ case RTW_TX_QUEUE_HI0: -+ case RTW_TX_QUEUE_MGMT: -+ /* high */ -+ pages_free = free_txpg & 0xff; -+ break; -+ case RTW_TX_QUEUE_VI: -+ case RTW_TX_QUEUE_VO: -+ /* normal */ -+ pages_free = (free_txpg >> 8) & 0xff; -+ break; -+ case RTW_TX_QUEUE_BE: -+ case RTW_TX_QUEUE_BK: -+ /* low */ -+ pages_free = (free_txpg >> 16) & 0xff; -+ break; -+ default: -+ rtw_warn(rtwdev, "Unknown mapping for queue %u\n", queue); -+ return -EINVAL; -+ } -+ -+ /* add the pages from the public queue */ -+ pages_free += (free_txpg >> 24) & 0xff; -+ } else { -+ u32 free_txpg[3]; -+ -+ free_txpg[0] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); -+ free_txpg[1] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 4); -+ free_txpg[2] = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG + 8); -+ -+ switch (queue) { -+ case RTW_TX_QUEUE_BCN: -+ case RTW_TX_QUEUE_H2C: -+ case RTW_TX_QUEUE_HI0: -+ /* high */ -+ pages_free = free_txpg[0] & 0xfff; -+ break; -+ case RTW_TX_QUEUE_VI: -+ case RTW_TX_QUEUE_VO: -+ /* normal */ -+ pages_free = (free_txpg[0] >> 16) & 0xfff; -+ break; -+ case RTW_TX_QUEUE_BE: -+ case RTW_TX_QUEUE_BK: -+ /* low */ -+ pages_free = free_txpg[1] & 0xfff; -+ break; -+ case RTW_TX_QUEUE_MGMT: -+ /* extra */ -+ pages_free = free_txpg[2] & 0xfff; -+ break; -+ default: -+ rtw_warn(rtwdev, "Unknown mapping for queue %u\n", queue); -+ return -EINVAL; -+ } -+ -+ /* add the pages from the public queue */ -+ pages_free += (free_txpg[1] >> 16) & 0xfff; -+ } -+ -+ pages_needed = DIV_ROUND_UP(count, rtwdev->chip->page_size); -+ -+ if (pages_needed > pages_free) { -+ rtw_dbg(rtwdev, RTW_DBG_SDIO, -+ "Not enough free pages (%u needed, %u free) in queue %u for %zu bytes\n", -+ pages_needed, pages_free, queue, count); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static int rtw_sdio_write_port(struct rtw_dev *rtwdev, struct sk_buff *skb, -+ enum rtw_tx_queue_type queue) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool bus_claim; -+ size_t txsize; -+ u32 txaddr; -+ int ret; -+ -+ txaddr = rtw_sdio_get_tx_addr(rtwdev, skb->len, queue); -+ if (!txaddr) -+ return -EINVAL; -+ -+ txsize = sdio_align_size(rtwsdio->sdio_func, skb->len); -+ -+ ret = rtw_sdio_check_free_txpg(rtwdev, queue, txsize); -+ if (ret) -+ return ret; -+ -+ if (!IS_ALIGNED((unsigned long)skb->data, RTW_SDIO_DATA_PTR_ALIGN)) -+ rtw_warn(rtwdev, "Got unaligned SKB in %s() for queue %u\n", -+ __func__, queue); -+ -+ bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); -+ -+ if (bus_claim) -+ sdio_claim_host(rtwsdio->sdio_func); -+ -+ ret = sdio_memcpy_toio(rtwsdio->sdio_func, txaddr, skb->data, txsize); -+ -+ if (bus_claim) -+ sdio_release_host(rtwsdio->sdio_func); -+ -+ if (ret) -+ rtw_warn(rtwdev, -+ "Failed to write %zu byte(s) to SDIO port 0x%08x", -+ txsize, txaddr); -+ -+ return ret; -+} -+ -+static void rtw_sdio_init(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ rtwsdio->irq_mask = REG_SDIO_HIMR_RX_REQUEST | REG_SDIO_HIMR_CPWM1; -+} -+ -+static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev) -+{ -+ u8 size, timeout; -+ -+ if (rtw_chip_wcpu_11n(rtwdev)) { -+ size = 0x6; -+ timeout = 0x6; -+ } else { -+ size = 0xff; -+ timeout = 0x1; -+ } -+ -+ /* Make the firmware honor the size limit configured below */ -+ rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); -+ -+ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); -+ -+ rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, -+ FIELD_PREP(BIT_RXDMA_AGG_PG_TH, size) | -+ FIELD_PREP(BIT_DMA_AGG_TO_V1, timeout)); -+ -+ rtw_write8_set(rtwdev, REG_RXDMA_MODE, BIT_DMA_MODE); -+} -+ -+static void rtw_sdio_enable_interrupt(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ rtw_write32(rtwdev, REG_SDIO_HIMR, rtwsdio->irq_mask); -+} -+ -+static void rtw_sdio_disable_interrupt(struct rtw_dev *rtwdev) -+{ -+ rtw_write32(rtwdev, REG_SDIO_HIMR, 0x0); -+} -+ -+static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb, -+ u8 queue) -+{ -+ switch (queue) { -+ case RTW_TX_QUEUE_BCN: -+ return TX_DESC_QSEL_BEACON; -+ case RTW_TX_QUEUE_H2C: -+ return TX_DESC_QSEL_H2C; -+ case RTW_TX_QUEUE_MGMT: -+ if (rtw_chip_wcpu_11n(rtwdev)) -+ return TX_DESC_QSEL_HIGH; -+ else -+ return TX_DESC_QSEL_MGMT; -+ case RTW_TX_QUEUE_HI0: -+ return TX_DESC_QSEL_HIGH; -+ default: -+ return skb->priority; -+ } -+} -+ -+static int rtw_sdio_setup(struct rtw_dev *rtwdev) -+{ -+ /* nothing to do */ -+ return 0; -+} -+ -+static int rtw_sdio_start(struct rtw_dev *rtwdev) -+{ -+ rtw_sdio_enable_rx_aggregation(rtwdev); -+ rtw_sdio_enable_interrupt(rtwdev); -+ -+ return 0; -+} -+ -+static void rtw_sdio_stop(struct rtw_dev *rtwdev) -+{ -+ rtw_sdio_disable_interrupt(rtwdev); -+} -+ -+static void rtw_sdio_deep_ps_enter(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ bool tx_empty = true; -+ u8 queue; -+ -+ if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) { -+ /* Deep PS state is not allowed to TX-DMA */ -+ for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { -+ /* BCN queue is rsvd page, does not have DMA interrupt -+ * H2C queue is managed by firmware -+ */ -+ if (queue == RTW_TX_QUEUE_BCN || -+ queue == RTW_TX_QUEUE_H2C) -+ continue; -+ -+ /* check if there is any skb DMAing */ -+ if (skb_queue_len(&rtwsdio->tx_queue[queue])) { -+ tx_empty = false; -+ break; -+ } -+ } -+ } -+ -+ if (!tx_empty) { -+ rtw_dbg(rtwdev, RTW_DBG_PS, -+ "TX path not empty, cannot enter deep power save state\n"); -+ return; -+ } -+ -+ set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); -+ rtw_power_mode_change(rtwdev, true); -+} -+ -+static void rtw_sdio_deep_ps_leave(struct rtw_dev *rtwdev) -+{ -+ if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) -+ rtw_power_mode_change(rtwdev, false); -+} -+ -+static void rtw_sdio_deep_ps(struct rtw_dev *rtwdev, bool enter) -+{ -+ if (enter && !test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) -+ rtw_sdio_deep_ps_enter(rtwdev); -+ -+ if (!enter && test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) -+ rtw_sdio_deep_ps_leave(rtwdev); -+} -+ -+static void rtw_sdio_tx_kick_off(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ queue_work(rtwsdio->txwq, &rtwsdio->tx_handler_data->work); -+} -+ -+static void rtw_sdio_link_ps(struct rtw_dev *rtwdev, bool enter) -+{ -+ /* nothing to do */ -+} -+ -+static void rtw_sdio_interface_cfg(struct rtw_dev *rtwdev) -+{ -+ u32 val; -+ -+ rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); -+ -+ val = rtw_read32(rtwdev, REG_SDIO_TX_CTRL); -+ val &= 0xfff8; -+ rtw_write32(rtwdev, REG_SDIO_TX_CTRL, val); -+} -+ -+static struct rtw_sdio_tx_data *rtw_sdio_get_tx_data(struct sk_buff *skb) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ -+ BUILD_BUG_ON(sizeof(struct rtw_sdio_tx_data) > -+ sizeof(info->status.status_driver_data)); -+ -+ return (struct rtw_sdio_tx_data *)info->status.status_driver_data; -+} -+ -+static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ struct sk_buff *skb, -+ enum rtw_tx_queue_type queue) -+{ -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ unsigned long data_addr, aligned_addr; -+ size_t offset; -+ u8 *pkt_desc; -+ -+ pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); -+ -+ data_addr = (unsigned long)pkt_desc; -+ aligned_addr = ALIGN(data_addr, RTW_SDIO_DATA_PTR_ALIGN); -+ -+ if (data_addr != aligned_addr) { -+ /* Ensure that the start of the pkt_desc is always aligned at -+ * RTW_SDIO_DATA_PTR_ALIGN. -+ */ -+ offset = RTW_SDIO_DATA_PTR_ALIGN - (aligned_addr - data_addr); -+ -+ pkt_desc = skb_push(skb, offset); -+ -+ /* By inserting padding to align the start of the pkt_desc we -+ * need to inform the firmware that the actual data starts at -+ * a different offset than normal. -+ */ -+ pkt_info->offset += offset; -+ } -+ -+ memset(pkt_desc, 0, chip->tx_pkt_desc_sz); -+ -+ pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); -+ -+ rtw_tx_fill_tx_desc(pkt_info, skb); -+ rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc); -+} -+ -+static int rtw_sdio_write_data(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ struct sk_buff *skb, -+ enum rtw_tx_queue_type queue) -+{ -+ int ret; -+ -+ rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue); -+ -+ ret = rtw_sdio_write_port(rtwdev, skb, queue); -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+static int rtw_sdio_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, -+ u32 size) -+{ -+ struct rtw_tx_pkt_info pkt_info = {}; -+ struct sk_buff *skb; -+ -+ skb = rtw_tx_write_data_rsvd_page_get(rtwdev, &pkt_info, buf, size); -+ if (!skb) -+ return -ENOMEM; -+ -+ return rtw_sdio_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_BCN); -+} -+ -+static int rtw_sdio_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) -+{ -+ struct rtw_tx_pkt_info pkt_info = {}; -+ struct sk_buff *skb; -+ -+ skb = rtw_tx_write_data_h2c_get(rtwdev, &pkt_info, buf, size); -+ if (!skb) -+ return -ENOMEM; -+ -+ return rtw_sdio_write_data(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_H2C); -+} -+ -+static int rtw_sdio_tx_write(struct rtw_dev *rtwdev, -+ struct rtw_tx_pkt_info *pkt_info, -+ struct sk_buff *skb) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ enum rtw_tx_queue_type queue = rtw_tx_queue_mapping(skb); -+ struct rtw_sdio_tx_data *tx_data; -+ -+ rtw_sdio_tx_skb_prepare(rtwdev, pkt_info, skb, queue); -+ -+ tx_data = rtw_sdio_get_tx_data(skb); -+ tx_data->sn = pkt_info->sn; -+ -+ skb_queue_tail(&rtwsdio->tx_queue[queue], skb); -+ -+ return 0; -+} -+ -+static void rtw_sdio_tx_err_isr(struct rtw_dev *rtwdev) -+{ -+ u32 val = rtw_read32(rtwdev, REG_TXDMA_STATUS); -+ -+ rtw_write32(rtwdev, REG_TXDMA_STATUS, val); -+} -+ -+static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb, -+ u32 pkt_offset, struct rtw_rx_pkt_stat *pkt_stat, -+ struct ieee80211_rx_status *rx_status) -+{ -+ *IEEE80211_SKB_RXCB(skb) = *rx_status; -+ -+ if (pkt_stat->is_c2h) { -+ skb_put(skb, pkt_stat->pkt_len + pkt_offset); -+ rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); -+ return; -+ } -+ -+ skb_put(skb, pkt_stat->pkt_len); -+ skb_reserve(skb, pkt_offset); -+ -+ rtw_rx_stats(rtwdev, pkt_stat->vif, skb); -+ -+ ieee80211_rx_irqsafe(rtwdev->hw, skb); -+} -+ -+static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ u32 pkt_desc_sz = chip->rx_pkt_desc_sz; -+ struct ieee80211_rx_status rx_status; -+ struct rtw_rx_pkt_stat pkt_stat; -+ struct sk_buff *skb, *split_skb; -+ u32 pkt_offset, curr_pkt_len; -+ size_t bufsz; -+ u8 *rx_desc; -+ int ret; -+ -+ bufsz = sdio_align_size(rtwsdio->sdio_func, rx_len); -+ -+ skb = dev_alloc_skb(bufsz); -+ if (!skb) -+ return; -+ -+ ret = rtw_sdio_read_port(rtwdev, skb->data, bufsz); -+ if (ret) { -+ dev_kfree_skb_any(skb); -+ return; -+ } -+ -+ while (true) { -+ rx_desc = skb->data; -+ chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, -+ &rx_status); -+ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + -+ pkt_stat.shift; -+ -+ curr_pkt_len = ALIGN(pkt_offset + pkt_stat.pkt_len, -+ RTW_SDIO_DATA_PTR_ALIGN); -+ -+ if ((curr_pkt_len + pkt_desc_sz) >= rx_len) { -+ /* Use the original skb (with it's adjusted offset) -+ * when processing the last (or even the only) entry to -+ * have it's memory freed automatically. -+ */ -+ rtw_sdio_rx_skb(rtwdev, skb, pkt_offset, &pkt_stat, -+ &rx_status); -+ break; -+ } -+ -+ split_skb = dev_alloc_skb(curr_pkt_len); -+ if (!split_skb) { -+ rtw_sdio_rx_skb(rtwdev, skb, pkt_offset, &pkt_stat, -+ &rx_status); -+ break; -+ } -+ -+ skb_copy_header(split_skb, skb); -+ memcpy(split_skb->data, skb->data, curr_pkt_len); -+ -+ rtw_sdio_rx_skb(rtwdev, split_skb, pkt_offset, &pkt_stat, -+ &rx_status); -+ -+ /* Move to the start of the next RX descriptor */ -+ skb_reserve(skb, curr_pkt_len); -+ rx_len -= curr_pkt_len; -+ } -+} -+ -+static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) -+{ -+ u32 rx_len, total_rx_bytes = 0; -+ -+ while (total_rx_bytes < SZ_64K) { -+ if (rtw_chip_wcpu_11n(rtwdev)) -+ rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); -+ else -+ rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN); -+ -+ if (!rx_len) -+ break; -+ -+ rtw_sdio_rxfifo_recv(rtwdev, rx_len); -+ -+ total_rx_bytes += rx_len; -+ } -+} -+ -+static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func) -+{ -+ struct ieee80211_hw *hw = sdio_get_drvdata(sdio_func); -+ struct rtw_sdio *rtwsdio; -+ struct rtw_dev *rtwdev; -+ u32 hisr; -+ -+ rtwdev = hw->priv; -+ rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ rtwsdio->irq_thread = current; -+ -+ hisr = rtw_read32(rtwdev, REG_SDIO_HISR); -+ -+ if (hisr & REG_SDIO_HISR_TXERR) -+ rtw_sdio_tx_err_isr(rtwdev); -+ if (hisr & REG_SDIO_HISR_RX_REQUEST) { -+ hisr &= ~REG_SDIO_HISR_RX_REQUEST; -+ rtw_sdio_rx_isr(rtwdev); -+ } -+ -+ rtw_write32(rtwdev, REG_SDIO_HISR, hisr); -+ -+ rtwsdio->irq_thread = NULL; -+} -+ -+static int __maybe_unused rtw_sdio_suspend(struct device *dev) -+{ -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ struct ieee80211_hw *hw = dev_get_drvdata(dev); -+ struct rtw_dev *rtwdev = hw->priv; -+ int ret; -+ -+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); -+ if (ret) -+ rtw_err(rtwdev, "Failed to host PM flag MMC_PM_KEEP_POWER"); -+ -+ return ret; -+} -+ -+static int __maybe_unused rtw_sdio_resume(struct device *dev) -+{ -+ return 0; -+} -+ -+SIMPLE_DEV_PM_OPS(rtw_sdio_pm_ops, rtw_sdio_suspend, rtw_sdio_resume); -+EXPORT_SYMBOL(rtw_sdio_pm_ops); -+ -+static int rtw_sdio_claim(struct rtw_dev *rtwdev, struct sdio_func *sdio_func) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ int ret; -+ -+ sdio_claim_host(sdio_func); -+ -+ ret = sdio_enable_func(sdio_func); -+ if (ret) { -+ rtw_err(rtwdev, "Failed to enable SDIO func"); -+ goto err_release_host; -+ } -+ -+ ret = sdio_set_block_size(sdio_func, RTW_SDIO_BLOCK_SIZE); -+ if (ret) { -+ rtw_err(rtwdev, "Failed to set SDIO block size to 512"); -+ goto err_disable_func; -+ } -+ -+ rtwsdio->sdio_func = sdio_func; -+ -+ rtwsdio->sdio3_bus_mode = mmc_card_uhs(sdio_func->card); -+ -+ sdio_set_drvdata(sdio_func, rtwdev->hw); -+ SET_IEEE80211_DEV(rtwdev->hw, &sdio_func->dev); -+ -+ sdio_release_host(sdio_func); -+ -+ return 0; -+ -+err_disable_func: -+ sdio_disable_func(sdio_func); -+err_release_host: -+ sdio_release_host(sdio_func); -+ return ret; -+} -+ -+static void rtw_sdio_declaim(struct rtw_dev *rtwdev, -+ struct sdio_func *sdio_func) -+{ -+ sdio_claim_host(sdio_func); -+ sdio_disable_func(sdio_func); -+ sdio_release_host(sdio_func); -+} -+ -+static struct rtw_hci_ops rtw_sdio_ops = { -+ .tx_write = rtw_sdio_tx_write, -+ .tx_kick_off = rtw_sdio_tx_kick_off, -+ .setup = rtw_sdio_setup, -+ .start = rtw_sdio_start, -+ .stop = rtw_sdio_stop, -+ .deep_ps = rtw_sdio_deep_ps, -+ .link_ps = rtw_sdio_link_ps, -+ .interface_cfg = rtw_sdio_interface_cfg, -+ -+ .read8 = rtw_sdio_read8, -+ .read16 = rtw_sdio_read16, -+ .read32 = rtw_sdio_read32, -+ .write8 = rtw_sdio_write8, -+ .write16 = rtw_sdio_write16, -+ .write32 = rtw_sdio_write32, -+ .write_data_rsvd_page = rtw_sdio_write_data_rsvd_page, -+ .write_data_h2c = rtw_sdio_write_data_h2c, -+}; -+ -+static int rtw_sdio_request_irq(struct rtw_dev *rtwdev, -+ struct sdio_func *sdio_func) -+{ -+ int ret; -+ -+ sdio_claim_host(sdio_func); -+ ret = sdio_claim_irq(sdio_func, &rtw_sdio_handle_interrupt); -+ sdio_release_host(sdio_func); -+ -+ if (ret) { -+ rtw_err(rtwdev, "failed to claim SDIO IRQ"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, -+ struct sk_buff *skb) -+{ -+ struct rtw_sdio_tx_data *tx_data = rtw_sdio_get_tx_data(skb); -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_hw *hw = rtwdev->hw; -+ -+ /* enqueue to wait for tx report */ -+ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -+ rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); -+ return; -+ } -+ -+ /* always ACK for others, then they won't be marked as drop */ -+ ieee80211_tx_info_clear_status(info); -+ if (info->flags & IEEE80211_TX_CTL_NO_ACK) -+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; -+ else -+ info->flags |= IEEE80211_TX_STAT_ACK; -+ -+ ieee80211_tx_status_irqsafe(hw, skb); -+} -+ -+static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev, -+ enum rtw_tx_queue_type queue) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ struct sk_buff *skb; -+ int ret; -+ -+ skb = skb_dequeue(&rtwsdio->tx_queue[queue]); -+ if (!skb) -+ return; -+ -+ ret = rtw_sdio_write_port(rtwdev, skb, queue); -+ if (ret) { -+ skb_queue_head(&rtwsdio->tx_queue[queue], skb); -+ return; -+ } -+ -+ if (queue <= RTW_TX_QUEUE_VO) -+ rtw_sdio_indicate_tx_status(rtwdev, skb); -+ else -+ dev_kfree_skb_any(skb); -+} -+ -+static void rtw_sdio_tx_handler(struct work_struct *work) -+{ -+ struct rtw_sdio_work_data *work_data = -+ container_of(work, struct rtw_sdio_work_data, work); -+ struct rtw_sdio *rtwsdio; -+ struct rtw_dev *rtwdev; -+ int limit, queue; -+ -+ rtwdev = work_data->rtwdev; -+ rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) -+ rtw_sdio_deep_ps_leave(rtwdev); -+ -+ for (queue = RTK_MAX_TX_QUEUE_NUM - 1; queue >= 0; queue--) { -+ for (limit = 0; limit < 1000; limit++) { -+ rtw_sdio_process_tx_queue(rtwdev, queue); -+ -+ if (skb_queue_empty(&rtwsdio->tx_queue[queue])) -+ break; -+ } -+ } -+} -+ -+static void rtw_sdio_free_irq(struct rtw_dev *rtwdev, -+ struct sdio_func *sdio_func) -+{ -+ sdio_claim_host(sdio_func); -+ sdio_release_irq(sdio_func); -+ sdio_release_host(sdio_func); -+} -+ -+static int rtw_sdio_init_tx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ int i; -+ -+ rtwsdio->txwq = create_singlethread_workqueue("rtw88_sdio: tx wq"); -+ if (!rtwsdio->txwq) { -+ rtw_err(rtwdev, "failed to create TX work queue\n"); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) -+ skb_queue_head_init(&rtwsdio->tx_queue[i]); -+ rtwsdio->tx_handler_data = kmalloc(sizeof(*rtwsdio->tx_handler_data), -+ GFP_KERNEL); -+ if (!rtwsdio->tx_handler_data) -+ goto err_destroy_wq; -+ -+ rtwsdio->tx_handler_data->rtwdev = rtwdev; -+ INIT_WORK(&rtwsdio->tx_handler_data->work, rtw_sdio_tx_handler); -+ -+ return 0; -+ -+err_destroy_wq: -+ destroy_workqueue(rtwsdio->txwq); -+ return -ENOMEM; -+} -+ -+static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ int i; -+ -+ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) -+ skb_queue_purge(&rtwsdio->tx_queue[i]); -+ -+ flush_workqueue(rtwsdio->txwq); -+ destroy_workqueue(rtwsdio->txwq); -+ kfree(rtwsdio->tx_handler_data); -+} -+ -+int rtw_sdio_probe(struct sdio_func *sdio_func, -+ const struct sdio_device_id *id) -+{ -+ struct ieee80211_hw *hw; -+ struct rtw_dev *rtwdev; -+ int drv_data_size; -+ int ret; -+ -+ drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_sdio); -+ hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops); -+ if (!hw) { -+ dev_err(&sdio_func->dev, "failed to allocate hw"); -+ return -ENOMEM; -+ } -+ -+ rtwdev = hw->priv; -+ rtwdev->hw = hw; -+ rtwdev->dev = &sdio_func->dev; -+ rtwdev->chip = (struct rtw_chip_info *)id->driver_data; -+ rtwdev->hci.ops = &rtw_sdio_ops; -+ rtwdev->hci.type = RTW_HCI_TYPE_SDIO; -+ -+ ret = rtw_core_init(rtwdev); -+ if (ret) -+ goto err_release_hw; -+ -+ rtw_dbg(rtwdev, RTW_DBG_SDIO, -+ "rtw88 SDIO probe: vendor=0x%04x device=%04x class=%02x", -+ id->vendor, id->device, id->class); -+ -+ ret = rtw_sdio_claim(rtwdev, sdio_func); -+ if (ret) { -+ rtw_err(rtwdev, "failed to claim SDIO device"); -+ goto err_deinit_core; -+ } -+ -+ rtw_sdio_init(rtwdev); -+ -+ ret = rtw_sdio_init_tx(rtwdev); -+ if (ret) { -+ rtw_err(rtwdev, "failed to init SDIO TX queue\n"); -+ goto err_sdio_declaim; -+ } -+ -+ ret = rtw_chip_info_setup(rtwdev); -+ if (ret) { -+ rtw_err(rtwdev, "failed to setup chip information"); -+ goto err_destroy_txwq; -+ } -+ -+ ret = rtw_sdio_request_irq(rtwdev, sdio_func); -+ if (ret) -+ goto err_destroy_txwq; -+ -+ ret = rtw_register_hw(rtwdev, hw); -+ if (ret) { -+ rtw_err(rtwdev, "failed to register hw"); -+ goto err_free_irq; -+ } -+ -+ return 0; -+ -+err_free_irq: -+ rtw_sdio_free_irq(rtwdev, sdio_func); -+err_destroy_txwq: -+ rtw_sdio_deinit_tx(rtwdev); -+err_sdio_declaim: -+ rtw_sdio_declaim(rtwdev, sdio_func); -+err_deinit_core: -+ rtw_core_deinit(rtwdev); -+err_release_hw: -+ ieee80211_free_hw(hw); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rtw_sdio_probe); -+ -+void rtw_sdio_remove(struct sdio_func *sdio_func) -+{ -+ struct ieee80211_hw *hw = sdio_get_drvdata(sdio_func); -+ struct rtw_dev *rtwdev; -+ -+ if (!hw) -+ return; -+ -+ rtwdev = hw->priv; -+ -+ rtw_unregister_hw(rtwdev, hw); -+ rtw_sdio_disable_interrupt(rtwdev); -+ rtw_sdio_free_irq(rtwdev, sdio_func); -+ rtw_sdio_declaim(rtwdev, sdio_func); -+ rtw_sdio_deinit_tx(rtwdev); -+ rtw_core_deinit(rtwdev); -+ ieee80211_free_hw(hw); -+} -+EXPORT_SYMBOL(rtw_sdio_remove); -+ -+void rtw_sdio_shutdown(struct device *dev) -+{ -+ struct sdio_func *sdio_func = dev_to_sdio_func(dev); -+ const struct rtw_chip_info *chip; -+ struct ieee80211_hw *hw; -+ struct rtw_dev *rtwdev; -+ -+ hw = sdio_get_drvdata(sdio_func); -+ if (!hw) -+ return; -+ -+ rtwdev = hw->priv; -+ chip = rtwdev->chip; -+ -+ if (chip->ops->shutdown) -+ chip->ops->shutdown(rtwdev); -+} -+EXPORT_SYMBOL(rtw_sdio_shutdown); -+ -+MODULE_AUTHOR("Martin Blumenstingl"); -+MODULE_AUTHOR("Jernej Skrabec"); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless SDIO driver"); -+MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/sdio.h -@@ -0,0 +1,178 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright (C) 2021 Martin Blumenstingl -+ * Copyright (C) 2021 Jernej Skrabec -+ */ -+ -+#ifndef __REG_SDIO_H_ -+#define __REG_SDIO_H_ -+ -+/* I/O bus domain address mapping */ -+#define SDIO_LOCAL_OFFSET 0x10250000 -+#define WLAN_IOREG_OFFSET 0x10260000 -+#define FIRMWARE_FIFO_OFFSET 0x10270000 -+#define TX_HIQ_OFFSET 0x10310000 -+#define TX_MIQ_OFFSET 0x10320000 -+#define TX_LOQ_OFFSET 0x10330000 -+#define TX_EPQ_OFFSET 0x10350000 -+#define RX_RX0FF_OFFSET 0x10340000 -+ -+#define RTW_SDIO_BUS_MSK 0xffff0000 -+#define SDIO_LOCAL_REG_MSK 0x00000fff -+#define WLAN_IOREG_REG_MSK 0x0000ffff -+ -+/* SDIO Tx Control */ -+#define REG_SDIO_TX_CTRL (SDIO_LOCAL_OFFSET + 0x0000) -+ -+/*SDIO status timeout*/ -+#define REG_SDIO_TIMEOUT (SDIO_LOCAL_OFFSET + 0x0002) -+ -+/* SDIO Host Interrupt Mask */ -+#define REG_SDIO_HIMR (SDIO_LOCAL_OFFSET + 0x0014) -+#define REG_SDIO_HIMR_RX_REQUEST BIT(0) -+#define REG_SDIO_HIMR_AVAL BIT(1) -+#define REG_SDIO_HIMR_TXERR BIT(2) -+#define REG_SDIO_HIMR_RXERR BIT(3) -+#define REG_SDIO_HIMR_TXFOVW BIT(4) -+#define REG_SDIO_HIMR_RXFOVW BIT(5) -+#define REG_SDIO_HIMR_TXBCNOK BIT(6) -+#define REG_SDIO_HIMR_TXBCNERR BIT(7) -+#define REG_SDIO_HIMR_BCNERLY_INT BIT(16) -+#define REG_SDIO_HIMR_C2HCMD BIT(17) -+#define REG_SDIO_HIMR_CPWM1 BIT(18) -+#define REG_SDIO_HIMR_CPWM2 BIT(19) -+#define REG_SDIO_HIMR_HSISR_IND BIT(20) -+#define REG_SDIO_HIMR_GTINT3_IND BIT(21) -+#define REG_SDIO_HIMR_GTINT4_IND BIT(22) -+#define REG_SDIO_HIMR_PSTIMEOUT BIT(23) -+#define REG_SDIO_HIMR_OCPINT BIT(24) -+#define REG_SDIO_HIMR_ATIMEND BIT(25) -+#define REG_SDIO_HIMR_ATIMEND_E BIT(26) -+#define REG_SDIO_HIMR_CTWEND BIT(27) -+/* the following two are RTL8188 SDIO Specific */ -+#define REG_SDIO_HIMR_MCU_ERR BIT(28) -+#define REG_SDIO_HIMR_TSF_BIT32_TOGGLE BIT(29) -+ -+/* SDIO Host Interrupt Service Routine */ -+#define REG_SDIO_HISR (SDIO_LOCAL_OFFSET + 0x0018) -+#define REG_SDIO_HISR_RX_REQUEST BIT(0) -+#define REG_SDIO_HISR_AVAL BIT(1) -+#define REG_SDIO_HISR_TXERR BIT(2) -+#define REG_SDIO_HISR_RXERR BIT(3) -+#define REG_SDIO_HISR_TXFOVW BIT(4) -+#define REG_SDIO_HISR_RXFOVW BIT(5) -+#define REG_SDIO_HISR_TXBCNOK BIT(6) -+#define REG_SDIO_HISR_TXBCNERR BIT(7) -+#define REG_SDIO_HISR_BCNERLY_INT BIT(16) -+#define REG_SDIO_HISR_C2HCMD BIT(17) -+#define REG_SDIO_HISR_CPWM1 BIT(18) -+#define REG_SDIO_HISR_CPWM2 BIT(19) -+#define REG_SDIO_HISR_HSISR_IND BIT(20) -+#define REG_SDIO_HISR_GTINT3_IND BIT(21) -+#define REG_SDIO_HISR_GTINT4_IND BIT(22) -+#define REG_SDIO_HISR_PSTIMEOUT BIT(23) -+#define REG_SDIO_HISR_OCPINT BIT(24) -+#define REG_SDIO_HISR_ATIMEND BIT(25) -+#define REG_SDIO_HISR_ATIMEND_E BIT(26) -+#define REG_SDIO_HISR_CTWEND BIT(27) -+/* the following two are RTL8188 SDIO Specific */ -+#define REG_SDIO_HISR_MCU_ERR BIT(28) -+#define REG_SDIO_HISR_TSF_BIT32_TOGGLE BIT(29) -+ -+/* HCI Current Power Mode */ -+#define REG_SDIO_HCPWM (SDIO_LOCAL_OFFSET + 0x0019) -+/* RXDMA Request Length */ -+#define REG_SDIO_RX0_REQ_LEN (SDIO_LOCAL_OFFSET + 0x001C) -+/* OQT Free Page */ -+#define REG_SDIO_OQT_FREE_PG (SDIO_LOCAL_OFFSET + 0x001E) -+/* Free Tx Buffer Page */ -+#define REG_SDIO_FREE_TXPG (SDIO_LOCAL_OFFSET + 0x0020) -+/* HCI Current Power Mode 1 */ -+#define REG_SDIO_HCPWM1 (SDIO_LOCAL_OFFSET + 0x0024) -+/* HCI Current Power Mode 2 */ -+#define REG_SDIO_HCPWM2 (SDIO_LOCAL_OFFSET + 0x0026) -+/* Free Tx Page Sequence */ -+#define REG_SDIO_FREE_TXPG_SEQ (SDIO_LOCAL_OFFSET + 0x0028) -+/* HTSF Information */ -+#define REG_SDIO_HTSFR_INFO (SDIO_LOCAL_OFFSET + 0x0030) -+#define REG_SDIO_HCPWM1_V2 (SDIO_LOCAL_OFFSET + 0x0038) -+/* H2C */ -+#define REG_SDIO_H2C (SDIO_LOCAL_OFFSET + 0x0060) -+/* HCI Request Power Mode 1 */ -+#define REG_SDIO_HRPWM1 (SDIO_LOCAL_OFFSET + 0x0080) -+/* HCI Request Power Mode 2 */ -+#define REG_SDIO_HRPWM2 (SDIO_LOCAL_OFFSET + 0x0082) -+/* HCI Power Save Clock */ -+#define REG_SDIO_HPS_CLKR (SDIO_LOCAL_OFFSET + 0x0084) -+/* SDIO HCI Suspend Control */ -+#define REG_SDIO_HSUS_CTRL (SDIO_LOCAL_OFFSET + 0x0086) -+#define BIT_HCI_SUS_REQ BIT(0) -+#define BIT_HCI_RESUME_RDY BIT(1) -+/* SDIO Host Extension Interrupt Mask Always */ -+#define REG_SDIO_HIMR_ON (SDIO_LOCAL_OFFSET + 0x0090) -+/* SDIO Host Extension Interrupt Status Always */ -+#define REG_SDIO_HISR_ON (SDIO_LOCAL_OFFSET + 0x0091) -+ -+#define REG_SDIO_INDIRECT_REG_CFG (SDIO_LOCAL_OFFSET + 0x0040) -+#define BIT_SDIO_INDIRECT_REG_CFG_WORD BIT(16) -+#define BIT_SDIO_INDIRECT_REG_CFG_DWORD BIT(17) -+#define BIT_SDIO_INDIRECT_REG_CFG_WRITE BIT(18) -+#define BIT_SDIO_INDIRECT_REG_CFG_READ BIT(19) -+#define BIT_SDIO_INDIRECT_REG_CFG_UNK20 BIT(20) -+#define REG_SDIO_INDIRECT_REG_DATA (SDIO_LOCAL_OFFSET + 0x0044) -+ -+/* Sdio Address for SDIO Local Reg, TRX FIFO, MAC Reg */ -+#define REG_SDIO_CMD_ADDR_MSK GENMASK(16, 13) -+#define REG_SDIO_CMD_ADDR_SDIO_REG 0 -+#define REG_SDIO_CMD_ADDR_MAC_REG 8 -+#define REG_SDIO_CMD_ADDR_TXFF_HIGH 4 -+#define REG_SDIO_CMD_ADDR_TXFF_LOW 6 -+#define REG_SDIO_CMD_ADDR_TXFF_NORMAL 5 -+#define REG_SDIO_CMD_ADDR_TXFF_EXTRA 7 -+#define REG_SDIO_CMD_ADDR_RXFF 7 -+ -+#define RTW_SDIO_BLOCK_SIZE 512 -+#define RTW_SDIO_ADDR_RX_RX0FF_GEN(_id) (0x0e000 | ((_id) & 0x3)) -+ -+#define RTW_SDIO_DATA_PTR_ALIGN 8 -+ -+struct sdio_func; -+struct sdio_device_id; -+ -+struct rtw_sdio_tx_data { -+ u8 sn; -+}; -+ -+struct rtw_sdio_work_data { -+ struct work_struct work; -+ struct rtw_dev *rtwdev; -+}; -+ -+struct rtw_sdio { -+ struct sdio_func *sdio_func; -+ -+ u32 irq_mask; -+ u8 rx_addr; -+ bool sdio3_bus_mode; -+ -+ void *irq_thread; -+ -+ struct workqueue_struct *txwq; -+ struct rtw_sdio_work_data *tx_handler_data; -+ struct sk_buff_head tx_queue[RTK_MAX_TX_QUEUE_NUM]; -+}; -+ -+extern const struct dev_pm_ops rtw_sdio_pm_ops; -+ -+int rtw_sdio_probe(struct sdio_func *sdio_func, -+ const struct sdio_device_id *id); -+void rtw_sdio_remove(struct sdio_func *sdio_func); -+void rtw_sdio_shutdown(struct device *dev); -+ -+static inline bool rtw_sdio_is_sdio30_supported(struct rtw_dev *rtwdev) -+{ -+ struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; -+ -+ return rtwsdio->sdio3_bus_mode; -+} -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/026-wifi-rtw88-mac-Support-SDIO-specific-bits-in-the-pow.patch b/package/kernel/mac80211/patches/rtl/026-wifi-rtw88-mac-Support-SDIO-specific-bits-in-the-pow.patch deleted file mode 100644 index 534836590..000000000 --- a/package/kernel/mac80211/patches/rtl/026-wifi-rtw88-mac-Support-SDIO-specific-bits-in-the-pow.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b722e5b130bcaa8224c93c6625685d8276742cbd Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:23 +0200 -Subject: [PATCH 26/45] wifi: rtw88: mac: Support SDIO specific bits in the - power on sequence - -Add the code specific to SDIO HCI in the MAC power on sequence. This is -based on the RTL8822BS and RTL8822CS vendor drivers. - -Co-developed-by: Jernej Skrabec -Signed-off-by: Jernej Skrabec -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-4-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 47 +++++++++++++++++++++--- - 1 file changed, 42 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -61,6 +61,7 @@ EXPORT_SYMBOL(rtw_set_channel_mac); - - static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) - { -+ unsigned int retry; - u32 value32; - u8 value8; - -@@ -78,6 +79,28 @@ static int rtw_mac_pre_system_cfg(struct - case RTW_HCI_TYPE_PCIE: - rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw_write8_clr(rtwdev, REG_SDIO_HSUS_CTRL, BIT_HCI_SUS_REQ); -+ -+ for (retry = 0; retry < RTW_PWR_POLLING_CNT; retry++) { -+ if (rtw_read8(rtwdev, REG_SDIO_HSUS_CTRL) & BIT_HCI_RESUME_RDY) -+ break; -+ -+ usleep_range(10, 50); -+ } -+ -+ if (retry == RTW_PWR_POLLING_CNT) { -+ rtw_err(rtwdev, "failed to poll REG_SDIO_HSUS_CTRL[1]"); -+ return -ETIMEDOUT; -+ } -+ -+ if (rtw_sdio_is_sdio30_supported(rtwdev)) -+ rtw_write8_set(rtwdev, REG_HCI_OPT_CTRL + 2, -+ BIT_SDIO_PAD_E5 >> 16); -+ else -+ rtw_write8_clr(rtwdev, REG_HCI_OPT_CTRL + 2, -+ BIT_SDIO_PAD_E5 >> 16); -+ break; - case RTW_HCI_TYPE_USB: - break; - default: -@@ -249,6 +272,7 @@ static int rtw_mac_power_switch(struct r - { - const struct rtw_chip_info *chip = rtwdev->chip; - const struct rtw_pwr_seq_cmd **pwr_seq; -+ u32 imr = 0; - u8 rpwm; - bool cur_pwr; - int ret; -@@ -274,18 +298,24 @@ static int rtw_mac_power_switch(struct r - if (pwr_on == cur_pwr) - return -EALREADY; - -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { -+ imr = rtw_read32(rtwdev, REG_SDIO_HIMR); -+ rtw_write32(rtwdev, REG_SDIO_HIMR, 0); -+ } -+ - if (!pwr_on) - clear_bit(RTW_FLAG_POWERON, rtwdev->flags); - - pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; - ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); -- if (ret) -- return ret; - -- if (pwr_on) -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) -+ rtw_write32(rtwdev, REG_SDIO_HIMR, imr); -+ -+ if (!ret && pwr_on) - set_bit(RTW_FLAG_POWERON, rtwdev->flags); - -- return 0; -+ return ret; - } - - static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) -@@ -456,6 +486,9 @@ static void download_firmware_reg_backup - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, 0x200); - rtw_write32(rtwdev, REG_RQPN_CTRL_2, bckp[bckp_idx - 1].val); - -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) -+ rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); -+ - /* Disable beacon related functions */ - tmp = rtw_read8(rtwdev, REG_BCN_CTRL); - bckp[bckp_idx].len = 1; -@@ -1068,8 +1101,12 @@ static int txdma_queue_mapping(struct rt - if (rtw_chip_wcpu_11ac(rtwdev)) - rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); - -- if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { -+ rtw_read32(rtwdev, REG_SDIO_FREE_TXPG); -+ rtw_write32(rtwdev, REG_SDIO_TX_CTRL, 0); -+ } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { - rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN); -+ } - - return 0; - } diff --git a/package/kernel/mac80211/patches/rtl/027-wifi-rtw88-main-Add-the-cpwm-rpwm-_addr-for-SDIO-bas.patch b/package/kernel/mac80211/patches/rtl/027-wifi-rtw88-main-Add-the-cpwm-rpwm-_addr-for-SDIO-bas.patch deleted file mode 100644 index 4f7fe2fa9..000000000 --- a/package/kernel/mac80211/patches/rtl/027-wifi-rtw88-main-Add-the-cpwm-rpwm-_addr-for-SDIO-bas.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a5d25f9ff91831f3a87aca96480a8b080546ccb8 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:24 +0200 -Subject: [PATCH 27/45] wifi: rtw88: main: Add the {cpwm,rpwm}_addr for SDIO - based chipsets - -Initialize the rpwm_addr and cpwm_addr for power-saving support on SDIO -based chipsets. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-5-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/main.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -18,6 +18,7 @@ - #include "debug.h" - #include "bf.h" - #include "sar.h" -+#include "sdio.h" - - bool rtw_disable_lps_deep_mode; - EXPORT_SYMBOL(rtw_disable_lps_deep_mode); -@@ -1785,6 +1786,10 @@ static int rtw_chip_parameter_setup(stru - rtwdev->hci.rpwm_addr = 0x03d9; - rtwdev->hci.cpwm_addr = 0x03da; - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtwdev->hci.rpwm_addr = REG_SDIO_HRPWM1; -+ rtwdev->hci.cpwm_addr = REG_SDIO_HCPWM1_V2; -+ break; - case RTW_HCI_TYPE_USB: - rtwdev->hci.rpwm_addr = 0xfe58; - rtwdev->hci.cpwm_addr = 0xfe57; diff --git a/package/kernel/mac80211/patches/rtl/028-wifi-rtw88-main-Reserve-8-bytes-of-extra-TX-headroom.patch b/package/kernel/mac80211/patches/rtl/028-wifi-rtw88-main-Reserve-8-bytes-of-extra-TX-headroom.patch deleted file mode 100644 index 9fb6dedea..000000000 --- a/package/kernel/mac80211/patches/rtl/028-wifi-rtw88-main-Reserve-8-bytes-of-extra-TX-headroom.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 02461d9368c59510ef51cc8a1db1f0f31cfbf9ad Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:25 +0200 -Subject: [PATCH 28/45] wifi: rtw88: main: Reserve 8 bytes of extra TX headroom - for SDIO cards - -For SDIO host controllers with DMA support the TX buffer physical memory -address need to be aligned at an 8-byte boundary. Reserve 8 bytes of -extra TX headroom so we can align the data without re-allocating the -transmit buffer. - -While here, also remove the TODO comment regarding extra headroom for -USB and SDIO. For SDIO the extra headroom is now handled and for USB it -was not needed so far. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-6-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2163,9 +2163,11 @@ int rtw_register_hw(struct rtw_dev *rtwd - int max_tx_headroom = 0; - int ret; - -- /* TODO: USB & SDIO may need extra room? */ - max_tx_headroom = rtwdev->chip->tx_pkt_desc_sz; - -+ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) -+ max_tx_headroom += RTW_SDIO_DATA_PTR_ALIGN; -+ - hw->extra_tx_headroom = max_tx_headroom; - hw->queues = IEEE80211_NUM_ACS; - hw->txq_data_size = sizeof(struct rtw_txq); diff --git a/package/kernel/mac80211/patches/rtl/029-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822BS-.patch b/package/kernel/mac80211/patches/rtl/029-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822BS-.patch deleted file mode 100644 index b924751b8..000000000 --- a/package/kernel/mac80211/patches/rtl/029-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822BS-.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 095e62dd74276dd801c04d9a2a9afcd922811218 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Wed, 5 Apr 2023 22:07:27 +0200 -Subject: [PATCH 29/45] wifi: rtw88: Add support for the SDIO based RTL8822BS - chipset - -Wire up RTL8822BS chipset support using the new rtw88 SDIO HCI code as -well as the existing RTL8822B chipset code. - -Signed-off-by: Jernej Skrabec -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-8-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 11 ++++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - .../net/wireless/realtek/rtw88/rtw8822bs.c | 36 +++++++++++++++++++ - 3 files changed, 50 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822bs.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -56,6 +56,19 @@ config RTW88_8822BE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8822BS -+ tristate "Realtek 8822BS SDIO wireless network adapter" -+ depends on m -+ depends on MMC -+ select RTW88_CORE -+ select RTW88_SDIO -+ select RTW88_8822B -+ help -+ Select this option will enable support for 8822BS chipset -+ -+ 802.11ac SDIO wireless network adapter -+ -+ - config RTW88_8822BU - tristate "Realtek 8822BU USB wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -26,6 +26,9 @@ rtw88_8822b-objs := rtw8822b.o rtw8822b - obj-$(CPTCFG_RTW88_8822BE) += rtw88_8822be.o - rtw88_8822be-objs := rtw8822be.o - -+obj-$(CPTCFG_RTW88_8822BS) += rtw88_8822bs.o -+rtw88_8822bs-objs := rtw8822bs.o -+ - obj-$(CPTCFG_RTW88_8822BU) += rtw88_8822bu.o - rtw88_8822bu-objs := rtw8822bu.o - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822bs.c -@@ -0,0 +1,36 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) Jernej Skrabec -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "rtw8822b.h" -+#include "sdio.h" -+ -+static const struct sdio_device_id rtw_8822bs_id_table[] = { -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8822BS), -+ .driver_data = (kernel_ulong_t)&rtw8822b_hw_spec, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(sdio, rtw_8822bs_id_table); -+ -+static struct sdio_driver rtw_8822bs_driver = { -+ .name = "rtw_8822bs", -+ .probe = rtw_sdio_probe, -+ .remove = rtw_sdio_remove, -+ .id_table = rtw_8822bs_id_table, -+ .drv = { -+ .pm = &rtw_sdio_pm_ops, -+ .shutdown = rtw_sdio_shutdown, -+ } -+}; -+module_sdio_driver(rtw_8822bs_driver); -+ -+MODULE_AUTHOR("Jernej Skrabec "); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bs driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/030-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822CS-.patch b/package/kernel/mac80211/patches/rtl/030-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822CS-.patch deleted file mode 100644 index 0d8fbc785..000000000 --- a/package/kernel/mac80211/patches/rtl/030-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8822CS-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 6fdacb78f7999f5c14d9dae10d47de50959297d9 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:28 +0200 -Subject: [PATCH 30/45] wifi: rtw88: Add support for the SDIO based RTL8822CS - chipset - -Wire up RTL8822CS chipset support using the new rtw88 SDIO HCI code as -well as the existing RTL8822C chipset code. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-9-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 11 ++++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - .../net/wireless/realtek/rtw88/rtw8822cs.c | 36 +++++++++++++++++++ - 3 files changed, 50 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8822cs.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -93,6 +93,18 @@ config RTW88_8822CE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8822CS -+ tristate "Realtek 8822CS SDIO wireless network adapter" -+ depends on m -+ depends on MMC -+ select RTW88_CORE -+ select RTW88_SDIO -+ select RTW88_8822C -+ help -+ Select this option will enable support for 8822CS chipset -+ -+ 802.11ac SDIO wireless network adapter -+ - config RTW88_8822CU - tristate "Realtek 8822CU USB wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -38,6 +38,9 @@ rtw88_8822c-objs := rtw8822c.o rtw8822c - obj-$(CPTCFG_RTW88_8822CE) += rtw88_8822ce.o - rtw88_8822ce-objs := rtw8822ce.o - -+obj-$(CPTCFG_RTW88_8822CS) += rtw88_8822cs.o -+rtw88_8822cs-objs := rtw8822cs.o -+ - obj-$(CPTCFG_RTW88_8822CU) += rtw88_8822cu.o - rtw88_8822cu-objs := rtw8822cu.o - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822cs.c -@@ -0,0 +1,36 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "rtw8822c.h" -+#include "sdio.h" -+ -+static const struct sdio_device_id rtw_8822cs_id_table[] = { -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8822CS), -+ .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(sdio, rtw_8822cs_id_table); -+ -+static struct sdio_driver rtw_8822cs_driver = { -+ .name = "rtw_8822cs", -+ .probe = rtw_sdio_probe, -+ .remove = rtw_sdio_remove, -+ .id_table = rtw_8822cs_id_table, -+ .drv = { -+ .pm = &rtw_sdio_pm_ops, -+ .shutdown = rtw_sdio_shutdown, -+ } -+}; -+module_sdio_driver(rtw_8822cs_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cs driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/031-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8821CS-.patch b/package/kernel/mac80211/patches/rtl/031-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8821CS-.patch deleted file mode 100644 index abd708efe..000000000 --- a/package/kernel/mac80211/patches/rtl/031-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8821CS-.patch +++ /dev/null @@ -1,93 +0,0 @@ -From b2a777d68434375dc05a6fda5fec34a474bbf21f Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Wed, 5 Apr 2023 22:07:29 +0200 -Subject: [PATCH 31/45] wifi: rtw88: Add support for the SDIO based RTL8821CS - chipset - -Wire up RTL8821CS chipset support using the new rtw88 SDIO HCI code as -well as the existing RTL8821C chipset code. - -Reviewed-by: Ping-Ke Shih -Tested-by: Chris Morgan -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230405200729.632435-10-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 11 ++++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - .../net/wireless/realtek/rtw88/rtw8821cs.c | 36 +++++++++++++++++++ - 3 files changed, 50 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821cs.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -153,6 +153,18 @@ config RTW88_8821CE - - 802.11ac PCIe wireless network adapter - -+config RTW88_8821CS -+ tristate "Realtek 8821CS SDIO wireless network adapter" -+ depends on m -+ depends on MMC -+ select RTW88_CORE -+ select RTW88_SDIO -+ select RTW88_8821C -+ help -+ Select this option will enable support for 8821CS chipset -+ -+ 802.11ac SDIO wireless network adapter -+ - config RTW88_8821CU - tristate "Realtek 8821CU USB wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -59,6 +59,9 @@ rtw88_8821c-objs := rtw8821c.o rtw8821c - obj-$(CPTCFG_RTW88_8821CE) += rtw88_8821ce.o - rtw88_8821ce-objs := rtw8821ce.o - -+obj-$(CPTCFG_RTW88_8821CS) += rtw88_8821cs.o -+rtw88_8821cs-objs := rtw8821cs.o -+ - obj-$(CPTCFG_RTW88_8821CU) += rtw88_8821cu.o - rtw88_8821cu-objs := rtw8821cu.o - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821cs.c -@@ -0,0 +1,36 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "rtw8821c.h" -+#include "sdio.h" -+ -+static const struct sdio_device_id rtw_8821cs_id_table[] = { -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8821CS), -+ .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(sdio, rtw_8821cs_id_table); -+ -+static struct sdio_driver rtw_8821cs_driver = { -+ .name = "rtw_8821cs", -+ .probe = rtw_sdio_probe, -+ .remove = rtw_sdio_remove, -+ .id_table = rtw_8821cs_id_table, -+ .drv = { -+ .pm = &rtw_sdio_pm_ops, -+ .shutdown = rtw_sdio_shutdown, -+ } -+}; -+module_sdio_driver(rtw_8821cs_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cs driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/032-wifi-rtw88-add-bitmap-for-dynamic-port-settings.patch b/package/kernel/mac80211/patches/rtl/032-wifi-rtw88-add-bitmap-for-dynamic-port-settings.patch deleted file mode 100644 index e84e97787..000000000 --- a/package/kernel/mac80211/patches/rtl/032-wifi-rtw88-add-bitmap-for-dynamic-port-settings.patch +++ /dev/null @@ -1,108 +0,0 @@ -From f0e741e4ddbc01610ca87167a123702b3fdac51f Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:11:28 +0800 -Subject: [PATCH 32/45] wifi: rtw88: add bitmap for dynamic port settings - -In order to support multiple interfaces, multiple port settings will -be required. Current code always uses port 0 and should be changed. -Declare a bitmap with size equal to hardware port number to record -the current usage. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121135.17828-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 13 ++++++++++--- - drivers/net/wireless/realtek/rtw88/main.c | 1 + - drivers/net/wireless/realtek/rtw88/main.h | 10 ++++++++++ - 3 files changed, 21 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -155,25 +155,30 @@ static int rtw_ops_add_interface(struct - struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; - enum rtw_net_type net_type; - u32 config = 0; -- u8 port = 0; -+ u8 port; - u8 bcn_ctrl = 0; - - if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER)) - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | - IEEE80211_VIF_SUPPORTS_CQM_RSSI; -- rtwvif->port = port; - rtwvif->stats.tx_unicast = 0; - rtwvif->stats.rx_unicast = 0; - rtwvif->stats.tx_cnt = 0; - rtwvif->stats.rx_cnt = 0; - rtwvif->scan_req = NULL; - memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee)); -- rtwvif->conf = &rtw_vif_port[port]; - rtw_txq_init(rtwdev, vif->txq); - INIT_LIST_HEAD(&rtwvif->rsvd_page_list); - - mutex_lock(&rtwdev->mutex); - -+ port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); -+ if (port >= RTW_PORT_NUM) -+ return -EINVAL; -+ set_bit(port, rtwdev->hw_port); -+ -+ rtwvif->port = port; -+ rtwvif->conf = &rtw_vif_port[port]; - rtw_leave_lps_deep(rtwdev); - - switch (vif->type) { -@@ -195,6 +200,7 @@ static int rtw_ops_add_interface(struct - break; - default: - WARN_ON(1); -+ clear_bit(rtwvif->port, rtwdev->hw_port); - mutex_unlock(&rtwdev->mutex); - return -EINVAL; - } -@@ -236,6 +242,7 @@ static void rtw_ops_remove_interface(str - rtwvif->bcn_ctrl = 0; - config |= PORT_SET_BCN_CTRL; - rtw_vif_port_config(rtwdev, rtwvif, config); -+ clear_bit(rtwvif->port, rtwdev->hw_port); - - mutex_unlock(&rtwdev->mutex); - } ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -610,6 +610,7 @@ free: - rcu_read_unlock(); - rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); - rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); -+ bitmap_zero(rtwdev->hw_port, RTW_PORT_NUM); - rtw_enter_ips(rtwdev); - } - ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -395,6 +395,15 @@ enum rtw_snr { - RTW_SNR_NUM - }; - -+enum rtw_port { -+ RTW_PORT_0 = 0, -+ RTW_PORT_1 = 1, -+ RTW_PORT_2 = 2, -+ RTW_PORT_3 = 3, -+ RTW_PORT_4 = 4, -+ RTW_PORT_NUM -+}; -+ - enum rtw_wow_flags { - RTW_WOW_FLAG_EN_MAGIC_PKT, - RTW_WOW_FLAG_EN_REKEY_PKT, -@@ -2036,6 +2045,7 @@ struct rtw_dev { - u8 sta_cnt; - u32 rts_threshold; - -+ DECLARE_BITMAP(hw_port, RTW_PORT_NUM); - DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); - DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); - diff --git a/package/kernel/mac80211/patches/rtl/033-wifi-rtw88-add-port-switch-for-AP-mode.patch b/package/kernel/mac80211/patches/rtl/033-wifi-rtw88-add-port-switch-for-AP-mode.patch deleted file mode 100644 index 4467c77ac..000000000 --- a/package/kernel/mac80211/patches/rtl/033-wifi-rtw88-add-port-switch-for-AP-mode.patch +++ /dev/null @@ -1,126 +0,0 @@ -From ccf73f6e69c0244a979e97eb6c38f80cd6cbc116 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:11:29 +0800 -Subject: [PATCH 33/45] wifi: rtw88: add port switch for AP mode - -Switch port settings if AP mode does not start on port 0 because of -hardware limitation. For some ICs, beacons on ports other than zero -could misbehave and do not issue properly, to fix this we change AP -VIFs to port zero when multiple interfaces is active. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121135.17828-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 1 + - drivers/net/wireless/realtek/rtw88/main.c | 79 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/main.h | 1 + - 3 files changed, 81 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -212,6 +212,7 @@ static int rtw_ops_add_interface(struct - rtwvif->bcn_ctrl = bcn_ctrl; - config |= PORT_SET_BCN_CTRL; - rtw_vif_port_config(rtwdev, rtwvif, config); -+ rtw_core_port_switch(rtwdev, vif); - - mutex_unlock(&rtwdev->mutex); - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2251,6 +2251,85 @@ void rtw_unregister_hw(struct rtw_dev *r - } - EXPORT_SYMBOL(rtw_unregister_hw); - -+static -+void rtw_swap_reg_nbytes(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, -+ const struct rtw_hw_reg *reg2, u8 nbytes) -+{ -+ u8 i; -+ -+ for (i = 0; i < nbytes; i++) { -+ u8 v1 = rtw_read8(rtwdev, reg1->addr + i); -+ u8 v2 = rtw_read8(rtwdev, reg2->addr + i); -+ -+ rtw_write8(rtwdev, reg1->addr + i, v2); -+ rtw_write8(rtwdev, reg2->addr + i, v1); -+ } -+} -+ -+static -+void rtw_swap_reg_mask(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, -+ const struct rtw_hw_reg *reg2) -+{ -+ u32 v1, v2; -+ -+ v1 = rtw_read32_mask(rtwdev, reg1->addr, reg1->mask); -+ v2 = rtw_read32_mask(rtwdev, reg2->addr, reg2->mask); -+ rtw_write32_mask(rtwdev, reg2->addr, reg2->mask, v1); -+ rtw_write32_mask(rtwdev, reg1->addr, reg1->mask, v2); -+} -+ -+struct rtw_iter_port_switch_data { -+ struct rtw_dev *rtwdev; -+ struct rtw_vif *rtwvif_ap; -+}; -+ -+static void rtw_port_switch_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -+{ -+ struct rtw_iter_port_switch_data *iter_data = data; -+ struct rtw_dev *rtwdev = iter_data->rtwdev; -+ struct rtw_vif *rtwvif_target = (struct rtw_vif *)vif->drv_priv; -+ struct rtw_vif *rtwvif_ap = iter_data->rtwvif_ap; -+ const struct rtw_hw_reg *reg1, *reg2; -+ -+ if (rtwvif_target->port != RTW_PORT_0) -+ return; -+ -+ rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", -+ rtwvif_ap->port, rtwvif_target->port); -+ -+ reg1 = &rtwvif_ap->conf->net_type; -+ reg2 = &rtwvif_target->conf->net_type; -+ rtw_swap_reg_mask(rtwdev, reg1, reg2); -+ -+ reg1 = &rtwvif_ap->conf->mac_addr; -+ reg2 = &rtwvif_target->conf->mac_addr; -+ rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); -+ -+ reg1 = &rtwvif_ap->conf->bssid; -+ reg2 = &rtwvif_target->conf->bssid; -+ rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); -+ -+ reg1 = &rtwvif_ap->conf->bcn_ctrl; -+ reg2 = &rtwvif_target->conf->bcn_ctrl; -+ rtw_swap_reg_nbytes(rtwdev, reg1, reg2, 1); -+ -+ swap(rtwvif_target->port, rtwvif_ap->port); -+ swap(rtwvif_target->conf, rtwvif_ap->conf); -+} -+ -+void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) -+{ -+ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; -+ struct rtw_iter_port_switch_data iter_data; -+ -+ if (vif->type != NL80211_IFTYPE_AP || rtwvif->port == RTW_PORT_0) -+ return; -+ -+ iter_data.rtwdev = rtwdev; -+ iter_data.rtwvif_ap = rtwvif; -+ rtw_iterate_vifs(rtwdev, rtw_port_switch_iter, &iter_data); -+} -+ - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); - MODULE_LICENSE("Dual BSD/GPL"); ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -2198,4 +2198,5 @@ void rtw_set_txrx_1ss(struct rtw_dev *rt - void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, - u8 primary_channel, enum rtw_supported_band band, - enum rtw_bandwidth bandwidth); -+void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif); - #endif diff --git a/package/kernel/mac80211/patches/rtl/034-wifi-rtw88-8822c-extend-reserved-page-number.patch b/package/kernel/mac80211/patches/rtl/034-wifi-rtw88-8822c-extend-reserved-page-number.patch deleted file mode 100644 index cc4eef318..000000000 --- a/package/kernel/mac80211/patches/rtl/034-wifi-rtw88-8822c-extend-reserved-page-number.patch +++ /dev/null @@ -1,84 +0,0 @@ -From ffa71c5477793f41bc7537a60aa54ac40275ab78 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:11:30 +0800 -Subject: [PATCH 34/45] wifi: rtw88: 8822c: extend reserved page number - -Extend 8822c's reserved page number to accommodate additional required -pages. Reserved page is an area of memory in the FIFO dedicated for -special purposes. Previously only one interface is supported so 8 pages -should suffice, extend it so we can support 2 interfaces concurrently. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121135.17828-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 2 +- - drivers/net/wireless/realtek/rtw88/main.h | 1 + - drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + - drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + - drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + - 6 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -1119,7 +1119,7 @@ static int set_trx_fifo_info(struct rtw_ - u8 csi_buf_pg_num = chip->csi_buf_pg_num; - - /* config rsvd page num */ -- fifo->rsvd_drv_pg_num = 8; -+ fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; - fifo->txff_pg_num = chip->txff_size >> 7; - if (rtw_chip_wcpu_11n(rtwdev)) - fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1177,6 +1177,7 @@ struct rtw_chip_info { - u32 txff_size; - u32 rxff_size; - u32 fw_rxff_size; -+ u16 rsvd_drv_pg_num; - u8 band; - u8 page_size; - u8 csi_buf_pg_num; ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -@@ -2743,6 +2743,7 @@ const struct rtw_chip_info rtw8723d_hw_s - .ptct_efuse_size = 96 + 1, - .txff_size = 32768, - .rxff_size = 16384, -+ .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -1920,6 +1920,7 @@ const struct rtw_chip_info rtw8821c_hw_s - .ptct_efuse_size = 96, - .txff_size = 65536, - .rxff_size = 16384, -+ .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, ---- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c -@@ -2540,6 +2540,7 @@ const struct rtw_chip_info rtw8822b_hw_s - .txff_size = 262144, - .rxff_size = 24576, - .fw_rxff_size = 12288, -+ .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, ---- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c -@@ -5358,6 +5358,7 @@ const struct rtw_chip_info rtw8822c_hw_s - .txff_size = 262144, - .rxff_size = 24576, - .fw_rxff_size = 12288, -+ .rsvd_drv_pg_num = 16, - .txgi_factor = 2, - .is_pwr_by_rate_dec = false, - .max_power_index = 0x7f, diff --git a/package/kernel/mac80211/patches/rtl/035-wifi-rtw88-disallow-PS-during-AP-mode.patch b/package/kernel/mac80211/patches/rtl/035-wifi-rtw88-disallow-PS-during-AP-mode.patch deleted file mode 100644 index 060600f00..000000000 --- a/package/kernel/mac80211/patches/rtl/035-wifi-rtw88-disallow-PS-during-AP-mode.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 5ec69129f195f340acb15b8535cb372ccdbcf5d7 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:11:31 +0800 -Subject: [PATCH 35/45] wifi: rtw88: disallow PS during AP mode - -Firmware can't support PS mode during AP mode, so disallow this case. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121135.17828-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 13 +++++++++++++ - drivers/net/wireless/realtek/rtw88/main.c | 2 +- - drivers/net/wireless/realtek/rtw88/main.h | 1 + - 3 files changed, 15 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -449,12 +449,24 @@ static int rtw_ops_start_ap(struct ieee8 - const struct rtw_chip_info *chip = rtwdev->chip; - - mutex_lock(&rtwdev->mutex); -+ rtwdev->ap_active = true; - chip->ops->phy_calibration(rtwdev); - mutex_unlock(&rtwdev->mutex); - - return 0; - } - -+static void rtw_ops_stop_ap(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_bss_conf *link_conf) -+{ -+ struct rtw_dev *rtwdev = hw->priv; -+ -+ mutex_lock(&rtwdev->mutex); -+ rtwdev->ap_active = false; -+ mutex_unlock(&rtwdev->mutex); -+} -+ - static int rtw_ops_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - unsigned int link_id, u16 ac, -@@ -916,6 +928,7 @@ const struct ieee80211_ops rtw_ops = { - .configure_filter = rtw_ops_configure_filter, - .bss_info_changed = rtw_ops_bss_info_changed, - .start_ap = rtw_ops_start_ap, -+ .stop_ap = rtw_ops_stop_ap, - .conf_tx = rtw_ops_conf_tx, - .sta_add = rtw_ops_sta_add, - .sta_remove = rtw_ops_sta_remove, ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -257,7 +257,7 @@ static void rtw_watch_dog_work(struct wo - * threshold. - */ - if (rtwdev->ps_enabled && data.rtwvif && !ps_active && -- !rtwdev->beacon_loss) -+ !rtwdev->beacon_loss && !rtwdev->ap_active) - rtw_enter_lps(rtwdev, data.rtwvif->port); - - rtwdev->watch_dog_cnt++; ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -2058,6 +2058,7 @@ struct rtw_dev { - - bool need_rfk; - struct completion fw_scan_density; -+ bool ap_active; - - /* hci related data, must be last */ - u8 priv[] __aligned(sizeof(void *)); diff --git a/package/kernel/mac80211/patches/rtl/036-wifi-rtw88-refine-reserved-page-flow-for-AP-mode.patch b/package/kernel/mac80211/patches/rtl/036-wifi-rtw88-refine-reserved-page-flow-for-AP-mode.patch deleted file mode 100644 index 8820e3adf..000000000 --- a/package/kernel/mac80211/patches/rtl/036-wifi-rtw88-refine-reserved-page-flow-for-AP-mode.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 982f4a2004f712ce7aed7f7e69fa64e4c06eee7d Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:13:00 +0800 -Subject: [PATCH 36/45] wifi: rtw88: refine reserved page flow for AP mode - -Only gather reserved pages from AP interface after it has started. Or -else ieee80211_beacon_get_*() returns NULL and causes other VIFs' -reserved pages fail to download. Update location of current reserved page -after beacon renews so offsets changed by beacon can be recognized. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121300.17900-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 5 +++++ - drivers/net/wireless/realtek/rtw88/mac80211.c | 1 + - 2 files changed, 6 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -1393,6 +1393,10 @@ static void rtw_build_rsvd_page_iter(voi - struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; - struct rtw_rsvd_page *rsvd_pkt; - -+ /* AP not yet started, don't gather its rsvd pages */ -+ if (vif->type == NL80211_IFTYPE_AP && !rtwdev->ap_active) -+ return; -+ - list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { - if (rsvd_pkt->type == RSVD_BEACON) - list_add(&rsvd_pkt->build_list, -@@ -1614,6 +1618,7 @@ void rtw_fw_update_beacon_work(struct wo - - mutex_lock(&rtwdev->mutex); - rtw_fw_download_rsvd_page(rtwdev); -+ rtw_send_rsvd_page_h2c(rtwdev); - mutex_unlock(&rtwdev->mutex); - } - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -417,6 +417,7 @@ static void rtw_ops_bss_info_changed(str - if (changed & BSS_CHANGED_BEACON) { - rtw_set_dtim_period(rtwdev, conf->dtim_period); - rtw_fw_download_rsvd_page(rtwdev); -+ rtw_send_rsvd_page_h2c(rtwdev); - } - - if (changed & BSS_CHANGED_BEACON_ENABLED) { diff --git a/package/kernel/mac80211/patches/rtl/037-wifi-rtw88-prevent-scan-abort-with-other-VIFs.patch b/package/kernel/mac80211/patches/rtl/037-wifi-rtw88-prevent-scan-abort-with-other-VIFs.patch deleted file mode 100644 index 9263bde93..000000000 --- a/package/kernel/mac80211/patches/rtl/037-wifi-rtw88-prevent-scan-abort-with-other-VIFs.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a1b8015da57a783b3ceebd8e114afbe07536bd54 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:13:12 +0800 -Subject: [PATCH 37/45] wifi: rtw88: prevent scan abort with other VIFs - -Only abort scan with current scanning VIF. If we have more than one -interface, we could call rtw_hw_scan_abort() with the wrong VIF as -input. This avoids potential null pointer being accessed when actually -the other VIF is scanning. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121312.17954-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 4 +++- - drivers/net/wireless/realtek/rtw88/fw.h | 2 +- - drivers/net/wireless/realtek/rtw88/mac80211.c | 7 ++++--- - 3 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -2163,8 +2163,10 @@ out: - return ret; - } - --void rtw_hw_scan_abort(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) -+void rtw_hw_scan_abort(struct rtw_dev *rtwdev) - { -+ struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; -+ - if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) - return; - ---- a/drivers/net/wireless/realtek/rtw88/fw.h -+++ b/drivers/net/wireless/realtek/rtw88/fw.h -@@ -868,5 +868,5 @@ int rtw_hw_scan_offload(struct rtw_dev * - bool enable); - void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, struct sk_buff *skb); - void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, struct sk_buff *skb); --void rtw_hw_scan_abort(struct rtw_dev *rtwdev, struct ieee80211_vif *vif); -+void rtw_hw_scan_abort(struct rtw_dev *rtwdev); - #endif ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -393,7 +393,8 @@ static void rtw_ops_bss_info_changed(str - * when disconnected by peer - */ - if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) -- rtw_hw_scan_abort(rtwdev, vif); -+ rtw_hw_scan_abort(rtwdev); -+ - } - - config |= PORT_SET_NET_TYPE; -@@ -870,7 +871,7 @@ static int rtw_ops_hw_scan(struct ieee80 - rtw_hw_scan_start(rtwdev, vif, req); - ret = rtw_hw_scan_offload(rtwdev, vif, true); - if (ret) { -- rtw_hw_scan_abort(rtwdev, vif); -+ rtw_hw_scan_abort(rtwdev); - rtw_err(rtwdev, "HW scan failed with status: %d\n", ret); - } - mutex_unlock(&rtwdev->mutex); -@@ -890,7 +891,7 @@ static void rtw_ops_cancel_hw_scan(struc - return; - - mutex_lock(&rtwdev->mutex); -- rtw_hw_scan_abort(rtwdev, vif); -+ rtw_hw_scan_abort(rtwdev); - mutex_unlock(&rtwdev->mutex); - } - diff --git a/package/kernel/mac80211/patches/rtl/038-wifi-rtw88-handle-station-mode-concurrent-scan-with-.patch b/package/kernel/mac80211/patches/rtl/038-wifi-rtw88-handle-station-mode-concurrent-scan-with-.patch deleted file mode 100644 index d0a1315e4..000000000 --- a/package/kernel/mac80211/patches/rtl/038-wifi-rtw88-handle-station-mode-concurrent-scan-with-.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 96fbb84de4ffce76d54de8656efe0a580081c037 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:13:23 +0800 -Subject: [PATCH 38/45] wifi: rtw88: handle station mode concurrent scan with - AP mode - -This patch allows vifs sharing same hardware with the AP mode vif to -do scan, do note that this could lead to packet loss or disconnection -of the AP's clients. Since we don't have chanctx, update scan info -upon set channel so bandwidth changes won't go unnoticed and get -misconfigured after scan. Download beacon just before scan starts to -allow hardware to get proper content to do beaconing. Last, beacons -should only be transmitted in AP's operating channel. Turn related -beacon functions off while we're in other channels so the receiving -stations won't get confused. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121323.18008-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 11 +++++- - drivers/net/wireless/realtek/rtw88/mac80211.c | 5 ++- - drivers/net/wireless/realtek/rtw88/main.c | 39 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/main.h | 2 + - 4 files changed, 55 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -2160,6 +2160,12 @@ int rtw_hw_scan_offload(struct rtw_dev * - } - rtw_fw_set_scan_offload(rtwdev, &cs_option, rtwvif, &chan_list); - out: -+ if (rtwdev->ap_active) { -+ ret = rtw_download_beacon(rtwdev); -+ if (ret) -+ rtw_err(rtwdev, "HW scan download beacon failed\n"); -+ } -+ - return ret; - } - -@@ -2251,6 +2257,7 @@ void rtw_hw_scan_chan_switch(struct rtw_ - if (rtw_is_op_chan(rtwdev, chan)) { - rtw_store_op_chan(rtwdev, false); - ieee80211_wake_queues(rtwdev->hw); -+ rtw_core_enable_beacon(rtwdev, true); - } - } else if (id == RTW_SCAN_NOTIFY_ID_PRESWITCH) { - if (IS_CH_5G_BAND(chan)) { -@@ -2269,8 +2276,10 @@ void rtw_hw_scan_chan_switch(struct rtw_ - * if next channel is non-op channel. - */ - if (!rtw_is_op_chan(rtwdev, chan) && -- rtw_is_op_chan(rtwdev, hal->current_channel)) -+ rtw_is_op_chan(rtwdev, hal->current_channel)) { -+ rtw_core_enable_beacon(rtwdev, false); - ieee80211_stop_queues(rtwdev->hw); -+ } - } - - rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -404,7 +404,7 @@ static void rtw_ops_bss_info_changed(str - if (changed & BSS_CHANGED_BSSID) { - ether_addr_copy(rtwvif->bssid, conf->bssid); - config |= PORT_SET_BSSID; -- if (is_zero_ether_addr(rtwvif->bssid)) -+ if (!rtw_core_check_sta_active(rtwdev)) - rtw_clear_op_chan(rtwdev); - else - rtw_store_op_chan(rtwdev, true); -@@ -452,6 +452,7 @@ static int rtw_ops_start_ap(struct ieee8 - - mutex_lock(&rtwdev->mutex); - rtwdev->ap_active = true; -+ rtw_store_op_chan(rtwdev, true); - chip->ops->phy_calibration(rtwdev); - mutex_unlock(&rtwdev->mutex); - -@@ -466,6 +467,8 @@ static void rtw_ops_stop_ap(struct ieee8 - - mutex_lock(&rtwdev->mutex); - rtwdev->ap_active = false; -+ if (!rtw_core_check_sta_active(rtwdev)) -+ rtw_clear_op_chan(rtwdev); - mutex_unlock(&rtwdev->mutex); - } - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -830,6 +830,9 @@ void rtw_set_channel(struct rtw_dev *rtw - - rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth); - -+ if (rtwdev->scan_info.op_chan) -+ rtw_store_op_chan(rtwdev, true); -+ - chip->ops->set_channel(rtwdev, center_chan, bandwidth, - hal->current_primary_channel_index); - -@@ -2330,6 +2333,42 @@ void rtw_core_port_switch(struct rtw_dev - rtw_iterate_vifs(rtwdev, rtw_port_switch_iter, &iter_data); - } - -+static void rtw_check_sta_active_iter(void *data, u8 *mac, -+ struct ieee80211_vif *vif) -+{ -+ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; -+ bool *active = data; -+ -+ if (*active) -+ return; -+ -+ if (vif->type != NL80211_IFTYPE_STATION) -+ return; -+ -+ if (vif->cfg.assoc || !is_zero_ether_addr(rtwvif->bssid)) -+ *active = true; -+} -+ -+bool rtw_core_check_sta_active(struct rtw_dev *rtwdev) -+{ -+ bool sta_active = false; -+ -+ rtw_iterate_vifs(rtwdev, rtw_check_sta_active_iter, &sta_active); -+ -+ return rtwdev->ap_active || sta_active; -+} -+ -+void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) -+{ -+ if (!rtwdev->ap_active) -+ return; -+ -+ if (enable) -+ rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+ else -+ rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+} -+ - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); - MODULE_LICENSE("Dual BSD/GPL"); ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -2201,4 +2201,6 @@ void rtw_update_channel(struct rtw_dev * - u8 primary_channel, enum rtw_supported_band band, - enum rtw_bandwidth bandwidth); - void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif); -+bool rtw_core_check_sta_active(struct rtw_dev *rtwdev); -+void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable); - #endif diff --git a/package/kernel/mac80211/patches/rtl/039-wifi-rtw88-8822c-add-iface-combination.patch b/package/kernel/mac80211/patches/rtl/039-wifi-rtw88-8822c-add-iface-combination.patch deleted file mode 100644 index ddea65516..000000000 --- a/package/kernel/mac80211/patches/rtl/039-wifi-rtw88-8822c-add-iface-combination.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d16836cdcc3b17734f6aae165268d2f1777a4f74 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 14 Apr 2023 20:13:31 +0800 -Subject: [PATCH 39/45] wifi: rtw88: 8822c: add iface combination - -Allow 8822c to operate two interface concurrently, only 1 AP mode plus -1 station mode under same frequency is supported. Combination of other -types will not be added until requested. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414121331.18062-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/main.c | 25 +++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -103,6 +103,26 @@ static struct ieee80211_rate rtw_ratetab - {.bitrate = 540, .hw_value = 0x0b,}, - }; - -+static const struct ieee80211_iface_limit rtw_iface_limits[] = { -+ { -+ .max = 1, -+ .types = BIT(NL80211_IFTYPE_STATION), -+ }, -+ { -+ .max = 1, -+ .types = BIT(NL80211_IFTYPE_AP), -+ } -+}; -+ -+static const struct ieee80211_iface_combination rtw_iface_combs[] = { -+ { -+ .limits = rtw_iface_limits, -+ .n_limits = ARRAY_SIZE(rtw_iface_limits), -+ .max_interfaces = 2, -+ .num_different_channels = 1, -+ } -+}; -+ - u16 rtw_desc_to_bitrate(u8 desc_rate) - { - struct ieee80211_rate rate; -@@ -2205,6 +2225,11 @@ int rtw_register_hw(struct rtw_dev *rtwd - hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; - hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); - -+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { -+ hw->wiphy->iface_combinations = rtw_iface_combs; -+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); -+ } -+ - wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); - wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); - wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); diff --git a/package/kernel/mac80211/patches/rtl/040-wifi-rtw88-usb-fix-priority-queue-to-endpoint-mappin.patch b/package/kernel/mac80211/patches/rtl/040-wifi-rtw88-usb-fix-priority-queue-to-endpoint-mappin.patch deleted file mode 100644 index 9ac3e61ad..000000000 --- a/package/kernel/mac80211/patches/rtl/040-wifi-rtw88-usb-fix-priority-queue-to-endpoint-mappin.patch +++ /dev/null @@ -1,140 +0,0 @@ -From a6f187f92bcc2b17821538b4a11d61764e68b091 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Mon, 17 Apr 2023 16:03:55 +0200 -Subject: [PATCH 40/45] wifi: rtw88: usb: fix priority queue to endpoint - mapping - -The RTW88 chipsets have four different priority queues in hardware. For -the USB type chipsets the packets destined for a specific priority queue -must be sent through the endpoint corresponding to the queue. This was -not fully understood when porting from the RTW88 USB out of tree driver -and thus violated. - -This patch implements the qsel to endpoint mapping as in -get_usb_bulkout_id_88xx() in the downstream driver. - -Without this the driver often issues "timed out to flush queue 3" -warnings and often TX stalls completely. - -Signed-off-by: Sascha Hauer -Tested-by: ValdikSS -Tested-by: Alexandru gagniuc -Tested-by: Larry Finger -Cc: stable@vger.kernel.org -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230417140358.2240429-2-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/usb.c | 70 ++++++++++++++++-------- - 1 file changed, 47 insertions(+), 23 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -118,6 +118,22 @@ static void rtw_usb_write32(struct rtw_d - rtw_usb_write(rtwdev, addr, val, 4); - } - -+static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping) -+{ -+ switch (dma_mapping) { -+ case RTW_DMA_MAPPING_HIGH: -+ return 0; -+ case RTW_DMA_MAPPING_NORMAL: -+ return 1; -+ case RTW_DMA_MAPPING_LOW: -+ return 2; -+ case RTW_DMA_MAPPING_EXTRA: -+ return 3; -+ default: -+ return -EINVAL; -+ } -+} -+ - static int rtw_usb_parse(struct rtw_dev *rtwdev, - struct usb_interface *interface) - { -@@ -129,6 +145,8 @@ static int rtw_usb_parse(struct rtw_dev - int num_out_pipes = 0; - int i; - u8 num; -+ const struct rtw_chip_info *chip = rtwdev->chip; -+ const struct rtw_rqpn *rqpn; - - for (i = 0; i < interface_desc->bNumEndpoints; i++) { - endpoint = &host_interface->endpoint[i].desc; -@@ -183,31 +201,34 @@ static int rtw_usb_parse(struct rtw_dev - - rtwdev->hci.bulkout_num = num_out_pipes; - -- switch (num_out_pipes) { -- case 4: -- case 3: -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0; -- break; -- case 2: -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1; -- rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1; -- break; -- case 1: -- break; -- default: -- rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes); -+ if (num_out_pipes < 1 || num_out_pipes > 4) { -+ rtw_err(rtwdev, "invalid number of endpoints %d\n", num_out_pipes); - return -EINVAL; - } - -+ rqpn = &chip->rqpn_table[num_out_pipes]; -+ -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = dma_mapping_to_ep(rqpn->dma_map_be); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = dma_mapping_to_ep(rqpn->dma_map_bk); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = dma_mapping_to_ep(rqpn->dma_map_bk); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = dma_mapping_to_ep(rqpn->dma_map_be); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = dma_mapping_to_ep(rqpn->dma_map_vi); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = dma_mapping_to_ep(rqpn->dma_map_vi); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = dma_mapping_to_ep(rqpn->dma_map_vo); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = dma_mapping_to_ep(rqpn->dma_map_vo); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID8] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID9] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID10] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID11] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID12] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID13] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID14] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_TID15] = -EINVAL; -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_BEACON] = dma_mapping_to_ep(rqpn->dma_map_hi); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_HIGH] = dma_mapping_to_ep(rqpn->dma_map_hi); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_MGMT] = dma_mapping_to_ep(rqpn->dma_map_mg); -+ rtwusb->qsel_to_ep[TX_DESC_QSEL_H2C] = dma_mapping_to_ep(rqpn->dma_map_hi); -+ - return 0; - } - -@@ -250,7 +271,7 @@ static void rtw_usb_write_port_tx_comple - static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel) - { - if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep)) -- return 0; -+ return -EINVAL; - - return rtwusb->qsel_to_ep[qsel]; - } -@@ -265,6 +286,9 @@ static int rtw_usb_write_port(struct rtw - int ret; - int ep = qsel_to_ep(rtwusb, qsel); - -+ if (ep < 0) -+ return ep; -+ - pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]); - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) diff --git a/package/kernel/mac80211/patches/rtl/041-wifi-rtw88-rtw8821c-Fix-rfe_option-field-width.patch b/package/kernel/mac80211/patches/rtl/041-wifi-rtw88-rtw8821c-Fix-rfe_option-field-width.patch deleted file mode 100644 index c140b4b05..000000000 --- a/package/kernel/mac80211/patches/rtl/041-wifi-rtw88-rtw8821c-Fix-rfe_option-field-width.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 14705f969d98187a1cc2682e0c9bd2e230b8098f Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Mon, 17 Apr 2023 16:03:56 +0200 -Subject: [PATCH 41/45] wifi: rtw88: rtw8821c: Fix rfe_option field width - -On my RTW8821CU chipset rfe_option reads as 0x22. Looking at the -vendor driver suggests that the field width of rfe_option is 5 bit, -so rfe_option should be masked with 0x1f. - -Without this the rfe_option comparisons with 2 further down the -driver evaluate as false when they should really evaluate as true. -The effect is that 2G channels do not work. - -rfe_option is also used as an array index into rtw8821c_rfe_defs[]. -rtw8821c_rfe_defs[34] (0x22) was added as part of adding USB support, -likely because rfe_option reads as 0x22. As this now becomes 0x2, -rtw8821c_rfe_defs[34] is no longer used and can be removed. - -Note that this might not be the whole truth. In the vendor driver -there are indeed places where the unmasked rfe_option value is used. -However, the driver has several places where rfe_option is tested -with the pattern if (rfe_option == 2 || rfe_option == 0x22) or -if (rfe_option == 4 || rfe_option == 0x24), so that rfe_option BIT(5) -has no influence on the code path taken. We therefore mask BIT(5) -out from rfe_option entirely until this assumption is proved wrong -by some chip variant we do not know yet. - -Signed-off-by: Sascha Hauer -Tested-by: Alexandru gagniuc -Tested-by: Larry Finger -Tested-by: ValdikSS -Cc: stable@vger.kernel.org -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230417140358.2240429-3-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -53,7 +53,7 @@ static int rtw8821c_read_efuse(struct rt - - map = (struct rtw8821c_efuse *)log_map; - -- efuse->rfe_option = map->rfe_option; -+ efuse->rfe_option = map->rfe_option & 0x1f; - efuse->rf_board_option = map->rf_board_option; - efuse->crystal_cap = map->xtal_k; - efuse->pa_type_2g = map->pa_type; -@@ -1546,7 +1546,6 @@ static const struct rtw_rfe_def rtw8821c - [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), - [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), - [6] = RTW_DEF_RFE(8821c, 0, 0), -- [34] = RTW_DEF_RFE(8821c, 0, 0), - }; - - static struct rtw_hw_reg rtw8821c_dig[] = { diff --git a/package/kernel/mac80211/patches/rtl/042-wifi-rtw88-set-pkg_type-correctly-for-specific-rtw88.patch b/package/kernel/mac80211/patches/rtl/042-wifi-rtw88-set-pkg_type-correctly-for-specific-rtw88.patch deleted file mode 100644 index e9954c515..000000000 --- a/package/kernel/mac80211/patches/rtl/042-wifi-rtw88-set-pkg_type-correctly-for-specific-rtw88.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 97c75e1adeda78b3794936c617d8b86e9ebd54f5 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Mon, 17 Apr 2023 16:03:57 +0200 -Subject: [PATCH 42/45] wifi: rtw88: set pkg_type correctly for specific - rtw8821c variants - -According to the vendor driver the pkg_type has to be set to '1' -for some rtw8821c variants. As the pkg_type has been hardcoded to -'0', add a field for it in struct rtw_hal and set this correctly -in the rtw8821c part. -With this parsing of a rtw_table is influenced and check_positive() -in phy.c returns true for some cases here. The same is done in the -vendor driver. However, this has no visible effect on the driver -here. - -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Sascha Hauer -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230417140358.2240429-4-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/main.c | 2 +- - drivers/net/wireless/realtek/rtw88/main.h | 1 + - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 3 +++ - 3 files changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2008,7 +2008,7 @@ static int rtw_chip_board_info_setup(str - if (!rfe_def) - return -ENODEV; - -- rtw_phy_setup_phy_cond(rtwdev, 0); -+ rtw_phy_setup_phy_cond(rtwdev, hal->pkg_type); - - rtw_phy_init_tx_power(rtwdev); - if (rfe_def->agc_btg_tbl) ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1900,6 +1900,7 @@ struct rtw_hal { - u8 cut_version; - u8 mp_chip; - u8 oem_id; -+ u8 pkg_type; - struct rtw_phy_cond phy_cond; - - u8 ps_mode; ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -47,6 +47,7 @@ enum rtw8821ce_rf_set { - - static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { -+ struct rtw_hal *hal = &rtwdev->hal; - struct rtw_efuse *efuse = &rtwdev->efuse; - struct rtw8821c_efuse *map; - int i; -@@ -70,6 +71,8 @@ static int rtw8821c_read_efuse(struct rt - efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; - efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; - -+ hal->pkg_type = map->rfe_option & BIT(5) ? 1 : 0; -+ - for (i = 0; i < 4; i++) - efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; - diff --git a/package/kernel/mac80211/patches/rtl/043-wifi-rtw88-call-rtw8821c_switch_rf_set-according-to-.patch b/package/kernel/mac80211/patches/rtl/043-wifi-rtw88-call-rtw8821c_switch_rf_set-according-to-.patch deleted file mode 100644 index da34691f3..000000000 --- a/package/kernel/mac80211/patches/rtl/043-wifi-rtw88-call-rtw8821c_switch_rf_set-according-to-.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 172591baa2cc1ec04869a0d798821a6ca9a2f4b4 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Mon, 17 Apr 2023 16:03:58 +0200 -Subject: [PATCH 43/45] wifi: rtw88: call rtw8821c_switch_rf_set() according to - chip variant - -We have to call rtw8821c_switch_rf_set() with SWITCH_TO_WLG or -SWITCH_TO_BTG according to the chip variant as denoted in rfe_option. -The information which argument to use for which variant has been -taken from the vendor driver. - -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230417140358.2240429-5-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/main.h | 1 + - drivers/net/wireless/realtek/rtw88/rtw8821c.c | 19 +++++++++++++++---- - 2 files changed, 16 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -1902,6 +1902,7 @@ struct rtw_hal { - u8 oem_id; - u8 pkg_type; - struct rtw_phy_cond phy_cond; -+ bool rfe_btg; - - u8 ps_mode; - u8 current_channel; ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -73,6 +73,17 @@ static int rtw8821c_read_efuse(struct rt - - hal->pkg_type = map->rfe_option & BIT(5) ? 1 : 0; - -+ switch (efuse->rfe_option) { -+ case 0x2: -+ case 0x4: -+ case 0x7: -+ case 0xa: -+ case 0xc: -+ case 0xf: -+ hal->rfe_btg = true; -+ break; -+ } -+ - for (i = 0; i < 4; i++) - efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; - -@@ -298,6 +309,7 @@ static void rtw8821c_switch_rf_set(struc - - static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) - { -+ struct rtw_hal *hal = &rtwdev->hal; - u32 rf_reg18; - - rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); -@@ -329,11 +341,10 @@ static void rtw8821c_set_channel_rf(stru - } - - if (channel <= 14) { -- if (rtwdev->efuse.rfe_option == 0) -- rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG); -- else if (rtwdev->efuse.rfe_option == 2 || -- rtwdev->efuse.rfe_option == 4) -+ if (hal->rfe_btg) - rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_BTG); -+ else -+ rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG); - rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1); - rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf); - } else { diff --git a/package/kernel/mac80211/patches/rtl/044-wifi-rtw88-Fix-memory-leak-in-rtw88_usb.patch b/package/kernel/mac80211/patches/rtl/044-wifi-rtw88-Fix-memory-leak-in-rtw88_usb.patch deleted file mode 100644 index aa2439e35..000000000 --- a/package/kernel/mac80211/patches/rtl/044-wifi-rtw88-Fix-memory-leak-in-rtw88_usb.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 59a3a312009723e3e5082899655fdcc420e2b47a Mon Sep 17 00:00:00 2001 -From: Larry Finger -Date: Mon, 17 Apr 2023 11:03:31 -0500 -Subject: [PATCH 44/45] wifi: rtw88: Fix memory leak in rtw88_usb - -Kmemleak shows the following leak arising from routine in the usb -probe routine: - -unreferenced object 0xffff895cb29bba00 (size 512): - comm "(udev-worker)", pid 534, jiffies 4294903932 (age 102751.088s) - hex dump (first 32 bytes): - 77 30 30 30 00 00 00 00 02 2f 2d 2b 30 00 00 00 w000...../-+0... - 02 00 2a 28 00 00 00 00 ff 55 ff ff ff 00 00 00 ..*(.....U...... - backtrace: - [] kmalloc_trace+0x26/0x90 - [] rtw_usb_probe+0x2f1/0x680 [rtw_usb] - [] usb_probe_interface+0xdd/0x2e0 [usbcore] - [] really_probe+0x18e/0x3d0 - [] __driver_probe_device+0x78/0x160 - [] driver_probe_device+0x1f/0x90 - [] __driver_attach+0xbf/0x1b0 - [] bus_for_each_dev+0x70/0xc0 - [] bus_add_driver+0x10e/0x210 - [] driver_register+0x55/0xf0 - [] usb_register_driver+0x88/0x140 [usbcore] - [] do_one_initcall+0x43/0x210 - [] do_init_module+0x4a/0x200 - [] __do_sys_finit_module+0xac/0x120 - [] do_syscall_64+0x56/0x80 - [] entry_SYSCALL_64_after_hwframe+0x46/0xb0 - -The leak was verified to be real by unloading the driver, which resulted -in a dangling pointer to the allocation. - -The allocated memory is freed in rtw_usb_intf_deinit(). - -Signed-off-by: Larry Finger -Cc: Sascha Hauer -Cc: Ping-Ke Shih -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230417160331.23071-1-Larry.Finger@lwfinger.net ---- - drivers/net/wireless/realtek/rtw88/usb.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -804,6 +804,7 @@ static void rtw_usb_intf_deinit(struct r - struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); - - usb_put_dev(rtwusb->udev); -+ kfree(rtwusb->usb_data); - usb_set_intfdata(intf, NULL); - } - diff --git a/package/kernel/mac80211/patches/rtl/045-wifi-rtw88-Update-spelling-in-main.h.patch b/package/kernel/mac80211/patches/rtl/045-wifi-rtw88-Update-spelling-in-main.h.patch deleted file mode 100644 index 534ae86e0..000000000 --- a/package/kernel/mac80211/patches/rtl/045-wifi-rtw88-Update-spelling-in-main.h.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 6c6d62ae8271bd4b55dd2ba4b7ed552162823880 Mon Sep 17 00:00:00 2001 -From: Simon Horman -Date: Tue, 18 Apr 2023 13:29:22 +0200 -Subject: [PATCH 45/45] wifi: rtw88: Update spelling in main.h - -Update spelling in comments in main.h - -Found by inspection. - -Signed-off-by: Simon Horman -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418-rtw88-starspell-v1-1-70e52a23979b@kernel.org ---- - drivers/net/wireless/realtek/rtw88/main.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -88,7 +88,7 @@ enum rtw_supported_band { - RTW_BAND_60G = BIT(NL80211_BAND_60GHZ), - }; - --/* now, support upto 80M bw */ -+/* now, support up to 80M bw */ - #define RTW_MAX_CHANNEL_WIDTH RTW_CHANNEL_WIDTH_80 - - enum rtw_bandwidth { -@@ -1881,7 +1881,7 @@ enum rtw_sar_bands { - RTW_SAR_BAND_NR, - }; - --/* the union is reserved for other knids of SAR sources -+/* the union is reserved for other kinds of SAR sources - * which might not re-use same format with array common. - */ - union rtw_sar_cfg { -@@ -2032,7 +2032,7 @@ struct rtw_dev { - struct rtw_tx_report tx_report; - - struct { -- /* incicate the mail box to use with fw */ -+ /* indicate the mail box to use with fw */ - u8 last_box_num; - u32 seq; - } h2c; diff --git a/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch b/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch deleted file mode 100644 index 4552d856a..000000000 --- a/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 225622256b1b7156624e281e1c0251c292ea24cd Mon Sep 17 00:00:00 2001 -From: Zhang Shurong -Date: Thu, 27 Apr 2023 01:02:20 +0800 -Subject: [PATCH 01/12] wifi: rtw88: fix incorrect error codes in - rtw_debugfs_copy_from_user - -If there is a failure during copy_from_user or user-provided data -buffer is invalid, rtw_debugfs_copy_from_user should return negative -error code instead of a positive value count. - -Fix this bug by returning correct error code. Moreover, the check -of buffer against null is removed since it will be handled by -copy_from_user. - -Signed-off-by: Zhang Shurong -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/tencent_D2EB102CC7435C0110154E62ECA6A7D67505@qq.com ---- - drivers/net/wireless/realtek/rtw88/debug.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -183,8 +183,8 @@ static int rtw_debugfs_copy_from_user(ch - - tmp_len = (count > size - 1 ? size - 1 : count); - -- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) -- return count; -+ if (copy_from_user(tmp, buffer, tmp_len)) -+ return -EFAULT; - - tmp[tmp_len] = '\0'; - diff --git a/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch b/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch deleted file mode 100644 index 02638f3cf..000000000 --- a/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-fix-incorrect-error-codes-in-rtw_debugfs_.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 77005533777267736fca64fa376b8a835cb8806b Mon Sep 17 00:00:00 2001 -From: Zhang Shurong -Date: Thu, 27 Apr 2023 01:02:21 +0800 -Subject: [PATCH 02/12] wifi: rtw88: fix incorrect error codes in - rtw_debugfs_set_* - -If there is a failure during copy_from_user or user-provided data -buffer is invalid, rtw_debugfs_set_* should return negative -error code instead of a positive value count. - -Fix this bug by returning correct error code. - -Signed-off-by: Zhang Shurong -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/tencent_53140CC2A3468101955F02EB66AA96780B05@qq.com ---- - drivers/net/wireless/realtek/rtw88/debug.c | 55 ++++++++++++++++------ - 1 file changed, 41 insertions(+), 14 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -201,13 +201,16 @@ static ssize_t rtw_debugfs_set_read_reg( - char tmp[32 + 1]; - u32 addr, len; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); -+ if (ret) -+ return ret; - - num = sscanf(tmp, "%x %x", &addr, &len); - - if (num != 2) -- return count; -+ return -EINVAL; - - if (len != 1 && len != 2 && len != 4) { - rtw_warn(rtwdev, "read reg setting wrong len\n"); -@@ -288,8 +291,11 @@ static ssize_t rtw_debugfs_set_rsvd_page - char tmp[32 + 1]; - u32 offset, page_num; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2); -+ if (ret) -+ return ret; - - num = sscanf(tmp, "%d %d", &offset, &page_num); - -@@ -314,8 +320,11 @@ static ssize_t rtw_debugfs_set_single_in - char tmp[32 + 1]; - u32 input; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ if (ret) -+ return ret; - - num = kstrtoint(tmp, 0, &input); - -@@ -338,14 +347,17 @@ static ssize_t rtw_debugfs_set_write_reg - char tmp[32 + 1]; - u32 addr, val, len; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ if (ret) -+ return ret; - - /* write BB/MAC register */ - num = sscanf(tmp, "%x %x %x", &addr, &val, &len); - - if (num != 3) -- return count; -+ return -EINVAL; - - switch (len) { - case 1: -@@ -381,8 +393,11 @@ static ssize_t rtw_debugfs_set_h2c(struc - char tmp[32 + 1]; - u8 param[8]; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ if (ret) -+ return ret; - - num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx", - ¶m[0], ¶m[1], ¶m[2], ¶m[3], -@@ -408,14 +423,17 @@ static ssize_t rtw_debugfs_set_rf_write( - char tmp[32 + 1]; - u32 path, addr, mask, val; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4); -+ if (ret) -+ return ret; - - num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val); - - if (num != 4) { - rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); -- return count; -+ return -EINVAL; - } - - mutex_lock(&rtwdev->mutex); -@@ -438,14 +456,17 @@ static ssize_t rtw_debugfs_set_rf_read(s - char tmp[32 + 1]; - u32 path, addr, mask; - int num; -+ int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3); -+ if (ret) -+ return ret; - - num = sscanf(tmp, "%x %x %x", &path, &addr, &mask); - - if (num != 3) { - rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n"); -- return count; -+ return -EINVAL; - } - - debugfs_priv->rf_path = path; -@@ -467,7 +488,9 @@ static ssize_t rtw_debugfs_set_fix_rate( - char tmp[32 + 1]; - int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ if (ret) -+ return ret; - - ret = kstrtou8(tmp, 0, &fix_rate); - if (ret) { -@@ -860,7 +883,9 @@ static ssize_t rtw_debugfs_set_coex_enab - bool enable; - int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ if (ret) -+ return ret; - - ret = kstrtobool(tmp, &enable); - if (ret) { -@@ -930,7 +955,9 @@ static ssize_t rtw_debugfs_set_fw_crash( - bool input; - int ret; - -- rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); -+ if (ret) -+ return ret; - - ret = kstrtobool(tmp, &input); - if (ret) diff --git a/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-unlock-on-error-path-in-rtw_ops_add_inter.patch b/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-unlock-on-error-path-in-rtw_ops_add_inter.patch deleted file mode 100644 index d067162ca..000000000 --- a/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-unlock-on-error-path-in-rtw_ops_add_inter.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e2ff1181b3d48257aab26bfd2165f3c7d271499f Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 3 May 2023 18:09:55 +0300 -Subject: [PATCH 03/12] wifi: rtw88: unlock on error path in - rtw_ops_add_interface() - -Call mutex_unlock(&rtwdev->mutex); before returning on this error path. - -Fixes: f0e741e4ddbc ("wifi: rtw88: add bitmap for dynamic port settings") -Signed-off-by: Dan Carpenter -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/ddd10a74-5982-4f65-8c59-c1cca558d239@kili.mountain ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -173,8 +173,10 @@ static int rtw_ops_add_interface(struct - mutex_lock(&rtwdev->mutex); - - port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); -- if (port >= RTW_PORT_NUM) -+ if (port >= RTW_PORT_NUM) { -+ mutex_unlock(&rtwdev->mutex); - return -EINVAL; -+ } - set_bit(port, rtwdev->hw_port); - - rtwvif->port = port; diff --git a/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-use-work-to-update-rate-to-avoid-RCU-warn.patch b/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-use-work-to-update-rate-to-avoid-RCU-warn.patch deleted file mode 100644 index e629593d1..000000000 --- a/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-use-work-to-update-rate-to-avoid-RCU-warn.patch +++ /dev/null @@ -1,132 +0,0 @@ -From bcafcb959a57a6890e900199690c5fc47da1a304 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 8 May 2023 16:54:29 +0800 -Subject: [PATCH 04/12] wifi: rtw88: use work to update rate to avoid RCU - warning - -The ieee80211_ops::sta_rc_update must be atomic, because -ieee80211_chan_bw_change() holds rcu_read lock while calling -drv_sta_rc_update(), so create a work to do original things. - - Voluntary context switch within RCU read-side critical section! - WARNING: CPU: 0 PID: 4621 at kernel/rcu/tree_plugin.h:318 - rcu_note_context_switch+0x571/0x5d0 - CPU: 0 PID: 4621 Comm: kworker/u16:2 Tainted: G W OE - Workqueue: phy3 ieee80211_chswitch_work [mac80211] - RIP: 0010:rcu_note_context_switch+0x571/0x5d0 - Call Trace: - - __schedule+0xb0/0x1460 - ? __mod_timer+0x116/0x360 - schedule+0x5a/0xc0 - schedule_timeout+0x87/0x150 - ? trace_raw_output_tick_stop+0x60/0x60 - wait_for_completion_timeout+0x7b/0x140 - usb_start_wait_urb+0x82/0x160 [usbcore - usb_control_msg+0xe3/0x140 [usbcore - rtw_usb_read+0x88/0xe0 [rtw_usb - rtw_usb_read8+0xf/0x10 [rtw_usb - rtw_fw_send_h2c_command+0xa0/0x170 [rtw_core - rtw_fw_send_ra_info+0xc9/0xf0 [rtw_core - drv_sta_rc_update+0x7c/0x160 [mac80211 - ieee80211_chan_bw_change+0xfb/0x110 [mac80211 - ieee80211_change_chanctx+0x38/0x130 [mac80211 - ieee80211_vif_use_reserved_switch+0x34e/0x900 [mac80211 - ieee80211_link_use_reserved_context+0x88/0xe0 [mac80211 - ieee80211_chswitch_work+0x95/0x170 [mac80211 - process_one_work+0x201/0x410 - worker_thread+0x4a/0x3b0 - ? process_one_work+0x410/0x410 - kthread+0xe1/0x110 - ? kthread_complete_and_exit+0x20/0x20 - ret_from_fork+0x1f/0x30 - - -Cc: stable@vger.kernel.org -Fixes: c1edc86472fc ("rtw88: add ieee80211:sta_rc_update ops") -Reported-by: Larry Finger -Link: https://lore.kernel.org/linux-wireless/f1e31e8e-f84e-3791-50fb-663a83c5c6e9@lwfinger.net/T/#t -Signed-off-by: Ping-Ke Shih -Tested-by: Larry Finger -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508085429.46653-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +- - drivers/net/wireless/realtek/rtw88/main.c | 15 +++++++++++++++ - drivers/net/wireless/realtek/rtw88/main.h | 3 +++ - 3 files changed, 19 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -920,7 +920,7 @@ static void rtw_ops_sta_rc_update(struct - struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; - - if (changed & IEEE80211_RC_BW_CHANGED) -- rtw_update_sta_info(rtwdev, si, true); -+ ieee80211_queue_work(rtwdev->hw, &si->rc_work); - } - - const struct ieee80211_ops rtw_ops = { ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -319,6 +319,17 @@ static u8 rtw_acquire_macid(struct rtw_d - return mac_id; - } - -+static void rtw_sta_rc_work(struct work_struct *work) -+{ -+ struct rtw_sta_info *si = container_of(work, struct rtw_sta_info, -+ rc_work); -+ struct rtw_dev *rtwdev = si->rtwdev; -+ -+ mutex_lock(&rtwdev->mutex); -+ rtw_update_sta_info(rtwdev, si, true); -+ mutex_unlock(&rtwdev->mutex); -+} -+ - int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, - struct ieee80211_vif *vif) - { -@@ -329,12 +340,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, - if (si->mac_id >= RTW_MAX_MAC_ID_NUM) - return -ENOSPC; - -+ si->rtwdev = rtwdev; - si->sta = sta; - si->vif = vif; - si->init_ra_lv = 1; - ewma_rssi_init(&si->avg_rssi); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - rtw_txq_init(rtwdev, sta->txq[i]); -+ INIT_WORK(&si->rc_work, rtw_sta_rc_work); - - rtw_update_sta_info(rtwdev, si, true); - rtw_fw_media_status_report(rtwdev, si->mac_id, true); -@@ -353,6 +366,8 @@ void rtw_sta_remove(struct rtw_dev *rtwd - struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; - int i; - -+ cancel_work_sync(&si->rc_work); -+ - rtw_release_macid(rtwdev, si->mac_id); - if (fw_exist) - rtw_fw_media_status_report(rtwdev, si->mac_id, false); ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -743,6 +743,7 @@ struct rtw_txq { - DECLARE_EWMA(rssi, 10, 16); - - struct rtw_sta_info { -+ struct rtw_dev *rtwdev; - struct ieee80211_sta *sta; - struct ieee80211_vif *vif; - -@@ -767,6 +768,8 @@ struct rtw_sta_info { - - bool use_cfg_mask; - struct cfg80211_bitrate_mask *mask; -+ -+ struct work_struct rc_work; - }; - - enum rtw_bfee_role { diff --git a/package/kernel/mac80211/patches/rtl/050-wifi-rtw88-correct-qsel_to_ep-type-as-int.patch b/package/kernel/mac80211/patches/rtl/050-wifi-rtw88-correct-qsel_to_ep-type-as-int.patch deleted file mode 100644 index d27af4739..000000000 --- a/package/kernel/mac80211/patches/rtl/050-wifi-rtw88-correct-qsel_to_ep-type-as-int.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8e4942db5f5ed7b7d9690d93235b3ca49c5c59ce Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 8 May 2023 16:55:39 +0800 -Subject: [PATCH 05/12] wifi: rtw88: correct qsel_to_ep[] type as int - -qsel_to_ep[] can be assigned negative value, so change type from 'u8' to -'int'. Otherwise, Smatch static checker warns: - drivers/net/wireless/realtek/rtw88/usb.c:219 rtw_usb_parse() warn: - assigning (-22) to unsigned variable 'rtwusb->qsel_to_ep[8]' - -Cc: stable@vger.kernel.org -Fixes: a6f187f92bcc ("wifi: rtw88: usb: fix priority queue to endpoint mapping") -Reported-by: Dan Carpenter -Link: https://lore.kernel.org/linux-wireless/c3f70197-829d-48ed-ae15-66a9de80fa90@kili.mountain/ -Cc: Sascha Hauer -Signed-off-by: Ping-Ke Shih -Acked-by: Sascha Hauer -Tested-by: Larry Finger -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508085539.46795-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/usb.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/usb.h -+++ b/drivers/net/wireless/realtek/rtw88/usb.h -@@ -78,7 +78,7 @@ struct rtw_usb { - u8 pipe_interrupt; - u8 pipe_in; - u8 out_ep[RTW_USB_EP_MAX]; -- u8 qsel_to_ep[TX_DESC_QSEL_MAX]; -+ int qsel_to_ep[TX_DESC_QSEL_MAX]; - u8 usb_txagg_num; - - struct workqueue_struct *txwq, *rxwq; diff --git a/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-sdio-Always-use-two-consecutive-bytes-for.patch b/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-sdio-Always-use-two-consecutive-bytes-for.patch deleted file mode 100644 index 3697343fa..000000000 --- a/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-sdio-Always-use-two-consecutive-bytes-for.patch +++ /dev/null @@ -1,60 +0,0 @@ -From cb0ddaaa5db09d7d216fcbf0e68779be223a1128 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 15 May 2023 21:50:43 +0200 -Subject: [PATCH 06/12] wifi: rtw88: sdio: Always use two consecutive bytes for - word operations - -The Allwinner sunxi-mmc controller cannot handle word (16 bit) -transfers. So and sdio_{read,write}w fails with messages like the -following example using an RTL8822BS (but the same problems were also -observed with RTL8822CS and RTL8723DS chips): - rtw_8822bs mmc1:0001:1: Firmware version 27.2.0, H2C version 13 - sunxi-mmc 4021000.mmc: unaligned scatterlist: os f80 length 2 - sunxi-mmc 4021000.mmc: map DMA failed - rtw_8822bs mmc1:0001:1: sdio read16 failed (0x10230): -22 - -Use two consecutive single byte accesses for word operations instead. It -turns out that upon closer inspection this is also what the vendor -driver does, even though it does have support for sdio_{read,write}w. So -we can conclude that the rtw88 chips do support word access but only on -SDIO controllers that also support it. Since there's no way to detect if -the controller supports word access or not the rtw88 sdio driver -switches to the easiest approach: avoiding word access. - -Reported-by: Larry Finger -Closes: https://lore.kernel.org/linux-wireless/527585e5-9cdd-66ed-c3af-6da162f4b720@lwfinger.net/ -Reported-by: Rudi Heitbaum -Link: https://github.com/LibreELEC/LibreELEC.tv/pull/7837#issue-1708469467 -Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230515195043.572375-1-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/sdio.c | 8 -------- - 1 file changed, 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/sdio.c -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -87,11 +87,6 @@ static void rtw_sdio_writew(struct rtw_d - u8 buf[2]; - int i; - -- if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2)) { -- sdio_writew(rtwsdio->sdio_func, val, addr, err_ret); -- return; -- } -- - *(__le16 *)buf = cpu_to_le16(val); - - for (i = 0; i < 2; i++) { -@@ -125,9 +120,6 @@ static u16 rtw_sdio_readw(struct rtw_dev - u8 buf[2]; - int i; - -- if (rtw_sdio_use_memcpy_io(rtwdev, addr, 2)) -- return sdio_readw(rtwsdio->sdio_func, addr, err_ret); -- - for (i = 0; i < 2; i++) { - buf[i] = sdio_readb(rtwsdio->sdio_func, addr + i, err_ret); - if (*err_ret) diff --git a/package/kernel/mac80211/patches/rtl/052-wifi-rtw88-sdio-Check-the-HISR-RX_REQUEST-bit-in-rtw.patch b/package/kernel/mac80211/patches/rtl/052-wifi-rtw88-sdio-Check-the-HISR-RX_REQUEST-bit-in-rtw.patch deleted file mode 100644 index d3216ede4..000000000 --- a/package/kernel/mac80211/patches/rtl/052-wifi-rtw88-sdio-Check-the-HISR-RX_REQUEST-bit-in-rtw.patch +++ /dev/null @@ -1,84 +0,0 @@ -From e967229ead0e6c5047a1cfd5a0db58ceb930800b Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 22 May 2023 22:24:22 +0200 -Subject: [PATCH 07/12] wifi: rtw88: sdio: Check the HISR RX_REQUEST bit in - rtw_sdio_rx_isr() - -rtw_sdio_rx_isr() is responsible for receiving data from the wifi chip -and is called from the SDIO interrupt handler when the interrupt status -register (HISR) has the RX_REQUEST bit set. After the first batch of -data has been processed by the driver the wifi chip may have more data -ready to be read, which is managed by a loop in rtw_sdio_rx_isr(). - -It turns out that there are cases where the RX buffer length (from the -REG_SDIO_RX0_REQ_LEN register) does not match the data we receive. The -following two cases were observed with a RTL8723DS card: -- RX length is smaller than the total packet length including overhead - and actual data bytes (whose length is part of the buffer we read from - the wifi chip and is stored in rtw_rx_pkt_stat.pkt_len). This can - result in errors like: - skbuff: skb_over_panic: text:ffff8000011924ac len:3341 put:3341 - (one case observed was: RX buffer length = 1536 bytes but - rtw_rx_pkt_stat.pkt_len = 1546 bytes, this is not valid as it means - we need to read beyond the end of the buffer) -- RX length looks valid but rtw_rx_pkt_stat.pkt_len is zero - -Check if the RX_REQUEST is set in the HISR register for each iteration -inside rtw_sdio_rx_isr(). This mimics what the RTL8723DS vendor driver -does and makes the driver only read more data if the RX_REQUEST bit is -set (which seems to be a way for the card's hardware or firmware to -tell the host that data is ready to be processed). - -For RTW_WCPU_11AC chips this check is not needed. The RTL8822BS vendor -driver for example states that this check is unnecessary (but still uses -it) and the RTL8822CS drops this check entirely. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522202425.1827005-2-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/sdio.c | 24 ++++++++++++++++++++--- - 1 file changed, 21 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/sdio.c -+++ b/drivers/net/wireless/realtek/rtw88/sdio.c -@@ -998,9 +998,9 @@ static void rtw_sdio_rxfifo_recv(struct - - static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) - { -- u32 rx_len, total_rx_bytes = 0; -+ u32 rx_len, hisr, total_rx_bytes = 0; - -- while (total_rx_bytes < SZ_64K) { -+ do { - if (rtw_chip_wcpu_11n(rtwdev)) - rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); - else -@@ -1012,7 +1012,25 @@ static void rtw_sdio_rx_isr(struct rtw_d - rtw_sdio_rxfifo_recv(rtwdev, rx_len); - - total_rx_bytes += rx_len; -- } -+ -+ if (rtw_chip_wcpu_11n(rtwdev)) { -+ /* Stop if no more RX requests are pending, even if -+ * rx_len could be greater than zero in the next -+ * iteration. This is needed because the RX buffer may -+ * already contain data while either HW or FW are not -+ * done filling that buffer yet. Still reading the -+ * buffer can result in packets where -+ * rtw_rx_pkt_stat.pkt_len is zero or points beyond the -+ * end of the buffer. -+ */ -+ hisr = rtw_read32(rtwdev, REG_SDIO_HISR); -+ } else { -+ /* RTW_WCPU_11AC chips have improved hardware or -+ * firmware and can use rx_len unconditionally. -+ */ -+ hisr = REG_SDIO_HISR_RX_REQUEST; -+ } -+ } while (total_rx_bytes < SZ_64K && hisr & REG_SDIO_HISR_RX_REQUEST); - } - - static void rtw_sdio_handle_interrupt(struct sdio_func *sdio_func) diff --git a/package/kernel/mac80211/patches/rtl/053-wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch b/package/kernel/mac80211/patches/rtl/053-wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch deleted file mode 100644 index d15854fb7..000000000 --- a/package/kernel/mac80211/patches/rtl/053-wifi-rtw88-rtw8723d-Implement-RTL8723DS-SDIO-efuse-p.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 9be20a82232779c59979527dfc8febca3182fee2 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 22 May 2023 22:24:23 +0200 -Subject: [PATCH 08/12] wifi: rtw88: rtw8723d: Implement RTL8723DS (SDIO) efuse - parsing - -The efuse of the SDIO RTL8723DS chip has only one known member: the mac -address is at offset 0x11a. Add a struct rtw8723ds_efuse describing this -and use it for copying the mac address when the SDIO bus is used. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522202425.1827005-3-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/rtw8723d.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw88/rtw8723d.h | 6 ++++++ - 2 files changed, 15 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -@@ -216,6 +216,12 @@ static void rtw8723du_efuse_parsing(stru - ether_addr_copy(efuse->addr, map->u.mac_addr); - } - -+static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, -+ struct rtw8723d_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->s.mac_addr); -+} -+ - static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - { - struct rtw_efuse *efuse = &rtwdev->efuse; -@@ -248,6 +254,9 @@ static int rtw8723d_read_efuse(struct rt - case RTW_HCI_TYPE_USB: - rtw8723du_efuse_parsing(efuse, map); - break; -+ case RTW_HCI_TYPE_SDIO: -+ rtw8723ds_efuse_parsing(efuse, map); -+ break; - default: - /* unsupported now */ - return -ENOTSUPP; ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h -@@ -49,6 +49,11 @@ struct rtw8723du_efuse { - u8 mac_addr[ETH_ALEN]; /* 0x107 */ - }; - -+struct rtw8723ds_efuse { -+ u8 res4[0x4a]; /* 0xd0 */ -+ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -+}; -+ - struct rtw8723d_efuse { - __le16 rtl_id; - u8 rsvd[2]; -@@ -80,6 +85,7 @@ struct rtw8723d_efuse { - union { - struct rtw8723de_efuse e; - struct rtw8723du_efuse u; -+ struct rtw8723ds_efuse s; - }; - }; - diff --git a/package/kernel/mac80211/patches/rtl/054-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch b/package/kernel/mac80211/patches/rtl/054-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch deleted file mode 100644 index 56a88f841..000000000 --- a/package/kernel/mac80211/patches/rtl/054-wifi-rtw88-Add-support-for-the-SDIO-based-RTL8723DS-.patch +++ /dev/null @@ -1,96 +0,0 @@ -From a3b125ceb45e1acd21c9bcb6d3a5c52897d536e6 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Mon, 22 May 2023 22:24:25 +0200 -Subject: [PATCH 09/12] wifi: rtw88: Add support for the SDIO based RTL8723DS - chipset - -Wire up RTL8723DS chipset support using the rtw88 SDIO HCI code as well -as the existing RTL8723D chipset code. - -Reviewed-by: Ping-Ke Shih -Signed-off-by: Martin Blumenstingl -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522202425.1827005-5-martin.blumenstingl@googlemail.com ---- - drivers/net/wireless/realtek/rtw88/Kconfig | 11 +++++ - drivers/net/wireless/realtek/rtw88/Makefile | 3 ++ - .../net/wireless/realtek/rtw88/rtw8723ds.c | 41 +++++++++++++++++++ - 3 files changed, 55 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723ds.c - ---- a/drivers/net/wireless/realtek/rtw88/Kconfig -+++ b/drivers/net/wireless/realtek/rtw88/Kconfig -@@ -129,6 +129,17 @@ config RTW88_8723DE - - 802.11n PCIe wireless network adapter - -+config RTW88_8723DS -+ tristate "Realtek 8723DS SDIO wireless network adapter" -+ depends on MMC -+ select RTW88_CORE -+ select RTW88_SDIO -+ select RTW88_8723D -+ help -+ Select this option will enable support for 8723DS chipset -+ -+ 802.11n SDIO wireless network adapter -+ - config RTW88_8723DU - tristate "Realtek 8723DU USB wireless network adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw88/Makefile -+++ b/drivers/net/wireless/realtek/rtw88/Makefile -@@ -50,6 +50,9 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d - obj-$(CPTCFG_RTW88_8723DE) += rtw88_8723de.o - rtw88_8723de-objs := rtw8723de.o - -+obj-$(CPTCFG_RTW88_8723DS) += rtw88_8723ds.o -+rtw88_8723ds-objs := rtw8723ds.o -+ - obj-$(CPTCFG_RTW88_8723DU) += rtw88_8723du.o - rtw88_8723du-objs := rtw8723du.o - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723ds.c -@@ -0,0 +1,41 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include "main.h" -+#include "rtw8723d.h" -+#include "sdio.h" -+ -+static const struct sdio_device_id rtw_8723ds_id_table[] = { -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT), -+ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, -+ }, -+ { -+ SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, -+ SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT), -+ .driver_data = (kernel_ulong_t)&rtw8723d_hw_spec, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); -+ -+static struct sdio_driver rtw_8723ds_driver = { -+ .name = "rtw_8723ds", -+ .probe = rtw_sdio_probe, -+ .remove = rtw_sdio_remove, -+ .id_table = rtw_8723ds_id_table, -+ .drv = { -+ .pm = &rtw_sdio_pm_ops, -+ .shutdown = rtw_sdio_shutdown, -+ } -+}; -+module_sdio_driver(rtw_8723ds_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Realtek 802.11n wireless 8723ds driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/055-wifi-rtw88-usb-silence-log-flooding-error-message.patch b/package/kernel/mac80211/patches/rtl/055-wifi-rtw88-usb-silence-log-flooding-error-message.patch deleted file mode 100644 index f5e4d40bc..000000000 --- a/package/kernel/mac80211/patches/rtl/055-wifi-rtw88-usb-silence-log-flooding-error-message.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1f1784a59caf3eefd127908a1a3cf224017ff9c7 Mon Sep 17 00:00:00 2001 -From: Sascha Hauer -Date: Wed, 24 May 2023 12:39:34 +0200 -Subject: [PATCH 10/12] wifi: rtw88: usb: silence log flooding error message - -When receiving more rx packets than the kernel can handle the driver -drops the packets and issues an error message. This is bad for two -reasons. The logs are flooded with myriads of messages, but then time -consumed for printing messages in that critical code path brings down -the device. After some time of excessive rx load the driver responds -with: - -rtw_8822cu 1-1:1.2: failed to get tx report from firmware -rtw_8822cu 1-1:1.2: firmware failed to report density after scan -rtw_8822cu 1-1:1.2: firmware failed to report density after scan - -The device stops working until being replugged. - -Fix this by lowering the priority to debug level and also by -ratelimiting it. - -Fixes: a82dfd33d1237 ("wifi: rtw88: Add common USB chip support") -Signed-off-by: Sascha Hauer -Reviewed-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230524103934.1019096-1-s.hauer@pengutronix.de ---- - drivers/net/wireless/realtek/rtw88/usb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -535,7 +535,7 @@ static void rtw_usb_rx_handler(struct wo - } - - if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { -- rtw_err(rtwdev, "failed to get rx_queue, overflow\n"); -+ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); - dev_kfree_skb_any(skb); - continue; - } diff --git a/package/kernel/mac80211/patches/rtl/056-wifi-rtw88-correct-PS-calculation-for-SUPPORTS_DYNAM.patch b/package/kernel/mac80211/patches/rtl/056-wifi-rtw88-correct-PS-calculation-for-SUPPORTS_DYNAM.patch deleted file mode 100644 index 5d15e8da8..000000000 --- a/package/kernel/mac80211/patches/rtl/056-wifi-rtw88-correct-PS-calculation-for-SUPPORTS_DYNAM.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 3918dd0177ee08970683a2c22a3388825d82fd79 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 27 May 2023 16:29:37 +0800 -Subject: [PATCH 11/12] wifi: rtw88: correct PS calculation for - SUPPORTS_DYNAMIC_PS - -This driver relies on IEEE80211_CONF_PS of hw->conf.flags to turn off PS or -turn on dynamic PS controlled by driver and firmware. Though this would be -incorrect, it did work before because the flag is always recalculated until -the commit 28977e790b5d ("wifi: mac80211: skip powersave recalc if driver SUPPORTS_DYNAMIC_PS") -is introduced by kernel 5.20 to skip to recalculate IEEE80211_CONF_PS -of hw->conf.flags if driver sets SUPPORTS_DYNAMIC_PS. - -Correct this by doing recalculation while BSS_CHANGED_PS is changed and -interface is added or removed. It is allowed to enter PS only if single -one station vif is working. Without this fix, driver doesn't enter PS -anymore that causes higher power consumption. - -Fixes: bcde60e599fb ("rtw88: remove misleading module parameter rtw_fw_support_lps") -Cc: stable@vger.kernel.org # 6.1+ -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230527082939.11206-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++--- - drivers/net/wireless/realtek/rtw88/main.c | 4 +- - drivers/net/wireless/realtek/rtw88/ps.c | 43 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/ps.h | 2 + - 4 files changed, 52 insertions(+), 11 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -88,15 +88,6 @@ static int rtw_ops_config(struct ieee802 - } - } - -- if (changed & IEEE80211_CONF_CHANGE_PS) { -- if (hw->conf.flags & IEEE80211_CONF_PS) { -- rtwdev->ps_enabled = true; -- } else { -- rtwdev->ps_enabled = false; -- rtw_leave_lps(rtwdev); -- } -- } -- - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) - rtw_set_channel(rtwdev); - -@@ -215,6 +206,7 @@ static int rtw_ops_add_interface(struct - config |= PORT_SET_BCN_CTRL; - rtw_vif_port_config(rtwdev, rtwvif, config); - rtw_core_port_switch(rtwdev, vif); -+ rtw_recalc_lps(rtwdev, vif); - - mutex_unlock(&rtwdev->mutex); - -@@ -246,6 +238,7 @@ static void rtw_ops_remove_interface(str - config |= PORT_SET_BCN_CTRL; - rtw_vif_port_config(rtwdev, rtwvif, config); - clear_bit(rtwvif->port, rtwdev->hw_port); -+ rtw_recalc_lps(rtwdev, NULL); - - mutex_unlock(&rtwdev->mutex); - } -@@ -440,6 +433,9 @@ static void rtw_ops_bss_info_changed(str - if (changed & BSS_CHANGED_ERP_SLOT) - rtw_conf_tx(rtwdev, rtwvif); - -+ if (changed & BSS_CHANGED_PS) -+ rtw_recalc_lps(rtwdev, NULL); -+ - rtw_vif_port_config(rtwdev, rtwvif, config); - - mutex_unlock(&rtwdev->mutex); ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -271,8 +271,8 @@ static void rtw_watch_dog_work(struct wo - * more than two stations associated to the AP, then we can not enter - * lps, because fw does not handle the overlapped beacon interval - * -- * mac80211 should iterate vifs and determine if driver can enter -- * ps by passing IEEE80211_CONF_PS to us, all we need to do is to -+ * rtw_recalc_lps() iterate vifs and determine if driver can enter -+ * ps by vif->type and vif->cfg.ps, all we need to do here is to - * get that vif and check if device is having traffic more than the - * threshold. - */ ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -299,3 +299,46 @@ void rtw_leave_lps_deep(struct rtw_dev * - - __rtw_leave_lps_deep(rtwdev); - } -+ -+struct rtw_vif_recalc_lps_iter_data { -+ struct rtw_dev *rtwdev; -+ struct ieee80211_vif *found_vif; -+ int count; -+}; -+ -+static void __rtw_vif_recalc_lps(struct rtw_vif_recalc_lps_iter_data *data, -+ struct ieee80211_vif *vif) -+{ -+ if (data->count < 0) -+ return; -+ -+ if (vif->type != NL80211_IFTYPE_STATION) { -+ data->count = -1; -+ return; -+ } -+ -+ data->count++; -+ data->found_vif = vif; -+} -+ -+static void rtw_vif_recalc_lps_iter(void *data, u8 *mac, -+ struct ieee80211_vif *vif) -+{ -+ __rtw_vif_recalc_lps(data, vif); -+} -+ -+void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif) -+{ -+ struct rtw_vif_recalc_lps_iter_data data = { .rtwdev = rtwdev }; -+ -+ if (new_vif) -+ __rtw_vif_recalc_lps(&data, new_vif); -+ rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data); -+ -+ if (data.count == 1 && data.found_vif->cfg.ps) { -+ rtwdev->ps_enabled = true; -+ } else { -+ rtwdev->ps_enabled = false; -+ rtw_leave_lps(rtwdev); -+ } -+} ---- a/drivers/net/wireless/realtek/rtw88/ps.h -+++ b/drivers/net/wireless/realtek/rtw88/ps.h -@@ -23,4 +23,6 @@ void rtw_enter_lps(struct rtw_dev *rtwde - void rtw_leave_lps(struct rtw_dev *rtwdev); - void rtw_leave_lps_deep(struct rtw_dev *rtwdev); - enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev); -+void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif); -+ - #endif diff --git a/package/kernel/mac80211/patches/rtl/057-wifi-rtw88-add-missing-unwind-goto-for-__rtw_downloa.patch b/package/kernel/mac80211/patches/rtl/057-wifi-rtw88-add-missing-unwind-goto-for-__rtw_downloa.patch deleted file mode 100644 index b3f650b41..000000000 --- a/package/kernel/mac80211/patches/rtl/057-wifi-rtw88-add-missing-unwind-goto-for-__rtw_downloa.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 91ccdbb94feadb0d8bf3b35c841b33ac95f2f45f Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 7 Jun 2023 09:27:41 +0800 -Subject: [PATCH 12/12] wifi: rtw88: add missing unwind goto for - __rtw_download_firmware() - -This flaw is detected by smatch: - drivers/net/wireless/realtek/rtw88/mac.c:748 __rtw_download_firmware() - warn: missing unwind goto? - -Though most things of dlfw_fail have been done by -download_firmware_end_flow() and wlan_cpu_enable(), an exception is that -download_firmware_end_flow() clear BIT_MCUFWDL_EN bit conditionally. -So, make this change to clear the bit. - -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Closes: https://lore.kernel.org/r/202306052310.OVhcUjZ3-lkp@intel.com/ -Cc: Sascha Hauer -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230607012741.10353-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac.c -+++ b/drivers/net/wireless/realtek/rtw88/mac.c -@@ -794,8 +794,10 @@ static int __rtw_download_firmware(struc - - wlan_cpu_enable(rtwdev, true); - -- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) -- return -EBUSY; -+ if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { -+ ret = -EBUSY; -+ goto dlfw_fail; -+ } - - ret = download_firmware_validate(rtwdev); - if (ret) diff --git a/package/kernel/mac80211/patches/rtl/058-wifi-rtw88-Fix-action-frame-transmission-fail-before.patch b/package/kernel/mac80211/patches/rtl/058-wifi-rtw88-Fix-action-frame-transmission-fail-before.patch deleted file mode 100644 index 28dfaed17..000000000 --- a/package/kernel/mac80211/patches/rtl/058-wifi-rtw88-Fix-action-frame-transmission-fail-before.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2ce9a91fe8bfb0c8e647a6b7b88055881faf7502 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Thu, 15 Jun 2023 19:43:48 +0800 -Subject: [PATCH 1/8] wifi: rtw88: Fix action frame transmission fail before - association - -For combo chips, antennas were controlled by bluetooth only during -power on. If WiFi wish to do transmission, notification to the coexistence -module are required. Previously we only do this before authentication. -To allow transmission before auth, such as management TX, now we start -the initiation of coexistence earlier so antennas are shared between -WiFi and bluetooth after set_channel(), and frames could then be sent. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615114348.7193-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/ps.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/ps.c -+++ b/drivers/net/wireless/realtek/rtw88/ps.c -@@ -18,6 +18,7 @@ static int rtw_ips_pwr_up(struct rtw_dev - if (ret) - rtw_err(rtwdev, "leave idle state failed\n"); - -+ rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); - rtw_set_channel(rtwdev); - - return ret; -@@ -63,8 +64,6 @@ int rtw_leave_ips(struct rtw_dev *rtwdev - - rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev); - -- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE); -- - return 0; - } - diff --git a/package/kernel/mac80211/patches/rtl/059-wifi-rtw88-process-VO-packets-without-workqueue-to-a.patch b/package/kernel/mac80211/patches/rtl/059-wifi-rtw88-process-VO-packets-without-workqueue-to-a.patch deleted file mode 100644 index e750903ed..000000000 --- a/package/kernel/mac80211/patches/rtl/059-wifi-rtw88-process-VO-packets-without-workqueue-to-a.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 67d7f24b194e6e8e82540aa4fe97580f6cfa0902 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Fri, 16 Jun 2023 11:17:13 +0800 -Subject: [PATCH 2/8] wifi: rtw88: process VO packets without workqueue to - avoid PTK rekey failed - -In the wpa_supplicant rekey flow, it sends an EAPOL packet 4/4 through -nl80211_tx_control_port() and triggers wake_tx_queue() in the driver. -Then, it sends nl80211_new_key() to configure a new key in mac80211. -However, in wake_tx_queue(), a workqueue is used to process the tx packet, -which might cause the driver to process the EAPOL packet later than -nl80211_new_key(). As a result, the EAPOL 4/4 packet is dropped by mac80211 -due to the rekey configuration being finished. The EAPOL packets belongs to -VO packets that need high priority. Therefore, we process VO packets -directly without workqueue to ensure that packets can process immediately. - -VO is normally used by voice application that is low traffic load and low -latency, that doesn't affect user experience. -We test iperf with VO packets(iperf3 -P4 -u -b 10000M -S 0xdf) - before after -TX throughput 162M 162M -ping RTT 3.8ms 3.7ms - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616031713.16769-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 6 +++++- - drivers/net/wireless/realtek/rtw88/tx.c | 10 ++++++++-- - drivers/net/wireless/realtek/rtw88/tx.h | 1 + - 3 files changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -43,7 +43,11 @@ static void rtw_ops_wake_tx_queue(struct - list_add_tail(&rtwtxq->list, &rtwdev->txqs); - spin_unlock_bh(&rtwdev->txq_lock); - -- queue_work(rtwdev->tx_wq, &rtwdev->tx_work); -+ /* ensure to dequeue EAPOL (4/4) at the right time */ -+ if (txq->ac == IEEE80211_AC_VO) -+ __rtw_tx_work(rtwdev); -+ else -+ queue_work(rtwdev->tx_wq, &rtwdev->tx_work); - } - - static int rtw_ops_start(struct ieee80211_hw *hw) ---- a/drivers/net/wireless/realtek/rtw88/tx.c -+++ b/drivers/net/wireless/realtek/rtw88/tx.c -@@ -635,9 +635,8 @@ static void rtw_txq_push(struct rtw_dev - rcu_read_unlock(); - } - --void rtw_tx_work(struct work_struct *w) -+void __rtw_tx_work(struct rtw_dev *rtwdev) - { -- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); - struct rtw_txq *rtwtxq, *tmp; - - spin_lock_bh(&rtwdev->txq_lock); -@@ -658,6 +657,13 @@ void rtw_tx_work(struct work_struct *w) - spin_unlock_bh(&rtwdev->txq_lock); - } - -+void rtw_tx_work(struct work_struct *w) -+{ -+ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); -+ -+ __rtw_tx_work(rtwdev); -+} -+ - void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) - { - struct rtw_txq *rtwtxq; ---- a/drivers/net/wireless/realtek/rtw88/tx.h -+++ b/drivers/net/wireless/realtek/rtw88/tx.h -@@ -111,6 +111,7 @@ void rtw_tx(struct rtw_dev *rtwdev, - void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); - void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); - void rtw_tx_work(struct work_struct *w); -+void __rtw_tx_work(struct rtw_dev *rtwdev); - void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, - struct rtw_tx_pkt_info *pkt_info, - struct ieee80211_sta *sta, diff --git a/package/kernel/mac80211/patches/rtl/060-wifi-rtw88-use-struct-instead-of-macros-to-set-TX-de.patch b/package/kernel/mac80211/patches/rtl/060-wifi-rtw88-use-struct-instead-of-macros-to-set-TX-de.patch deleted file mode 100644 index 771288241..000000000 --- a/package/kernel/mac80211/patches/rtl/060-wifi-rtw88-use-struct-instead-of-macros-to-set-TX-de.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 88b9d8e6cf9cf89be50ca2ee6cb9b3180b432172 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:35 +0800 -Subject: [PATCH 3/8] wifi: rtw88: use struct instead of macros to set TX desc - -Remove macros that set TX descriptors. Use struct and -le32_encode_bits() with mask definitions. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/rtw8723d.c | 6 +- - drivers/net/wireless/realtek/rtw88/tx.c | 79 +++++++----- - drivers/net/wireless/realtek/rtw88/tx.h | 122 +++++++----------- - drivers/net/wireless/realtek/rtw88/usb.c | 12 +- - 4 files changed, 106 insertions(+), 113 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c -@@ -1970,15 +1970,17 @@ static void rtw8723d_fill_txdesc_checksu - size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ - __le16 chksum = 0; - __le16 *data = (__le16 *)(txdesc); -+ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; - -- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); -+ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); - - while (words--) - chksum ^= *data++; - - chksum = ~chksum; - -- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); -+ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), -+ RTW_TX_DESC_W7_TXDESC_CHECKSUM); - } - - static struct rtw_chip_ops rtw8723d_ops = { ---- a/drivers/net/wireless/realtek/rtw88/tx.c -+++ b/drivers/net/wireless/realtek/rtw88/tx.c -@@ -34,43 +34,52 @@ void rtw_tx_stats(struct rtw_dev *rtwdev - - void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) - { -- __le32 *txdesc = (__le32 *)skb->data; -+ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; -+ -+ tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | -+ le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | -+ le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) | -+ le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | -+ le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); -+ -+ tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | -+ le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | -+ le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | -+ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET); -+ -+ tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | -+ le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | -+ le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) | -+ le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL); -+ -+ tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) | -+ le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) | -+ le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) | -+ le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) | -+ le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) | -+ le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM); -+ -+ tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); -+ -+ tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | -+ le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | -+ le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | -+ le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC); -+ -+ tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE); -+ -+ tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ); -+ -+ tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ); - -- SET_TX_DESC_TXPKTSIZE(txdesc, pkt_info->tx_pkt_size); -- SET_TX_DESC_OFFSET(txdesc, pkt_info->offset); -- SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset); -- SET_TX_DESC_QSEL(txdesc, pkt_info->qsel); -- SET_TX_DESC_BMC(txdesc, pkt_info->bmc); -- SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id); -- SET_TX_DESC_DATARATE(txdesc, pkt_info->rate); -- SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback); -- SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate); -- SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type); -- SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw); -- SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq); -- SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor); -- SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density); -- SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc); -- SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc); -- SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en); -- SET_TX_DESC_LS(txdesc, pkt_info->ls); -- SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); -- SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); -- SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); -- SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); - if (pkt_info->rts) { -- SET_TX_DESC_RTSRATE(txdesc, DESC_RATE24M); -- SET_TX_DESC_DATA_RTS_SHORT(txdesc, 1); -- } -- SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); -- SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); -- SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); -- SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); -- SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); -- if (pkt_info->tim_offset) { -- SET_TX_DESC_TIM_EN(txdesc, 1); -- SET_TX_DESC_TIM_OFFSET(txdesc, pkt_info->tim_offset); -+ tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE); -+ tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT); - } -+ -+ if (pkt_info->tim_offset) -+ tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) | -+ le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET); - } - EXPORT_SYMBOL(rtw_tx_fill_tx_desc); - ---- a/drivers/net/wireless/realtek/rtw88/tx.h -+++ b/drivers/net/wireless/realtek/rtw88/tx.h -@@ -9,76 +9,52 @@ - - #define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500) - --#define SET_TX_DESC_TXPKTSIZE(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(15, 0)) --#define SET_TX_DESC_OFFSET(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, GENMASK(23, 16)) --#define SET_TX_DESC_PKT_OFFSET(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(28, 24)) --#define SET_TX_DESC_QSEL(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(12, 8)) --#define SET_TX_DESC_BMC(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(24)) --#define SET_TX_DESC_RATE_ID(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(20, 16)) --#define SET_TX_DESC_DATARATE(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(6, 0)) --#define SET_TX_DESC_DISDATAFB(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(10)) --#define SET_TX_DESC_USE_RATE(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(8)) --#define SET_TX_DESC_SEC_TYPE(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x01, value, GENMASK(23, 22)) --#define SET_TX_DESC_DATA_BW(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(6, 5)) --#define SET_TX_DESC_SW_SEQ(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) --#define SET_TX_DESC_TIM_EN(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, BIT(7)) --#define SET_TX_DESC_TIM_OFFSET(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(6, 0)) --#define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) --#define SET_TX_DESC_USE_RTS(tx_desc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) --#define SET_TX_DESC_RTSRATE(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x04, value, GENMASK(28, 24)) --#define SET_TX_DESC_DATA_RTS_SHORT(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(12)) --#define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) --#define SET_TX_DESC_DATA_STBC(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, GENMASK(9, 8)) --#define SET_TX_DESC_DATA_LDPC(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(7)) --#define SET_TX_DESC_AGG_EN(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(12)) --#define SET_TX_DESC_LS(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(26)) --#define SET_TX_DESC_DATA_SHORT(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x05, value, BIT(4)) --#define SET_TX_DESC_SPE_RPT(tx_desc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) --#define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) --#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) --#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) --#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) --#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) --#define SET_TX_DESC_BT_NULL(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) --#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0)) --#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \ -- le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24)) --#define GET_TX_DESC_PKT_OFFSET(txdesc) \ -- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24)) --#define GET_TX_DESC_QSEL(txdesc) \ -- le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8)) -+struct rtw_tx_desc { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+ __le32 w3; -+ __le32 w4; -+ __le32 w5; -+ __le32 w6; -+ __le32 w7; -+ __le32 w8; -+ __le32 w9; -+} __packed; -+ -+#define RTW_TX_DESC_W0_TXPKTSIZE GENMASK(15, 0) -+#define RTW_TX_DESC_W0_OFFSET GENMASK(23, 16) -+#define RTW_TX_DESC_W0_BMC BIT(24) -+#define RTW_TX_DESC_W0_LS BIT(26) -+#define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) -+#define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) -+#define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) -+#define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) -+#define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) -+#define RTW_TX_DESC_W2_AGG_EN BIT(12) -+#define RTW_TX_DESC_W2_SPE_RPT BIT(19) -+#define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) -+#define RTW_TX_DESC_W2_BT_NULL BIT(23) -+#define RTW_TX_DESC_W3_HW_SSN_SEL GENMASK(7, 6) -+#define RTW_TX_DESC_W3_USE_RATE BIT(8) -+#define RTW_TX_DESC_W3_DISDATAFB BIT(10) -+#define RTW_TX_DESC_W3_USE_RTS BIT(12) -+#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) -+#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) -+#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) -+#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) -+#define RTW_TX_DESC_W5_DATA_SHORT BIT(4) -+#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) -+#define RTW_TX_DESC_W5_DATA_LDPC BIT(7) -+#define RTW_TX_DESC_W5_DATA_STBC GENMASK(9, 8) -+#define RTW_TX_DESC_W5_DATA_RTS_SHORT BIT(12) -+#define RTW_TX_DESC_W6_SW_DEFINE GENMASK(11, 0) -+#define RTW_TX_DESC_W7_TXDESC_CHECKSUM GENMASK(15, 0) -+#define RTW_TX_DESC_W7_DMA_TXAGG_NUM GENMASK(31, 24) -+#define RTW_TX_DESC_W8_EN_HWSEQ BIT(15) -+#define RTW_TX_DESC_W9_SW_SEQ GENMASK(23, 12) -+#define RTW_TX_DESC_W9_TIM_EN BIT(7) -+#define RTW_TX_DESC_W9_TIM_OFFSET GENMASK(6, 0) - - enum rtw_tx_desc_queue_select { - TX_DESC_QSEL_TID0 = 0, -@@ -140,13 +116,15 @@ void fill_txdesc_checksum_common(u8 *txd - { - __le16 chksum = 0; - __le16 *data = (__le16 *)(txdesc); -+ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; - -- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000); -+ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); - - while (words--) - chksum ^= *data++; - -- SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum)); -+ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), -+ RTW_TX_DESC_W7_TXDESC_CHECKSUM); - } - - static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -24,11 +24,12 @@ struct rtw_usb_txcb { - static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb, - struct sk_buff *skb, int agg_num) - { -+ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; - struct rtw_dev *rtwdev = rtwusb->rtwdev; - struct rtw_tx_pkt_info pkt_info; - -- SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num); -- pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data); -+ le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM); -+ pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET); - rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data); - } - -@@ -306,11 +307,13 @@ static int rtw_usb_write_port(struct rtw - static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list) - { - struct rtw_dev *rtwdev = rtwusb->rtwdev; -+ struct rtw_tx_desc *tx_desc; - struct rtw_usb_txcb *txcb; - struct sk_buff *skb_head; - struct sk_buff *skb_iter; - int agg_num = 0; - unsigned int align_next = 0; -+ u8 qsel; - - if (skb_queue_empty(list)) - return false; -@@ -363,9 +366,10 @@ static bool rtw_usb_tx_agg_skb(struct rt - - queue: - skb_queue_tail(&txcb->tx_ack_queue, skb_head); -+ tx_desc = (struct rtw_tx_desc *)skb_head->data; -+ qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL); - -- rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head, -- rtw_usb_write_port_tx_complete, txcb); -+ rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb); - - return true; - } diff --git a/package/kernel/mac80211/patches/rtl/061-wifi-rtw88-Fix-AP-mode-incorrect-DTIM-behavior.patch b/package/kernel/mac80211/patches/rtl/061-wifi-rtw88-Fix-AP-mode-incorrect-DTIM-behavior.patch deleted file mode 100644 index 8bb49133e..000000000 --- a/package/kernel/mac80211/patches/rtl/061-wifi-rtw88-Fix-AP-mode-incorrect-DTIM-behavior.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 076f786a0ae14a81f40314b96a2d815e264bc213 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:36 +0800 -Subject: [PATCH 4/8] wifi: rtw88: Fix AP mode incorrect DTIM behavior - -Broadcast and multicast packets in high queue should be transmitted -all at once during DTIM. But without proper settings, hardware fails -to recognize that there are multiple packets and fetches only one. -Fix this by signaling hardware with more data bit set when there are -packets in the high queue. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/mac80211.c | 2 ++ - drivers/net/wireless/realtek/rtw88/reg.h | 1 + - drivers/net/wireless/realtek/rtw88/tx.c | 7 ++++++- - drivers/net/wireless/realtek/rtw88/tx.h | 1 + - drivers/net/wireless/realtek/rtw88/usb.c | 3 +++ - 5 files changed, 13 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -453,6 +453,7 @@ static int rtw_ops_start_ap(struct ieee8 - const struct rtw_chip_info *chip = rtwdev->chip; - - mutex_lock(&rtwdev->mutex); -+ rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); - rtwdev->ap_active = true; - rtw_store_op_chan(rtwdev, true); - chip->ops->phy_calibration(rtwdev); -@@ -468,6 +469,7 @@ static void rtw_ops_stop_ap(struct ieee8 - struct rtw_dev *rtwdev = hw->priv; - - mutex_lock(&rtwdev->mutex); -+ rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); - rtwdev->ap_active = false; - if (!rtw_core_check_sta_active(rtwdev)) - rtw_clear_op_chan(rtwdev); ---- a/drivers/net/wireless/realtek/rtw88/reg.h -+++ b/drivers/net/wireless/realtek/rtw88/reg.h -@@ -410,6 +410,7 @@ - #define REG_TCR 0x0604 - #define BIT_PWRMGT_HWDATA_EN BIT(7) - #define BIT_TCR_UPDATE_TIMIE BIT(5) -+#define BIT_TCR_UPDATE_HGQMD BIT(4) - #define REG_RCR 0x0608 - #define BIT_APP_FCS BIT(31) - #define BIT_APP_MIC BIT(30) ---- a/drivers/net/wireless/realtek/rtw88/tx.c -+++ b/drivers/net/wireless/realtek/rtw88/tx.c -@@ -35,6 +35,10 @@ void rtw_tx_stats(struct rtw_dev *rtwdev - void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) - { - struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; -+ bool more_data = false; -+ -+ if (pkt_info->qsel == TX_DESC_QSEL_HIGH) -+ more_data = true; - - tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) | - le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) | -@@ -45,7 +49,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p - tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | - le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | - le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | -- le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET); -+ le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | -+ le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA); - - tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) | - le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) | ---- a/drivers/net/wireless/realtek/rtw88/tx.h -+++ b/drivers/net/wireless/realtek/rtw88/tx.h -@@ -31,6 +31,7 @@ struct rtw_tx_desc { - #define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) - #define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) - #define RTW_TX_DESC_W1_PKT_OFFSET GENMASK(28, 24) -+#define RTW_TX_DESC_W1_MORE_DATA BIT(29) - #define RTW_TX_DESC_W2_AGG_EN BIT(12) - #define RTW_TX_DESC_W2_SPE_RPT BIT(19) - #define RTW_TX_DESC_W2_AMPDU_DEN GENMASK(22, 20) ---- a/drivers/net/wireless/realtek/rtw88/usb.c -+++ b/drivers/net/wireless/realtek/rtw88/usb.c -@@ -469,6 +469,9 @@ static u8 rtw_usb_tx_queue_mapping_to_qs - - if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) - qsel = TX_DESC_QSEL_MGMT; -+ else if (is_broadcast_ether_addr(hdr->addr1) || -+ is_multicast_ether_addr(hdr->addr1)) -+ qsel = TX_DESC_QSEL_HIGH; - else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK) - qsel = skb->priority; - else diff --git a/package/kernel/mac80211/patches/rtl/062-wifi-rtw88-Skip-high-queue-in-hci_flush.patch b/package/kernel/mac80211/patches/rtl/062-wifi-rtw88-Skip-high-queue-in-hci_flush.patch deleted file mode 100644 index 4f8b31a89..000000000 --- a/package/kernel/mac80211/patches/rtl/062-wifi-rtw88-Skip-high-queue-in-hci_flush.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 9e09fbc5e90247fc6e77fb6ba72dcbf8088cf59a Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:37 +0800 -Subject: [PATCH 5/8] wifi: rtw88: Skip high queue in hci_flush - -The flush period may not always intersect with DTIM and when that -happens, an error log "timed out to flush pci TX ring[6]" is shown. -Bypass this since hardware will do proper transmission on the next -DTIM period for broadcast/multicast packets in high queue. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/pci.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/pci.c -+++ b/drivers/net/wireless/realtek/rtw88/pci.c -@@ -738,8 +738,9 @@ static void __rtw_pci_flush_queues(struc - u8 q; - - for (q = 0; q < RTK_MAX_TX_QUEUE_NUM; q++) { -- /* It may be not necessary to flush BCN and H2C tx queues. */ -- if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C) -+ /* Unnecessary to flush BCN, H2C and HI tx queues. */ -+ if (q == RTW_TX_QUEUE_BCN || q == RTW_TX_QUEUE_H2C || -+ q == RTW_TX_QUEUE_HI0) - continue; - - if (pci_queues & BIT(q)) diff --git a/package/kernel/mac80211/patches/rtl/063-wifi-rtw88-Stop-high-queue-during-scan.patch b/package/kernel/mac80211/patches/rtl/063-wifi-rtw88-Stop-high-queue-during-scan.patch deleted file mode 100644 index 68c28a72a..000000000 --- a/package/kernel/mac80211/patches/rtl/063-wifi-rtw88-Stop-high-queue-during-scan.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ad6741b1e0449ba8f4eb41dc28e269dc20ab9219 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:38 +0800 -Subject: [PATCH 6/8] wifi: rtw88: Stop high queue during scan - -When traversing channel list, TX in high queue should be disabled -along with beacon function, so packets won't be sent to incorrect -channels. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/main.c | 7 +++++-- - drivers/net/wireless/realtek/rtw88/reg.h | 1 + - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -2403,10 +2403,13 @@ void rtw_core_enable_beacon(struct rtw_d - if (!rtwdev->ap_active) - return; - -- if (enable) -+ if (enable) { - rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -- else -+ rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); -+ } else { - rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); -+ rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); -+ } - } - - MODULE_AUTHOR("Realtek Corporation"); ---- a/drivers/net/wireless/realtek/rtw88/reg.h -+++ b/drivers/net/wireless/realtek/rtw88/reg.h -@@ -378,6 +378,7 @@ - #define BIT_SIFS_BK_EN BIT(12) - #define REG_TXPAUSE 0x0522 - #define BIT_AC_QUEUE GENMASK(7, 0) -+#define BIT_HIGH_QUEUE BIT(5) - #define REG_RD_CTRL 0x0524 - #define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) - #define BIT_DIS_TXOP_CFE BIT(10) diff --git a/package/kernel/mac80211/patches/rtl/064-wifi-rtw88-refine-register-based-H2C-command.patch b/package/kernel/mac80211/patches/rtl/064-wifi-rtw88-refine-register-based-H2C-command.patch deleted file mode 100644 index 29564e357..000000000 --- a/package/kernel/mac80211/patches/rtl/064-wifi-rtw88-refine-register-based-H2C-command.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 455afa45edb3f1dbc1371201c5ee486bb9a8cd1a Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:39 +0800 -Subject: [PATCH 7/8] wifi: rtw88: refine register based H2C command - -Since register based H2C commands don't need endian conversion. -Introduce a new API that don't do conversion and send it directly. -New caller are expected to encode with cpu order and gradually -replace the old ones. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 51 +++++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw88/fw.h | 5 +++ - 2 files changed, 56 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -308,6 +308,57 @@ void rtw_fw_c2h_cmd_isr(struct rtw_dev * - } - EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr); - -+static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, -+ struct rtw_h2c_register *h2c) -+{ -+ u32 box_reg, box_ex_reg; -+ u8 box_state, box; -+ int ret; -+ -+ rtw_dbg(rtwdev, RTW_DBG_FW, "send H2C content %08x %08x\n", h2c->w0, -+ h2c->w1); -+ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ box = rtwdev->h2c.last_box_num; -+ switch (box) { -+ case 0: -+ box_reg = REG_HMEBOX0; -+ box_ex_reg = REG_HMEBOX0_EX; -+ break; -+ case 1: -+ box_reg = REG_HMEBOX1; -+ box_ex_reg = REG_HMEBOX1_EX; -+ break; -+ case 2: -+ box_reg = REG_HMEBOX2; -+ box_ex_reg = REG_HMEBOX2_EX; -+ break; -+ case 3: -+ box_reg = REG_HMEBOX3; -+ box_ex_reg = REG_HMEBOX3_EX; -+ break; -+ default: -+ WARN(1, "invalid h2c mail box number\n"); -+ return; -+ } -+ -+ ret = read_poll_timeout_atomic(rtw_read8, box_state, -+ !((box_state >> box) & 0x1), 100, 3000, -+ false, rtwdev, REG_HMETFR); -+ -+ if (ret) { -+ rtw_err(rtwdev, "failed to send h2c command\n"); -+ return; -+ } -+ -+ rtw_write32(rtwdev, box_ex_reg, h2c->w1); -+ rtw_write32(rtwdev, box_reg, h2c->w0); -+ -+ if (++rtwdev->h2c.last_box_num >= 4) -+ rtwdev->h2c.last_box_num = 0; -+} -+ - static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, - u8 *h2c) - { ---- a/drivers/net/wireless/realtek/rtw88/fw.h -+++ b/drivers/net/wireless/realtek/rtw88/fw.h -@@ -81,6 +81,11 @@ struct rtw_c2h_adaptivity { - u8 option; - } __packed; - -+struct rtw_h2c_register { -+ u32 w0; -+ u32 w1; -+} __packed; -+ - struct rtw_h2c_cmd { - __le32 msg; - __le32 msg_ext; diff --git a/package/kernel/mac80211/patches/rtl/065-wifi-rtw88-fix-not-entering-PS-mode-after-AP-stops.patch b/package/kernel/mac80211/patches/rtl/065-wifi-rtw88-fix-not-entering-PS-mode-after-AP-stops.patch deleted file mode 100644 index 0508a19c4..000000000 --- a/package/kernel/mac80211/patches/rtl/065-wifi-rtw88-fix-not-entering-PS-mode-after-AP-stops.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 28c11c29494f1b34e39641eead9c60a8bd26170d Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 16 Jun 2023 20:55:40 +0800 -Subject: [PATCH 8/8] wifi: rtw88: fix not entering PS mode after AP stops - -Without this patch, firmware only track beacons for port 0 and since -we will always start AP on port 0, this results in misbehavior of -power saving mode on other ports after AP stops. - -The "default port" H2C command is used to notify which port should -firmware track. Update the correct settings to firmware so power -saving mode can work properly. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616125540.36877-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw88/fw.c | 17 +++++++++++++++++ - drivers/net/wireless/realtek/rtw88/fw.h | 8 ++++++++ - drivers/net/wireless/realtek/rtw88/mac80211.c | 1 + - drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++++ - drivers/net/wireless/realtek/rtw88/main.h | 1 + - 5 files changed, 35 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw88/fw.c -+++ b/drivers/net/wireless/realtek/rtw88/fw.c -@@ -519,6 +519,23 @@ void rtw_fw_query_bt_info(struct rtw_dev - rtw_fw_send_h2c_command(rtwdev, h2c_pkt); - } - -+void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) -+{ -+ struct rtw_h2c_register h2c = {}; -+ -+ if (rtwvif->net_type != RTW_NET_MGD_LINKED) -+ return; -+ -+ /* Leave LPS before default port H2C so FW timer is correct */ -+ rtw_leave_lps(rtwdev); -+ -+ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) | -+ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) | -+ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID); -+ -+ rtw_fw_send_h2c_command_register(rtwdev, &h2c); -+} -+ - void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw) - { - u8 h2c_pkt[H2C_PKT_SIZE] = {0}; ---- a/drivers/net/wireless/realtek/rtw88/fw.h -+++ b/drivers/net/wireless/realtek/rtw88/fw.h -@@ -86,6 +86,12 @@ struct rtw_h2c_register { - u32 w1; - } __packed; - -+#define RTW_H2C_W0_CMDID GENMASK(7, 0) -+ -+/* H2C_CMD_DEFAULT_PORT command */ -+#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8) -+#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16) -+ - struct rtw_h2c_cmd { - __le32 msg; - __le32 msg_ext; -@@ -535,6 +541,7 @@ static inline void rtw_h2c_pkt_set_heade - #define H2C_CMD_MEDIA_STATUS_RPT 0x01 - #define H2C_CMD_SET_PWR_MODE 0x20 - #define H2C_CMD_LPS_PG_INFO 0x2b -+#define H2C_CMD_DEFAULT_PORT 0x2c - #define H2C_CMD_RA_INFO 0x40 - #define H2C_CMD_RSSI_MONITOR 0x42 - #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 -@@ -806,6 +813,7 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rt - void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); - void rtw_fw_send_general_info(struct rtw_dev *rtwdev); - void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); -+void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); - - void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); - void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start); ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -382,6 +382,7 @@ static void rtw_ops_bss_info_changed(str - - rtw_fw_download_rsvd_page(rtwdev); - rtw_send_rsvd_page_h2c(rtwdev); -+ rtw_fw_default_port(rtwdev, rtwvif); - rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); - if (rtw_bf_support) - rtw_bf_assoc(rtwdev, vif, conf); ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -334,12 +334,15 @@ int rtw_sta_add(struct rtw_dev *rtwdev, - struct ieee80211_vif *vif) - { - struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; -+ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; - int i; - - si->mac_id = rtw_acquire_macid(rtwdev); - if (si->mac_id >= RTW_MAX_MAC_ID_NUM) - return -ENOSPC; - -+ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) -+ rtwvif->mac_id = si->mac_id; - si->rtwdev = rtwdev; - si->sta = sta; - si->vif = vif; -@@ -2340,6 +2343,9 @@ static void rtw_port_switch_iter(void *d - rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n", - rtwvif_ap->port, rtwvif_target->port); - -+ /* Leave LPS so the value swapped are not in PS mode */ -+ rtw_leave_lps(rtwdev); -+ - reg1 = &rtwvif_ap->conf->net_type; - reg2 = &rtwvif_target->conf->net_type; - rtw_swap_reg_mask(rtwdev, reg1, reg2); -@@ -2358,6 +2364,8 @@ static void rtw_port_switch_iter(void *d - - swap(rtwvif_target->port, rtwvif_ap->port); - swap(rtwvif_target->conf, rtwvif_ap->conf); -+ -+ rtw_fw_default_port(rtwdev, rtwvif_target); - } - - void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) ---- a/drivers/net/wireless/realtek/rtw88/main.h -+++ b/drivers/net/wireless/realtek/rtw88/main.h -@@ -803,6 +803,7 @@ struct rtw_bf_info { - struct rtw_vif { - enum rtw_net_type net_type; - u16 aid; -+ u8 mac_id; /* for STA mode only */ - u8 mac_addr[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u8 port; diff --git a/package/kernel/mac80211/patches/rtl/200-add-rtw89.patch b/package/kernel/mac80211/patches/rtl/200-add-rtw89.patch deleted file mode 100644 index 8770318c4..000000000 --- a/package/kernel/mac80211/patches/rtl/200-add-rtw89.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/defconfigs/wifi -+++ b/defconfigs/wifi -@@ -128,6 +128,9 @@ CPTCFG_RTW88_8822BU=m - CPTCFG_RTW88_8822CE=m - CPTCFG_RTW88_8822CU=m - CPTCFG_RTW88=m -+CPTCFG_RTW89_8852AE=m -+CPTCFG_RTW89_8852CE=m -+CPTCFG_RTW89=m - CPTCFG_SSB=m - CPTCFG_SSB_PCMCIAHOST=y - CPTCFG_SSB_SDIOHOST=y diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch deleted file mode 100644 index 3075b5ac5..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch +++ /dev/null @@ -1,13309 +0,0 @@ -From c8b5fc2e1d2f6a11fe2ba82da8b0c39bb379b529 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:28 +0800 -Subject: [PATCH 001/149] wifi: rtw89: 8852b: add BB and RF tables (1 of 2) - -These tables contain BB and RF parameters that driver will load them into -registers. It also contains TX power according to country, band, rate and -so on. Increasing thermal can cause TX power degraded, so power tracking -tables are defined to compensate TX power. - -Internal version of these tables: - - HALRF_029_00_014 (R32) - - HALBB_027_046_05 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-2-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8852b_table.c | 13249 ++++++++++++++++ - .../wireless/realtek/rtw89/rtw8852b_table.h | 30 + - 2 files changed, 13279 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -@@ -0,0 +1,13249 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2019-2020 Realtek Corporation -+ */ -+ -+#include "phy.h" -+#include "reg.h" -+#include "rtw8852b_table.h" -+ -+static const struct rtw89_reg2_def rtw89_8852b_phy_bb_regs[] = { -+ {0x704, 0x601E0100}, -+ {0x4000, 0x00000000}, -+ {0x4004, 0xCA014000}, -+ {0x4008, 0xC751D4F0}, -+ {0x400C, 0x44511475}, -+ {0x4010, 0x00000000}, -+ {0x4014, 0x00000000}, -+ {0x4018, 0x4F4C084B}, -+ {0x401C, 0x084A4E52}, -+ {0x4020, 0x4D504E4B}, -+ {0x4024, 0x4F4C0849}, -+ {0x4028, 0x08484C50}, -+ {0x402C, 0x4C50504C}, -+ {0x4030, 0x5454084A}, -+ {0x4034, 0x084B5654}, -+ {0x4038, 0x6A6C605A}, -+ {0x403C, 0x4C4C084C}, -+ {0x4040, 0x084B4E4D}, -+ {0x4044, 0x4E4C4B4B}, -+ {0x4048, 0x4B4B084A}, -+ {0x404C, 0x084A4E4C}, -+ {0x4050, 0x514F4C4A}, -+ {0x4054, 0x524E084A}, -+ {0x4058, 0x084A5154}, -+ {0x405C, 0x53555554}, -+ {0x4060, 0x45450845}, -+ {0x4064, 0x08454144}, -+ {0x4068, 0x40434445}, -+ {0x406C, 0x44450845}, -+ {0x4070, 0x08444043}, -+ {0x4074, 0x42434444}, -+ {0x4078, 0x46450844}, -+ {0x407C, 0x08444843}, -+ {0x4080, 0x4B4E4A47}, -+ {0x4084, 0x4F4C084B}, -+ {0x4088, 0x084A4E52}, -+ {0x408C, 0x4D504E4B}, -+ {0x4090, 0x4F4C0849}, -+ {0x4094, 0x08484C50}, -+ {0x4098, 0x4C50504C}, -+ {0x409C, 0x5454084A}, -+ {0x40A0, 0x084B5654}, -+ {0x40A4, 0x6A6C605A}, -+ {0x40A8, 0x4C4C084C}, -+ {0x40AC, 0x084B4E4D}, -+ {0x40B0, 0x4E4C4B4B}, -+ {0x40B4, 0x4B4B084A}, -+ {0x40B8, 0x084A4E4C}, -+ {0x40BC, 0x514F4C4A}, -+ {0x40C0, 0x524E084A}, -+ {0x40C4, 0x084A5154}, -+ {0x40C8, 0x53555554}, -+ {0x40CC, 0x45450845}, -+ {0x40D0, 0x08454144}, -+ {0x40D4, 0x40434445}, -+ {0x40D8, 0x44450845}, -+ {0x40DC, 0x08444043}, -+ {0x40E0, 0x42434444}, -+ {0x40E4, 0x46450844}, -+ {0x40E8, 0x08444843}, -+ {0x40EC, 0x4B4E4A47}, -+ {0x40F0, 0x00000000}, -+ {0x40F4, 0x00000006}, -+ {0x40F8, 0x00000000}, -+ {0x40FC, 0x8C30C30C}, -+ {0x4100, 0x4C30C30C}, -+ {0x4104, 0x0C30C30C}, -+ {0x4108, 0x0C30C30C}, -+ {0x410C, 0x0C30C30C}, -+ {0x4110, 0x0C30C30C}, -+ {0x4114, 0x28A28A28}, -+ {0x4118, 0x28A28A28}, -+ {0x411C, 0x28A28A28}, -+ {0x4120, 0x28A28A28}, -+ {0x4124, 0x28A28A28}, -+ {0x4128, 0x28A28A28}, -+ {0x412C, 0x06666666}, -+ {0x4130, 0x33333333}, -+ {0x4134, 0x33333333}, -+ {0x4138, 0x33333333}, -+ {0x413C, 0x00000031}, -+ {0x4140, 0x5100600A}, -+ {0x4144, 0x18363113}, -+ {0x4148, 0x1D976DDC}, -+ {0x414C, 0x1C072DD7}, -+ {0x4150, 0x1127CDF4}, -+ {0x4154, 0x1E37BDF1}, -+ {0x4158, 0x1FB7F1D6}, -+ {0x415C, 0x1EA7DDF9}, -+ {0x4160, 0x1FE445DD}, -+ {0x4164, 0x1F97F1FE}, -+ {0x4168, 0x1FF781ED}, -+ {0x416C, 0x1FA7F5FE}, -+ {0x4170, 0x1E07B913}, -+ {0x4174, 0x1FD7FDFF}, -+ {0x4178, 0x1E17B9FA}, -+ {0x417C, 0x19A66914}, -+ {0x4180, 0x10F65598}, -+ {0x4184, 0x14A5A111}, -+ {0x4188, 0x1D3765DB}, -+ {0x418C, 0x17C685CA}, -+ {0x4190, 0x1107C5F3}, -+ {0x4194, 0x1B5785EB}, -+ {0x4198, 0x1F97ED8F}, -+ {0x419C, 0x1BC7A5F3}, -+ {0x41A0, 0x1FE43595}, -+ {0x41A4, 0x1EB7D9FC}, -+ {0x41A8, 0x1FE65DBE}, -+ {0x41AC, 0x1EC7D9FC}, -+ {0x41B0, 0x1976FCFF}, -+ {0x41B4, 0x1F77F5FF}, -+ {0x41B8, 0x1976FDEC}, -+ {0x41BC, 0x198664EF}, -+ {0x41C0, 0x11062D93}, -+ {0x41C4, 0x10C4E910}, -+ {0x41C8, 0x1CA759DB}, -+ {0x41CC, 0x1335A9B5}, -+ {0x41D0, 0x1097B9F3}, -+ {0x41D4, 0x17B72DE1}, -+ {0x41D8, 0x1F67ED42}, -+ {0x41DC, 0x18074DE9}, -+ {0x41E0, 0x1FD40547}, -+ {0x41E4, 0x1D57ADF9}, -+ {0x41E8, 0x1FE52182}, -+ {0x41EC, 0x1D67B1F9}, -+ {0x41F0, 0x14860CE1}, -+ {0x41F4, 0x1EC7E9FE}, -+ {0x41F8, 0x14860DD6}, -+ {0x41FC, 0x195664C7}, -+ {0x4200, 0x0005E58A}, -+ {0x4204, 0x00000000}, -+ {0x4208, 0x00000000}, -+ {0x420C, 0x7A000000}, -+ {0x4210, 0x0F9F3D7A}, -+ {0x4214, 0x0040817C}, -+ {0x4218, 0x00E10204}, -+ {0x421C, 0x227D94CD}, -+ {0x4220, 0x08028A28}, -+ {0x4224, 0x00000210}, -+ {0x4228, 0x04688000}, -+ {0x4A48, 0x00000002}, -+ {0x422C, 0x0060B002}, -+ {0x4230, 0x9A8249A8}, -+ {0x4234, 0x26A1469E}, -+ {0x4238, 0x2099A824}, -+ {0x423C, 0x2359461C}, -+ {0x4240, 0x1631A675}, -+ {0x4244, 0x2C6B1D63}, -+ {0x4248, 0x0000000E}, -+ {0x424C, 0x00000001}, -+ {0x4250, 0x00000001}, -+ {0x4254, 0x00000000}, -+ {0x4258, 0x00000000}, -+ {0x425C, 0x00000000}, -+ {0x4260, 0x0020000C}, -+ {0x4264, 0x00000000}, -+ {0x4268, 0x00000000}, -+ {0x426C, 0x0418317C}, -+ {0x4270, 0x2B33135C}, -+ {0x4274, 0x00000002}, -+ {0x4278, 0x00000000}, -+ {0x427C, 0x00000000}, -+ {0x4280, 0x00000000}, -+ {0x4284, 0x00000000}, -+ {0x4288, 0x00000000}, -+ {0x428C, 0x00000000}, -+ {0x4290, 0x00000000}, -+ {0x4294, 0x00000000}, -+ {0x4298, 0x00000000}, -+ {0x429C, 0x84026000}, -+ {0x42A0, 0x0051AC20}, -+ {0x4A24, 0x0010C040}, -+ {0x42A4, 0x02024008}, -+ {0x42A8, 0x00000000}, -+ {0x42AC, 0x00000000}, -+ {0x42B0, 0x22CE803C}, -+ {0x42B4, 0x32000000}, -+ {0x42B8, 0x996FD67D}, -+ {0x42BC, 0xBD67D67D}, -+ {0x42C0, 0x7D67D65B}, -+ {0x42C4, 0x28029F59}, -+ {0x42C8, 0x00280280}, -+ {0x42CC, 0x00000000}, -+ {0x42D0, 0x00000000}, -+ {0x42D4, 0x00000003}, -+ {0x42D8, 0x00000001}, -+ {0x42DC, 0x61861800}, -+ {0x42E0, 0x830C30C3}, -+ {0x42E4, 0xC30C30C3}, -+ {0x42E8, 0x830C30C3}, -+ {0x42EC, 0x451450C3}, -+ {0x42F0, 0x05145145}, -+ {0x42F4, 0x05145145}, -+ {0x42F8, 0x05145145}, -+ {0x42FC, 0x0F0C3145}, -+ {0x4300, 0x030C30CF}, -+ {0x4304, 0x030C30C3}, -+ {0x4308, 0x030CF3C3}, -+ {0x430C, 0x030C30C3}, -+ {0x4310, 0x0F3CF3C3}, -+ {0x4314, 0x0F3CF3CF}, -+ {0x4318, 0x0F3CF3CF}, -+ {0x431C, 0x0F3CF3CF}, -+ {0x4320, 0x0F3CF3CF}, -+ {0x4324, 0x030C10C3}, -+ {0x4328, 0x051430C3}, -+ {0x432C, 0x051490CB}, -+ {0x4330, 0x030CD151}, -+ {0x4334, 0x050C50C7}, -+ {0x4338, 0x051492CB}, -+ {0x433C, 0x05145145}, -+ {0x4340, 0x05145145}, -+ {0x4344, 0x05145145}, -+ {0x4348, 0x05145145}, -+ {0x434C, 0x090CD3CF}, -+ {0x4350, 0x071491C5}, -+ {0x4354, 0x073CF143}, -+ {0x4358, 0x071431C3}, -+ {0x435C, 0x0F3CF1C5}, -+ {0x4360, 0x0F3CF3CF}, -+ {0x4364, 0x0F3CF3CF}, -+ {0x4368, 0x0F3CF3CF}, -+ {0x436C, 0x0F3CF3CF}, -+ {0x4370, 0x090C91CF}, -+ {0x4374, 0x11243143}, -+ {0x4378, 0x9777A777}, -+ {0x437C, 0xBB7BAC95}, -+ {0x4380, 0xB667B889}, -+ {0x4384, 0x7B9B8899}, -+ {0x4388, 0x7A5567C8}, -+ {0x438C, 0x2278CCCC}, -+ {0x4390, 0x7C222222}, -+ {0x4394, 0x0000069B}, -+ {0x4398, 0x001CCCCC}, -+ {0x4AAC, 0xCCCCC88C}, -+ {0x4AB0, 0x0000AACC}, -+ {0x439C, 0x00000000}, -+ {0x43A0, 0x00000008}, -+ {0x43A4, 0x00000000}, -+ {0x43A8, 0x00000000}, -+ {0x43AC, 0x00000000}, -+ {0x43B0, 0x10000000}, -+ {0x43B4, 0x00401001}, -+ {0x43B8, 0x00061003}, -+ {0x43BC, 0x000024D8}, -+ {0x43C0, 0x00000000}, -+ {0x43C4, 0x10000020}, -+ {0x43C8, 0x20000200}, -+ {0x43CC, 0x00000000}, -+ {0x43D0, 0x04000000}, -+ {0x43D4, 0x44000100}, -+ {0x43D8, 0x60804060}, -+ {0x43DC, 0x44204210}, -+ {0x43E0, 0x82108082}, -+ {0x43E4, 0x82108402}, -+ {0x43E8, 0xC8082108}, -+ {0x43EC, 0xC8202084}, -+ {0x43F0, 0x44208208}, -+ {0x43F4, 0x84108204}, -+ {0x43F8, 0xD0108104}, -+ {0x43FC, 0xF8210108}, -+ {0x4400, 0x6431E930}, -+ {0x4404, 0x02309468}, -+ {0x4408, 0x10C61C22}, -+ {0x440C, 0x02109469}, -+ {0x4410, 0x10C61C22}, -+ {0x4414, 0x00041049}, -+ {0x4A4C, 0x00060581}, -+ {0x4418, 0x00000000}, -+ {0x441C, 0x00000000}, -+ {0x4420, 0x6C000000}, -+ {0x4424, 0xB0200020}, -+ {0x4428, 0x00001FF0}, -+ {0x442C, 0x00000000}, -+ {0x4430, 0x00000000}, -+ {0x4434, 0x00000000}, -+ {0x4438, 0x00000000}, -+ {0x443C, 0x190642D0}, -+ {0x4440, 0xA80668A0}, -+ {0x4444, 0x60900820}, -+ {0x4448, 0x9F28518C}, -+ {0x444C, 0x32488A62}, -+ {0x4450, 0x9C6E36DC}, -+ {0x4454, 0x0000F52B}, -+ {0x4458, 0x00000000}, -+ {0x445C, 0x4801442E}, -+ {0x4460, 0x0051A0B8}, -+ {0x4464, 0x00000000}, -+ {0x4468, 0x00000000}, -+ {0x446C, 0x00000000}, -+ {0x4470, 0x00000000}, -+ {0x4474, 0x00000000}, -+ {0x4478, 0x00000000}, -+ {0x447C, 0x00000000}, -+ {0x4480, 0x2A0A6040}, -+ {0x4484, 0x0A0A6829}, -+ {0x4488, 0x00000004}, -+ {0x448C, 0x00000000}, -+ {0x4490, 0x80000000}, -+ {0x4494, 0x10000000}, -+ {0x4498, 0xE0000000}, -+ {0x4AB4, 0x00000000}, -+ {0x449C, 0x0000001E}, -+ {0x44A0, 0x02B2C3A6}, -+ {0x44A4, 0x00000400}, -+ {0x44A8, 0x00000001}, -+ {0x44AC, 0x000190C0}, -+ {0x44B0, 0x00000000}, -+ {0x44B4, 0x00000000}, -+ {0x44B8, 0x00000000}, -+ {0x44BC, 0x00000000}, -+ {0x44C0, 0x00000000}, -+ {0x44C4, 0x00000000}, -+ {0x44C8, 0x00000000}, -+ {0x44CC, 0x00000000}, -+ {0x44D0, 0x00000000}, -+ {0x44D4, 0x00000000}, -+ {0x44D8, 0x00000000}, -+ {0x44DC, 0x00000000}, -+ {0x44E0, 0x00000000}, -+ {0x44E4, 0x00000000}, -+ {0x44E8, 0x00000000}, -+ {0x44EC, 0x00000000}, -+ {0x44F0, 0x00000000}, -+ {0x44F4, 0x00000000}, -+ {0x44F8, 0x00000000}, -+ {0x44FC, 0x00000000}, -+ {0x4500, 0x00000000}, -+ {0x4504, 0x00000000}, -+ {0x4508, 0x00000000}, -+ {0x450C, 0x00000000}, -+ {0x4510, 0x00000000}, -+ {0x4514, 0x00000000}, -+ {0x4518, 0x00000000}, -+ {0x451C, 0x00000000}, -+ {0x4520, 0x00000000}, -+ {0x4524, 0x00000000}, -+ {0x4528, 0x00000000}, -+ {0x452C, 0x00000000}, -+ {0x4530, 0x4E830171}, -+ {0x4534, 0x00000870}, -+ {0x4538, 0x000000FF}, -+ {0x453C, 0x00000000}, -+ {0x4540, 0x00000000}, -+ {0x4544, 0x00000000}, -+ {0x4548, 0x00000000}, -+ {0x454C, 0x00000000}, -+ {0x4550, 0x00000000}, -+ {0x4554, 0x00000000}, -+ {0x4558, 0x00000000}, -+ {0x455C, 0x00000000}, -+ {0x4560, 0x40000000}, -+ {0x4564, 0x40000000}, -+ {0x4568, 0x00000000}, -+ {0x456C, 0x20000000}, -+ {0x4570, 0x04F040BB}, -+ {0x4574, 0x000E53FF}, -+ {0x4578, 0x000205CB}, -+ {0x457C, 0x00200000}, -+ {0x4580, 0x00000040}, -+ {0x4584, 0x00000000}, -+ {0x4588, 0x00000017}, -+ {0x458C, 0x30000000}, -+ {0x4590, 0x00000000}, -+ {0x4594, 0x00000000}, -+ {0x4598, 0x00000001}, -+ {0x459C, 0x0003FE00}, -+ {0x45A0, 0x00000086}, -+ {0x45A4, 0x00000000}, -+ {0x45A8, 0xC00001C0}, -+ {0x45AC, 0x78038000}, -+ {0x45B0, 0x8000004A}, -+ {0x45B4, 0x04094800}, -+ {0x45B8, 0x00280002}, -+ {0x45BC, 0x06748790}, -+ {0x45C0, 0x80000000}, -+ {0x45C4, 0x00000000}, -+ {0x45C8, 0x00000000}, -+ {0x45CC, 0x00558670}, -+ {0x45D0, 0x002883F0}, -+ {0x45D4, 0x00090120}, -+ {0x45D8, 0x00000000}, -+ {0x45E0, 0xA3A6D3C4}, -+ {0x45E4, 0xAB27B126}, -+ {0x45E8, 0x00006778}, -+ {0x45F4, 0x000001B5}, -+ {0x45EC, 0x11110F0A}, -+ {0x45F0, 0x00000003}, -+ {0x4A0C, 0x0000000A}, -+ {0x45F8, 0x0058BC3F}, -+ {0x45FC, 0x00000003}, -+ {0x462C, 0x00000020}, -+ {0x4600, 0x000003D9}, -+ {0x45F0, 0x00000004}, -+ {0x4604, 0x002B1CB0}, -+ {0x4A50, 0xC0000000}, -+ {0x4A54, 0x00001000}, -+ {0x4A58, 0x00000000}, -+ {0x4A18, 0x00000024}, -+ {0x4608, 0x00000001}, -+ {0x460C, 0x00000000}, -+ {0x4A10, 0x00000001}, -+ {0x4610, 0x00000001}, -+ {0x4614, 0x16E5298F}, -+ {0x4618, 0x18C6294A}, -+ {0x461C, 0x0E06318A}, -+ {0x4620, 0x0E539CE5}, -+ {0x4624, 0x00019287}, -+ {0x4A14, 0x000000BF}, -+ {0x4628, 0x00000001}, -+ {0x4630, 0x000001AA}, -+ {0x4A18, 0x00001900}, -+ {0x4A1C, 0x000002A6}, -+ {0x4634, 0x000000A3}, -+ {0x4A20, 0x00000086}, -+ {0x4638, 0x01986456}, -+ {0x49F8, 0x00000000}, -+ {0x463C, 0x00000000}, -+ {0x4640, 0x00000000}, -+ {0x4644, 0x00C8CC00}, -+ {0x4648, 0xC400B6B6}, -+ {0x464C, 0xDC400FC0}, -+ {0x4A8C, 0x00000110}, -+ {0x4650, 0x08882550}, -+ {0x4654, 0x08CC2660}, -+ {0x4658, 0x09102660}, -+ {0x465C, 0x00000154}, -+ {0x45DC, 0xC39E38E8}, -+ {0x4660, 0x452607E6}, -+ {0x4664, 0x6750DC65}, -+ {0x4668, 0xF3F0F1ED}, -+ {0x466C, 0x30141506}, -+ {0x4670, 0x2C2B2B2B}, -+ {0x4674, 0x2C2C2C2C}, -+ {0x4678, 0xDDB738E8}, -+ {0x467C, 0x543618FB}, -+ {0x4680, 0x4F31DC6F}, -+ {0x4684, 0xFBEBDA00}, -+ {0x4688, 0x1A10FF04}, -+ {0x468C, 0x282A3000}, -+ {0x4690, 0x2A29292A}, -+ {0x4694, 0x04FA2A2A}, -+ {0x4698, 0xEE0F04D1}, -+ {0x469C, 0x99E91436}, -+ {0x46A0, 0x0701E79E}, -+ {0x46A4, 0x08D77CFF}, -+ {0x46A8, 0x2212FF14}, -+ {0x46AC, 0x60322437}, -+ {0x46B0, 0x63666666}, -+ {0x46B4, 0x35374425}, -+ {0x46B8, 0x35883042}, -+ {0x46BC, 0x5177C252}, -+ {0x4720, 0x7FFFFD63}, -+ {0x4724, 0xB58D11FF}, -+ {0x4728, 0x07FFFFFF}, -+ {0x472C, 0x0E7893B6}, -+ {0x4730, 0xE0391201}, -+ {0x4734, 0x00000020}, -+ {0x4738, 0x8325C500}, -+ {0x473C, 0x00000B7F}, -+ {0x46C0, 0x00000000}, -+ {0x46C4, 0x00000000}, -+ {0x46C8, 0x00000219}, -+ {0x46CC, 0x00000000}, -+ {0x46D0, 0x00000000}, -+ {0x46D4, 0x00000001}, -+ {0x46D8, 0x00000001}, -+ {0x46DC, 0x00000000}, -+ {0x46E0, 0x00000000}, -+ {0x46E4, 0x00000151}, -+ {0x46E8, 0x00000498}, -+ {0x46EC, 0x00000498}, -+ {0x46F0, 0x00000000}, -+ {0x46F4, 0x00000000}, -+ {0x46F8, 0x00001146}, -+ {0x46FC, 0x00000000}, -+ {0x4700, 0x00000000}, -+ {0x4704, 0x00C8CC00}, -+ {0x4708, 0xC400B6B6}, -+ {0x470C, 0xDC400FC0}, -+ {0x4A90, 0x00000110}, -+ {0x4710, 0x08882550}, -+ {0x4714, 0x08CC2660}, -+ {0x4718, 0x09102660}, -+ {0x471C, 0x00000154}, -+ {0x4740, 0xC69F38E8}, -+ {0x4744, 0x462709E9}, -+ {0x4748, 0x6750DC67}, -+ {0x474C, 0xF3F0F1ED}, -+ {0x4750, 0x30141506}, -+ {0x4754, 0x2C2B2B2B}, -+ {0x4758, 0x2C2C2C2C}, -+ {0x475C, 0xE0B738E8}, -+ {0x4760, 0x52381BFE}, -+ {0x4764, 0x5031DC6C}, -+ {0x4768, 0xFBEBDA00}, -+ {0x476C, 0x1A10FF04}, -+ {0x4770, 0x282A3000}, -+ {0x4774, 0x2A29292A}, -+ {0x4778, 0x04FA2A2A}, -+ {0x477C, 0xEE0F04D1}, -+ {0x49F0, 0x99E91436}, -+ {0x49F4, 0x0701E79E}, -+ {0x49FC, 0x08D77CFF}, -+ {0x4A5C, 0x2212FF14}, -+ {0x4A60, 0x60322437}, -+ {0x4A64, 0x63666666}, -+ {0x4A68, 0x35374425}, -+ {0x4A6C, 0x35883042}, -+ {0x4A70, 0x5177C252}, -+ {0x4A74, 0x7FFFFD63}, -+ {0x4A78, 0xB58D11FF}, -+ {0x4A7C, 0x07FFFFFF}, -+ {0x4A80, 0x0E7893B6}, -+ {0x4A9C, 0xE0391201}, -+ {0x4AA0, 0x00000020}, -+ {0x4AA4, 0x8325C500}, -+ {0x4AA8, 0x00000B7F}, -+ {0x4780, 0x00000000}, -+ {0x4784, 0x00000000}, -+ {0x4788, 0x00000219}, -+ {0x478C, 0x00000000}, -+ {0x4790, 0x00000000}, -+ {0x4794, 0x00000001}, -+ {0x4798, 0x00000001}, -+ {0x479C, 0x00000000}, -+ {0x47A0, 0x00000000}, -+ {0x47A4, 0x00000151}, -+ {0x47A8, 0x00000498}, -+ {0x47AC, 0x00000498}, -+ {0x47B0, 0x00000000}, -+ {0x47B4, 0x00000000}, -+ {0x47B8, 0x00001146}, -+ {0x47BC, 0x00000002}, -+ {0x47C0, 0x00000002}, -+ {0x47C4, 0x00000000}, -+ {0x47C8, 0xA32103FE}, -+ {0x47CC, 0xB20A5328}, -+ {0x47D0, 0xC686314F}, -+ {0x47D4, 0x000005D7}, -+ {0x47D8, 0x009B902A}, -+ {0x47DC, 0x009B902A}, -+ {0x47E0, 0x98682C18}, -+ {0x47E4, 0x6308C4C1}, -+ {0x47E8, 0x6248C631}, -+ {0x47EC, 0x922A8253}, -+ {0x47F0, 0x00000005}, -+ {0x47F4, 0x00001759}, -+ {0x47F8, 0x4BB02000}, -+ {0x47FC, 0x831408BE}, -+ {0x4A84, 0x000000E9}, -+ {0x4800, 0x9ABBCACB}, -+ {0x4804, 0x56767578}, -+ {0x4808, 0xBCCBBB13}, -+ {0x480C, 0x7889989B}, -+ {0x4810, 0xBBB0F455}, -+ {0x4814, 0x777BBBBB}, -+ {0x4818, 0x15277777}, -+ {0x481C, 0x27039CE9}, -+ {0x4820, 0x42424432}, -+ {0x4824, 0x36058342}, -+ {0x4828, 0x00000006}, -+ {0x482C, 0x00000005}, -+ {0x4830, 0x00000005}, -+ {0x4834, 0xC7013016}, -+ {0x4838, 0x84413016}, -+ {0x483C, 0x84413016}, -+ {0x4840, 0x8C413016}, -+ {0x4844, 0x8C40B028}, -+ {0x4848, 0x3140B028}, -+ {0x484C, 0x2940B028}, -+ {0x4850, 0x8440B028}, -+ {0x4854, 0x2318C610}, -+ {0x4858, 0x45344753}, -+ {0x485C, 0x236A6A88}, -+ {0x4860, 0xAC8DF814}, -+ {0x4864, 0x08877ACB}, -+ {0x4868, 0x000107AA}, -+ {0x4A94, 0x00000000}, -+ {0x486C, 0xBCEB4A14}, -+ {0x4870, 0x000A3A4A}, -+ {0x4874, 0xBCEB4A14}, -+ {0x4878, 0x000A3A4A}, -+ {0x487C, 0xBCBDBD85}, -+ {0x4880, 0x0CABB99A}, -+ {0x4884, 0x38384242}, -+ {0x4888, 0x0086102E}, -+ {0x488C, 0xCA24C82A}, -+ {0x4890, 0x00008A62}, -+ {0x4894, 0x00000008}, -+ {0x4898, 0x009B902A}, -+ {0x489C, 0x009B902A}, -+ {0x48A0, 0x98682C18}, -+ {0x48A4, 0x6308C4C1}, -+ {0x48A8, 0x6248C631}, -+ {0x48AC, 0x922A8253}, -+ {0x48B0, 0x00000005}, -+ {0x48B4, 0x00001759}, -+ {0x48B8, 0x4BA02000}, -+ {0x48BC, 0x831408BE}, -+ {0x4A88, 0x000000E9}, -+ {0x48C0, 0x9898A8BB}, -+ {0x48C4, 0x54535368}, -+ {0x48C8, 0x99999B13}, -+ {0x48CC, 0x55555899}, -+ {0x48D0, 0xBBB07453}, -+ {0x48D4, 0x777BBBBB}, -+ {0x48D8, 0x15277777}, -+ {0x48DC, 0x27039CE9}, -+ {0x48E0, 0x31413432}, -+ {0x48E4, 0x36058342}, -+ {0x48E8, 0x00000006}, -+ {0x48EC, 0x00000005}, -+ {0x48F0, 0x00000005}, -+ {0x48F4, 0xC7013016}, -+ {0x48F8, 0x84413016}, -+ {0x48FC, 0x84413016}, -+ {0x4900, 0x8C413016}, -+ {0x4904, 0x8C40B028}, -+ {0x4908, 0x3140B028}, -+ {0x490C, 0x2940B028}, -+ {0x4910, 0x8440B028}, -+ {0x4914, 0x2318C610}, -+ {0x4918, 0x45334753}, -+ {0x491C, 0x236A6A88}, -+ {0x4920, 0xAC8DF814}, -+ {0x4924, 0x08877ACB}, -+ {0x4928, 0x000007AA}, -+ {0x4A98, 0x00000000}, -+ {0x492C, 0xBCEB4A14}, -+ {0x4930, 0x000A3A4A}, -+ {0x4934, 0xBCEB4A14}, -+ {0x4938, 0x000A3A4A}, -+ {0x493C, 0x9A8A8A85}, -+ {0x4940, 0x0CA3B99A}, -+ {0x4944, 0x38384242}, -+ {0x4948, 0x8086102E}, -+ {0x494C, 0xCA24C82A}, -+ {0x4950, 0x00008A62}, -+ {0x4954, 0x00000008}, -+ {0x4958, 0x80040000}, -+ {0x495C, 0x80040000}, -+ {0x4960, 0xFE800000}, -+ {0x4964, 0x834C0000}, -+ {0x4968, 0x00000000}, -+ {0x496C, 0x00000000}, -+ {0x4970, 0x00000000}, -+ {0x4974, 0x00000000}, -+ {0x4978, 0x00000000}, -+ {0x497C, 0x00000000}, -+ {0x4980, 0x40000000}, -+ {0x4984, 0x00000000}, -+ {0x4988, 0x00000000}, -+ {0x498C, 0x00000000}, -+ {0x4990, 0x00000000}, -+ {0x4994, 0x04065800}, -+ {0x4998, 0x02004080}, -+ {0x499C, 0x0E1E3E05}, -+ {0x49A0, 0x0A163068}, -+ {0x49A4, 0x00206040}, -+ {0x49A8, 0x02020202}, -+ {0x49AC, 0x00002020}, -+ {0x49B0, 0xF8F8F418}, -+ {0x49B4, 0xF8E8F8F8}, -+ {0x49B8, 0xF80808E8}, -+ {0x4A00, 0xF8F8FA00}, -+ {0x4A04, 0xFAFAFAF8}, -+ {0x4A08, 0xFAFAFAFA}, -+ {0x4A28, 0xFAFAFAFA}, -+ {0x4A2C, 0xFAFAFAFA}, -+ {0x4A30, 0xFAFAFAFA}, -+ {0x4A34, 0xFAFAFAFA}, -+ {0x4A38, 0xFAFAFAFA}, -+ {0x4A3C, 0xFAFAFAFA}, -+ {0x4A40, 0xFAFAFAFA}, -+ {0x4A44, 0x0000FAFA}, -+ {0x49BC, 0x00000000}, -+ {0x49C0, 0x800CD62D}, -+ {0x49C4, 0x00000103}, -+ {0x49C8, 0x00000000}, -+ {0x49CC, 0x00000000}, -+ {0x49D0, 0x00000000}, -+ {0x49D4, 0x00000000}, -+ {0x49D8, 0x00000000}, -+ {0x49DC, 0x00000000}, -+ {0x49E0, 0x00000000}, -+ {0x49E4, 0x00000000}, -+ {0x49E8, 0x00000000}, -+ {0x49EC, 0x00000000}, -+ {0x994, 0x00000010}, -+ {0x904, 0x00000005}, -+ {0xC3C, 0x2840E1BF}, -+ {0xC40, 0x00000000}, -+ {0xC44, 0x00000007}, -+ {0xC48, 0x410E4000}, -+ {0xC54, 0x1EE14368}, -+ {0xC58, 0x41000000}, -+ {0x730, 0x00000002}, -+ {0xC60, 0x017FFFF2}, -+ {0xC64, 0x0010A130}, -+ {0xC68, 0x10000050}, -+ {0xC6C, 0x10001021}, -+ {0x708, 0x00000000}, -+ {0x884, 0x0043F01D}, -+ {0x704, 0x601E0100}, -+ {0x710, 0xEF810000}, -+ {0x704, 0x601E0100}, -+ {0xD40, 0xF64FA0F7}, -+ {0xD44, 0x0400063F}, -+ {0xD48, 0x0003FF7F}, -+ {0xD4C, 0x00000000}, -+ {0xD50, 0xF64FA0F7}, -+ {0xD54, 0x04100437}, -+ {0xD58, 0x0000FF7F}, -+ {0xD5C, 0x00000000}, -+ {0xD60, 0x00000000}, -+ {0xD64, 0x00000000}, -+ {0xD70, 0x00000015}, -+ {0xD90, 0x000003FF}, -+ {0xD94, 0x00000000}, -+ {0xD98, 0x0000003F}, -+ {0xD9C, 0x00000000}, -+ {0xDA0, 0x000003FE}, -+ {0xDA4, 0x00000000}, -+ {0xDA8, 0x0000003F}, -+ {0xDAC, 0x00000000}, -+ {0xD00, 0x77777777}, -+ {0xD04, 0xBBBBBBBB}, -+ {0xD08, 0xBBBBBBBB}, -+ {0xD0C, 0x00000070}, -+ {0xD10, 0x20110900}, -+ {0xD10, 0x20110FFF}, -+ {0xD78, 0x00000001}, -+ {0xD7C, 0x001D050E}, -+ {0xD84, 0x00004207}, -+ {0xD18, 0x50209900}, -+ {0xD80, 0x00804100}, -+ {0x718, 0x1333233F}, -+ {0x604, 0x041E1E1E}, -+ {0x714, 0x00010000}, -+ {0x586C, 0x000000F0}, -+ {0x586C, 0x000000E0}, -+ {0x586C, 0x000000D0}, -+ {0x586C, 0x000000C0}, -+ {0x586C, 0x000000B0}, -+ {0x586C, 0x000000A0}, -+ {0x586C, 0x00000090}, -+ {0x586C, 0x00000080}, -+ {0x586C, 0x00000070}, -+ {0x586C, 0x00000060}, -+ {0x586C, 0x00000050}, -+ {0x586C, 0x00000040}, -+ {0x586C, 0x00000030}, -+ {0x586C, 0x00000020}, -+ {0x586C, 0x00000010}, -+ {0x586C, 0x00000000}, -+ {0x786C, 0x000000F0}, -+ {0x786C, 0x000000E0}, -+ {0x786C, 0x000000D0}, -+ {0x786C, 0x000000C0}, -+ {0x786C, 0x000000B0}, -+ {0x786C, 0x000000A0}, -+ {0x786C, 0x00000090}, -+ {0x786C, 0x00000080}, -+ {0x786C, 0x00000070}, -+ {0x786C, 0x00000060}, -+ {0x786C, 0x00000050}, -+ {0x786C, 0x00000040}, -+ {0x786C, 0x00000030}, -+ {0x786C, 0x00000020}, -+ {0x786C, 0x00000010}, -+ {0x786C, 0x00000000}, -+ {0xC0D4, 0x4486888C}, -+ {0xC0D8, 0xC6BA10E1}, -+ {0xC0DC, 0x30C52868}, -+ {0xC0E0, 0x05008128}, -+ {0xC0E4, 0x0000A72B}, -+ {0xC1D4, 0x4486888C}, -+ {0xC1D8, 0xC6BA10E1}, -+ {0xC1DC, 0x30C52868}, -+ {0xC1E0, 0x05008128}, -+ {0xC1E4, 0x0000A72B}, -+ {0xC0EC, 0x00000000}, -+ {0xC0E4, 0x0000272B}, -+ {0xC1EC, 0x00000000}, -+ {0xC1E4, 0x0000272B}, -+ {0x334, 0xFFFFFFFF}, -+ {0x33C, 0x55000000}, -+ {0x340, 0x00005555}, -+ {0x724, 0x00111200}, -+ {0x5868, 0xA9550000}, -+ {0x5870, 0x33221100}, -+ {0x5874, 0x77665544}, -+ {0x5878, 0xBBAA9988}, -+ {0x587C, 0xFFEEDDCC}, -+ {0x5880, 0x76543210}, -+ {0x5884, 0xFEDCBA98}, -+ {0x5888, 0x00000000}, -+ {0x588C, 0x00000000}, -+ {0x5894, 0x00000008}, -+ {0x7868, 0xA9550000}, -+ {0x7870, 0x33221100}, -+ {0x7874, 0x77665544}, -+ {0x7878, 0xBBAA9988}, -+ {0x787C, 0xFFEEDDCC}, -+ {0x7880, 0x76543210}, -+ {0x7884, 0xFEDCBA98}, -+ {0x7888, 0x00000000}, -+ {0x788C, 0x00000000}, -+ {0x7894, 0x00000008}, -+ {0x650, 0x00200888}, -+ {0x710, 0xF3810000}, -+ {0x020, 0x0000F381}, -+ {0x024, 0x0000F381}, -+ {0x000, 0xC580801E}, -+ {0xC70, 0x00000400}, -+ {0x980, 0x10002250}, -+ {0x988, 0x3C3C4107}, -+ {0x994, 0x00000010}, -+ {0x2994, 0x00000010}, -+ {0x000, 0x0580801F}, -+ {0x240C, 0x00000000}, -+ {0x640, 0x140A141E}, -+ {0x640, 0x1414141E}, -+ {0x640, 0x1414141E}, -+ {0x644, 0x3414283C}, -+ {0x644, 0x3425283C}, -+ {0x644, 0x3426283C}, -+ {0x2640, 0x140A141E}, -+ {0x2640, 0x1414141E}, -+ {0x2640, 0x1414141E}, -+ {0x2644, 0x3414283C}, -+ {0x2644, 0x3425283C}, -+ {0x2644, 0x3425183C}, -+ {0x2300, 0x02748790}, -+ {0x2304, 0x00558670}, -+ {0x2308, 0x002883F0}, -+ {0x230C, 0x00090120}, -+ {0x2310, 0x00000000}, -+ {0x2314, 0x06000000}, -+ {0x2318, 0x00000000}, -+ {0x231C, 0x00000000}, -+ {0x2320, 0x03020100}, -+ {0x2324, 0x07060504}, -+ {0x2328, 0x0B0A0908}, -+ {0x232C, 0x0F0E0D0C}, -+ {0x2330, 0x13121110}, -+ {0x2334, 0x17161514}, -+ {0x2338, 0x0C700022}, -+ {0x233C, 0x0A0529D0}, -+ {0x2340, 0x000529D0}, -+ {0x2344, 0x0006318A}, -+ {0x2348, 0xB7E6318A}, -+ {0x234C, 0x80039C00}, -+ {0x2350, 0x80039C00}, -+ {0x2354, 0x0005298F}, -+ {0x2358, 0x0015296E}, -+ {0x235C, 0x0C07FC31}, -+ {0x2360, 0x0219AAAE}, -+ {0x2364, 0xE4F624C3}, -+ {0x2368, 0x53626F15}, -+ {0x236C, 0x48000000}, -+ {0x2370, 0x48000000}, -+ {0x2374, 0x07540000}, -+ {0x2378, 0x202401B9}, -+ {0x237C, 0x00F7000E}, -+ {0x2380, 0x0F0A1111}, -+ {0x2384, 0x30D9000F}, -+ {0x2388, 0x0200EA02}, -+ {0x238C, 0x003CB061}, -+ {0x2390, 0x69C00000}, -+ {0x2394, 0x00000000}, -+ {0x2398, 0x000000F0}, -+ {0x239C, 0x0001FFFF}, -+ {0x23A0, 0x00C80064}, -+ {0x23A4, 0x0190012C}, -+ {0x23A8, 0x001917BE}, -+ {0x23AC, 0x0B30880C}, -+ {0x23B0, 0x9281CE00}, -+ {0x23B4, 0x7F027C00}, -+ {0x704, 0x601E0102}, -+ {0x704, 0x601E0102}, -+ {0x5864, 0x080801FF}, -+ {0x7864, 0x080801FF}, -+ {0xC60, 0x017FFFF3}, -+ {0x58AC, 0x08000000}, -+ {0x78AC, 0x08000000}, -+ {0x8088, 0x007F0000}, -+ {0x81A4, 0x003F3A00}, -+ {0x81B4, 0x0100007F}, -+ {0x81C0, 0x0060010B}, -+ {0x81A0, 0x00000010}, -+ {0x8138, 0x00000002}, -+ {0x82A4, 0x003F3A00}, -+ {0x82B4, 0x0100007F}, -+ {0x82C0, 0x0060010B}, -+ {0x82A0, 0x00000010}, -+ {0x81A0, 0x00000010}, -+ {0x8238, 0x00000002}, -+ {0x8088, 0x00000000}, -+ {0x8020, 0x00000000}, -+ {0x8120, 0x00000000}, -+ {0x8220, 0x00000000}, -+ {0x8124, 0x00000F0F}, -+ {0x8224, 0x00000F0F}, -+ {0x5864, 0x180801FF}, -+ {0x7864, 0x180801FF}, -+ {0xC60, 0x017FFFF3}, -+ {0xC70, 0x00000600}, -+ {0xC70, 0x00000660}, -+ {0x58AC, 0x08000000}, -+ {0x78AC, 0x08000000}, -+ {0x8120, 0x10000000}, -+ {0x8120, 0x10030000}, -+ {0x8124, 0x00000F0F}, -+ {0x8124, 0x00000F0F}, -+ {0x8224, 0x00000F0F}, -+ {0x8224, 0x00000F0F}, -+ {0x8220, 0x10000000}, -+ {0x8220, 0x10030000}, -+ {0x704, 0x601E0100}, -+ {0x5864, 0x100801FF}, -+ {0x7864, 0x100801FF}, -+ {0x5864, 0x180801FF}, -+ {0x7864, 0x180801FF}, -+ {0x58D4, 0x7401FE00}, -+ {0x78D4, 0x7401FE00}, -+ {0x58F0, 0x400401FF}, -+ {0x78F0, 0x400401FF}, -+ {0x58F0, 0x400401FF}, -+ {0x78F0, 0x400401FF}, -+ {0x704, 0x601E0102}, -+ {0xC7C, 0x0020BFE0}, -+ {0x58C0, 0x00FE0000}, -+ {0x58FC, 0x00000000}, -+ {0x566C, 0x00000005}, -+ {0x566C, 0x00001005}, -+ {0x78C0, 0x00FE0000}, -+ {0x78FC, 0x00000000}, -+ {0x700, 0x00000030}, -+ {0x704, 0x601E0102}, -+ {0x704, 0x601E0100}, -+ {0x704, 0x601E0502}, -+ {0x20FC, 0x00000000}, -+ {0x20F8, 0x00000000}, -+ {0x20F0, 0x00000000}, -+ {0x9C0, 0x00000001}, -+ {0x9C0, 0x00000000}, -+ {0x9C0, 0x00000001}, -+ {0x9C0, 0x00000000}, -+ {0x4AE8, 0x00000744}, -+ {0x4AF0, 0x00000744}, -+ {0x1010, 0x00000010}, -+ {0x3010, 0x00000010}, -+ {0x4AD4, 0x00000040}, -+ {0x4AE0, 0x00000040}, -+ {0x4AE4, 0x0079E99E}, -+ {0x4AEC, 0x0079E99E}, -+ {0x300, 0xF30CE31C}, -+ {0x304, 0x13EF1F19}, -+ {0x308, 0x0C0CF3F3}, -+ {0x30C, 0x0C0C0C0C}, -+ {0x310, 0x80496000}, -+ {0x314, 0x0041E000}, -+ {0x318, 0x20022042}, -+ {0x31C, 0x20448009}, -+ {0x320, 0x00010031}, -+ {0x324, 0xE000E000}, -+ {0x328, 0xE000E000}, -+ {0x32C, 0xE000E000}, -+ {0x12BC, 0x10104041}, -+ {0x12C0, 0x14411111}, -+ {0x32BC, 0x10104041}, -+ {0x32C0, 0x14411111}, -+ {0x010, 0x0005FFFF}, -+ {0x028, 0x0000F381}, -+ {0x02C, 0x0000F381}, -+ {0x620, 0x00141230}, -+ {0x704, 0x601C05FF}, -+ {0x720, 0x20000000}, -+ {0x738, 0x004100CC}, -+ {0x12A0, 0x24903056}, -+ {0x12AC, 0x12333121}, -+ {0x12B8, 0x30020000}, -+ {0x12E4, 0x30D52A68}, -+ {0x2000, 0x50BBBF04}, -+ {0x32A0, 0x24903056}, -+ {0x32AC, 0x12333121}, -+ {0x32B8, 0x30020000}, -+ {0x32E4, 0x30D52A68}, -+ {0x5800, 0x03FF807F}, -+ {0x5804, 0x04237040}, -+ {0x5808, 0x04237040}, -+ {0x7800, 0x03FF807F}, -+ {0x7804, 0x04237040}, -+ {0x7808, 0x04237040}, -+ {0x73C, 0x00000002}, -+ {0x74C, 0x00000001}, -+ {0x748, 0x00000002}, -+ {0x5818, 0x082C1800}, -+ {0x7818, 0x082C1800}, -+ {0x624, 0x0101030A}, -+ {0xC14, 0x85010000}, -+ {0xDD4, 0x00000001}, -+ {0x241C, 0x00000001}, -+ {0x1200, 0x00010142}, -+ {0x3200, 0x00010142}, -+ {0xC0F8, 0x00000001}, -+ {0xC1F8, 0x00000001}, -+ {0x35C, 0x000004C4}, -+ {0x0F0, 0x00000002}, -+ {0x0F4, 0x00000028}, -+ {0x0F8, 0x20220408}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8852b_phy_bb_reg_gain[] = { -+ {0x000, 0x18FBDDB7}, -+ {0x001, 0x006F5436}, -+ {0x002, 0x00004F31}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x10000, 0x07E6C39E}, -+ {0x10001, 0x00654526}, -+ {0x10002, 0x00006750}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x20000, 0x06E8C49F}, -+ {0x20001, 0x00654526}, -+ {0x20002, 0x00006750}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x30000, 0x04E5C39D}, -+ {0x30001, 0x00634325}, -+ {0x30002, 0x00006750}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x1000000, 0x000000F4}, -+ {0x1000010, 0x000000F8}, -+ {0x1000011, 0x0000F8F8}, -+ {0x1000100, 0x000000F8}, -+ {0x1000110, 0x00000000}, -+ {0x1000111, 0x00000000}, -+ {0x1010000, 0x000000F4}, -+ {0x1010010, 0x000000F8}, -+ {0x1010011, 0x0000F8F8}, -+ {0x1010020, 0x000000F8}, -+ {0x1010021, 0x0808E8E8}, -+ {0x1010029, 0x0000F8F8}, -+ {0x1010100, 0x000000F4}, -+ {0x1010110, 0x000000F8}, -+ {0x1010111, 0x0000F8F8}, -+ {0x1010120, 0x000000F8}, -+ {0x1010121, 0x0808E8E8}, -+ {0x1010129, 0x0000F8F8}, -+ {0x1020000, 0x000000F4}, -+ {0x1020010, 0x000000F8}, -+ {0x1020011, 0x0000F8F8}, -+ {0x1020020, 0x000000F8}, -+ {0x1020021, 0x0808E8E8}, -+ {0x1020029, 0x0000F8F8}, -+ {0x1020100, 0x000000F4}, -+ {0x1020110, 0x000000F8}, -+ {0x1020111, 0x0000F8F8}, -+ {0x1020120, 0x000000F8}, -+ {0x1020121, 0x0808E8E8}, -+ {0x1020129, 0x0000F8F8}, -+ {0x1030000, 0x000000F4}, -+ {0x1030010, 0x000000F8}, -+ {0x1030011, 0x0000F8F8}, -+ {0x1030020, 0x000000F8}, -+ {0x1030021, 0x0808E8E8}, -+ {0x1030029, 0x0000F8F8}, -+ {0x1030100, 0x000000F4}, -+ {0x1030110, 0x000000F8}, -+ {0x1030111, 0x0000F8F8}, -+ {0x1030120, 0x000000F8}, -+ {0x1030121, 0x0808E8E8}, -+ {0x1030129, 0x0000F8F8}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8852b_phy_radioa_regs[] = { -+ {0xF0010000, 0x00000000}, -+ {0xF0020000, 0x00000001}, -+ {0xF0010001, 0x00000002}, -+ {0xF0020001, 0x00000003}, -+ {0xF0030001, 0x00000004}, -+ {0xF0040001, 0x00000005}, -+ {0xF0050001, 0x00000006}, -+ {0xF0060001, 0x00000007}, -+ {0xF0070001, 0x00000008}, -+ {0xF0080001, 0x00000009}, -+ {0xF0290001, 0x0000000A}, -+ {0xF02B0001, 0x0000000B}, -+ {0x005, 0x00000000}, -+ {0x000, 0x00030000}, -+ {0x10000, 0x00030000}, -+ {0x018, 0x00011124}, -+ {0x10018, 0x00011124}, -+ {0x000, 0x00033C00}, -+ {0x10000, 0x00033C00}, -+ {0x01A, 0x00040004}, -+ {0x011, 0x00014073}, -+ {0x067, 0x00000070}, -+ {0x059, 0x000A0000}, -+ {0x066, 0x00000100}, -+ {0x057, 0x0000D589}, -+ {0x05A, 0x0007FFFF}, -+ {0x0A4, 0x0006FF12}, -+ {0x043, 0x00005000}, -+ {0x0E1, 0x00000001}, -+ {0x0DD, 0x000001A0}, -+ {0x0CA, 0x00002000}, -+ {0x0D3, 0x00000003}, -+ {0x0B3, 0x0004EFE0}, -+ {0x0B4, 0x0007C07E}, -+ {0x0B5, 0x0003A701}, -+ {0x0B6, 0x000581E0}, -+ {0x0B7, 0x00001A0A}, -+ {0x0BB, 0x000C7000}, -+ {0x0ED, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000543}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000542}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000541}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000521}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000343}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000342}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000341}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000321}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x000005C3}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x000005C2}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x000005C1}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x000005A1}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x000002C3}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x000002C2}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x000002C1}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x000002A1}, -+ {0x0ED, 0x00000000}, -+ {0x0ED, 0x00002000}, -+ {0x033, 0x00000002}, -+ {0x03D, 0x0004A883}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000006}, -+ {0x03D, 0x0004A883}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x0ED, 0x00000000}, -+ {0x018, 0x00001001}, -+ {0x10018, 0x00001001}, -+ {0x002, 0x0000000D}, -+ {0x10002, 0x0000000D}, -+ {0x0EE, 0x00000004}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x0000000B}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x00000012}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00000019}, -+ {0x0EE, 0x00000000}, -+ {0x08F, 0x000D0F7A}, -+ {0x0EF, 0x00080000}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000034C0}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000035D0}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000035C8}, -+ {0x033, 0x0000008A}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000035F7}, -+ {0x0EF, 0x00000000}, -+ {0x08D, 0x000CC800}, -+ {0x0EF, 0x00004000}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00090600}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000A3500}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000A3400}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00008B00}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00001B00}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00003A00}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00090600}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x000A3500}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x000A3400}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x00008B00}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00001B00}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00003A00}, -+ {0x0EF, 0x00000000}, -+ {0x0EE, 0x00000010}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00000001}, -+ {0x0EE, 0x00000000}, -+ {0x0EF, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000017}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00008000}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000031}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000032}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000033}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000034}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000035}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000036}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000100}, -+ {0x033, 0x00000000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000001}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000002}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00004376}, -+ {0x033, 0x00000004}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00004376}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00004376}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00004376}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00004376}, -+ {0x033, 0x0000000A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000010}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000011}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000012}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000013}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000014}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000015}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000016}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000017}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000020}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000021}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000022}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000023}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000024}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000025}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000026}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000027}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004386}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004396}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x067, 0x00008072}, -+ {0x0EF, 0x00000010}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000ED5}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000FC7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000783}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000973}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000762}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000762}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000080}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000007}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023958}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000017}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000018}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000019}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001A}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001B}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001C}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001D}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000027}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000031}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000032}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000033}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000034}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000035}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000036}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000037}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000038}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000039}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026858}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000003A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000003B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00023A58}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x0002C758}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x0EE, 0x00000800}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000006}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00003001}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00003003}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00003007}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000300F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000310F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000330F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000330F}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00003001}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x00003003}, -+ {0x033, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00003103}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00002307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xB0000000, 0x00000000}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00000200}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000004}, -+ {0x03D, 0x00000078}, -+ {0x03E, 0x00080000}, -+ {0x03F, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x03D, 0x0000007B}, -+ {0x03E, 0x00020000}, -+ {0x03F, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x0DE, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x033, 0x00000000}, -+ {0x008, 0x00060280}, -+ {0x009, 0x00030400}, -+ {0x0EF, 0x00000000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000200}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000007F}, -+ {0x0EF, 0x00000000}, -+ {0x06E, 0x00077A18}, -+ {0x06F, 0x00077A18}, -+ {0x06D, 0x00000C31}, -+ {0x0EF, 0x00020000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000005FF}, -+ {0x0EF, 0x00000000}, -+ {0x005, 0x00000001}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0xA0000000, 0x00000000}, -+ {0x094, 0x000001FC}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00002000}, -+ {0x10033, 0x00000080}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000081}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000082}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000083}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000084}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000085}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000086}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000087}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000088}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000089}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000090}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A2}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A3}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C2}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C3}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10033, 0x00000080}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x00000081}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x00000082}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x00000083}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x00000084}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000085}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000086}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000087}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000088}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000089}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000090}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000091}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A0}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x000000A1}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x000000A2}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x000000A3}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x000000A4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C0}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x000000C1}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x000000C2}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x000000C3}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x000000C4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00002000}, -+ {0x10033, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0x10033, 0x00000001}, -+ {0x1003F, 0x000000F3}, -+ {0x10033, 0x00000002}, -+ {0x1003F, 0x000000F0}, -+ {0x10033, 0x00000003}, -+ {0x1003F, 0x000000ED}, -+ {0x10033, 0x00000004}, -+ {0x1003F, 0x000000EA}, -+ {0x10033, 0x00000005}, -+ {0x1003F, 0x000000E7}, -+ {0x10033, 0x00000006}, -+ {0x1003F, 0x000000A6}, -+ {0x10033, 0x00000007}, -+ {0x1003F, 0x000000A3}, -+ {0x10033, 0x00000008}, -+ {0x1003F, 0x00000063}, -+ {0x10033, 0x00000009}, -+ {0x1003F, 0x00000060}, -+ {0x10033, 0x0000000A}, -+ {0x1003F, 0x00000023}, -+ {0x10033, 0x0000000B}, -+ {0x1003F, 0x00000020}, -+ {0x10033, 0x0000000C}, -+ {0x1003F, 0x0000001D}, -+ {0x10033, 0x0000000D}, -+ {0x1003F, 0x0000001A}, -+ {0x10033, 0x0000000E}, -+ {0x1003F, 0x00000017}, -+ {0x10033, 0x0000000F}, -+ {0x1003F, 0x00000014}, -+ {0x10033, 0x00000010}, -+ {0x1003F, 0x00000011}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10033, 0x00000000}, -+ {0x1003F, 0x000001AF}, -+ {0x10033, 0x00000001}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x00000002}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x00000003}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x00000004}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x00000005}, -+ {0x1003F, 0x0000015F}, -+ {0x10033, 0x00000006}, -+ {0x1003F, 0x00000159}, -+ {0x10033, 0x00000007}, -+ {0x1003F, 0x0000011F}, -+ {0x10033, 0x00000008}, -+ {0x1003F, 0x00000119}, -+ {0x10033, 0x00000009}, -+ {0x1003F, 0x000000DF}, -+ {0x10033, 0x0000000A}, -+ {0x1003F, 0x000000D9}, -+ {0x10033, 0x0000000B}, -+ {0x1003F, 0x0000009F}, -+ {0x10033, 0x0000000C}, -+ {0x1003F, 0x00000099}, -+ {0x10033, 0x0000000D}, -+ {0x1003F, 0x0000005F}, -+ {0x10033, 0x0000000E}, -+ {0x1003F, 0x00000059}, -+ {0x10033, 0x0000000F}, -+ {0x1003F, 0x0000001F}, -+ {0x10033, 0x00000010}, -+ {0x1003F, 0x00000019}, -+ {0x10033, 0x00000011}, -+ {0x1003F, 0x00000013}, -+ {0x100EE, 0x00000000}, -+ {0x10005, 0x00000001}, -+ {0x09F, 0x00000032}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8852b_phy_radiob_regs[] = { -+ {0xF0010000, 0x00000000}, -+ {0xF0020000, 0x00000001}, -+ {0xF0010001, 0x00000002}, -+ {0xF0020001, 0x00000003}, -+ {0xF0030001, 0x00000004}, -+ {0xF0040001, 0x00000005}, -+ {0xF0050001, 0x00000006}, -+ {0xF0060001, 0x00000007}, -+ {0xF0070001, 0x00000008}, -+ {0xF0080001, 0x00000009}, -+ {0xF0290001, 0x0000000A}, -+ {0xF02B0001, 0x0000000B}, -+ {0x005, 0x00000000}, -+ {0x000, 0x00030000}, -+ {0x10000, 0x00030000}, -+ {0x018, 0x00011124}, -+ {0x10018, 0x00011124}, -+ {0x000, 0x00033C00}, -+ {0x10000, 0x00033C00}, -+ {0x01A, 0x00040004}, -+ {0x011, 0x00014073}, -+ {0x067, 0x00000070}, -+ {0x059, 0x000A0000}, -+ {0x066, 0x00000100}, -+ {0x05A, 0x0007F000}, -+ {0x0A4, 0x0006FF12}, -+ {0x043, 0x00005000}, -+ {0x0E1, 0x00000001}, -+ {0x0DD, 0x000001A0}, -+ {0x0CA, 0x00002000}, -+ {0x0D3, 0x00000003}, -+ {0x0B3, 0x0004EFE0}, -+ {0x0B4, 0x0007C03E}, -+ {0x0B5, 0x0003A201}, -+ {0x0BB, 0x000C7000}, -+ {0x0ED, 0x00002000}, -+ {0x033, 0x00000002}, -+ {0x03D, 0x0004A883}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000006}, -+ {0x03D, 0x0004A883}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x0ED, 0x00000000}, -+ {0x018, 0x00001001}, -+ {0x10018, 0x00001001}, -+ {0x002, 0x0000000D}, -+ {0x10002, 0x0000000D}, -+ {0x0EE, 0x00000004}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x0000000B}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x00000012}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00000019}, -+ {0x0EE, 0x00000000}, -+ {0x08F, 0x000D0F7A}, -+ {0x0EF, 0x00080000}, -+ {0x033, 0x00000008}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D30}, -+ {0xA0000000, 0x00000000}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000034C0}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D74}, -+ {0xA0000000, 0x00000000}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000035D0}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D72}, -+ {0xA0000000, 0x00000000}, -+ {0x03E, 0x000000C4}, -+ {0x03F, 0x000035C8}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000008A}, -+ {0x03E, 0x00000031}, -+ {0x03F, 0x00000D7D}, -+ {0x0EF, 0x00000000}, -+ {0x08D, 0x000CC800}, -+ {0x0EF, 0x00004000}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00090600}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000A3500}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000A3400}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00008B00}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00001B00}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00003A00}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x00000700}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00090600}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x000A3500}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x000A3400}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x00008B00}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00001B00}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00003A00}, -+ {0x033, 0x00000017}, -+ {0x03F, 0x00000705}, -+ {0x033, 0x00000016}, -+ {0x03F, 0x00000705}, -+ {0x033, 0x00000015}, -+ {0x03F, 0x00090605}, -+ {0x033, 0x00000014}, -+ {0x03F, 0x000A3505}, -+ {0x033, 0x00000013}, -+ {0x03F, 0x000A3405}, -+ {0x033, 0x00000012}, -+ {0x03F, 0x00008B05}, -+ {0x033, 0x00000011}, -+ {0x03F, 0x00001B05}, -+ {0x033, 0x00000010}, -+ {0x03F, 0x00003A05}, -+ {0x0EF, 0x00000000}, -+ {0x0EE, 0x00000010}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00000001}, -+ {0x0EE, 0x00000000}, -+ {0x0EF, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x033, 0x00000001}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000002}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000015}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000003}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000007}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00008000}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x00004FC0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000031}, -+ {0x03E, 0x000046C0}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000032}, -+ {0x03E, 0x00004240}, -+ {0x03F, 0x00000087}, -+ {0x033, 0x00000033}, -+ {0x03E, 0x00008010}, -+ {0x03F, 0x00000147}, -+ {0x033, 0x00000034}, -+ {0x03E, 0x0000A048}, -+ {0x03F, 0x0000004F}, -+ {0x033, 0x00000035}, -+ {0x03E, 0x0000A030}, -+ {0x03F, 0x0000005F}, -+ {0x033, 0x00000036}, -+ {0x03E, 0x0000A000}, -+ {0x03F, 0x0000009F}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000100}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00004346}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00004346}, -+ {0x033, 0x00000003}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00004346}, -+ {0x033, 0x00000005}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004317}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000006}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000007}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000008}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000009}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004376}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000043A6}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000010}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000011}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000012}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000013}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000014}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000015}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000016}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000017}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000020}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000021}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004347}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000022}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00004346}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00004366}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000023}, -+ {0x03F, 0x00004386}, -+ {0x033, 0x00000024}, -+ {0x03F, 0x00004386}, -+ {0x033, 0x00000025}, -+ {0x03F, 0x00004386}, -+ {0x033, 0x00000026}, -+ {0x03F, 0x00004386}, -+ {0x033, 0x00000027}, -+ {0x03F, 0x00004386}, -+ {0x0EF, 0x00000000}, -+ {0x067, 0x00008072}, -+ {0x0EF, 0x00000010}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000ED5}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000FC5}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000A93}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000973}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000761}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000761}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000080}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000007}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020758}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000017}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000018}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000019}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001A}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001B}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001C}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001D}, -+ {0x03E, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000001F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000027}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000002F}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000031}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000032}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000033}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000034}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000035}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000036}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000037}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000038}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000039}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022658}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00026458}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000003A}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00022858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000003B}, -+ {0x03E, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00020858}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00027558}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x0EE, 0x00000800}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000006}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00003001}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00003003}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00003007}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000300F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000310F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000330F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000330F}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00003001}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x00003003}, -+ {0x033, 0x0000000B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003007}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00003103}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003107}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00003307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00002307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00001307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x0000000F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00000307}, -+ {0xB0000000, 0x00000000}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00000200}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x0EC, 0x00000100}, -+ {0xB0000000, 0x00000000}, -+ {0x033, 0x00000004}, -+ {0x03D, 0x00000078}, -+ {0x03E, 0x00080000}, -+ {0x03F, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x03D, 0x0000007B}, -+ {0x03E, 0x00020000}, -+ {0x03F, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x0DE, 0x00000000}, -+ {0x0EF, 0x00000000}, -+ {0x033, 0x00000000}, -+ {0x008, 0x00060280}, -+ {0x009, 0x00030400}, -+ {0x0EF, 0x00000000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000013F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FB}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000001FF}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000001F7}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000000FF}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000000FF}, -+ {0xB0000000, 0x00000000}, -+ {0x0EF, 0x00000200}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000017F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000007F}, -+ {0x0EF, 0x00000000}, -+ {0x06E, 0x00077A18}, -+ {0x06F, 0x00077A18}, -+ {0x06D, 0x00000C31}, -+ {0x0EF, 0x00020000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000005FF}, -+ {0x0EF, 0x00000000}, -+ {0x005, 0x00000001}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x094, 0x000000FC}, -+ {0xA0000000, 0x00000000}, -+ {0x094, 0x000001FC}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00002000}, -+ {0x10033, 0x00000080}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000081}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000082}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000083}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000084}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000085}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000086}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000087}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000088}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000089}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000090}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A2}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A3}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000FB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C2}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F5}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000F0}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C3}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000F2}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000ED}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000EA}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000EC}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000E7}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000AB}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A6}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000A8}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000A3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000068}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000063}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000065}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000060}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000002B}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000026}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000028}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000023}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000025}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000020}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000022}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000001A}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001C}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000017}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000014}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10033, 0x00000080}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x00000081}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x00000082}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x00000083}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x00000084}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000085}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000086}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000087}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000088}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000089}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008A}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008B}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008C}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008D}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008E}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x0000008F}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000090}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x00000091}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A0}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x000000A1}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x000000A2}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x000000A3}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x000000A4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000A9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000AF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000B1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C0}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x000000C1}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x000000C2}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x000000C3}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x000000C4}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000158}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000191}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C5}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000011F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000018B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C6}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000119}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000014D}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C7}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000010B}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C8}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000DF}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000C9}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000009F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D9}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CA}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x000000D3}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CB}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000005F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000099}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CC}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000093}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CD}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000059}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CE}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000053}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000CF}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000019}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D0}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x00000013}, -+ {0xB0000000, 0x00000000}, -+ {0x10033, 0x000000D1}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90060001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90080001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x90290001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0x902b0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x1003F, 0x00000007}, -+ {0xA0000000, 0x00000000}, -+ {0x1003F, 0x0000000D}, -+ {0xB0000000, 0x00000000}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00002000}, -+ {0x10033, 0x00000000}, -+ {0x1003F, 0x000000F6}, -+ {0x10033, 0x00000001}, -+ {0x1003F, 0x000000F3}, -+ {0x10033, 0x00000002}, -+ {0x1003F, 0x000000F0}, -+ {0x10033, 0x00000003}, -+ {0x1003F, 0x000000ED}, -+ {0x10033, 0x00000004}, -+ {0x1003F, 0x000000EA}, -+ {0x10033, 0x00000005}, -+ {0x1003F, 0x000000E7}, -+ {0x10033, 0x00000006}, -+ {0x1003F, 0x000000A6}, -+ {0x10033, 0x00000007}, -+ {0x1003F, 0x000000A3}, -+ {0x10033, 0x00000008}, -+ {0x1003F, 0x00000063}, -+ {0x10033, 0x00000009}, -+ {0x1003F, 0x00000060}, -+ {0x10033, 0x0000000A}, -+ {0x1003F, 0x00000023}, -+ {0x10033, 0x0000000B}, -+ {0x1003F, 0x00000020}, -+ {0x10033, 0x0000000C}, -+ {0x1003F, 0x0000001D}, -+ {0x10033, 0x0000000D}, -+ {0x1003F, 0x0000001A}, -+ {0x10033, 0x0000000E}, -+ {0x1003F, 0x00000017}, -+ {0x10033, 0x0000000F}, -+ {0x1003F, 0x00000014}, -+ {0x10033, 0x00000010}, -+ {0x1003F, 0x00000011}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10033, 0x00000000}, -+ {0x1003F, 0x000001AF}, -+ {0x10033, 0x00000001}, -+ {0x1003F, 0x000001A9}, -+ {0x10033, 0x00000002}, -+ {0x1003F, 0x000001A3}, -+ {0x10033, 0x00000003}, -+ {0x1003F, 0x0000019D}, -+ {0x10033, 0x00000004}, -+ {0x1003F, 0x00000197}, -+ {0x10033, 0x00000005}, -+ {0x1003F, 0x0000015F}, -+ {0x10033, 0x00000006}, -+ {0x1003F, 0x00000159}, -+ {0x10033, 0x00000007}, -+ {0x1003F, 0x0000011F}, -+ {0x10033, 0x00000008}, -+ {0x1003F, 0x00000119}, -+ {0x10033, 0x00000009}, -+ {0x1003F, 0x000000DF}, -+ {0x10033, 0x0000000A}, -+ {0x1003F, 0x000000D9}, -+ {0x10033, 0x0000000B}, -+ {0x1003F, 0x0000009F}, -+ {0x10033, 0x0000000C}, -+ {0x1003F, 0x00000099}, -+ {0x10033, 0x0000000D}, -+ {0x1003F, 0x0000005F}, -+ {0x10033, 0x0000000E}, -+ {0x1003F, 0x00000059}, -+ {0x10033, 0x0000000F}, -+ {0x1003F, 0x0000001F}, -+ {0x10033, 0x00000010}, -+ {0x1003F, 0x00000019}, -+ {0x10033, 0x00000011}, -+ {0x1003F, 0x00000013}, -+ {0x100EE, 0x00000000}, -+ {0x10005, 0x00000001}, -+ {0x09F, 0x00000032}, -+}; ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h -@@ -0,0 +1,30 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2019-2020 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8852B_TABLE_H__ -+#define __RTW89_8852B_TABLE_H__ -+ -+#include "core.h" -+ -+extern const struct rtw89_phy_table rtw89_8852b_phy_bb_table; -+extern const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table; -+extern const struct rtw89_phy_table rtw89_8852b_phy_radioa_table; -+extern const struct rtw89_phy_table rtw89_8852b_phy_radiob_table; -+extern const struct rtw89_phy_table rtw89_8852b_phy_nctl_table; -+extern const struct rtw89_txpwr_table rtw89_8852b_byr_table; -+extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg; -+extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+ [RTW89_REGD_NUM]; -+extern const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -+extern const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+extern const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -+extern const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch deleted file mode 100644 index 4d8d2cfee..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch +++ /dev/null @@ -1,9655 +0,0 @@ -From 3e65a0ae142a97bb9b2e0a988e1ddf55fe289cf0 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:29 +0800 -Subject: [PATCH 002/149] wifi: rtw89: 8852b: add BB and RF tables (2 of 2) - -These tables contain BB and RF parameters that driver will load them into -registers. It also contains TX power according to country, band, rate and -so on. Increasing thermal can cause TX power degraded, so power tracking -tables are defined to compensate TX power. - -Internal version of these tables: - - HALRF_029_00_014 (R32) - - HALBB_027_046_05 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-3-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8852b_table.c | 9628 +++++++++++++++++ - 1 file changed, 9628 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -@@ -13247,3 +13247,9631 @@ static const struct rtw89_reg2_def rtw89 - {0x10005, 0x00000001}, - {0x09F, 0x00000032}, - }; -+ -+static const struct rtw89_reg2_def rtw89_8852b_phy_nctl_regs[] = { -+ {0x8000, 0x00000008}, -+ {0x8008, 0x00000000}, -+ {0x8004, 0xf0862966}, -+ {0x800c, 0x78000000}, -+ {0x8010, 0x88015000}, -+ {0x8014, 0x80010100}, -+ {0x8018, 0x10010100}, -+ {0x801c, 0xa210bc00}, -+ {0x8020, 0x000403e0}, -+ {0x8024, 0x00072160}, -+ {0x8028, 0x00180e00}, -+ {0x8030, 0x400000c0}, -+ {0x8034, 0x11000830}, -+ {0x8038, 0x00000009}, -+ {0x803c, 0x00000008}, -+ {0x8040, 0x00000046}, -+ {0x8044, 0x0010001f}, -+ {0x8048, 0xf0000003}, -+ {0x804c, 0x62ac6162}, -+ {0x8050, 0xf2acf162}, -+ {0x8054, 0x62ac6162}, -+ {0x8058, 0xf2acf162}, -+ {0x805c, 0x150c0b02}, -+ {0x8060, 0x150c0b02}, -+ {0x8064, 0x2aa00047}, -+ {0x8074, 0x80000000}, -+ {0x807c, 0x000000ee}, -+ {0x8088, 0x80000000}, -+ {0x8098, 0x0000ff00}, -+ {0x809c, 0x0000001f}, -+ {0x80a0, 0x00010300}, -+ {0x80b8, 0x00001000}, -+ {0x80b0, 0x00000000}, -+ {0x80d0, 0x00000000}, -+ {0x80ec, 0x00000002}, -+ {0x810c, 0x33112200}, -+ {0x8110, 0x33112200}, -+ {0x8114, 0x00000000}, -+ {0x8120, 0x10010000}, -+ {0x8124, 0x00000000}, -+ {0x812c, 0x0000c000}, -+ {0x8138, 0x40000000}, -+ {0x813c, 0x40000000}, -+ {0x8140, 0x00000000}, -+ {0x8144, 0x0b040b03}, -+ {0x8148, 0x0a050b04}, -+ {0x814c, 0x0a050b04}, -+ {0x8150, 0xe4e40000}, -+ {0x8158, 0xffffffff}, -+ {0x815c, 0xffffffff}, -+ {0x8160, 0xffffffff}, -+ {0x8164, 0xffffffff}, -+ {0x8168, 0xffffffff}, -+ {0x816c, 0x1fffffff}, -+ {0x81a0, 0x00000000}, -+ {0x81ac, 0x003f2e2e}, -+ {0x81b0, 0x003f2e2e}, -+ {0x81bc, 0x005b5b5b}, -+ {0x81c0, 0x005b5b5b}, -+ {0x81b4, 0x00600060}, -+ {0x81b8, 0x00600060}, -+ {0x81cc, 0x00000000}, -+ {0x81dc, 0x00000002}, -+ {0x81e0, 0x00000000}, -+ {0x81e4, 0x00000001}, -+ {0x820c, 0x33112200}, -+ {0x8210, 0x33112200}, -+ {0x8214, 0x00000000}, -+ {0x8220, 0x10010000}, -+ {0x8224, 0x00000000}, -+ {0x822c, 0x0000d000}, -+ {0x8238, 0x40000000}, -+ {0x823c, 0x40000000}, -+ {0x8240, 0x00000000}, -+ {0x8244, 0x0b040b03}, -+ {0x8248, 0x0a050b04}, -+ {0x824c, 0x0a050b04}, -+ {0x8250, 0xe4e40000}, -+ {0x8258, 0xffffffff}, -+ {0x825c, 0xffffffff}, -+ {0x8260, 0xffffffff}, -+ {0x8264, 0xffffffff}, -+ {0x8268, 0xffffffff}, -+ {0x826c, 0x1fffffff}, -+ {0x82a0, 0x00000000}, -+ {0x82ac, 0x003f2e2e}, -+ {0x82b0, 0x003f2e2e}, -+ {0x82bc, 0x005b5b5b}, -+ {0x82c0, 0x005b5b5b}, -+ {0x82b4, 0x00600060}, -+ {0x82b8, 0x00600060}, -+ {0x82cc, 0x00000000}, -+ {0x82dc, 0x00000002}, -+ {0x82e0, 0x00100000}, -+ {0x82e4, 0x00000001}, -+ {0x81d8, 0x00000001}, -+ {0x82d8, 0x00000001}, -+ {0x8d00, 0x00000000}, -+ {0x8d04, 0x00000000}, -+ {0x8d08, 0x00000000}, -+ {0x8d0c, 0x00000000}, -+ {0x8d10, 0x00000000}, -+ {0x8d14, 0x00000000}, -+ {0x8d18, 0x00000000}, -+ {0x8d1c, 0x00000000}, -+ {0x8d20, 0x00000000}, -+ {0x8d24, 0x00000000}, -+ {0x8d28, 0x00000000}, -+ {0x8d2c, 0x00000000}, -+ {0x8d30, 0x00000000}, -+ {0x8d34, 0x00000000}, -+ {0x8d38, 0x00000000}, -+ {0x8d3c, 0x00000000}, -+ {0x8d40, 0x00000000}, -+ {0x8d44, 0x00000000}, -+ {0x8d48, 0x00000000}, -+ {0x8d4c, 0x00000000}, -+ {0x8d50, 0x00000000}, -+ {0x8d54, 0x00000000}, -+ {0x8d58, 0x00000000}, -+ {0x8d5c, 0x00000000}, -+ {0x8d60, 0x00000000}, -+ {0x8d64, 0x00000000}, -+ {0x8d68, 0x00000000}, -+ {0x8d6c, 0x00000000}, -+ {0x8d70, 0x00000000}, -+ {0x8d74, 0x00000000}, -+ {0x8d78, 0x00000000}, -+ {0x8d7c, 0x00000000}, -+ {0x8d80, 0x00000000}, -+ {0x8d84, 0x00000000}, -+ {0x8d88, 0x00000000}, -+ {0x8d8c, 0x00000000}, -+ {0x8d90, 0x00000000}, -+ {0x8d94, 0x00000000}, -+ {0x8d98, 0x00000000}, -+ {0x8d9c, 0x00000000}, -+ {0x8da0, 0x00000000}, -+ {0x8da4, 0x00000000}, -+ {0x8da8, 0x00000000}, -+ {0x8dac, 0x00000000}, -+ {0x8db0, 0x00000000}, -+ {0x8db4, 0x00000000}, -+ {0x8db8, 0x00000000}, -+ {0x8dbc, 0x00000000}, -+ {0x8dc0, 0x00000000}, -+ {0x8dc4, 0x00000000}, -+ {0x8dc8, 0x00000000}, -+ {0x8dcc, 0x00000000}, -+ {0x8dd0, 0x00000000}, -+ {0x8dd4, 0x00000000}, -+ {0x8dd8, 0x00000000}, -+ {0x8ddc, 0x00000000}, -+ {0x8de0, 0x00000000}, -+ {0x8de4, 0x00000000}, -+ {0x8de8, 0x00000000}, -+ {0x8dec, 0x00000000}, -+ {0x8df0, 0x00000000}, -+ {0x8df4, 0x00000000}, -+ {0x8df8, 0x00000000}, -+ {0x8dfc, 0x00000000}, -+ {0x8e00, 0x00000000}, -+ {0x8e04, 0x00000000}, -+ {0x8e08, 0x00000000}, -+ {0x8e0c, 0x00000000}, -+ {0x8e10, 0x00000000}, -+ {0x8e14, 0x00000000}, -+ {0x8e18, 0x00000000}, -+ {0x8e1c, 0x00000000}, -+ {0x8e20, 0x00000000}, -+ {0x8e24, 0x00000000}, -+ {0x8e28, 0x00000000}, -+ {0x8e2c, 0x00000000}, -+ {0x8e30, 0x00000000}, -+ {0x8e34, 0x00000000}, -+ {0x8e38, 0x00000000}, -+ {0x8e3c, 0x00000000}, -+ {0x8e40, 0x00000000}, -+ {0x8e44, 0x00000000}, -+ {0x8e48, 0x00000000}, -+ {0x8e4c, 0x00000000}, -+ {0x8e50, 0x00000000}, -+ {0x8e54, 0x00000000}, -+ {0x8e58, 0x00000000}, -+ {0x8e5c, 0x00000000}, -+ {0x8e60, 0x00000000}, -+ {0x8e64, 0x00000000}, -+ {0x8e68, 0x00000000}, -+ {0x8e6c, 0x00000000}, -+ {0x8e70, 0x00000000}, -+ {0x8e74, 0x00000000}, -+ {0x8e78, 0x00000000}, -+ {0x8e7c, 0x00000000}, -+ {0x8e80, 0x00000000}, -+ {0x8e84, 0x00000000}, -+ {0x8e88, 0x00000000}, -+ {0x8e8c, 0x00000000}, -+ {0x8e90, 0x00000000}, -+ {0x8e94, 0x00000000}, -+ {0x8e98, 0x00000000}, -+ {0x8e9c, 0x00000000}, -+ {0x8ea0, 0x00000000}, -+ {0x8ea4, 0x00000000}, -+ {0x8ea8, 0x00000000}, -+ {0x8eac, 0x00000000}, -+ {0x8eb0, 0x00000000}, -+ {0x8eb4, 0x00000000}, -+ {0x8eb8, 0x00000000}, -+ {0x8ebc, 0x00000000}, -+ {0x8ec0, 0x00000000}, -+ {0x8ec4, 0x00000000}, -+ {0x8ec8, 0x00000000}, -+ {0x8ecc, 0x00000000}, -+ {0x8ed0, 0x00000000}, -+ {0x8ed4, 0x00000000}, -+ {0x8ed8, 0x00000000}, -+ {0x8edc, 0x00000000}, -+ {0x8ee0, 0x00000000}, -+ {0x8ee4, 0x00000000}, -+ {0x8ee8, 0x00000000}, -+ {0x8eec, 0x00000000}, -+ {0x8ef0, 0x00000000}, -+ {0x8ef4, 0x00000000}, -+ {0x8ef8, 0x00000000}, -+ {0x8efc, 0x00000000}, -+ {0x8f00, 0x00000000}, -+ {0x8f04, 0x00000000}, -+ {0x8f08, 0x00000000}, -+ {0x8f0c, 0x00000000}, -+ {0x8f10, 0x00000000}, -+ {0x8f14, 0x00000000}, -+ {0x8f18, 0x00000000}, -+ {0x8f1c, 0x00000000}, -+ {0x8f20, 0x00000000}, -+ {0x8f24, 0x00000000}, -+ {0x8f28, 0x00000000}, -+ {0x8f2c, 0x00000000}, -+ {0x8f30, 0x00000000}, -+ {0x8f34, 0x00000000}, -+ {0x8f38, 0x00000000}, -+ {0x8f3c, 0x00000000}, -+ {0x8f40, 0x00000000}, -+ {0x8f44, 0x00000000}, -+ {0x8f48, 0x00000000}, -+ {0x8f4c, 0x00000000}, -+ {0x8f50, 0x00000000}, -+ {0x8f54, 0x00000000}, -+ {0x8f58, 0x00000000}, -+ {0x8f5c, 0x00000000}, -+ {0x8f60, 0x00000000}, -+ {0x8f64, 0x00000000}, -+ {0x8f68, 0x00000000}, -+ {0x8f6c, 0x00000000}, -+ {0x8f70, 0x00000000}, -+ {0x8f74, 0x00000000}, -+ {0x8f78, 0x00000000}, -+ {0x8f7c, 0x00000000}, -+ {0x8f80, 0x00000000}, -+ {0x8f84, 0x00000000}, -+ {0x8f88, 0x00000000}, -+ {0x8f8c, 0x00000000}, -+ {0x8f90, 0x00000000}, -+ {0x8f94, 0x00000000}, -+ {0x8f98, 0x00000000}, -+ {0x8f9c, 0x00000000}, -+ {0x8fa0, 0x00000000}, -+ {0x8fa4, 0x00000000}, -+ {0x8fa8, 0x00000000}, -+ {0x8fac, 0x00000000}, -+ {0x8fb0, 0x00000000}, -+ {0x8fb4, 0x00000000}, -+ {0x8fb8, 0x00000000}, -+ {0x8fbc, 0x00000000}, -+ {0x8fc0, 0x00000000}, -+ {0x8fc4, 0x00000000}, -+ {0x8fc8, 0x00000000}, -+ {0x8fcc, 0x00000000}, -+ {0x8fd0, 0x00000000}, -+ {0x8fd4, 0x00000000}, -+ {0x8fd8, 0x00000000}, -+ {0x8fdc, 0x00000000}, -+ {0x8fe0, 0x00000000}, -+ {0x8fe4, 0x00000000}, -+ {0x8fe8, 0x00000000}, -+ {0x8fec, 0x00000000}, -+ {0x8ff0, 0x00000000}, -+ {0x8ff4, 0x00000000}, -+ {0x8ff8, 0x00000000}, -+ {0x8ffc, 0x00000000}, -+ {0x9000, 0x00000000}, -+ {0x9004, 0x00000000}, -+ {0x9008, 0x00000000}, -+ {0x900c, 0x00000000}, -+ {0x9010, 0x00000000}, -+ {0x9014, 0x00000000}, -+ {0x9018, 0x00000000}, -+ {0x901c, 0x00000000}, -+ {0x9020, 0x00000000}, -+ {0x9024, 0x00000000}, -+ {0x9028, 0x00000000}, -+ {0x902c, 0x00000000}, -+ {0x9030, 0x00000000}, -+ {0x9034, 0x00000000}, -+ {0x9038, 0x00000000}, -+ {0x903c, 0x00000000}, -+ {0x9040, 0x00000000}, -+ {0x9044, 0x00000000}, -+ {0x9048, 0x00000000}, -+ {0x904c, 0x00000000}, -+ {0x9050, 0x00000000}, -+ {0x9054, 0x00000000}, -+ {0x9058, 0x00000000}, -+ {0x905c, 0x00000000}, -+ {0x9060, 0x00000000}, -+ {0x9064, 0x00000000}, -+ {0x9068, 0x00000000}, -+ {0x906c, 0x00000000}, -+ {0x9070, 0x00000000}, -+ {0x9074, 0x00000000}, -+ {0x9078, 0x00000000}, -+ {0x907c, 0x00000000}, -+ {0x9080, 0x00000000}, -+ {0x9084, 0x00000000}, -+ {0x9088, 0x00000000}, -+ {0x908c, 0x00000000}, -+ {0x9090, 0x00000000}, -+ {0x9094, 0x00000000}, -+ {0x9098, 0x00000000}, -+ {0x909c, 0x00000000}, -+ {0x90a0, 0x00000000}, -+ {0x90a4, 0x00000000}, -+ {0x90a8, 0x00000000}, -+ {0x90ac, 0x00000000}, -+ {0x90b0, 0x00000000}, -+ {0x90b4, 0x00000000}, -+ {0x90b8, 0x00000000}, -+ {0x90bc, 0x00000000}, -+ {0x9100, 0x00000000}, -+ {0x9104, 0x00000000}, -+ {0x9108, 0x00000000}, -+ {0x910c, 0x00000000}, -+ {0x9110, 0x00000000}, -+ {0x9114, 0x00000000}, -+ {0x9118, 0x00000000}, -+ {0x911c, 0x00000000}, -+ {0x9120, 0x00000000}, -+ {0x9124, 0x00000000}, -+ {0x9128, 0x00000000}, -+ {0x912c, 0x00000000}, -+ {0x9130, 0x00000000}, -+ {0x9134, 0x00000000}, -+ {0x9138, 0x00000000}, -+ {0x913c, 0x00000000}, -+ {0x9140, 0x00000000}, -+ {0x9144, 0x00000000}, -+ {0x9148, 0x00000000}, -+ {0x914c, 0x00000000}, -+ {0x9150, 0x00000000}, -+ {0x9154, 0x00000000}, -+ {0x9158, 0x00000000}, -+ {0x915c, 0x00000000}, -+ {0x9160, 0x00000000}, -+ {0x9164, 0x00000000}, -+ {0x9168, 0x00000000}, -+ {0x916c, 0x00000000}, -+ {0x9170, 0x00000000}, -+ {0x9174, 0x00000000}, -+ {0x9178, 0x00000000}, -+ {0x917c, 0x00000000}, -+ {0x9180, 0x00000000}, -+ {0x9184, 0x00000000}, -+ {0x9188, 0x00000000}, -+ {0x918c, 0x00000000}, -+ {0x9190, 0x00000000}, -+ {0x9194, 0x00000000}, -+ {0x9198, 0x00000000}, -+ {0x919c, 0x00000000}, -+ {0x91a0, 0x00000000}, -+ {0x91a4, 0x00000000}, -+ {0x91a8, 0x00000000}, -+ {0x91ac, 0x00000000}, -+ {0x91b0, 0x00000000}, -+ {0x91b4, 0x00000000}, -+ {0x91b8, 0x00000000}, -+ {0x91bc, 0x00000000}, -+ {0x91c0, 0x00000000}, -+ {0x91c4, 0x00000000}, -+ {0x91c8, 0x00000000}, -+ {0x91cc, 0x00000000}, -+ {0x91d0, 0x00000000}, -+ {0x91d4, 0x00000000}, -+ {0x91d8, 0x00000000}, -+ {0x91dc, 0x00000000}, -+ {0x91e0, 0x00000000}, -+ {0x91e4, 0x00000000}, -+ {0x91e8, 0x00000000}, -+ {0x91ec, 0x00000000}, -+ {0x91f0, 0x00000000}, -+ {0x91f4, 0x00000000}, -+ {0x91f8, 0x00000000}, -+ {0x91fc, 0x00000000}, -+ {0x9200, 0x00000000}, -+ {0x9204, 0x00000000}, -+ {0x9208, 0x00000000}, -+ {0x920c, 0x00000000}, -+ {0x9210, 0x00000000}, -+ {0x9214, 0x00000000}, -+ {0x9218, 0x00000000}, -+ {0x921c, 0x00000000}, -+ {0x9220, 0x00000000}, -+ {0x9224, 0x00000000}, -+ {0x9228, 0x00000000}, -+ {0x922c, 0x00000000}, -+ {0x9230, 0x00000000}, -+ {0x9234, 0x00000000}, -+ {0x9238, 0x00000000}, -+ {0x923c, 0x00000000}, -+ {0x9240, 0x00000000}, -+ {0x9244, 0x00000000}, -+ {0x9248, 0x00000000}, -+ {0x924c, 0x00000000}, -+ {0x9250, 0x00000000}, -+ {0x9254, 0x00000000}, -+ {0x9258, 0x00000000}, -+ {0x925c, 0x00000000}, -+ {0x9260, 0x00000000}, -+ {0x9264, 0x00000000}, -+ {0x9268, 0x00000000}, -+ {0x926c, 0x00000000}, -+ {0x9270, 0x00000000}, -+ {0x9274, 0x00000000}, -+ {0x9278, 0x00000000}, -+ {0x927c, 0x00000000}, -+ {0x9280, 0x00000000}, -+ {0x9284, 0x00000000}, -+ {0x9288, 0x00000000}, -+ {0x928c, 0x00000000}, -+ {0x9290, 0x00000000}, -+ {0x9294, 0x00000000}, -+ {0x9298, 0x00000000}, -+ {0x929c, 0x00000000}, -+ {0x92a0, 0x00000000}, -+ {0x92a4, 0x00000000}, -+ {0x92a8, 0x00000000}, -+ {0x92ac, 0x00000000}, -+ {0x92b0, 0x00000000}, -+ {0x92b4, 0x00000000}, -+ {0x92b8, 0x00000000}, -+ {0x92bc, 0x00000000}, -+ {0x92c0, 0x00000000}, -+ {0x92c4, 0x00000000}, -+ {0x92c8, 0x00000000}, -+ {0x92cc, 0x00000000}, -+ {0x92d0, 0x00000000}, -+ {0x92d4, 0x00000000}, -+ {0x92d8, 0x00000000}, -+ {0x92dc, 0x00000000}, -+ {0x92e0, 0x00000000}, -+ {0x92e4, 0x00000000}, -+ {0x92e8, 0x00000000}, -+ {0x92ec, 0x00000000}, -+ {0x92f0, 0x00000000}, -+ {0x92f4, 0x00000000}, -+ {0x92f8, 0x00000000}, -+ {0x92fc, 0x00000000}, -+ {0x9300, 0x00000000}, -+ {0x9304, 0x00000000}, -+ {0x9308, 0x00000000}, -+ {0x930c, 0x00000000}, -+ {0x9310, 0x00000000}, -+ {0x9314, 0x00000000}, -+ {0x9318, 0x00000000}, -+ {0x931c, 0x00000000}, -+ {0x9320, 0x00000000}, -+ {0x9324, 0x00000000}, -+ {0x9328, 0x00000000}, -+ {0x932c, 0x00000000}, -+ {0x9330, 0x00000000}, -+ {0x9334, 0x00000000}, -+ {0x9338, 0x00000000}, -+ {0x933c, 0x00000000}, -+ {0x9340, 0x00000000}, -+ {0x9344, 0x00000000}, -+ {0x9348, 0x00000000}, -+ {0x934c, 0x00000000}, -+ {0x9350, 0x00000000}, -+ {0x9354, 0x00000000}, -+ {0x9358, 0x00000000}, -+ {0x935c, 0x00000000}, -+ {0x9360, 0x00000000}, -+ {0x9364, 0x00000000}, -+ {0x9368, 0x00000000}, -+ {0x936c, 0x00000000}, -+ {0x9370, 0x00000000}, -+ {0x9374, 0x00000000}, -+ {0x9378, 0x00000000}, -+ {0x937c, 0x00000000}, -+ {0x9380, 0x00000000}, -+ {0x9384, 0x00000000}, -+ {0x9388, 0x00000000}, -+ {0x938c, 0x00000000}, -+ {0x9390, 0x00000000}, -+ {0x9394, 0x00000000}, -+ {0x9398, 0x00000000}, -+ {0x939c, 0x00000000}, -+ {0x93a0, 0x00000000}, -+ {0x93a4, 0x00000000}, -+ {0x93a8, 0x00000000}, -+ {0x93ac, 0x00000000}, -+ {0x93b0, 0x00000000}, -+ {0x93b4, 0x00000000}, -+ {0x93b8, 0x00000000}, -+ {0x93bc, 0x00000000}, -+ {0x93c0, 0x00000000}, -+ {0x93c4, 0x00000000}, -+ {0x93c8, 0x00000000}, -+ {0x93cc, 0x00000000}, -+ {0x93d0, 0x00000000}, -+ {0x93d4, 0x00000000}, -+ {0x93d8, 0x00000000}, -+ {0x93dc, 0x00000000}, -+ {0x93e0, 0x00000000}, -+ {0x93e4, 0x00000000}, -+ {0x93e8, 0x00000000}, -+ {0x93ec, 0x00000000}, -+ {0x93f0, 0x00000000}, -+ {0x93f4, 0x00000000}, -+ {0x93f8, 0x00000000}, -+ {0x93fc, 0x00000000}, -+ {0x9400, 0x00000000}, -+ {0x9404, 0x00000000}, -+ {0x9408, 0x00000000}, -+ {0x940c, 0x00000000}, -+ {0x9410, 0x00000000}, -+ {0x9414, 0x00000000}, -+ {0x9418, 0x00000000}, -+ {0x941c, 0x00000000}, -+ {0x9420, 0x00000000}, -+ {0x9424, 0x00000000}, -+ {0x9428, 0x00000000}, -+ {0x942c, 0x00000000}, -+ {0x9430, 0x00000000}, -+ {0x9434, 0x00000000}, -+ {0x9438, 0x00000000}, -+ {0x943c, 0x00000000}, -+ {0x9440, 0x00000000}, -+ {0x9444, 0x00000000}, -+ {0x9448, 0x00000000}, -+ {0x944c, 0x00000000}, -+ {0x9450, 0x00000000}, -+ {0x9454, 0x00000000}, -+ {0x9458, 0x00000000}, -+ {0x945c, 0x00000000}, -+ {0x9460, 0x00000000}, -+ {0x9464, 0x00000000}, -+ {0x9468, 0x00000000}, -+ {0x946c, 0x00000000}, -+ {0x9470, 0x00000000}, -+ {0x9474, 0x00000000}, -+ {0x9478, 0x00000000}, -+ {0x947c, 0x00000000}, -+ {0x9480, 0x00000000}, -+ {0x9484, 0x00000000}, -+ {0x9488, 0x00000000}, -+ {0x948c, 0x00000000}, -+ {0x9490, 0x00000000}, -+ {0x9494, 0x00000000}, -+ {0x9498, 0x00000000}, -+ {0x949c, 0x00000000}, -+ {0x94a0, 0x00000000}, -+ {0x94a4, 0x00000000}, -+ {0x94a8, 0x00000000}, -+ {0x94ac, 0x00000000}, -+ {0x94b0, 0x00000000}, -+ {0x94b4, 0x00000000}, -+ {0x94b8, 0x00000000}, -+ {0x94bc, 0x00000000}, -+ {0xa220, 0x00000000}, -+ {0xa224, 0x00000000}, -+ {0xa228, 0x00000000}, -+ {0xa22c, 0x00000000}, -+ {0xa230, 0x00000000}, -+ {0xa234, 0x00000000}, -+ {0xa238, 0x00000000}, -+ {0xa23c, 0x00000000}, -+ {0xa240, 0x00000000}, -+ {0xa244, 0x00000000}, -+ {0xa248, 0x00000000}, -+ {0xa24c, 0x00000000}, -+ {0xa250, 0x00000000}, -+ {0xa254, 0x00000000}, -+ {0xa258, 0x00000000}, -+ {0xa25c, 0x00000000}, -+ {0xa260, 0x00000000}, -+ {0xa264, 0x00000000}, -+ {0xa268, 0x00000000}, -+ {0xa26c, 0x00000000}, -+ {0xa270, 0x00000000}, -+ {0xa274, 0x00000000}, -+ {0xa278, 0x00000000}, -+ {0xa27c, 0x00000000}, -+ {0xa280, 0x00000000}, -+ {0xa284, 0x00000000}, -+ {0xa288, 0x00000000}, -+ {0xa28c, 0x00000000}, -+ {0xa290, 0x00000000}, -+ {0xa294, 0x00000000}, -+ {0xa298, 0x00000000}, -+ {0xa29c, 0x00000000}, -+ {0xa2a0, 0x00000000}, -+ {0xa2a4, 0x00000000}, -+ {0xa2a8, 0x00000000}, -+ {0xa2ac, 0x00000000}, -+ {0xa2b0, 0x00000000}, -+ {0xa2b4, 0x00000000}, -+ {0xa2b8, 0x00000000}, -+ {0xa2bc, 0x00000000}, -+ {0xa2c0, 0x00000000}, -+ {0xa2c4, 0x00000000}, -+ {0xa2c8, 0x00000000}, -+ {0xa2cc, 0x00000000}, -+ {0xa2d0, 0x00000000}, -+ {0xa2d4, 0x00000000}, -+ {0xa2d8, 0x00000000}, -+ {0xa2dc, 0x00000000}, -+ {0xa2e0, 0x00000000}, -+ {0xa2e4, 0x00000000}, -+ {0xa2e8, 0x00000000}, -+ {0xa2ec, 0x00000000}, -+ {0xa2f0, 0x00000000}, -+ {0xa2f4, 0x00000000}, -+ {0xa2f8, 0x00000000}, -+ {0xa2fc, 0x00000000}, -+ {0xa300, 0x00000000}, -+ {0xa304, 0x00000000}, -+ {0xa308, 0x00000000}, -+ {0xa30c, 0x00000000}, -+ {0xa310, 0x00000000}, -+ {0xa314, 0x00000000}, -+ {0xa318, 0x00000000}, -+ {0xa31c, 0x00000000}, -+ {0xa320, 0x00000000}, -+ {0xa324, 0x00000000}, -+ {0xa328, 0x00000000}, -+ {0xa32c, 0x00000000}, -+ {0xa330, 0x00000000}, -+ {0xa334, 0x00000000}, -+ {0xa338, 0x00000000}, -+ {0xa33c, 0x00000000}, -+ {0xa340, 0x00000000}, -+ {0xa344, 0x00000000}, -+ {0xa348, 0x00000000}, -+ {0xa34c, 0x00000000}, -+ {0xa350, 0x00000000}, -+ {0xa354, 0x00000000}, -+ {0xa358, 0x00000000}, -+ {0xa35c, 0x00000000}, -+ {0xa360, 0x00000000}, -+ {0xa364, 0x00000000}, -+ {0xa368, 0x00000000}, -+ {0xa36c, 0x00000000}, -+ {0xa370, 0x00000000}, -+ {0xa374, 0x00000000}, -+ {0xa378, 0x00000000}, -+ {0xa37c, 0x00000000}, -+ {0xa380, 0x00000000}, -+ {0xa384, 0x00000000}, -+ {0xa388, 0x00000000}, -+ {0xa38c, 0x00000000}, -+ {0xa390, 0x00000000}, -+ {0xa394, 0x00000000}, -+ {0xa398, 0x00000000}, -+ {0xa39c, 0x00000000}, -+ {0xa3a0, 0x00000000}, -+ {0xa3a4, 0x00000000}, -+ {0xa3a8, 0x00000000}, -+ {0xa3ac, 0x00000000}, -+ {0xa3b0, 0x00000000}, -+ {0xa3b4, 0x00000000}, -+ {0xa3b8, 0x00000000}, -+ {0xa3bc, 0x00000000}, -+ {0xa620, 0x00000000}, -+ {0xa624, 0x00000000}, -+ {0xa628, 0x00000000}, -+ {0xa62c, 0x00000000}, -+ {0xa630, 0x00000000}, -+ {0xa634, 0x00000000}, -+ {0xa638, 0x00000000}, -+ {0xa63c, 0x00000000}, -+ {0xa640, 0x00000000}, -+ {0xa644, 0x00000000}, -+ {0xa648, 0x00000000}, -+ {0xa64c, 0x00000000}, -+ {0xa650, 0x00000000}, -+ {0xa654, 0x00000000}, -+ {0xa658, 0x00000000}, -+ {0xa65c, 0x00000000}, -+ {0xa660, 0x00000000}, -+ {0xa664, 0x00000000}, -+ {0xa668, 0x00000000}, -+ {0xa66c, 0x00000000}, -+ {0xa670, 0x00000000}, -+ {0xa674, 0x00000000}, -+ {0xa678, 0x00000000}, -+ {0xa67c, 0x00000000}, -+ {0xa680, 0x00000000}, -+ {0xa684, 0x00000000}, -+ {0xa688, 0x00000000}, -+ {0xa68c, 0x00000000}, -+ {0xa690, 0x00000000}, -+ {0xa694, 0x00000000}, -+ {0xa698, 0x00000000}, -+ {0xa69c, 0x00000000}, -+ {0xa6a0, 0x00000000}, -+ {0xa6a4, 0x00000000}, -+ {0xa6a8, 0x00000000}, -+ {0xa6ac, 0x00000000}, -+ {0xa6b0, 0x00000000}, -+ {0xa6b4, 0x00000000}, -+ {0xa6b8, 0x00000000}, -+ {0xa6bc, 0x00000000}, -+ {0xa6c0, 0x00000000}, -+ {0xa6c4, 0x00000000}, -+ {0xa6c8, 0x00000000}, -+ {0xa6cc, 0x00000000}, -+ {0xa6d0, 0x00000000}, -+ {0xa6d4, 0x00000000}, -+ {0xa6d8, 0x00000000}, -+ {0xa6dc, 0x00000000}, -+ {0xa6e0, 0x00000000}, -+ {0xa6e4, 0x00000000}, -+ {0xa6e8, 0x00000000}, -+ {0xa6ec, 0x00000000}, -+ {0xa6f0, 0x00000000}, -+ {0xa6f4, 0x00000000}, -+ {0xa6f8, 0x00000000}, -+ {0xa6fc, 0x00000000}, -+ {0xa700, 0x00000000}, -+ {0xa704, 0x00000000}, -+ {0xa708, 0x00000000}, -+ {0xa70c, 0x00000000}, -+ {0xa710, 0x00000000}, -+ {0xa714, 0x00000000}, -+ {0xa718, 0x00000000}, -+ {0xa71c, 0x00000000}, -+ {0xa720, 0x00000000}, -+ {0xa724, 0x00000000}, -+ {0xa728, 0x00000000}, -+ {0xa72c, 0x00000000}, -+ {0xa730, 0x00000000}, -+ {0xa734, 0x00000000}, -+ {0xa738, 0x00000000}, -+ {0xa73c, 0x00000000}, -+ {0xa740, 0x00000000}, -+ {0xa744, 0x00000000}, -+ {0xa748, 0x00000000}, -+ {0xa74c, 0x00000000}, -+ {0xa750, 0x00000000}, -+ {0xa754, 0x00000000}, -+ {0xa758, 0x00000000}, -+ {0xa75c, 0x00000000}, -+ {0xa760, 0x00000000}, -+ {0xa764, 0x00000000}, -+ {0xa768, 0x00000000}, -+ {0xa76c, 0x00000000}, -+ {0xa770, 0x00000000}, -+ {0xa774, 0x00000000}, -+ {0xa778, 0x00000000}, -+ {0xa77c, 0x00000000}, -+ {0xa780, 0x00000000}, -+ {0xa784, 0x00000000}, -+ {0xa788, 0x00000000}, -+ {0xa78c, 0x00000000}, -+ {0xa790, 0x00000000}, -+ {0xa794, 0x00000000}, -+ {0xa798, 0x00000000}, -+ {0xa79c, 0x00000000}, -+ {0xa7a0, 0x00000000}, -+ {0xa7a4, 0x00000000}, -+ {0xa7a8, 0x00000000}, -+ {0xa7ac, 0x00000000}, -+ {0xa7b0, 0x00000000}, -+ {0xa7b4, 0x00000000}, -+ {0xa7b8, 0x00000000}, -+ {0xa7bc, 0x00000000}, -+ {0x81d8, 0x00000000}, -+ {0x82d8, 0x00000000}, -+ {0x9f04, 0x2b251f19}, -+ {0x9f08, 0x433d3731}, -+ {0x9f0c, 0x5b554f49}, -+ {0x9f10, 0x736d6761}, -+ {0x9f14, 0x7f7f7f79}, -+ {0x9f18, 0x120f7f7f}, -+ {0x9f1c, 0x1e1b1815}, -+ {0x9f20, 0x2a272421}, -+ {0x9f24, 0x3633302d}, -+ {0x9f28, 0x3f3f3c39}, -+ {0x9f2c, 0x3f3f3f3f}, -+ {0x8008, 0x00000080}, -+ {0x8088, 0x807f030a}, -+ {0x80c8, 0x708f0bf1}, -+ {0x80c8, 0x708e0aa5}, -+ {0x80c8, 0x708d097d}, -+ {0x80c8, 0x708c0875}, -+ {0x80c8, 0x708b0789}, -+ {0x80c8, 0x708a06b7}, -+ {0x80c8, 0x708905fc}, -+ {0x80c8, 0x70880556}, -+ {0x80c8, 0x708704c1}, -+ {0x80c8, 0x7086043d}, -+ {0x80c8, 0x708503c7}, -+ {0x80c8, 0x7084035e}, -+ {0x80c8, 0x708302ac}, -+ {0x80c8, 0x70820262}, -+ {0x80c8, 0x70810220}, -+ {0x80c8, 0x70800000}, -+ {0x80c8, 0x7090011f}, -+ {0x80c8, 0x7010011f}, -+ {0x8088, 0x80000000}, -+ {0x8008, 0x00000000}, -+ {0x8088, 0x00000110}, -+ {0x8000, 0x00000008}, -+ {0x8080, 0x00000005}, -+ {0x8500, 0x80000008}, -+ {0x8504, 0x43000004}, -+ {0x8508, 0x4b044a00}, -+ {0x850c, 0x40098604}, -+ {0x8510, 0x0004e020}, -+ {0x8514, 0x87044b05}, -+ {0x8518, 0xe020400b}, -+ {0x851c, 0x4b000004}, -+ {0x8520, 0x21e07410}, -+ {0x8524, 0x74300000}, -+ {0x8528, 0x43800004}, -+ {0x852c, 0x4c000007}, -+ {0x8530, 0x43000004}, -+ {0x8534, 0x42fe5700}, -+ {0x8538, 0x42004000}, -+ {0x853c, 0x30005055}, -+ {0x8540, 0xa50fb41a}, -+ {0x8544, 0xf11ce3c7}, -+ {0x8548, 0xf31cf21c}, -+ {0x854c, 0xf61cf41c}, -+ {0x8550, 0xf91cf81c}, -+ {0x8554, 0xfb1cfa1c}, -+ {0x8558, 0xfd1cfc1c}, -+ {0x855c, 0xff1cfe1c}, -+ {0x8560, 0xf11cf01c}, -+ {0x8564, 0xf31cf21c}, -+ {0x8568, 0xf51cf41c}, -+ {0x856c, 0xf71cf61c}, -+ {0x8570, 0xf91cf81c}, -+ {0x8574, 0xe3c7a504}, -+ {0x8578, 0xf11af01a}, -+ {0x857c, 0x30580001}, -+ {0x8580, 0x30b030c9}, -+ {0x8584, 0x30ff30fc}, -+ {0x8588, 0x310f3102}, -+ {0x858c, 0x3148311c}, -+ {0x8590, 0x31603158}, -+ {0x8594, 0x30c7320e}, -+ {0x8598, 0x32293225}, -+ {0x859c, 0x32433242}, -+ {0x85a0, 0x3286327a}, -+ {0x85a4, 0x329d328a}, -+ {0x85a8, 0x32aa32a8}, -+ {0x85ac, 0x320331c5}, -+ {0x85b0, 0x7410e2c1}, -+ {0x85b4, 0x020020a8}, -+ {0x85b8, 0x2098140f}, -+ {0x85bc, 0x140f0200}, -+ {0x85c0, 0x02002088}, -+ {0x85c4, 0x7430140f}, -+ {0x85c8, 0x5b10e31c}, -+ {0x85cc, 0x20a87410}, -+ {0x85d0, 0x140f0201}, -+ {0x85d4, 0x00002080}, -+ {0x85d8, 0x5507140f}, -+ {0x85dc, 0x5c065661}, -+ {0x85e0, 0x7410e308}, -+ {0x85e4, 0x02002088}, -+ {0x85e8, 0x5517140f}, -+ {0x85ec, 0x7410e308}, -+ {0x85f0, 0x020020a8}, -+ {0x85f4, 0x5517140f}, -+ {0x85f8, 0x5c025641}, -+ {0x85fc, 0x7410e308}, -+ {0x8600, 0x00002080}, -+ {0x8604, 0x1407140f}, -+ {0x8608, 0xe3085507}, -+ {0x860c, 0x7508e2b4}, -+ {0x8610, 0xe312468e}, -+ {0x8614, 0x5b10e0f4}, -+ {0x8618, 0x20a87410}, -+ {0x861c, 0x140f0201}, -+ {0x8620, 0x00002090}, -+ {0x8624, 0x5507140f}, -+ {0x8628, 0x5c065661}, -+ {0x862c, 0x7410e308}, -+ {0x8630, 0x02002098}, -+ {0x8634, 0x5517140f}, -+ {0x8638, 0x7410e308}, -+ {0x863c, 0x020020a8}, -+ {0x8640, 0x5517140f}, -+ {0x8644, 0x5c025641}, -+ {0x8648, 0x7410e308}, -+ {0x864c, 0x00002090}, -+ {0x8650, 0x5507140f}, -+ {0x8654, 0x7509e308}, -+ {0x8658, 0xe3124696}, -+ {0x865c, 0x0001e0f4}, -+ {0x8660, 0x74105b10}, -+ {0x8664, 0x000020a0}, -+ {0x8668, 0x5507140f}, -+ {0x866c, 0xe3085601}, -+ {0x8670, 0x20a87410}, -+ {0x8674, 0x140f0200}, -+ {0x8678, 0xe3085517}, -+ {0x867c, 0x750ae2b4}, -+ {0x8680, 0xe3124686}, -+ {0x8684, 0x5500e0f4}, -+ {0x8688, 0x5501e304}, -+ {0x868c, 0xe2c10001}, -+ {0x8690, 0x5b10e31c}, -+ {0x8694, 0x20807410}, -+ {0x8698, 0x140f0000}, -+ {0x869c, 0x02002098}, -+ {0x86a0, 0xf204140f}, -+ {0x86a4, 0x020020a8}, -+ {0x86a8, 0x5507140f}, -+ {0x86ac, 0xe3085601}, -+ {0x86b0, 0x20887410}, -+ {0x86b4, 0x140f0200}, -+ {0x86b8, 0xe3085517}, -+ {0x86bc, 0x7508e2b4}, -+ {0x86c0, 0xe312468e}, -+ {0x86c4, 0x7410e0f4}, -+ {0x86c8, 0x00002090}, -+ {0x86cc, 0x5507140f}, -+ {0x86d0, 0x7410e308}, -+ {0x86d4, 0x02002098}, -+ {0x86d8, 0x5517140f}, -+ {0x86dc, 0x7509e308}, -+ {0x86e0, 0xe3124696}, -+ {0x86e4, 0x0001e0f4}, -+ {0x86e8, 0x74207900}, -+ {0x86ec, 0x57005710}, -+ {0x86f0, 0x9700140f}, -+ {0x86f4, 0x00017430}, -+ {0x86f8, 0xe31ce2c1}, -+ {0x86fc, 0xe2ca0001}, -+ {0x8700, 0x0001e34b}, -+ {0x8704, 0x312ae2c1}, -+ {0x8708, 0xe3ba0023}, -+ {0x870c, 0x54ed0002}, -+ {0x8710, 0x00230baa}, -+ {0x8714, 0x0002e3ba}, -+ {0x8718, 0xe2b9e367}, -+ {0x871c, 0xe2c10001}, -+ {0x8720, 0x00223125}, -+ {0x8724, 0x0002e3ba}, -+ {0x8728, 0x0baa54ec}, -+ {0x872c, 0xe3ba0022}, -+ {0x8730, 0xe3670002}, -+ {0x8734, 0x0001e2b9}, -+ {0x8738, 0x0baae2c1}, -+ {0x873c, 0x6d0f6c67}, -+ {0x8740, 0xe3bae31c}, -+ {0x8744, 0xe31c6c8b}, -+ {0x8748, 0x0bace3ba}, -+ {0x874c, 0x6d0f6cb3}, -+ {0x8750, 0xe3bae31c}, -+ {0x8754, 0x6cdb0bad}, -+ {0x8758, 0xe31c6d0f}, -+ {0x875c, 0x6cf7e3ba}, -+ {0x8760, 0xe31c6d0f}, -+ {0x8764, 0x6c09e3ba}, -+ {0x8768, 0xe31c6d00}, -+ {0x876c, 0x6c25e3ba}, -+ {0x8770, 0xe3bae31c}, -+ {0x8774, 0x6c4df8ca}, -+ {0x8778, 0xe3bae31c}, -+ {0x877c, 0x6c75f9d3}, -+ {0x8780, 0xe3bae31c}, -+ {0x8784, 0xe31c6c99}, -+ {0x8788, 0xe367e3ba}, -+ {0x878c, 0x0001e2b9}, -+ {0x8790, 0x4380e2ca}, -+ {0x8794, 0x43006344}, -+ {0x8798, 0x00223188}, -+ {0x879c, 0x0002e3bf}, -+ {0x87a0, 0x0baa54ec}, -+ {0x87a4, 0xe3bf0022}, -+ {0x87a8, 0xe3670002}, -+ {0x87ac, 0x0001e2c5}, -+ {0x87b0, 0x4380e2ca}, -+ {0x87b4, 0x43006344}, -+ {0x87b8, 0xe367317b}, -+ {0x87bc, 0x0001e2c5}, -+ {0x87c0, 0x4380e2ca}, -+ {0x87c4, 0x4300634d}, -+ {0x87c8, 0x74100ba6}, -+ {0x87cc, 0x000921e8}, -+ {0x87d0, 0x6f0f6e67}, -+ {0x87d4, 0xe3bfe34b}, -+ {0x87d8, 0x000a21e8}, -+ {0x87dc, 0xe34b6e77}, -+ {0x87e0, 0x21e8e3bf}, -+ {0x87e4, 0x6e8b000b}, -+ {0x87e8, 0xe3bfe34b}, -+ {0x87ec, 0x000c21e8}, -+ {0x87f0, 0xe34b6e9f}, -+ {0x87f4, 0x0baae3bf}, -+ {0x87f8, 0x21e87410}, -+ {0x87fc, 0x6eb3000d}, -+ {0x8800, 0xe34b6f0f}, -+ {0x8804, 0x21e8e3bf}, -+ {0x8808, 0x6ec7000e}, -+ {0x880c, 0xe3bfe34b}, -+ {0x8810, 0x74100bac}, -+ {0x8814, 0x000f21e8}, -+ {0x8818, 0x6f0f6edb}, -+ {0x881c, 0xe3bfe34b}, -+ {0x8820, 0x001021e8}, -+ {0x8824, 0xe34b6eef}, -+ {0x8828, 0xe3bfe3bf}, -+ {0x882c, 0x001321e8}, -+ {0x8830, 0x6f006e11}, -+ {0x8834, 0xe3bfe34b}, -+ {0x8838, 0x21e8e3bf}, -+ {0x883c, 0x6e250014}, -+ {0x8840, 0xe3bfe34b}, -+ {0x8844, 0x21e8fbab}, -+ {0x8848, 0x6e390015}, -+ {0x884c, 0xe3bfe34b}, -+ {0x8850, 0x001621e8}, -+ {0x8854, 0xe34b6e4d}, -+ {0x8858, 0xfcb0e3bf}, -+ {0x885c, 0x001721e8}, -+ {0x8860, 0xe34b6e61}, -+ {0x8864, 0x21e8e3bf}, -+ {0x8868, 0x6e750018}, -+ {0x886c, 0xe3bfe34b}, -+ {0x8870, 0x001921e8}, -+ {0x8874, 0xe34b6e89}, -+ {0x8878, 0x21e8e3bf}, -+ {0x887c, 0x6e99001a}, -+ {0x8880, 0xe3bfe34b}, -+ {0x8884, 0xe2c5e367}, -+ {0x8888, 0x00040001}, -+ {0x888c, 0x42fc0004}, -+ {0x8890, 0x60010007}, -+ {0x8894, 0x42000004}, -+ {0x8898, 0x62200007}, -+ {0x889c, 0x00046200}, -+ {0x88a0, 0x5b005501}, -+ {0x88a4, 0x5b40e304}, -+ {0x88a8, 0x00076605}, -+ {0x88ac, 0x63006200}, -+ {0x88b0, 0x0004e388}, -+ {0x88b4, 0x0a010900}, -+ {0x88b8, 0x0d000b40}, -+ {0x88bc, 0x00320e01}, -+ {0x88c0, 0x95090004}, -+ {0x88c4, 0x790442fb}, -+ {0x88c8, 0x43804200}, -+ {0x88cc, 0x4d010007}, -+ {0x88d0, 0x43000004}, -+ {0x88d4, 0x05620007}, -+ {0x88d8, 0x961d05a3}, -+ {0x88dc, 0x0004e388}, -+ {0x88e0, 0x0007e304}, -+ {0x88e4, 0x07a306a2}, -+ {0x88e8, 0x0004e388}, -+ {0x88ec, 0xe378e304}, -+ {0x88f0, 0xe3800002}, -+ {0x88f4, 0x00074380}, -+ {0x88f8, 0x00044d00}, -+ {0x88fc, 0x42fe4300}, -+ {0x8900, 0x42007900}, -+ {0x8904, 0x00040001}, -+ {0x8908, 0x000742fc}, -+ {0x890c, 0x00046003}, -+ {0x8910, 0x31cc4200}, -+ {0x8914, 0x06a20007}, -+ {0x8918, 0x31f807a3}, -+ {0x891c, 0x77000005}, -+ {0x8920, 0x52000007}, -+ {0x8924, 0x42fe0004}, -+ {0x8928, 0x60000007}, -+ {0x892c, 0x42000004}, -+ {0x8930, 0x60004380}, -+ {0x8934, 0x62016100}, -+ {0x8938, 0x00056310}, -+ {0x893c, 0x55004100}, -+ {0x8940, 0x5c020007}, -+ {0x8944, 0x43000004}, -+ {0x8948, 0xe2d70001}, -+ {0x894c, 0x73000005}, -+ {0x8950, 0xe2d70001}, -+ {0x8954, 0x5d000006}, -+ {0x8958, 0x42f70004}, -+ {0x895c, 0x6c000005}, -+ {0x8960, 0x42000004}, -+ {0x8964, 0x0004e2de}, -+ {0x8968, 0x00074380}, -+ {0x896c, 0x4a004e00}, -+ {0x8970, 0x00064c00}, -+ {0x8974, 0x60007f00}, -+ {0x8978, 0x00046f00}, -+ {0x897c, 0x00054300}, -+ {0x8980, 0x00017300}, -+ {0x8984, 0xe2d70001}, -+ {0x8988, 0x5d010006}, -+ {0x898c, 0x61006002}, -+ {0x8990, 0x00055601}, -+ {0x8994, 0xe2e27710}, -+ {0x8998, 0x73000005}, -+ {0x899c, 0x43800004}, -+ {0x89a0, 0x5e010007}, -+ {0x89a4, 0x4d205e00}, -+ {0x89a8, 0x4a084e20}, -+ {0x89ac, 0x4c3f4960}, -+ {0x89b0, 0x00064301}, -+ {0x89b4, 0x63807f01}, -+ {0x89b8, 0x00046010}, -+ {0x89bc, 0x00064300}, -+ {0x89c0, 0x00077402}, -+ {0x89c4, 0x40004001}, -+ {0x89c8, 0x0006ab00}, -+ {0x89cc, 0x00077404}, -+ {0x89d0, 0x40004001}, -+ {0x89d4, 0x0004ab00}, -+ {0x89d8, 0x00074380}, -+ {0x89dc, 0x4e004d00}, -+ {0x89e0, 0x4c004a00}, -+ {0x89e4, 0x00064300}, -+ {0x89e8, 0x63007f00}, -+ {0x89ec, 0x00046000}, -+ {0x89f0, 0x00014300}, -+ {0x89f4, 0x73800005}, -+ {0x89f8, 0x42fe0004}, -+ {0x89fc, 0x6c010005}, -+ {0x8a00, 0x000514c8}, -+ {0x8a04, 0x00046c00}, -+ {0x8a08, 0x00014200}, -+ {0x8a0c, 0x0005e2ce}, -+ {0x8a10, 0x00017300}, -+ {0x8a14, 0x00040006}, -+ {0x8a18, 0x42fa4380}, -+ {0x8a1c, 0x42007c05}, -+ {0x8a20, 0x7c5b0006}, -+ {0x8a24, 0x7e5b7d5b}, -+ {0x8a28, 0x00077f00}, -+ {0x8a2c, 0x415b405b}, -+ {0x8a30, 0x4300425b}, -+ {0x8a34, 0x43000004}, -+ {0x8a38, 0x00040001}, -+ {0x8a3c, 0x60004380}, -+ {0x8a40, 0x62016100}, -+ {0x8a44, 0x42fa6310}, -+ {0x8a48, 0x42007c00}, -+ {0x8a4c, 0x00014300}, -+ {0x8a50, 0x0001e2e5}, -+ {0x8a54, 0x55000007}, -+ {0x8a58, 0x74200004}, -+ {0x8a5c, 0x79017711}, -+ {0x8a60, 0x57005710}, -+ {0x8a64, 0x00019700}, -+ {0x8a68, 0x4e004f02}, -+ {0x8a6c, 0x52015302}, -+ {0x8a70, 0x43800001}, -+ {0x8a74, 0x78006505}, -+ {0x8a78, 0x7a007900}, -+ {0x8a7c, 0x43007b00}, -+ {0x8a80, 0x43800001}, -+ {0x8a84, 0x43006500}, -+ {0x8a88, 0x43800001}, -+ {0x8a8c, 0x7c006405}, -+ {0x8a90, 0x00014300}, -+ {0x8a94, 0x64004380}, -+ {0x8a98, 0x00014300}, -+ {0x8a9c, 0x74200004}, -+ {0x8aa0, 0x0005e392}, -+ {0x8aa4, 0x73807388}, -+ {0x8aa8, 0xe3a08f00}, -+ {0x8aac, 0xe3920001}, -+ {0x8ab0, 0x73810005}, -+ {0x8ab4, 0x93007380}, -+ {0x8ab8, 0x0001e3a0}, -+ {0x8abc, 0xe2e5e3a7}, -+ {0x8ac0, 0x0001e3ae}, -+ {0x8ac4, 0xe3aee3a7}, -+ {0x8ac8, 0x00040001}, -+ {0x8acc, 0x24207410}, -+ {0x8ad0, 0x14c80000}, -+ {0x8ad4, 0x00002428}, -+ {0x8ad8, 0x1a4215f4}, -+ {0x8adc, 0x74300008}, -+ {0x8ae0, 0x43800001}, -+ {0x8ae4, 0x7a907b48}, -+ {0x8ae8, 0x78027900}, -+ {0x8aec, 0x55034300}, -+ {0x8af0, 0x43803308}, -+ {0x8af4, 0x7a807b38}, -+ {0x8af8, 0x55134300}, -+ {0x8afc, 0x43803308}, -+ {0x8b00, 0x7a007b40}, -+ {0x8b04, 0x55234300}, -+ {0x8b08, 0x74007401}, -+ {0x8b0c, 0x00018e00}, -+ {0x8b10, 0x52300007}, -+ {0x8b14, 0x74310004}, -+ {0x8b18, 0x8e007430}, -+ {0x8b1c, 0x52200007}, -+ {0x8b20, 0x00010004}, -+ {0x8b24, 0x57005702}, -+ {0x8b28, 0x00018e00}, -+ {0x8b2c, 0x561042ef}, -+ {0x8b30, 0x42005600}, -+ {0x8b34, 0x00018c00}, -+ {0x8b38, 0x4e004f78}, -+ {0x8b3c, 0x52015388}, -+ {0x8b40, 0xe32b5b20}, -+ {0x8b44, 0x54005480}, -+ {0x8b48, 0x54005481}, -+ {0x8b4c, 0x54005482}, -+ {0x8b50, 0xbf1de336}, -+ {0x8b54, 0xe2f13010}, -+ {0x8b58, 0xe2ffe2f9}, -+ {0x8b5c, 0xe3b3e312}, -+ {0x8b60, 0xe3085523}, -+ {0x8b64, 0xe3125525}, -+ {0x8b68, 0x0001e3b3}, -+ {0x8b6c, 0x54c054bf}, -+ {0x8b70, 0x54c154a3}, -+ {0x8b74, 0x4c1854a4}, -+ {0x8b78, 0x54c2bf07}, -+ {0x8b7c, 0xbf0454a4}, -+ {0x8b80, 0x54a354c1}, -+ {0x8b84, 0xe3c4bf01}, -+ {0x8b88, 0x000154df}, -+ {0x8b8c, 0x54e554bf}, -+ {0x8b90, 0x54df050a}, -+ {0x8b94, 0x16570001}, -+ {0x8b98, 0x74307b80}, -+ {0x8b9c, 0x7f404380}, -+ {0x8ba0, 0x7d007e00}, -+ {0x8ba4, 0x43007c02}, -+ {0x8ba8, 0x55015b40}, -+ {0x8bac, 0xe3165c01}, -+ {0x8bb0, 0x54005480}, -+ {0x8bb4, 0x54005481}, -+ {0x8bb8, 0x54005482}, -+ {0x8bbc, 0x74107b00}, -+ {0x8bc0, 0xbfe5e336}, -+ {0x8bc4, 0x56103010}, -+ {0x8bc8, 0x8c005600}, -+ {0x8bcc, 0x57040001}, -+ {0x8bd0, 0x8e005700}, -+ {0x8bd4, 0x57005708}, -+ {0x8bd8, 0x57818e00}, -+ {0x8bdc, 0x8e005780}, -+ {0x8be0, 0x00074380}, -+ {0x8be4, 0x5c005c01}, -+ {0x8be8, 0x00041403}, -+ {0x8bec, 0x00014300}, -+ {0x8bf0, 0x0007427f}, -+ {0x8bf4, 0x62006280}, -+ {0x8bf8, 0x00049200}, -+ {0x8bfc, 0x00014200}, -+ {0x8c00, 0x0007427f}, -+ {0x8c04, 0x63146394}, -+ {0x8c08, 0x00049200}, -+ {0x8c0c, 0x00014200}, -+ {0x8c10, 0x42fe0004}, -+ {0x8c14, 0x42007901}, -+ {0x8c18, 0x14037420}, -+ {0x8c1c, 0x57005710}, -+ {0x8c20, 0x0001140f}, -+ {0x8c24, 0x56010006}, -+ {0x8c28, 0x54005502}, -+ {0x8c2c, 0x7f000005}, -+ {0x8c30, 0x77107e12}, -+ {0x8c34, 0x75007600}, -+ {0x8c38, 0x00047400}, -+ {0x8c3c, 0x00014270}, -+ {0x8c40, 0x42000004}, -+ {0x8c44, 0x77000005}, -+ {0x8c48, 0x56000006}, -+ {0x8c4c, 0x00060001}, -+ {0x8c50, 0x5f005f80}, -+ {0x8c54, 0x00059900}, -+ {0x8c58, 0x00017300}, -+ {0x8c5c, 0x63800006}, -+ {0x8c60, 0x98006300}, -+ {0x8c64, 0x549f0001}, -+ {0x8c68, 0x5c015400}, -+ {0x8c6c, 0x540054df}, -+ {0x8c70, 0x00015c02}, -+ {0x8c74, 0x07145c01}, -+ {0x8c78, 0x5c025400}, -+ {0x8c7c, 0x5c020001}, -+ {0x8c80, 0x54000714}, -+ {0x8c84, 0x00015c01}, -+ {0x8c88, 0x4c184c98}, -+ {0x8c8c, 0x00040001}, -+ {0x8c90, 0x74305c02}, -+ {0x8c94, 0x0c010901}, -+ {0x8c98, 0x00050ba6}, -+ {0x8c9c, 0x00077780}, -+ {0x8ca0, 0x00045220}, -+ {0x8ca4, 0x60084380}, -+ {0x8ca8, 0x6200610a}, -+ {0x8cac, 0x000763ce}, -+ {0x8cb0, 0x00045c00}, -+ {0x8cb4, 0x00014300}, -+ {0x8080, 0x00000004}, -+ {0x8080, 0x00000000}, -+ {0x8088, 0x00000000}, -+}; -+ -+static const struct rtw89_txpwr_byrate_cfg rtw89_8852b_txpwr_byrate[] = { -+ { 0, 0, 0, 0, 4, 0x50505050, }, -+ { 0, 0, 1, 0, 4, 0x50505050, }, -+ { 0, 0, 1, 4, 4, 0x484c5050, }, -+ { 0, 0, 2, 0, 4, 0x50505050, }, -+ { 0, 0, 2, 4, 4, 0x44484c50, }, -+ { 0, 0, 2, 8, 4, 0x34383c40, }, -+ { 0, 0, 3, 0, 4, 0x50505050, }, -+ { 0, 1, 2, 0, 4, 0x50505050, }, -+ { 0, 1, 2, 4, 4, 0x44484c50, }, -+ { 0, 1, 2, 8, 4, 0x34383c40, }, -+ { 0, 1, 3, 0, 4, 0x50505050, }, -+ { 0, 0, 4, 1, 4, 0x00000000, }, -+ { 0, 0, 4, 0, 1, 0x00000000, }, -+ { 1, 0, 1, 0, 4, 0x50505050, }, -+ { 1, 0, 1, 4, 4, 0x484c5050, }, -+ { 1, 0, 2, 0, 4, 0x50505050, }, -+ { 1, 0, 2, 4, 4, 0x44484c50, }, -+ { 1, 0, 2, 8, 4, 0x34383c40, }, -+ { 1, 0, 3, 0, 4, 0x50505050, }, -+ { 1, 1, 2, 0, 4, 0x50505050, }, -+ { 1, 1, 2, 4, 4, 0x44484c50, }, -+ { 1, 1, 2, 8, 4, 0x34383c40, }, -+ { 1, 1, 3, 0, 4, 0x50505050, }, -+ { 1, 0, 4, 0, 4, 0x00000000, }, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { -+ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, -+ 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8}, -+ {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, -+ 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8}, -+ {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, -+ 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { -+ {0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, -+ 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8}, -+ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, -+ 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8}, -+ {0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, -+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { -+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, -+ 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4}, -+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, -+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { -+ {0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, -+ 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, -+ {0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, -+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9}, -+ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, -+ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_2gb_n[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2}; -+ -+static const s8 _txpwr_track_delta_swingidx_2gb_p[] = { -+ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, -+ 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6}; -+ -+static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ -+static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { -+ 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, -+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { -+ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, -+ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2, -2, -+ -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { -+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -+ -+const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+ [RTW89_REGD_NUM] = { -+ [0][0][RTW89_ACMA] = 0, -+ [0][0][RTW89_CHILE] = 0, -+ [0][0][RTW89_CN] = 0, -+ [0][0][RTW89_ETSI] = 0, -+ [0][0][RTW89_FCC] = 1, -+ [0][0][RTW89_IC] = 1, -+ [0][0][RTW89_KCC] = 0, -+ [0][0][RTW89_MEXICO] = 1, -+ [0][0][RTW89_MKK] = 0, -+ [0][0][RTW89_QATAR] = 0, -+ [0][0][RTW89_UK] = 0, -+ [0][0][RTW89_UKRAINE] = 0, -+ [0][1][RTW89_ACMA] = 0, -+ [0][1][RTW89_CHILE] = 0, -+ [0][1][RTW89_CN] = 0, -+ [0][1][RTW89_ETSI] = 0, -+ [0][1][RTW89_FCC] = 3, -+ [0][1][RTW89_IC] = 3, -+ [0][1][RTW89_KCC] = 0, -+ [0][1][RTW89_MEXICO] = 3, -+ [0][1][RTW89_MKK] = 0, -+ [0][1][RTW89_QATAR] = 0, -+ [0][1][RTW89_UK] = 0, -+ [0][1][RTW89_UKRAINE] = 0, -+ [1][1][RTW89_ACMA] = 0, -+ [1][1][RTW89_CHILE] = 0, -+ [1][1][RTW89_CN] = 0, -+ [1][1][RTW89_ETSI] = 0, -+ [1][1][RTW89_FCC] = 3, -+ [1][1][RTW89_IC] = 3, -+ [1][1][RTW89_KCC] = 0, -+ [1][1][RTW89_MEXICO] = 3, -+ [1][1][RTW89_MKK] = 0, -+ [1][1][RTW89_QATAR] = 0, -+ [1][1][RTW89_UK] = 0, -+ [1][1][RTW89_UKRAINE] = 0, -+}; -+ -+const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][0][0][RTW89_WW][0] = 58, -+ [0][0][0][0][RTW89_WW][1] = 58, -+ [0][0][0][0][RTW89_WW][2] = 58, -+ [0][0][0][0][RTW89_WW][3] = 58, -+ [0][0][0][0][RTW89_WW][4] = 58, -+ [0][0][0][0][RTW89_WW][5] = 58, -+ [0][0][0][0][RTW89_WW][6] = 58, -+ [0][0][0][0][RTW89_WW][7] = 58, -+ [0][0][0][0][RTW89_WW][8] = 58, -+ [0][0][0][0][RTW89_WW][9] = 58, -+ [0][0][0][0][RTW89_WW][10] = 58, -+ [0][0][0][0][RTW89_WW][11] = 58, -+ [0][0][0][0][RTW89_WW][12] = 56, -+ [0][0][0][0][RTW89_WW][13] = 76, -+ [0][1][0][0][RTW89_WW][0] = 46, -+ [0][1][0][0][RTW89_WW][1] = 46, -+ [0][1][0][0][RTW89_WW][2] = 46, -+ [0][1][0][0][RTW89_WW][3] = 46, -+ [0][1][0][0][RTW89_WW][4] = 46, -+ [0][1][0][0][RTW89_WW][5] = 46, -+ [0][1][0][0][RTW89_WW][6] = 46, -+ [0][1][0][0][RTW89_WW][7] = 46, -+ [0][1][0][0][RTW89_WW][8] = 46, -+ [0][1][0][0][RTW89_WW][9] = 46, -+ [0][1][0][0][RTW89_WW][10] = 46, -+ [0][1][0][0][RTW89_WW][11] = 46, -+ [0][1][0][0][RTW89_WW][12] = 42, -+ [0][1][0][0][RTW89_WW][13] = 64, -+ [1][0][0][0][RTW89_WW][0] = 0, -+ [1][0][0][0][RTW89_WW][1] = 0, -+ [1][0][0][0][RTW89_WW][2] = 50, -+ [1][0][0][0][RTW89_WW][3] = 50, -+ [1][0][0][0][RTW89_WW][4] = 50, -+ [1][0][0][0][RTW89_WW][5] = 58, -+ [1][0][0][0][RTW89_WW][6] = 50, -+ [1][0][0][0][RTW89_WW][7] = 50, -+ [1][0][0][0][RTW89_WW][8] = 50, -+ [1][0][0][0][RTW89_WW][9] = 42, -+ [1][0][0][0][RTW89_WW][10] = 30, -+ [1][0][0][0][RTW89_WW][11] = 0, -+ [1][0][0][0][RTW89_WW][12] = 0, -+ [1][0][0][0][RTW89_WW][13] = 0, -+ [1][1][0][0][RTW89_WW][0] = 0, -+ [1][1][0][0][RTW89_WW][1] = 0, -+ [1][1][0][0][RTW89_WW][2] = 46, -+ [1][1][0][0][RTW89_WW][3] = 46, -+ [1][1][0][0][RTW89_WW][4] = 46, -+ [1][1][0][0][RTW89_WW][5] = 46, -+ [1][1][0][0][RTW89_WW][6] = 34, -+ [1][1][0][0][RTW89_WW][7] = 34, -+ [1][1][0][0][RTW89_WW][8] = 34, -+ [1][1][0][0][RTW89_WW][9] = 30, -+ [1][1][0][0][RTW89_WW][10] = 30, -+ [1][1][0][0][RTW89_WW][11] = 0, -+ [1][1][0][0][RTW89_WW][12] = 0, -+ [1][1][0][0][RTW89_WW][13] = 0, -+ [0][0][1][0][RTW89_WW][0] = 58, -+ [0][0][1][0][RTW89_WW][1] = 58, -+ [0][0][1][0][RTW89_WW][2] = 58, -+ [0][0][1][0][RTW89_WW][3] = 58, -+ [0][0][1][0][RTW89_WW][4] = 58, -+ [0][0][1][0][RTW89_WW][5] = 58, -+ [0][0][1][0][RTW89_WW][6] = 58, -+ [0][0][1][0][RTW89_WW][7] = 58, -+ [0][0][1][0][RTW89_WW][8] = 58, -+ [0][0][1][0][RTW89_WW][9] = 58, -+ [0][0][1][0][RTW89_WW][10] = 58, -+ [0][0][1][0][RTW89_WW][11] = 54, -+ [0][0][1][0][RTW89_WW][12] = 50, -+ [0][0][1][0][RTW89_WW][13] = 0, -+ [0][1][1][0][RTW89_WW][0] = 46, -+ [0][1][1][0][RTW89_WW][1] = 46, -+ [0][1][1][0][RTW89_WW][2] = 46, -+ [0][1][1][0][RTW89_WW][3] = 46, -+ [0][1][1][0][RTW89_WW][4] = 46, -+ [0][1][1][0][RTW89_WW][5] = 46, -+ [0][1][1][0][RTW89_WW][6] = 46, -+ [0][1][1][0][RTW89_WW][7] = 46, -+ [0][1][1][0][RTW89_WW][8] = 46, -+ [0][1][1][0][RTW89_WW][9] = 46, -+ [0][1][1][0][RTW89_WW][10] = 46, -+ [0][1][1][0][RTW89_WW][11] = 46, -+ [0][1][1][0][RTW89_WW][12] = 42, -+ [0][1][1][0][RTW89_WW][13] = 0, -+ [0][0][2][0][RTW89_WW][0] = 58, -+ [0][0][2][0][RTW89_WW][1] = 58, -+ [0][0][2][0][RTW89_WW][2] = 58, -+ [0][0][2][0][RTW89_WW][3] = 58, -+ [0][0][2][0][RTW89_WW][4] = 58, -+ [0][0][2][0][RTW89_WW][5] = 58, -+ [0][0][2][0][RTW89_WW][6] = 58, -+ [0][0][2][0][RTW89_WW][7] = 58, -+ [0][0][2][0][RTW89_WW][8] = 58, -+ [0][0][2][0][RTW89_WW][9] = 58, -+ [0][0][2][0][RTW89_WW][10] = 58, -+ [0][0][2][0][RTW89_WW][11] = 54, -+ [0][0][2][0][RTW89_WW][12] = 50, -+ [0][0][2][0][RTW89_WW][13] = 0, -+ [0][1][2][0][RTW89_WW][0] = 46, -+ [0][1][2][0][RTW89_WW][1] = 46, -+ [0][1][2][0][RTW89_WW][2] = 46, -+ [0][1][2][0][RTW89_WW][3] = 46, -+ [0][1][2][0][RTW89_WW][4] = 46, -+ [0][1][2][0][RTW89_WW][5] = 46, -+ [0][1][2][0][RTW89_WW][6] = 46, -+ [0][1][2][0][RTW89_WW][7] = 46, -+ [0][1][2][0][RTW89_WW][8] = 46, -+ [0][1][2][0][RTW89_WW][9] = 46, -+ [0][1][2][0][RTW89_WW][10] = 46, -+ [0][1][2][0][RTW89_WW][11] = 46, -+ [0][1][2][0][RTW89_WW][12] = 42, -+ [0][1][2][0][RTW89_WW][13] = 0, -+ [0][1][2][1][RTW89_WW][0] = 34, -+ [0][1][2][1][RTW89_WW][1] = 34, -+ [0][1][2][1][RTW89_WW][2] = 34, -+ [0][1][2][1][RTW89_WW][3] = 34, -+ [0][1][2][1][RTW89_WW][4] = 34, -+ [0][1][2][1][RTW89_WW][5] = 34, -+ [0][1][2][1][RTW89_WW][6] = 34, -+ [0][1][2][1][RTW89_WW][7] = 34, -+ [0][1][2][1][RTW89_WW][8] = 34, -+ [0][1][2][1][RTW89_WW][9] = 34, -+ [0][1][2][1][RTW89_WW][10] = 34, -+ [0][1][2][1][RTW89_WW][11] = 34, -+ [0][1][2][1][RTW89_WW][12] = 34, -+ [0][1][2][1][RTW89_WW][13] = 0, -+ [1][0][2][0][RTW89_WW][0] = 0, -+ [1][0][2][0][RTW89_WW][1] = 0, -+ [1][0][2][0][RTW89_WW][2] = 58, -+ [1][0][2][0][RTW89_WW][3] = 58, -+ [1][0][2][0][RTW89_WW][4] = 58, -+ [1][0][2][0][RTW89_WW][5] = 58, -+ [1][0][2][0][RTW89_WW][6] = 58, -+ [1][0][2][0][RTW89_WW][7] = 58, -+ [1][0][2][0][RTW89_WW][8] = 58, -+ [1][0][2][0][RTW89_WW][9] = 58, -+ [1][0][2][0][RTW89_WW][10] = 58, -+ [1][0][2][0][RTW89_WW][11] = 0, -+ [1][0][2][0][RTW89_WW][12] = 0, -+ [1][0][2][0][RTW89_WW][13] = 0, -+ [1][1][2][0][RTW89_WW][0] = 0, -+ [1][1][2][0][RTW89_WW][1] = 0, -+ [1][1][2][0][RTW89_WW][2] = 46, -+ [1][1][2][0][RTW89_WW][3] = 46, -+ [1][1][2][0][RTW89_WW][4] = 46, -+ [1][1][2][0][RTW89_WW][5] = 46, -+ [1][1][2][0][RTW89_WW][6] = 46, -+ [1][1][2][0][RTW89_WW][7] = 46, -+ [1][1][2][0][RTW89_WW][8] = 46, -+ [1][1][2][0][RTW89_WW][9] = 42, -+ [1][1][2][0][RTW89_WW][10] = 38, -+ [1][1][2][0][RTW89_WW][11] = 0, -+ [1][1][2][0][RTW89_WW][12] = 0, -+ [1][1][2][0][RTW89_WW][13] = 0, -+ [1][1][2][1][RTW89_WW][0] = 0, -+ [1][1][2][1][RTW89_WW][1] = 0, -+ [1][1][2][1][RTW89_WW][2] = 34, -+ [1][1][2][1][RTW89_WW][3] = 34, -+ [1][1][2][1][RTW89_WW][4] = 34, -+ [1][1][2][1][RTW89_WW][5] = 34, -+ [1][1][2][1][RTW89_WW][6] = 34, -+ [1][1][2][1][RTW89_WW][7] = 34, -+ [1][1][2][1][RTW89_WW][8] = 34, -+ [1][1][2][1][RTW89_WW][9] = 34, -+ [1][1][2][1][RTW89_WW][10] = 34, -+ [1][1][2][1][RTW89_WW][11] = 0, -+ [1][1][2][1][RTW89_WW][12] = 0, -+ [1][1][2][1][RTW89_WW][13] = 0, -+ [0][0][0][0][RTW89_FCC][0] = 78, -+ [0][0][0][0][RTW89_ETSI][0] = 58, -+ [0][0][0][0][RTW89_MKK][0] = 68, -+ [0][0][0][0][RTW89_IC][0] = 78, -+ [0][0][0][0][RTW89_KCC][0] = 68, -+ [0][0][0][0][RTW89_ACMA][0] = 58, -+ [0][0][0][0][RTW89_CHILE][0] = 64, -+ [0][0][0][0][RTW89_UKRAINE][0] = 58, -+ [0][0][0][0][RTW89_MEXICO][0] = 78, -+ [0][0][0][0][RTW89_CN][0] = 58, -+ [0][0][0][0][RTW89_QATAR][0] = 58, -+ [0][0][0][0][RTW89_UK][0] = 58, -+ [0][0][0][0][RTW89_FCC][1] = 78, -+ [0][0][0][0][RTW89_ETSI][1] = 58, -+ [0][0][0][0][RTW89_MKK][1] = 68, -+ [0][0][0][0][RTW89_IC][1] = 78, -+ [0][0][0][0][RTW89_KCC][1] = 68, -+ [0][0][0][0][RTW89_ACMA][1] = 58, -+ [0][0][0][0][RTW89_CHILE][1] = 64, -+ [0][0][0][0][RTW89_UKRAINE][1] = 58, -+ [0][0][0][0][RTW89_MEXICO][1] = 78, -+ [0][0][0][0][RTW89_CN][1] = 58, -+ [0][0][0][0][RTW89_QATAR][1] = 58, -+ [0][0][0][0][RTW89_UK][1] = 58, -+ [0][0][0][0][RTW89_FCC][2] = 78, -+ [0][0][0][0][RTW89_ETSI][2] = 58, -+ [0][0][0][0][RTW89_MKK][2] = 68, -+ [0][0][0][0][RTW89_IC][2] = 78, -+ [0][0][0][0][RTW89_KCC][2] = 68, -+ [0][0][0][0][RTW89_ACMA][2] = 58, -+ [0][0][0][0][RTW89_CHILE][2] = 64, -+ [0][0][0][0][RTW89_UKRAINE][2] = 58, -+ [0][0][0][0][RTW89_MEXICO][2] = 78, -+ [0][0][0][0][RTW89_CN][2] = 58, -+ [0][0][0][0][RTW89_QATAR][2] = 58, -+ [0][0][0][0][RTW89_UK][2] = 58, -+ [0][0][0][0][RTW89_FCC][3] = 78, -+ [0][0][0][0][RTW89_ETSI][3] = 58, -+ [0][0][0][0][RTW89_MKK][3] = 68, -+ [0][0][0][0][RTW89_IC][3] = 78, -+ [0][0][0][0][RTW89_KCC][3] = 68, -+ [0][0][0][0][RTW89_ACMA][3] = 58, -+ [0][0][0][0][RTW89_CHILE][3] = 64, -+ [0][0][0][0][RTW89_UKRAINE][3] = 58, -+ [0][0][0][0][RTW89_MEXICO][3] = 78, -+ [0][0][0][0][RTW89_CN][3] = 58, -+ [0][0][0][0][RTW89_QATAR][3] = 58, -+ [0][0][0][0][RTW89_UK][3] = 58, -+ [0][0][0][0][RTW89_FCC][4] = 78, -+ [0][0][0][0][RTW89_ETSI][4] = 58, -+ [0][0][0][0][RTW89_MKK][4] = 68, -+ [0][0][0][0][RTW89_IC][4] = 78, -+ [0][0][0][0][RTW89_KCC][4] = 70, -+ [0][0][0][0][RTW89_ACMA][4] = 58, -+ [0][0][0][0][RTW89_CHILE][4] = 64, -+ [0][0][0][0][RTW89_UKRAINE][4] = 58, -+ [0][0][0][0][RTW89_MEXICO][4] = 78, -+ [0][0][0][0][RTW89_CN][4] = 58, -+ [0][0][0][0][RTW89_QATAR][4] = 58, -+ [0][0][0][0][RTW89_UK][4] = 58, -+ [0][0][0][0][RTW89_FCC][5] = 78, -+ [0][0][0][0][RTW89_ETSI][5] = 58, -+ [0][0][0][0][RTW89_MKK][5] = 68, -+ [0][0][0][0][RTW89_IC][5] = 78, -+ [0][0][0][0][RTW89_KCC][5] = 70, -+ [0][0][0][0][RTW89_ACMA][5] = 58, -+ [0][0][0][0][RTW89_CHILE][5] = 64, -+ [0][0][0][0][RTW89_UKRAINE][5] = 58, -+ [0][0][0][0][RTW89_MEXICO][5] = 78, -+ [0][0][0][0][RTW89_CN][5] = 58, -+ [0][0][0][0][RTW89_QATAR][5] = 58, -+ [0][0][0][0][RTW89_UK][5] = 58, -+ [0][0][0][0][RTW89_FCC][6] = 78, -+ [0][0][0][0][RTW89_ETSI][6] = 58, -+ [0][0][0][0][RTW89_MKK][6] = 68, -+ [0][0][0][0][RTW89_IC][6] = 78, -+ [0][0][0][0][RTW89_KCC][6] = 70, -+ [0][0][0][0][RTW89_ACMA][6] = 58, -+ [0][0][0][0][RTW89_CHILE][6] = 64, -+ [0][0][0][0][RTW89_UKRAINE][6] = 58, -+ [0][0][0][0][RTW89_MEXICO][6] = 78, -+ [0][0][0][0][RTW89_CN][6] = 58, -+ [0][0][0][0][RTW89_QATAR][6] = 58, -+ [0][0][0][0][RTW89_UK][6] = 58, -+ [0][0][0][0][RTW89_FCC][7] = 78, -+ [0][0][0][0][RTW89_ETSI][7] = 58, -+ [0][0][0][0][RTW89_MKK][7] = 68, -+ [0][0][0][0][RTW89_IC][7] = 78, -+ [0][0][0][0][RTW89_KCC][7] = 70, -+ [0][0][0][0][RTW89_ACMA][7] = 58, -+ [0][0][0][0][RTW89_CHILE][7] = 64, -+ [0][0][0][0][RTW89_UKRAINE][7] = 58, -+ [0][0][0][0][RTW89_MEXICO][7] = 78, -+ [0][0][0][0][RTW89_CN][7] = 58, -+ [0][0][0][0][RTW89_QATAR][7] = 58, -+ [0][0][0][0][RTW89_UK][7] = 58, -+ [0][0][0][0][RTW89_FCC][8] = 78, -+ [0][0][0][0][RTW89_ETSI][8] = 58, -+ [0][0][0][0][RTW89_MKK][8] = 68, -+ [0][0][0][0][RTW89_IC][8] = 78, -+ [0][0][0][0][RTW89_KCC][8] = 70, -+ [0][0][0][0][RTW89_ACMA][8] = 58, -+ [0][0][0][0][RTW89_CHILE][8] = 64, -+ [0][0][0][0][RTW89_UKRAINE][8] = 58, -+ [0][0][0][0][RTW89_MEXICO][8] = 78, -+ [0][0][0][0][RTW89_CN][8] = 58, -+ [0][0][0][0][RTW89_QATAR][8] = 58, -+ [0][0][0][0][RTW89_UK][8] = 58, -+ [0][0][0][0][RTW89_FCC][9] = 78, -+ [0][0][0][0][RTW89_ETSI][9] = 58, -+ [0][0][0][0][RTW89_MKK][9] = 68, -+ [0][0][0][0][RTW89_IC][9] = 78, -+ [0][0][0][0][RTW89_KCC][9] = 70, -+ [0][0][0][0][RTW89_ACMA][9] = 58, -+ [0][0][0][0][RTW89_CHILE][9] = 64, -+ [0][0][0][0][RTW89_UKRAINE][9] = 58, -+ [0][0][0][0][RTW89_MEXICO][9] = 78, -+ [0][0][0][0][RTW89_CN][9] = 58, -+ [0][0][0][0][RTW89_QATAR][9] = 58, -+ [0][0][0][0][RTW89_UK][9] = 58, -+ [0][0][0][0][RTW89_FCC][10] = 78, -+ [0][0][0][0][RTW89_ETSI][10] = 58, -+ [0][0][0][0][RTW89_MKK][10] = 68, -+ [0][0][0][0][RTW89_IC][10] = 78, -+ [0][0][0][0][RTW89_KCC][10] = 70, -+ [0][0][0][0][RTW89_ACMA][10] = 58, -+ [0][0][0][0][RTW89_CHILE][10] = 66, -+ [0][0][0][0][RTW89_UKRAINE][10] = 58, -+ [0][0][0][0][RTW89_MEXICO][10] = 78, -+ [0][0][0][0][RTW89_CN][10] = 58, -+ [0][0][0][0][RTW89_QATAR][10] = 58, -+ [0][0][0][0][RTW89_UK][10] = 58, -+ [0][0][0][0][RTW89_FCC][11] = 70, -+ [0][0][0][0][RTW89_ETSI][11] = 58, -+ [0][0][0][0][RTW89_MKK][11] = 68, -+ [0][0][0][0][RTW89_IC][11] = 70, -+ [0][0][0][0][RTW89_KCC][11] = 70, -+ [0][0][0][0][RTW89_ACMA][11] = 58, -+ [0][0][0][0][RTW89_CHILE][11] = 64, -+ [0][0][0][0][RTW89_UKRAINE][11] = 58, -+ [0][0][0][0][RTW89_MEXICO][11] = 70, -+ [0][0][0][0][RTW89_CN][11] = 58, -+ [0][0][0][0][RTW89_QATAR][11] = 58, -+ [0][0][0][0][RTW89_UK][11] = 58, -+ [0][0][0][0][RTW89_FCC][12] = 56, -+ [0][0][0][0][RTW89_ETSI][12] = 58, -+ [0][0][0][0][RTW89_MKK][12] = 68, -+ [0][0][0][0][RTW89_IC][12] = 56, -+ [0][0][0][0][RTW89_KCC][12] = 70, -+ [0][0][0][0][RTW89_ACMA][12] = 58, -+ [0][0][0][0][RTW89_CHILE][12] = 56, -+ [0][0][0][0][RTW89_UKRAINE][12] = 58, -+ [0][0][0][0][RTW89_MEXICO][12] = 56, -+ [0][0][0][0][RTW89_CN][12] = 58, -+ [0][0][0][0][RTW89_QATAR][12] = 58, -+ [0][0][0][0][RTW89_UK][12] = 58, -+ [0][0][0][0][RTW89_FCC][13] = 127, -+ [0][0][0][0][RTW89_ETSI][13] = 127, -+ [0][0][0][0][RTW89_MKK][13] = 76, -+ [0][0][0][0][RTW89_IC][13] = 127, -+ [0][0][0][0][RTW89_KCC][13] = 127, -+ [0][0][0][0][RTW89_ACMA][13] = 127, -+ [0][0][0][0][RTW89_CHILE][13] = 127, -+ [0][0][0][0][RTW89_UKRAINE][13] = 127, -+ [0][0][0][0][RTW89_MEXICO][13] = 127, -+ [0][0][0][0][RTW89_CN][13] = 127, -+ [0][0][0][0][RTW89_QATAR][13] = 127, -+ [0][0][0][0][RTW89_UK][13] = 127, -+ [0][1][0][0][RTW89_FCC][0] = 74, -+ [0][1][0][0][RTW89_ETSI][0] = 46, -+ [0][1][0][0][RTW89_MKK][0] = 56, -+ [0][1][0][0][RTW89_IC][0] = 74, -+ [0][1][0][0][RTW89_KCC][0] = 58, -+ [0][1][0][0][RTW89_ACMA][0] = 46, -+ [0][1][0][0][RTW89_CHILE][0] = 50, -+ [0][1][0][0][RTW89_UKRAINE][0] = 46, -+ [0][1][0][0][RTW89_MEXICO][0] = 74, -+ [0][1][0][0][RTW89_CN][0] = 46, -+ [0][1][0][0][RTW89_QATAR][0] = 46, -+ [0][1][0][0][RTW89_UK][0] = 46, -+ [0][1][0][0][RTW89_FCC][1] = 74, -+ [0][1][0][0][RTW89_ETSI][1] = 46, -+ [0][1][0][0][RTW89_MKK][1] = 56, -+ [0][1][0][0][RTW89_IC][1] = 74, -+ [0][1][0][0][RTW89_KCC][1] = 58, -+ [0][1][0][0][RTW89_ACMA][1] = 46, -+ [0][1][0][0][RTW89_CHILE][1] = 50, -+ [0][1][0][0][RTW89_UKRAINE][1] = 46, -+ [0][1][0][0][RTW89_MEXICO][1] = 74, -+ [0][1][0][0][RTW89_CN][1] = 46, -+ [0][1][0][0][RTW89_QATAR][1] = 46, -+ [0][1][0][0][RTW89_UK][1] = 46, -+ [0][1][0][0][RTW89_FCC][2] = 74, -+ [0][1][0][0][RTW89_ETSI][2] = 46, -+ [0][1][0][0][RTW89_MKK][2] = 56, -+ [0][1][0][0][RTW89_IC][2] = 74, -+ [0][1][0][0][RTW89_KCC][2] = 58, -+ [0][1][0][0][RTW89_ACMA][2] = 46, -+ [0][1][0][0][RTW89_CHILE][2] = 50, -+ [0][1][0][0][RTW89_UKRAINE][2] = 46, -+ [0][1][0][0][RTW89_MEXICO][2] = 74, -+ [0][1][0][0][RTW89_CN][2] = 46, -+ [0][1][0][0][RTW89_QATAR][2] = 46, -+ [0][1][0][0][RTW89_UK][2] = 46, -+ [0][1][0][0][RTW89_FCC][3] = 74, -+ [0][1][0][0][RTW89_ETSI][3] = 46, -+ [0][1][0][0][RTW89_MKK][3] = 56, -+ [0][1][0][0][RTW89_IC][3] = 74, -+ [0][1][0][0][RTW89_KCC][3] = 58, -+ [0][1][0][0][RTW89_ACMA][3] = 46, -+ [0][1][0][0][RTW89_CHILE][3] = 50, -+ [0][1][0][0][RTW89_UKRAINE][3] = 46, -+ [0][1][0][0][RTW89_MEXICO][3] = 74, -+ [0][1][0][0][RTW89_CN][3] = 46, -+ [0][1][0][0][RTW89_QATAR][3] = 46, -+ [0][1][0][0][RTW89_UK][3] = 46, -+ [0][1][0][0][RTW89_FCC][4] = 74, -+ [0][1][0][0][RTW89_ETSI][4] = 46, -+ [0][1][0][0][RTW89_MKK][4] = 56, -+ [0][1][0][0][RTW89_IC][4] = 74, -+ [0][1][0][0][RTW89_KCC][4] = 56, -+ [0][1][0][0][RTW89_ACMA][4] = 46, -+ [0][1][0][0][RTW89_CHILE][4] = 50, -+ [0][1][0][0][RTW89_UKRAINE][4] = 46, -+ [0][1][0][0][RTW89_MEXICO][4] = 74, -+ [0][1][0][0][RTW89_CN][4] = 46, -+ [0][1][0][0][RTW89_QATAR][4] = 46, -+ [0][1][0][0][RTW89_UK][4] = 46, -+ [0][1][0][0][RTW89_FCC][5] = 74, -+ [0][1][0][0][RTW89_ETSI][5] = 46, -+ [0][1][0][0][RTW89_MKK][5] = 56, -+ [0][1][0][0][RTW89_IC][5] = 74, -+ [0][1][0][0][RTW89_KCC][5] = 56, -+ [0][1][0][0][RTW89_ACMA][5] = 46, -+ [0][1][0][0][RTW89_CHILE][5] = 50, -+ [0][1][0][0][RTW89_UKRAINE][5] = 46, -+ [0][1][0][0][RTW89_MEXICO][5] = 74, -+ [0][1][0][0][RTW89_CN][5] = 46, -+ [0][1][0][0][RTW89_QATAR][5] = 46, -+ [0][1][0][0][RTW89_UK][5] = 46, -+ [0][1][0][0][RTW89_FCC][6] = 74, -+ [0][1][0][0][RTW89_ETSI][6] = 46, -+ [0][1][0][0][RTW89_MKK][6] = 56, -+ [0][1][0][0][RTW89_IC][6] = 74, -+ [0][1][0][0][RTW89_KCC][6] = 56, -+ [0][1][0][0][RTW89_ACMA][6] = 46, -+ [0][1][0][0][RTW89_CHILE][6] = 52, -+ [0][1][0][0][RTW89_UKRAINE][6] = 46, -+ [0][1][0][0][RTW89_MEXICO][6] = 74, -+ [0][1][0][0][RTW89_CN][6] = 46, -+ [0][1][0][0][RTW89_QATAR][6] = 46, -+ [0][1][0][0][RTW89_UK][6] = 46, -+ [0][1][0][0][RTW89_FCC][7] = 74, -+ [0][1][0][0][RTW89_ETSI][7] = 46, -+ [0][1][0][0][RTW89_MKK][7] = 56, -+ [0][1][0][0][RTW89_IC][7] = 74, -+ [0][1][0][0][RTW89_KCC][7] = 56, -+ [0][1][0][0][RTW89_ACMA][7] = 46, -+ [0][1][0][0][RTW89_CHILE][7] = 50, -+ [0][1][0][0][RTW89_UKRAINE][7] = 46, -+ [0][1][0][0][RTW89_MEXICO][7] = 74, -+ [0][1][0][0][RTW89_CN][7] = 46, -+ [0][1][0][0][RTW89_QATAR][7] = 46, -+ [0][1][0][0][RTW89_UK][7] = 46, -+ [0][1][0][0][RTW89_FCC][8] = 74, -+ [0][1][0][0][RTW89_ETSI][8] = 46, -+ [0][1][0][0][RTW89_MKK][8] = 56, -+ [0][1][0][0][RTW89_IC][8] = 74, -+ [0][1][0][0][RTW89_KCC][8] = 56, -+ [0][1][0][0][RTW89_ACMA][8] = 46, -+ [0][1][0][0][RTW89_CHILE][8] = 50, -+ [0][1][0][0][RTW89_UKRAINE][8] = 46, -+ [0][1][0][0][RTW89_MEXICO][8] = 74, -+ [0][1][0][0][RTW89_CN][8] = 46, -+ [0][1][0][0][RTW89_QATAR][8] = 46, -+ [0][1][0][0][RTW89_UK][8] = 46, -+ [0][1][0][0][RTW89_FCC][9] = 74, -+ [0][1][0][0][RTW89_ETSI][9] = 46, -+ [0][1][0][0][RTW89_MKK][9] = 56, -+ [0][1][0][0][RTW89_IC][9] = 74, -+ [0][1][0][0][RTW89_KCC][9] = 54, -+ [0][1][0][0][RTW89_ACMA][9] = 46, -+ [0][1][0][0][RTW89_CHILE][9] = 50, -+ [0][1][0][0][RTW89_UKRAINE][9] = 46, -+ [0][1][0][0][RTW89_MEXICO][9] = 74, -+ [0][1][0][0][RTW89_CN][9] = 46, -+ [0][1][0][0][RTW89_QATAR][9] = 46, -+ [0][1][0][0][RTW89_UK][9] = 46, -+ [0][1][0][0][RTW89_FCC][10] = 74, -+ [0][1][0][0][RTW89_ETSI][10] = 46, -+ [0][1][0][0][RTW89_MKK][10] = 56, -+ [0][1][0][0][RTW89_IC][10] = 74, -+ [0][1][0][0][RTW89_KCC][10] = 54, -+ [0][1][0][0][RTW89_ACMA][10] = 46, -+ [0][1][0][0][RTW89_CHILE][10] = 52, -+ [0][1][0][0][RTW89_UKRAINE][10] = 46, -+ [0][1][0][0][RTW89_MEXICO][10] = 74, -+ [0][1][0][0][RTW89_CN][10] = 46, -+ [0][1][0][0][RTW89_QATAR][10] = 46, -+ [0][1][0][0][RTW89_UK][10] = 46, -+ [0][1][0][0][RTW89_FCC][11] = 54, -+ [0][1][0][0][RTW89_ETSI][11] = 46, -+ [0][1][0][0][RTW89_MKK][11] = 56, -+ [0][1][0][0][RTW89_IC][11] = 54, -+ [0][1][0][0][RTW89_KCC][11] = 54, -+ [0][1][0][0][RTW89_ACMA][11] = 46, -+ [0][1][0][0][RTW89_CHILE][11] = 50, -+ [0][1][0][0][RTW89_UKRAINE][11] = 46, -+ [0][1][0][0][RTW89_MEXICO][11] = 54, -+ [0][1][0][0][RTW89_CN][11] = 46, -+ [0][1][0][0][RTW89_QATAR][11] = 46, -+ [0][1][0][0][RTW89_UK][11] = 46, -+ [0][1][0][0][RTW89_FCC][12] = 42, -+ [0][1][0][0][RTW89_ETSI][12] = 46, -+ [0][1][0][0][RTW89_MKK][12] = 56, -+ [0][1][0][0][RTW89_IC][12] = 42, -+ [0][1][0][0][RTW89_KCC][12] = 54, -+ [0][1][0][0][RTW89_ACMA][12] = 46, -+ [0][1][0][0][RTW89_CHILE][12] = 42, -+ [0][1][0][0][RTW89_UKRAINE][12] = 46, -+ [0][1][0][0][RTW89_MEXICO][12] = 42, -+ [0][1][0][0][RTW89_CN][12] = 46, -+ [0][1][0][0][RTW89_QATAR][12] = 46, -+ [0][1][0][0][RTW89_UK][12] = 46, -+ [0][1][0][0][RTW89_FCC][13] = 127, -+ [0][1][0][0][RTW89_ETSI][13] = 127, -+ [0][1][0][0][RTW89_MKK][13] = 64, -+ [0][1][0][0][RTW89_IC][13] = 127, -+ [0][1][0][0][RTW89_KCC][13] = 127, -+ [0][1][0][0][RTW89_ACMA][13] = 127, -+ [0][1][0][0][RTW89_CHILE][13] = 127, -+ [0][1][0][0][RTW89_UKRAINE][13] = 127, -+ [0][1][0][0][RTW89_MEXICO][13] = 127, -+ [0][1][0][0][RTW89_CN][13] = 127, -+ [0][1][0][0][RTW89_QATAR][13] = 127, -+ [0][1][0][0][RTW89_UK][13] = 127, -+ [1][0][0][0][RTW89_FCC][0] = 127, -+ [1][0][0][0][RTW89_ETSI][0] = 127, -+ [1][0][0][0][RTW89_MKK][0] = 127, -+ [1][0][0][0][RTW89_IC][0] = 127, -+ [1][0][0][0][RTW89_KCC][0] = 127, -+ [1][0][0][0][RTW89_ACMA][0] = 127, -+ [1][0][0][0][RTW89_CHILE][0] = 127, -+ [1][0][0][0][RTW89_UKRAINE][0] = 127, -+ [1][0][0][0][RTW89_MEXICO][0] = 127, -+ [1][0][0][0][RTW89_CN][0] = 127, -+ [1][0][0][0][RTW89_QATAR][0] = 127, -+ [1][0][0][0][RTW89_UK][0] = 127, -+ [1][0][0][0][RTW89_FCC][1] = 127, -+ [1][0][0][0][RTW89_ETSI][1] = 127, -+ [1][0][0][0][RTW89_MKK][1] = 127, -+ [1][0][0][0][RTW89_IC][1] = 127, -+ [1][0][0][0][RTW89_KCC][1] = 127, -+ [1][0][0][0][RTW89_ACMA][1] = 127, -+ [1][0][0][0][RTW89_CHILE][1] = 127, -+ [1][0][0][0][RTW89_UKRAINE][1] = 127, -+ [1][0][0][0][RTW89_MEXICO][1] = 127, -+ [1][0][0][0][RTW89_CN][1] = 127, -+ [1][0][0][0][RTW89_QATAR][1] = 127, -+ [1][0][0][0][RTW89_UK][1] = 127, -+ [1][0][0][0][RTW89_FCC][2] = 50, -+ [1][0][0][0][RTW89_ETSI][2] = 58, -+ [1][0][0][0][RTW89_MKK][2] = 76, -+ [1][0][0][0][RTW89_IC][2] = 50, -+ [1][0][0][0][RTW89_KCC][2] = 70, -+ [1][0][0][0][RTW89_ACMA][2] = 58, -+ [1][0][0][0][RTW89_CHILE][2] = 62, -+ [1][0][0][0][RTW89_UKRAINE][2] = 58, -+ [1][0][0][0][RTW89_MEXICO][2] = 50, -+ [1][0][0][0][RTW89_CN][2] = 58, -+ [1][0][0][0][RTW89_QATAR][2] = 58, -+ [1][0][0][0][RTW89_UK][2] = 58, -+ [1][0][0][0][RTW89_FCC][3] = 50, -+ [1][0][0][0][RTW89_ETSI][3] = 58, -+ [1][0][0][0][RTW89_MKK][3] = 76, -+ [1][0][0][0][RTW89_IC][3] = 50, -+ [1][0][0][0][RTW89_KCC][3] = 70, -+ [1][0][0][0][RTW89_ACMA][3] = 58, -+ [1][0][0][0][RTW89_CHILE][3] = 62, -+ [1][0][0][0][RTW89_UKRAINE][3] = 58, -+ [1][0][0][0][RTW89_MEXICO][3] = 50, -+ [1][0][0][0][RTW89_CN][3] = 58, -+ [1][0][0][0][RTW89_QATAR][3] = 58, -+ [1][0][0][0][RTW89_UK][3] = 58, -+ [1][0][0][0][RTW89_FCC][4] = 50, -+ [1][0][0][0][RTW89_ETSI][4] = 58, -+ [1][0][0][0][RTW89_MKK][4] = 76, -+ [1][0][0][0][RTW89_IC][4] = 50, -+ [1][0][0][0][RTW89_KCC][4] = 70, -+ [1][0][0][0][RTW89_ACMA][4] = 58, -+ [1][0][0][0][RTW89_CHILE][4] = 62, -+ [1][0][0][0][RTW89_UKRAINE][4] = 58, -+ [1][0][0][0][RTW89_MEXICO][4] = 50, -+ [1][0][0][0][RTW89_CN][4] = 58, -+ [1][0][0][0][RTW89_QATAR][4] = 58, -+ [1][0][0][0][RTW89_UK][4] = 58, -+ [1][0][0][0][RTW89_FCC][5] = 66, -+ [1][0][0][0][RTW89_ETSI][5] = 58, -+ [1][0][0][0][RTW89_MKK][5] = 76, -+ [1][0][0][0][RTW89_IC][5] = 66, -+ [1][0][0][0][RTW89_KCC][5] = 70, -+ [1][0][0][0][RTW89_ACMA][5] = 58, -+ [1][0][0][0][RTW89_CHILE][5] = 62, -+ [1][0][0][0][RTW89_UKRAINE][5] = 58, -+ [1][0][0][0][RTW89_MEXICO][5] = 66, -+ [1][0][0][0][RTW89_CN][5] = 58, -+ [1][0][0][0][RTW89_QATAR][5] = 58, -+ [1][0][0][0][RTW89_UK][5] = 58, -+ [1][0][0][0][RTW89_FCC][6] = 50, -+ [1][0][0][0][RTW89_ETSI][6] = 58, -+ [1][0][0][0][RTW89_MKK][6] = 76, -+ [1][0][0][0][RTW89_IC][6] = 50, -+ [1][0][0][0][RTW89_KCC][6] = 70, -+ [1][0][0][0][RTW89_ACMA][6] = 58, -+ [1][0][0][0][RTW89_CHILE][6] = 62, -+ [1][0][0][0][RTW89_UKRAINE][6] = 58, -+ [1][0][0][0][RTW89_MEXICO][6] = 50, -+ [1][0][0][0][RTW89_CN][6] = 58, -+ [1][0][0][0][RTW89_QATAR][6] = 58, -+ [1][0][0][0][RTW89_UK][6] = 58, -+ [1][0][0][0][RTW89_FCC][7] = 50, -+ [1][0][0][0][RTW89_ETSI][7] = 58, -+ [1][0][0][0][RTW89_MKK][7] = 76, -+ [1][0][0][0][RTW89_IC][7] = 50, -+ [1][0][0][0][RTW89_KCC][7] = 70, -+ [1][0][0][0][RTW89_ACMA][7] = 58, -+ [1][0][0][0][RTW89_CHILE][7] = 62, -+ [1][0][0][0][RTW89_UKRAINE][7] = 58, -+ [1][0][0][0][RTW89_MEXICO][7] = 50, -+ [1][0][0][0][RTW89_CN][7] = 58, -+ [1][0][0][0][RTW89_QATAR][7] = 58, -+ [1][0][0][0][RTW89_UK][7] = 58, -+ [1][0][0][0][RTW89_FCC][8] = 50, -+ [1][0][0][0][RTW89_ETSI][8] = 58, -+ [1][0][0][0][RTW89_MKK][8] = 76, -+ [1][0][0][0][RTW89_IC][8] = 50, -+ [1][0][0][0][RTW89_KCC][8] = 70, -+ [1][0][0][0][RTW89_ACMA][8] = 58, -+ [1][0][0][0][RTW89_CHILE][8] = 62, -+ [1][0][0][0][RTW89_UKRAINE][8] = 58, -+ [1][0][0][0][RTW89_MEXICO][8] = 50, -+ [1][0][0][0][RTW89_CN][8] = 58, -+ [1][0][0][0][RTW89_QATAR][8] = 58, -+ [1][0][0][0][RTW89_UK][8] = 58, -+ [1][0][0][0][RTW89_FCC][9] = 42, -+ [1][0][0][0][RTW89_ETSI][9] = 58, -+ [1][0][0][0][RTW89_MKK][9] = 76, -+ [1][0][0][0][RTW89_IC][9] = 42, -+ [1][0][0][0][RTW89_KCC][9] = 70, -+ [1][0][0][0][RTW89_ACMA][9] = 58, -+ [1][0][0][0][RTW89_CHILE][9] = 42, -+ [1][0][0][0][RTW89_UKRAINE][9] = 58, -+ [1][0][0][0][RTW89_MEXICO][9] = 42, -+ [1][0][0][0][RTW89_CN][9] = 58, -+ [1][0][0][0][RTW89_QATAR][9] = 58, -+ [1][0][0][0][RTW89_UK][9] = 58, -+ [1][0][0][0][RTW89_FCC][10] = 30, -+ [1][0][0][0][RTW89_ETSI][10] = 58, -+ [1][0][0][0][RTW89_MKK][10] = 72, -+ [1][0][0][0][RTW89_IC][10] = 30, -+ [1][0][0][0][RTW89_KCC][10] = 70, -+ [1][0][0][0][RTW89_ACMA][10] = 58, -+ [1][0][0][0][RTW89_CHILE][10] = 30, -+ [1][0][0][0][RTW89_UKRAINE][10] = 58, -+ [1][0][0][0][RTW89_MEXICO][10] = 30, -+ [1][0][0][0][RTW89_CN][10] = 58, -+ [1][0][0][0][RTW89_QATAR][10] = 58, -+ [1][0][0][0][RTW89_UK][10] = 58, -+ [1][0][0][0][RTW89_FCC][11] = 127, -+ [1][0][0][0][RTW89_ETSI][11] = 127, -+ [1][0][0][0][RTW89_MKK][11] = 127, -+ [1][0][0][0][RTW89_IC][11] = 127, -+ [1][0][0][0][RTW89_KCC][11] = 127, -+ [1][0][0][0][RTW89_ACMA][11] = 127, -+ [1][0][0][0][RTW89_CHILE][11] = 127, -+ [1][0][0][0][RTW89_UKRAINE][11] = 127, -+ [1][0][0][0][RTW89_MEXICO][11] = 127, -+ [1][0][0][0][RTW89_CN][11] = 127, -+ [1][0][0][0][RTW89_QATAR][11] = 127, -+ [1][0][0][0][RTW89_UK][11] = 127, -+ [1][0][0][0][RTW89_FCC][12] = 127, -+ [1][0][0][0][RTW89_ETSI][12] = 127, -+ [1][0][0][0][RTW89_MKK][12] = 127, -+ [1][0][0][0][RTW89_IC][12] = 127, -+ [1][0][0][0][RTW89_KCC][12] = 127, -+ [1][0][0][0][RTW89_ACMA][12] = 127, -+ [1][0][0][0][RTW89_CHILE][12] = 127, -+ [1][0][0][0][RTW89_UKRAINE][12] = 127, -+ [1][0][0][0][RTW89_MEXICO][12] = 127, -+ [1][0][0][0][RTW89_CN][12] = 127, -+ [1][0][0][0][RTW89_QATAR][12] = 127, -+ [1][0][0][0][RTW89_UK][12] = 127, -+ [1][0][0][0][RTW89_FCC][13] = 127, -+ [1][0][0][0][RTW89_ETSI][13] = 127, -+ [1][0][0][0][RTW89_MKK][13] = 127, -+ [1][0][0][0][RTW89_IC][13] = 127, -+ [1][0][0][0][RTW89_KCC][13] = 127, -+ [1][0][0][0][RTW89_ACMA][13] = 127, -+ [1][0][0][0][RTW89_CHILE][13] = 127, -+ [1][0][0][0][RTW89_UKRAINE][13] = 127, -+ [1][0][0][0][RTW89_MEXICO][13] = 127, -+ [1][0][0][0][RTW89_CN][13] = 127, -+ [1][0][0][0][RTW89_QATAR][13] = 127, -+ [1][0][0][0][RTW89_UK][13] = 127, -+ [1][1][0][0][RTW89_FCC][0] = 127, -+ [1][1][0][0][RTW89_ETSI][0] = 127, -+ [1][1][0][0][RTW89_MKK][0] = 127, -+ [1][1][0][0][RTW89_IC][0] = 127, -+ [1][1][0][0][RTW89_KCC][0] = 127, -+ [1][1][0][0][RTW89_ACMA][0] = 127, -+ [1][1][0][0][RTW89_CHILE][0] = 127, -+ [1][1][0][0][RTW89_UKRAINE][0] = 127, -+ [1][1][0][0][RTW89_MEXICO][0] = 127, -+ [1][1][0][0][RTW89_CN][0] = 127, -+ [1][1][0][0][RTW89_QATAR][0] = 127, -+ [1][1][0][0][RTW89_UK][0] = 127, -+ [1][1][0][0][RTW89_FCC][1] = 127, -+ [1][1][0][0][RTW89_ETSI][1] = 127, -+ [1][1][0][0][RTW89_MKK][1] = 127, -+ [1][1][0][0][RTW89_IC][1] = 127, -+ [1][1][0][0][RTW89_KCC][1] = 127, -+ [1][1][0][0][RTW89_ACMA][1] = 127, -+ [1][1][0][0][RTW89_CHILE][1] = 127, -+ [1][1][0][0][RTW89_UKRAINE][1] = 127, -+ [1][1][0][0][RTW89_MEXICO][1] = 127, -+ [1][1][0][0][RTW89_CN][1] = 127, -+ [1][1][0][0][RTW89_QATAR][1] = 127, -+ [1][1][0][0][RTW89_UK][1] = 127, -+ [1][1][0][0][RTW89_FCC][2] = 46, -+ [1][1][0][0][RTW89_ETSI][2] = 46, -+ [1][1][0][0][RTW89_MKK][2] = 64, -+ [1][1][0][0][RTW89_IC][2] = 46, -+ [1][1][0][0][RTW89_KCC][2] = 58, -+ [1][1][0][0][RTW89_ACMA][2] = 46, -+ [1][1][0][0][RTW89_CHILE][2] = 50, -+ [1][1][0][0][RTW89_UKRAINE][2] = 46, -+ [1][1][0][0][RTW89_MEXICO][2] = 46, -+ [1][1][0][0][RTW89_CN][2] = 46, -+ [1][1][0][0][RTW89_QATAR][2] = 46, -+ [1][1][0][0][RTW89_UK][2] = 46, -+ [1][1][0][0][RTW89_FCC][3] = 46, -+ [1][1][0][0][RTW89_ETSI][3] = 46, -+ [1][1][0][0][RTW89_MKK][3] = 64, -+ [1][1][0][0][RTW89_IC][3] = 46, -+ [1][1][0][0][RTW89_KCC][3] = 58, -+ [1][1][0][0][RTW89_ACMA][3] = 46, -+ [1][1][0][0][RTW89_CHILE][3] = 50, -+ [1][1][0][0][RTW89_UKRAINE][3] = 46, -+ [1][1][0][0][RTW89_MEXICO][3] = 46, -+ [1][1][0][0][RTW89_CN][3] = 46, -+ [1][1][0][0][RTW89_QATAR][3] = 46, -+ [1][1][0][0][RTW89_UK][3] = 46, -+ [1][1][0][0][RTW89_FCC][4] = 46, -+ [1][1][0][0][RTW89_ETSI][4] = 46, -+ [1][1][0][0][RTW89_MKK][4] = 64, -+ [1][1][0][0][RTW89_IC][4] = 46, -+ [1][1][0][0][RTW89_KCC][4] = 58, -+ [1][1][0][0][RTW89_ACMA][4] = 46, -+ [1][1][0][0][RTW89_CHILE][4] = 50, -+ [1][1][0][0][RTW89_UKRAINE][4] = 46, -+ [1][1][0][0][RTW89_MEXICO][4] = 46, -+ [1][1][0][0][RTW89_CN][4] = 46, -+ [1][1][0][0][RTW89_QATAR][4] = 46, -+ [1][1][0][0][RTW89_UK][4] = 46, -+ [1][1][0][0][RTW89_FCC][5] = 62, -+ [1][1][0][0][RTW89_ETSI][5] = 46, -+ [1][1][0][0][RTW89_MKK][5] = 64, -+ [1][1][0][0][RTW89_IC][5] = 62, -+ [1][1][0][0][RTW89_KCC][5] = 58, -+ [1][1][0][0][RTW89_ACMA][5] = 46, -+ [1][1][0][0][RTW89_CHILE][5] = 50, -+ [1][1][0][0][RTW89_UKRAINE][5] = 46, -+ [1][1][0][0][RTW89_MEXICO][5] = 62, -+ [1][1][0][0][RTW89_CN][5] = 46, -+ [1][1][0][0][RTW89_QATAR][5] = 46, -+ [1][1][0][0][RTW89_UK][5] = 46, -+ [1][1][0][0][RTW89_FCC][6] = 34, -+ [1][1][0][0][RTW89_ETSI][6] = 46, -+ [1][1][0][0][RTW89_MKK][6] = 64, -+ [1][1][0][0][RTW89_IC][6] = 34, -+ [1][1][0][0][RTW89_KCC][6] = 58, -+ [1][1][0][0][RTW89_ACMA][6] = 46, -+ [1][1][0][0][RTW89_CHILE][6] = 50, -+ [1][1][0][0][RTW89_UKRAINE][6] = 46, -+ [1][1][0][0][RTW89_MEXICO][6] = 34, -+ [1][1][0][0][RTW89_CN][6] = 46, -+ [1][1][0][0][RTW89_QATAR][6] = 46, -+ [1][1][0][0][RTW89_UK][6] = 46, -+ [1][1][0][0][RTW89_FCC][7] = 34, -+ [1][1][0][0][RTW89_ETSI][7] = 46, -+ [1][1][0][0][RTW89_MKK][7] = 64, -+ [1][1][0][0][RTW89_IC][7] = 34, -+ [1][1][0][0][RTW89_KCC][7] = 58, -+ [1][1][0][0][RTW89_ACMA][7] = 46, -+ [1][1][0][0][RTW89_CHILE][7] = 50, -+ [1][1][0][0][RTW89_UKRAINE][7] = 46, -+ [1][1][0][0][RTW89_MEXICO][7] = 34, -+ [1][1][0][0][RTW89_CN][7] = 46, -+ [1][1][0][0][RTW89_QATAR][7] = 46, -+ [1][1][0][0][RTW89_UK][7] = 46, -+ [1][1][0][0][RTW89_FCC][8] = 34, -+ [1][1][0][0][RTW89_ETSI][8] = 46, -+ [1][1][0][0][RTW89_MKK][8] = 64, -+ [1][1][0][0][RTW89_IC][8] = 34, -+ [1][1][0][0][RTW89_KCC][8] = 58, -+ [1][1][0][0][RTW89_ACMA][8] = 46, -+ [1][1][0][0][RTW89_CHILE][8] = 50, -+ [1][1][0][0][RTW89_UKRAINE][8] = 46, -+ [1][1][0][0][RTW89_MEXICO][8] = 34, -+ [1][1][0][0][RTW89_CN][8] = 46, -+ [1][1][0][0][RTW89_QATAR][8] = 46, -+ [1][1][0][0][RTW89_UK][8] = 46, -+ [1][1][0][0][RTW89_FCC][9] = 30, -+ [1][1][0][0][RTW89_ETSI][9] = 46, -+ [1][1][0][0][RTW89_MKK][9] = 64, -+ [1][1][0][0][RTW89_IC][9] = 30, -+ [1][1][0][0][RTW89_KCC][9] = 58, -+ [1][1][0][0][RTW89_ACMA][9] = 46, -+ [1][1][0][0][RTW89_CHILE][9] = 30, -+ [1][1][0][0][RTW89_UKRAINE][9] = 46, -+ [1][1][0][0][RTW89_MEXICO][9] = 30, -+ [1][1][0][0][RTW89_CN][9] = 46, -+ [1][1][0][0][RTW89_QATAR][9] = 46, -+ [1][1][0][0][RTW89_UK][9] = 46, -+ [1][1][0][0][RTW89_FCC][10] = 30, -+ [1][1][0][0][RTW89_ETSI][10] = 46, -+ [1][1][0][0][RTW89_MKK][10] = 64, -+ [1][1][0][0][RTW89_IC][10] = 30, -+ [1][1][0][0][RTW89_KCC][10] = 58, -+ [1][1][0][0][RTW89_ACMA][10] = 46, -+ [1][1][0][0][RTW89_CHILE][10] = 30, -+ [1][1][0][0][RTW89_UKRAINE][10] = 46, -+ [1][1][0][0][RTW89_MEXICO][10] = 30, -+ [1][1][0][0][RTW89_CN][10] = 46, -+ [1][1][0][0][RTW89_QATAR][10] = 46, -+ [1][1][0][0][RTW89_UK][10] = 46, -+ [1][1][0][0][RTW89_FCC][11] = 127, -+ [1][1][0][0][RTW89_ETSI][11] = 127, -+ [1][1][0][0][RTW89_MKK][11] = 127, -+ [1][1][0][0][RTW89_IC][11] = 127, -+ [1][1][0][0][RTW89_KCC][11] = 127, -+ [1][1][0][0][RTW89_ACMA][11] = 127, -+ [1][1][0][0][RTW89_CHILE][11] = 127, -+ [1][1][0][0][RTW89_UKRAINE][11] = 127, -+ [1][1][0][0][RTW89_MEXICO][11] = 127, -+ [1][1][0][0][RTW89_CN][11] = 127, -+ [1][1][0][0][RTW89_QATAR][11] = 127, -+ [1][1][0][0][RTW89_UK][11] = 127, -+ [1][1][0][0][RTW89_FCC][12] = 127, -+ [1][1][0][0][RTW89_ETSI][12] = 127, -+ [1][1][0][0][RTW89_MKK][12] = 127, -+ [1][1][0][0][RTW89_IC][12] = 127, -+ [1][1][0][0][RTW89_KCC][12] = 127, -+ [1][1][0][0][RTW89_ACMA][12] = 127, -+ [1][1][0][0][RTW89_CHILE][12] = 127, -+ [1][1][0][0][RTW89_UKRAINE][12] = 127, -+ [1][1][0][0][RTW89_MEXICO][12] = 127, -+ [1][1][0][0][RTW89_CN][12] = 127, -+ [1][1][0][0][RTW89_QATAR][12] = 127, -+ [1][1][0][0][RTW89_UK][12] = 127, -+ [1][1][0][0][RTW89_FCC][13] = 127, -+ [1][1][0][0][RTW89_ETSI][13] = 127, -+ [1][1][0][0][RTW89_MKK][13] = 127, -+ [1][1][0][0][RTW89_IC][13] = 127, -+ [1][1][0][0][RTW89_KCC][13] = 127, -+ [1][1][0][0][RTW89_ACMA][13] = 127, -+ [1][1][0][0][RTW89_CHILE][13] = 127, -+ [1][1][0][0][RTW89_UKRAINE][13] = 127, -+ [1][1][0][0][RTW89_MEXICO][13] = 127, -+ [1][1][0][0][RTW89_CN][13] = 127, -+ [1][1][0][0][RTW89_QATAR][13] = 127, -+ [1][1][0][0][RTW89_UK][13] = 127, -+ [0][0][1][0][RTW89_FCC][0] = 76, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 74, -+ [0][0][1][0][RTW89_IC][0] = 76, -+ [0][0][1][0][RTW89_KCC][0] = 76, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CHILE][0] = 66, -+ [0][0][1][0][RTW89_UKRAINE][0] = 58, -+ [0][0][1][0][RTW89_MEXICO][0] = 76, -+ [0][0][1][0][RTW89_CN][0] = 58, -+ [0][0][1][0][RTW89_QATAR][0] = 58, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][1] = 76, -+ [0][0][1][0][RTW89_ETSI][1] = 58, -+ [0][0][1][0][RTW89_MKK][1] = 76, -+ [0][0][1][0][RTW89_IC][1] = 76, -+ [0][0][1][0][RTW89_KCC][1] = 76, -+ [0][0][1][0][RTW89_ACMA][1] = 58, -+ [0][0][1][0][RTW89_CHILE][1] = 66, -+ [0][0][1][0][RTW89_UKRAINE][1] = 58, -+ [0][0][1][0][RTW89_MEXICO][1] = 76, -+ [0][0][1][0][RTW89_CN][1] = 58, -+ [0][0][1][0][RTW89_QATAR][1] = 58, -+ [0][0][1][0][RTW89_UK][1] = 58, -+ [0][0][1][0][RTW89_FCC][2] = 78, -+ [0][0][1][0][RTW89_ETSI][2] = 58, -+ [0][0][1][0][RTW89_MKK][2] = 76, -+ [0][0][1][0][RTW89_IC][2] = 78, -+ [0][0][1][0][RTW89_KCC][2] = 76, -+ [0][0][1][0][RTW89_ACMA][2] = 58, -+ [0][0][1][0][RTW89_CHILE][2] = 66, -+ [0][0][1][0][RTW89_UKRAINE][2] = 58, -+ [0][0][1][0][RTW89_MEXICO][2] = 78, -+ [0][0][1][0][RTW89_CN][2] = 58, -+ [0][0][1][0][RTW89_QATAR][2] = 58, -+ [0][0][1][0][RTW89_UK][2] = 58, -+ [0][0][1][0][RTW89_FCC][3] = 78, -+ [0][0][1][0][RTW89_ETSI][3] = 58, -+ [0][0][1][0][RTW89_MKK][3] = 76, -+ [0][0][1][0][RTW89_IC][3] = 78, -+ [0][0][1][0][RTW89_KCC][3] = 76, -+ [0][0][1][0][RTW89_ACMA][3] = 58, -+ [0][0][1][0][RTW89_CHILE][3] = 66, -+ [0][0][1][0][RTW89_UKRAINE][3] = 58, -+ [0][0][1][0][RTW89_MEXICO][3] = 78, -+ [0][0][1][0][RTW89_CN][3] = 58, -+ [0][0][1][0][RTW89_QATAR][3] = 58, -+ [0][0][1][0][RTW89_UK][3] = 58, -+ [0][0][1][0][RTW89_FCC][4] = 78, -+ [0][0][1][0][RTW89_ETSI][4] = 58, -+ [0][0][1][0][RTW89_MKK][4] = 76, -+ [0][0][1][0][RTW89_IC][4] = 78, -+ [0][0][1][0][RTW89_KCC][4] = 76, -+ [0][0][1][0][RTW89_ACMA][4] = 58, -+ [0][0][1][0][RTW89_CHILE][4] = 66, -+ [0][0][1][0][RTW89_UKRAINE][4] = 58, -+ [0][0][1][0][RTW89_MEXICO][4] = 78, -+ [0][0][1][0][RTW89_CN][4] = 58, -+ [0][0][1][0][RTW89_QATAR][4] = 58, -+ [0][0][1][0][RTW89_UK][4] = 58, -+ [0][0][1][0][RTW89_FCC][5] = 78, -+ [0][0][1][0][RTW89_ETSI][5] = 58, -+ [0][0][1][0][RTW89_MKK][5] = 76, -+ [0][0][1][0][RTW89_IC][5] = 78, -+ [0][0][1][0][RTW89_KCC][5] = 76, -+ [0][0][1][0][RTW89_ACMA][5] = 58, -+ [0][0][1][0][RTW89_CHILE][5] = 66, -+ [0][0][1][0][RTW89_UKRAINE][5] = 58, -+ [0][0][1][0][RTW89_MEXICO][5] = 78, -+ [0][0][1][0][RTW89_CN][5] = 58, -+ [0][0][1][0][RTW89_QATAR][5] = 58, -+ [0][0][1][0][RTW89_UK][5] = 58, -+ [0][0][1][0][RTW89_FCC][6] = 78, -+ [0][0][1][0][RTW89_ETSI][6] = 58, -+ [0][0][1][0][RTW89_MKK][6] = 76, -+ [0][0][1][0][RTW89_IC][6] = 78, -+ [0][0][1][0][RTW89_KCC][6] = 76, -+ [0][0][1][0][RTW89_ACMA][6] = 58, -+ [0][0][1][0][RTW89_CHILE][6] = 66, -+ [0][0][1][0][RTW89_UKRAINE][6] = 58, -+ [0][0][1][0][RTW89_MEXICO][6] = 78, -+ [0][0][1][0][RTW89_CN][6] = 58, -+ [0][0][1][0][RTW89_QATAR][6] = 58, -+ [0][0][1][0][RTW89_UK][6] = 58, -+ [0][0][1][0][RTW89_FCC][7] = 78, -+ [0][0][1][0][RTW89_ETSI][7] = 58, -+ [0][0][1][0][RTW89_MKK][7] = 76, -+ [0][0][1][0][RTW89_IC][7] = 78, -+ [0][0][1][0][RTW89_KCC][7] = 76, -+ [0][0][1][0][RTW89_ACMA][7] = 58, -+ [0][0][1][0][RTW89_CHILE][7] = 66, -+ [0][0][1][0][RTW89_UKRAINE][7] = 58, -+ [0][0][1][0][RTW89_MEXICO][7] = 78, -+ [0][0][1][0][RTW89_CN][7] = 58, -+ [0][0][1][0][RTW89_QATAR][7] = 58, -+ [0][0][1][0][RTW89_UK][7] = 58, -+ [0][0][1][0][RTW89_FCC][8] = 78, -+ [0][0][1][0][RTW89_ETSI][8] = 58, -+ [0][0][1][0][RTW89_MKK][8] = 76, -+ [0][0][1][0][RTW89_IC][8] = 78, -+ [0][0][1][0][RTW89_KCC][8] = 76, -+ [0][0][1][0][RTW89_ACMA][8] = 58, -+ [0][0][1][0][RTW89_CHILE][8] = 66, -+ [0][0][1][0][RTW89_UKRAINE][8] = 58, -+ [0][0][1][0][RTW89_MEXICO][8] = 78, -+ [0][0][1][0][RTW89_CN][8] = 58, -+ [0][0][1][0][RTW89_QATAR][8] = 58, -+ [0][0][1][0][RTW89_UK][8] = 58, -+ [0][0][1][0][RTW89_FCC][9] = 74, -+ [0][0][1][0][RTW89_ETSI][9] = 58, -+ [0][0][1][0][RTW89_MKK][9] = 76, -+ [0][0][1][0][RTW89_IC][9] = 74, -+ [0][0][1][0][RTW89_KCC][9] = 76, -+ [0][0][1][0][RTW89_ACMA][9] = 58, -+ [0][0][1][0][RTW89_CHILE][9] = 66, -+ [0][0][1][0][RTW89_UKRAINE][9] = 58, -+ [0][0][1][0][RTW89_MEXICO][9] = 74, -+ [0][0][1][0][RTW89_CN][9] = 58, -+ [0][0][1][0][RTW89_QATAR][9] = 58, -+ [0][0][1][0][RTW89_UK][9] = 58, -+ [0][0][1][0][RTW89_FCC][10] = 74, -+ [0][0][1][0][RTW89_ETSI][10] = 58, -+ [0][0][1][0][RTW89_MKK][10] = 76, -+ [0][0][1][0][RTW89_IC][10] = 74, -+ [0][0][1][0][RTW89_KCC][10] = 76, -+ [0][0][1][0][RTW89_ACMA][10] = 58, -+ [0][0][1][0][RTW89_CHILE][10] = 66, -+ [0][0][1][0][RTW89_UKRAINE][10] = 58, -+ [0][0][1][0][RTW89_MEXICO][10] = 74, -+ [0][0][1][0][RTW89_CN][10] = 58, -+ [0][0][1][0][RTW89_QATAR][10] = 58, -+ [0][0][1][0][RTW89_UK][10] = 58, -+ [0][0][1][0][RTW89_FCC][11] = 54, -+ [0][0][1][0][RTW89_ETSI][11] = 58, -+ [0][0][1][0][RTW89_MKK][11] = 76, -+ [0][0][1][0][RTW89_IC][11] = 54, -+ [0][0][1][0][RTW89_KCC][11] = 76, -+ [0][0][1][0][RTW89_ACMA][11] = 58, -+ [0][0][1][0][RTW89_CHILE][11] = 54, -+ [0][0][1][0][RTW89_UKRAINE][11] = 58, -+ [0][0][1][0][RTW89_MEXICO][11] = 54, -+ [0][0][1][0][RTW89_CN][11] = 58, -+ [0][0][1][0][RTW89_QATAR][11] = 58, -+ [0][0][1][0][RTW89_UK][11] = 58, -+ [0][0][1][0][RTW89_FCC][12] = 50, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 76, -+ [0][0][1][0][RTW89_IC][12] = 50, -+ [0][0][1][0][RTW89_KCC][12] = 76, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CHILE][12] = 50, -+ [0][0][1][0][RTW89_UKRAINE][12] = 58, -+ [0][0][1][0][RTW89_MEXICO][12] = 50, -+ [0][0][1][0][RTW89_CN][12] = 58, -+ [0][0][1][0][RTW89_QATAR][12] = 58, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][13] = 127, -+ [0][0][1][0][RTW89_ETSI][13] = 127, -+ [0][0][1][0][RTW89_MKK][13] = 127, -+ [0][0][1][0][RTW89_IC][13] = 127, -+ [0][0][1][0][RTW89_KCC][13] = 127, -+ [0][0][1][0][RTW89_ACMA][13] = 127, -+ [0][0][1][0][RTW89_CHILE][13] = 127, -+ [0][0][1][0][RTW89_UKRAINE][13] = 127, -+ [0][0][1][0][RTW89_MEXICO][13] = 127, -+ [0][0][1][0][RTW89_CN][13] = 127, -+ [0][0][1][0][RTW89_QATAR][13] = 127, -+ [0][0][1][0][RTW89_UK][13] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 62, -+ [0][1][1][0][RTW89_ETSI][0] = 46, -+ [0][1][1][0][RTW89_MKK][0] = 64, -+ [0][1][1][0][RTW89_IC][0] = 62, -+ [0][1][1][0][RTW89_KCC][0] = 66, -+ [0][1][1][0][RTW89_ACMA][0] = 46, -+ [0][1][1][0][RTW89_CHILE][0] = 50, -+ [0][1][1][0][RTW89_UKRAINE][0] = 46, -+ [0][1][1][0][RTW89_MEXICO][0] = 62, -+ [0][1][1][0][RTW89_CN][0] = 46, -+ [0][1][1][0][RTW89_QATAR][0] = 46, -+ [0][1][1][0][RTW89_UK][0] = 46, -+ [0][1][1][0][RTW89_FCC][1] = 62, -+ [0][1][1][0][RTW89_ETSI][1] = 46, -+ [0][1][1][0][RTW89_MKK][1] = 64, -+ [0][1][1][0][RTW89_IC][1] = 62, -+ [0][1][1][0][RTW89_KCC][1] = 66, -+ [0][1][1][0][RTW89_ACMA][1] = 46, -+ [0][1][1][0][RTW89_CHILE][1] = 50, -+ [0][1][1][0][RTW89_UKRAINE][1] = 46, -+ [0][1][1][0][RTW89_MEXICO][1] = 62, -+ [0][1][1][0][RTW89_CN][1] = 46, -+ [0][1][1][0][RTW89_QATAR][1] = 46, -+ [0][1][1][0][RTW89_UK][1] = 46, -+ [0][1][1][0][RTW89_FCC][2] = 66, -+ [0][1][1][0][RTW89_ETSI][2] = 46, -+ [0][1][1][0][RTW89_MKK][2] = 64, -+ [0][1][1][0][RTW89_IC][2] = 66, -+ [0][1][1][0][RTW89_KCC][2] = 66, -+ [0][1][1][0][RTW89_ACMA][2] = 46, -+ [0][1][1][0][RTW89_CHILE][2] = 50, -+ [0][1][1][0][RTW89_UKRAINE][2] = 46, -+ [0][1][1][0][RTW89_MEXICO][2] = 66, -+ [0][1][1][0][RTW89_CN][2] = 46, -+ [0][1][1][0][RTW89_QATAR][2] = 46, -+ [0][1][1][0][RTW89_UK][2] = 46, -+ [0][1][1][0][RTW89_FCC][3] = 70, -+ [0][1][1][0][RTW89_ETSI][3] = 46, -+ [0][1][1][0][RTW89_MKK][3] = 64, -+ [0][1][1][0][RTW89_IC][3] = 70, -+ [0][1][1][0][RTW89_KCC][3] = 66, -+ [0][1][1][0][RTW89_ACMA][3] = 46, -+ [0][1][1][0][RTW89_CHILE][3] = 50, -+ [0][1][1][0][RTW89_UKRAINE][3] = 46, -+ [0][1][1][0][RTW89_MEXICO][3] = 70, -+ [0][1][1][0][RTW89_CN][3] = 46, -+ [0][1][1][0][RTW89_QATAR][3] = 46, -+ [0][1][1][0][RTW89_UK][3] = 46, -+ [0][1][1][0][RTW89_FCC][4] = 78, -+ [0][1][1][0][RTW89_ETSI][4] = 46, -+ [0][1][1][0][RTW89_MKK][4] = 64, -+ [0][1][1][0][RTW89_IC][4] = 78, -+ [0][1][1][0][RTW89_KCC][4] = 64, -+ [0][1][1][0][RTW89_ACMA][4] = 46, -+ [0][1][1][0][RTW89_CHILE][4] = 50, -+ [0][1][1][0][RTW89_UKRAINE][4] = 46, -+ [0][1][1][0][RTW89_MEXICO][4] = 78, -+ [0][1][1][0][RTW89_CN][4] = 46, -+ [0][1][1][0][RTW89_QATAR][4] = 46, -+ [0][1][1][0][RTW89_UK][4] = 46, -+ [0][1][1][0][RTW89_FCC][5] = 78, -+ [0][1][1][0][RTW89_ETSI][5] = 46, -+ [0][1][1][0][RTW89_MKK][5] = 64, -+ [0][1][1][0][RTW89_IC][5] = 78, -+ [0][1][1][0][RTW89_KCC][5] = 64, -+ [0][1][1][0][RTW89_ACMA][5] = 46, -+ [0][1][1][0][RTW89_CHILE][5] = 50, -+ [0][1][1][0][RTW89_UKRAINE][5] = 46, -+ [0][1][1][0][RTW89_MEXICO][5] = 78, -+ [0][1][1][0][RTW89_CN][5] = 46, -+ [0][1][1][0][RTW89_QATAR][5] = 46, -+ [0][1][1][0][RTW89_UK][5] = 46, -+ [0][1][1][0][RTW89_FCC][6] = 78, -+ [0][1][1][0][RTW89_ETSI][6] = 46, -+ [0][1][1][0][RTW89_MKK][6] = 64, -+ [0][1][1][0][RTW89_IC][6] = 78, -+ [0][1][1][0][RTW89_KCC][6] = 64, -+ [0][1][1][0][RTW89_ACMA][6] = 46, -+ [0][1][1][0][RTW89_CHILE][6] = 50, -+ [0][1][1][0][RTW89_UKRAINE][6] = 46, -+ [0][1][1][0][RTW89_MEXICO][6] = 78, -+ [0][1][1][0][RTW89_CN][6] = 46, -+ [0][1][1][0][RTW89_QATAR][6] = 46, -+ [0][1][1][0][RTW89_UK][6] = 46, -+ [0][1][1][0][RTW89_FCC][7] = 70, -+ [0][1][1][0][RTW89_ETSI][7] = 46, -+ [0][1][1][0][RTW89_MKK][7] = 64, -+ [0][1][1][0][RTW89_IC][7] = 70, -+ [0][1][1][0][RTW89_KCC][7] = 64, -+ [0][1][1][0][RTW89_ACMA][7] = 46, -+ [0][1][1][0][RTW89_CHILE][7] = 50, -+ [0][1][1][0][RTW89_UKRAINE][7] = 46, -+ [0][1][1][0][RTW89_MEXICO][7] = 70, -+ [0][1][1][0][RTW89_CN][7] = 46, -+ [0][1][1][0][RTW89_QATAR][7] = 46, -+ [0][1][1][0][RTW89_UK][7] = 46, -+ [0][1][1][0][RTW89_FCC][8] = 66, -+ [0][1][1][0][RTW89_ETSI][8] = 46, -+ [0][1][1][0][RTW89_MKK][8] = 64, -+ [0][1][1][0][RTW89_IC][8] = 66, -+ [0][1][1][0][RTW89_KCC][8] = 64, -+ [0][1][1][0][RTW89_ACMA][8] = 46, -+ [0][1][1][0][RTW89_CHILE][8] = 50, -+ [0][1][1][0][RTW89_UKRAINE][8] = 46, -+ [0][1][1][0][RTW89_MEXICO][8] = 66, -+ [0][1][1][0][RTW89_CN][8] = 46, -+ [0][1][1][0][RTW89_QATAR][8] = 46, -+ [0][1][1][0][RTW89_UK][8] = 46, -+ [0][1][1][0][RTW89_FCC][9] = 62, -+ [0][1][1][0][RTW89_ETSI][9] = 46, -+ [0][1][1][0][RTW89_MKK][9] = 64, -+ [0][1][1][0][RTW89_IC][9] = 62, -+ [0][1][1][0][RTW89_KCC][9] = 64, -+ [0][1][1][0][RTW89_ACMA][9] = 46, -+ [0][1][1][0][RTW89_CHILE][9] = 50, -+ [0][1][1][0][RTW89_UKRAINE][9] = 46, -+ [0][1][1][0][RTW89_MEXICO][9] = 62, -+ [0][1][1][0][RTW89_CN][9] = 46, -+ [0][1][1][0][RTW89_QATAR][9] = 46, -+ [0][1][1][0][RTW89_UK][9] = 46, -+ [0][1][1][0][RTW89_FCC][10] = 62, -+ [0][1][1][0][RTW89_ETSI][10] = 46, -+ [0][1][1][0][RTW89_MKK][10] = 64, -+ [0][1][1][0][RTW89_IC][10] = 62, -+ [0][1][1][0][RTW89_KCC][10] = 64, -+ [0][1][1][0][RTW89_ACMA][10] = 46, -+ [0][1][1][0][RTW89_CHILE][10] = 52, -+ [0][1][1][0][RTW89_UKRAINE][10] = 46, -+ [0][1][1][0][RTW89_MEXICO][10] = 62, -+ [0][1][1][0][RTW89_CN][10] = 46, -+ [0][1][1][0][RTW89_QATAR][10] = 46, -+ [0][1][1][0][RTW89_UK][10] = 46, -+ [0][1][1][0][RTW89_FCC][11] = 46, -+ [0][1][1][0][RTW89_ETSI][11] = 46, -+ [0][1][1][0][RTW89_MKK][11] = 64, -+ [0][1][1][0][RTW89_IC][11] = 46, -+ [0][1][1][0][RTW89_KCC][11] = 64, -+ [0][1][1][0][RTW89_ACMA][11] = 46, -+ [0][1][1][0][RTW89_CHILE][11] = 46, -+ [0][1][1][0][RTW89_UKRAINE][11] = 46, -+ [0][1][1][0][RTW89_MEXICO][11] = 46, -+ [0][1][1][0][RTW89_CN][11] = 46, -+ [0][1][1][0][RTW89_QATAR][11] = 46, -+ [0][1][1][0][RTW89_UK][11] = 46, -+ [0][1][1][0][RTW89_FCC][12] = 42, -+ [0][1][1][0][RTW89_ETSI][12] = 46, -+ [0][1][1][0][RTW89_MKK][12] = 64, -+ [0][1][1][0][RTW89_IC][12] = 42, -+ [0][1][1][0][RTW89_KCC][12] = 64, -+ [0][1][1][0][RTW89_ACMA][12] = 46, -+ [0][1][1][0][RTW89_CHILE][12] = 42, -+ [0][1][1][0][RTW89_UKRAINE][12] = 46, -+ [0][1][1][0][RTW89_MEXICO][12] = 42, -+ [0][1][1][0][RTW89_CN][12] = 46, -+ [0][1][1][0][RTW89_QATAR][12] = 46, -+ [0][1][1][0][RTW89_UK][12] = 46, -+ [0][1][1][0][RTW89_FCC][13] = 127, -+ [0][1][1][0][RTW89_ETSI][13] = 127, -+ [0][1][1][0][RTW89_MKK][13] = 127, -+ [0][1][1][0][RTW89_IC][13] = 127, -+ [0][1][1][0][RTW89_KCC][13] = 127, -+ [0][1][1][0][RTW89_ACMA][13] = 127, -+ [0][1][1][0][RTW89_CHILE][13] = 127, -+ [0][1][1][0][RTW89_UKRAINE][13] = 127, -+ [0][1][1][0][RTW89_MEXICO][13] = 127, -+ [0][1][1][0][RTW89_CN][13] = 127, -+ [0][1][1][0][RTW89_QATAR][13] = 127, -+ [0][1][1][0][RTW89_UK][13] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 76, -+ [0][0][2][0][RTW89_ETSI][0] = 58, -+ [0][0][2][0][RTW89_MKK][0] = 76, -+ [0][0][2][0][RTW89_IC][0] = 76, -+ [0][0][2][0][RTW89_KCC][0] = 76, -+ [0][0][2][0][RTW89_ACMA][0] = 58, -+ [0][0][2][0][RTW89_CHILE][0] = 66, -+ [0][0][2][0][RTW89_UKRAINE][0] = 58, -+ [0][0][2][0][RTW89_MEXICO][0] = 76, -+ [0][0][2][0][RTW89_CN][0] = 58, -+ [0][0][2][0][RTW89_QATAR][0] = 58, -+ [0][0][2][0][RTW89_UK][0] = 58, -+ [0][0][2][0][RTW89_FCC][1] = 76, -+ [0][0][2][0][RTW89_ETSI][1] = 58, -+ [0][0][2][0][RTW89_MKK][1] = 76, -+ [0][0][2][0][RTW89_IC][1] = 76, -+ [0][0][2][0][RTW89_KCC][1] = 76, -+ [0][0][2][0][RTW89_ACMA][1] = 58, -+ [0][0][2][0][RTW89_CHILE][1] = 66, -+ [0][0][2][0][RTW89_UKRAINE][1] = 58, -+ [0][0][2][0][RTW89_MEXICO][1] = 76, -+ [0][0][2][0][RTW89_CN][1] = 58, -+ [0][0][2][0][RTW89_QATAR][1] = 58, -+ [0][0][2][0][RTW89_UK][1] = 58, -+ [0][0][2][0][RTW89_FCC][2] = 78, -+ [0][0][2][0][RTW89_ETSI][2] = 58, -+ [0][0][2][0][RTW89_MKK][2] = 76, -+ [0][0][2][0][RTW89_IC][2] = 78, -+ [0][0][2][0][RTW89_KCC][2] = 76, -+ [0][0][2][0][RTW89_ACMA][2] = 58, -+ [0][0][2][0][RTW89_CHILE][2] = 66, -+ [0][0][2][0][RTW89_UKRAINE][2] = 58, -+ [0][0][2][0][RTW89_MEXICO][2] = 78, -+ [0][0][2][0][RTW89_CN][2] = 58, -+ [0][0][2][0][RTW89_QATAR][2] = 58, -+ [0][0][2][0][RTW89_UK][2] = 58, -+ [0][0][2][0][RTW89_FCC][3] = 78, -+ [0][0][2][0][RTW89_ETSI][3] = 58, -+ [0][0][2][0][RTW89_MKK][3] = 76, -+ [0][0][2][0][RTW89_IC][3] = 78, -+ [0][0][2][0][RTW89_KCC][3] = 76, -+ [0][0][2][0][RTW89_ACMA][3] = 58, -+ [0][0][2][0][RTW89_CHILE][3] = 66, -+ [0][0][2][0][RTW89_UKRAINE][3] = 58, -+ [0][0][2][0][RTW89_MEXICO][3] = 78, -+ [0][0][2][0][RTW89_CN][3] = 58, -+ [0][0][2][0][RTW89_QATAR][3] = 58, -+ [0][0][2][0][RTW89_UK][3] = 58, -+ [0][0][2][0][RTW89_FCC][4] = 78, -+ [0][0][2][0][RTW89_ETSI][4] = 58, -+ [0][0][2][0][RTW89_MKK][4] = 76, -+ [0][0][2][0][RTW89_IC][4] = 78, -+ [0][0][2][0][RTW89_KCC][4] = 76, -+ [0][0][2][0][RTW89_ACMA][4] = 58, -+ [0][0][2][0][RTW89_CHILE][4] = 66, -+ [0][0][2][0][RTW89_UKRAINE][4] = 58, -+ [0][0][2][0][RTW89_MEXICO][4] = 78, -+ [0][0][2][0][RTW89_CN][4] = 58, -+ [0][0][2][0][RTW89_QATAR][4] = 58, -+ [0][0][2][0][RTW89_UK][4] = 58, -+ [0][0][2][0][RTW89_FCC][5] = 78, -+ [0][0][2][0][RTW89_ETSI][5] = 58, -+ [0][0][2][0][RTW89_MKK][5] = 76, -+ [0][0][2][0][RTW89_IC][5] = 78, -+ [0][0][2][0][RTW89_KCC][5] = 76, -+ [0][0][2][0][RTW89_ACMA][5] = 58, -+ [0][0][2][0][RTW89_CHILE][5] = 66, -+ [0][0][2][0][RTW89_UKRAINE][5] = 58, -+ [0][0][2][0][RTW89_MEXICO][5] = 78, -+ [0][0][2][0][RTW89_CN][5] = 58, -+ [0][0][2][0][RTW89_QATAR][5] = 58, -+ [0][0][2][0][RTW89_UK][5] = 58, -+ [0][0][2][0][RTW89_FCC][6] = 78, -+ [0][0][2][0][RTW89_ETSI][6] = 58, -+ [0][0][2][0][RTW89_MKK][6] = 76, -+ [0][0][2][0][RTW89_IC][6] = 78, -+ [0][0][2][0][RTW89_KCC][6] = 76, -+ [0][0][2][0][RTW89_ACMA][6] = 58, -+ [0][0][2][0][RTW89_CHILE][6] = 66, -+ [0][0][2][0][RTW89_UKRAINE][6] = 58, -+ [0][0][2][0][RTW89_MEXICO][6] = 78, -+ [0][0][2][0][RTW89_CN][6] = 58, -+ [0][0][2][0][RTW89_QATAR][6] = 58, -+ [0][0][2][0][RTW89_UK][6] = 58, -+ [0][0][2][0][RTW89_FCC][7] = 78, -+ [0][0][2][0][RTW89_ETSI][7] = 58, -+ [0][0][2][0][RTW89_MKK][7] = 76, -+ [0][0][2][0][RTW89_IC][7] = 78, -+ [0][0][2][0][RTW89_KCC][7] = 76, -+ [0][0][2][0][RTW89_ACMA][7] = 58, -+ [0][0][2][0][RTW89_CHILE][7] = 66, -+ [0][0][2][0][RTW89_UKRAINE][7] = 58, -+ [0][0][2][0][RTW89_MEXICO][7] = 78, -+ [0][0][2][0][RTW89_CN][7] = 58, -+ [0][0][2][0][RTW89_QATAR][7] = 58, -+ [0][0][2][0][RTW89_UK][7] = 58, -+ [0][0][2][0][RTW89_FCC][8] = 76, -+ [0][0][2][0][RTW89_ETSI][8] = 58, -+ [0][0][2][0][RTW89_MKK][8] = 76, -+ [0][0][2][0][RTW89_IC][8] = 76, -+ [0][0][2][0][RTW89_KCC][8] = 76, -+ [0][0][2][0][RTW89_ACMA][8] = 58, -+ [0][0][2][0][RTW89_CHILE][8] = 66, -+ [0][0][2][0][RTW89_UKRAINE][8] = 58, -+ [0][0][2][0][RTW89_MEXICO][8] = 76, -+ [0][0][2][0][RTW89_CN][8] = 58, -+ [0][0][2][0][RTW89_QATAR][8] = 58, -+ [0][0][2][0][RTW89_UK][8] = 58, -+ [0][0][2][0][RTW89_FCC][9] = 72, -+ [0][0][2][0][RTW89_ETSI][9] = 58, -+ [0][0][2][0][RTW89_MKK][9] = 76, -+ [0][0][2][0][RTW89_IC][9] = 72, -+ [0][0][2][0][RTW89_KCC][9] = 76, -+ [0][0][2][0][RTW89_ACMA][9] = 58, -+ [0][0][2][0][RTW89_CHILE][9] = 66, -+ [0][0][2][0][RTW89_UKRAINE][9] = 58, -+ [0][0][2][0][RTW89_MEXICO][9] = 72, -+ [0][0][2][0][RTW89_CN][9] = 58, -+ [0][0][2][0][RTW89_QATAR][9] = 58, -+ [0][0][2][0][RTW89_UK][9] = 58, -+ [0][0][2][0][RTW89_FCC][10] = 72, -+ [0][0][2][0][RTW89_ETSI][10] = 58, -+ [0][0][2][0][RTW89_MKK][10] = 76, -+ [0][0][2][0][RTW89_IC][10] = 72, -+ [0][0][2][0][RTW89_KCC][10] = 76, -+ [0][0][2][0][RTW89_ACMA][10] = 58, -+ [0][0][2][0][RTW89_CHILE][10] = 66, -+ [0][0][2][0][RTW89_UKRAINE][10] = 58, -+ [0][0][2][0][RTW89_MEXICO][10] = 72, -+ [0][0][2][0][RTW89_CN][10] = 58, -+ [0][0][2][0][RTW89_QATAR][10] = 58, -+ [0][0][2][0][RTW89_UK][10] = 58, -+ [0][0][2][0][RTW89_FCC][11] = 54, -+ [0][0][2][0][RTW89_ETSI][11] = 58, -+ [0][0][2][0][RTW89_MKK][11] = 76, -+ [0][0][2][0][RTW89_IC][11] = 54, -+ [0][0][2][0][RTW89_KCC][11] = 76, -+ [0][0][2][0][RTW89_ACMA][11] = 58, -+ [0][0][2][0][RTW89_CHILE][11] = 54, -+ [0][0][2][0][RTW89_UKRAINE][11] = 58, -+ [0][0][2][0][RTW89_MEXICO][11] = 54, -+ [0][0][2][0][RTW89_CN][11] = 58, -+ [0][0][2][0][RTW89_QATAR][11] = 58, -+ [0][0][2][0][RTW89_UK][11] = 58, -+ [0][0][2][0][RTW89_FCC][12] = 50, -+ [0][0][2][0][RTW89_ETSI][12] = 58, -+ [0][0][2][0][RTW89_MKK][12] = 76, -+ [0][0][2][0][RTW89_IC][12] = 50, -+ [0][0][2][0][RTW89_KCC][12] = 76, -+ [0][0][2][0][RTW89_ACMA][12] = 58, -+ [0][0][2][0][RTW89_CHILE][12] = 50, -+ [0][0][2][0][RTW89_UKRAINE][12] = 58, -+ [0][0][2][0][RTW89_MEXICO][12] = 50, -+ [0][0][2][0][RTW89_CN][12] = 58, -+ [0][0][2][0][RTW89_QATAR][12] = 58, -+ [0][0][2][0][RTW89_UK][12] = 58, -+ [0][0][2][0][RTW89_FCC][13] = 127, -+ [0][0][2][0][RTW89_ETSI][13] = 127, -+ [0][0][2][0][RTW89_MKK][13] = 127, -+ [0][0][2][0][RTW89_IC][13] = 127, -+ [0][0][2][0][RTW89_KCC][13] = 127, -+ [0][0][2][0][RTW89_ACMA][13] = 127, -+ [0][0][2][0][RTW89_CHILE][13] = 127, -+ [0][0][2][0][RTW89_UKRAINE][13] = 127, -+ [0][0][2][0][RTW89_MEXICO][13] = 127, -+ [0][0][2][0][RTW89_CN][13] = 127, -+ [0][0][2][0][RTW89_QATAR][13] = 127, -+ [0][0][2][0][RTW89_UK][13] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 58, -+ [0][1][2][0][RTW89_ETSI][0] = 46, -+ [0][1][2][0][RTW89_MKK][0] = 66, -+ [0][1][2][0][RTW89_IC][0] = 58, -+ [0][1][2][0][RTW89_KCC][0] = 62, -+ [0][1][2][0][RTW89_ACMA][0] = 46, -+ [0][1][2][0][RTW89_CHILE][0] = 50, -+ [0][1][2][0][RTW89_UKRAINE][0] = 46, -+ [0][1][2][0][RTW89_MEXICO][0] = 58, -+ [0][1][2][0][RTW89_CN][0] = 46, -+ [0][1][2][0][RTW89_QATAR][0] = 46, -+ [0][1][2][0][RTW89_UK][0] = 46, -+ [0][1][2][0][RTW89_FCC][1] = 58, -+ [0][1][2][0][RTW89_ETSI][1] = 46, -+ [0][1][2][0][RTW89_MKK][1] = 66, -+ [0][1][2][0][RTW89_IC][1] = 58, -+ [0][1][2][0][RTW89_KCC][1] = 62, -+ [0][1][2][0][RTW89_ACMA][1] = 46, -+ [0][1][2][0][RTW89_CHILE][1] = 50, -+ [0][1][2][0][RTW89_UKRAINE][1] = 46, -+ [0][1][2][0][RTW89_MEXICO][1] = 58, -+ [0][1][2][0][RTW89_CN][1] = 46, -+ [0][1][2][0][RTW89_QATAR][1] = 46, -+ [0][1][2][0][RTW89_UK][1] = 46, -+ [0][1][2][0][RTW89_FCC][2] = 62, -+ [0][1][2][0][RTW89_ETSI][2] = 46, -+ [0][1][2][0][RTW89_MKK][2] = 66, -+ [0][1][2][0][RTW89_IC][2] = 62, -+ [0][1][2][0][RTW89_KCC][2] = 62, -+ [0][1][2][0][RTW89_ACMA][2] = 46, -+ [0][1][2][0][RTW89_CHILE][2] = 50, -+ [0][1][2][0][RTW89_UKRAINE][2] = 46, -+ [0][1][2][0][RTW89_MEXICO][2] = 62, -+ [0][1][2][0][RTW89_CN][2] = 46, -+ [0][1][2][0][RTW89_QATAR][2] = 46, -+ [0][1][2][0][RTW89_UK][2] = 46, -+ [0][1][2][0][RTW89_FCC][3] = 66, -+ [0][1][2][0][RTW89_ETSI][3] = 46, -+ [0][1][2][0][RTW89_MKK][3] = 66, -+ [0][1][2][0][RTW89_IC][3] = 66, -+ [0][1][2][0][RTW89_KCC][3] = 62, -+ [0][1][2][0][RTW89_ACMA][3] = 46, -+ [0][1][2][0][RTW89_CHILE][3] = 50, -+ [0][1][2][0][RTW89_UKRAINE][3] = 46, -+ [0][1][2][0][RTW89_MEXICO][3] = 66, -+ [0][1][2][0][RTW89_CN][3] = 46, -+ [0][1][2][0][RTW89_QATAR][3] = 46, -+ [0][1][2][0][RTW89_UK][3] = 46, -+ [0][1][2][0][RTW89_FCC][4] = 72, -+ [0][1][2][0][RTW89_ETSI][4] = 46, -+ [0][1][2][0][RTW89_MKK][4] = 66, -+ [0][1][2][0][RTW89_IC][4] = 72, -+ [0][1][2][0][RTW89_KCC][4] = 62, -+ [0][1][2][0][RTW89_ACMA][4] = 46, -+ [0][1][2][0][RTW89_CHILE][4] = 50, -+ [0][1][2][0][RTW89_UKRAINE][4] = 46, -+ [0][1][2][0][RTW89_MEXICO][4] = 72, -+ [0][1][2][0][RTW89_CN][4] = 46, -+ [0][1][2][0][RTW89_QATAR][4] = 46, -+ [0][1][2][0][RTW89_UK][4] = 46, -+ [0][1][2][0][RTW89_FCC][5] = 78, -+ [0][1][2][0][RTW89_ETSI][5] = 46, -+ [0][1][2][0][RTW89_MKK][5] = 66, -+ [0][1][2][0][RTW89_IC][5] = 78, -+ [0][1][2][0][RTW89_KCC][5] = 62, -+ [0][1][2][0][RTW89_ACMA][5] = 46, -+ [0][1][2][0][RTW89_CHILE][5] = 50, -+ [0][1][2][0][RTW89_UKRAINE][5] = 46, -+ [0][1][2][0][RTW89_MEXICO][5] = 78, -+ [0][1][2][0][RTW89_CN][5] = 46, -+ [0][1][2][0][RTW89_QATAR][5] = 46, -+ [0][1][2][0][RTW89_UK][5] = 46, -+ [0][1][2][0][RTW89_FCC][6] = 74, -+ [0][1][2][0][RTW89_ETSI][6] = 46, -+ [0][1][2][0][RTW89_MKK][6] = 66, -+ [0][1][2][0][RTW89_IC][6] = 74, -+ [0][1][2][0][RTW89_KCC][6] = 62, -+ [0][1][2][0][RTW89_ACMA][6] = 46, -+ [0][1][2][0][RTW89_CHILE][6] = 50, -+ [0][1][2][0][RTW89_UKRAINE][6] = 46, -+ [0][1][2][0][RTW89_MEXICO][6] = 74, -+ [0][1][2][0][RTW89_CN][6] = 46, -+ [0][1][2][0][RTW89_QATAR][6] = 46, -+ [0][1][2][0][RTW89_UK][6] = 46, -+ [0][1][2][0][RTW89_FCC][7] = 66, -+ [0][1][2][0][RTW89_ETSI][7] = 46, -+ [0][1][2][0][RTW89_MKK][7] = 66, -+ [0][1][2][0][RTW89_IC][7] = 66, -+ [0][1][2][0][RTW89_KCC][7] = 62, -+ [0][1][2][0][RTW89_ACMA][7] = 46, -+ [0][1][2][0][RTW89_CHILE][7] = 50, -+ [0][1][2][0][RTW89_UKRAINE][7] = 46, -+ [0][1][2][0][RTW89_MEXICO][7] = 66, -+ [0][1][2][0][RTW89_CN][7] = 46, -+ [0][1][2][0][RTW89_QATAR][7] = 46, -+ [0][1][2][0][RTW89_UK][7] = 46, -+ [0][1][2][0][RTW89_FCC][8] = 62, -+ [0][1][2][0][RTW89_ETSI][8] = 46, -+ [0][1][2][0][RTW89_MKK][8] = 66, -+ [0][1][2][0][RTW89_IC][8] = 62, -+ [0][1][2][0][RTW89_KCC][8] = 62, -+ [0][1][2][0][RTW89_ACMA][8] = 46, -+ [0][1][2][0][RTW89_CHILE][8] = 50, -+ [0][1][2][0][RTW89_UKRAINE][8] = 46, -+ [0][1][2][0][RTW89_MEXICO][8] = 62, -+ [0][1][2][0][RTW89_CN][8] = 46, -+ [0][1][2][0][RTW89_QATAR][8] = 46, -+ [0][1][2][0][RTW89_UK][8] = 46, -+ [0][1][2][0][RTW89_FCC][9] = 58, -+ [0][1][2][0][RTW89_ETSI][9] = 46, -+ [0][1][2][0][RTW89_MKK][9] = 66, -+ [0][1][2][0][RTW89_IC][9] = 58, -+ [0][1][2][0][RTW89_KCC][9] = 60, -+ [0][1][2][0][RTW89_ACMA][9] = 46, -+ [0][1][2][0][RTW89_CHILE][9] = 50, -+ [0][1][2][0][RTW89_UKRAINE][9] = 46, -+ [0][1][2][0][RTW89_MEXICO][9] = 58, -+ [0][1][2][0][RTW89_CN][9] = 46, -+ [0][1][2][0][RTW89_QATAR][9] = 46, -+ [0][1][2][0][RTW89_UK][9] = 46, -+ [0][1][2][0][RTW89_FCC][10] = 58, -+ [0][1][2][0][RTW89_ETSI][10] = 46, -+ [0][1][2][0][RTW89_MKK][10] = 66, -+ [0][1][2][0][RTW89_IC][10] = 58, -+ [0][1][2][0][RTW89_KCC][10] = 60, -+ [0][1][2][0][RTW89_ACMA][10] = 46, -+ [0][1][2][0][RTW89_CHILE][10] = 50, -+ [0][1][2][0][RTW89_UKRAINE][10] = 46, -+ [0][1][2][0][RTW89_MEXICO][10] = 58, -+ [0][1][2][0][RTW89_CN][10] = 46, -+ [0][1][2][0][RTW89_QATAR][10] = 46, -+ [0][1][2][0][RTW89_UK][10] = 46, -+ [0][1][2][0][RTW89_FCC][11] = 46, -+ [0][1][2][0][RTW89_ETSI][11] = 46, -+ [0][1][2][0][RTW89_MKK][11] = 66, -+ [0][1][2][0][RTW89_IC][11] = 46, -+ [0][1][2][0][RTW89_KCC][11] = 60, -+ [0][1][2][0][RTW89_ACMA][11] = 46, -+ [0][1][2][0][RTW89_CHILE][11] = 46, -+ [0][1][2][0][RTW89_UKRAINE][11] = 46, -+ [0][1][2][0][RTW89_MEXICO][11] = 46, -+ [0][1][2][0][RTW89_CN][11] = 46, -+ [0][1][2][0][RTW89_QATAR][11] = 46, -+ [0][1][2][0][RTW89_UK][11] = 46, -+ [0][1][2][0][RTW89_FCC][12] = 42, -+ [0][1][2][0][RTW89_ETSI][12] = 46, -+ [0][1][2][0][RTW89_MKK][12] = 66, -+ [0][1][2][0][RTW89_IC][12] = 42, -+ [0][1][2][0][RTW89_KCC][12] = 60, -+ [0][1][2][0][RTW89_ACMA][12] = 46, -+ [0][1][2][0][RTW89_CHILE][12] = 42, -+ [0][1][2][0][RTW89_UKRAINE][12] = 46, -+ [0][1][2][0][RTW89_MEXICO][12] = 42, -+ [0][1][2][0][RTW89_CN][12] = 46, -+ [0][1][2][0][RTW89_QATAR][12] = 46, -+ [0][1][2][0][RTW89_UK][12] = 46, -+ [0][1][2][0][RTW89_FCC][13] = 127, -+ [0][1][2][0][RTW89_ETSI][13] = 127, -+ [0][1][2][0][RTW89_MKK][13] = 127, -+ [0][1][2][0][RTW89_IC][13] = 127, -+ [0][1][2][0][RTW89_KCC][13] = 127, -+ [0][1][2][0][RTW89_ACMA][13] = 127, -+ [0][1][2][0][RTW89_CHILE][13] = 127, -+ [0][1][2][0][RTW89_UKRAINE][13] = 127, -+ [0][1][2][0][RTW89_MEXICO][13] = 127, -+ [0][1][2][0][RTW89_CN][13] = 127, -+ [0][1][2][0][RTW89_QATAR][13] = 127, -+ [0][1][2][0][RTW89_UK][13] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 58, -+ [0][1][2][1][RTW89_ETSI][0] = 34, -+ [0][1][2][1][RTW89_MKK][0] = 66, -+ [0][1][2][1][RTW89_IC][0] = 58, -+ [0][1][2][1][RTW89_KCC][0] = 62, -+ [0][1][2][1][RTW89_ACMA][0] = 34, -+ [0][1][2][1][RTW89_CHILE][0] = 42, -+ [0][1][2][1][RTW89_UKRAINE][0] = 34, -+ [0][1][2][1][RTW89_MEXICO][0] = 58, -+ [0][1][2][1][RTW89_CN][0] = 34, -+ [0][1][2][1][RTW89_QATAR][0] = 34, -+ [0][1][2][1][RTW89_UK][0] = 34, -+ [0][1][2][1][RTW89_FCC][1] = 58, -+ [0][1][2][1][RTW89_ETSI][1] = 34, -+ [0][1][2][1][RTW89_MKK][1] = 66, -+ [0][1][2][1][RTW89_IC][1] = 58, -+ [0][1][2][1][RTW89_KCC][1] = 62, -+ [0][1][2][1][RTW89_ACMA][1] = 34, -+ [0][1][2][1][RTW89_CHILE][1] = 40, -+ [0][1][2][1][RTW89_UKRAINE][1] = 34, -+ [0][1][2][1][RTW89_MEXICO][1] = 58, -+ [0][1][2][1][RTW89_CN][1] = 34, -+ [0][1][2][1][RTW89_QATAR][1] = 34, -+ [0][1][2][1][RTW89_UK][1] = 34, -+ [0][1][2][1][RTW89_FCC][2] = 62, -+ [0][1][2][1][RTW89_ETSI][2] = 34, -+ [0][1][2][1][RTW89_MKK][2] = 66, -+ [0][1][2][1][RTW89_IC][2] = 62, -+ [0][1][2][1][RTW89_KCC][2] = 62, -+ [0][1][2][1][RTW89_ACMA][2] = 34, -+ [0][1][2][1][RTW89_CHILE][2] = 40, -+ [0][1][2][1][RTW89_UKRAINE][2] = 34, -+ [0][1][2][1][RTW89_MEXICO][2] = 62, -+ [0][1][2][1][RTW89_CN][2] = 34, -+ [0][1][2][1][RTW89_QATAR][2] = 34, -+ [0][1][2][1][RTW89_UK][2] = 34, -+ [0][1][2][1][RTW89_FCC][3] = 66, -+ [0][1][2][1][RTW89_ETSI][3] = 34, -+ [0][1][2][1][RTW89_MKK][3] = 66, -+ [0][1][2][1][RTW89_IC][3] = 66, -+ [0][1][2][1][RTW89_KCC][3] = 62, -+ [0][1][2][1][RTW89_ACMA][3] = 34, -+ [0][1][2][1][RTW89_CHILE][3] = 40, -+ [0][1][2][1][RTW89_UKRAINE][3] = 34, -+ [0][1][2][1][RTW89_MEXICO][3] = 66, -+ [0][1][2][1][RTW89_CN][3] = 34, -+ [0][1][2][1][RTW89_QATAR][3] = 34, -+ [0][1][2][1][RTW89_UK][3] = 34, -+ [0][1][2][1][RTW89_FCC][4] = 72, -+ [0][1][2][1][RTW89_ETSI][4] = 34, -+ [0][1][2][1][RTW89_MKK][4] = 66, -+ [0][1][2][1][RTW89_IC][4] = 72, -+ [0][1][2][1][RTW89_KCC][4] = 62, -+ [0][1][2][1][RTW89_ACMA][4] = 34, -+ [0][1][2][1][RTW89_CHILE][4] = 40, -+ [0][1][2][1][RTW89_UKRAINE][4] = 34, -+ [0][1][2][1][RTW89_MEXICO][4] = 72, -+ [0][1][2][1][RTW89_CN][4] = 34, -+ [0][1][2][1][RTW89_QATAR][4] = 34, -+ [0][1][2][1][RTW89_UK][4] = 34, -+ [0][1][2][1][RTW89_FCC][5] = 78, -+ [0][1][2][1][RTW89_ETSI][5] = 34, -+ [0][1][2][1][RTW89_MKK][5] = 66, -+ [0][1][2][1][RTW89_IC][5] = 78, -+ [0][1][2][1][RTW89_KCC][5] = 62, -+ [0][1][2][1][RTW89_ACMA][5] = 34, -+ [0][1][2][1][RTW89_CHILE][5] = 42, -+ [0][1][2][1][RTW89_UKRAINE][5] = 34, -+ [0][1][2][1][RTW89_MEXICO][5] = 78, -+ [0][1][2][1][RTW89_CN][5] = 34, -+ [0][1][2][1][RTW89_QATAR][5] = 34, -+ [0][1][2][1][RTW89_UK][5] = 34, -+ [0][1][2][1][RTW89_FCC][6] = 74, -+ [0][1][2][1][RTW89_ETSI][6] = 34, -+ [0][1][2][1][RTW89_MKK][6] = 66, -+ [0][1][2][1][RTW89_IC][6] = 74, -+ [0][1][2][1][RTW89_KCC][6] = 62, -+ [0][1][2][1][RTW89_ACMA][6] = 34, -+ [0][1][2][1][RTW89_CHILE][6] = 40, -+ [0][1][2][1][RTW89_UKRAINE][6] = 34, -+ [0][1][2][1][RTW89_MEXICO][6] = 74, -+ [0][1][2][1][RTW89_CN][6] = 34, -+ [0][1][2][1][RTW89_QATAR][6] = 34, -+ [0][1][2][1][RTW89_UK][6] = 34, -+ [0][1][2][1][RTW89_FCC][7] = 66, -+ [0][1][2][1][RTW89_ETSI][7] = 34, -+ [0][1][2][1][RTW89_MKK][7] = 66, -+ [0][1][2][1][RTW89_IC][7] = 66, -+ [0][1][2][1][RTW89_KCC][7] = 62, -+ [0][1][2][1][RTW89_ACMA][7] = 34, -+ [0][1][2][1][RTW89_CHILE][7] = 40, -+ [0][1][2][1][RTW89_UKRAINE][7] = 34, -+ [0][1][2][1][RTW89_MEXICO][7] = 66, -+ [0][1][2][1][RTW89_CN][7] = 34, -+ [0][1][2][1][RTW89_QATAR][7] = 34, -+ [0][1][2][1][RTW89_UK][7] = 34, -+ [0][1][2][1][RTW89_FCC][8] = 62, -+ [0][1][2][1][RTW89_ETSI][8] = 34, -+ [0][1][2][1][RTW89_MKK][8] = 66, -+ [0][1][2][1][RTW89_IC][8] = 62, -+ [0][1][2][1][RTW89_KCC][8] = 62, -+ [0][1][2][1][RTW89_ACMA][8] = 34, -+ [0][1][2][1][RTW89_CHILE][8] = 40, -+ [0][1][2][1][RTW89_UKRAINE][8] = 34, -+ [0][1][2][1][RTW89_MEXICO][8] = 62, -+ [0][1][2][1][RTW89_CN][8] = 34, -+ [0][1][2][1][RTW89_QATAR][8] = 34, -+ [0][1][2][1][RTW89_UK][8] = 34, -+ [0][1][2][1][RTW89_FCC][9] = 58, -+ [0][1][2][1][RTW89_ETSI][9] = 34, -+ [0][1][2][1][RTW89_MKK][9] = 66, -+ [0][1][2][1][RTW89_IC][9] = 58, -+ [0][1][2][1][RTW89_KCC][9] = 60, -+ [0][1][2][1][RTW89_ACMA][9] = 34, -+ [0][1][2][1][RTW89_CHILE][9] = 40, -+ [0][1][2][1][RTW89_UKRAINE][9] = 34, -+ [0][1][2][1][RTW89_MEXICO][9] = 58, -+ [0][1][2][1][RTW89_CN][9] = 34, -+ [0][1][2][1][RTW89_QATAR][9] = 34, -+ [0][1][2][1][RTW89_UK][9] = 34, -+ [0][1][2][1][RTW89_FCC][10] = 58, -+ [0][1][2][1][RTW89_ETSI][10] = 34, -+ [0][1][2][1][RTW89_MKK][10] = 66, -+ [0][1][2][1][RTW89_IC][10] = 58, -+ [0][1][2][1][RTW89_KCC][10] = 60, -+ [0][1][2][1][RTW89_ACMA][10] = 34, -+ [0][1][2][1][RTW89_CHILE][10] = 40, -+ [0][1][2][1][RTW89_UKRAINE][10] = 34, -+ [0][1][2][1][RTW89_MEXICO][10] = 58, -+ [0][1][2][1][RTW89_CN][10] = 34, -+ [0][1][2][1][RTW89_QATAR][10] = 34, -+ [0][1][2][1][RTW89_UK][10] = 34, -+ [0][1][2][1][RTW89_FCC][11] = 46, -+ [0][1][2][1][RTW89_ETSI][11] = 34, -+ [0][1][2][1][RTW89_MKK][11] = 66, -+ [0][1][2][1][RTW89_IC][11] = 46, -+ [0][1][2][1][RTW89_KCC][11] = 60, -+ [0][1][2][1][RTW89_ACMA][11] = 34, -+ [0][1][2][1][RTW89_CHILE][11] = 40, -+ [0][1][2][1][RTW89_UKRAINE][11] = 34, -+ [0][1][2][1][RTW89_MEXICO][11] = 46, -+ [0][1][2][1][RTW89_CN][11] = 34, -+ [0][1][2][1][RTW89_QATAR][11] = 34, -+ [0][1][2][1][RTW89_UK][11] = 34, -+ [0][1][2][1][RTW89_FCC][12] = 42, -+ [0][1][2][1][RTW89_ETSI][12] = 34, -+ [0][1][2][1][RTW89_MKK][12] = 66, -+ [0][1][2][1][RTW89_IC][12] = 42, -+ [0][1][2][1][RTW89_KCC][12] = 60, -+ [0][1][2][1][RTW89_ACMA][12] = 34, -+ [0][1][2][1][RTW89_CHILE][12] = 40, -+ [0][1][2][1][RTW89_UKRAINE][12] = 34, -+ [0][1][2][1][RTW89_MEXICO][12] = 42, -+ [0][1][2][1][RTW89_CN][12] = 34, -+ [0][1][2][1][RTW89_QATAR][12] = 34, -+ [0][1][2][1][RTW89_UK][12] = 34, -+ [0][1][2][1][RTW89_FCC][13] = 127, -+ [0][1][2][1][RTW89_ETSI][13] = 127, -+ [0][1][2][1][RTW89_MKK][13] = 127, -+ [0][1][2][1][RTW89_IC][13] = 127, -+ [0][1][2][1][RTW89_KCC][13] = 127, -+ [0][1][2][1][RTW89_ACMA][13] = 127, -+ [0][1][2][1][RTW89_CHILE][13] = 127, -+ [0][1][2][1][RTW89_UKRAINE][13] = 127, -+ [0][1][2][1][RTW89_MEXICO][13] = 127, -+ [0][1][2][1][RTW89_CN][13] = 127, -+ [0][1][2][1][RTW89_QATAR][13] = 127, -+ [0][1][2][1][RTW89_UK][13] = 127, -+ [1][0][2][0][RTW89_FCC][0] = 127, -+ [1][0][2][0][RTW89_ETSI][0] = 127, -+ [1][0][2][0][RTW89_MKK][0] = 127, -+ [1][0][2][0][RTW89_IC][0] = 127, -+ [1][0][2][0][RTW89_KCC][0] = 127, -+ [1][0][2][0][RTW89_ACMA][0] = 127, -+ [1][0][2][0][RTW89_CHILE][0] = 127, -+ [1][0][2][0][RTW89_UKRAINE][0] = 127, -+ [1][0][2][0][RTW89_MEXICO][0] = 127, -+ [1][0][2][0][RTW89_CN][0] = 127, -+ [1][0][2][0][RTW89_QATAR][0] = 127, -+ [1][0][2][0][RTW89_UK][0] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 127, -+ [1][0][2][0][RTW89_ETSI][1] = 127, -+ [1][0][2][0][RTW89_MKK][1] = 127, -+ [1][0][2][0][RTW89_IC][1] = 127, -+ [1][0][2][0][RTW89_KCC][1] = 127, -+ [1][0][2][0][RTW89_ACMA][1] = 127, -+ [1][0][2][0][RTW89_CHILE][1] = 127, -+ [1][0][2][0][RTW89_UKRAINE][1] = 127, -+ [1][0][2][0][RTW89_MEXICO][1] = 127, -+ [1][0][2][0][RTW89_CN][1] = 127, -+ [1][0][2][0][RTW89_QATAR][1] = 127, -+ [1][0][2][0][RTW89_UK][1] = 127, -+ [1][0][2][0][RTW89_FCC][2] = 70, -+ [1][0][2][0][RTW89_ETSI][2] = 58, -+ [1][0][2][0][RTW89_MKK][2] = 74, -+ [1][0][2][0][RTW89_IC][2] = 70, -+ [1][0][2][0][RTW89_KCC][2] = 74, -+ [1][0][2][0][RTW89_ACMA][2] = 58, -+ [1][0][2][0][RTW89_CHILE][2] = 66, -+ [1][0][2][0][RTW89_UKRAINE][2] = 58, -+ [1][0][2][0][RTW89_MEXICO][2] = 70, -+ [1][0][2][0][RTW89_CN][2] = 58, -+ [1][0][2][0][RTW89_QATAR][2] = 58, -+ [1][0][2][0][RTW89_UK][2] = 58, -+ [1][0][2][0][RTW89_FCC][3] = 70, -+ [1][0][2][0][RTW89_ETSI][3] = 58, -+ [1][0][2][0][RTW89_MKK][3] = 74, -+ [1][0][2][0][RTW89_IC][3] = 70, -+ [1][0][2][0][RTW89_KCC][3] = 74, -+ [1][0][2][0][RTW89_ACMA][3] = 58, -+ [1][0][2][0][RTW89_CHILE][3] = 66, -+ [1][0][2][0][RTW89_UKRAINE][3] = 58, -+ [1][0][2][0][RTW89_MEXICO][3] = 70, -+ [1][0][2][0][RTW89_CN][3] = 58, -+ [1][0][2][0][RTW89_QATAR][3] = 58, -+ [1][0][2][0][RTW89_UK][3] = 58, -+ [1][0][2][0][RTW89_FCC][4] = 72, -+ [1][0][2][0][RTW89_ETSI][4] = 58, -+ [1][0][2][0][RTW89_MKK][4] = 74, -+ [1][0][2][0][RTW89_IC][4] = 72, -+ [1][0][2][0][RTW89_KCC][4] = 74, -+ [1][0][2][0][RTW89_ACMA][4] = 58, -+ [1][0][2][0][RTW89_CHILE][4] = 66, -+ [1][0][2][0][RTW89_UKRAINE][4] = 58, -+ [1][0][2][0][RTW89_MEXICO][4] = 72, -+ [1][0][2][0][RTW89_CN][4] = 58, -+ [1][0][2][0][RTW89_QATAR][4] = 58, -+ [1][0][2][0][RTW89_UK][4] = 58, -+ [1][0][2][0][RTW89_FCC][5] = 72, -+ [1][0][2][0][RTW89_ETSI][5] = 58, -+ [1][0][2][0][RTW89_MKK][5] = 74, -+ [1][0][2][0][RTW89_IC][5] = 72, -+ [1][0][2][0][RTW89_KCC][5] = 74, -+ [1][0][2][0][RTW89_ACMA][5] = 58, -+ [1][0][2][0][RTW89_CHILE][5] = 66, -+ [1][0][2][0][RTW89_UKRAINE][5] = 58, -+ [1][0][2][0][RTW89_MEXICO][5] = 72, -+ [1][0][2][0][RTW89_CN][5] = 58, -+ [1][0][2][0][RTW89_QATAR][5] = 58, -+ [1][0][2][0][RTW89_UK][5] = 58, -+ [1][0][2][0][RTW89_FCC][6] = 72, -+ [1][0][2][0][RTW89_ETSI][6] = 58, -+ [1][0][2][0][RTW89_MKK][6] = 74, -+ [1][0][2][0][RTW89_IC][6] = 72, -+ [1][0][2][0][RTW89_KCC][6] = 74, -+ [1][0][2][0][RTW89_ACMA][6] = 58, -+ [1][0][2][0][RTW89_CHILE][6] = 66, -+ [1][0][2][0][RTW89_UKRAINE][6] = 58, -+ [1][0][2][0][RTW89_MEXICO][6] = 72, -+ [1][0][2][0][RTW89_CN][6] = 58, -+ [1][0][2][0][RTW89_QATAR][6] = 58, -+ [1][0][2][0][RTW89_UK][6] = 58, -+ [1][0][2][0][RTW89_FCC][7] = 68, -+ [1][0][2][0][RTW89_ETSI][7] = 58, -+ [1][0][2][0][RTW89_MKK][7] = 74, -+ [1][0][2][0][RTW89_IC][7] = 68, -+ [1][0][2][0][RTW89_KCC][7] = 74, -+ [1][0][2][0][RTW89_ACMA][7] = 58, -+ [1][0][2][0][RTW89_CHILE][7] = 66, -+ [1][0][2][0][RTW89_UKRAINE][7] = 58, -+ [1][0][2][0][RTW89_MEXICO][7] = 68, -+ [1][0][2][0][RTW89_CN][7] = 58, -+ [1][0][2][0][RTW89_QATAR][7] = 58, -+ [1][0][2][0][RTW89_UK][7] = 58, -+ [1][0][2][0][RTW89_FCC][8] = 68, -+ [1][0][2][0][RTW89_ETSI][8] = 58, -+ [1][0][2][0][RTW89_MKK][8] = 74, -+ [1][0][2][0][RTW89_IC][8] = 68, -+ [1][0][2][0][RTW89_KCC][8] = 74, -+ [1][0][2][0][RTW89_ACMA][8] = 58, -+ [1][0][2][0][RTW89_CHILE][8] = 66, -+ [1][0][2][0][RTW89_UKRAINE][8] = 58, -+ [1][0][2][0][RTW89_MEXICO][8] = 68, -+ [1][0][2][0][RTW89_CN][8] = 58, -+ [1][0][2][0][RTW89_QATAR][8] = 58, -+ [1][0][2][0][RTW89_UK][8] = 58, -+ [1][0][2][0][RTW89_FCC][9] = 68, -+ [1][0][2][0][RTW89_ETSI][9] = 58, -+ [1][0][2][0][RTW89_MKK][9] = 74, -+ [1][0][2][0][RTW89_IC][9] = 68, -+ [1][0][2][0][RTW89_KCC][9] = 74, -+ [1][0][2][0][RTW89_ACMA][9] = 58, -+ [1][0][2][0][RTW89_CHILE][9] = 66, -+ [1][0][2][0][RTW89_UKRAINE][9] = 58, -+ [1][0][2][0][RTW89_MEXICO][9] = 68, -+ [1][0][2][0][RTW89_CN][9] = 58, -+ [1][0][2][0][RTW89_QATAR][9] = 58, -+ [1][0][2][0][RTW89_UK][9] = 58, -+ [1][0][2][0][RTW89_FCC][10] = 66, -+ [1][0][2][0][RTW89_ETSI][10] = 58, -+ [1][0][2][0][RTW89_MKK][10] = 74, -+ [1][0][2][0][RTW89_IC][10] = 66, -+ [1][0][2][0][RTW89_KCC][10] = 74, -+ [1][0][2][0][RTW89_ACMA][10] = 58, -+ [1][0][2][0][RTW89_CHILE][10] = 66, -+ [1][0][2][0][RTW89_UKRAINE][10] = 58, -+ [1][0][2][0][RTW89_MEXICO][10] = 66, -+ [1][0][2][0][RTW89_CN][10] = 58, -+ [1][0][2][0][RTW89_QATAR][10] = 58, -+ [1][0][2][0][RTW89_UK][10] = 58, -+ [1][0][2][0][RTW89_FCC][11] = 127, -+ [1][0][2][0][RTW89_ETSI][11] = 127, -+ [1][0][2][0][RTW89_MKK][11] = 127, -+ [1][0][2][0][RTW89_IC][11] = 127, -+ [1][0][2][0][RTW89_KCC][11] = 127, -+ [1][0][2][0][RTW89_ACMA][11] = 127, -+ [1][0][2][0][RTW89_CHILE][11] = 127, -+ [1][0][2][0][RTW89_UKRAINE][11] = 127, -+ [1][0][2][0][RTW89_MEXICO][11] = 127, -+ [1][0][2][0][RTW89_CN][11] = 127, -+ [1][0][2][0][RTW89_QATAR][11] = 127, -+ [1][0][2][0][RTW89_UK][11] = 127, -+ [1][0][2][0][RTW89_FCC][12] = 127, -+ [1][0][2][0][RTW89_ETSI][12] = 127, -+ [1][0][2][0][RTW89_MKK][12] = 127, -+ [1][0][2][0][RTW89_IC][12] = 127, -+ [1][0][2][0][RTW89_KCC][12] = 127, -+ [1][0][2][0][RTW89_ACMA][12] = 127, -+ [1][0][2][0][RTW89_CHILE][12] = 127, -+ [1][0][2][0][RTW89_UKRAINE][12] = 127, -+ [1][0][2][0][RTW89_MEXICO][12] = 127, -+ [1][0][2][0][RTW89_CN][12] = 127, -+ [1][0][2][0][RTW89_QATAR][12] = 127, -+ [1][0][2][0][RTW89_UK][12] = 127, -+ [1][0][2][0][RTW89_FCC][13] = 127, -+ [1][0][2][0][RTW89_ETSI][13] = 127, -+ [1][0][2][0][RTW89_MKK][13] = 127, -+ [1][0][2][0][RTW89_IC][13] = 127, -+ [1][0][2][0][RTW89_KCC][13] = 127, -+ [1][0][2][0][RTW89_ACMA][13] = 127, -+ [1][0][2][0][RTW89_CHILE][13] = 127, -+ [1][0][2][0][RTW89_UKRAINE][13] = 127, -+ [1][0][2][0][RTW89_MEXICO][13] = 127, -+ [1][0][2][0][RTW89_CN][13] = 127, -+ [1][0][2][0][RTW89_QATAR][13] = 127, -+ [1][0][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_FCC][0] = 127, -+ [1][1][2][0][RTW89_ETSI][0] = 127, -+ [1][1][2][0][RTW89_MKK][0] = 127, -+ [1][1][2][0][RTW89_IC][0] = 127, -+ [1][1][2][0][RTW89_KCC][0] = 127, -+ [1][1][2][0][RTW89_ACMA][0] = 127, -+ [1][1][2][0][RTW89_CHILE][0] = 127, -+ [1][1][2][0][RTW89_UKRAINE][0] = 127, -+ [1][1][2][0][RTW89_MEXICO][0] = 127, -+ [1][1][2][0][RTW89_CN][0] = 127, -+ [1][1][2][0][RTW89_QATAR][0] = 127, -+ [1][1][2][0][RTW89_UK][0] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 127, -+ [1][1][2][0][RTW89_ETSI][1] = 127, -+ [1][1][2][0][RTW89_MKK][1] = 127, -+ [1][1][2][0][RTW89_IC][1] = 127, -+ [1][1][2][0][RTW89_KCC][1] = 127, -+ [1][1][2][0][RTW89_ACMA][1] = 127, -+ [1][1][2][0][RTW89_CHILE][1] = 127, -+ [1][1][2][0][RTW89_UKRAINE][1] = 127, -+ [1][1][2][0][RTW89_MEXICO][1] = 127, -+ [1][1][2][0][RTW89_CN][1] = 127, -+ [1][1][2][0][RTW89_QATAR][1] = 127, -+ [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_FCC][2] = 54, -+ [1][1][2][0][RTW89_ETSI][2] = 46, -+ [1][1][2][0][RTW89_MKK][2] = 66, -+ [1][1][2][0][RTW89_IC][2] = 54, -+ [1][1][2][0][RTW89_KCC][2] = 62, -+ [1][1][2][0][RTW89_ACMA][2] = 46, -+ [1][1][2][0][RTW89_CHILE][2] = 52, -+ [1][1][2][0][RTW89_UKRAINE][2] = 46, -+ [1][1][2][0][RTW89_MEXICO][2] = 54, -+ [1][1][2][0][RTW89_CN][2] = 46, -+ [1][1][2][0][RTW89_QATAR][2] = 46, -+ [1][1][2][0][RTW89_UK][2] = 46, -+ [1][1][2][0][RTW89_FCC][3] = 54, -+ [1][1][2][0][RTW89_ETSI][3] = 46, -+ [1][1][2][0][RTW89_MKK][3] = 66, -+ [1][1][2][0][RTW89_IC][3] = 54, -+ [1][1][2][0][RTW89_KCC][3] = 62, -+ [1][1][2][0][RTW89_ACMA][3] = 46, -+ [1][1][2][0][RTW89_CHILE][3] = 52, -+ [1][1][2][0][RTW89_UKRAINE][3] = 46, -+ [1][1][2][0][RTW89_MEXICO][3] = 54, -+ [1][1][2][0][RTW89_CN][3] = 46, -+ [1][1][2][0][RTW89_QATAR][3] = 46, -+ [1][1][2][0][RTW89_UK][3] = 46, -+ [1][1][2][0][RTW89_FCC][4] = 58, -+ [1][1][2][0][RTW89_ETSI][4] = 46, -+ [1][1][2][0][RTW89_MKK][4] = 66, -+ [1][1][2][0][RTW89_IC][4] = 58, -+ [1][1][2][0][RTW89_KCC][4] = 62, -+ [1][1][2][0][RTW89_ACMA][4] = 46, -+ [1][1][2][0][RTW89_CHILE][4] = 52, -+ [1][1][2][0][RTW89_UKRAINE][4] = 46, -+ [1][1][2][0][RTW89_MEXICO][4] = 58, -+ [1][1][2][0][RTW89_CN][4] = 46, -+ [1][1][2][0][RTW89_QATAR][4] = 46, -+ [1][1][2][0][RTW89_UK][4] = 46, -+ [1][1][2][0][RTW89_FCC][5] = 66, -+ [1][1][2][0][RTW89_ETSI][5] = 46, -+ [1][1][2][0][RTW89_MKK][5] = 66, -+ [1][1][2][0][RTW89_IC][5] = 66, -+ [1][1][2][0][RTW89_KCC][5] = 62, -+ [1][1][2][0][RTW89_ACMA][5] = 46, -+ [1][1][2][0][RTW89_CHILE][5] = 54, -+ [1][1][2][0][RTW89_UKRAINE][5] = 46, -+ [1][1][2][0][RTW89_MEXICO][5] = 66, -+ [1][1][2][0][RTW89_CN][5] = 46, -+ [1][1][2][0][RTW89_QATAR][5] = 46, -+ [1][1][2][0][RTW89_UK][5] = 46, -+ [1][1][2][0][RTW89_FCC][6] = 58, -+ [1][1][2][0][RTW89_ETSI][6] = 46, -+ [1][1][2][0][RTW89_MKK][6] = 66, -+ [1][1][2][0][RTW89_IC][6] = 58, -+ [1][1][2][0][RTW89_KCC][6] = 62, -+ [1][1][2][0][RTW89_ACMA][6] = 46, -+ [1][1][2][0][RTW89_CHILE][6] = 52, -+ [1][1][2][0][RTW89_UKRAINE][6] = 46, -+ [1][1][2][0][RTW89_MEXICO][6] = 58, -+ [1][1][2][0][RTW89_CN][6] = 46, -+ [1][1][2][0][RTW89_QATAR][6] = 46, -+ [1][1][2][0][RTW89_UK][6] = 46, -+ [1][1][2][0][RTW89_FCC][7] = 54, -+ [1][1][2][0][RTW89_ETSI][7] = 46, -+ [1][1][2][0][RTW89_MKK][7] = 66, -+ [1][1][2][0][RTW89_IC][7] = 54, -+ [1][1][2][0][RTW89_KCC][7] = 62, -+ [1][1][2][0][RTW89_ACMA][7] = 46, -+ [1][1][2][0][RTW89_CHILE][7] = 52, -+ [1][1][2][0][RTW89_UKRAINE][7] = 46, -+ [1][1][2][0][RTW89_MEXICO][7] = 54, -+ [1][1][2][0][RTW89_CN][7] = 46, -+ [1][1][2][0][RTW89_QATAR][7] = 46, -+ [1][1][2][0][RTW89_UK][7] = 46, -+ [1][1][2][0][RTW89_FCC][8] = 54, -+ [1][1][2][0][RTW89_ETSI][8] = 46, -+ [1][1][2][0][RTW89_MKK][8] = 66, -+ [1][1][2][0][RTW89_IC][8] = 54, -+ [1][1][2][0][RTW89_KCC][8] = 62, -+ [1][1][2][0][RTW89_ACMA][8] = 46, -+ [1][1][2][0][RTW89_CHILE][8] = 52, -+ [1][1][2][0][RTW89_UKRAINE][8] = 46, -+ [1][1][2][0][RTW89_MEXICO][8] = 54, -+ [1][1][2][0][RTW89_CN][8] = 46, -+ [1][1][2][0][RTW89_QATAR][8] = 46, -+ [1][1][2][0][RTW89_UK][8] = 46, -+ [1][1][2][0][RTW89_FCC][9] = 42, -+ [1][1][2][0][RTW89_ETSI][9] = 46, -+ [1][1][2][0][RTW89_MKK][9] = 66, -+ [1][1][2][0][RTW89_IC][9] = 42, -+ [1][1][2][0][RTW89_KCC][9] = 62, -+ [1][1][2][0][RTW89_ACMA][9] = 46, -+ [1][1][2][0][RTW89_CHILE][9] = 42, -+ [1][1][2][0][RTW89_UKRAINE][9] = 46, -+ [1][1][2][0][RTW89_MEXICO][9] = 42, -+ [1][1][2][0][RTW89_CN][9] = 46, -+ [1][1][2][0][RTW89_QATAR][9] = 46, -+ [1][1][2][0][RTW89_UK][9] = 46, -+ [1][1][2][0][RTW89_FCC][10] = 38, -+ [1][1][2][0][RTW89_ETSI][10] = 46, -+ [1][1][2][0][RTW89_MKK][10] = 66, -+ [1][1][2][0][RTW89_IC][10] = 38, -+ [1][1][2][0][RTW89_KCC][10] = 62, -+ [1][1][2][0][RTW89_ACMA][10] = 46, -+ [1][1][2][0][RTW89_CHILE][10] = 38, -+ [1][1][2][0][RTW89_UKRAINE][10] = 46, -+ [1][1][2][0][RTW89_MEXICO][10] = 38, -+ [1][1][2][0][RTW89_CN][10] = 46, -+ [1][1][2][0][RTW89_QATAR][10] = 46, -+ [1][1][2][0][RTW89_UK][10] = 46, -+ [1][1][2][0][RTW89_FCC][11] = 127, -+ [1][1][2][0][RTW89_ETSI][11] = 127, -+ [1][1][2][0][RTW89_MKK][11] = 127, -+ [1][1][2][0][RTW89_IC][11] = 127, -+ [1][1][2][0][RTW89_KCC][11] = 127, -+ [1][1][2][0][RTW89_ACMA][11] = 127, -+ [1][1][2][0][RTW89_CHILE][11] = 127, -+ [1][1][2][0][RTW89_UKRAINE][11] = 127, -+ [1][1][2][0][RTW89_MEXICO][11] = 127, -+ [1][1][2][0][RTW89_CN][11] = 127, -+ [1][1][2][0][RTW89_QATAR][11] = 127, -+ [1][1][2][0][RTW89_UK][11] = 127, -+ [1][1][2][0][RTW89_FCC][12] = 127, -+ [1][1][2][0][RTW89_ETSI][12] = 127, -+ [1][1][2][0][RTW89_MKK][12] = 127, -+ [1][1][2][0][RTW89_IC][12] = 127, -+ [1][1][2][0][RTW89_KCC][12] = 127, -+ [1][1][2][0][RTW89_ACMA][12] = 127, -+ [1][1][2][0][RTW89_CHILE][12] = 127, -+ [1][1][2][0][RTW89_UKRAINE][12] = 127, -+ [1][1][2][0][RTW89_MEXICO][12] = 127, -+ [1][1][2][0][RTW89_CN][12] = 127, -+ [1][1][2][0][RTW89_QATAR][12] = 127, -+ [1][1][2][0][RTW89_UK][12] = 127, -+ [1][1][2][0][RTW89_FCC][13] = 127, -+ [1][1][2][0][RTW89_ETSI][13] = 127, -+ [1][1][2][0][RTW89_MKK][13] = 127, -+ [1][1][2][0][RTW89_IC][13] = 127, -+ [1][1][2][0][RTW89_KCC][13] = 127, -+ [1][1][2][0][RTW89_ACMA][13] = 127, -+ [1][1][2][0][RTW89_CHILE][13] = 127, -+ [1][1][2][0][RTW89_UKRAINE][13] = 127, -+ [1][1][2][0][RTW89_MEXICO][13] = 127, -+ [1][1][2][0][RTW89_CN][13] = 127, -+ [1][1][2][0][RTW89_QATAR][13] = 127, -+ [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_FCC][0] = 127, -+ [1][1][2][1][RTW89_ETSI][0] = 127, -+ [1][1][2][1][RTW89_MKK][0] = 127, -+ [1][1][2][1][RTW89_IC][0] = 127, -+ [1][1][2][1][RTW89_KCC][0] = 127, -+ [1][1][2][1][RTW89_ACMA][0] = 127, -+ [1][1][2][1][RTW89_CHILE][0] = 127, -+ [1][1][2][1][RTW89_UKRAINE][0] = 127, -+ [1][1][2][1][RTW89_MEXICO][0] = 127, -+ [1][1][2][1][RTW89_CN][0] = 127, -+ [1][1][2][1][RTW89_QATAR][0] = 127, -+ [1][1][2][1][RTW89_UK][0] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 127, -+ [1][1][2][1][RTW89_ETSI][1] = 127, -+ [1][1][2][1][RTW89_MKK][1] = 127, -+ [1][1][2][1][RTW89_IC][1] = 127, -+ [1][1][2][1][RTW89_KCC][1] = 127, -+ [1][1][2][1][RTW89_ACMA][1] = 127, -+ [1][1][2][1][RTW89_CHILE][1] = 127, -+ [1][1][2][1][RTW89_UKRAINE][1] = 127, -+ [1][1][2][1][RTW89_MEXICO][1] = 127, -+ [1][1][2][1][RTW89_CN][1] = 127, -+ [1][1][2][1][RTW89_QATAR][1] = 127, -+ [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_FCC][2] = 54, -+ [1][1][2][1][RTW89_ETSI][2] = 34, -+ [1][1][2][1][RTW89_MKK][2] = 66, -+ [1][1][2][1][RTW89_IC][2] = 54, -+ [1][1][2][1][RTW89_KCC][2] = 62, -+ [1][1][2][1][RTW89_ACMA][2] = 34, -+ [1][1][2][1][RTW89_CHILE][2] = 42, -+ [1][1][2][1][RTW89_UKRAINE][2] = 34, -+ [1][1][2][1][RTW89_MEXICO][2] = 54, -+ [1][1][2][1][RTW89_CN][2] = 34, -+ [1][1][2][1][RTW89_QATAR][2] = 34, -+ [1][1][2][1][RTW89_UK][2] = 34, -+ [1][1][2][1][RTW89_FCC][3] = 54, -+ [1][1][2][1][RTW89_ETSI][3] = 34, -+ [1][1][2][1][RTW89_MKK][3] = 66, -+ [1][1][2][1][RTW89_IC][3] = 54, -+ [1][1][2][1][RTW89_KCC][3] = 62, -+ [1][1][2][1][RTW89_ACMA][3] = 34, -+ [1][1][2][1][RTW89_CHILE][3] = 42, -+ [1][1][2][1][RTW89_UKRAINE][3] = 34, -+ [1][1][2][1][RTW89_MEXICO][3] = 54, -+ [1][1][2][1][RTW89_CN][3] = 34, -+ [1][1][2][1][RTW89_QATAR][3] = 34, -+ [1][1][2][1][RTW89_UK][3] = 34, -+ [1][1][2][1][RTW89_FCC][4] = 58, -+ [1][1][2][1][RTW89_ETSI][4] = 34, -+ [1][1][2][1][RTW89_MKK][4] = 66, -+ [1][1][2][1][RTW89_IC][4] = 58, -+ [1][1][2][1][RTW89_KCC][4] = 62, -+ [1][1][2][1][RTW89_ACMA][4] = 34, -+ [1][1][2][1][RTW89_CHILE][4] = 42, -+ [1][1][2][1][RTW89_UKRAINE][4] = 34, -+ [1][1][2][1][RTW89_MEXICO][4] = 58, -+ [1][1][2][1][RTW89_CN][4] = 34, -+ [1][1][2][1][RTW89_QATAR][4] = 34, -+ [1][1][2][1][RTW89_UK][4] = 34, -+ [1][1][2][1][RTW89_FCC][5] = 66, -+ [1][1][2][1][RTW89_ETSI][5] = 34, -+ [1][1][2][1][RTW89_MKK][5] = 66, -+ [1][1][2][1][RTW89_IC][5] = 66, -+ [1][1][2][1][RTW89_KCC][5] = 62, -+ [1][1][2][1][RTW89_ACMA][5] = 34, -+ [1][1][2][1][RTW89_CHILE][5] = 42, -+ [1][1][2][1][RTW89_UKRAINE][5] = 34, -+ [1][1][2][1][RTW89_MEXICO][5] = 66, -+ [1][1][2][1][RTW89_CN][5] = 34, -+ [1][1][2][1][RTW89_QATAR][5] = 34, -+ [1][1][2][1][RTW89_UK][5] = 34, -+ [1][1][2][1][RTW89_FCC][6] = 58, -+ [1][1][2][1][RTW89_ETSI][6] = 34, -+ [1][1][2][1][RTW89_MKK][6] = 66, -+ [1][1][2][1][RTW89_IC][6] = 58, -+ [1][1][2][1][RTW89_KCC][6] = 62, -+ [1][1][2][1][RTW89_ACMA][6] = 34, -+ [1][1][2][1][RTW89_CHILE][6] = 42, -+ [1][1][2][1][RTW89_UKRAINE][6] = 34, -+ [1][1][2][1][RTW89_MEXICO][6] = 58, -+ [1][1][2][1][RTW89_CN][6] = 34, -+ [1][1][2][1][RTW89_QATAR][6] = 34, -+ [1][1][2][1][RTW89_UK][6] = 34, -+ [1][1][2][1][RTW89_FCC][7] = 54, -+ [1][1][2][1][RTW89_ETSI][7] = 34, -+ [1][1][2][1][RTW89_MKK][7] = 66, -+ [1][1][2][1][RTW89_IC][7] = 54, -+ [1][1][2][1][RTW89_KCC][7] = 62, -+ [1][1][2][1][RTW89_ACMA][7] = 34, -+ [1][1][2][1][RTW89_CHILE][7] = 42, -+ [1][1][2][1][RTW89_UKRAINE][7] = 34, -+ [1][1][2][1][RTW89_MEXICO][7] = 54, -+ [1][1][2][1][RTW89_CN][7] = 34, -+ [1][1][2][1][RTW89_QATAR][7] = 34, -+ [1][1][2][1][RTW89_UK][7] = 34, -+ [1][1][2][1][RTW89_FCC][8] = 54, -+ [1][1][2][1][RTW89_ETSI][8] = 34, -+ [1][1][2][1][RTW89_MKK][8] = 66, -+ [1][1][2][1][RTW89_IC][8] = 54, -+ [1][1][2][1][RTW89_KCC][8] = 62, -+ [1][1][2][1][RTW89_ACMA][8] = 34, -+ [1][1][2][1][RTW89_CHILE][8] = 42, -+ [1][1][2][1][RTW89_UKRAINE][8] = 34, -+ [1][1][2][1][RTW89_MEXICO][8] = 54, -+ [1][1][2][1][RTW89_CN][8] = 34, -+ [1][1][2][1][RTW89_QATAR][8] = 34, -+ [1][1][2][1][RTW89_UK][8] = 34, -+ [1][1][2][1][RTW89_FCC][9] = 42, -+ [1][1][2][1][RTW89_ETSI][9] = 34, -+ [1][1][2][1][RTW89_MKK][9] = 66, -+ [1][1][2][1][RTW89_IC][9] = 42, -+ [1][1][2][1][RTW89_KCC][9] = 62, -+ [1][1][2][1][RTW89_ACMA][9] = 34, -+ [1][1][2][1][RTW89_CHILE][9] = 42, -+ [1][1][2][1][RTW89_UKRAINE][9] = 34, -+ [1][1][2][1][RTW89_MEXICO][9] = 42, -+ [1][1][2][1][RTW89_CN][9] = 34, -+ [1][1][2][1][RTW89_QATAR][9] = 34, -+ [1][1][2][1][RTW89_UK][9] = 34, -+ [1][1][2][1][RTW89_FCC][10] = 38, -+ [1][1][2][1][RTW89_ETSI][10] = 34, -+ [1][1][2][1][RTW89_MKK][10] = 66, -+ [1][1][2][1][RTW89_IC][10] = 38, -+ [1][1][2][1][RTW89_KCC][10] = 62, -+ [1][1][2][1][RTW89_ACMA][10] = 34, -+ [1][1][2][1][RTW89_CHILE][10] = 38, -+ [1][1][2][1][RTW89_UKRAINE][10] = 34, -+ [1][1][2][1][RTW89_MEXICO][10] = 38, -+ [1][1][2][1][RTW89_CN][10] = 34, -+ [1][1][2][1][RTW89_QATAR][10] = 34, -+ [1][1][2][1][RTW89_UK][10] = 34, -+ [1][1][2][1][RTW89_FCC][11] = 127, -+ [1][1][2][1][RTW89_ETSI][11] = 127, -+ [1][1][2][1][RTW89_MKK][11] = 127, -+ [1][1][2][1][RTW89_IC][11] = 127, -+ [1][1][2][1][RTW89_KCC][11] = 127, -+ [1][1][2][1][RTW89_ACMA][11] = 127, -+ [1][1][2][1][RTW89_CHILE][11] = 127, -+ [1][1][2][1][RTW89_UKRAINE][11] = 127, -+ [1][1][2][1][RTW89_MEXICO][11] = 127, -+ [1][1][2][1][RTW89_CN][11] = 127, -+ [1][1][2][1][RTW89_QATAR][11] = 127, -+ [1][1][2][1][RTW89_UK][11] = 127, -+ [1][1][2][1][RTW89_FCC][12] = 127, -+ [1][1][2][1][RTW89_ETSI][12] = 127, -+ [1][1][2][1][RTW89_MKK][12] = 127, -+ [1][1][2][1][RTW89_IC][12] = 127, -+ [1][1][2][1][RTW89_KCC][12] = 127, -+ [1][1][2][1][RTW89_ACMA][12] = 127, -+ [1][1][2][1][RTW89_CHILE][12] = 127, -+ [1][1][2][1][RTW89_UKRAINE][12] = 127, -+ [1][1][2][1][RTW89_MEXICO][12] = 127, -+ [1][1][2][1][RTW89_CN][12] = 127, -+ [1][1][2][1][RTW89_QATAR][12] = 127, -+ [1][1][2][1][RTW89_UK][12] = 127, -+ [1][1][2][1][RTW89_FCC][13] = 127, -+ [1][1][2][1][RTW89_ETSI][13] = 127, -+ [1][1][2][1][RTW89_MKK][13] = 127, -+ [1][1][2][1][RTW89_IC][13] = 127, -+ [1][1][2][1][RTW89_KCC][13] = 127, -+ [1][1][2][1][RTW89_ACMA][13] = 127, -+ [1][1][2][1][RTW89_CHILE][13] = 127, -+ [1][1][2][1][RTW89_UKRAINE][13] = 127, -+ [1][1][2][1][RTW89_MEXICO][13] = 127, -+ [1][1][2][1][RTW89_CN][13] = 127, -+ [1][1][2][1][RTW89_QATAR][13] = 127, -+ [1][1][2][1][RTW89_UK][13] = 127, -+}; -+ -+const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][1][0][RTW89_WW][0] = 42, -+ [0][0][1][0][RTW89_WW][2] = 42, -+ [0][0][1][0][RTW89_WW][4] = 42, -+ [0][0][1][0][RTW89_WW][6] = 42, -+ [0][0][1][0][RTW89_WW][8] = 52, -+ [0][0][1][0][RTW89_WW][10] = 52, -+ [0][0][1][0][RTW89_WW][12] = 52, -+ [0][0][1][0][RTW89_WW][14] = 52, -+ [0][0][1][0][RTW89_WW][15] = 52, -+ [0][0][1][0][RTW89_WW][17] = 52, -+ [0][0][1][0][RTW89_WW][19] = 52, -+ [0][0][1][0][RTW89_WW][21] = 52, -+ [0][0][1][0][RTW89_WW][23] = 52, -+ [0][0][1][0][RTW89_WW][25] = 52, -+ [0][0][1][0][RTW89_WW][27] = 52, -+ [0][0][1][0][RTW89_WW][29] = 52, -+ [0][0][1][0][RTW89_WW][31] = 52, -+ [0][0][1][0][RTW89_WW][33] = 52, -+ [0][0][1][0][RTW89_WW][35] = 52, -+ [0][0][1][0][RTW89_WW][37] = 68, -+ [0][0][1][0][RTW89_WW][38] = 28, -+ [0][0][1][0][RTW89_WW][40] = 28, -+ [0][0][1][0][RTW89_WW][42] = 28, -+ [0][0][1][0][RTW89_WW][44] = 28, -+ [0][0][1][0][RTW89_WW][46] = 28, -+ [0][0][1][0][RTW89_WW][48] = 78, -+ [0][0][1][0][RTW89_WW][50] = 78, -+ [0][0][1][0][RTW89_WW][52] = 78, -+ [0][1][1][0][RTW89_WW][0] = 30, -+ [0][1][1][0][RTW89_WW][2] = 32, -+ [0][1][1][0][RTW89_WW][4] = 30, -+ [0][1][1][0][RTW89_WW][6] = 30, -+ [0][1][1][0][RTW89_WW][8] = 40, -+ [0][1][1][0][RTW89_WW][10] = 40, -+ [0][1][1][0][RTW89_WW][12] = 40, -+ [0][1][1][0][RTW89_WW][14] = 40, -+ [0][1][1][0][RTW89_WW][15] = 40, -+ [0][1][1][0][RTW89_WW][17] = 40, -+ [0][1][1][0][RTW89_WW][19] = 40, -+ [0][1][1][0][RTW89_WW][21] = 40, -+ [0][1][1][0][RTW89_WW][23] = 40, -+ [0][1][1][0][RTW89_WW][25] = 40, -+ [0][1][1][0][RTW89_WW][27] = 40, -+ [0][1][1][0][RTW89_WW][29] = 40, -+ [0][1][1][0][RTW89_WW][31] = 40, -+ [0][1][1][0][RTW89_WW][33] = 40, -+ [0][1][1][0][RTW89_WW][35] = 40, -+ [0][1][1][0][RTW89_WW][37] = 50, -+ [0][1][1][0][RTW89_WW][38] = 16, -+ [0][1][1][0][RTW89_WW][40] = 16, -+ [0][1][1][0][RTW89_WW][42] = 16, -+ [0][1][1][0][RTW89_WW][44] = 16, -+ [0][1][1][0][RTW89_WW][46] = 16, -+ [0][1][1][0][RTW89_WW][48] = 56, -+ [0][1][1][0][RTW89_WW][50] = 56, -+ [0][1][1][0][RTW89_WW][52] = 56, -+ [0][0][2][0][RTW89_WW][0] = 42, -+ [0][0][2][0][RTW89_WW][2] = 42, -+ [0][0][2][0][RTW89_WW][4] = 42, -+ [0][0][2][0][RTW89_WW][6] = 42, -+ [0][0][2][0][RTW89_WW][8] = 52, -+ [0][0][2][0][RTW89_WW][10] = 52, -+ [0][0][2][0][RTW89_WW][12] = 52, -+ [0][0][2][0][RTW89_WW][14] = 52, -+ [0][0][2][0][RTW89_WW][15] = 52, -+ [0][0][2][0][RTW89_WW][17] = 52, -+ [0][0][2][0][RTW89_WW][19] = 52, -+ [0][0][2][0][RTW89_WW][21] = 52, -+ [0][0][2][0][RTW89_WW][23] = 52, -+ [0][0][2][0][RTW89_WW][25] = 52, -+ [0][0][2][0][RTW89_WW][27] = 52, -+ [0][0][2][0][RTW89_WW][29] = 52, -+ [0][0][2][0][RTW89_WW][31] = 52, -+ [0][0][2][0][RTW89_WW][33] = 52, -+ [0][0][2][0][RTW89_WW][35] = 52, -+ [0][0][2][0][RTW89_WW][37] = 64, -+ [0][0][2][0][RTW89_WW][38] = 28, -+ [0][0][2][0][RTW89_WW][40] = 28, -+ [0][0][2][0][RTW89_WW][42] = 28, -+ [0][0][2][0][RTW89_WW][44] = 28, -+ [0][0][2][0][RTW89_WW][46] = 28, -+ [0][0][2][0][RTW89_WW][48] = 78, -+ [0][0][2][0][RTW89_WW][50] = 78, -+ [0][0][2][0][RTW89_WW][52] = 78, -+ [0][1][2][0][RTW89_WW][0] = 30, -+ [0][1][2][0][RTW89_WW][2] = 30, -+ [0][1][2][0][RTW89_WW][4] = 30, -+ [0][1][2][0][RTW89_WW][6] = 30, -+ [0][1][2][0][RTW89_WW][8] = 40, -+ [0][1][2][0][RTW89_WW][10] = 40, -+ [0][1][2][0][RTW89_WW][12] = 40, -+ [0][1][2][0][RTW89_WW][14] = 40, -+ [0][1][2][0][RTW89_WW][15] = 40, -+ [0][1][2][0][RTW89_WW][17] = 40, -+ [0][1][2][0][RTW89_WW][19] = 40, -+ [0][1][2][0][RTW89_WW][21] = 40, -+ [0][1][2][0][RTW89_WW][23] = 40, -+ [0][1][2][0][RTW89_WW][25] = 40, -+ [0][1][2][0][RTW89_WW][27] = 40, -+ [0][1][2][0][RTW89_WW][29] = 40, -+ [0][1][2][0][RTW89_WW][31] = 40, -+ [0][1][2][0][RTW89_WW][33] = 40, -+ [0][1][2][0][RTW89_WW][35] = 40, -+ [0][1][2][0][RTW89_WW][37] = 50, -+ [0][1][2][0][RTW89_WW][38] = 16, -+ [0][1][2][0][RTW89_WW][40] = 16, -+ [0][1][2][0][RTW89_WW][42] = 16, -+ [0][1][2][0][RTW89_WW][44] = 16, -+ [0][1][2][0][RTW89_WW][46] = 16, -+ [0][1][2][0][RTW89_WW][48] = 58, -+ [0][1][2][0][RTW89_WW][50] = 58, -+ [0][1][2][0][RTW89_WW][52] = 58, -+ [0][1][2][1][RTW89_WW][0] = 14, -+ [0][1][2][1][RTW89_WW][2] = 14, -+ [0][1][2][1][RTW89_WW][4] = 14, -+ [0][1][2][1][RTW89_WW][6] = 14, -+ [0][1][2][1][RTW89_WW][8] = 28, -+ [0][1][2][1][RTW89_WW][10] = 28, -+ [0][1][2][1][RTW89_WW][12] = 28, -+ [0][1][2][1][RTW89_WW][14] = 28, -+ [0][1][2][1][RTW89_WW][15] = 28, -+ [0][1][2][1][RTW89_WW][17] = 28, -+ [0][1][2][1][RTW89_WW][19] = 28, -+ [0][1][2][1][RTW89_WW][21] = 28, -+ [0][1][2][1][RTW89_WW][23] = 28, -+ [0][1][2][1][RTW89_WW][25] = 28, -+ [0][1][2][1][RTW89_WW][27] = 28, -+ [0][1][2][1][RTW89_WW][29] = 28, -+ [0][1][2][1][RTW89_WW][31] = 28, -+ [0][1][2][1][RTW89_WW][33] = 28, -+ [0][1][2][1][RTW89_WW][35] = 28, -+ [0][1][2][1][RTW89_WW][37] = 36, -+ [0][1][2][1][RTW89_WW][38] = 4, -+ [0][1][2][1][RTW89_WW][40] = 4, -+ [0][1][2][1][RTW89_WW][42] = 4, -+ [0][1][2][1][RTW89_WW][44] = 4, -+ [0][1][2][1][RTW89_WW][46] = 4, -+ [0][1][2][1][RTW89_WW][48] = 58, -+ [0][1][2][1][RTW89_WW][50] = 58, -+ [0][1][2][1][RTW89_WW][52] = 58, -+ [1][0][2][0][RTW89_WW][1] = 42, -+ [1][0][2][0][RTW89_WW][5] = 42, -+ [1][0][2][0][RTW89_WW][9] = 52, -+ [1][0][2][0][RTW89_WW][13] = 52, -+ [1][0][2][0][RTW89_WW][16] = 52, -+ [1][0][2][0][RTW89_WW][20] = 52, -+ [1][0][2][0][RTW89_WW][24] = 52, -+ [1][0][2][0][RTW89_WW][28] = 52, -+ [1][0][2][0][RTW89_WW][32] = 52, -+ [1][0][2][0][RTW89_WW][36] = 64, -+ [1][0][2][0][RTW89_WW][39] = 28, -+ [1][0][2][0][RTW89_WW][43] = 28, -+ [1][0][2][0][RTW89_WW][47] = 78, -+ [1][0][2][0][RTW89_WW][51] = 70, -+ [1][1][2][0][RTW89_WW][1] = 30, -+ [1][1][2][0][RTW89_WW][5] = 30, -+ [1][1][2][0][RTW89_WW][9] = 40, -+ [1][1][2][0][RTW89_WW][13] = 40, -+ [1][1][2][0][RTW89_WW][16] = 40, -+ [1][1][2][0][RTW89_WW][20] = 40, -+ [1][1][2][0][RTW89_WW][24] = 40, -+ [1][1][2][0][RTW89_WW][28] = 40, -+ [1][1][2][0][RTW89_WW][32] = 40, -+ [1][1][2][0][RTW89_WW][36] = 50, -+ [1][1][2][0][RTW89_WW][39] = 16, -+ [1][1][2][0][RTW89_WW][43] = 16, -+ [1][1][2][0][RTW89_WW][47] = 68, -+ [1][1][2][0][RTW89_WW][51] = 66, -+ [1][1][2][1][RTW89_WW][1] = 16, -+ [1][1][2][1][RTW89_WW][5] = 16, -+ [1][1][2][1][RTW89_WW][9] = 28, -+ [1][1][2][1][RTW89_WW][13] = 28, -+ [1][1][2][1][RTW89_WW][16] = 28, -+ [1][1][2][1][RTW89_WW][20] = 28, -+ [1][1][2][1][RTW89_WW][24] = 28, -+ [1][1][2][1][RTW89_WW][28] = 28, -+ [1][1][2][1][RTW89_WW][32] = 28, -+ [1][1][2][1][RTW89_WW][36] = 36, -+ [1][1][2][1][RTW89_WW][39] = 4, -+ [1][1][2][1][RTW89_WW][43] = 4, -+ [1][1][2][1][RTW89_WW][47] = 68, -+ [1][1][2][1][RTW89_WW][51] = 66, -+ [2][0][2][0][RTW89_WW][3] = 42, -+ [2][0][2][0][RTW89_WW][11] = 52, -+ [2][0][2][0][RTW89_WW][18] = 52, -+ [2][0][2][0][RTW89_WW][26] = 52, -+ [2][0][2][0][RTW89_WW][34] = 64, -+ [2][0][2][0][RTW89_WW][41] = 28, -+ [2][0][2][0][RTW89_WW][49] = 64, -+ [2][1][2][0][RTW89_WW][3] = 28, -+ [2][1][2][0][RTW89_WW][11] = 40, -+ [2][1][2][0][RTW89_WW][18] = 40, -+ [2][1][2][0][RTW89_WW][26] = 40, -+ [2][1][2][0][RTW89_WW][34] = 50, -+ [2][1][2][0][RTW89_WW][41] = 16, -+ [2][1][2][0][RTW89_WW][49] = 58, -+ [2][1][2][1][RTW89_WW][3] = 16, -+ [2][1][2][1][RTW89_WW][11] = 28, -+ [2][1][2][1][RTW89_WW][18] = 28, -+ [2][1][2][1][RTW89_WW][26] = 28, -+ [2][1][2][1][RTW89_WW][34] = 34, -+ [2][1][2][1][RTW89_WW][41] = 4, -+ [2][1][2][1][RTW89_WW][49] = 58, -+ [0][0][1][0][RTW89_FCC][0] = 78, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 60, -+ [0][0][1][0][RTW89_IC][0] = 60, -+ [0][0][1][0][RTW89_KCC][0] = 76, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CHILE][0] = 42, -+ [0][0][1][0][RTW89_UKRAINE][0] = 52, -+ [0][0][1][0][RTW89_MEXICO][0] = 62, -+ [0][0][1][0][RTW89_CN][0] = 58, -+ [0][0][1][0][RTW89_QATAR][0] = 58, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][2] = 78, -+ [0][0][1][0][RTW89_ETSI][2] = 58, -+ [0][0][1][0][RTW89_MKK][2] = 60, -+ [0][0][1][0][RTW89_IC][2] = 60, -+ [0][0][1][0][RTW89_KCC][2] = 76, -+ [0][0][1][0][RTW89_ACMA][2] = 58, -+ [0][0][1][0][RTW89_CHILE][2] = 42, -+ [0][0][1][0][RTW89_UKRAINE][2] = 52, -+ [0][0][1][0][RTW89_MEXICO][2] = 62, -+ [0][0][1][0][RTW89_CN][2] = 58, -+ [0][0][1][0][RTW89_QATAR][2] = 58, -+ [0][0][1][0][RTW89_UK][2] = 58, -+ [0][0][1][0][RTW89_FCC][4] = 78, -+ [0][0][1][0][RTW89_ETSI][4] = 58, -+ [0][0][1][0][RTW89_MKK][4] = 60, -+ [0][0][1][0][RTW89_IC][4] = 60, -+ [0][0][1][0][RTW89_KCC][4] = 76, -+ [0][0][1][0][RTW89_ACMA][4] = 58, -+ [0][0][1][0][RTW89_CHILE][4] = 42, -+ [0][0][1][0][RTW89_UKRAINE][4] = 52, -+ [0][0][1][0][RTW89_MEXICO][4] = 62, -+ [0][0][1][0][RTW89_CN][4] = 58, -+ [0][0][1][0][RTW89_QATAR][4] = 58, -+ [0][0][1][0][RTW89_UK][4] = 58, -+ [0][0][1][0][RTW89_FCC][6] = 78, -+ [0][0][1][0][RTW89_ETSI][6] = 58, -+ [0][0][1][0][RTW89_MKK][6] = 60, -+ [0][0][1][0][RTW89_IC][6] = 60, -+ [0][0][1][0][RTW89_KCC][6] = 50, -+ [0][0][1][0][RTW89_ACMA][6] = 58, -+ [0][0][1][0][RTW89_CHILE][6] = 42, -+ [0][0][1][0][RTW89_UKRAINE][6] = 52, -+ [0][0][1][0][RTW89_MEXICO][6] = 62, -+ [0][0][1][0][RTW89_CN][6] = 58, -+ [0][0][1][0][RTW89_QATAR][6] = 58, -+ [0][0][1][0][RTW89_UK][6] = 58, -+ [0][0][1][0][RTW89_FCC][8] = 78, -+ [0][0][1][0][RTW89_ETSI][8] = 58, -+ [0][0][1][0][RTW89_MKK][8] = 62, -+ [0][0][1][0][RTW89_IC][8] = 64, -+ [0][0][1][0][RTW89_KCC][8] = 70, -+ [0][0][1][0][RTW89_ACMA][8] = 58, -+ [0][0][1][0][RTW89_CHILE][8] = 66, -+ [0][0][1][0][RTW89_UKRAINE][8] = 52, -+ [0][0][1][0][RTW89_MEXICO][8] = 78, -+ [0][0][1][0][RTW89_CN][8] = 58, -+ [0][0][1][0][RTW89_QATAR][8] = 58, -+ [0][0][1][0][RTW89_UK][8] = 58, -+ [0][0][1][0][RTW89_FCC][10] = 78, -+ [0][0][1][0][RTW89_ETSI][10] = 58, -+ [0][0][1][0][RTW89_MKK][10] = 62, -+ [0][0][1][0][RTW89_IC][10] = 64, -+ [0][0][1][0][RTW89_KCC][10] = 70, -+ [0][0][1][0][RTW89_ACMA][10] = 58, -+ [0][0][1][0][RTW89_CHILE][10] = 66, -+ [0][0][1][0][RTW89_UKRAINE][10] = 52, -+ [0][0][1][0][RTW89_MEXICO][10] = 78, -+ [0][0][1][0][RTW89_CN][10] = 58, -+ [0][0][1][0][RTW89_QATAR][10] = 58, -+ [0][0][1][0][RTW89_UK][10] = 58, -+ [0][0][1][0][RTW89_FCC][12] = 78, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 62, -+ [0][0][1][0][RTW89_IC][12] = 64, -+ [0][0][1][0][RTW89_KCC][12] = 74, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CHILE][12] = 66, -+ [0][0][1][0][RTW89_UKRAINE][12] = 52, -+ [0][0][1][0][RTW89_MEXICO][12] = 78, -+ [0][0][1][0][RTW89_CN][12] = 58, -+ [0][0][1][0][RTW89_QATAR][12] = 58, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][14] = 78, -+ [0][0][1][0][RTW89_ETSI][14] = 58, -+ [0][0][1][0][RTW89_MKK][14] = 60, -+ [0][0][1][0][RTW89_IC][14] = 64, -+ [0][0][1][0][RTW89_KCC][14] = 74, -+ [0][0][1][0][RTW89_ACMA][14] = 58, -+ [0][0][1][0][RTW89_CHILE][14] = 66, -+ [0][0][1][0][RTW89_UKRAINE][14] = 52, -+ [0][0][1][0][RTW89_MEXICO][14] = 78, -+ [0][0][1][0][RTW89_CN][14] = 58, -+ [0][0][1][0][RTW89_QATAR][14] = 58, -+ [0][0][1][0][RTW89_UK][14] = 58, -+ [0][0][1][0][RTW89_FCC][15] = 76, -+ [0][0][1][0][RTW89_ETSI][15] = 58, -+ [0][0][1][0][RTW89_MKK][15] = 76, -+ [0][0][1][0][RTW89_IC][15] = 76, -+ [0][0][1][0][RTW89_KCC][15] = 74, -+ [0][0][1][0][RTW89_ACMA][15] = 58, -+ [0][0][1][0][RTW89_CHILE][15] = 66, -+ [0][0][1][0][RTW89_UKRAINE][15] = 52, -+ [0][0][1][0][RTW89_MEXICO][15] = 76, -+ [0][0][1][0][RTW89_CN][15] = 127, -+ [0][0][1][0][RTW89_QATAR][15] = 58, -+ [0][0][1][0][RTW89_UK][15] = 58, -+ [0][0][1][0][RTW89_FCC][17] = 78, -+ [0][0][1][0][RTW89_ETSI][17] = 58, -+ [0][0][1][0][RTW89_MKK][17] = 76, -+ [0][0][1][0][RTW89_IC][17] = 78, -+ [0][0][1][0][RTW89_KCC][17] = 74, -+ [0][0][1][0][RTW89_ACMA][17] = 58, -+ [0][0][1][0][RTW89_CHILE][17] = 66, -+ [0][0][1][0][RTW89_UKRAINE][17] = 52, -+ [0][0][1][0][RTW89_MEXICO][17] = 78, -+ [0][0][1][0][RTW89_CN][17] = 127, -+ [0][0][1][0][RTW89_QATAR][17] = 58, -+ [0][0][1][0][RTW89_UK][17] = 58, -+ [0][0][1][0][RTW89_FCC][19] = 78, -+ [0][0][1][0][RTW89_ETSI][19] = 58, -+ [0][0][1][0][RTW89_MKK][19] = 76, -+ [0][0][1][0][RTW89_IC][19] = 78, -+ [0][0][1][0][RTW89_KCC][19] = 74, -+ [0][0][1][0][RTW89_ACMA][19] = 58, -+ [0][0][1][0][RTW89_CHILE][19] = 66, -+ [0][0][1][0][RTW89_UKRAINE][19] = 52, -+ [0][0][1][0][RTW89_MEXICO][19] = 78, -+ [0][0][1][0][RTW89_CN][19] = 127, -+ [0][0][1][0][RTW89_QATAR][19] = 58, -+ [0][0][1][0][RTW89_UK][19] = 58, -+ [0][0][1][0][RTW89_FCC][21] = 78, -+ [0][0][1][0][RTW89_ETSI][21] = 58, -+ [0][0][1][0][RTW89_MKK][21] = 76, -+ [0][0][1][0][RTW89_IC][21] = 78, -+ [0][0][1][0][RTW89_KCC][21] = 74, -+ [0][0][1][0][RTW89_ACMA][21] = 58, -+ [0][0][1][0][RTW89_CHILE][21] = 68, -+ [0][0][1][0][RTW89_UKRAINE][21] = 52, -+ [0][0][1][0][RTW89_MEXICO][21] = 78, -+ [0][0][1][0][RTW89_CN][21] = 127, -+ [0][0][1][0][RTW89_QATAR][21] = 58, -+ [0][0][1][0][RTW89_UK][21] = 58, -+ [0][0][1][0][RTW89_FCC][23] = 78, -+ [0][0][1][0][RTW89_ETSI][23] = 58, -+ [0][0][1][0][RTW89_MKK][23] = 76, -+ [0][0][1][0][RTW89_IC][23] = 78, -+ [0][0][1][0][RTW89_KCC][23] = 74, -+ [0][0][1][0][RTW89_ACMA][23] = 58, -+ [0][0][1][0][RTW89_CHILE][23] = 68, -+ [0][0][1][0][RTW89_UKRAINE][23] = 52, -+ [0][0][1][0][RTW89_MEXICO][23] = 78, -+ [0][0][1][0][RTW89_CN][23] = 127, -+ [0][0][1][0][RTW89_QATAR][23] = 58, -+ [0][0][1][0][RTW89_UK][23] = 58, -+ [0][0][1][0][RTW89_FCC][25] = 78, -+ [0][0][1][0][RTW89_ETSI][25] = 58, -+ [0][0][1][0][RTW89_MKK][25] = 76, -+ [0][0][1][0][RTW89_IC][25] = 127, -+ [0][0][1][0][RTW89_KCC][25] = 74, -+ [0][0][1][0][RTW89_ACMA][25] = 127, -+ [0][0][1][0][RTW89_CHILE][25] = 68, -+ [0][0][1][0][RTW89_UKRAINE][25] = 52, -+ [0][0][1][0][RTW89_MEXICO][25] = 78, -+ [0][0][1][0][RTW89_CN][25] = 127, -+ [0][0][1][0][RTW89_QATAR][25] = 58, -+ [0][0][1][0][RTW89_UK][25] = 58, -+ [0][0][1][0][RTW89_FCC][27] = 78, -+ [0][0][1][0][RTW89_ETSI][27] = 58, -+ [0][0][1][0][RTW89_MKK][27] = 76, -+ [0][0][1][0][RTW89_IC][27] = 127, -+ [0][0][1][0][RTW89_KCC][27] = 74, -+ [0][0][1][0][RTW89_ACMA][27] = 127, -+ [0][0][1][0][RTW89_CHILE][27] = 66, -+ [0][0][1][0][RTW89_UKRAINE][27] = 52, -+ [0][0][1][0][RTW89_MEXICO][27] = 78, -+ [0][0][1][0][RTW89_CN][27] = 127, -+ [0][0][1][0][RTW89_QATAR][27] = 58, -+ [0][0][1][0][RTW89_UK][27] = 58, -+ [0][0][1][0][RTW89_FCC][29] = 78, -+ [0][0][1][0][RTW89_ETSI][29] = 58, -+ [0][0][1][0][RTW89_MKK][29] = 76, -+ [0][0][1][0][RTW89_IC][29] = 127, -+ [0][0][1][0][RTW89_KCC][29] = 74, -+ [0][0][1][0][RTW89_ACMA][29] = 127, -+ [0][0][1][0][RTW89_CHILE][29] = 66, -+ [0][0][1][0][RTW89_UKRAINE][29] = 52, -+ [0][0][1][0][RTW89_MEXICO][29] = 78, -+ [0][0][1][0][RTW89_CN][29] = 127, -+ [0][0][1][0][RTW89_QATAR][29] = 58, -+ [0][0][1][0][RTW89_UK][29] = 58, -+ [0][0][1][0][RTW89_FCC][31] = 78, -+ [0][0][1][0][RTW89_ETSI][31] = 58, -+ [0][0][1][0][RTW89_MKK][31] = 76, -+ [0][0][1][0][RTW89_IC][31] = 78, -+ [0][0][1][0][RTW89_KCC][31] = 72, -+ [0][0][1][0][RTW89_ACMA][31] = 58, -+ [0][0][1][0][RTW89_CHILE][31] = 66, -+ [0][0][1][0][RTW89_UKRAINE][31] = 52, -+ [0][0][1][0][RTW89_MEXICO][31] = 78, -+ [0][0][1][0][RTW89_CN][31] = 127, -+ [0][0][1][0][RTW89_QATAR][31] = 58, -+ [0][0][1][0][RTW89_UK][31] = 58, -+ [0][0][1][0][RTW89_FCC][33] = 78, -+ [0][0][1][0][RTW89_ETSI][33] = 58, -+ [0][0][1][0][RTW89_MKK][33] = 76, -+ [0][0][1][0][RTW89_IC][33] = 78, -+ [0][0][1][0][RTW89_KCC][33] = 72, -+ [0][0][1][0][RTW89_ACMA][33] = 58, -+ [0][0][1][0][RTW89_CHILE][33] = 66, -+ [0][0][1][0][RTW89_UKRAINE][33] = 52, -+ [0][0][1][0][RTW89_MEXICO][33] = 78, -+ [0][0][1][0][RTW89_CN][33] = 127, -+ [0][0][1][0][RTW89_QATAR][33] = 58, -+ [0][0][1][0][RTW89_UK][33] = 58, -+ [0][0][1][0][RTW89_FCC][35] = 70, -+ [0][0][1][0][RTW89_ETSI][35] = 58, -+ [0][0][1][0][RTW89_MKK][35] = 76, -+ [0][0][1][0][RTW89_IC][35] = 70, -+ [0][0][1][0][RTW89_KCC][35] = 72, -+ [0][0][1][0][RTW89_ACMA][35] = 58, -+ [0][0][1][0][RTW89_CHILE][35] = 66, -+ [0][0][1][0][RTW89_UKRAINE][35] = 52, -+ [0][0][1][0][RTW89_MEXICO][35] = 70, -+ [0][0][1][0][RTW89_CN][35] = 127, -+ [0][0][1][0][RTW89_QATAR][35] = 58, -+ [0][0][1][0][RTW89_UK][35] = 58, -+ [0][0][1][0][RTW89_FCC][37] = 78, -+ [0][0][1][0][RTW89_ETSI][37] = 127, -+ [0][0][1][0][RTW89_MKK][37] = 76, -+ [0][0][1][0][RTW89_IC][37] = 78, -+ [0][0][1][0][RTW89_KCC][37] = 72, -+ [0][0][1][0][RTW89_ACMA][37] = 76, -+ [0][0][1][0][RTW89_CHILE][37] = 68, -+ [0][0][1][0][RTW89_UKRAINE][37] = 127, -+ [0][0][1][0][RTW89_MEXICO][37] = 78, -+ [0][0][1][0][RTW89_CN][37] = 127, -+ [0][0][1][0][RTW89_QATAR][37] = 127, -+ [0][0][1][0][RTW89_UK][37] = 76, -+ [0][0][1][0][RTW89_FCC][38] = 78, -+ [0][0][1][0][RTW89_ETSI][38] = 28, -+ [0][0][1][0][RTW89_MKK][38] = 127, -+ [0][0][1][0][RTW89_IC][38] = 78, -+ [0][0][1][0][RTW89_KCC][38] = 74, -+ [0][0][1][0][RTW89_ACMA][38] = 76, -+ [0][0][1][0][RTW89_CHILE][38] = 68, -+ [0][0][1][0][RTW89_UKRAINE][38] = 28, -+ [0][0][1][0][RTW89_MEXICO][38] = 78, -+ [0][0][1][0][RTW89_CN][38] = 76, -+ [0][0][1][0][RTW89_QATAR][38] = 28, -+ [0][0][1][0][RTW89_UK][38] = 58, -+ [0][0][1][0][RTW89_FCC][40] = 78, -+ [0][0][1][0][RTW89_ETSI][40] = 28, -+ [0][0][1][0][RTW89_MKK][40] = 127, -+ [0][0][1][0][RTW89_IC][40] = 78, -+ [0][0][1][0][RTW89_KCC][40] = 74, -+ [0][0][1][0][RTW89_ACMA][40] = 76, -+ [0][0][1][0][RTW89_CHILE][40] = 68, -+ [0][0][1][0][RTW89_UKRAINE][40] = 28, -+ [0][0][1][0][RTW89_MEXICO][40] = 78, -+ [0][0][1][0][RTW89_CN][40] = 76, -+ [0][0][1][0][RTW89_QATAR][40] = 28, -+ [0][0][1][0][RTW89_UK][40] = 58, -+ [0][0][1][0][RTW89_FCC][42] = 78, -+ [0][0][1][0][RTW89_ETSI][42] = 28, -+ [0][0][1][0][RTW89_MKK][42] = 127, -+ [0][0][1][0][RTW89_IC][42] = 78, -+ [0][0][1][0][RTW89_KCC][42] = 74, -+ [0][0][1][0][RTW89_ACMA][42] = 76, -+ [0][0][1][0][RTW89_CHILE][42] = 66, -+ [0][0][1][0][RTW89_UKRAINE][42] = 28, -+ [0][0][1][0][RTW89_MEXICO][42] = 78, -+ [0][0][1][0][RTW89_CN][42] = 76, -+ [0][0][1][0][RTW89_QATAR][42] = 28, -+ [0][0][1][0][RTW89_UK][42] = 58, -+ [0][0][1][0][RTW89_FCC][44] = 78, -+ [0][0][1][0][RTW89_ETSI][44] = 28, -+ [0][0][1][0][RTW89_MKK][44] = 127, -+ [0][0][1][0][RTW89_IC][44] = 78, -+ [0][0][1][0][RTW89_KCC][44] = 74, -+ [0][0][1][0][RTW89_ACMA][44] = 76, -+ [0][0][1][0][RTW89_CHILE][44] = 68, -+ [0][0][1][0][RTW89_UKRAINE][44] = 28, -+ [0][0][1][0][RTW89_MEXICO][44] = 78, -+ [0][0][1][0][RTW89_CN][44] = 76, -+ [0][0][1][0][RTW89_QATAR][44] = 28, -+ [0][0][1][0][RTW89_UK][44] = 58, -+ [0][0][1][0][RTW89_FCC][46] = 78, -+ [0][0][1][0][RTW89_ETSI][46] = 28, -+ [0][0][1][0][RTW89_MKK][46] = 127, -+ [0][0][1][0][RTW89_IC][46] = 78, -+ [0][0][1][0][RTW89_KCC][46] = 74, -+ [0][0][1][0][RTW89_ACMA][46] = 76, -+ [0][0][1][0][RTW89_CHILE][46] = 68, -+ [0][0][1][0][RTW89_UKRAINE][46] = 28, -+ [0][0][1][0][RTW89_MEXICO][46] = 78, -+ [0][0][1][0][RTW89_CN][46] = 76, -+ [0][0][1][0][RTW89_QATAR][46] = 28, -+ [0][0][1][0][RTW89_UK][46] = 58, -+ [0][0][1][0][RTW89_FCC][48] = 78, -+ [0][0][1][0][RTW89_ETSI][48] = 127, -+ [0][0][1][0][RTW89_MKK][48] = 127, -+ [0][0][1][0][RTW89_IC][48] = 127, -+ [0][0][1][0][RTW89_KCC][48] = 127, -+ [0][0][1][0][RTW89_ACMA][48] = 127, -+ [0][0][1][0][RTW89_CHILE][48] = 127, -+ [0][0][1][0][RTW89_UKRAINE][48] = 127, -+ [0][0][1][0][RTW89_MEXICO][48] = 127, -+ [0][0][1][0][RTW89_CN][48] = 127, -+ [0][0][1][0][RTW89_QATAR][48] = 127, -+ [0][0][1][0][RTW89_UK][48] = 127, -+ [0][0][1][0][RTW89_FCC][50] = 78, -+ [0][0][1][0][RTW89_ETSI][50] = 127, -+ [0][0][1][0][RTW89_MKK][50] = 127, -+ [0][0][1][0][RTW89_IC][50] = 127, -+ [0][0][1][0][RTW89_KCC][50] = 127, -+ [0][0][1][0][RTW89_ACMA][50] = 127, -+ [0][0][1][0][RTW89_CHILE][50] = 127, -+ [0][0][1][0][RTW89_UKRAINE][50] = 127, -+ [0][0][1][0][RTW89_MEXICO][50] = 127, -+ [0][0][1][0][RTW89_CN][50] = 127, -+ [0][0][1][0][RTW89_QATAR][50] = 127, -+ [0][0][1][0][RTW89_UK][50] = 127, -+ [0][0][1][0][RTW89_FCC][52] = 78, -+ [0][0][1][0][RTW89_ETSI][52] = 127, -+ [0][0][1][0][RTW89_MKK][52] = 127, -+ [0][0][1][0][RTW89_IC][52] = 127, -+ [0][0][1][0][RTW89_KCC][52] = 127, -+ [0][0][1][0][RTW89_ACMA][52] = 127, -+ [0][0][1][0][RTW89_CHILE][52] = 127, -+ [0][0][1][0][RTW89_UKRAINE][52] = 127, -+ [0][0][1][0][RTW89_MEXICO][52] = 127, -+ [0][0][1][0][RTW89_CN][52] = 127, -+ [0][0][1][0][RTW89_QATAR][52] = 127, -+ [0][0][1][0][RTW89_UK][52] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 68, -+ [0][1][1][0][RTW89_ETSI][0] = 46, -+ [0][1][1][0][RTW89_MKK][0] = 48, -+ [0][1][1][0][RTW89_IC][0] = 40, -+ [0][1][1][0][RTW89_KCC][0] = 64, -+ [0][1][1][0][RTW89_ACMA][0] = 46, -+ [0][1][1][0][RTW89_CHILE][0] = 30, -+ [0][1][1][0][RTW89_UKRAINE][0] = 40, -+ [0][1][1][0][RTW89_MEXICO][0] = 50, -+ [0][1][1][0][RTW89_CN][0] = 46, -+ [0][1][1][0][RTW89_QATAR][0] = 46, -+ [0][1][1][0][RTW89_UK][0] = 46, -+ [0][1][1][0][RTW89_FCC][2] = 68, -+ [0][1][1][0][RTW89_ETSI][2] = 46, -+ [0][1][1][0][RTW89_MKK][2] = 48, -+ [0][1][1][0][RTW89_IC][2] = 40, -+ [0][1][1][0][RTW89_KCC][2] = 64, -+ [0][1][1][0][RTW89_ACMA][2] = 46, -+ [0][1][1][0][RTW89_CHILE][2] = 32, -+ [0][1][1][0][RTW89_UKRAINE][2] = 40, -+ [0][1][1][0][RTW89_MEXICO][2] = 50, -+ [0][1][1][0][RTW89_CN][2] = 46, -+ [0][1][1][0][RTW89_QATAR][2] = 46, -+ [0][1][1][0][RTW89_UK][2] = 46, -+ [0][1][1][0][RTW89_FCC][4] = 68, -+ [0][1][1][0][RTW89_ETSI][4] = 46, -+ [0][1][1][0][RTW89_MKK][4] = 48, -+ [0][1][1][0][RTW89_IC][4] = 40, -+ [0][1][1][0][RTW89_KCC][4] = 64, -+ [0][1][1][0][RTW89_ACMA][4] = 46, -+ [0][1][1][0][RTW89_CHILE][4] = 30, -+ [0][1][1][0][RTW89_UKRAINE][4] = 40, -+ [0][1][1][0][RTW89_MEXICO][4] = 50, -+ [0][1][1][0][RTW89_CN][4] = 46, -+ [0][1][1][0][RTW89_QATAR][4] = 46, -+ [0][1][1][0][RTW89_UK][4] = 46, -+ [0][1][1][0][RTW89_FCC][6] = 68, -+ [0][1][1][0][RTW89_ETSI][6] = 46, -+ [0][1][1][0][RTW89_MKK][6] = 48, -+ [0][1][1][0][RTW89_IC][6] = 40, -+ [0][1][1][0][RTW89_KCC][6] = 38, -+ [0][1][1][0][RTW89_ACMA][6] = 46, -+ [0][1][1][0][RTW89_CHILE][6] = 30, -+ [0][1][1][0][RTW89_UKRAINE][6] = 40, -+ [0][1][1][0][RTW89_MEXICO][6] = 50, -+ [0][1][1][0][RTW89_CN][6] = 46, -+ [0][1][1][0][RTW89_QATAR][6] = 46, -+ [0][1][1][0][RTW89_UK][6] = 46, -+ [0][1][1][0][RTW89_FCC][8] = 68, -+ [0][1][1][0][RTW89_ETSI][8] = 46, -+ [0][1][1][0][RTW89_MKK][8] = 48, -+ [0][1][1][0][RTW89_IC][8] = 52, -+ [0][1][1][0][RTW89_KCC][8] = 64, -+ [0][1][1][0][RTW89_ACMA][8] = 46, -+ [0][1][1][0][RTW89_CHILE][8] = 52, -+ [0][1][1][0][RTW89_UKRAINE][8] = 40, -+ [0][1][1][0][RTW89_MEXICO][8] = 68, -+ [0][1][1][0][RTW89_CN][8] = 46, -+ [0][1][1][0][RTW89_QATAR][8] = 46, -+ [0][1][1][0][RTW89_UK][8] = 46, -+ [0][1][1][0][RTW89_FCC][10] = 68, -+ [0][1][1][0][RTW89_ETSI][10] = 46, -+ [0][1][1][0][RTW89_MKK][10] = 48, -+ [0][1][1][0][RTW89_IC][10] = 52, -+ [0][1][1][0][RTW89_KCC][10] = 64, -+ [0][1][1][0][RTW89_ACMA][10] = 46, -+ [0][1][1][0][RTW89_CHILE][10] = 52, -+ [0][1][1][0][RTW89_UKRAINE][10] = 40, -+ [0][1][1][0][RTW89_MEXICO][10] = 68, -+ [0][1][1][0][RTW89_CN][10] = 46, -+ [0][1][1][0][RTW89_QATAR][10] = 46, -+ [0][1][1][0][RTW89_UK][10] = 46, -+ [0][1][1][0][RTW89_FCC][12] = 68, -+ [0][1][1][0][RTW89_ETSI][12] = 46, -+ [0][1][1][0][RTW89_MKK][12] = 48, -+ [0][1][1][0][RTW89_IC][12] = 52, -+ [0][1][1][0][RTW89_KCC][12] = 64, -+ [0][1][1][0][RTW89_ACMA][12] = 46, -+ [0][1][1][0][RTW89_CHILE][12] = 52, -+ [0][1][1][0][RTW89_UKRAINE][12] = 40, -+ [0][1][1][0][RTW89_MEXICO][12] = 68, -+ [0][1][1][0][RTW89_CN][12] = 46, -+ [0][1][1][0][RTW89_QATAR][12] = 46, -+ [0][1][1][0][RTW89_UK][12] = 46, -+ [0][1][1][0][RTW89_FCC][14] = 68, -+ [0][1][1][0][RTW89_ETSI][14] = 46, -+ [0][1][1][0][RTW89_MKK][14] = 48, -+ [0][1][1][0][RTW89_IC][14] = 52, -+ [0][1][1][0][RTW89_KCC][14] = 64, -+ [0][1][1][0][RTW89_ACMA][14] = 46, -+ [0][1][1][0][RTW89_CHILE][14] = 52, -+ [0][1][1][0][RTW89_UKRAINE][14] = 40, -+ [0][1][1][0][RTW89_MEXICO][14] = 68, -+ [0][1][1][0][RTW89_CN][14] = 46, -+ [0][1][1][0][RTW89_QATAR][14] = 46, -+ [0][1][1][0][RTW89_UK][14] = 46, -+ [0][1][1][0][RTW89_FCC][15] = 66, -+ [0][1][1][0][RTW89_ETSI][15] = 46, -+ [0][1][1][0][RTW89_MKK][15] = 68, -+ [0][1][1][0][RTW89_IC][15] = 66, -+ [0][1][1][0][RTW89_KCC][15] = 62, -+ [0][1][1][0][RTW89_ACMA][15] = 46, -+ [0][1][1][0][RTW89_CHILE][15] = 48, -+ [0][1][1][0][RTW89_UKRAINE][15] = 40, -+ [0][1][1][0][RTW89_MEXICO][15] = 66, -+ [0][1][1][0][RTW89_CN][15] = 127, -+ [0][1][1][0][RTW89_QATAR][15] = 46, -+ [0][1][1][0][RTW89_UK][15] = 46, -+ [0][1][1][0][RTW89_FCC][17] = 68, -+ [0][1][1][0][RTW89_ETSI][17] = 46, -+ [0][1][1][0][RTW89_MKK][17] = 70, -+ [0][1][1][0][RTW89_IC][17] = 68, -+ [0][1][1][0][RTW89_KCC][17] = 62, -+ [0][1][1][0][RTW89_ACMA][17] = 46, -+ [0][1][1][0][RTW89_CHILE][17] = 48, -+ [0][1][1][0][RTW89_UKRAINE][17] = 40, -+ [0][1][1][0][RTW89_MEXICO][17] = 68, -+ [0][1][1][0][RTW89_CN][17] = 127, -+ [0][1][1][0][RTW89_QATAR][17] = 46, -+ [0][1][1][0][RTW89_UK][17] = 46, -+ [0][1][1][0][RTW89_FCC][19] = 68, -+ [0][1][1][0][RTW89_ETSI][19] = 46, -+ [0][1][1][0][RTW89_MKK][19] = 70, -+ [0][1][1][0][RTW89_IC][19] = 68, -+ [0][1][1][0][RTW89_KCC][19] = 62, -+ [0][1][1][0][RTW89_ACMA][19] = 46, -+ [0][1][1][0][RTW89_CHILE][19] = 48, -+ [0][1][1][0][RTW89_UKRAINE][19] = 40, -+ [0][1][1][0][RTW89_MEXICO][19] = 68, -+ [0][1][1][0][RTW89_CN][19] = 127, -+ [0][1][1][0][RTW89_QATAR][19] = 46, -+ [0][1][1][0][RTW89_UK][19] = 46, -+ [0][1][1][0][RTW89_FCC][21] = 68, -+ [0][1][1][0][RTW89_ETSI][21] = 46, -+ [0][1][1][0][RTW89_MKK][21] = 70, -+ [0][1][1][0][RTW89_IC][21] = 68, -+ [0][1][1][0][RTW89_KCC][21] = 62, -+ [0][1][1][0][RTW89_ACMA][21] = 46, -+ [0][1][1][0][RTW89_CHILE][21] = 48, -+ [0][1][1][0][RTW89_UKRAINE][21] = 40, -+ [0][1][1][0][RTW89_MEXICO][21] = 68, -+ [0][1][1][0][RTW89_CN][21] = 127, -+ [0][1][1][0][RTW89_QATAR][21] = 46, -+ [0][1][1][0][RTW89_UK][21] = 46, -+ [0][1][1][0][RTW89_FCC][23] = 68, -+ [0][1][1][0][RTW89_ETSI][23] = 46, -+ [0][1][1][0][RTW89_MKK][23] = 70, -+ [0][1][1][0][RTW89_IC][23] = 68, -+ [0][1][1][0][RTW89_KCC][23] = 62, -+ [0][1][1][0][RTW89_ACMA][23] = 46, -+ [0][1][1][0][RTW89_CHILE][23] = 48, -+ [0][1][1][0][RTW89_UKRAINE][23] = 40, -+ [0][1][1][0][RTW89_MEXICO][23] = 68, -+ [0][1][1][0][RTW89_CN][23] = 127, -+ [0][1][1][0][RTW89_QATAR][23] = 46, -+ [0][1][1][0][RTW89_UK][23] = 46, -+ [0][1][1][0][RTW89_FCC][25] = 68, -+ [0][1][1][0][RTW89_ETSI][25] = 46, -+ [0][1][1][0][RTW89_MKK][25] = 68, -+ [0][1][1][0][RTW89_IC][25] = 127, -+ [0][1][1][0][RTW89_KCC][25] = 62, -+ [0][1][1][0][RTW89_ACMA][25] = 127, -+ [0][1][1][0][RTW89_CHILE][25] = 48, -+ [0][1][1][0][RTW89_UKRAINE][25] = 40, -+ [0][1][1][0][RTW89_MEXICO][25] = 68, -+ [0][1][1][0][RTW89_CN][25] = 127, -+ [0][1][1][0][RTW89_QATAR][25] = 46, -+ [0][1][1][0][RTW89_UK][25] = 46, -+ [0][1][1][0][RTW89_FCC][27] = 68, -+ [0][1][1][0][RTW89_ETSI][27] = 46, -+ [0][1][1][0][RTW89_MKK][27] = 70, -+ [0][1][1][0][RTW89_IC][27] = 127, -+ [0][1][1][0][RTW89_KCC][27] = 62, -+ [0][1][1][0][RTW89_ACMA][27] = 127, -+ [0][1][1][0][RTW89_CHILE][27] = 50, -+ [0][1][1][0][RTW89_UKRAINE][27] = 40, -+ [0][1][1][0][RTW89_MEXICO][27] = 68, -+ [0][1][1][0][RTW89_CN][27] = 127, -+ [0][1][1][0][RTW89_QATAR][27] = 46, -+ [0][1][1][0][RTW89_UK][27] = 46, -+ [0][1][1][0][RTW89_FCC][29] = 68, -+ [0][1][1][0][RTW89_ETSI][29] = 46, -+ [0][1][1][0][RTW89_MKK][29] = 70, -+ [0][1][1][0][RTW89_IC][29] = 127, -+ [0][1][1][0][RTW89_KCC][29] = 62, -+ [0][1][1][0][RTW89_ACMA][29] = 127, -+ [0][1][1][0][RTW89_CHILE][29] = 50, -+ [0][1][1][0][RTW89_UKRAINE][29] = 40, -+ [0][1][1][0][RTW89_MEXICO][29] = 68, -+ [0][1][1][0][RTW89_CN][29] = 127, -+ [0][1][1][0][RTW89_QATAR][29] = 46, -+ [0][1][1][0][RTW89_UK][29] = 46, -+ [0][1][1][0][RTW89_FCC][31] = 68, -+ [0][1][1][0][RTW89_ETSI][31] = 46, -+ [0][1][1][0][RTW89_MKK][31] = 70, -+ [0][1][1][0][RTW89_IC][31] = 68, -+ [0][1][1][0][RTW89_KCC][31] = 62, -+ [0][1][1][0][RTW89_ACMA][31] = 46, -+ [0][1][1][0][RTW89_CHILE][31] = 50, -+ [0][1][1][0][RTW89_UKRAINE][31] = 40, -+ [0][1][1][0][RTW89_MEXICO][31] = 68, -+ [0][1][1][0][RTW89_CN][31] = 127, -+ [0][1][1][0][RTW89_QATAR][31] = 46, -+ [0][1][1][0][RTW89_UK][31] = 46, -+ [0][1][1][0][RTW89_FCC][33] = 68, -+ [0][1][1][0][RTW89_ETSI][33] = 46, -+ [0][1][1][0][RTW89_MKK][33] = 70, -+ [0][1][1][0][RTW89_IC][33] = 68, -+ [0][1][1][0][RTW89_KCC][33] = 62, -+ [0][1][1][0][RTW89_ACMA][33] = 46, -+ [0][1][1][0][RTW89_CHILE][33] = 50, -+ [0][1][1][0][RTW89_UKRAINE][33] = 40, -+ [0][1][1][0][RTW89_MEXICO][33] = 68, -+ [0][1][1][0][RTW89_CN][33] = 127, -+ [0][1][1][0][RTW89_QATAR][33] = 46, -+ [0][1][1][0][RTW89_UK][33] = 46, -+ [0][1][1][0][RTW89_FCC][35] = 66, -+ [0][1][1][0][RTW89_ETSI][35] = 46, -+ [0][1][1][0][RTW89_MKK][35] = 70, -+ [0][1][1][0][RTW89_IC][35] = 66, -+ [0][1][1][0][RTW89_KCC][35] = 62, -+ [0][1][1][0][RTW89_ACMA][35] = 46, -+ [0][1][1][0][RTW89_CHILE][35] = 50, -+ [0][1][1][0][RTW89_UKRAINE][35] = 40, -+ [0][1][1][0][RTW89_MEXICO][35] = 66, -+ [0][1][1][0][RTW89_CN][35] = 127, -+ [0][1][1][0][RTW89_QATAR][35] = 46, -+ [0][1][1][0][RTW89_UK][35] = 46, -+ [0][1][1][0][RTW89_FCC][37] = 68, -+ [0][1][1][0][RTW89_ETSI][37] = 127, -+ [0][1][1][0][RTW89_MKK][37] = 70, -+ [0][1][1][0][RTW89_IC][37] = 68, -+ [0][1][1][0][RTW89_KCC][37] = 62, -+ [0][1][1][0][RTW89_ACMA][37] = 70, -+ [0][1][1][0][RTW89_CHILE][37] = 50, -+ [0][1][1][0][RTW89_UKRAINE][37] = 127, -+ [0][1][1][0][RTW89_MEXICO][37] = 68, -+ [0][1][1][0][RTW89_CN][37] = 127, -+ [0][1][1][0][RTW89_QATAR][37] = 127, -+ [0][1][1][0][RTW89_UK][37] = 76, -+ [0][1][1][0][RTW89_FCC][38] = 78, -+ [0][1][1][0][RTW89_ETSI][38] = 16, -+ [0][1][1][0][RTW89_MKK][38] = 127, -+ [0][1][1][0][RTW89_IC][38] = 78, -+ [0][1][1][0][RTW89_KCC][38] = 60, -+ [0][1][1][0][RTW89_ACMA][38] = 72, -+ [0][1][1][0][RTW89_CHILE][38] = 48, -+ [0][1][1][0][RTW89_UKRAINE][38] = 16, -+ [0][1][1][0][RTW89_MEXICO][38] = 78, -+ [0][1][1][0][RTW89_CN][38] = 76, -+ [0][1][1][0][RTW89_QATAR][38] = 16, -+ [0][1][1][0][RTW89_UK][38] = 46, -+ [0][1][1][0][RTW89_FCC][40] = 78, -+ [0][1][1][0][RTW89_ETSI][40] = 16, -+ [0][1][1][0][RTW89_MKK][40] = 127, -+ [0][1][1][0][RTW89_IC][40] = 78, -+ [0][1][1][0][RTW89_KCC][40] = 60, -+ [0][1][1][0][RTW89_ACMA][40] = 72, -+ [0][1][1][0][RTW89_CHILE][40] = 48, -+ [0][1][1][0][RTW89_UKRAINE][40] = 16, -+ [0][1][1][0][RTW89_MEXICO][40] = 78, -+ [0][1][1][0][RTW89_CN][40] = 76, -+ [0][1][1][0][RTW89_QATAR][40] = 16, -+ [0][1][1][0][RTW89_UK][40] = 46, -+ [0][1][1][0][RTW89_FCC][42] = 78, -+ [0][1][1][0][RTW89_ETSI][42] = 16, -+ [0][1][1][0][RTW89_MKK][42] = 127, -+ [0][1][1][0][RTW89_IC][42] = 78, -+ [0][1][1][0][RTW89_KCC][42] = 60, -+ [0][1][1][0][RTW89_ACMA][42] = 76, -+ [0][1][1][0][RTW89_CHILE][42] = 48, -+ [0][1][1][0][RTW89_UKRAINE][42] = 16, -+ [0][1][1][0][RTW89_MEXICO][42] = 78, -+ [0][1][1][0][RTW89_CN][42] = 76, -+ [0][1][1][0][RTW89_QATAR][42] = 16, -+ [0][1][1][0][RTW89_UK][42] = 46, -+ [0][1][1][0][RTW89_FCC][44] = 78, -+ [0][1][1][0][RTW89_ETSI][44] = 16, -+ [0][1][1][0][RTW89_MKK][44] = 127, -+ [0][1][1][0][RTW89_IC][44] = 78, -+ [0][1][1][0][RTW89_KCC][44] = 60, -+ [0][1][1][0][RTW89_ACMA][44] = 76, -+ [0][1][1][0][RTW89_CHILE][44] = 48, -+ [0][1][1][0][RTW89_UKRAINE][44] = 16, -+ [0][1][1][0][RTW89_MEXICO][44] = 78, -+ [0][1][1][0][RTW89_CN][44] = 76, -+ [0][1][1][0][RTW89_QATAR][44] = 16, -+ [0][1][1][0][RTW89_UK][44] = 46, -+ [0][1][1][0][RTW89_FCC][46] = 78, -+ [0][1][1][0][RTW89_ETSI][46] = 16, -+ [0][1][1][0][RTW89_MKK][46] = 127, -+ [0][1][1][0][RTW89_IC][46] = 78, -+ [0][1][1][0][RTW89_KCC][46] = 60, -+ [0][1][1][0][RTW89_ACMA][46] = 76, -+ [0][1][1][0][RTW89_CHILE][46] = 48, -+ [0][1][1][0][RTW89_UKRAINE][46] = 16, -+ [0][1][1][0][RTW89_MEXICO][46] = 78, -+ [0][1][1][0][RTW89_CN][46] = 76, -+ [0][1][1][0][RTW89_QATAR][46] = 16, -+ [0][1][1][0][RTW89_UK][46] = 46, -+ [0][1][1][0][RTW89_FCC][48] = 56, -+ [0][1][1][0][RTW89_ETSI][48] = 127, -+ [0][1][1][0][RTW89_MKK][48] = 127, -+ [0][1][1][0][RTW89_IC][48] = 127, -+ [0][1][1][0][RTW89_KCC][48] = 127, -+ [0][1][1][0][RTW89_ACMA][48] = 127, -+ [0][1][1][0][RTW89_CHILE][48] = 127, -+ [0][1][1][0][RTW89_UKRAINE][48] = 127, -+ [0][1][1][0][RTW89_MEXICO][48] = 127, -+ [0][1][1][0][RTW89_CN][48] = 127, -+ [0][1][1][0][RTW89_QATAR][48] = 127, -+ [0][1][1][0][RTW89_UK][48] = 127, -+ [0][1][1][0][RTW89_FCC][50] = 56, -+ [0][1][1][0][RTW89_ETSI][50] = 127, -+ [0][1][1][0][RTW89_MKK][50] = 127, -+ [0][1][1][0][RTW89_IC][50] = 127, -+ [0][1][1][0][RTW89_KCC][50] = 127, -+ [0][1][1][0][RTW89_ACMA][50] = 127, -+ [0][1][1][0][RTW89_CHILE][50] = 127, -+ [0][1][1][0][RTW89_UKRAINE][50] = 127, -+ [0][1][1][0][RTW89_MEXICO][50] = 127, -+ [0][1][1][0][RTW89_CN][50] = 127, -+ [0][1][1][0][RTW89_QATAR][50] = 127, -+ [0][1][1][0][RTW89_UK][50] = 127, -+ [0][1][1][0][RTW89_FCC][52] = 56, -+ [0][1][1][0][RTW89_ETSI][52] = 127, -+ [0][1][1][0][RTW89_MKK][52] = 127, -+ [0][1][1][0][RTW89_IC][52] = 127, -+ [0][1][1][0][RTW89_KCC][52] = 127, -+ [0][1][1][0][RTW89_ACMA][52] = 127, -+ [0][1][1][0][RTW89_CHILE][52] = 127, -+ [0][1][1][0][RTW89_UKRAINE][52] = 127, -+ [0][1][1][0][RTW89_MEXICO][52] = 127, -+ [0][1][1][0][RTW89_CN][52] = 127, -+ [0][1][1][0][RTW89_QATAR][52] = 127, -+ [0][1][1][0][RTW89_UK][52] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 78, -+ [0][0][2][0][RTW89_ETSI][0] = 60, -+ [0][0][2][0][RTW89_MKK][0] = 62, -+ [0][0][2][0][RTW89_IC][0] = 64, -+ [0][0][2][0][RTW89_KCC][0] = 74, -+ [0][0][2][0][RTW89_ACMA][0] = 60, -+ [0][0][2][0][RTW89_CHILE][0] = 42, -+ [0][0][2][0][RTW89_UKRAINE][0] = 52, -+ [0][0][2][0][RTW89_MEXICO][0] = 62, -+ [0][0][2][0][RTW89_CN][0] = 60, -+ [0][0][2][0][RTW89_QATAR][0] = 60, -+ [0][0][2][0][RTW89_UK][0] = 60, -+ [0][0][2][0][RTW89_FCC][2] = 78, -+ [0][0][2][0][RTW89_ETSI][2] = 60, -+ [0][0][2][0][RTW89_MKK][2] = 62, -+ [0][0][2][0][RTW89_IC][2] = 64, -+ [0][0][2][0][RTW89_KCC][2] = 74, -+ [0][0][2][0][RTW89_ACMA][2] = 60, -+ [0][0][2][0][RTW89_CHILE][2] = 42, -+ [0][0][2][0][RTW89_UKRAINE][2] = 52, -+ [0][0][2][0][RTW89_MEXICO][2] = 62, -+ [0][0][2][0][RTW89_CN][2] = 60, -+ [0][0][2][0][RTW89_QATAR][2] = 60, -+ [0][0][2][0][RTW89_UK][2] = 60, -+ [0][0][2][0][RTW89_FCC][4] = 78, -+ [0][0][2][0][RTW89_ETSI][4] = 60, -+ [0][0][2][0][RTW89_MKK][4] = 62, -+ [0][0][2][0][RTW89_IC][4] = 64, -+ [0][0][2][0][RTW89_KCC][4] = 74, -+ [0][0][2][0][RTW89_ACMA][4] = 60, -+ [0][0][2][0][RTW89_CHILE][4] = 42, -+ [0][0][2][0][RTW89_UKRAINE][4] = 52, -+ [0][0][2][0][RTW89_MEXICO][4] = 62, -+ [0][0][2][0][RTW89_CN][4] = 60, -+ [0][0][2][0][RTW89_QATAR][4] = 60, -+ [0][0][2][0][RTW89_UK][4] = 60, -+ [0][0][2][0][RTW89_FCC][6] = 78, -+ [0][0][2][0][RTW89_ETSI][6] = 60, -+ [0][0][2][0][RTW89_MKK][6] = 62, -+ [0][0][2][0][RTW89_IC][6] = 64, -+ [0][0][2][0][RTW89_KCC][6] = 50, -+ [0][0][2][0][RTW89_ACMA][6] = 60, -+ [0][0][2][0][RTW89_CHILE][6] = 42, -+ [0][0][2][0][RTW89_UKRAINE][6] = 52, -+ [0][0][2][0][RTW89_MEXICO][6] = 62, -+ [0][0][2][0][RTW89_CN][6] = 60, -+ [0][0][2][0][RTW89_QATAR][6] = 60, -+ [0][0][2][0][RTW89_UK][6] = 60, -+ [0][0][2][0][RTW89_FCC][8] = 78, -+ [0][0][2][0][RTW89_ETSI][8] = 60, -+ [0][0][2][0][RTW89_MKK][8] = 62, -+ [0][0][2][0][RTW89_IC][8] = 64, -+ [0][0][2][0][RTW89_KCC][8] = 74, -+ [0][0][2][0][RTW89_ACMA][8] = 60, -+ [0][0][2][0][RTW89_CHILE][8] = 66, -+ [0][0][2][0][RTW89_UKRAINE][8] = 52, -+ [0][0][2][0][RTW89_MEXICO][8] = 78, -+ [0][0][2][0][RTW89_CN][8] = 60, -+ [0][0][2][0][RTW89_QATAR][8] = 60, -+ [0][0][2][0][RTW89_UK][8] = 60, -+ [0][0][2][0][RTW89_FCC][10] = 78, -+ [0][0][2][0][RTW89_ETSI][10] = 60, -+ [0][0][2][0][RTW89_MKK][10] = 62, -+ [0][0][2][0][RTW89_IC][10] = 64, -+ [0][0][2][0][RTW89_KCC][10] = 74, -+ [0][0][2][0][RTW89_ACMA][10] = 60, -+ [0][0][2][0][RTW89_CHILE][10] = 66, -+ [0][0][2][0][RTW89_UKRAINE][10] = 52, -+ [0][0][2][0][RTW89_MEXICO][10] = 78, -+ [0][0][2][0][RTW89_CN][10] = 60, -+ [0][0][2][0][RTW89_QATAR][10] = 60, -+ [0][0][2][0][RTW89_UK][10] = 60, -+ [0][0][2][0][RTW89_FCC][12] = 78, -+ [0][0][2][0][RTW89_ETSI][12] = 60, -+ [0][0][2][0][RTW89_MKK][12] = 62, -+ [0][0][2][0][RTW89_IC][12] = 64, -+ [0][0][2][0][RTW89_KCC][12] = 74, -+ [0][0][2][0][RTW89_ACMA][12] = 60, -+ [0][0][2][0][RTW89_CHILE][12] = 66, -+ [0][0][2][0][RTW89_UKRAINE][12] = 52, -+ [0][0][2][0][RTW89_MEXICO][12] = 78, -+ [0][0][2][0][RTW89_CN][12] = 60, -+ [0][0][2][0][RTW89_QATAR][12] = 60, -+ [0][0][2][0][RTW89_UK][12] = 60, -+ [0][0][2][0][RTW89_FCC][14] = 78, -+ [0][0][2][0][RTW89_ETSI][14] = 60, -+ [0][0][2][0][RTW89_MKK][14] = 62, -+ [0][0][2][0][RTW89_IC][14] = 64, -+ [0][0][2][0][RTW89_KCC][14] = 74, -+ [0][0][2][0][RTW89_ACMA][14] = 60, -+ [0][0][2][0][RTW89_CHILE][14] = 66, -+ [0][0][2][0][RTW89_UKRAINE][14] = 52, -+ [0][0][2][0][RTW89_MEXICO][14] = 78, -+ [0][0][2][0][RTW89_CN][14] = 60, -+ [0][0][2][0][RTW89_QATAR][14] = 60, -+ [0][0][2][0][RTW89_UK][14] = 60, -+ [0][0][2][0][RTW89_FCC][15] = 74, -+ [0][0][2][0][RTW89_ETSI][15] = 60, -+ [0][0][2][0][RTW89_MKK][15] = 76, -+ [0][0][2][0][RTW89_IC][15] = 74, -+ [0][0][2][0][RTW89_KCC][15] = 74, -+ [0][0][2][0][RTW89_ACMA][15] = 60, -+ [0][0][2][0][RTW89_CHILE][15] = 64, -+ [0][0][2][0][RTW89_UKRAINE][15] = 52, -+ [0][0][2][0][RTW89_MEXICO][15] = 74, -+ [0][0][2][0][RTW89_CN][15] = 127, -+ [0][0][2][0][RTW89_QATAR][15] = 60, -+ [0][0][2][0][RTW89_UK][15] = 60, -+ [0][0][2][0][RTW89_FCC][17] = 78, -+ [0][0][2][0][RTW89_ETSI][17] = 60, -+ [0][0][2][0][RTW89_MKK][17] = 76, -+ [0][0][2][0][RTW89_IC][17] = 78, -+ [0][0][2][0][RTW89_KCC][17] = 74, -+ [0][0][2][0][RTW89_ACMA][17] = 60, -+ [0][0][2][0][RTW89_CHILE][17] = 64, -+ [0][0][2][0][RTW89_UKRAINE][17] = 52, -+ [0][0][2][0][RTW89_MEXICO][17] = 78, -+ [0][0][2][0][RTW89_CN][17] = 127, -+ [0][0][2][0][RTW89_QATAR][17] = 60, -+ [0][0][2][0][RTW89_UK][17] = 60, -+ [0][0][2][0][RTW89_FCC][19] = 78, -+ [0][0][2][0][RTW89_ETSI][19] = 60, -+ [0][0][2][0][RTW89_MKK][19] = 76, -+ [0][0][2][0][RTW89_IC][19] = 78, -+ [0][0][2][0][RTW89_KCC][19] = 74, -+ [0][0][2][0][RTW89_ACMA][19] = 60, -+ [0][0][2][0][RTW89_CHILE][19] = 64, -+ [0][0][2][0][RTW89_UKRAINE][19] = 52, -+ [0][0][2][0][RTW89_MEXICO][19] = 78, -+ [0][0][2][0][RTW89_CN][19] = 127, -+ [0][0][2][0][RTW89_QATAR][19] = 60, -+ [0][0][2][0][RTW89_UK][19] = 60, -+ [0][0][2][0][RTW89_FCC][21] = 78, -+ [0][0][2][0][RTW89_ETSI][21] = 60, -+ [0][0][2][0][RTW89_MKK][21] = 76, -+ [0][0][2][0][RTW89_IC][21] = 78, -+ [0][0][2][0][RTW89_KCC][21] = 74, -+ [0][0][2][0][RTW89_ACMA][21] = 60, -+ [0][0][2][0][RTW89_CHILE][21] = 66, -+ [0][0][2][0][RTW89_UKRAINE][21] = 52, -+ [0][0][2][0][RTW89_MEXICO][21] = 78, -+ [0][0][2][0][RTW89_CN][21] = 127, -+ [0][0][2][0][RTW89_QATAR][21] = 60, -+ [0][0][2][0][RTW89_UK][21] = 60, -+ [0][0][2][0][RTW89_FCC][23] = 78, -+ [0][0][2][0][RTW89_ETSI][23] = 60, -+ [0][0][2][0][RTW89_MKK][23] = 76, -+ [0][0][2][0][RTW89_IC][23] = 78, -+ [0][0][2][0][RTW89_KCC][23] = 74, -+ [0][0][2][0][RTW89_ACMA][23] = 60, -+ [0][0][2][0][RTW89_CHILE][23] = 66, -+ [0][0][2][0][RTW89_UKRAINE][23] = 52, -+ [0][0][2][0][RTW89_MEXICO][23] = 78, -+ [0][0][2][0][RTW89_CN][23] = 127, -+ [0][0][2][0][RTW89_QATAR][23] = 60, -+ [0][0][2][0][RTW89_UK][23] = 60, -+ [0][0][2][0][RTW89_FCC][25] = 78, -+ [0][0][2][0][RTW89_ETSI][25] = 60, -+ [0][0][2][0][RTW89_MKK][25] = 76, -+ [0][0][2][0][RTW89_IC][25] = 127, -+ [0][0][2][0][RTW89_KCC][25] = 74, -+ [0][0][2][0][RTW89_ACMA][25] = 127, -+ [0][0][2][0][RTW89_CHILE][25] = 66, -+ [0][0][2][0][RTW89_UKRAINE][25] = 52, -+ [0][0][2][0][RTW89_MEXICO][25] = 78, -+ [0][0][2][0][RTW89_CN][25] = 127, -+ [0][0][2][0][RTW89_QATAR][25] = 60, -+ [0][0][2][0][RTW89_UK][25] = 60, -+ [0][0][2][0][RTW89_FCC][27] = 78, -+ [0][0][2][0][RTW89_ETSI][27] = 60, -+ [0][0][2][0][RTW89_MKK][27] = 76, -+ [0][0][2][0][RTW89_IC][27] = 127, -+ [0][0][2][0][RTW89_KCC][27] = 74, -+ [0][0][2][0][RTW89_ACMA][27] = 127, -+ [0][0][2][0][RTW89_CHILE][27] = 64, -+ [0][0][2][0][RTW89_UKRAINE][27] = 52, -+ [0][0][2][0][RTW89_MEXICO][27] = 78, -+ [0][0][2][0][RTW89_CN][27] = 127, -+ [0][0][2][0][RTW89_QATAR][27] = 60, -+ [0][0][2][0][RTW89_UK][27] = 60, -+ [0][0][2][0][RTW89_FCC][29] = 78, -+ [0][0][2][0][RTW89_ETSI][29] = 60, -+ [0][0][2][0][RTW89_MKK][29] = 76, -+ [0][0][2][0][RTW89_IC][29] = 127, -+ [0][0][2][0][RTW89_KCC][29] = 74, -+ [0][0][2][0][RTW89_ACMA][29] = 127, -+ [0][0][2][0][RTW89_CHILE][29] = 64, -+ [0][0][2][0][RTW89_UKRAINE][29] = 52, -+ [0][0][2][0][RTW89_MEXICO][29] = 78, -+ [0][0][2][0][RTW89_CN][29] = 127, -+ [0][0][2][0][RTW89_QATAR][29] = 60, -+ [0][0][2][0][RTW89_UK][29] = 60, -+ [0][0][2][0][RTW89_FCC][31] = 78, -+ [0][0][2][0][RTW89_ETSI][31] = 60, -+ [0][0][2][0][RTW89_MKK][31] = 76, -+ [0][0][2][0][RTW89_IC][31] = 78, -+ [0][0][2][0][RTW89_KCC][31] = 74, -+ [0][0][2][0][RTW89_ACMA][31] = 60, -+ [0][0][2][0][RTW89_CHILE][31] = 64, -+ [0][0][2][0][RTW89_UKRAINE][31] = 52, -+ [0][0][2][0][RTW89_MEXICO][31] = 78, -+ [0][0][2][0][RTW89_CN][31] = 127, -+ [0][0][2][0][RTW89_QATAR][31] = 60, -+ [0][0][2][0][RTW89_UK][31] = 60, -+ [0][0][2][0][RTW89_FCC][33] = 78, -+ [0][0][2][0][RTW89_ETSI][33] = 60, -+ [0][0][2][0][RTW89_MKK][33] = 76, -+ [0][0][2][0][RTW89_IC][33] = 78, -+ [0][0][2][0][RTW89_KCC][33] = 74, -+ [0][0][2][0][RTW89_ACMA][33] = 60, -+ [0][0][2][0][RTW89_CHILE][33] = 64, -+ [0][0][2][0][RTW89_UKRAINE][33] = 52, -+ [0][0][2][0][RTW89_MEXICO][33] = 78, -+ [0][0][2][0][RTW89_CN][33] = 127, -+ [0][0][2][0][RTW89_QATAR][33] = 60, -+ [0][0][2][0][RTW89_UK][33] = 60, -+ [0][0][2][0][RTW89_FCC][35] = 70, -+ [0][0][2][0][RTW89_ETSI][35] = 60, -+ [0][0][2][0][RTW89_MKK][35] = 76, -+ [0][0][2][0][RTW89_IC][35] = 70, -+ [0][0][2][0][RTW89_KCC][35] = 74, -+ [0][0][2][0][RTW89_ACMA][35] = 60, -+ [0][0][2][0][RTW89_CHILE][35] = 64, -+ [0][0][2][0][RTW89_UKRAINE][35] = 52, -+ [0][0][2][0][RTW89_MEXICO][35] = 70, -+ [0][0][2][0][RTW89_CN][35] = 127, -+ [0][0][2][0][RTW89_QATAR][35] = 60, -+ [0][0][2][0][RTW89_UK][35] = 60, -+ [0][0][2][0][RTW89_FCC][37] = 78, -+ [0][0][2][0][RTW89_ETSI][37] = 127, -+ [0][0][2][0][RTW89_MKK][37] = 76, -+ [0][0][2][0][RTW89_IC][37] = 78, -+ [0][0][2][0][RTW89_KCC][37] = 74, -+ [0][0][2][0][RTW89_ACMA][37] = 76, -+ [0][0][2][0][RTW89_CHILE][37] = 64, -+ [0][0][2][0][RTW89_UKRAINE][37] = 127, -+ [0][0][2][0][RTW89_MEXICO][37] = 78, -+ [0][0][2][0][RTW89_CN][37] = 127, -+ [0][0][2][0][RTW89_QATAR][37] = 127, -+ [0][0][2][0][RTW89_UK][37] = 74, -+ [0][0][2][0][RTW89_FCC][38] = 78, -+ [0][0][2][0][RTW89_ETSI][38] = 28, -+ [0][0][2][0][RTW89_MKK][38] = 127, -+ [0][0][2][0][RTW89_IC][38] = 78, -+ [0][0][2][0][RTW89_KCC][38] = 72, -+ [0][0][2][0][RTW89_ACMA][38] = 76, -+ [0][0][2][0][RTW89_CHILE][38] = 64, -+ [0][0][2][0][RTW89_UKRAINE][38] = 28, -+ [0][0][2][0][RTW89_MEXICO][38] = 78, -+ [0][0][2][0][RTW89_CN][38] = 76, -+ [0][0][2][0][RTW89_QATAR][38] = 28, -+ [0][0][2][0][RTW89_UK][38] = 60, -+ [0][0][2][0][RTW89_FCC][40] = 78, -+ [0][0][2][0][RTW89_ETSI][40] = 28, -+ [0][0][2][0][RTW89_MKK][40] = 127, -+ [0][0][2][0][RTW89_IC][40] = 78, -+ [0][0][2][0][RTW89_KCC][40] = 72, -+ [0][0][2][0][RTW89_ACMA][40] = 76, -+ [0][0][2][0][RTW89_CHILE][40] = 64, -+ [0][0][2][0][RTW89_UKRAINE][40] = 28, -+ [0][0][2][0][RTW89_MEXICO][40] = 78, -+ [0][0][2][0][RTW89_CN][40] = 76, -+ [0][0][2][0][RTW89_QATAR][40] = 28, -+ [0][0][2][0][RTW89_UK][40] = 60, -+ [0][0][2][0][RTW89_FCC][42] = 78, -+ [0][0][2][0][RTW89_ETSI][42] = 28, -+ [0][0][2][0][RTW89_MKK][42] = 127, -+ [0][0][2][0][RTW89_IC][42] = 78, -+ [0][0][2][0][RTW89_KCC][42] = 72, -+ [0][0][2][0][RTW89_ACMA][42] = 76, -+ [0][0][2][0][RTW89_CHILE][42] = 64, -+ [0][0][2][0][RTW89_UKRAINE][42] = 28, -+ [0][0][2][0][RTW89_MEXICO][42] = 78, -+ [0][0][2][0][RTW89_CN][42] = 76, -+ [0][0][2][0][RTW89_QATAR][42] = 28, -+ [0][0][2][0][RTW89_UK][42] = 60, -+ [0][0][2][0][RTW89_FCC][44] = 78, -+ [0][0][2][0][RTW89_ETSI][44] = 28, -+ [0][0][2][0][RTW89_MKK][44] = 127, -+ [0][0][2][0][RTW89_IC][44] = 78, -+ [0][0][2][0][RTW89_KCC][44] = 72, -+ [0][0][2][0][RTW89_ACMA][44] = 76, -+ [0][0][2][0][RTW89_CHILE][44] = 66, -+ [0][0][2][0][RTW89_UKRAINE][44] = 28, -+ [0][0][2][0][RTW89_MEXICO][44] = 78, -+ [0][0][2][0][RTW89_CN][44] = 76, -+ [0][0][2][0][RTW89_QATAR][44] = 28, -+ [0][0][2][0][RTW89_UK][44] = 60, -+ [0][0][2][0][RTW89_FCC][46] = 78, -+ [0][0][2][0][RTW89_ETSI][46] = 28, -+ [0][0][2][0][RTW89_MKK][46] = 127, -+ [0][0][2][0][RTW89_IC][46] = 78, -+ [0][0][2][0][RTW89_KCC][46] = 72, -+ [0][0][2][0][RTW89_ACMA][46] = 76, -+ [0][0][2][0][RTW89_CHILE][46] = 66, -+ [0][0][2][0][RTW89_UKRAINE][46] = 28, -+ [0][0][2][0][RTW89_MEXICO][46] = 78, -+ [0][0][2][0][RTW89_CN][46] = 76, -+ [0][0][2][0][RTW89_QATAR][46] = 28, -+ [0][0][2][0][RTW89_UK][46] = 60, -+ [0][0][2][0][RTW89_FCC][48] = 78, -+ [0][0][2][0][RTW89_ETSI][48] = 127, -+ [0][0][2][0][RTW89_MKK][48] = 127, -+ [0][0][2][0][RTW89_IC][48] = 127, -+ [0][0][2][0][RTW89_KCC][48] = 127, -+ [0][0][2][0][RTW89_ACMA][48] = 127, -+ [0][0][2][0][RTW89_CHILE][48] = 127, -+ [0][0][2][0][RTW89_UKRAINE][48] = 127, -+ [0][0][2][0][RTW89_MEXICO][48] = 127, -+ [0][0][2][0][RTW89_CN][48] = 127, -+ [0][0][2][0][RTW89_QATAR][48] = 127, -+ [0][0][2][0][RTW89_UK][48] = 127, -+ [0][0][2][0][RTW89_FCC][50] = 78, -+ [0][0][2][0][RTW89_ETSI][50] = 127, -+ [0][0][2][0][RTW89_MKK][50] = 127, -+ [0][0][2][0][RTW89_IC][50] = 127, -+ [0][0][2][0][RTW89_KCC][50] = 127, -+ [0][0][2][0][RTW89_ACMA][50] = 127, -+ [0][0][2][0][RTW89_CHILE][50] = 127, -+ [0][0][2][0][RTW89_UKRAINE][50] = 127, -+ [0][0][2][0][RTW89_MEXICO][50] = 127, -+ [0][0][2][0][RTW89_CN][50] = 127, -+ [0][0][2][0][RTW89_QATAR][50] = 127, -+ [0][0][2][0][RTW89_UK][50] = 127, -+ [0][0][2][0][RTW89_FCC][52] = 78, -+ [0][0][2][0][RTW89_ETSI][52] = 127, -+ [0][0][2][0][RTW89_MKK][52] = 127, -+ [0][0][2][0][RTW89_IC][52] = 127, -+ [0][0][2][0][RTW89_KCC][52] = 127, -+ [0][0][2][0][RTW89_ACMA][52] = 127, -+ [0][0][2][0][RTW89_CHILE][52] = 127, -+ [0][0][2][0][RTW89_UKRAINE][52] = 127, -+ [0][0][2][0][RTW89_MEXICO][52] = 127, -+ [0][0][2][0][RTW89_CN][52] = 127, -+ [0][0][2][0][RTW89_QATAR][52] = 127, -+ [0][0][2][0][RTW89_UK][52] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 70, -+ [0][1][2][0][RTW89_ETSI][0] = 48, -+ [0][1][2][0][RTW89_MKK][0] = 50, -+ [0][1][2][0][RTW89_IC][0] = 42, -+ [0][1][2][0][RTW89_KCC][0] = 62, -+ [0][1][2][0][RTW89_ACMA][0] = 48, -+ [0][1][2][0][RTW89_CHILE][0] = 30, -+ [0][1][2][0][RTW89_UKRAINE][0] = 40, -+ [0][1][2][0][RTW89_MEXICO][0] = 50, -+ [0][1][2][0][RTW89_CN][0] = 48, -+ [0][1][2][0][RTW89_QATAR][0] = 48, -+ [0][1][2][0][RTW89_UK][0] = 48, -+ [0][1][2][0][RTW89_FCC][2] = 70, -+ [0][1][2][0][RTW89_ETSI][2] = 48, -+ [0][1][2][0][RTW89_MKK][2] = 50, -+ [0][1][2][0][RTW89_IC][2] = 42, -+ [0][1][2][0][RTW89_KCC][2] = 62, -+ [0][1][2][0][RTW89_ACMA][2] = 48, -+ [0][1][2][0][RTW89_CHILE][2] = 30, -+ [0][1][2][0][RTW89_UKRAINE][2] = 40, -+ [0][1][2][0][RTW89_MEXICO][2] = 50, -+ [0][1][2][0][RTW89_CN][2] = 48, -+ [0][1][2][0][RTW89_QATAR][2] = 48, -+ [0][1][2][0][RTW89_UK][2] = 48, -+ [0][1][2][0][RTW89_FCC][4] = 70, -+ [0][1][2][0][RTW89_ETSI][4] = 48, -+ [0][1][2][0][RTW89_MKK][4] = 50, -+ [0][1][2][0][RTW89_IC][4] = 42, -+ [0][1][2][0][RTW89_KCC][4] = 62, -+ [0][1][2][0][RTW89_ACMA][4] = 48, -+ [0][1][2][0][RTW89_CHILE][4] = 30, -+ [0][1][2][0][RTW89_UKRAINE][4] = 40, -+ [0][1][2][0][RTW89_MEXICO][4] = 50, -+ [0][1][2][0][RTW89_CN][4] = 48, -+ [0][1][2][0][RTW89_QATAR][4] = 48, -+ [0][1][2][0][RTW89_UK][4] = 48, -+ [0][1][2][0][RTW89_FCC][6] = 70, -+ [0][1][2][0][RTW89_ETSI][6] = 48, -+ [0][1][2][0][RTW89_MKK][6] = 50, -+ [0][1][2][0][RTW89_IC][6] = 42, -+ [0][1][2][0][RTW89_KCC][6] = 34, -+ [0][1][2][0][RTW89_ACMA][6] = 48, -+ [0][1][2][0][RTW89_CHILE][6] = 30, -+ [0][1][2][0][RTW89_UKRAINE][6] = 40, -+ [0][1][2][0][RTW89_MEXICO][6] = 50, -+ [0][1][2][0][RTW89_CN][6] = 48, -+ [0][1][2][0][RTW89_QATAR][6] = 48, -+ [0][1][2][0][RTW89_UK][6] = 48, -+ [0][1][2][0][RTW89_FCC][8] = 70, -+ [0][1][2][0][RTW89_ETSI][8] = 48, -+ [0][1][2][0][RTW89_MKK][8] = 50, -+ [0][1][2][0][RTW89_IC][8] = 52, -+ [0][1][2][0][RTW89_KCC][8] = 62, -+ [0][1][2][0][RTW89_ACMA][8] = 48, -+ [0][1][2][0][RTW89_CHILE][8] = 50, -+ [0][1][2][0][RTW89_UKRAINE][8] = 40, -+ [0][1][2][0][RTW89_MEXICO][8] = 70, -+ [0][1][2][0][RTW89_CN][8] = 48, -+ [0][1][2][0][RTW89_QATAR][8] = 48, -+ [0][1][2][0][RTW89_UK][8] = 48, -+ [0][1][2][0][RTW89_FCC][10] = 70, -+ [0][1][2][0][RTW89_ETSI][10] = 48, -+ [0][1][2][0][RTW89_MKK][10] = 50, -+ [0][1][2][0][RTW89_IC][10] = 52, -+ [0][1][2][0][RTW89_KCC][10] = 62, -+ [0][1][2][0][RTW89_ACMA][10] = 48, -+ [0][1][2][0][RTW89_CHILE][10] = 50, -+ [0][1][2][0][RTW89_UKRAINE][10] = 40, -+ [0][1][2][0][RTW89_MEXICO][10] = 70, -+ [0][1][2][0][RTW89_CN][10] = 48, -+ [0][1][2][0][RTW89_QATAR][10] = 48, -+ [0][1][2][0][RTW89_UK][10] = 48, -+ [0][1][2][0][RTW89_FCC][12] = 70, -+ [0][1][2][0][RTW89_ETSI][12] = 48, -+ [0][1][2][0][RTW89_MKK][12] = 50, -+ [0][1][2][0][RTW89_IC][12] = 52, -+ [0][1][2][0][RTW89_KCC][12] = 62, -+ [0][1][2][0][RTW89_ACMA][12] = 48, -+ [0][1][2][0][RTW89_CHILE][12] = 50, -+ [0][1][2][0][RTW89_UKRAINE][12] = 40, -+ [0][1][2][0][RTW89_MEXICO][12] = 70, -+ [0][1][2][0][RTW89_CN][12] = 48, -+ [0][1][2][0][RTW89_QATAR][12] = 48, -+ [0][1][2][0][RTW89_UK][12] = 48, -+ [0][1][2][0][RTW89_FCC][14] = 70, -+ [0][1][2][0][RTW89_ETSI][14] = 48, -+ [0][1][2][0][RTW89_MKK][14] = 50, -+ [0][1][2][0][RTW89_IC][14] = 52, -+ [0][1][2][0][RTW89_KCC][14] = 62, -+ [0][1][2][0][RTW89_ACMA][14] = 48, -+ [0][1][2][0][RTW89_CHILE][14] = 50, -+ [0][1][2][0][RTW89_UKRAINE][14] = 40, -+ [0][1][2][0][RTW89_MEXICO][14] = 70, -+ [0][1][2][0][RTW89_CN][14] = 48, -+ [0][1][2][0][RTW89_QATAR][14] = 48, -+ [0][1][2][0][RTW89_UK][14] = 48, -+ [0][1][2][0][RTW89_FCC][15] = 68, -+ [0][1][2][0][RTW89_ETSI][15] = 48, -+ [0][1][2][0][RTW89_MKK][15] = 70, -+ [0][1][2][0][RTW89_IC][15] = 68, -+ [0][1][2][0][RTW89_KCC][15] = 62, -+ [0][1][2][0][RTW89_ACMA][15] = 48, -+ [0][1][2][0][RTW89_CHILE][15] = 48, -+ [0][1][2][0][RTW89_UKRAINE][15] = 40, -+ [0][1][2][0][RTW89_MEXICO][15] = 68, -+ [0][1][2][0][RTW89_CN][15] = 127, -+ [0][1][2][0][RTW89_QATAR][15] = 48, -+ [0][1][2][0][RTW89_UK][15] = 48, -+ [0][1][2][0][RTW89_FCC][17] = 70, -+ [0][1][2][0][RTW89_ETSI][17] = 48, -+ [0][1][2][0][RTW89_MKK][17] = 70, -+ [0][1][2][0][RTW89_IC][17] = 70, -+ [0][1][2][0][RTW89_KCC][17] = 62, -+ [0][1][2][0][RTW89_ACMA][17] = 48, -+ [0][1][2][0][RTW89_CHILE][17] = 48, -+ [0][1][2][0][RTW89_UKRAINE][17] = 40, -+ [0][1][2][0][RTW89_MEXICO][17] = 70, -+ [0][1][2][0][RTW89_CN][17] = 127, -+ [0][1][2][0][RTW89_QATAR][17] = 48, -+ [0][1][2][0][RTW89_UK][17] = 48, -+ [0][1][2][0][RTW89_FCC][19] = 70, -+ [0][1][2][0][RTW89_ETSI][19] = 48, -+ [0][1][2][0][RTW89_MKK][19] = 70, -+ [0][1][2][0][RTW89_IC][19] = 70, -+ [0][1][2][0][RTW89_KCC][19] = 62, -+ [0][1][2][0][RTW89_ACMA][19] = 48, -+ [0][1][2][0][RTW89_CHILE][19] = 48, -+ [0][1][2][0][RTW89_UKRAINE][19] = 40, -+ [0][1][2][0][RTW89_MEXICO][19] = 70, -+ [0][1][2][0][RTW89_CN][19] = 127, -+ [0][1][2][0][RTW89_QATAR][19] = 48, -+ [0][1][2][0][RTW89_UK][19] = 48, -+ [0][1][2][0][RTW89_FCC][21] = 70, -+ [0][1][2][0][RTW89_ETSI][21] = 48, -+ [0][1][2][0][RTW89_MKK][21] = 70, -+ [0][1][2][0][RTW89_IC][21] = 70, -+ [0][1][2][0][RTW89_KCC][21] = 62, -+ [0][1][2][0][RTW89_ACMA][21] = 48, -+ [0][1][2][0][RTW89_CHILE][21] = 48, -+ [0][1][2][0][RTW89_UKRAINE][21] = 40, -+ [0][1][2][0][RTW89_MEXICO][21] = 70, -+ [0][1][2][0][RTW89_CN][21] = 127, -+ [0][1][2][0][RTW89_QATAR][21] = 48, -+ [0][1][2][0][RTW89_UK][21] = 48, -+ [0][1][2][0][RTW89_FCC][23] = 70, -+ [0][1][2][0][RTW89_ETSI][23] = 48, -+ [0][1][2][0][RTW89_MKK][23] = 70, -+ [0][1][2][0][RTW89_IC][23] = 70, -+ [0][1][2][0][RTW89_KCC][23] = 62, -+ [0][1][2][0][RTW89_ACMA][23] = 48, -+ [0][1][2][0][RTW89_CHILE][23] = 48, -+ [0][1][2][0][RTW89_UKRAINE][23] = 40, -+ [0][1][2][0][RTW89_MEXICO][23] = 70, -+ [0][1][2][0][RTW89_CN][23] = 127, -+ [0][1][2][0][RTW89_QATAR][23] = 48, -+ [0][1][2][0][RTW89_UK][23] = 48, -+ [0][1][2][0][RTW89_FCC][25] = 70, -+ [0][1][2][0][RTW89_ETSI][25] = 48, -+ [0][1][2][0][RTW89_MKK][25] = 70, -+ [0][1][2][0][RTW89_IC][25] = 127, -+ [0][1][2][0][RTW89_KCC][25] = 62, -+ [0][1][2][0][RTW89_ACMA][25] = 127, -+ [0][1][2][0][RTW89_CHILE][25] = 48, -+ [0][1][2][0][RTW89_UKRAINE][25] = 40, -+ [0][1][2][0][RTW89_MEXICO][25] = 70, -+ [0][1][2][0][RTW89_CN][25] = 127, -+ [0][1][2][0][RTW89_QATAR][25] = 48, -+ [0][1][2][0][RTW89_UK][25] = 48, -+ [0][1][2][0][RTW89_FCC][27] = 70, -+ [0][1][2][0][RTW89_ETSI][27] = 48, -+ [0][1][2][0][RTW89_MKK][27] = 70, -+ [0][1][2][0][RTW89_IC][27] = 127, -+ [0][1][2][0][RTW89_KCC][27] = 62, -+ [0][1][2][0][RTW89_ACMA][27] = 127, -+ [0][1][2][0][RTW89_CHILE][27] = 50, -+ [0][1][2][0][RTW89_UKRAINE][27] = 40, -+ [0][1][2][0][RTW89_MEXICO][27] = 70, -+ [0][1][2][0][RTW89_CN][27] = 127, -+ [0][1][2][0][RTW89_QATAR][27] = 48, -+ [0][1][2][0][RTW89_UK][27] = 48, -+ [0][1][2][0][RTW89_FCC][29] = 70, -+ [0][1][2][0][RTW89_ETSI][29] = 48, -+ [0][1][2][0][RTW89_MKK][29] = 70, -+ [0][1][2][0][RTW89_IC][29] = 127, -+ [0][1][2][0][RTW89_KCC][29] = 62, -+ [0][1][2][0][RTW89_ACMA][29] = 127, -+ [0][1][2][0][RTW89_CHILE][29] = 50, -+ [0][1][2][0][RTW89_UKRAINE][29] = 40, -+ [0][1][2][0][RTW89_MEXICO][29] = 70, -+ [0][1][2][0][RTW89_CN][29] = 127, -+ [0][1][2][0][RTW89_QATAR][29] = 48, -+ [0][1][2][0][RTW89_UK][29] = 48, -+ [0][1][2][0][RTW89_FCC][31] = 70, -+ [0][1][2][0][RTW89_ETSI][31] = 48, -+ [0][1][2][0][RTW89_MKK][31] = 70, -+ [0][1][2][0][RTW89_IC][31] = 70, -+ [0][1][2][0][RTW89_KCC][31] = 62, -+ [0][1][2][0][RTW89_ACMA][31] = 48, -+ [0][1][2][0][RTW89_CHILE][31] = 50, -+ [0][1][2][0][RTW89_UKRAINE][31] = 40, -+ [0][1][2][0][RTW89_MEXICO][31] = 70, -+ [0][1][2][0][RTW89_CN][31] = 127, -+ [0][1][2][0][RTW89_QATAR][31] = 48, -+ [0][1][2][0][RTW89_UK][31] = 48, -+ [0][1][2][0][RTW89_FCC][33] = 70, -+ [0][1][2][0][RTW89_ETSI][33] = 48, -+ [0][1][2][0][RTW89_MKK][33] = 70, -+ [0][1][2][0][RTW89_IC][33] = 70, -+ [0][1][2][0][RTW89_KCC][33] = 62, -+ [0][1][2][0][RTW89_ACMA][33] = 48, -+ [0][1][2][0][RTW89_CHILE][33] = 50, -+ [0][1][2][0][RTW89_UKRAINE][33] = 40, -+ [0][1][2][0][RTW89_MEXICO][33] = 70, -+ [0][1][2][0][RTW89_CN][33] = 127, -+ [0][1][2][0][RTW89_QATAR][33] = 48, -+ [0][1][2][0][RTW89_UK][33] = 48, -+ [0][1][2][0][RTW89_FCC][35] = 66, -+ [0][1][2][0][RTW89_ETSI][35] = 48, -+ [0][1][2][0][RTW89_MKK][35] = 70, -+ [0][1][2][0][RTW89_IC][35] = 66, -+ [0][1][2][0][RTW89_KCC][35] = 62, -+ [0][1][2][0][RTW89_ACMA][35] = 48, -+ [0][1][2][0][RTW89_CHILE][35] = 50, -+ [0][1][2][0][RTW89_UKRAINE][35] = 40, -+ [0][1][2][0][RTW89_MEXICO][35] = 66, -+ [0][1][2][0][RTW89_CN][35] = 127, -+ [0][1][2][0][RTW89_QATAR][35] = 48, -+ [0][1][2][0][RTW89_UK][35] = 48, -+ [0][1][2][0][RTW89_FCC][37] = 70, -+ [0][1][2][0][RTW89_ETSI][37] = 127, -+ [0][1][2][0][RTW89_MKK][37] = 70, -+ [0][1][2][0][RTW89_IC][37] = 70, -+ [0][1][2][0][RTW89_KCC][37] = 62, -+ [0][1][2][0][RTW89_ACMA][37] = 70, -+ [0][1][2][0][RTW89_CHILE][37] = 50, -+ [0][1][2][0][RTW89_UKRAINE][37] = 127, -+ [0][1][2][0][RTW89_MEXICO][37] = 70, -+ [0][1][2][0][RTW89_CN][37] = 127, -+ [0][1][2][0][RTW89_QATAR][37] = 127, -+ [0][1][2][0][RTW89_UK][37] = 76, -+ [0][1][2][0][RTW89_FCC][38] = 78, -+ [0][1][2][0][RTW89_ETSI][38] = 16, -+ [0][1][2][0][RTW89_MKK][38] = 127, -+ [0][1][2][0][RTW89_IC][38] = 78, -+ [0][1][2][0][RTW89_KCC][38] = 62, -+ [0][1][2][0][RTW89_ACMA][38] = 74, -+ [0][1][2][0][RTW89_CHILE][38] = 50, -+ [0][1][2][0][RTW89_UKRAINE][38] = 16, -+ [0][1][2][0][RTW89_MEXICO][38] = 78, -+ [0][1][2][0][RTW89_CN][38] = 76, -+ [0][1][2][0][RTW89_QATAR][38] = 16, -+ [0][1][2][0][RTW89_UK][38] = 48, -+ [0][1][2][0][RTW89_FCC][40] = 78, -+ [0][1][2][0][RTW89_ETSI][40] = 16, -+ [0][1][2][0][RTW89_MKK][40] = 127, -+ [0][1][2][0][RTW89_IC][40] = 78, -+ [0][1][2][0][RTW89_KCC][40] = 62, -+ [0][1][2][0][RTW89_ACMA][40] = 74, -+ [0][1][2][0][RTW89_CHILE][40] = 50, -+ [0][1][2][0][RTW89_UKRAINE][40] = 16, -+ [0][1][2][0][RTW89_MEXICO][40] = 78, -+ [0][1][2][0][RTW89_CN][40] = 76, -+ [0][1][2][0][RTW89_QATAR][40] = 16, -+ [0][1][2][0][RTW89_UK][40] = 48, -+ [0][1][2][0][RTW89_FCC][42] = 78, -+ [0][1][2][0][RTW89_ETSI][42] = 16, -+ [0][1][2][0][RTW89_MKK][42] = 127, -+ [0][1][2][0][RTW89_IC][42] = 78, -+ [0][1][2][0][RTW89_KCC][42] = 62, -+ [0][1][2][0][RTW89_ACMA][42] = 76, -+ [0][1][2][0][RTW89_CHILE][42] = 52, -+ [0][1][2][0][RTW89_UKRAINE][42] = 16, -+ [0][1][2][0][RTW89_MEXICO][42] = 78, -+ [0][1][2][0][RTW89_CN][42] = 76, -+ [0][1][2][0][RTW89_QATAR][42] = 16, -+ [0][1][2][0][RTW89_UK][42] = 48, -+ [0][1][2][0][RTW89_FCC][44] = 78, -+ [0][1][2][0][RTW89_ETSI][44] = 16, -+ [0][1][2][0][RTW89_MKK][44] = 127, -+ [0][1][2][0][RTW89_IC][44] = 78, -+ [0][1][2][0][RTW89_KCC][44] = 62, -+ [0][1][2][0][RTW89_ACMA][44] = 76, -+ [0][1][2][0][RTW89_CHILE][44] = 52, -+ [0][1][2][0][RTW89_UKRAINE][44] = 16, -+ [0][1][2][0][RTW89_MEXICO][44] = 78, -+ [0][1][2][0][RTW89_CN][44] = 76, -+ [0][1][2][0][RTW89_QATAR][44] = 16, -+ [0][1][2][0][RTW89_UK][44] = 48, -+ [0][1][2][0][RTW89_FCC][46] = 78, -+ [0][1][2][0][RTW89_ETSI][46] = 16, -+ [0][1][2][0][RTW89_MKK][46] = 127, -+ [0][1][2][0][RTW89_IC][46] = 78, -+ [0][1][2][0][RTW89_KCC][46] = 62, -+ [0][1][2][0][RTW89_ACMA][46] = 76, -+ [0][1][2][0][RTW89_CHILE][46] = 52, -+ [0][1][2][0][RTW89_UKRAINE][46] = 16, -+ [0][1][2][0][RTW89_MEXICO][46] = 78, -+ [0][1][2][0][RTW89_CN][46] = 76, -+ [0][1][2][0][RTW89_QATAR][46] = 16, -+ [0][1][2][0][RTW89_UK][46] = 48, -+ [0][1][2][0][RTW89_FCC][48] = 58, -+ [0][1][2][0][RTW89_ETSI][48] = 127, -+ [0][1][2][0][RTW89_MKK][48] = 127, -+ [0][1][2][0][RTW89_IC][48] = 127, -+ [0][1][2][0][RTW89_KCC][48] = 127, -+ [0][1][2][0][RTW89_ACMA][48] = 127, -+ [0][1][2][0][RTW89_CHILE][48] = 127, -+ [0][1][2][0][RTW89_UKRAINE][48] = 127, -+ [0][1][2][0][RTW89_MEXICO][48] = 127, -+ [0][1][2][0][RTW89_CN][48] = 127, -+ [0][1][2][0][RTW89_QATAR][48] = 127, -+ [0][1][2][0][RTW89_UK][48] = 127, -+ [0][1][2][0][RTW89_FCC][50] = 58, -+ [0][1][2][0][RTW89_ETSI][50] = 127, -+ [0][1][2][0][RTW89_MKK][50] = 127, -+ [0][1][2][0][RTW89_IC][50] = 127, -+ [0][1][2][0][RTW89_KCC][50] = 127, -+ [0][1][2][0][RTW89_ACMA][50] = 127, -+ [0][1][2][0][RTW89_CHILE][50] = 127, -+ [0][1][2][0][RTW89_UKRAINE][50] = 127, -+ [0][1][2][0][RTW89_MEXICO][50] = 127, -+ [0][1][2][0][RTW89_CN][50] = 127, -+ [0][1][2][0][RTW89_QATAR][50] = 127, -+ [0][1][2][0][RTW89_UK][50] = 127, -+ [0][1][2][0][RTW89_FCC][52] = 58, -+ [0][1][2][0][RTW89_ETSI][52] = 127, -+ [0][1][2][0][RTW89_MKK][52] = 127, -+ [0][1][2][0][RTW89_IC][52] = 127, -+ [0][1][2][0][RTW89_KCC][52] = 127, -+ [0][1][2][0][RTW89_ACMA][52] = 127, -+ [0][1][2][0][RTW89_CHILE][52] = 127, -+ [0][1][2][0][RTW89_UKRAINE][52] = 127, -+ [0][1][2][0][RTW89_MEXICO][52] = 127, -+ [0][1][2][0][RTW89_CN][52] = 127, -+ [0][1][2][0][RTW89_QATAR][52] = 127, -+ [0][1][2][0][RTW89_UK][52] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 68, -+ [0][1][2][1][RTW89_ETSI][0] = 36, -+ [0][1][2][1][RTW89_MKK][0] = 50, -+ [0][1][2][1][RTW89_IC][0] = 40, -+ [0][1][2][1][RTW89_KCC][0] = 62, -+ [0][1][2][1][RTW89_ACMA][0] = 36, -+ [0][1][2][1][RTW89_CHILE][0] = 14, -+ [0][1][2][1][RTW89_UKRAINE][0] = 28, -+ [0][1][2][1][RTW89_MEXICO][0] = 50, -+ [0][1][2][1][RTW89_CN][0] = 36, -+ [0][1][2][1][RTW89_QATAR][0] = 36, -+ [0][1][2][1][RTW89_UK][0] = 36, -+ [0][1][2][1][RTW89_FCC][2] = 68, -+ [0][1][2][1][RTW89_ETSI][2] = 36, -+ [0][1][2][1][RTW89_MKK][2] = 50, -+ [0][1][2][1][RTW89_IC][2] = 40, -+ [0][1][2][1][RTW89_KCC][2] = 62, -+ [0][1][2][1][RTW89_ACMA][2] = 36, -+ [0][1][2][1][RTW89_CHILE][2] = 14, -+ [0][1][2][1][RTW89_UKRAINE][2] = 28, -+ [0][1][2][1][RTW89_MEXICO][2] = 50, -+ [0][1][2][1][RTW89_CN][2] = 36, -+ [0][1][2][1][RTW89_QATAR][2] = 36, -+ [0][1][2][1][RTW89_UK][2] = 36, -+ [0][1][2][1][RTW89_FCC][4] = 68, -+ [0][1][2][1][RTW89_ETSI][4] = 36, -+ [0][1][2][1][RTW89_MKK][4] = 50, -+ [0][1][2][1][RTW89_IC][4] = 40, -+ [0][1][2][1][RTW89_KCC][4] = 62, -+ [0][1][2][1][RTW89_ACMA][4] = 36, -+ [0][1][2][1][RTW89_CHILE][4] = 14, -+ [0][1][2][1][RTW89_UKRAINE][4] = 28, -+ [0][1][2][1][RTW89_MEXICO][4] = 50, -+ [0][1][2][1][RTW89_CN][4] = 36, -+ [0][1][2][1][RTW89_QATAR][4] = 36, -+ [0][1][2][1][RTW89_UK][4] = 36, -+ [0][1][2][1][RTW89_FCC][6] = 68, -+ [0][1][2][1][RTW89_ETSI][6] = 36, -+ [0][1][2][1][RTW89_MKK][6] = 50, -+ [0][1][2][1][RTW89_IC][6] = 40, -+ [0][1][2][1][RTW89_KCC][6] = 34, -+ [0][1][2][1][RTW89_ACMA][6] = 36, -+ [0][1][2][1][RTW89_CHILE][6] = 14, -+ [0][1][2][1][RTW89_UKRAINE][6] = 28, -+ [0][1][2][1][RTW89_MEXICO][6] = 50, -+ [0][1][2][1][RTW89_CN][6] = 36, -+ [0][1][2][1][RTW89_QATAR][6] = 36, -+ [0][1][2][1][RTW89_UK][6] = 36, -+ [0][1][2][1][RTW89_FCC][8] = 68, -+ [0][1][2][1][RTW89_ETSI][8] = 36, -+ [0][1][2][1][RTW89_MKK][8] = 50, -+ [0][1][2][1][RTW89_IC][8] = 40, -+ [0][1][2][1][RTW89_KCC][8] = 62, -+ [0][1][2][1][RTW89_ACMA][8] = 36, -+ [0][1][2][1][RTW89_CHILE][8] = 36, -+ [0][1][2][1][RTW89_UKRAINE][8] = 28, -+ [0][1][2][1][RTW89_MEXICO][8] = 68, -+ [0][1][2][1][RTW89_CN][8] = 36, -+ [0][1][2][1][RTW89_QATAR][8] = 36, -+ [0][1][2][1][RTW89_UK][8] = 36, -+ [0][1][2][1][RTW89_FCC][10] = 68, -+ [0][1][2][1][RTW89_ETSI][10] = 36, -+ [0][1][2][1][RTW89_MKK][10] = 50, -+ [0][1][2][1][RTW89_IC][10] = 40, -+ [0][1][2][1][RTW89_KCC][10] = 62, -+ [0][1][2][1][RTW89_ACMA][10] = 36, -+ [0][1][2][1][RTW89_CHILE][10] = 36, -+ [0][1][2][1][RTW89_UKRAINE][10] = 28, -+ [0][1][2][1][RTW89_MEXICO][10] = 68, -+ [0][1][2][1][RTW89_CN][10] = 36, -+ [0][1][2][1][RTW89_QATAR][10] = 36, -+ [0][1][2][1][RTW89_UK][10] = 36, -+ [0][1][2][1][RTW89_FCC][12] = 68, -+ [0][1][2][1][RTW89_ETSI][12] = 36, -+ [0][1][2][1][RTW89_MKK][12] = 50, -+ [0][1][2][1][RTW89_IC][12] = 40, -+ [0][1][2][1][RTW89_KCC][12] = 62, -+ [0][1][2][1][RTW89_ACMA][12] = 36, -+ [0][1][2][1][RTW89_CHILE][12] = 36, -+ [0][1][2][1][RTW89_UKRAINE][12] = 28, -+ [0][1][2][1][RTW89_MEXICO][12] = 68, -+ [0][1][2][1][RTW89_CN][12] = 36, -+ [0][1][2][1][RTW89_QATAR][12] = 36, -+ [0][1][2][1][RTW89_UK][12] = 36, -+ [0][1][2][1][RTW89_FCC][14] = 68, -+ [0][1][2][1][RTW89_ETSI][14] = 36, -+ [0][1][2][1][RTW89_MKK][14] = 50, -+ [0][1][2][1][RTW89_IC][14] = 40, -+ [0][1][2][1][RTW89_KCC][14] = 62, -+ [0][1][2][1][RTW89_ACMA][14] = 36, -+ [0][1][2][1][RTW89_CHILE][14] = 36, -+ [0][1][2][1][RTW89_UKRAINE][14] = 28, -+ [0][1][2][1][RTW89_MEXICO][14] = 68, -+ [0][1][2][1][RTW89_CN][14] = 36, -+ [0][1][2][1][RTW89_QATAR][14] = 36, -+ [0][1][2][1][RTW89_UK][14] = 36, -+ [0][1][2][1][RTW89_FCC][15] = 68, -+ [0][1][2][1][RTW89_ETSI][15] = 36, -+ [0][1][2][1][RTW89_MKK][15] = 70, -+ [0][1][2][1][RTW89_IC][15] = 68, -+ [0][1][2][1][RTW89_KCC][15] = 62, -+ [0][1][2][1][RTW89_ACMA][15] = 36, -+ [0][1][2][1][RTW89_CHILE][15] = 36, -+ [0][1][2][1][RTW89_UKRAINE][15] = 28, -+ [0][1][2][1][RTW89_MEXICO][15] = 68, -+ [0][1][2][1][RTW89_CN][15] = 127, -+ [0][1][2][1][RTW89_QATAR][15] = 36, -+ [0][1][2][1][RTW89_UK][15] = 36, -+ [0][1][2][1][RTW89_FCC][17] = 68, -+ [0][1][2][1][RTW89_ETSI][17] = 36, -+ [0][1][2][1][RTW89_MKK][17] = 70, -+ [0][1][2][1][RTW89_IC][17] = 68, -+ [0][1][2][1][RTW89_KCC][17] = 62, -+ [0][1][2][1][RTW89_ACMA][17] = 36, -+ [0][1][2][1][RTW89_CHILE][17] = 36, -+ [0][1][2][1][RTW89_UKRAINE][17] = 28, -+ [0][1][2][1][RTW89_MEXICO][17] = 68, -+ [0][1][2][1][RTW89_CN][17] = 127, -+ [0][1][2][1][RTW89_QATAR][17] = 36, -+ [0][1][2][1][RTW89_UK][17] = 36, -+ [0][1][2][1][RTW89_FCC][19] = 68, -+ [0][1][2][1][RTW89_ETSI][19] = 36, -+ [0][1][2][1][RTW89_MKK][19] = 70, -+ [0][1][2][1][RTW89_IC][19] = 68, -+ [0][1][2][1][RTW89_KCC][19] = 62, -+ [0][1][2][1][RTW89_ACMA][19] = 36, -+ [0][1][2][1][RTW89_CHILE][19] = 36, -+ [0][1][2][1][RTW89_UKRAINE][19] = 28, -+ [0][1][2][1][RTW89_MEXICO][19] = 68, -+ [0][1][2][1][RTW89_CN][19] = 127, -+ [0][1][2][1][RTW89_QATAR][19] = 36, -+ [0][1][2][1][RTW89_UK][19] = 36, -+ [0][1][2][1][RTW89_FCC][21] = 68, -+ [0][1][2][1][RTW89_ETSI][21] = 36, -+ [0][1][2][1][RTW89_MKK][21] = 70, -+ [0][1][2][1][RTW89_IC][21] = 68, -+ [0][1][2][1][RTW89_KCC][21] = 62, -+ [0][1][2][1][RTW89_ACMA][21] = 36, -+ [0][1][2][1][RTW89_CHILE][21] = 36, -+ [0][1][2][1][RTW89_UKRAINE][21] = 28, -+ [0][1][2][1][RTW89_MEXICO][21] = 68, -+ [0][1][2][1][RTW89_CN][21] = 127, -+ [0][1][2][1][RTW89_QATAR][21] = 36, -+ [0][1][2][1][RTW89_UK][21] = 36, -+ [0][1][2][1][RTW89_FCC][23] = 68, -+ [0][1][2][1][RTW89_ETSI][23] = 36, -+ [0][1][2][1][RTW89_MKK][23] = 70, -+ [0][1][2][1][RTW89_IC][23] = 68, -+ [0][1][2][1][RTW89_KCC][23] = 62, -+ [0][1][2][1][RTW89_ACMA][23] = 36, -+ [0][1][2][1][RTW89_CHILE][23] = 36, -+ [0][1][2][1][RTW89_UKRAINE][23] = 28, -+ [0][1][2][1][RTW89_MEXICO][23] = 68, -+ [0][1][2][1][RTW89_CN][23] = 127, -+ [0][1][2][1][RTW89_QATAR][23] = 36, -+ [0][1][2][1][RTW89_UK][23] = 36, -+ [0][1][2][1][RTW89_FCC][25] = 66, -+ [0][1][2][1][RTW89_ETSI][25] = 36, -+ [0][1][2][1][RTW89_MKK][25] = 70, -+ [0][1][2][1][RTW89_IC][25] = 127, -+ [0][1][2][1][RTW89_KCC][25] = 62, -+ [0][1][2][1][RTW89_ACMA][25] = 127, -+ [0][1][2][1][RTW89_CHILE][25] = 36, -+ [0][1][2][1][RTW89_UKRAINE][25] = 28, -+ [0][1][2][1][RTW89_MEXICO][25] = 66, -+ [0][1][2][1][RTW89_CN][25] = 127, -+ [0][1][2][1][RTW89_QATAR][25] = 36, -+ [0][1][2][1][RTW89_UK][25] = 36, -+ [0][1][2][1][RTW89_FCC][27] = 66, -+ [0][1][2][1][RTW89_ETSI][27] = 36, -+ [0][1][2][1][RTW89_MKK][27] = 70, -+ [0][1][2][1][RTW89_IC][27] = 127, -+ [0][1][2][1][RTW89_KCC][27] = 62, -+ [0][1][2][1][RTW89_ACMA][27] = 127, -+ [0][1][2][1][RTW89_CHILE][27] = 36, -+ [0][1][2][1][RTW89_UKRAINE][27] = 28, -+ [0][1][2][1][RTW89_MEXICO][27] = 66, -+ [0][1][2][1][RTW89_CN][27] = 127, -+ [0][1][2][1][RTW89_QATAR][27] = 36, -+ [0][1][2][1][RTW89_UK][27] = 36, -+ [0][1][2][1][RTW89_FCC][29] = 66, -+ [0][1][2][1][RTW89_ETSI][29] = 36, -+ [0][1][2][1][RTW89_MKK][29] = 70, -+ [0][1][2][1][RTW89_IC][29] = 127, -+ [0][1][2][1][RTW89_KCC][29] = 62, -+ [0][1][2][1][RTW89_ACMA][29] = 127, -+ [0][1][2][1][RTW89_CHILE][29] = 36, -+ [0][1][2][1][RTW89_UKRAINE][29] = 28, -+ [0][1][2][1][RTW89_MEXICO][29] = 66, -+ [0][1][2][1][RTW89_CN][29] = 127, -+ [0][1][2][1][RTW89_QATAR][29] = 36, -+ [0][1][2][1][RTW89_UK][29] = 36, -+ [0][1][2][1][RTW89_FCC][31] = 66, -+ [0][1][2][1][RTW89_ETSI][31] = 36, -+ [0][1][2][1][RTW89_MKK][31] = 70, -+ [0][1][2][1][RTW89_IC][31] = 66, -+ [0][1][2][1][RTW89_KCC][31] = 62, -+ [0][1][2][1][RTW89_ACMA][31] = 36, -+ [0][1][2][1][RTW89_CHILE][31] = 36, -+ [0][1][2][1][RTW89_UKRAINE][31] = 28, -+ [0][1][2][1][RTW89_MEXICO][31] = 66, -+ [0][1][2][1][RTW89_CN][31] = 127, -+ [0][1][2][1][RTW89_QATAR][31] = 36, -+ [0][1][2][1][RTW89_UK][31] = 36, -+ [0][1][2][1][RTW89_FCC][33] = 66, -+ [0][1][2][1][RTW89_ETSI][33] = 36, -+ [0][1][2][1][RTW89_MKK][33] = 70, -+ [0][1][2][1][RTW89_IC][33] = 66, -+ [0][1][2][1][RTW89_KCC][33] = 62, -+ [0][1][2][1][RTW89_ACMA][33] = 36, -+ [0][1][2][1][RTW89_CHILE][33] = 36, -+ [0][1][2][1][RTW89_UKRAINE][33] = 28, -+ [0][1][2][1][RTW89_MEXICO][33] = 66, -+ [0][1][2][1][RTW89_CN][33] = 127, -+ [0][1][2][1][RTW89_QATAR][33] = 36, -+ [0][1][2][1][RTW89_UK][33] = 36, -+ [0][1][2][1][RTW89_FCC][35] = 66, -+ [0][1][2][1][RTW89_ETSI][35] = 36, -+ [0][1][2][1][RTW89_MKK][35] = 70, -+ [0][1][2][1][RTW89_IC][35] = 66, -+ [0][1][2][1][RTW89_KCC][35] = 62, -+ [0][1][2][1][RTW89_ACMA][35] = 36, -+ [0][1][2][1][RTW89_CHILE][35] = 36, -+ [0][1][2][1][RTW89_UKRAINE][35] = 28, -+ [0][1][2][1][RTW89_MEXICO][35] = 66, -+ [0][1][2][1][RTW89_CN][35] = 127, -+ [0][1][2][1][RTW89_QATAR][35] = 36, -+ [0][1][2][1][RTW89_UK][35] = 36, -+ [0][1][2][1][RTW89_FCC][37] = 68, -+ [0][1][2][1][RTW89_ETSI][37] = 127, -+ [0][1][2][1][RTW89_MKK][37] = 70, -+ [0][1][2][1][RTW89_IC][37] = 68, -+ [0][1][2][1][RTW89_KCC][37] = 62, -+ [0][1][2][1][RTW89_ACMA][37] = 70, -+ [0][1][2][1][RTW89_CHILE][37] = 36, -+ [0][1][2][1][RTW89_UKRAINE][37] = 127, -+ [0][1][2][1][RTW89_MEXICO][37] = 68, -+ [0][1][2][1][RTW89_CN][37] = 127, -+ [0][1][2][1][RTW89_QATAR][37] = 127, -+ [0][1][2][1][RTW89_UK][37] = 62, -+ [0][1][2][1][RTW89_FCC][38] = 78, -+ [0][1][2][1][RTW89_ETSI][38] = 4, -+ [0][1][2][1][RTW89_MKK][38] = 127, -+ [0][1][2][1][RTW89_IC][38] = 78, -+ [0][1][2][1][RTW89_KCC][38] = 62, -+ [0][1][2][1][RTW89_ACMA][38] = 74, -+ [0][1][2][1][RTW89_CHILE][38] = 36, -+ [0][1][2][1][RTW89_UKRAINE][38] = 4, -+ [0][1][2][1][RTW89_MEXICO][38] = 78, -+ [0][1][2][1][RTW89_CN][38] = 72, -+ [0][1][2][1][RTW89_QATAR][38] = 4, -+ [0][1][2][1][RTW89_UK][38] = 36, -+ [0][1][2][1][RTW89_FCC][40] = 78, -+ [0][1][2][1][RTW89_ETSI][40] = 4, -+ [0][1][2][1][RTW89_MKK][40] = 127, -+ [0][1][2][1][RTW89_IC][40] = 78, -+ [0][1][2][1][RTW89_KCC][40] = 62, -+ [0][1][2][1][RTW89_ACMA][40] = 74, -+ [0][1][2][1][RTW89_CHILE][40] = 36, -+ [0][1][2][1][RTW89_UKRAINE][40] = 4, -+ [0][1][2][1][RTW89_MEXICO][40] = 78, -+ [0][1][2][1][RTW89_CN][40] = 72, -+ [0][1][2][1][RTW89_QATAR][40] = 4, -+ [0][1][2][1][RTW89_UK][40] = 36, -+ [0][1][2][1][RTW89_FCC][42] = 78, -+ [0][1][2][1][RTW89_ETSI][42] = 4, -+ [0][1][2][1][RTW89_MKK][42] = 127, -+ [0][1][2][1][RTW89_IC][42] = 78, -+ [0][1][2][1][RTW89_KCC][42] = 62, -+ [0][1][2][1][RTW89_ACMA][42] = 76, -+ [0][1][2][1][RTW89_CHILE][42] = 36, -+ [0][1][2][1][RTW89_UKRAINE][42] = 4, -+ [0][1][2][1][RTW89_MEXICO][42] = 78, -+ [0][1][2][1][RTW89_CN][42] = 72, -+ [0][1][2][1][RTW89_QATAR][42] = 4, -+ [0][1][2][1][RTW89_UK][42] = 36, -+ [0][1][2][1][RTW89_FCC][44] = 78, -+ [0][1][2][1][RTW89_ETSI][44] = 4, -+ [0][1][2][1][RTW89_MKK][44] = 127, -+ [0][1][2][1][RTW89_IC][44] = 78, -+ [0][1][2][1][RTW89_KCC][44] = 62, -+ [0][1][2][1][RTW89_ACMA][44] = 76, -+ [0][1][2][1][RTW89_CHILE][44] = 36, -+ [0][1][2][1][RTW89_UKRAINE][44] = 4, -+ [0][1][2][1][RTW89_MEXICO][44] = 78, -+ [0][1][2][1][RTW89_CN][44] = 76, -+ [0][1][2][1][RTW89_QATAR][44] = 4, -+ [0][1][2][1][RTW89_UK][44] = 36, -+ [0][1][2][1][RTW89_FCC][46] = 78, -+ [0][1][2][1][RTW89_ETSI][46] = 4, -+ [0][1][2][1][RTW89_MKK][46] = 127, -+ [0][1][2][1][RTW89_IC][46] = 78, -+ [0][1][2][1][RTW89_KCC][46] = 62, -+ [0][1][2][1][RTW89_ACMA][46] = 76, -+ [0][1][2][1][RTW89_CHILE][46] = 36, -+ [0][1][2][1][RTW89_UKRAINE][46] = 4, -+ [0][1][2][1][RTW89_MEXICO][46] = 78, -+ [0][1][2][1][RTW89_CN][46] = 76, -+ [0][1][2][1][RTW89_QATAR][46] = 4, -+ [0][1][2][1][RTW89_UK][46] = 36, -+ [0][1][2][1][RTW89_FCC][48] = 58, -+ [0][1][2][1][RTW89_ETSI][48] = 127, -+ [0][1][2][1][RTW89_MKK][48] = 127, -+ [0][1][2][1][RTW89_IC][48] = 127, -+ [0][1][2][1][RTW89_KCC][48] = 127, -+ [0][1][2][1][RTW89_ACMA][48] = 127, -+ [0][1][2][1][RTW89_CHILE][48] = 127, -+ [0][1][2][1][RTW89_UKRAINE][48] = 127, -+ [0][1][2][1][RTW89_MEXICO][48] = 127, -+ [0][1][2][1][RTW89_CN][48] = 127, -+ [0][1][2][1][RTW89_QATAR][48] = 127, -+ [0][1][2][1][RTW89_UK][48] = 127, -+ [0][1][2][1][RTW89_FCC][50] = 58, -+ [0][1][2][1][RTW89_ETSI][50] = 127, -+ [0][1][2][1][RTW89_MKK][50] = 127, -+ [0][1][2][1][RTW89_IC][50] = 127, -+ [0][1][2][1][RTW89_KCC][50] = 127, -+ [0][1][2][1][RTW89_ACMA][50] = 127, -+ [0][1][2][1][RTW89_CHILE][50] = 127, -+ [0][1][2][1][RTW89_UKRAINE][50] = 127, -+ [0][1][2][1][RTW89_MEXICO][50] = 127, -+ [0][1][2][1][RTW89_CN][50] = 127, -+ [0][1][2][1][RTW89_QATAR][50] = 127, -+ [0][1][2][1][RTW89_UK][50] = 127, -+ [0][1][2][1][RTW89_FCC][52] = 58, -+ [0][1][2][1][RTW89_ETSI][52] = 127, -+ [0][1][2][1][RTW89_MKK][52] = 127, -+ [0][1][2][1][RTW89_IC][52] = 127, -+ [0][1][2][1][RTW89_KCC][52] = 127, -+ [0][1][2][1][RTW89_ACMA][52] = 127, -+ [0][1][2][1][RTW89_CHILE][52] = 127, -+ [0][1][2][1][RTW89_UKRAINE][52] = 127, -+ [0][1][2][1][RTW89_MEXICO][52] = 127, -+ [0][1][2][1][RTW89_CN][52] = 127, -+ [0][1][2][1][RTW89_QATAR][52] = 127, -+ [0][1][2][1][RTW89_UK][52] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 66, -+ [1][0][2][0][RTW89_ETSI][1] = 64, -+ [1][0][2][0][RTW89_MKK][1] = 62, -+ [1][0][2][0][RTW89_IC][1] = 64, -+ [1][0][2][0][RTW89_KCC][1] = 70, -+ [1][0][2][0][RTW89_ACMA][1] = 64, -+ [1][0][2][0][RTW89_CHILE][1] = 42, -+ [1][0][2][0][RTW89_UKRAINE][1] = 52, -+ [1][0][2][0][RTW89_MEXICO][1] = 62, -+ [1][0][2][0][RTW89_CN][1] = 62, -+ [1][0][2][0][RTW89_QATAR][1] = 64, -+ [1][0][2][0][RTW89_UK][1] = 64, -+ [1][0][2][0][RTW89_FCC][5] = 78, -+ [1][0][2][0][RTW89_ETSI][5] = 64, -+ [1][0][2][0][RTW89_MKK][5] = 62, -+ [1][0][2][0][RTW89_IC][5] = 64, -+ [1][0][2][0][RTW89_KCC][5] = 66, -+ [1][0][2][0][RTW89_ACMA][5] = 64, -+ [1][0][2][0][RTW89_CHILE][5] = 42, -+ [1][0][2][0][RTW89_UKRAINE][5] = 52, -+ [1][0][2][0][RTW89_MEXICO][5] = 62, -+ [1][0][2][0][RTW89_CN][5] = 62, -+ [1][0][2][0][RTW89_QATAR][5] = 64, -+ [1][0][2][0][RTW89_UK][5] = 64, -+ [1][0][2][0][RTW89_FCC][9] = 78, -+ [1][0][2][0][RTW89_ETSI][9] = 64, -+ [1][0][2][0][RTW89_MKK][9] = 62, -+ [1][0][2][0][RTW89_IC][9] = 64, -+ [1][0][2][0][RTW89_KCC][9] = 74, -+ [1][0][2][0][RTW89_ACMA][9] = 64, -+ [1][0][2][0][RTW89_CHILE][9] = 66, -+ [1][0][2][0][RTW89_UKRAINE][9] = 52, -+ [1][0][2][0][RTW89_MEXICO][9] = 78, -+ [1][0][2][0][RTW89_CN][9] = 62, -+ [1][0][2][0][RTW89_QATAR][9] = 64, -+ [1][0][2][0][RTW89_UK][9] = 64, -+ [1][0][2][0][RTW89_FCC][13] = 66, -+ [1][0][2][0][RTW89_ETSI][13] = 64, -+ [1][0][2][0][RTW89_MKK][13] = 62, -+ [1][0][2][0][RTW89_IC][13] = 64, -+ [1][0][2][0][RTW89_KCC][13] = 68, -+ [1][0][2][0][RTW89_ACMA][13] = 64, -+ [1][0][2][0][RTW89_CHILE][13] = 66, -+ [1][0][2][0][RTW89_UKRAINE][13] = 52, -+ [1][0][2][0][RTW89_MEXICO][13] = 66, -+ [1][0][2][0][RTW89_CN][13] = 62, -+ [1][0][2][0][RTW89_QATAR][13] = 64, -+ [1][0][2][0][RTW89_UK][13] = 64, -+ [1][0][2][0][RTW89_FCC][16] = 64, -+ [1][0][2][0][RTW89_ETSI][16] = 64, -+ [1][0][2][0][RTW89_MKK][16] = 74, -+ [1][0][2][0][RTW89_IC][16] = 64, -+ [1][0][2][0][RTW89_KCC][16] = 70, -+ [1][0][2][0][RTW89_ACMA][16] = 64, -+ [1][0][2][0][RTW89_CHILE][16] = 64, -+ [1][0][2][0][RTW89_UKRAINE][16] = 52, -+ [1][0][2][0][RTW89_MEXICO][16] = 64, -+ [1][0][2][0][RTW89_CN][16] = 127, -+ [1][0][2][0][RTW89_QATAR][16] = 64, -+ [1][0][2][0][RTW89_UK][16] = 64, -+ [1][0][2][0][RTW89_FCC][20] = 78, -+ [1][0][2][0][RTW89_ETSI][20] = 64, -+ [1][0][2][0][RTW89_MKK][20] = 74, -+ [1][0][2][0][RTW89_IC][20] = 78, -+ [1][0][2][0][RTW89_KCC][20] = 70, -+ [1][0][2][0][RTW89_ACMA][20] = 64, -+ [1][0][2][0][RTW89_CHILE][20] = 62, -+ [1][0][2][0][RTW89_UKRAINE][20] = 52, -+ [1][0][2][0][RTW89_MEXICO][20] = 78, -+ [1][0][2][0][RTW89_CN][20] = 127, -+ [1][0][2][0][RTW89_QATAR][20] = 64, -+ [1][0][2][0][RTW89_UK][20] = 64, -+ [1][0][2][0][RTW89_FCC][24] = 78, -+ [1][0][2][0][RTW89_ETSI][24] = 64, -+ [1][0][2][0][RTW89_MKK][24] = 74, -+ [1][0][2][0][RTW89_IC][24] = 127, -+ [1][0][2][0][RTW89_KCC][24] = 70, -+ [1][0][2][0][RTW89_ACMA][24] = 127, -+ [1][0][2][0][RTW89_CHILE][24] = 62, -+ [1][0][2][0][RTW89_UKRAINE][24] = 52, -+ [1][0][2][0][RTW89_MEXICO][24] = 78, -+ [1][0][2][0][RTW89_CN][24] = 127, -+ [1][0][2][0][RTW89_QATAR][24] = 64, -+ [1][0][2][0][RTW89_UK][24] = 64, -+ [1][0][2][0][RTW89_FCC][28] = 78, -+ [1][0][2][0][RTW89_ETSI][28] = 64, -+ [1][0][2][0][RTW89_MKK][28] = 74, -+ [1][0][2][0][RTW89_IC][28] = 127, -+ [1][0][2][0][RTW89_KCC][28] = 74, -+ [1][0][2][0][RTW89_ACMA][28] = 127, -+ [1][0][2][0][RTW89_CHILE][28] = 64, -+ [1][0][2][0][RTW89_UKRAINE][28] = 52, -+ [1][0][2][0][RTW89_MEXICO][28] = 78, -+ [1][0][2][0][RTW89_CN][28] = 127, -+ [1][0][2][0][RTW89_QATAR][28] = 64, -+ [1][0][2][0][RTW89_UK][28] = 64, -+ [1][0][2][0][RTW89_FCC][32] = 76, -+ [1][0][2][0][RTW89_ETSI][32] = 64, -+ [1][0][2][0][RTW89_MKK][32] = 74, -+ [1][0][2][0][RTW89_IC][32] = 76, -+ [1][0][2][0][RTW89_KCC][32] = 74, -+ [1][0][2][0][RTW89_ACMA][32] = 64, -+ [1][0][2][0][RTW89_CHILE][32] = 64, -+ [1][0][2][0][RTW89_UKRAINE][32] = 52, -+ [1][0][2][0][RTW89_MEXICO][32] = 76, -+ [1][0][2][0][RTW89_CN][32] = 127, -+ [1][0][2][0][RTW89_QATAR][32] = 64, -+ [1][0][2][0][RTW89_UK][32] = 64, -+ [1][0][2][0][RTW89_FCC][36] = 78, -+ [1][0][2][0][RTW89_ETSI][36] = 127, -+ [1][0][2][0][RTW89_MKK][36] = 74, -+ [1][0][2][0][RTW89_IC][36] = 78, -+ [1][0][2][0][RTW89_KCC][36] = 74, -+ [1][0][2][0][RTW89_ACMA][36] = 74, -+ [1][0][2][0][RTW89_CHILE][36] = 64, -+ [1][0][2][0][RTW89_UKRAINE][36] = 127, -+ [1][0][2][0][RTW89_MEXICO][36] = 78, -+ [1][0][2][0][RTW89_CN][36] = 127, -+ [1][0][2][0][RTW89_QATAR][36] = 127, -+ [1][0][2][0][RTW89_UK][36] = 74, -+ [1][0][2][0][RTW89_FCC][39] = 78, -+ [1][0][2][0][RTW89_ETSI][39] = 28, -+ [1][0][2][0][RTW89_MKK][39] = 127, -+ [1][0][2][0][RTW89_IC][39] = 78, -+ [1][0][2][0][RTW89_KCC][39] = 74, -+ [1][0][2][0][RTW89_ACMA][39] = 74, -+ [1][0][2][0][RTW89_CHILE][39] = 64, -+ [1][0][2][0][RTW89_UKRAINE][39] = 28, -+ [1][0][2][0][RTW89_MEXICO][39] = 78, -+ [1][0][2][0][RTW89_CN][39] = 70, -+ [1][0][2][0][RTW89_QATAR][39] = 28, -+ [1][0][2][0][RTW89_UK][39] = 64, -+ [1][0][2][0][RTW89_FCC][43] = 78, -+ [1][0][2][0][RTW89_ETSI][43] = 28, -+ [1][0][2][0][RTW89_MKK][43] = 127, -+ [1][0][2][0][RTW89_IC][43] = 78, -+ [1][0][2][0][RTW89_KCC][43] = 74, -+ [1][0][2][0][RTW89_ACMA][43] = 74, -+ [1][0][2][0][RTW89_CHILE][43] = 64, -+ [1][0][2][0][RTW89_UKRAINE][43] = 28, -+ [1][0][2][0][RTW89_MEXICO][43] = 78, -+ [1][0][2][0][RTW89_CN][43] = 74, -+ [1][0][2][0][RTW89_QATAR][43] = 28, -+ [1][0][2][0][RTW89_UK][43] = 62, -+ [1][0][2][0][RTW89_FCC][47] = 78, -+ [1][0][2][0][RTW89_ETSI][47] = 127, -+ [1][0][2][0][RTW89_MKK][47] = 127, -+ [1][0][2][0][RTW89_IC][47] = 127, -+ [1][0][2][0][RTW89_KCC][47] = 127, -+ [1][0][2][0][RTW89_ACMA][47] = 127, -+ [1][0][2][0][RTW89_CHILE][47] = 127, -+ [1][0][2][0][RTW89_UKRAINE][47] = 127, -+ [1][0][2][0][RTW89_MEXICO][47] = 127, -+ [1][0][2][0][RTW89_CN][47] = 127, -+ [1][0][2][0][RTW89_QATAR][47] = 127, -+ [1][0][2][0][RTW89_UK][47] = 127, -+ [1][0][2][0][RTW89_FCC][51] = 70, -+ [1][0][2][0][RTW89_ETSI][51] = 127, -+ [1][0][2][0][RTW89_MKK][51] = 127, -+ [1][0][2][0][RTW89_IC][51] = 127, -+ [1][0][2][0][RTW89_KCC][51] = 127, -+ [1][0][2][0][RTW89_ACMA][51] = 127, -+ [1][0][2][0][RTW89_CHILE][51] = 127, -+ [1][0][2][0][RTW89_UKRAINE][51] = 127, -+ [1][0][2][0][RTW89_MEXICO][51] = 127, -+ [1][0][2][0][RTW89_CN][51] = 127, -+ [1][0][2][0][RTW89_QATAR][51] = 127, -+ [1][0][2][0][RTW89_UK][51] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 62, -+ [1][1][2][0][RTW89_ETSI][1] = 52, -+ [1][1][2][0][RTW89_MKK][1] = 50, -+ [1][1][2][0][RTW89_IC][1] = 52, -+ [1][1][2][0][RTW89_KCC][1] = 58, -+ [1][1][2][0][RTW89_ACMA][1] = 52, -+ [1][1][2][0][RTW89_CHILE][1] = 30, -+ [1][1][2][0][RTW89_UKRAINE][1] = 40, -+ [1][1][2][0][RTW89_MEXICO][1] = 50, -+ [1][1][2][0][RTW89_CN][1] = 50, -+ [1][1][2][0][RTW89_QATAR][1] = 52, -+ [1][1][2][0][RTW89_UK][1] = 52, -+ [1][1][2][0][RTW89_FCC][5] = 76, -+ [1][1][2][0][RTW89_ETSI][5] = 52, -+ [1][1][2][0][RTW89_MKK][5] = 50, -+ [1][1][2][0][RTW89_IC][5] = 52, -+ [1][1][2][0][RTW89_KCC][5] = 48, -+ [1][1][2][0][RTW89_ACMA][5] = 52, -+ [1][1][2][0][RTW89_CHILE][5] = 30, -+ [1][1][2][0][RTW89_UKRAINE][5] = 40, -+ [1][1][2][0][RTW89_MEXICO][5] = 50, -+ [1][1][2][0][RTW89_CN][5] = 50, -+ [1][1][2][0][RTW89_QATAR][5] = 52, -+ [1][1][2][0][RTW89_UK][5] = 52, -+ [1][1][2][0][RTW89_FCC][9] = 76, -+ [1][1][2][0][RTW89_ETSI][9] = 52, -+ [1][1][2][0][RTW89_MKK][9] = 50, -+ [1][1][2][0][RTW89_IC][9] = 52, -+ [1][1][2][0][RTW89_KCC][9] = 60, -+ [1][1][2][0][RTW89_ACMA][9] = 52, -+ [1][1][2][0][RTW89_CHILE][9] = 50, -+ [1][1][2][0][RTW89_UKRAINE][9] = 40, -+ [1][1][2][0][RTW89_MEXICO][9] = 76, -+ [1][1][2][0][RTW89_CN][9] = 50, -+ [1][1][2][0][RTW89_QATAR][9] = 52, -+ [1][1][2][0][RTW89_UK][9] = 52, -+ [1][1][2][0][RTW89_FCC][13] = 62, -+ [1][1][2][0][RTW89_ETSI][13] = 52, -+ [1][1][2][0][RTW89_MKK][13] = 50, -+ [1][1][2][0][RTW89_IC][13] = 52, -+ [1][1][2][0][RTW89_KCC][13] = 58, -+ [1][1][2][0][RTW89_ACMA][13] = 52, -+ [1][1][2][0][RTW89_CHILE][13] = 48, -+ [1][1][2][0][RTW89_UKRAINE][13] = 40, -+ [1][1][2][0][RTW89_MEXICO][13] = 62, -+ [1][1][2][0][RTW89_CN][13] = 50, -+ [1][1][2][0][RTW89_QATAR][13] = 52, -+ [1][1][2][0][RTW89_UK][13] = 52, -+ [1][1][2][0][RTW89_FCC][16] = 56, -+ [1][1][2][0][RTW89_ETSI][16] = 52, -+ [1][1][2][0][RTW89_MKK][16] = 70, -+ [1][1][2][0][RTW89_IC][16] = 56, -+ [1][1][2][0][RTW89_KCC][16] = 58, -+ [1][1][2][0][RTW89_ACMA][16] = 52, -+ [1][1][2][0][RTW89_CHILE][16] = 48, -+ [1][1][2][0][RTW89_UKRAINE][16] = 40, -+ [1][1][2][0][RTW89_MEXICO][16] = 56, -+ [1][1][2][0][RTW89_CN][16] = 127, -+ [1][1][2][0][RTW89_QATAR][16] = 52, -+ [1][1][2][0][RTW89_UK][16] = 52, -+ [1][1][2][0][RTW89_FCC][20] = 76, -+ [1][1][2][0][RTW89_ETSI][20] = 52, -+ [1][1][2][0][RTW89_MKK][20] = 70, -+ [1][1][2][0][RTW89_IC][20] = 76, -+ [1][1][2][0][RTW89_KCC][20] = 58, -+ [1][1][2][0][RTW89_ACMA][20] = 52, -+ [1][1][2][0][RTW89_CHILE][20] = 50, -+ [1][1][2][0][RTW89_UKRAINE][20] = 40, -+ [1][1][2][0][RTW89_MEXICO][20] = 76, -+ [1][1][2][0][RTW89_CN][20] = 127, -+ [1][1][2][0][RTW89_QATAR][20] = 52, -+ [1][1][2][0][RTW89_UK][20] = 52, -+ [1][1][2][0][RTW89_FCC][24] = 76, -+ [1][1][2][0][RTW89_ETSI][24] = 52, -+ [1][1][2][0][RTW89_MKK][24] = 70, -+ [1][1][2][0][RTW89_IC][24] = 127, -+ [1][1][2][0][RTW89_KCC][24] = 58, -+ [1][1][2][0][RTW89_ACMA][24] = 127, -+ [1][1][2][0][RTW89_CHILE][24] = 50, -+ [1][1][2][0][RTW89_UKRAINE][24] = 40, -+ [1][1][2][0][RTW89_MEXICO][24] = 76, -+ [1][1][2][0][RTW89_CN][24] = 127, -+ [1][1][2][0][RTW89_QATAR][24] = 52, -+ [1][1][2][0][RTW89_UK][24] = 52, -+ [1][1][2][0][RTW89_FCC][28] = 76, -+ [1][1][2][0][RTW89_ETSI][28] = 52, -+ [1][1][2][0][RTW89_MKK][28] = 70, -+ [1][1][2][0][RTW89_IC][28] = 127, -+ [1][1][2][0][RTW89_KCC][28] = 60, -+ [1][1][2][0][RTW89_ACMA][28] = 127, -+ [1][1][2][0][RTW89_CHILE][28] = 48, -+ [1][1][2][0][RTW89_UKRAINE][28] = 40, -+ [1][1][2][0][RTW89_MEXICO][28] = 76, -+ [1][1][2][0][RTW89_CN][28] = 127, -+ [1][1][2][0][RTW89_QATAR][28] = 52, -+ [1][1][2][0][RTW89_UK][28] = 52, -+ [1][1][2][0][RTW89_FCC][32] = 68, -+ [1][1][2][0][RTW89_ETSI][32] = 52, -+ [1][1][2][0][RTW89_MKK][32] = 70, -+ [1][1][2][0][RTW89_IC][32] = 68, -+ [1][1][2][0][RTW89_KCC][32] = 60, -+ [1][1][2][0][RTW89_ACMA][32] = 52, -+ [1][1][2][0][RTW89_CHILE][32] = 48, -+ [1][1][2][0][RTW89_UKRAINE][32] = 40, -+ [1][1][2][0][RTW89_MEXICO][32] = 68, -+ [1][1][2][0][RTW89_CN][32] = 127, -+ [1][1][2][0][RTW89_QATAR][32] = 52, -+ [1][1][2][0][RTW89_UK][32] = 52, -+ [1][1][2][0][RTW89_FCC][36] = 76, -+ [1][1][2][0][RTW89_ETSI][36] = 127, -+ [1][1][2][0][RTW89_MKK][36] = 70, -+ [1][1][2][0][RTW89_IC][36] = 76, -+ [1][1][2][0][RTW89_KCC][36] = 60, -+ [1][1][2][0][RTW89_ACMA][36] = 74, -+ [1][1][2][0][RTW89_CHILE][36] = 50, -+ [1][1][2][0][RTW89_UKRAINE][36] = 127, -+ [1][1][2][0][RTW89_MEXICO][36] = 76, -+ [1][1][2][0][RTW89_CN][36] = 127, -+ [1][1][2][0][RTW89_QATAR][36] = 127, -+ [1][1][2][0][RTW89_UK][36] = 74, -+ [1][1][2][0][RTW89_FCC][39] = 78, -+ [1][1][2][0][RTW89_ETSI][39] = 16, -+ [1][1][2][0][RTW89_MKK][39] = 127, -+ [1][1][2][0][RTW89_IC][39] = 78, -+ [1][1][2][0][RTW89_KCC][39] = 58, -+ [1][1][2][0][RTW89_ACMA][39] = 72, -+ [1][1][2][0][RTW89_CHILE][39] = 52, -+ [1][1][2][0][RTW89_UKRAINE][39] = 16, -+ [1][1][2][0][RTW89_MEXICO][39] = 78, -+ [1][1][2][0][RTW89_CN][39] = 70, -+ [1][1][2][0][RTW89_QATAR][39] = 16, -+ [1][1][2][0][RTW89_UK][39] = 52, -+ [1][1][2][0][RTW89_FCC][43] = 78, -+ [1][1][2][0][RTW89_ETSI][43] = 16, -+ [1][1][2][0][RTW89_MKK][43] = 127, -+ [1][1][2][0][RTW89_IC][43] = 78, -+ [1][1][2][0][RTW89_KCC][43] = 58, -+ [1][1][2][0][RTW89_ACMA][43] = 74, -+ [1][1][2][0][RTW89_CHILE][43] = 52, -+ [1][1][2][0][RTW89_UKRAINE][43] = 16, -+ [1][1][2][0][RTW89_MEXICO][43] = 78, -+ [1][1][2][0][RTW89_CN][43] = 74, -+ [1][1][2][0][RTW89_QATAR][43] = 16, -+ [1][1][2][0][RTW89_UK][43] = 52, -+ [1][1][2][0][RTW89_FCC][47] = 68, -+ [1][1][2][0][RTW89_ETSI][47] = 127, -+ [1][1][2][0][RTW89_MKK][47] = 127, -+ [1][1][2][0][RTW89_IC][47] = 127, -+ [1][1][2][0][RTW89_KCC][47] = 127, -+ [1][1][2][0][RTW89_ACMA][47] = 127, -+ [1][1][2][0][RTW89_CHILE][47] = 127, -+ [1][1][2][0][RTW89_UKRAINE][47] = 127, -+ [1][1][2][0][RTW89_MEXICO][47] = 127, -+ [1][1][2][0][RTW89_CN][47] = 127, -+ [1][1][2][0][RTW89_QATAR][47] = 127, -+ [1][1][2][0][RTW89_UK][47] = 127, -+ [1][1][2][0][RTW89_FCC][51] = 66, -+ [1][1][2][0][RTW89_ETSI][51] = 127, -+ [1][1][2][0][RTW89_MKK][51] = 127, -+ [1][1][2][0][RTW89_IC][51] = 127, -+ [1][1][2][0][RTW89_KCC][51] = 127, -+ [1][1][2][0][RTW89_ACMA][51] = 127, -+ [1][1][2][0][RTW89_CHILE][51] = 127, -+ [1][1][2][0][RTW89_UKRAINE][51] = 127, -+ [1][1][2][0][RTW89_MEXICO][51] = 127, -+ [1][1][2][0][RTW89_CN][51] = 127, -+ [1][1][2][0][RTW89_QATAR][51] = 127, -+ [1][1][2][0][RTW89_UK][51] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 62, -+ [1][1][2][1][RTW89_ETSI][1] = 40, -+ [1][1][2][1][RTW89_MKK][1] = 50, -+ [1][1][2][1][RTW89_IC][1] = 40, -+ [1][1][2][1][RTW89_KCC][1] = 58, -+ [1][1][2][1][RTW89_ACMA][1] = 40, -+ [1][1][2][1][RTW89_CHILE][1] = 16, -+ [1][1][2][1][RTW89_UKRAINE][1] = 28, -+ [1][1][2][1][RTW89_MEXICO][1] = 50, -+ [1][1][2][1][RTW89_CN][1] = 38, -+ [1][1][2][1][RTW89_QATAR][1] = 40, -+ [1][1][2][1][RTW89_UK][1] = 40, -+ [1][1][2][1][RTW89_FCC][5] = 68, -+ [1][1][2][1][RTW89_ETSI][5] = 40, -+ [1][1][2][1][RTW89_MKK][5] = 50, -+ [1][1][2][1][RTW89_IC][5] = 40, -+ [1][1][2][1][RTW89_KCC][5] = 48, -+ [1][1][2][1][RTW89_ACMA][5] = 40, -+ [1][1][2][1][RTW89_CHILE][5] = 16, -+ [1][1][2][1][RTW89_UKRAINE][5] = 28, -+ [1][1][2][1][RTW89_MEXICO][5] = 50, -+ [1][1][2][1][RTW89_CN][5] = 38, -+ [1][1][2][1][RTW89_QATAR][5] = 40, -+ [1][1][2][1][RTW89_UK][5] = 40, -+ [1][1][2][1][RTW89_FCC][9] = 68, -+ [1][1][2][1][RTW89_ETSI][9] = 40, -+ [1][1][2][1][RTW89_MKK][9] = 50, -+ [1][1][2][1][RTW89_IC][9] = 40, -+ [1][1][2][1][RTW89_KCC][9] = 60, -+ [1][1][2][1][RTW89_ACMA][9] = 40, -+ [1][1][2][1][RTW89_CHILE][9] = 36, -+ [1][1][2][1][RTW89_UKRAINE][9] = 28, -+ [1][1][2][1][RTW89_MEXICO][9] = 68, -+ [1][1][2][1][RTW89_CN][9] = 38, -+ [1][1][2][1][RTW89_QATAR][9] = 40, -+ [1][1][2][1][RTW89_UK][9] = 40, -+ [1][1][2][1][RTW89_FCC][13] = 62, -+ [1][1][2][1][RTW89_ETSI][13] = 40, -+ [1][1][2][1][RTW89_MKK][13] = 50, -+ [1][1][2][1][RTW89_IC][13] = 40, -+ [1][1][2][1][RTW89_KCC][13] = 58, -+ [1][1][2][1][RTW89_ACMA][13] = 40, -+ [1][1][2][1][RTW89_CHILE][13] = 36, -+ [1][1][2][1][RTW89_UKRAINE][13] = 28, -+ [1][1][2][1][RTW89_MEXICO][13] = 62, -+ [1][1][2][1][RTW89_CN][13] = 38, -+ [1][1][2][1][RTW89_QATAR][13] = 40, -+ [1][1][2][1][RTW89_UK][13] = 40, -+ [1][1][2][1][RTW89_FCC][16] = 56, -+ [1][1][2][1][RTW89_ETSI][16] = 40, -+ [1][1][2][1][RTW89_MKK][16] = 70, -+ [1][1][2][1][RTW89_IC][16] = 56, -+ [1][1][2][1][RTW89_KCC][16] = 58, -+ [1][1][2][1][RTW89_ACMA][16] = 40, -+ [1][1][2][1][RTW89_CHILE][16] = 36, -+ [1][1][2][1][RTW89_UKRAINE][16] = 28, -+ [1][1][2][1][RTW89_MEXICO][16] = 56, -+ [1][1][2][1][RTW89_CN][16] = 127, -+ [1][1][2][1][RTW89_QATAR][16] = 40, -+ [1][1][2][1][RTW89_UK][16] = 40, -+ [1][1][2][1][RTW89_FCC][20] = 68, -+ [1][1][2][1][RTW89_ETSI][20] = 40, -+ [1][1][2][1][RTW89_MKK][20] = 70, -+ [1][1][2][1][RTW89_IC][20] = 68, -+ [1][1][2][1][RTW89_KCC][20] = 58, -+ [1][1][2][1][RTW89_ACMA][20] = 40, -+ [1][1][2][1][RTW89_CHILE][20] = 36, -+ [1][1][2][1][RTW89_UKRAINE][20] = 28, -+ [1][1][2][1][RTW89_MEXICO][20] = 68, -+ [1][1][2][1][RTW89_CN][20] = 127, -+ [1][1][2][1][RTW89_QATAR][20] = 40, -+ [1][1][2][1][RTW89_UK][20] = 40, -+ [1][1][2][1][RTW89_FCC][24] = 68, -+ [1][1][2][1][RTW89_ETSI][24] = 40, -+ [1][1][2][1][RTW89_MKK][24] = 70, -+ [1][1][2][1][RTW89_IC][24] = 127, -+ [1][1][2][1][RTW89_KCC][24] = 58, -+ [1][1][2][1][RTW89_ACMA][24] = 127, -+ [1][1][2][1][RTW89_CHILE][24] = 36, -+ [1][1][2][1][RTW89_UKRAINE][24] = 28, -+ [1][1][2][1][RTW89_MEXICO][24] = 68, -+ [1][1][2][1][RTW89_CN][24] = 127, -+ [1][1][2][1][RTW89_QATAR][24] = 40, -+ [1][1][2][1][RTW89_UK][24] = 40, -+ [1][1][2][1][RTW89_FCC][28] = 68, -+ [1][1][2][1][RTW89_ETSI][28] = 40, -+ [1][1][2][1][RTW89_MKK][28] = 70, -+ [1][1][2][1][RTW89_IC][28] = 127, -+ [1][1][2][1][RTW89_KCC][28] = 60, -+ [1][1][2][1][RTW89_ACMA][28] = 127, -+ [1][1][2][1][RTW89_CHILE][28] = 36, -+ [1][1][2][1][RTW89_UKRAINE][28] = 28, -+ [1][1][2][1][RTW89_MEXICO][28] = 68, -+ [1][1][2][1][RTW89_CN][28] = 127, -+ [1][1][2][1][RTW89_QATAR][28] = 40, -+ [1][1][2][1][RTW89_UK][28] = 40, -+ [1][1][2][1][RTW89_FCC][32] = 68, -+ [1][1][2][1][RTW89_ETSI][32] = 40, -+ [1][1][2][1][RTW89_MKK][32] = 70, -+ [1][1][2][1][RTW89_IC][32] = 68, -+ [1][1][2][1][RTW89_KCC][32] = 60, -+ [1][1][2][1][RTW89_ACMA][32] = 40, -+ [1][1][2][1][RTW89_CHILE][32] = 36, -+ [1][1][2][1][RTW89_UKRAINE][32] = 28, -+ [1][1][2][1][RTW89_MEXICO][32] = 68, -+ [1][1][2][1][RTW89_CN][32] = 127, -+ [1][1][2][1][RTW89_QATAR][32] = 40, -+ [1][1][2][1][RTW89_UK][32] = 40, -+ [1][1][2][1][RTW89_FCC][36] = 68, -+ [1][1][2][1][RTW89_ETSI][36] = 127, -+ [1][1][2][1][RTW89_MKK][36] = 70, -+ [1][1][2][1][RTW89_IC][36] = 68, -+ [1][1][2][1][RTW89_KCC][36] = 60, -+ [1][1][2][1][RTW89_ACMA][36] = 70, -+ [1][1][2][1][RTW89_CHILE][36] = 36, -+ [1][1][2][1][RTW89_UKRAINE][36] = 127, -+ [1][1][2][1][RTW89_MEXICO][36] = 68, -+ [1][1][2][1][RTW89_CN][36] = 127, -+ [1][1][2][1][RTW89_QATAR][36] = 127, -+ [1][1][2][1][RTW89_UK][36] = 62, -+ [1][1][2][1][RTW89_FCC][39] = 78, -+ [1][1][2][1][RTW89_ETSI][39] = 4, -+ [1][1][2][1][RTW89_MKK][39] = 127, -+ [1][1][2][1][RTW89_IC][39] = 78, -+ [1][1][2][1][RTW89_KCC][39] = 58, -+ [1][1][2][1][RTW89_ACMA][39] = 72, -+ [1][1][2][1][RTW89_CHILE][39] = 36, -+ [1][1][2][1][RTW89_UKRAINE][39] = 4, -+ [1][1][2][1][RTW89_MEXICO][39] = 78, -+ [1][1][2][1][RTW89_CN][39] = 70, -+ [1][1][2][1][RTW89_QATAR][39] = 4, -+ [1][1][2][1][RTW89_UK][39] = 40, -+ [1][1][2][1][RTW89_FCC][43] = 78, -+ [1][1][2][1][RTW89_ETSI][43] = 4, -+ [1][1][2][1][RTW89_MKK][43] = 127, -+ [1][1][2][1][RTW89_IC][43] = 78, -+ [1][1][2][1][RTW89_KCC][43] = 58, -+ [1][1][2][1][RTW89_ACMA][43] = 74, -+ [1][1][2][1][RTW89_CHILE][43] = 36, -+ [1][1][2][1][RTW89_UKRAINE][43] = 4, -+ [1][1][2][1][RTW89_MEXICO][43] = 78, -+ [1][1][2][1][RTW89_CN][43] = 74, -+ [1][1][2][1][RTW89_QATAR][43] = 4, -+ [1][1][2][1][RTW89_UK][43] = 40, -+ [1][1][2][1][RTW89_FCC][47] = 68, -+ [1][1][2][1][RTW89_ETSI][47] = 127, -+ [1][1][2][1][RTW89_MKK][47] = 127, -+ [1][1][2][1][RTW89_IC][47] = 127, -+ [1][1][2][1][RTW89_KCC][47] = 127, -+ [1][1][2][1][RTW89_ACMA][47] = 127, -+ [1][1][2][1][RTW89_CHILE][47] = 127, -+ [1][1][2][1][RTW89_UKRAINE][47] = 127, -+ [1][1][2][1][RTW89_MEXICO][47] = 127, -+ [1][1][2][1][RTW89_CN][47] = 127, -+ [1][1][2][1][RTW89_QATAR][47] = 127, -+ [1][1][2][1][RTW89_UK][47] = 127, -+ [1][1][2][1][RTW89_FCC][51] = 66, -+ [1][1][2][1][RTW89_ETSI][51] = 127, -+ [1][1][2][1][RTW89_MKK][51] = 127, -+ [1][1][2][1][RTW89_IC][51] = 127, -+ [1][1][2][1][RTW89_KCC][51] = 127, -+ [1][1][2][1][RTW89_ACMA][51] = 127, -+ [1][1][2][1][RTW89_CHILE][51] = 127, -+ [1][1][2][1][RTW89_UKRAINE][51] = 127, -+ [1][1][2][1][RTW89_MEXICO][51] = 127, -+ [1][1][2][1][RTW89_CN][51] = 127, -+ [1][1][2][1][RTW89_QATAR][51] = 127, -+ [1][1][2][1][RTW89_UK][51] = 127, -+ [2][0][2][0][RTW89_FCC][3] = 64, -+ [2][0][2][0][RTW89_ETSI][3] = 64, -+ [2][0][2][0][RTW89_MKK][3] = 64, -+ [2][0][2][0][RTW89_IC][3] = 62, -+ [2][0][2][0][RTW89_KCC][3] = 68, -+ [2][0][2][0][RTW89_ACMA][3] = 64, -+ [2][0][2][0][RTW89_CHILE][3] = 42, -+ [2][0][2][0][RTW89_UKRAINE][3] = 52, -+ [2][0][2][0][RTW89_MEXICO][3] = 62, -+ [2][0][2][0][RTW89_CN][3] = 62, -+ [2][0][2][0][RTW89_QATAR][3] = 64, -+ [2][0][2][0][RTW89_UK][3] = 64, -+ [2][0][2][0][RTW89_FCC][11] = 66, -+ [2][0][2][0][RTW89_ETSI][11] = 64, -+ [2][0][2][0][RTW89_MKK][11] = 64, -+ [2][0][2][0][RTW89_IC][11] = 64, -+ [2][0][2][0][RTW89_KCC][11] = 70, -+ [2][0][2][0][RTW89_ACMA][11] = 64, -+ [2][0][2][0][RTW89_CHILE][11] = 66, -+ [2][0][2][0][RTW89_UKRAINE][11] = 52, -+ [2][0][2][0][RTW89_MEXICO][11] = 66, -+ [2][0][2][0][RTW89_CN][11] = 62, -+ [2][0][2][0][RTW89_QATAR][11] = 64, -+ [2][0][2][0][RTW89_UK][11] = 64, -+ [2][0][2][0][RTW89_FCC][18] = 62, -+ [2][0][2][0][RTW89_ETSI][18] = 64, -+ [2][0][2][0][RTW89_MKK][18] = 70, -+ [2][0][2][0][RTW89_IC][18] = 62, -+ [2][0][2][0][RTW89_KCC][18] = 64, -+ [2][0][2][0][RTW89_ACMA][18] = 64, -+ [2][0][2][0][RTW89_CHILE][18] = 64, -+ [2][0][2][0][RTW89_UKRAINE][18] = 52, -+ [2][0][2][0][RTW89_MEXICO][18] = 62, -+ [2][0][2][0][RTW89_CN][18] = 127, -+ [2][0][2][0][RTW89_QATAR][18] = 64, -+ [2][0][2][0][RTW89_UK][18] = 64, -+ [2][0][2][0][RTW89_FCC][26] = 74, -+ [2][0][2][0][RTW89_ETSI][26] = 64, -+ [2][0][2][0][RTW89_MKK][26] = 70, -+ [2][0][2][0][RTW89_IC][26] = 127, -+ [2][0][2][0][RTW89_KCC][26] = 70, -+ [2][0][2][0][RTW89_ACMA][26] = 127, -+ [2][0][2][0][RTW89_CHILE][26] = 64, -+ [2][0][2][0][RTW89_UKRAINE][26] = 52, -+ [2][0][2][0][RTW89_MEXICO][26] = 74, -+ [2][0][2][0][RTW89_CN][26] = 127, -+ [2][0][2][0][RTW89_QATAR][26] = 64, -+ [2][0][2][0][RTW89_UK][26] = 64, -+ [2][0][2][0][RTW89_FCC][34] = 74, -+ [2][0][2][0][RTW89_ETSI][34] = 127, -+ [2][0][2][0][RTW89_MKK][34] = 70, -+ [2][0][2][0][RTW89_IC][34] = 74, -+ [2][0][2][0][RTW89_KCC][34] = 70, -+ [2][0][2][0][RTW89_ACMA][34] = 70, -+ [2][0][2][0][RTW89_CHILE][34] = 64, -+ [2][0][2][0][RTW89_UKRAINE][34] = 127, -+ [2][0][2][0][RTW89_MEXICO][34] = 74, -+ [2][0][2][0][RTW89_CN][34] = 127, -+ [2][0][2][0][RTW89_QATAR][34] = 127, -+ [2][0][2][0][RTW89_UK][34] = 70, -+ [2][0][2][0][RTW89_FCC][41] = 74, -+ [2][0][2][0][RTW89_ETSI][41] = 28, -+ [2][0][2][0][RTW89_MKK][41] = 127, -+ [2][0][2][0][RTW89_IC][41] = 74, -+ [2][0][2][0][RTW89_KCC][41] = 66, -+ [2][0][2][0][RTW89_ACMA][41] = 70, -+ [2][0][2][0][RTW89_CHILE][41] = 64, -+ [2][0][2][0][RTW89_UKRAINE][41] = 28, -+ [2][0][2][0][RTW89_MEXICO][41] = 74, -+ [2][0][2][0][RTW89_CN][41] = 70, -+ [2][0][2][0][RTW89_QATAR][41] = 28, -+ [2][0][2][0][RTW89_UK][41] = 64, -+ [2][0][2][0][RTW89_FCC][49] = 64, -+ [2][0][2][0][RTW89_ETSI][49] = 127, -+ [2][0][2][0][RTW89_MKK][49] = 127, -+ [2][0][2][0][RTW89_IC][49] = 127, -+ [2][0][2][0][RTW89_KCC][49] = 127, -+ [2][0][2][0][RTW89_ACMA][49] = 127, -+ [2][0][2][0][RTW89_CHILE][49] = 127, -+ [2][0][2][0][RTW89_UKRAINE][49] = 127, -+ [2][0][2][0][RTW89_MEXICO][49] = 127, -+ [2][0][2][0][RTW89_CN][49] = 127, -+ [2][0][2][0][RTW89_QATAR][49] = 127, -+ [2][0][2][0][RTW89_UK][49] = 127, -+ [2][1][2][0][RTW89_FCC][3] = 56, -+ [2][1][2][0][RTW89_ETSI][3] = 52, -+ [2][1][2][0][RTW89_MKK][3] = 52, -+ [2][1][2][0][RTW89_IC][3] = 52, -+ [2][1][2][0][RTW89_KCC][3] = 54, -+ [2][1][2][0][RTW89_ACMA][3] = 52, -+ [2][1][2][0][RTW89_CHILE][3] = 28, -+ [2][1][2][0][RTW89_UKRAINE][3] = 40, -+ [2][1][2][0][RTW89_MEXICO][3] = 50, -+ [2][1][2][0][RTW89_CN][3] = 50, -+ [2][1][2][0][RTW89_QATAR][3] = 52, -+ [2][1][2][0][RTW89_UK][3] = 52, -+ [2][1][2][0][RTW89_FCC][11] = 62, -+ [2][1][2][0][RTW89_ETSI][11] = 52, -+ [2][1][2][0][RTW89_MKK][11] = 52, -+ [2][1][2][0][RTW89_IC][11] = 52, -+ [2][1][2][0][RTW89_KCC][11] = 56, -+ [2][1][2][0][RTW89_ACMA][11] = 52, -+ [2][1][2][0][RTW89_CHILE][11] = 52, -+ [2][1][2][0][RTW89_UKRAINE][11] = 40, -+ [2][1][2][0][RTW89_MEXICO][11] = 62, -+ [2][1][2][0][RTW89_CN][11] = 50, -+ [2][1][2][0][RTW89_QATAR][11] = 52, -+ [2][1][2][0][RTW89_UK][11] = 52, -+ [2][1][2][0][RTW89_FCC][18] = 56, -+ [2][1][2][0][RTW89_ETSI][18] = 52, -+ [2][1][2][0][RTW89_MKK][18] = 70, -+ [2][1][2][0][RTW89_IC][18] = 56, -+ [2][1][2][0][RTW89_KCC][18] = 58, -+ [2][1][2][0][RTW89_ACMA][18] = 52, -+ [2][1][2][0][RTW89_CHILE][18] = 48, -+ [2][1][2][0][RTW89_UKRAINE][18] = 40, -+ [2][1][2][0][RTW89_MEXICO][18] = 56, -+ [2][1][2][0][RTW89_CN][18] = 127, -+ [2][1][2][0][RTW89_QATAR][18] = 52, -+ [2][1][2][0][RTW89_UK][18] = 52, -+ [2][1][2][0][RTW89_FCC][26] = 70, -+ [2][1][2][0][RTW89_ETSI][26] = 52, -+ [2][1][2][0][RTW89_MKK][26] = 70, -+ [2][1][2][0][RTW89_IC][26] = 127, -+ [2][1][2][0][RTW89_KCC][26] = 56, -+ [2][1][2][0][RTW89_ACMA][26] = 127, -+ [2][1][2][0][RTW89_CHILE][26] = 50, -+ [2][1][2][0][RTW89_UKRAINE][26] = 40, -+ [2][1][2][0][RTW89_MEXICO][26] = 70, -+ [2][1][2][0][RTW89_CN][26] = 127, -+ [2][1][2][0][RTW89_QATAR][26] = 52, -+ [2][1][2][0][RTW89_UK][26] = 52, -+ [2][1][2][0][RTW89_FCC][34] = 74, -+ [2][1][2][0][RTW89_ETSI][34] = 127, -+ [2][1][2][0][RTW89_MKK][34] = 70, -+ [2][1][2][0][RTW89_IC][34] = 74, -+ [2][1][2][0][RTW89_KCC][34] = 56, -+ [2][1][2][0][RTW89_ACMA][34] = 70, -+ [2][1][2][0][RTW89_CHILE][34] = 50, -+ [2][1][2][0][RTW89_UKRAINE][34] = 127, -+ [2][1][2][0][RTW89_MEXICO][34] = 74, -+ [2][1][2][0][RTW89_CN][34] = 127, -+ [2][1][2][0][RTW89_QATAR][34] = 127, -+ [2][1][2][0][RTW89_UK][34] = 68, -+ [2][1][2][0][RTW89_FCC][41] = 74, -+ [2][1][2][0][RTW89_ETSI][41] = 16, -+ [2][1][2][0][RTW89_MKK][41] = 127, -+ [2][1][2][0][RTW89_IC][41] = 74, -+ [2][1][2][0][RTW89_KCC][41] = 56, -+ [2][1][2][0][RTW89_ACMA][41] = 70, -+ [2][1][2][0][RTW89_CHILE][41] = 50, -+ [2][1][2][0][RTW89_UKRAINE][41] = 16, -+ [2][1][2][0][RTW89_MEXICO][41] = 74, -+ [2][1][2][0][RTW89_CN][41] = 70, -+ [2][1][2][0][RTW89_QATAR][41] = 16, -+ [2][1][2][0][RTW89_UK][41] = 52, -+ [2][1][2][0][RTW89_FCC][49] = 58, -+ [2][1][2][0][RTW89_ETSI][49] = 127, -+ [2][1][2][0][RTW89_MKK][49] = 127, -+ [2][1][2][0][RTW89_IC][49] = 127, -+ [2][1][2][0][RTW89_KCC][49] = 127, -+ [2][1][2][0][RTW89_ACMA][49] = 127, -+ [2][1][2][0][RTW89_CHILE][49] = 127, -+ [2][1][2][0][RTW89_UKRAINE][49] = 127, -+ [2][1][2][0][RTW89_MEXICO][49] = 127, -+ [2][1][2][0][RTW89_CN][49] = 127, -+ [2][1][2][0][RTW89_QATAR][49] = 127, -+ [2][1][2][0][RTW89_UK][49] = 127, -+ [2][1][2][1][RTW89_FCC][3] = 56, -+ [2][1][2][1][RTW89_ETSI][3] = 40, -+ [2][1][2][1][RTW89_MKK][3] = 52, -+ [2][1][2][1][RTW89_IC][3] = 40, -+ [2][1][2][1][RTW89_KCC][3] = 54, -+ [2][1][2][1][RTW89_ACMA][3] = 40, -+ [2][1][2][1][RTW89_CHILE][3] = 16, -+ [2][1][2][1][RTW89_UKRAINE][3] = 28, -+ [2][1][2][1][RTW89_MEXICO][3] = 50, -+ [2][1][2][1][RTW89_CN][3] = 38, -+ [2][1][2][1][RTW89_QATAR][3] = 40, -+ [2][1][2][1][RTW89_UK][3] = 40, -+ [2][1][2][1][RTW89_FCC][11] = 62, -+ [2][1][2][1][RTW89_ETSI][11] = 40, -+ [2][1][2][1][RTW89_MKK][11] = 52, -+ [2][1][2][1][RTW89_IC][11] = 40, -+ [2][1][2][1][RTW89_KCC][11] = 56, -+ [2][1][2][1][RTW89_ACMA][11] = 40, -+ [2][1][2][1][RTW89_CHILE][11] = 34, -+ [2][1][2][1][RTW89_UKRAINE][11] = 28, -+ [2][1][2][1][RTW89_MEXICO][11] = 62, -+ [2][1][2][1][RTW89_CN][11] = 38, -+ [2][1][2][1][RTW89_QATAR][11] = 40, -+ [2][1][2][1][RTW89_UK][11] = 40, -+ [2][1][2][1][RTW89_FCC][18] = 56, -+ [2][1][2][1][RTW89_ETSI][18] = 40, -+ [2][1][2][1][RTW89_MKK][18] = 70, -+ [2][1][2][1][RTW89_IC][18] = 56, -+ [2][1][2][1][RTW89_KCC][18] = 58, -+ [2][1][2][1][RTW89_ACMA][18] = 40, -+ [2][1][2][1][RTW89_CHILE][18] = 34, -+ [2][1][2][1][RTW89_UKRAINE][18] = 28, -+ [2][1][2][1][RTW89_MEXICO][18] = 56, -+ [2][1][2][1][RTW89_CN][18] = 127, -+ [2][1][2][1][RTW89_QATAR][18] = 40, -+ [2][1][2][1][RTW89_UK][18] = 40, -+ [2][1][2][1][RTW89_FCC][26] = 68, -+ [2][1][2][1][RTW89_ETSI][26] = 40, -+ [2][1][2][1][RTW89_MKK][26] = 70, -+ [2][1][2][1][RTW89_IC][26] = 127, -+ [2][1][2][1][RTW89_KCC][26] = 56, -+ [2][1][2][1][RTW89_ACMA][26] = 127, -+ [2][1][2][1][RTW89_CHILE][26] = 34, -+ [2][1][2][1][RTW89_UKRAINE][26] = 28, -+ [2][1][2][1][RTW89_MEXICO][26] = 68, -+ [2][1][2][1][RTW89_CN][26] = 127, -+ [2][1][2][1][RTW89_QATAR][26] = 40, -+ [2][1][2][1][RTW89_UK][26] = 40, -+ [2][1][2][1][RTW89_FCC][34] = 68, -+ [2][1][2][1][RTW89_ETSI][34] = 127, -+ [2][1][2][1][RTW89_MKK][34] = 70, -+ [2][1][2][1][RTW89_IC][34] = 68, -+ [2][1][2][1][RTW89_KCC][34] = 56, -+ [2][1][2][1][RTW89_ACMA][34] = 70, -+ [2][1][2][1][RTW89_CHILE][34] = 34, -+ [2][1][2][1][RTW89_UKRAINE][34] = 127, -+ [2][1][2][1][RTW89_MEXICO][34] = 68, -+ [2][1][2][1][RTW89_CN][34] = 127, -+ [2][1][2][1][RTW89_QATAR][34] = 127, -+ [2][1][2][1][RTW89_UK][34] = 56, -+ [2][1][2][1][RTW89_FCC][41] = 74, -+ [2][1][2][1][RTW89_ETSI][41] = 4, -+ [2][1][2][1][RTW89_MKK][41] = 127, -+ [2][1][2][1][RTW89_IC][41] = 74, -+ [2][1][2][1][RTW89_KCC][41] = 56, -+ [2][1][2][1][RTW89_ACMA][41] = 70, -+ [2][1][2][1][RTW89_CHILE][41] = 36, -+ [2][1][2][1][RTW89_UKRAINE][41] = 4, -+ [2][1][2][1][RTW89_MEXICO][41] = 74, -+ [2][1][2][1][RTW89_CN][41] = 70, -+ [2][1][2][1][RTW89_QATAR][41] = 4, -+ [2][1][2][1][RTW89_UK][41] = 38, -+ [2][1][2][1][RTW89_FCC][49] = 58, -+ [2][1][2][1][RTW89_ETSI][49] = 127, -+ [2][1][2][1][RTW89_MKK][49] = 127, -+ [2][1][2][1][RTW89_IC][49] = 127, -+ [2][1][2][1][RTW89_KCC][49] = 127, -+ [2][1][2][1][RTW89_ACMA][49] = 127, -+ [2][1][2][1][RTW89_CHILE][49] = 127, -+ [2][1][2][1][RTW89_UKRAINE][49] = 127, -+ [2][1][2][1][RTW89_MEXICO][49] = 127, -+ [2][1][2][1][RTW89_CN][49] = 127, -+ [2][1][2][1][RTW89_QATAR][49] = 127, -+ [2][1][2][1][RTW89_UK][49] = 127, -+}; -+ -+const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 32, -+ [0][0][RTW89_WW][1] = 32, -+ [0][0][RTW89_WW][2] = 32, -+ [0][0][RTW89_WW][3] = 32, -+ [0][0][RTW89_WW][4] = 32, -+ [0][0][RTW89_WW][5] = 32, -+ [0][0][RTW89_WW][6] = 32, -+ [0][0][RTW89_WW][7] = 32, -+ [0][0][RTW89_WW][8] = 32, -+ [0][0][RTW89_WW][9] = 32, -+ [0][0][RTW89_WW][10] = 32, -+ [0][0][RTW89_WW][11] = 32, -+ [0][0][RTW89_WW][12] = 32, -+ [0][0][RTW89_WW][13] = 0, -+ [0][1][RTW89_WW][0] = 20, -+ [0][1][RTW89_WW][1] = 22, -+ [0][1][RTW89_WW][2] = 22, -+ [0][1][RTW89_WW][3] = 22, -+ [0][1][RTW89_WW][4] = 22, -+ [0][1][RTW89_WW][5] = 22, -+ [0][1][RTW89_WW][6] = 22, -+ [0][1][RTW89_WW][7] = 22, -+ [0][1][RTW89_WW][8] = 22, -+ [0][1][RTW89_WW][9] = 22, -+ [0][1][RTW89_WW][10] = 22, -+ [0][1][RTW89_WW][11] = 22, -+ [0][1][RTW89_WW][12] = 20, -+ [0][1][RTW89_WW][13] = 0, -+ [1][0][RTW89_WW][0] = 42, -+ [1][0][RTW89_WW][1] = 44, -+ [1][0][RTW89_WW][2] = 44, -+ [1][0][RTW89_WW][3] = 44, -+ [1][0][RTW89_WW][4] = 44, -+ [1][0][RTW89_WW][5] = 44, -+ [1][0][RTW89_WW][6] = 44, -+ [1][0][RTW89_WW][7] = 44, -+ [1][0][RTW89_WW][8] = 44, -+ [1][0][RTW89_WW][9] = 44, -+ [1][0][RTW89_WW][10] = 44, -+ [1][0][RTW89_WW][11] = 44, -+ [1][0][RTW89_WW][12] = 38, -+ [1][0][RTW89_WW][13] = 0, -+ [1][1][RTW89_WW][0] = 32, -+ [1][1][RTW89_WW][1] = 32, -+ [1][1][RTW89_WW][2] = 32, -+ [1][1][RTW89_WW][3] = 32, -+ [1][1][RTW89_WW][4] = 32, -+ [1][1][RTW89_WW][5] = 32, -+ [1][1][RTW89_WW][6] = 32, -+ [1][1][RTW89_WW][7] = 32, -+ [1][1][RTW89_WW][8] = 32, -+ [1][1][RTW89_WW][9] = 32, -+ [1][1][RTW89_WW][10] = 32, -+ [1][1][RTW89_WW][11] = 32, -+ [1][1][RTW89_WW][12] = 32, -+ [1][1][RTW89_WW][13] = 0, -+ [2][0][RTW89_WW][0] = 56, -+ [2][0][RTW89_WW][1] = 56, -+ [2][0][RTW89_WW][2] = 56, -+ [2][0][RTW89_WW][3] = 56, -+ [2][0][RTW89_WW][4] = 56, -+ [2][0][RTW89_WW][5] = 56, -+ [2][0][RTW89_WW][6] = 56, -+ [2][0][RTW89_WW][7] = 56, -+ [2][0][RTW89_WW][8] = 56, -+ [2][0][RTW89_WW][9] = 56, -+ [2][0][RTW89_WW][10] = 56, -+ [2][0][RTW89_WW][11] = 50, -+ [2][0][RTW89_WW][12] = 46, -+ [2][0][RTW89_WW][13] = 0, -+ [2][1][RTW89_WW][0] = 44, -+ [2][1][RTW89_WW][1] = 44, -+ [2][1][RTW89_WW][2] = 44, -+ [2][1][RTW89_WW][3] = 44, -+ [2][1][RTW89_WW][4] = 44, -+ [2][1][RTW89_WW][5] = 44, -+ [2][1][RTW89_WW][6] = 44, -+ [2][1][RTW89_WW][7] = 44, -+ [2][1][RTW89_WW][8] = 44, -+ [2][1][RTW89_WW][9] = 44, -+ [2][1][RTW89_WW][10] = 44, -+ [2][1][RTW89_WW][11] = 38, -+ [2][1][RTW89_WW][12] = 34, -+ [2][1][RTW89_WW][13] = 0, -+ [0][0][RTW89_FCC][0] = 68, -+ [0][0][RTW89_ETSI][0] = 32, -+ [0][0][RTW89_MKK][0] = 42, -+ [0][0][RTW89_IC][0] = 68, -+ [0][0][RTW89_KCC][0] = 44, -+ [0][0][RTW89_ACMA][0] = 32, -+ [0][0][RTW89_CHILE][0] = 66, -+ [0][0][RTW89_UKRAINE][0] = 32, -+ [0][0][RTW89_MEXICO][0] = 68, -+ [0][0][RTW89_CN][0] = 32, -+ [0][0][RTW89_QATAR][0] = 32, -+ [0][0][RTW89_UK][0] = 32, -+ [0][0][RTW89_FCC][1] = 68, -+ [0][0][RTW89_ETSI][1] = 32, -+ [0][0][RTW89_MKK][1] = 42, -+ [0][0][RTW89_IC][1] = 68, -+ [0][0][RTW89_KCC][1] = 44, -+ [0][0][RTW89_ACMA][1] = 32, -+ [0][0][RTW89_CHILE][1] = 64, -+ [0][0][RTW89_UKRAINE][1] = 32, -+ [0][0][RTW89_MEXICO][1] = 68, -+ [0][0][RTW89_CN][1] = 32, -+ [0][0][RTW89_QATAR][1] = 32, -+ [0][0][RTW89_UK][1] = 32, -+ [0][0][RTW89_FCC][2] = 72, -+ [0][0][RTW89_ETSI][2] = 32, -+ [0][0][RTW89_MKK][2] = 42, -+ [0][0][RTW89_IC][2] = 72, -+ [0][0][RTW89_KCC][2] = 44, -+ [0][0][RTW89_ACMA][2] = 32, -+ [0][0][RTW89_CHILE][2] = 64, -+ [0][0][RTW89_UKRAINE][2] = 32, -+ [0][0][RTW89_MEXICO][2] = 72, -+ [0][0][RTW89_CN][2] = 32, -+ [0][0][RTW89_QATAR][2] = 32, -+ [0][0][RTW89_UK][2] = 32, -+ [0][0][RTW89_FCC][3] = 76, -+ [0][0][RTW89_ETSI][3] = 32, -+ [0][0][RTW89_MKK][3] = 42, -+ [0][0][RTW89_IC][3] = 76, -+ [0][0][RTW89_KCC][3] = 44, -+ [0][0][RTW89_ACMA][3] = 32, -+ [0][0][RTW89_CHILE][3] = 64, -+ [0][0][RTW89_UKRAINE][3] = 32, -+ [0][0][RTW89_MEXICO][3] = 76, -+ [0][0][RTW89_CN][3] = 32, -+ [0][0][RTW89_QATAR][3] = 32, -+ [0][0][RTW89_UK][3] = 32, -+ [0][0][RTW89_FCC][4] = 76, -+ [0][0][RTW89_ETSI][4] = 32, -+ [0][0][RTW89_MKK][4] = 42, -+ [0][0][RTW89_IC][4] = 76, -+ [0][0][RTW89_KCC][4] = 44, -+ [0][0][RTW89_ACMA][4] = 32, -+ [0][0][RTW89_CHILE][4] = 64, -+ [0][0][RTW89_UKRAINE][4] = 32, -+ [0][0][RTW89_MEXICO][4] = 76, -+ [0][0][RTW89_CN][4] = 32, -+ [0][0][RTW89_QATAR][4] = 32, -+ [0][0][RTW89_UK][4] = 32, -+ [0][0][RTW89_FCC][5] = 84, -+ [0][0][RTW89_ETSI][5] = 32, -+ [0][0][RTW89_MKK][5] = 42, -+ [0][0][RTW89_IC][5] = 84, -+ [0][0][RTW89_KCC][5] = 44, -+ [0][0][RTW89_ACMA][5] = 32, -+ [0][0][RTW89_CHILE][5] = 64, -+ [0][0][RTW89_UKRAINE][5] = 32, -+ [0][0][RTW89_MEXICO][5] = 84, -+ [0][0][RTW89_CN][5] = 32, -+ [0][0][RTW89_QATAR][5] = 32, -+ [0][0][RTW89_UK][5] = 32, -+ [0][0][RTW89_FCC][6] = 74, -+ [0][0][RTW89_ETSI][6] = 32, -+ [0][0][RTW89_MKK][6] = 42, -+ [0][0][RTW89_IC][6] = 74, -+ [0][0][RTW89_KCC][6] = 44, -+ [0][0][RTW89_ACMA][6] = 32, -+ [0][0][RTW89_CHILE][6] = 64, -+ [0][0][RTW89_UKRAINE][6] = 32, -+ [0][0][RTW89_MEXICO][6] = 74, -+ [0][0][RTW89_CN][6] = 32, -+ [0][0][RTW89_QATAR][6] = 32, -+ [0][0][RTW89_UK][6] = 32, -+ [0][0][RTW89_FCC][7] = 74, -+ [0][0][RTW89_ETSI][7] = 32, -+ [0][0][RTW89_MKK][7] = 42, -+ [0][0][RTW89_IC][7] = 74, -+ [0][0][RTW89_KCC][7] = 44, -+ [0][0][RTW89_ACMA][7] = 32, -+ [0][0][RTW89_CHILE][7] = 64, -+ [0][0][RTW89_UKRAINE][7] = 32, -+ [0][0][RTW89_MEXICO][7] = 74, -+ [0][0][RTW89_CN][7] = 32, -+ [0][0][RTW89_QATAR][7] = 32, -+ [0][0][RTW89_UK][7] = 32, -+ [0][0][RTW89_FCC][8] = 70, -+ [0][0][RTW89_ETSI][8] = 32, -+ [0][0][RTW89_MKK][8] = 42, -+ [0][0][RTW89_IC][8] = 70, -+ [0][0][RTW89_KCC][8] = 44, -+ [0][0][RTW89_ACMA][8] = 32, -+ [0][0][RTW89_CHILE][8] = 64, -+ [0][0][RTW89_UKRAINE][8] = 32, -+ [0][0][RTW89_MEXICO][8] = 70, -+ [0][0][RTW89_CN][8] = 32, -+ [0][0][RTW89_QATAR][8] = 32, -+ [0][0][RTW89_UK][8] = 32, -+ [0][0][RTW89_FCC][9] = 66, -+ [0][0][RTW89_ETSI][9] = 32, -+ [0][0][RTW89_MKK][9] = 42, -+ [0][0][RTW89_IC][9] = 66, -+ [0][0][RTW89_KCC][9] = 42, -+ [0][0][RTW89_ACMA][9] = 32, -+ [0][0][RTW89_CHILE][9] = 64, -+ [0][0][RTW89_UKRAINE][9] = 32, -+ [0][0][RTW89_MEXICO][9] = 66, -+ [0][0][RTW89_CN][9] = 32, -+ [0][0][RTW89_QATAR][9] = 32, -+ [0][0][RTW89_UK][9] = 32, -+ [0][0][RTW89_FCC][10] = 66, -+ [0][0][RTW89_ETSI][10] = 32, -+ [0][0][RTW89_MKK][10] = 42, -+ [0][0][RTW89_IC][10] = 66, -+ [0][0][RTW89_KCC][10] = 42, -+ [0][0][RTW89_ACMA][10] = 32, -+ [0][0][RTW89_CHILE][10] = 66, -+ [0][0][RTW89_UKRAINE][10] = 32, -+ [0][0][RTW89_MEXICO][10] = 66, -+ [0][0][RTW89_CN][10] = 32, -+ [0][0][RTW89_QATAR][10] = 32, -+ [0][0][RTW89_UK][10] = 32, -+ [0][0][RTW89_FCC][11] = 50, -+ [0][0][RTW89_ETSI][11] = 32, -+ [0][0][RTW89_MKK][11] = 42, -+ [0][0][RTW89_IC][11] = 50, -+ [0][0][RTW89_KCC][11] = 42, -+ [0][0][RTW89_ACMA][11] = 32, -+ [0][0][RTW89_CHILE][11] = 64, -+ [0][0][RTW89_UKRAINE][11] = 32, -+ [0][0][RTW89_MEXICO][11] = 50, -+ [0][0][RTW89_CN][11] = 32, -+ [0][0][RTW89_QATAR][11] = 32, -+ [0][0][RTW89_UK][11] = 32, -+ [0][0][RTW89_FCC][12] = 32, -+ [0][0][RTW89_ETSI][12] = 32, -+ [0][0][RTW89_MKK][12] = 42, -+ [0][0][RTW89_IC][12] = 32, -+ [0][0][RTW89_KCC][12] = 42, -+ [0][0][RTW89_ACMA][12] = 32, -+ [0][0][RTW89_CHILE][12] = 64, -+ [0][0][RTW89_UKRAINE][12] = 32, -+ [0][0][RTW89_MEXICO][12] = 32, -+ [0][0][RTW89_CN][12] = 32, -+ [0][0][RTW89_QATAR][12] = 32, -+ [0][0][RTW89_UK][12] = 32, -+ [0][0][RTW89_FCC][13] = 127, -+ [0][0][RTW89_ETSI][13] = 127, -+ [0][0][RTW89_MKK][13] = 127, -+ [0][0][RTW89_IC][13] = 127, -+ [0][0][RTW89_KCC][13] = 127, -+ [0][0][RTW89_ACMA][13] = 127, -+ [0][0][RTW89_CHILE][13] = 127, -+ [0][0][RTW89_UKRAINE][13] = 127, -+ [0][0][RTW89_MEXICO][13] = 127, -+ [0][0][RTW89_CN][13] = 127, -+ [0][0][RTW89_QATAR][13] = 127, -+ [0][0][RTW89_UK][13] = 127, -+ [0][1][RTW89_FCC][0] = 54, -+ [0][1][RTW89_ETSI][0] = 20, -+ [0][1][RTW89_MKK][0] = 32, -+ [0][1][RTW89_IC][0] = 54, -+ [0][1][RTW89_KCC][0] = 32, -+ [0][1][RTW89_ACMA][0] = 20, -+ [0][1][RTW89_CHILE][0] = 50, -+ [0][1][RTW89_UKRAINE][0] = 20, -+ [0][1][RTW89_MEXICO][0] = 54, -+ [0][1][RTW89_CN][0] = 20, -+ [0][1][RTW89_QATAR][0] = 20, -+ [0][1][RTW89_UK][0] = 20, -+ [0][1][RTW89_FCC][1] = 54, -+ [0][1][RTW89_ETSI][1] = 22, -+ [0][1][RTW89_MKK][1] = 32, -+ [0][1][RTW89_IC][1] = 54, -+ [0][1][RTW89_KCC][1] = 32, -+ [0][1][RTW89_ACMA][1] = 22, -+ [0][1][RTW89_CHILE][1] = 50, -+ [0][1][RTW89_UKRAINE][1] = 22, -+ [0][1][RTW89_MEXICO][1] = 54, -+ [0][1][RTW89_CN][1] = 22, -+ [0][1][RTW89_QATAR][1] = 22, -+ [0][1][RTW89_UK][1] = 22, -+ [0][1][RTW89_FCC][2] = 58, -+ [0][1][RTW89_ETSI][2] = 22, -+ [0][1][RTW89_MKK][2] = 32, -+ [0][1][RTW89_IC][2] = 58, -+ [0][1][RTW89_KCC][2] = 32, -+ [0][1][RTW89_ACMA][2] = 22, -+ [0][1][RTW89_CHILE][2] = 50, -+ [0][1][RTW89_UKRAINE][2] = 22, -+ [0][1][RTW89_MEXICO][2] = 58, -+ [0][1][RTW89_CN][2] = 22, -+ [0][1][RTW89_QATAR][2] = 22, -+ [0][1][RTW89_UK][2] = 22, -+ [0][1][RTW89_FCC][3] = 62, -+ [0][1][RTW89_ETSI][3] = 22, -+ [0][1][RTW89_MKK][3] = 32, -+ [0][1][RTW89_IC][3] = 62, -+ [0][1][RTW89_KCC][3] = 32, -+ [0][1][RTW89_ACMA][3] = 22, -+ [0][1][RTW89_CHILE][3] = 50, -+ [0][1][RTW89_UKRAINE][3] = 22, -+ [0][1][RTW89_MEXICO][3] = 62, -+ [0][1][RTW89_CN][3] = 22, -+ [0][1][RTW89_QATAR][3] = 22, -+ [0][1][RTW89_UK][3] = 22, -+ [0][1][RTW89_FCC][4] = 66, -+ [0][1][RTW89_ETSI][4] = 22, -+ [0][1][RTW89_MKK][4] = 32, -+ [0][1][RTW89_IC][4] = 66, -+ [0][1][RTW89_KCC][4] = 30, -+ [0][1][RTW89_ACMA][4] = 22, -+ [0][1][RTW89_CHILE][4] = 50, -+ [0][1][RTW89_UKRAINE][4] = 22, -+ [0][1][RTW89_MEXICO][4] = 66, -+ [0][1][RTW89_CN][4] = 22, -+ [0][1][RTW89_QATAR][4] = 22, -+ [0][1][RTW89_UK][4] = 22, -+ [0][1][RTW89_FCC][5] = 74, -+ [0][1][RTW89_ETSI][5] = 22, -+ [0][1][RTW89_MKK][5] = 32, -+ [0][1][RTW89_IC][5] = 74, -+ [0][1][RTW89_KCC][5] = 30, -+ [0][1][RTW89_ACMA][5] = 22, -+ [0][1][RTW89_CHILE][5] = 52, -+ [0][1][RTW89_UKRAINE][5] = 22, -+ [0][1][RTW89_MEXICO][5] = 74, -+ [0][1][RTW89_CN][5] = 22, -+ [0][1][RTW89_QATAR][5] = 22, -+ [0][1][RTW89_UK][5] = 22, -+ [0][1][RTW89_FCC][6] = 66, -+ [0][1][RTW89_ETSI][6] = 22, -+ [0][1][RTW89_MKK][6] = 30, -+ [0][1][RTW89_IC][6] = 66, -+ [0][1][RTW89_KCC][6] = 30, -+ [0][1][RTW89_ACMA][6] = 22, -+ [0][1][RTW89_CHILE][6] = 50, -+ [0][1][RTW89_UKRAINE][6] = 22, -+ [0][1][RTW89_MEXICO][6] = 66, -+ [0][1][RTW89_CN][6] = 22, -+ [0][1][RTW89_QATAR][6] = 22, -+ [0][1][RTW89_UK][6] = 22, -+ [0][1][RTW89_FCC][7] = 62, -+ [0][1][RTW89_ETSI][7] = 22, -+ [0][1][RTW89_MKK][7] = 32, -+ [0][1][RTW89_IC][7] = 62, -+ [0][1][RTW89_KCC][7] = 30, -+ [0][1][RTW89_ACMA][7] = 22, -+ [0][1][RTW89_CHILE][7] = 50, -+ [0][1][RTW89_UKRAINE][7] = 22, -+ [0][1][RTW89_MEXICO][7] = 62, -+ [0][1][RTW89_CN][7] = 22, -+ [0][1][RTW89_QATAR][7] = 22, -+ [0][1][RTW89_UK][7] = 22, -+ [0][1][RTW89_FCC][8] = 58, -+ [0][1][RTW89_ETSI][8] = 22, -+ [0][1][RTW89_MKK][8] = 32, -+ [0][1][RTW89_IC][8] = 58, -+ [0][1][RTW89_KCC][8] = 30, -+ [0][1][RTW89_ACMA][8] = 22, -+ [0][1][RTW89_CHILE][8] = 50, -+ [0][1][RTW89_UKRAINE][8] = 22, -+ [0][1][RTW89_MEXICO][8] = 58, -+ [0][1][RTW89_CN][8] = 22, -+ [0][1][RTW89_QATAR][8] = 22, -+ [0][1][RTW89_UK][8] = 22, -+ [0][1][RTW89_FCC][9] = 54, -+ [0][1][RTW89_ETSI][9] = 22, -+ [0][1][RTW89_MKK][9] = 32, -+ [0][1][RTW89_IC][9] = 54, -+ [0][1][RTW89_KCC][9] = 30, -+ [0][1][RTW89_ACMA][9] = 22, -+ [0][1][RTW89_CHILE][9] = 50, -+ [0][1][RTW89_UKRAINE][9] = 22, -+ [0][1][RTW89_MEXICO][9] = 54, -+ [0][1][RTW89_CN][9] = 22, -+ [0][1][RTW89_QATAR][9] = 22, -+ [0][1][RTW89_UK][9] = 22, -+ [0][1][RTW89_FCC][10] = 54, -+ [0][1][RTW89_ETSI][10] = 22, -+ [0][1][RTW89_MKK][10] = 32, -+ [0][1][RTW89_IC][10] = 54, -+ [0][1][RTW89_KCC][10] = 30, -+ [0][1][RTW89_ACMA][10] = 22, -+ [0][1][RTW89_CHILE][10] = 50, -+ [0][1][RTW89_UKRAINE][10] = 22, -+ [0][1][RTW89_MEXICO][10] = 54, -+ [0][1][RTW89_CN][10] = 22, -+ [0][1][RTW89_QATAR][10] = 22, -+ [0][1][RTW89_UK][10] = 22, -+ [0][1][RTW89_FCC][11] = 38, -+ [0][1][RTW89_ETSI][11] = 22, -+ [0][1][RTW89_MKK][11] = 32, -+ [0][1][RTW89_IC][11] = 38, -+ [0][1][RTW89_KCC][11] = 30, -+ [0][1][RTW89_ACMA][11] = 22, -+ [0][1][RTW89_CHILE][11] = 50, -+ [0][1][RTW89_UKRAINE][11] = 22, -+ [0][1][RTW89_MEXICO][11] = 38, -+ [0][1][RTW89_CN][11] = 22, -+ [0][1][RTW89_QATAR][11] = 22, -+ [0][1][RTW89_UK][11] = 22, -+ [0][1][RTW89_FCC][12] = 30, -+ [0][1][RTW89_ETSI][12] = 20, -+ [0][1][RTW89_MKK][12] = 30, -+ [0][1][RTW89_IC][12] = 30, -+ [0][1][RTW89_KCC][12] = 30, -+ [0][1][RTW89_ACMA][12] = 20, -+ [0][1][RTW89_CHILE][12] = 50, -+ [0][1][RTW89_UKRAINE][12] = 20, -+ [0][1][RTW89_MEXICO][12] = 30, -+ [0][1][RTW89_CN][12] = 20, -+ [0][1][RTW89_QATAR][12] = 20, -+ [0][1][RTW89_UK][12] = 20, -+ [0][1][RTW89_FCC][13] = 127, -+ [0][1][RTW89_ETSI][13] = 127, -+ [0][1][RTW89_MKK][13] = 127, -+ [0][1][RTW89_IC][13] = 127, -+ [0][1][RTW89_KCC][13] = 127, -+ [0][1][RTW89_ACMA][13] = 127, -+ [0][1][RTW89_CHILE][13] = 127, -+ [0][1][RTW89_UKRAINE][13] = 127, -+ [0][1][RTW89_MEXICO][13] = 127, -+ [0][1][RTW89_CN][13] = 127, -+ [0][1][RTW89_QATAR][13] = 127, -+ [0][1][RTW89_UK][13] = 127, -+ [1][0][RTW89_FCC][0] = 72, -+ [1][0][RTW89_ETSI][0] = 42, -+ [1][0][RTW89_MKK][0] = 52, -+ [1][0][RTW89_IC][0] = 72, -+ [1][0][RTW89_KCC][0] = 52, -+ [1][0][RTW89_ACMA][0] = 42, -+ [1][0][RTW89_CHILE][0] = 68, -+ [1][0][RTW89_UKRAINE][0] = 42, -+ [1][0][RTW89_MEXICO][0] = 72, -+ [1][0][RTW89_CN][0] = 42, -+ [1][0][RTW89_QATAR][0] = 42, -+ [1][0][RTW89_UK][0] = 42, -+ [1][0][RTW89_FCC][1] = 72, -+ [1][0][RTW89_ETSI][1] = 44, -+ [1][0][RTW89_MKK][1] = 52, -+ [1][0][RTW89_IC][1] = 72, -+ [1][0][RTW89_KCC][1] = 52, -+ [1][0][RTW89_ACMA][1] = 44, -+ [1][0][RTW89_CHILE][1] = 68, -+ [1][0][RTW89_UKRAINE][1] = 44, -+ [1][0][RTW89_MEXICO][1] = 72, -+ [1][0][RTW89_CN][1] = 44, -+ [1][0][RTW89_QATAR][1] = 44, -+ [1][0][RTW89_UK][1] = 44, -+ [1][0][RTW89_FCC][2] = 76, -+ [1][0][RTW89_ETSI][2] = 44, -+ [1][0][RTW89_MKK][2] = 52, -+ [1][0][RTW89_IC][2] = 76, -+ [1][0][RTW89_KCC][2] = 52, -+ [1][0][RTW89_ACMA][2] = 44, -+ [1][0][RTW89_CHILE][2] = 68, -+ [1][0][RTW89_UKRAINE][2] = 44, -+ [1][0][RTW89_MEXICO][2] = 76, -+ [1][0][RTW89_CN][2] = 44, -+ [1][0][RTW89_QATAR][2] = 44, -+ [1][0][RTW89_UK][2] = 44, -+ [1][0][RTW89_FCC][3] = 78, -+ [1][0][RTW89_ETSI][3] = 44, -+ [1][0][RTW89_MKK][3] = 52, -+ [1][0][RTW89_IC][3] = 78, -+ [1][0][RTW89_KCC][3] = 52, -+ [1][0][RTW89_ACMA][3] = 44, -+ [1][0][RTW89_CHILE][3] = 68, -+ [1][0][RTW89_UKRAINE][3] = 44, -+ [1][0][RTW89_MEXICO][3] = 78, -+ [1][0][RTW89_CN][3] = 44, -+ [1][0][RTW89_QATAR][3] = 44, -+ [1][0][RTW89_UK][3] = 44, -+ [1][0][RTW89_FCC][4] = 78, -+ [1][0][RTW89_ETSI][4] = 44, -+ [1][0][RTW89_MKK][4] = 52, -+ [1][0][RTW89_IC][4] = 78, -+ [1][0][RTW89_KCC][4] = 52, -+ [1][0][RTW89_ACMA][4] = 44, -+ [1][0][RTW89_CHILE][4] = 68, -+ [1][0][RTW89_UKRAINE][4] = 44, -+ [1][0][RTW89_MEXICO][4] = 78, -+ [1][0][RTW89_CN][4] = 44, -+ [1][0][RTW89_QATAR][4] = 44, -+ [1][0][RTW89_UK][4] = 44, -+ [1][0][RTW89_FCC][5] = 84, -+ [1][0][RTW89_ETSI][5] = 44, -+ [1][0][RTW89_MKK][5] = 52, -+ [1][0][RTW89_IC][5] = 84, -+ [1][0][RTW89_KCC][5] = 52, -+ [1][0][RTW89_ACMA][5] = 44, -+ [1][0][RTW89_CHILE][5] = 68, -+ [1][0][RTW89_UKRAINE][5] = 44, -+ [1][0][RTW89_MEXICO][5] = 84, -+ [1][0][RTW89_CN][5] = 44, -+ [1][0][RTW89_QATAR][5] = 44, -+ [1][0][RTW89_UK][5] = 44, -+ [1][0][RTW89_FCC][6] = 72, -+ [1][0][RTW89_ETSI][6] = 44, -+ [1][0][RTW89_MKK][6] = 52, -+ [1][0][RTW89_IC][6] = 72, -+ [1][0][RTW89_KCC][6] = 52, -+ [1][0][RTW89_ACMA][6] = 44, -+ [1][0][RTW89_CHILE][6] = 68, -+ [1][0][RTW89_UKRAINE][6] = 44, -+ [1][0][RTW89_MEXICO][6] = 72, -+ [1][0][RTW89_CN][6] = 44, -+ [1][0][RTW89_QATAR][6] = 44, -+ [1][0][RTW89_UK][6] = 44, -+ [1][0][RTW89_FCC][7] = 72, -+ [1][0][RTW89_ETSI][7] = 44, -+ [1][0][RTW89_MKK][7] = 52, -+ [1][0][RTW89_IC][7] = 72, -+ [1][0][RTW89_KCC][7] = 52, -+ [1][0][RTW89_ACMA][7] = 44, -+ [1][0][RTW89_CHILE][7] = 68, -+ [1][0][RTW89_UKRAINE][7] = 44, -+ [1][0][RTW89_MEXICO][7] = 72, -+ [1][0][RTW89_CN][7] = 44, -+ [1][0][RTW89_QATAR][7] = 44, -+ [1][0][RTW89_UK][7] = 44, -+ [1][0][RTW89_FCC][8] = 72, -+ [1][0][RTW89_ETSI][8] = 44, -+ [1][0][RTW89_MKK][8] = 52, -+ [1][0][RTW89_IC][8] = 72, -+ [1][0][RTW89_KCC][8] = 52, -+ [1][0][RTW89_ACMA][8] = 44, -+ [1][0][RTW89_CHILE][8] = 68, -+ [1][0][RTW89_UKRAINE][8] = 44, -+ [1][0][RTW89_MEXICO][8] = 72, -+ [1][0][RTW89_CN][8] = 44, -+ [1][0][RTW89_QATAR][8] = 44, -+ [1][0][RTW89_UK][8] = 44, -+ [1][0][RTW89_FCC][9] = 68, -+ [1][0][RTW89_ETSI][9] = 44, -+ [1][0][RTW89_MKK][9] = 52, -+ [1][0][RTW89_IC][9] = 68, -+ [1][0][RTW89_KCC][9] = 52, -+ [1][0][RTW89_ACMA][9] = 44, -+ [1][0][RTW89_CHILE][9] = 68, -+ [1][0][RTW89_UKRAINE][9] = 44, -+ [1][0][RTW89_MEXICO][9] = 68, -+ [1][0][RTW89_CN][9] = 44, -+ [1][0][RTW89_QATAR][9] = 44, -+ [1][0][RTW89_UK][9] = 44, -+ [1][0][RTW89_FCC][10] = 68, -+ [1][0][RTW89_ETSI][10] = 44, -+ [1][0][RTW89_MKK][10] = 52, -+ [1][0][RTW89_IC][10] = 68, -+ [1][0][RTW89_KCC][10] = 52, -+ [1][0][RTW89_ACMA][10] = 44, -+ [1][0][RTW89_CHILE][10] = 70, -+ [1][0][RTW89_UKRAINE][10] = 44, -+ [1][0][RTW89_MEXICO][10] = 68, -+ [1][0][RTW89_CN][10] = 44, -+ [1][0][RTW89_QATAR][10] = 44, -+ [1][0][RTW89_UK][10] = 44, -+ [1][0][RTW89_FCC][11] = 50, -+ [1][0][RTW89_ETSI][11] = 44, -+ [1][0][RTW89_MKK][11] = 52, -+ [1][0][RTW89_IC][11] = 50, -+ [1][0][RTW89_KCC][11] = 52, -+ [1][0][RTW89_ACMA][11] = 44, -+ [1][0][RTW89_CHILE][11] = 68, -+ [1][0][RTW89_UKRAINE][11] = 44, -+ [1][0][RTW89_MEXICO][11] = 50, -+ [1][0][RTW89_CN][11] = 44, -+ [1][0][RTW89_QATAR][11] = 44, -+ [1][0][RTW89_UK][11] = 44, -+ [1][0][RTW89_FCC][12] = 38, -+ [1][0][RTW89_ETSI][12] = 42, -+ [1][0][RTW89_MKK][12] = 52, -+ [1][0][RTW89_IC][12] = 38, -+ [1][0][RTW89_KCC][12] = 52, -+ [1][0][RTW89_ACMA][12] = 42, -+ [1][0][RTW89_CHILE][12] = 68, -+ [1][0][RTW89_UKRAINE][12] = 42, -+ [1][0][RTW89_MEXICO][12] = 38, -+ [1][0][RTW89_CN][12] = 42, -+ [1][0][RTW89_QATAR][12] = 42, -+ [1][0][RTW89_UK][12] = 42, -+ [1][0][RTW89_FCC][13] = 127, -+ [1][0][RTW89_ETSI][13] = 127, -+ [1][0][RTW89_MKK][13] = 127, -+ [1][0][RTW89_IC][13] = 127, -+ [1][0][RTW89_KCC][13] = 127, -+ [1][0][RTW89_ACMA][13] = 127, -+ [1][0][RTW89_CHILE][13] = 127, -+ [1][0][RTW89_UKRAINE][13] = 127, -+ [1][0][RTW89_MEXICO][13] = 127, -+ [1][0][RTW89_CN][13] = 127, -+ [1][0][RTW89_QATAR][13] = 127, -+ [1][0][RTW89_UK][13] = 127, -+ [1][1][RTW89_FCC][0] = 54, -+ [1][1][RTW89_ETSI][0] = 32, -+ [1][1][RTW89_MKK][0] = 40, -+ [1][1][RTW89_IC][0] = 54, -+ [1][1][RTW89_KCC][0] = 40, -+ [1][1][RTW89_ACMA][0] = 32, -+ [1][1][RTW89_CHILE][0] = 54, -+ [1][1][RTW89_UKRAINE][0] = 32, -+ [1][1][RTW89_MEXICO][0] = 54, -+ [1][1][RTW89_CN][0] = 32, -+ [1][1][RTW89_QATAR][0] = 32, -+ [1][1][RTW89_UK][0] = 32, -+ [1][1][RTW89_FCC][1] = 54, -+ [1][1][RTW89_ETSI][1] = 32, -+ [1][1][RTW89_MKK][1] = 40, -+ [1][1][RTW89_IC][1] = 54, -+ [1][1][RTW89_KCC][1] = 40, -+ [1][1][RTW89_ACMA][1] = 32, -+ [1][1][RTW89_CHILE][1] = 54, -+ [1][1][RTW89_UKRAINE][1] = 32, -+ [1][1][RTW89_MEXICO][1] = 54, -+ [1][1][RTW89_CN][1] = 32, -+ [1][1][RTW89_QATAR][1] = 32, -+ [1][1][RTW89_UK][1] = 32, -+ [1][1][RTW89_FCC][2] = 58, -+ [1][1][RTW89_ETSI][2] = 32, -+ [1][1][RTW89_MKK][2] = 40, -+ [1][1][RTW89_IC][2] = 58, -+ [1][1][RTW89_KCC][2] = 40, -+ [1][1][RTW89_ACMA][2] = 32, -+ [1][1][RTW89_CHILE][2] = 54, -+ [1][1][RTW89_UKRAINE][2] = 32, -+ [1][1][RTW89_MEXICO][2] = 58, -+ [1][1][RTW89_CN][2] = 32, -+ [1][1][RTW89_QATAR][2] = 32, -+ [1][1][RTW89_UK][2] = 32, -+ [1][1][RTW89_FCC][3] = 62, -+ [1][1][RTW89_ETSI][3] = 32, -+ [1][1][RTW89_MKK][3] = 40, -+ [1][1][RTW89_IC][3] = 62, -+ [1][1][RTW89_KCC][3] = 40, -+ [1][1][RTW89_ACMA][3] = 32, -+ [1][1][RTW89_CHILE][3] = 54, -+ [1][1][RTW89_UKRAINE][3] = 32, -+ [1][1][RTW89_MEXICO][3] = 62, -+ [1][1][RTW89_CN][3] = 32, -+ [1][1][RTW89_QATAR][3] = 32, -+ [1][1][RTW89_UK][3] = 32, -+ [1][1][RTW89_FCC][4] = 66, -+ [1][1][RTW89_ETSI][4] = 32, -+ [1][1][RTW89_MKK][4] = 40, -+ [1][1][RTW89_IC][4] = 66, -+ [1][1][RTW89_KCC][4] = 40, -+ [1][1][RTW89_ACMA][4] = 32, -+ [1][1][RTW89_CHILE][4] = 54, -+ [1][1][RTW89_UKRAINE][4] = 32, -+ [1][1][RTW89_MEXICO][4] = 66, -+ [1][1][RTW89_CN][4] = 32, -+ [1][1][RTW89_QATAR][4] = 32, -+ [1][1][RTW89_UK][4] = 32, -+ [1][1][RTW89_FCC][5] = 74, -+ [1][1][RTW89_ETSI][5] = 32, -+ [1][1][RTW89_MKK][5] = 40, -+ [1][1][RTW89_IC][5] = 74, -+ [1][1][RTW89_KCC][5] = 40, -+ [1][1][RTW89_ACMA][5] = 32, -+ [1][1][RTW89_CHILE][5] = 54, -+ [1][1][RTW89_UKRAINE][5] = 32, -+ [1][1][RTW89_MEXICO][5] = 74, -+ [1][1][RTW89_CN][5] = 32, -+ [1][1][RTW89_QATAR][5] = 32, -+ [1][1][RTW89_UK][5] = 32, -+ [1][1][RTW89_FCC][6] = 66, -+ [1][1][RTW89_ETSI][6] = 32, -+ [1][1][RTW89_MKK][6] = 40, -+ [1][1][RTW89_IC][6] = 66, -+ [1][1][RTW89_KCC][6] = 40, -+ [1][1][RTW89_ACMA][6] = 32, -+ [1][1][RTW89_CHILE][6] = 54, -+ [1][1][RTW89_UKRAINE][6] = 32, -+ [1][1][RTW89_MEXICO][6] = 66, -+ [1][1][RTW89_CN][6] = 32, -+ [1][1][RTW89_QATAR][6] = 32, -+ [1][1][RTW89_UK][6] = 32, -+ [1][1][RTW89_FCC][7] = 62, -+ [1][1][RTW89_ETSI][7] = 32, -+ [1][1][RTW89_MKK][7] = 40, -+ [1][1][RTW89_IC][7] = 62, -+ [1][1][RTW89_KCC][7] = 40, -+ [1][1][RTW89_ACMA][7] = 32, -+ [1][1][RTW89_CHILE][7] = 54, -+ [1][1][RTW89_UKRAINE][7] = 32, -+ [1][1][RTW89_MEXICO][7] = 62, -+ [1][1][RTW89_CN][7] = 32, -+ [1][1][RTW89_QATAR][7] = 32, -+ [1][1][RTW89_UK][7] = 32, -+ [1][1][RTW89_FCC][8] = 58, -+ [1][1][RTW89_ETSI][8] = 32, -+ [1][1][RTW89_MKK][8] = 40, -+ [1][1][RTW89_IC][8] = 58, -+ [1][1][RTW89_KCC][8] = 40, -+ [1][1][RTW89_ACMA][8] = 32, -+ [1][1][RTW89_CHILE][8] = 54, -+ [1][1][RTW89_UKRAINE][8] = 32, -+ [1][1][RTW89_MEXICO][8] = 58, -+ [1][1][RTW89_CN][8] = 32, -+ [1][1][RTW89_QATAR][8] = 32, -+ [1][1][RTW89_UK][8] = 32, -+ [1][1][RTW89_FCC][9] = 54, -+ [1][1][RTW89_ETSI][9] = 32, -+ [1][1][RTW89_MKK][9] = 40, -+ [1][1][RTW89_IC][9] = 54, -+ [1][1][RTW89_KCC][9] = 40, -+ [1][1][RTW89_ACMA][9] = 32, -+ [1][1][RTW89_CHILE][9] = 54, -+ [1][1][RTW89_UKRAINE][9] = 32, -+ [1][1][RTW89_MEXICO][9] = 54, -+ [1][1][RTW89_CN][9] = 32, -+ [1][1][RTW89_QATAR][9] = 32, -+ [1][1][RTW89_UK][9] = 32, -+ [1][1][RTW89_FCC][10] = 54, -+ [1][1][RTW89_ETSI][10] = 32, -+ [1][1][RTW89_MKK][10] = 40, -+ [1][1][RTW89_IC][10] = 54, -+ [1][1][RTW89_KCC][10] = 40, -+ [1][1][RTW89_ACMA][10] = 32, -+ [1][1][RTW89_CHILE][10] = 54, -+ [1][1][RTW89_UKRAINE][10] = 32, -+ [1][1][RTW89_MEXICO][10] = 54, -+ [1][1][RTW89_CN][10] = 32, -+ [1][1][RTW89_QATAR][10] = 32, -+ [1][1][RTW89_UK][10] = 32, -+ [1][1][RTW89_FCC][11] = 38, -+ [1][1][RTW89_ETSI][11] = 32, -+ [1][1][RTW89_MKK][11] = 40, -+ [1][1][RTW89_IC][11] = 38, -+ [1][1][RTW89_KCC][11] = 40, -+ [1][1][RTW89_ACMA][11] = 32, -+ [1][1][RTW89_CHILE][11] = 54, -+ [1][1][RTW89_UKRAINE][11] = 32, -+ [1][1][RTW89_MEXICO][11] = 38, -+ [1][1][RTW89_CN][11] = 32, -+ [1][1][RTW89_QATAR][11] = 32, -+ [1][1][RTW89_UK][11] = 32, -+ [1][1][RTW89_FCC][12] = 32, -+ [1][1][RTW89_ETSI][12] = 32, -+ [1][1][RTW89_MKK][12] = 40, -+ [1][1][RTW89_IC][12] = 32, -+ [1][1][RTW89_KCC][12] = 40, -+ [1][1][RTW89_ACMA][12] = 32, -+ [1][1][RTW89_CHILE][12] = 54, -+ [1][1][RTW89_UKRAINE][12] = 32, -+ [1][1][RTW89_MEXICO][12] = 32, -+ [1][1][RTW89_CN][12] = 32, -+ [1][1][RTW89_QATAR][12] = 32, -+ [1][1][RTW89_UK][12] = 32, -+ [1][1][RTW89_FCC][13] = 127, -+ [1][1][RTW89_ETSI][13] = 127, -+ [1][1][RTW89_MKK][13] = 127, -+ [1][1][RTW89_IC][13] = 127, -+ [1][1][RTW89_KCC][13] = 127, -+ [1][1][RTW89_ACMA][13] = 127, -+ [1][1][RTW89_CHILE][13] = 127, -+ [1][1][RTW89_UKRAINE][13] = 127, -+ [1][1][RTW89_MEXICO][13] = 127, -+ [1][1][RTW89_CN][13] = 127, -+ [1][1][RTW89_QATAR][13] = 127, -+ [1][1][RTW89_UK][13] = 127, -+ [2][0][RTW89_FCC][0] = 72, -+ [2][0][RTW89_ETSI][0] = 56, -+ [2][0][RTW89_MKK][0] = 64, -+ [2][0][RTW89_IC][0] = 72, -+ [2][0][RTW89_KCC][0] = 66, -+ [2][0][RTW89_ACMA][0] = 56, -+ [2][0][RTW89_CHILE][0] = 68, -+ [2][0][RTW89_UKRAINE][0] = 56, -+ [2][0][RTW89_MEXICO][0] = 72, -+ [2][0][RTW89_CN][0] = 56, -+ [2][0][RTW89_QATAR][0] = 56, -+ [2][0][RTW89_UK][0] = 56, -+ [2][0][RTW89_FCC][1] = 72, -+ [2][0][RTW89_ETSI][1] = 56, -+ [2][0][RTW89_MKK][1] = 64, -+ [2][0][RTW89_IC][1] = 72, -+ [2][0][RTW89_KCC][1] = 66, -+ [2][0][RTW89_ACMA][1] = 56, -+ [2][0][RTW89_CHILE][1] = 68, -+ [2][0][RTW89_UKRAINE][1] = 56, -+ [2][0][RTW89_MEXICO][1] = 72, -+ [2][0][RTW89_CN][1] = 56, -+ [2][0][RTW89_QATAR][1] = 56, -+ [2][0][RTW89_UK][1] = 56, -+ [2][0][RTW89_FCC][2] = 74, -+ [2][0][RTW89_ETSI][2] = 56, -+ [2][0][RTW89_MKK][2] = 64, -+ [2][0][RTW89_IC][2] = 74, -+ [2][0][RTW89_KCC][2] = 66, -+ [2][0][RTW89_ACMA][2] = 56, -+ [2][0][RTW89_CHILE][2] = 68, -+ [2][0][RTW89_UKRAINE][2] = 56, -+ [2][0][RTW89_MEXICO][2] = 74, -+ [2][0][RTW89_CN][2] = 56, -+ [2][0][RTW89_QATAR][2] = 56, -+ [2][0][RTW89_UK][2] = 56, -+ [2][0][RTW89_FCC][3] = 74, -+ [2][0][RTW89_ETSI][3] = 56, -+ [2][0][RTW89_MKK][3] = 64, -+ [2][0][RTW89_IC][3] = 74, -+ [2][0][RTW89_KCC][3] = 66, -+ [2][0][RTW89_ACMA][3] = 56, -+ [2][0][RTW89_CHILE][3] = 68, -+ [2][0][RTW89_UKRAINE][3] = 56, -+ [2][0][RTW89_MEXICO][3] = 74, -+ [2][0][RTW89_CN][3] = 56, -+ [2][0][RTW89_QATAR][3] = 56, -+ [2][0][RTW89_UK][3] = 56, -+ [2][0][RTW89_FCC][4] = 74, -+ [2][0][RTW89_ETSI][4] = 56, -+ [2][0][RTW89_MKK][4] = 64, -+ [2][0][RTW89_IC][4] = 74, -+ [2][0][RTW89_KCC][4] = 66, -+ [2][0][RTW89_ACMA][4] = 56, -+ [2][0][RTW89_CHILE][4] = 68, -+ [2][0][RTW89_UKRAINE][4] = 56, -+ [2][0][RTW89_MEXICO][4] = 74, -+ [2][0][RTW89_CN][4] = 56, -+ [2][0][RTW89_QATAR][4] = 56, -+ [2][0][RTW89_UK][4] = 56, -+ [2][0][RTW89_FCC][5] = 84, -+ [2][0][RTW89_ETSI][5] = 56, -+ [2][0][RTW89_MKK][5] = 64, -+ [2][0][RTW89_IC][5] = 84, -+ [2][0][RTW89_KCC][5] = 66, -+ [2][0][RTW89_ACMA][5] = 56, -+ [2][0][RTW89_CHILE][5] = 70, -+ [2][0][RTW89_UKRAINE][5] = 56, -+ [2][0][RTW89_MEXICO][5] = 84, -+ [2][0][RTW89_CN][5] = 56, -+ [2][0][RTW89_QATAR][5] = 56, -+ [2][0][RTW89_UK][5] = 56, -+ [2][0][RTW89_FCC][6] = 70, -+ [2][0][RTW89_ETSI][6] = 56, -+ [2][0][RTW89_MKK][6] = 64, -+ [2][0][RTW89_IC][6] = 70, -+ [2][0][RTW89_KCC][6] = 66, -+ [2][0][RTW89_ACMA][6] = 56, -+ [2][0][RTW89_CHILE][6] = 68, -+ [2][0][RTW89_UKRAINE][6] = 56, -+ [2][0][RTW89_MEXICO][6] = 70, -+ [2][0][RTW89_CN][6] = 56, -+ [2][0][RTW89_QATAR][6] = 56, -+ [2][0][RTW89_UK][6] = 56, -+ [2][0][RTW89_FCC][7] = 70, -+ [2][0][RTW89_ETSI][7] = 56, -+ [2][0][RTW89_MKK][7] = 64, -+ [2][0][RTW89_IC][7] = 70, -+ [2][0][RTW89_KCC][7] = 66, -+ [2][0][RTW89_ACMA][7] = 56, -+ [2][0][RTW89_CHILE][7] = 68, -+ [2][0][RTW89_UKRAINE][7] = 56, -+ [2][0][RTW89_MEXICO][7] = 70, -+ [2][0][RTW89_CN][7] = 56, -+ [2][0][RTW89_QATAR][7] = 56, -+ [2][0][RTW89_UK][7] = 56, -+ [2][0][RTW89_FCC][8] = 70, -+ [2][0][RTW89_ETSI][8] = 56, -+ [2][0][RTW89_MKK][8] = 64, -+ [2][0][RTW89_IC][8] = 70, -+ [2][0][RTW89_KCC][8] = 66, -+ [2][0][RTW89_ACMA][8] = 56, -+ [2][0][RTW89_CHILE][8] = 68, -+ [2][0][RTW89_UKRAINE][8] = 56, -+ [2][0][RTW89_MEXICO][8] = 70, -+ [2][0][RTW89_CN][8] = 56, -+ [2][0][RTW89_QATAR][8] = 56, -+ [2][0][RTW89_UK][8] = 56, -+ [2][0][RTW89_FCC][9] = 68, -+ [2][0][RTW89_ETSI][9] = 56, -+ [2][0][RTW89_MKK][9] = 64, -+ [2][0][RTW89_IC][9] = 68, -+ [2][0][RTW89_KCC][9] = 66, -+ [2][0][RTW89_ACMA][9] = 56, -+ [2][0][RTW89_CHILE][9] = 68, -+ [2][0][RTW89_UKRAINE][9] = 56, -+ [2][0][RTW89_MEXICO][9] = 68, -+ [2][0][RTW89_CN][9] = 56, -+ [2][0][RTW89_QATAR][9] = 56, -+ [2][0][RTW89_UK][9] = 56, -+ [2][0][RTW89_FCC][10] = 68, -+ [2][0][RTW89_ETSI][10] = 56, -+ [2][0][RTW89_MKK][10] = 64, -+ [2][0][RTW89_IC][10] = 68, -+ [2][0][RTW89_KCC][10] = 66, -+ [2][0][RTW89_ACMA][10] = 56, -+ [2][0][RTW89_CHILE][10] = 68, -+ [2][0][RTW89_UKRAINE][10] = 56, -+ [2][0][RTW89_MEXICO][10] = 68, -+ [2][0][RTW89_CN][10] = 56, -+ [2][0][RTW89_QATAR][10] = 56, -+ [2][0][RTW89_UK][10] = 56, -+ [2][0][RTW89_FCC][11] = 50, -+ [2][0][RTW89_ETSI][11] = 56, -+ [2][0][RTW89_MKK][11] = 64, -+ [2][0][RTW89_IC][11] = 50, -+ [2][0][RTW89_KCC][11] = 66, -+ [2][0][RTW89_ACMA][11] = 56, -+ [2][0][RTW89_CHILE][11] = 68, -+ [2][0][RTW89_UKRAINE][11] = 56, -+ [2][0][RTW89_MEXICO][11] = 50, -+ [2][0][RTW89_CN][11] = 56, -+ [2][0][RTW89_QATAR][11] = 56, -+ [2][0][RTW89_UK][11] = 56, -+ [2][0][RTW89_FCC][12] = 46, -+ [2][0][RTW89_ETSI][12] = 56, -+ [2][0][RTW89_MKK][12] = 64, -+ [2][0][RTW89_IC][12] = 46, -+ [2][0][RTW89_KCC][12] = 66, -+ [2][0][RTW89_ACMA][12] = 56, -+ [2][0][RTW89_CHILE][12] = 68, -+ [2][0][RTW89_UKRAINE][12] = 56, -+ [2][0][RTW89_MEXICO][12] = 46, -+ [2][0][RTW89_CN][12] = 56, -+ [2][0][RTW89_QATAR][12] = 56, -+ [2][0][RTW89_UK][12] = 56, -+ [2][0][RTW89_FCC][13] = 127, -+ [2][0][RTW89_ETSI][13] = 127, -+ [2][0][RTW89_MKK][13] = 127, -+ [2][0][RTW89_IC][13] = 127, -+ [2][0][RTW89_KCC][13] = 127, -+ [2][0][RTW89_ACMA][13] = 127, -+ [2][0][RTW89_CHILE][13] = 127, -+ [2][0][RTW89_UKRAINE][13] = 127, -+ [2][0][RTW89_MEXICO][13] = 127, -+ [2][0][RTW89_CN][13] = 127, -+ [2][0][RTW89_QATAR][13] = 127, -+ [2][0][RTW89_UK][13] = 127, -+ [2][1][RTW89_FCC][0] = 54, -+ [2][1][RTW89_ETSI][0] = 44, -+ [2][1][RTW89_MKK][0] = 52, -+ [2][1][RTW89_IC][0] = 54, -+ [2][1][RTW89_KCC][0] = 54, -+ [2][1][RTW89_ACMA][0] = 44, -+ [2][1][RTW89_CHILE][0] = 58, -+ [2][1][RTW89_UKRAINE][0] = 44, -+ [2][1][RTW89_MEXICO][0] = 54, -+ [2][1][RTW89_CN][0] = 44, -+ [2][1][RTW89_QATAR][0] = 44, -+ [2][1][RTW89_UK][0] = 44, -+ [2][1][RTW89_FCC][1] = 54, -+ [2][1][RTW89_ETSI][1] = 44, -+ [2][1][RTW89_MKK][1] = 52, -+ [2][1][RTW89_IC][1] = 54, -+ [2][1][RTW89_KCC][1] = 54, -+ [2][1][RTW89_ACMA][1] = 44, -+ [2][1][RTW89_CHILE][1] = 56, -+ [2][1][RTW89_UKRAINE][1] = 44, -+ [2][1][RTW89_MEXICO][1] = 54, -+ [2][1][RTW89_CN][1] = 44, -+ [2][1][RTW89_QATAR][1] = 44, -+ [2][1][RTW89_UK][1] = 44, -+ [2][1][RTW89_FCC][2] = 58, -+ [2][1][RTW89_ETSI][2] = 44, -+ [2][1][RTW89_MKK][2] = 52, -+ [2][1][RTW89_IC][2] = 58, -+ [2][1][RTW89_KCC][2] = 54, -+ [2][1][RTW89_ACMA][2] = 44, -+ [2][1][RTW89_CHILE][2] = 56, -+ [2][1][RTW89_UKRAINE][2] = 44, -+ [2][1][RTW89_MEXICO][2] = 58, -+ [2][1][RTW89_CN][2] = 44, -+ [2][1][RTW89_QATAR][2] = 44, -+ [2][1][RTW89_UK][2] = 44, -+ [2][1][RTW89_FCC][3] = 62, -+ [2][1][RTW89_ETSI][3] = 44, -+ [2][1][RTW89_MKK][3] = 52, -+ [2][1][RTW89_IC][3] = 62, -+ [2][1][RTW89_KCC][3] = 54, -+ [2][1][RTW89_ACMA][3] = 44, -+ [2][1][RTW89_CHILE][3] = 56, -+ [2][1][RTW89_UKRAINE][3] = 44, -+ [2][1][RTW89_MEXICO][3] = 62, -+ [2][1][RTW89_CN][3] = 44, -+ [2][1][RTW89_QATAR][3] = 44, -+ [2][1][RTW89_UK][3] = 44, -+ [2][1][RTW89_FCC][4] = 64, -+ [2][1][RTW89_ETSI][4] = 44, -+ [2][1][RTW89_MKK][4] = 52, -+ [2][1][RTW89_IC][4] = 64, -+ [2][1][RTW89_KCC][4] = 52, -+ [2][1][RTW89_ACMA][4] = 44, -+ [2][1][RTW89_CHILE][4] = 56, -+ [2][1][RTW89_UKRAINE][4] = 44, -+ [2][1][RTW89_MEXICO][4] = 64, -+ [2][1][RTW89_CN][4] = 44, -+ [2][1][RTW89_QATAR][4] = 44, -+ [2][1][RTW89_UK][4] = 44, -+ [2][1][RTW89_FCC][5] = 80, -+ [2][1][RTW89_ETSI][5] = 44, -+ [2][1][RTW89_MKK][5] = 52, -+ [2][1][RTW89_IC][5] = 80, -+ [2][1][RTW89_KCC][5] = 52, -+ [2][1][RTW89_ACMA][5] = 44, -+ [2][1][RTW89_CHILE][5] = 56, -+ [2][1][RTW89_UKRAINE][5] = 44, -+ [2][1][RTW89_MEXICO][5] = 80, -+ [2][1][RTW89_CN][5] = 44, -+ [2][1][RTW89_QATAR][5] = 44, -+ [2][1][RTW89_UK][5] = 44, -+ [2][1][RTW89_FCC][6] = 62, -+ [2][1][RTW89_ETSI][6] = 44, -+ [2][1][RTW89_MKK][6] = 52, -+ [2][1][RTW89_IC][6] = 62, -+ [2][1][RTW89_KCC][6] = 52, -+ [2][1][RTW89_ACMA][6] = 44, -+ [2][1][RTW89_CHILE][6] = 56, -+ [2][1][RTW89_UKRAINE][6] = 44, -+ [2][1][RTW89_MEXICO][6] = 62, -+ [2][1][RTW89_CN][6] = 44, -+ [2][1][RTW89_QATAR][6] = 44, -+ [2][1][RTW89_UK][6] = 44, -+ [2][1][RTW89_FCC][7] = 62, -+ [2][1][RTW89_ETSI][7] = 44, -+ [2][1][RTW89_MKK][7] = 52, -+ [2][1][RTW89_IC][7] = 62, -+ [2][1][RTW89_KCC][7] = 52, -+ [2][1][RTW89_ACMA][7] = 44, -+ [2][1][RTW89_CHILE][7] = 56, -+ [2][1][RTW89_UKRAINE][7] = 44, -+ [2][1][RTW89_MEXICO][7] = 62, -+ [2][1][RTW89_CN][7] = 44, -+ [2][1][RTW89_QATAR][7] = 44, -+ [2][1][RTW89_UK][7] = 44, -+ [2][1][RTW89_FCC][8] = 58, -+ [2][1][RTW89_ETSI][8] = 44, -+ [2][1][RTW89_MKK][8] = 52, -+ [2][1][RTW89_IC][8] = 58, -+ [2][1][RTW89_KCC][8] = 52, -+ [2][1][RTW89_ACMA][8] = 44, -+ [2][1][RTW89_CHILE][8] = 56, -+ [2][1][RTW89_UKRAINE][8] = 44, -+ [2][1][RTW89_MEXICO][8] = 58, -+ [2][1][RTW89_CN][8] = 44, -+ [2][1][RTW89_QATAR][8] = 44, -+ [2][1][RTW89_UK][8] = 44, -+ [2][1][RTW89_FCC][9] = 54, -+ [2][1][RTW89_ETSI][9] = 44, -+ [2][1][RTW89_MKK][9] = 52, -+ [2][1][RTW89_IC][9] = 54, -+ [2][1][RTW89_KCC][9] = 54, -+ [2][1][RTW89_ACMA][9] = 44, -+ [2][1][RTW89_CHILE][9] = 56, -+ [2][1][RTW89_UKRAINE][9] = 44, -+ [2][1][RTW89_MEXICO][9] = 54, -+ [2][1][RTW89_CN][9] = 44, -+ [2][1][RTW89_QATAR][9] = 44, -+ [2][1][RTW89_UK][9] = 44, -+ [2][1][RTW89_FCC][10] = 54, -+ [2][1][RTW89_ETSI][10] = 44, -+ [2][1][RTW89_MKK][10] = 52, -+ [2][1][RTW89_IC][10] = 54, -+ [2][1][RTW89_KCC][10] = 54, -+ [2][1][RTW89_ACMA][10] = 44, -+ [2][1][RTW89_CHILE][10] = 56, -+ [2][1][RTW89_UKRAINE][10] = 44, -+ [2][1][RTW89_MEXICO][10] = 54, -+ [2][1][RTW89_CN][10] = 44, -+ [2][1][RTW89_QATAR][10] = 44, -+ [2][1][RTW89_UK][10] = 44, -+ [2][1][RTW89_FCC][11] = 38, -+ [2][1][RTW89_ETSI][11] = 44, -+ [2][1][RTW89_MKK][11] = 52, -+ [2][1][RTW89_IC][11] = 38, -+ [2][1][RTW89_KCC][11] = 54, -+ [2][1][RTW89_ACMA][11] = 44, -+ [2][1][RTW89_CHILE][11] = 56, -+ [2][1][RTW89_UKRAINE][11] = 44, -+ [2][1][RTW89_MEXICO][11] = 38, -+ [2][1][RTW89_CN][11] = 44, -+ [2][1][RTW89_QATAR][11] = 44, -+ [2][1][RTW89_UK][11] = 44, -+ [2][1][RTW89_FCC][12] = 34, -+ [2][1][RTW89_ETSI][12] = 42, -+ [2][1][RTW89_MKK][12] = 52, -+ [2][1][RTW89_IC][12] = 34, -+ [2][1][RTW89_KCC][12] = 54, -+ [2][1][RTW89_ACMA][12] = 42, -+ [2][1][RTW89_CHILE][12] = 56, -+ [2][1][RTW89_UKRAINE][12] = 42, -+ [2][1][RTW89_MEXICO][12] = 34, -+ [2][1][RTW89_CN][12] = 42, -+ [2][1][RTW89_QATAR][12] = 42, -+ [2][1][RTW89_UK][12] = 42, -+ [2][1][RTW89_FCC][13] = 127, -+ [2][1][RTW89_ETSI][13] = 127, -+ [2][1][RTW89_MKK][13] = 127, -+ [2][1][RTW89_IC][13] = 127, -+ [2][1][RTW89_KCC][13] = 127, -+ [2][1][RTW89_ACMA][13] = 127, -+ [2][1][RTW89_CHILE][13] = 127, -+ [2][1][RTW89_UKRAINE][13] = 127, -+ [2][1][RTW89_MEXICO][13] = 127, -+ [2][1][RTW89_CN][13] = 127, -+ [2][1][RTW89_QATAR][13] = 127, -+ [2][1][RTW89_UK][13] = 127, -+}; -+ -+const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 24, -+ [0][0][RTW89_WW][2] = 24, -+ [0][0][RTW89_WW][4] = 24, -+ [0][0][RTW89_WW][6] = 12, -+ [0][0][RTW89_WW][8] = 24, -+ [0][0][RTW89_WW][10] = 24, -+ [0][0][RTW89_WW][12] = 24, -+ [0][0][RTW89_WW][14] = 24, -+ [0][0][RTW89_WW][15] = 24, -+ [0][0][RTW89_WW][17] = 24, -+ [0][0][RTW89_WW][19] = 24, -+ [0][0][RTW89_WW][21] = 24, -+ [0][0][RTW89_WW][23] = 24, -+ [0][0][RTW89_WW][25] = 24, -+ [0][0][RTW89_WW][27] = 24, -+ [0][0][RTW89_WW][29] = 24, -+ [0][0][RTW89_WW][31] = 24, -+ [0][0][RTW89_WW][33] = 24, -+ [0][0][RTW89_WW][35] = 24, -+ [0][0][RTW89_WW][37] = 44, -+ [0][0][RTW89_WW][38] = 26, -+ [0][0][RTW89_WW][40] = 26, -+ [0][0][RTW89_WW][42] = 26, -+ [0][0][RTW89_WW][44] = 26, -+ [0][0][RTW89_WW][46] = 26, -+ [0][0][RTW89_WW][48] = 32, -+ [0][0][RTW89_WW][50] = 32, -+ [0][0][RTW89_WW][52] = 32, -+ [0][1][RTW89_WW][0] = 0, -+ [0][1][RTW89_WW][2] = 4, -+ [0][1][RTW89_WW][4] = 0, -+ [0][1][RTW89_WW][6] = 0, -+ [0][1][RTW89_WW][8] = 12, -+ [0][1][RTW89_WW][10] = 12, -+ [0][1][RTW89_WW][12] = 12, -+ [0][1][RTW89_WW][14] = 12, -+ [0][1][RTW89_WW][15] = 12, -+ [0][1][RTW89_WW][17] = 12, -+ [0][1][RTW89_WW][19] = 12, -+ [0][1][RTW89_WW][21] = 12, -+ [0][1][RTW89_WW][23] = 12, -+ [0][1][RTW89_WW][25] = 12, -+ [0][1][RTW89_WW][27] = 12, -+ [0][1][RTW89_WW][29] = 12, -+ [0][1][RTW89_WW][31] = 12, -+ [0][1][RTW89_WW][33] = 12, -+ [0][1][RTW89_WW][35] = 12, -+ [0][1][RTW89_WW][37] = 30, -+ [0][1][RTW89_WW][38] = 14, -+ [0][1][RTW89_WW][40] = 14, -+ [0][1][RTW89_WW][42] = 14, -+ [0][1][RTW89_WW][44] = 14, -+ [0][1][RTW89_WW][46] = 14, -+ [0][1][RTW89_WW][48] = 20, -+ [0][1][RTW89_WW][50] = 20, -+ [0][1][RTW89_WW][52] = 20, -+ [1][0][RTW89_WW][0] = 34, -+ [1][0][RTW89_WW][2] = 34, -+ [1][0][RTW89_WW][4] = 34, -+ [1][0][RTW89_WW][6] = 26, -+ [1][0][RTW89_WW][8] = 34, -+ [1][0][RTW89_WW][10] = 34, -+ [1][0][RTW89_WW][12] = 34, -+ [1][0][RTW89_WW][14] = 34, -+ [1][0][RTW89_WW][15] = 34, -+ [1][0][RTW89_WW][17] = 34, -+ [1][0][RTW89_WW][19] = 34, -+ [1][0][RTW89_WW][21] = 34, -+ [1][0][RTW89_WW][23] = 34, -+ [1][0][RTW89_WW][25] = 34, -+ [1][0][RTW89_WW][27] = 34, -+ [1][0][RTW89_WW][29] = 34, -+ [1][0][RTW89_WW][31] = 34, -+ [1][0][RTW89_WW][33] = 34, -+ [1][0][RTW89_WW][35] = 34, -+ [1][0][RTW89_WW][37] = 52, -+ [1][0][RTW89_WW][38] = 28, -+ [1][0][RTW89_WW][40] = 28, -+ [1][0][RTW89_WW][42] = 28, -+ [1][0][RTW89_WW][44] = 28, -+ [1][0][RTW89_WW][46] = 28, -+ [1][0][RTW89_WW][48] = 44, -+ [1][0][RTW89_WW][50] = 44, -+ [1][0][RTW89_WW][52] = 44, -+ [1][1][RTW89_WW][0] = 10, -+ [1][1][RTW89_WW][2] = 14, -+ [1][1][RTW89_WW][4] = 10, -+ [1][1][RTW89_WW][6] = 10, -+ [1][1][RTW89_WW][8] = 20, -+ [1][1][RTW89_WW][10] = 20, -+ [1][1][RTW89_WW][12] = 22, -+ [1][1][RTW89_WW][14] = 22, -+ [1][1][RTW89_WW][15] = 22, -+ [1][1][RTW89_WW][17] = 22, -+ [1][1][RTW89_WW][19] = 22, -+ [1][1][RTW89_WW][21] = 22, -+ [1][1][RTW89_WW][23] = 22, -+ [1][1][RTW89_WW][25] = 22, -+ [1][1][RTW89_WW][27] = 22, -+ [1][1][RTW89_WW][29] = 22, -+ [1][1][RTW89_WW][31] = 22, -+ [1][1][RTW89_WW][33] = 22, -+ [1][1][RTW89_WW][35] = 22, -+ [1][1][RTW89_WW][37] = 38, -+ [1][1][RTW89_WW][38] = 16, -+ [1][1][RTW89_WW][40] = 16, -+ [1][1][RTW89_WW][42] = 16, -+ [1][1][RTW89_WW][44] = 16, -+ [1][1][RTW89_WW][46] = 16, -+ [1][1][RTW89_WW][48] = 32, -+ [1][1][RTW89_WW][50] = 32, -+ [1][1][RTW89_WW][52] = 32, -+ [2][0][RTW89_WW][0] = 44, -+ [2][0][RTW89_WW][2] = 44, -+ [2][0][RTW89_WW][4] = 44, -+ [2][0][RTW89_WW][6] = 38, -+ [2][0][RTW89_WW][8] = 48, -+ [2][0][RTW89_WW][10] = 48, -+ [2][0][RTW89_WW][12] = 46, -+ [2][0][RTW89_WW][14] = 46, -+ [2][0][RTW89_WW][15] = 48, -+ [2][0][RTW89_WW][17] = 48, -+ [2][0][RTW89_WW][19] = 48, -+ [2][0][RTW89_WW][21] = 48, -+ [2][0][RTW89_WW][23] = 48, -+ [2][0][RTW89_WW][25] = 48, -+ [2][0][RTW89_WW][27] = 48, -+ [2][0][RTW89_WW][29] = 48, -+ [2][0][RTW89_WW][31] = 48, -+ [2][0][RTW89_WW][33] = 48, -+ [2][0][RTW89_WW][35] = 48, -+ [2][0][RTW89_WW][37] = 64, -+ [2][0][RTW89_WW][38] = 28, -+ [2][0][RTW89_WW][40] = 28, -+ [2][0][RTW89_WW][42] = 28, -+ [2][0][RTW89_WW][44] = 28, -+ [2][0][RTW89_WW][46] = 28, -+ [2][0][RTW89_WW][48] = 56, -+ [2][0][RTW89_WW][50] = 56, -+ [2][0][RTW89_WW][52] = 56, -+ [2][1][RTW89_WW][0] = 20, -+ [2][1][RTW89_WW][2] = 18, -+ [2][1][RTW89_WW][4] = 22, -+ [2][1][RTW89_WW][6] = 22, -+ [2][1][RTW89_WW][8] = 34, -+ [2][1][RTW89_WW][10] = 34, -+ [2][1][RTW89_WW][12] = 36, -+ [2][1][RTW89_WW][14] = 36, -+ [2][1][RTW89_WW][15] = 36, -+ [2][1][RTW89_WW][17] = 36, -+ [2][1][RTW89_WW][19] = 36, -+ [2][1][RTW89_WW][21] = 36, -+ [2][1][RTW89_WW][23] = 36, -+ [2][1][RTW89_WW][25] = 36, -+ [2][1][RTW89_WW][27] = 36, -+ [2][1][RTW89_WW][29] = 36, -+ [2][1][RTW89_WW][31] = 36, -+ [2][1][RTW89_WW][33] = 36, -+ [2][1][RTW89_WW][35] = 36, -+ [2][1][RTW89_WW][37] = 48, -+ [2][1][RTW89_WW][38] = 16, -+ [2][1][RTW89_WW][40] = 16, -+ [2][1][RTW89_WW][42] = 16, -+ [2][1][RTW89_WW][44] = 16, -+ [2][1][RTW89_WW][46] = 16, -+ [2][1][RTW89_WW][48] = 44, -+ [2][1][RTW89_WW][50] = 44, -+ [2][1][RTW89_WW][52] = 44, -+ [0][0][RTW89_FCC][0] = 52, -+ [0][0][RTW89_ETSI][0] = 24, -+ [0][0][RTW89_MKK][0] = 26, -+ [0][0][RTW89_IC][0] = 24, -+ [0][0][RTW89_KCC][0] = 44, -+ [0][0][RTW89_ACMA][0] = 24, -+ [0][0][RTW89_CHILE][0] = 40, -+ [0][0][RTW89_UKRAINE][0] = 24, -+ [0][0][RTW89_MEXICO][0] = 52, -+ [0][0][RTW89_CN][0] = 24, -+ [0][0][RTW89_QATAR][0] = 24, -+ [0][0][RTW89_UK][0] = 24, -+ [0][0][RTW89_FCC][2] = 52, -+ [0][0][RTW89_ETSI][2] = 24, -+ [0][0][RTW89_MKK][2] = 26, -+ [0][0][RTW89_IC][2] = 24, -+ [0][0][RTW89_KCC][2] = 44, -+ [0][0][RTW89_ACMA][2] = 24, -+ [0][0][RTW89_CHILE][2] = 38, -+ [0][0][RTW89_UKRAINE][2] = 24, -+ [0][0][RTW89_MEXICO][2] = 52, -+ [0][0][RTW89_CN][2] = 24, -+ [0][0][RTW89_QATAR][2] = 24, -+ [0][0][RTW89_UK][2] = 24, -+ [0][0][RTW89_FCC][4] = 52, -+ [0][0][RTW89_ETSI][4] = 24, -+ [0][0][RTW89_MKK][4] = 26, -+ [0][0][RTW89_IC][4] = 24, -+ [0][0][RTW89_KCC][4] = 44, -+ [0][0][RTW89_ACMA][4] = 24, -+ [0][0][RTW89_CHILE][4] = 38, -+ [0][0][RTW89_UKRAINE][4] = 24, -+ [0][0][RTW89_MEXICO][4] = 52, -+ [0][0][RTW89_CN][4] = 24, -+ [0][0][RTW89_QATAR][4] = 24, -+ [0][0][RTW89_UK][4] = 24, -+ [0][0][RTW89_FCC][6] = 52, -+ [0][0][RTW89_ETSI][6] = 24, -+ [0][0][RTW89_MKK][6] = 26, -+ [0][0][RTW89_IC][6] = 24, -+ [0][0][RTW89_KCC][6] = 12, -+ [0][0][RTW89_ACMA][6] = 24, -+ [0][0][RTW89_CHILE][6] = 40, -+ [0][0][RTW89_UKRAINE][6] = 24, -+ [0][0][RTW89_MEXICO][6] = 52, -+ [0][0][RTW89_CN][6] = 24, -+ [0][0][RTW89_QATAR][6] = 24, -+ [0][0][RTW89_UK][6] = 24, -+ [0][0][RTW89_FCC][8] = 52, -+ [0][0][RTW89_ETSI][8] = 24, -+ [0][0][RTW89_MKK][8] = 26, -+ [0][0][RTW89_IC][8] = 52, -+ [0][0][RTW89_KCC][8] = 46, -+ [0][0][RTW89_ACMA][8] = 24, -+ [0][0][RTW89_CHILE][8] = 64, -+ [0][0][RTW89_UKRAINE][8] = 24, -+ [0][0][RTW89_MEXICO][8] = 52, -+ [0][0][RTW89_CN][8] = 24, -+ [0][0][RTW89_QATAR][8] = 24, -+ [0][0][RTW89_UK][8] = 24, -+ [0][0][RTW89_FCC][10] = 52, -+ [0][0][RTW89_ETSI][10] = 24, -+ [0][0][RTW89_MKK][10] = 26, -+ [0][0][RTW89_IC][10] = 52, -+ [0][0][RTW89_KCC][10] = 46, -+ [0][0][RTW89_ACMA][10] = 24, -+ [0][0][RTW89_CHILE][10] = 64, -+ [0][0][RTW89_UKRAINE][10] = 24, -+ [0][0][RTW89_MEXICO][10] = 52, -+ [0][0][RTW89_CN][10] = 24, -+ [0][0][RTW89_QATAR][10] = 24, -+ [0][0][RTW89_UK][10] = 24, -+ [0][0][RTW89_FCC][12] = 52, -+ [0][0][RTW89_ETSI][12] = 24, -+ [0][0][RTW89_MKK][12] = 24, -+ [0][0][RTW89_IC][12] = 52, -+ [0][0][RTW89_KCC][12] = 42, -+ [0][0][RTW89_ACMA][12] = 24, -+ [0][0][RTW89_CHILE][12] = 64, -+ [0][0][RTW89_UKRAINE][12] = 24, -+ [0][0][RTW89_MEXICO][12] = 52, -+ [0][0][RTW89_CN][12] = 24, -+ [0][0][RTW89_QATAR][12] = 24, -+ [0][0][RTW89_UK][12] = 24, -+ [0][0][RTW89_FCC][14] = 52, -+ [0][0][RTW89_ETSI][14] = 24, -+ [0][0][RTW89_MKK][14] = 24, -+ [0][0][RTW89_IC][14] = 52, -+ [0][0][RTW89_KCC][14] = 42, -+ [0][0][RTW89_ACMA][14] = 24, -+ [0][0][RTW89_CHILE][14] = 64, -+ [0][0][RTW89_UKRAINE][14] = 24, -+ [0][0][RTW89_MEXICO][14] = 52, -+ [0][0][RTW89_CN][14] = 24, -+ [0][0][RTW89_QATAR][14] = 24, -+ [0][0][RTW89_UK][14] = 24, -+ [0][0][RTW89_FCC][15] = 52, -+ [0][0][RTW89_ETSI][15] = 24, -+ [0][0][RTW89_MKK][15] = 46, -+ [0][0][RTW89_IC][15] = 52, -+ [0][0][RTW89_KCC][15] = 44, -+ [0][0][RTW89_ACMA][15] = 24, -+ [0][0][RTW89_CHILE][15] = 60, -+ [0][0][RTW89_UKRAINE][15] = 24, -+ [0][0][RTW89_MEXICO][15] = 52, -+ [0][0][RTW89_CN][15] = 127, -+ [0][0][RTW89_QATAR][15] = 24, -+ [0][0][RTW89_UK][15] = 24, -+ [0][0][RTW89_FCC][17] = 52, -+ [0][0][RTW89_ETSI][17] = 24, -+ [0][0][RTW89_MKK][17] = 48, -+ [0][0][RTW89_IC][17] = 52, -+ [0][0][RTW89_KCC][17] = 44, -+ [0][0][RTW89_ACMA][17] = 24, -+ [0][0][RTW89_CHILE][17] = 60, -+ [0][0][RTW89_UKRAINE][17] = 24, -+ [0][0][RTW89_MEXICO][17] = 52, -+ [0][0][RTW89_CN][17] = 127, -+ [0][0][RTW89_QATAR][17] = 24, -+ [0][0][RTW89_UK][17] = 24, -+ [0][0][RTW89_FCC][19] = 52, -+ [0][0][RTW89_ETSI][19] = 24, -+ [0][0][RTW89_MKK][19] = 48, -+ [0][0][RTW89_IC][19] = 52, -+ [0][0][RTW89_KCC][19] = 44, -+ [0][0][RTW89_ACMA][19] = 24, -+ [0][0][RTW89_CHILE][19] = 60, -+ [0][0][RTW89_UKRAINE][19] = 24, -+ [0][0][RTW89_MEXICO][19] = 52, -+ [0][0][RTW89_CN][19] = 127, -+ [0][0][RTW89_QATAR][19] = 24, -+ [0][0][RTW89_UK][19] = 24, -+ [0][0][RTW89_FCC][21] = 52, -+ [0][0][RTW89_ETSI][21] = 24, -+ [0][0][RTW89_MKK][21] = 48, -+ [0][0][RTW89_IC][21] = 52, -+ [0][0][RTW89_KCC][21] = 44, -+ [0][0][RTW89_ACMA][21] = 24, -+ [0][0][RTW89_CHILE][21] = 62, -+ [0][0][RTW89_UKRAINE][21] = 24, -+ [0][0][RTW89_MEXICO][21] = 52, -+ [0][0][RTW89_CN][21] = 127, -+ [0][0][RTW89_QATAR][21] = 24, -+ [0][0][RTW89_UK][21] = 24, -+ [0][0][RTW89_FCC][23] = 52, -+ [0][0][RTW89_ETSI][23] = 24, -+ [0][0][RTW89_MKK][23] = 48, -+ [0][0][RTW89_IC][23] = 52, -+ [0][0][RTW89_KCC][23] = 44, -+ [0][0][RTW89_ACMA][23] = 24, -+ [0][0][RTW89_CHILE][23] = 62, -+ [0][0][RTW89_UKRAINE][23] = 24, -+ [0][0][RTW89_MEXICO][23] = 52, -+ [0][0][RTW89_CN][23] = 127, -+ [0][0][RTW89_QATAR][23] = 24, -+ [0][0][RTW89_UK][23] = 24, -+ [0][0][RTW89_FCC][25] = 52, -+ [0][0][RTW89_ETSI][25] = 24, -+ [0][0][RTW89_MKK][25] = 48, -+ [0][0][RTW89_IC][25] = 127, -+ [0][0][RTW89_KCC][25] = 44, -+ [0][0][RTW89_ACMA][25] = 127, -+ [0][0][RTW89_CHILE][25] = 62, -+ [0][0][RTW89_UKRAINE][25] = 24, -+ [0][0][RTW89_MEXICO][25] = 52, -+ [0][0][RTW89_CN][25] = 127, -+ [0][0][RTW89_QATAR][25] = 24, -+ [0][0][RTW89_UK][25] = 24, -+ [0][0][RTW89_FCC][27] = 52, -+ [0][0][RTW89_ETSI][27] = 24, -+ [0][0][RTW89_MKK][27] = 48, -+ [0][0][RTW89_IC][27] = 127, -+ [0][0][RTW89_KCC][27] = 44, -+ [0][0][RTW89_ACMA][27] = 127, -+ [0][0][RTW89_CHILE][27] = 62, -+ [0][0][RTW89_UKRAINE][27] = 24, -+ [0][0][RTW89_MEXICO][27] = 52, -+ [0][0][RTW89_CN][27] = 127, -+ [0][0][RTW89_QATAR][27] = 24, -+ [0][0][RTW89_UK][27] = 24, -+ [0][0][RTW89_FCC][29] = 52, -+ [0][0][RTW89_ETSI][29] = 24, -+ [0][0][RTW89_MKK][29] = 48, -+ [0][0][RTW89_IC][29] = 127, -+ [0][0][RTW89_KCC][29] = 44, -+ [0][0][RTW89_ACMA][29] = 127, -+ [0][0][RTW89_CHILE][29] = 60, -+ [0][0][RTW89_UKRAINE][29] = 24, -+ [0][0][RTW89_MEXICO][29] = 52, -+ [0][0][RTW89_CN][29] = 127, -+ [0][0][RTW89_QATAR][29] = 24, -+ [0][0][RTW89_UK][29] = 24, -+ [0][0][RTW89_FCC][31] = 52, -+ [0][0][RTW89_ETSI][31] = 24, -+ [0][0][RTW89_MKK][31] = 48, -+ [0][0][RTW89_IC][31] = 52, -+ [0][0][RTW89_KCC][31] = 44, -+ [0][0][RTW89_ACMA][31] = 24, -+ [0][0][RTW89_CHILE][31] = 60, -+ [0][0][RTW89_UKRAINE][31] = 24, -+ [0][0][RTW89_MEXICO][31] = 52, -+ [0][0][RTW89_CN][31] = 127, -+ [0][0][RTW89_QATAR][31] = 24, -+ [0][0][RTW89_UK][31] = 24, -+ [0][0][RTW89_FCC][33] = 52, -+ [0][0][RTW89_ETSI][33] = 24, -+ [0][0][RTW89_MKK][33] = 48, -+ [0][0][RTW89_IC][33] = 52, -+ [0][0][RTW89_KCC][33] = 44, -+ [0][0][RTW89_ACMA][33] = 24, -+ [0][0][RTW89_CHILE][33] = 60, -+ [0][0][RTW89_UKRAINE][33] = 24, -+ [0][0][RTW89_MEXICO][33] = 52, -+ [0][0][RTW89_CN][33] = 127, -+ [0][0][RTW89_QATAR][33] = 24, -+ [0][0][RTW89_UK][33] = 24, -+ [0][0][RTW89_FCC][35] = 52, -+ [0][0][RTW89_ETSI][35] = 24, -+ [0][0][RTW89_MKK][35] = 48, -+ [0][0][RTW89_IC][35] = 52, -+ [0][0][RTW89_KCC][35] = 44, -+ [0][0][RTW89_ACMA][35] = 24, -+ [0][0][RTW89_CHILE][35] = 60, -+ [0][0][RTW89_UKRAINE][35] = 24, -+ [0][0][RTW89_MEXICO][35] = 52, -+ [0][0][RTW89_CN][35] = 127, -+ [0][0][RTW89_QATAR][35] = 24, -+ [0][0][RTW89_UK][35] = 24, -+ [0][0][RTW89_FCC][37] = 52, -+ [0][0][RTW89_ETSI][37] = 127, -+ [0][0][RTW89_MKK][37] = 44, -+ [0][0][RTW89_IC][37] = 52, -+ [0][0][RTW89_KCC][37] = 44, -+ [0][0][RTW89_ACMA][37] = 52, -+ [0][0][RTW89_CHILE][37] = 62, -+ [0][0][RTW89_UKRAINE][37] = 127, -+ [0][0][RTW89_MEXICO][37] = 52, -+ [0][0][RTW89_CN][37] = 127, -+ [0][0][RTW89_QATAR][37] = 127, -+ [0][0][RTW89_UK][37] = 56, -+ [0][0][RTW89_FCC][38] = 84, -+ [0][0][RTW89_ETSI][38] = 28, -+ [0][0][RTW89_MKK][38] = 127, -+ [0][0][RTW89_IC][38] = 84, -+ [0][0][RTW89_KCC][38] = 44, -+ [0][0][RTW89_ACMA][38] = 84, -+ [0][0][RTW89_CHILE][38] = 60, -+ [0][0][RTW89_UKRAINE][38] = 28, -+ [0][0][RTW89_MEXICO][38] = 84, -+ [0][0][RTW89_CN][38] = 62, -+ [0][0][RTW89_QATAR][38] = 28, -+ [0][0][RTW89_UK][38] = 26, -+ [0][0][RTW89_FCC][40] = 84, -+ [0][0][RTW89_ETSI][40] = 28, -+ [0][0][RTW89_MKK][40] = 127, -+ [0][0][RTW89_IC][40] = 84, -+ [0][0][RTW89_KCC][40] = 44, -+ [0][0][RTW89_ACMA][40] = 84, -+ [0][0][RTW89_CHILE][40] = 60, -+ [0][0][RTW89_UKRAINE][40] = 28, -+ [0][0][RTW89_MEXICO][40] = 84, -+ [0][0][RTW89_CN][40] = 62, -+ [0][0][RTW89_QATAR][40] = 28, -+ [0][0][RTW89_UK][40] = 26, -+ [0][0][RTW89_FCC][42] = 84, -+ [0][0][RTW89_ETSI][42] = 28, -+ [0][0][RTW89_MKK][42] = 127, -+ [0][0][RTW89_IC][42] = 84, -+ [0][0][RTW89_KCC][42] = 44, -+ [0][0][RTW89_ACMA][42] = 84, -+ [0][0][RTW89_CHILE][42] = 64, -+ [0][0][RTW89_UKRAINE][42] = 28, -+ [0][0][RTW89_MEXICO][42] = 84, -+ [0][0][RTW89_CN][42] = 62, -+ [0][0][RTW89_QATAR][42] = 28, -+ [0][0][RTW89_UK][42] = 26, -+ [0][0][RTW89_FCC][44] = 84, -+ [0][0][RTW89_ETSI][44] = 28, -+ [0][0][RTW89_MKK][44] = 127, -+ [0][0][RTW89_IC][44] = 84, -+ [0][0][RTW89_KCC][44] = 44, -+ [0][0][RTW89_ACMA][44] = 84, -+ [0][0][RTW89_CHILE][44] = 60, -+ [0][0][RTW89_UKRAINE][44] = 28, -+ [0][0][RTW89_MEXICO][44] = 84, -+ [0][0][RTW89_CN][44] = 62, -+ [0][0][RTW89_QATAR][44] = 28, -+ [0][0][RTW89_UK][44] = 26, -+ [0][0][RTW89_FCC][46] = 84, -+ [0][0][RTW89_ETSI][46] = 28, -+ [0][0][RTW89_MKK][46] = 127, -+ [0][0][RTW89_IC][46] = 84, -+ [0][0][RTW89_KCC][46] = 44, -+ [0][0][RTW89_ACMA][46] = 84, -+ [0][0][RTW89_CHILE][46] = 60, -+ [0][0][RTW89_UKRAINE][46] = 28, -+ [0][0][RTW89_MEXICO][46] = 84, -+ [0][0][RTW89_CN][46] = 62, -+ [0][0][RTW89_QATAR][46] = 28, -+ [0][0][RTW89_UK][46] = 26, -+ [0][0][RTW89_FCC][48] = 32, -+ [0][0][RTW89_ETSI][48] = 127, -+ [0][0][RTW89_MKK][48] = 127, -+ [0][0][RTW89_IC][48] = 127, -+ [0][0][RTW89_KCC][48] = 127, -+ [0][0][RTW89_ACMA][48] = 127, -+ [0][0][RTW89_CHILE][48] = 127, -+ [0][0][RTW89_UKRAINE][48] = 127, -+ [0][0][RTW89_MEXICO][48] = 127, -+ [0][0][RTW89_CN][48] = 127, -+ [0][0][RTW89_QATAR][48] = 127, -+ [0][0][RTW89_UK][48] = 127, -+ [0][0][RTW89_FCC][50] = 32, -+ [0][0][RTW89_ETSI][50] = 127, -+ [0][0][RTW89_MKK][50] = 127, -+ [0][0][RTW89_IC][50] = 127, -+ [0][0][RTW89_KCC][50] = 127, -+ [0][0][RTW89_ACMA][50] = 127, -+ [0][0][RTW89_CHILE][50] = 127, -+ [0][0][RTW89_UKRAINE][50] = 127, -+ [0][0][RTW89_MEXICO][50] = 127, -+ [0][0][RTW89_CN][50] = 127, -+ [0][0][RTW89_QATAR][50] = 127, -+ [0][0][RTW89_UK][50] = 127, -+ [0][0][RTW89_FCC][52] = 32, -+ [0][0][RTW89_ETSI][52] = 127, -+ [0][0][RTW89_MKK][52] = 127, -+ [0][0][RTW89_IC][52] = 127, -+ [0][0][RTW89_KCC][52] = 127, -+ [0][0][RTW89_ACMA][52] = 127, -+ [0][0][RTW89_CHILE][52] = 127, -+ [0][0][RTW89_UKRAINE][52] = 127, -+ [0][0][RTW89_MEXICO][52] = 127, -+ [0][0][RTW89_CN][52] = 127, -+ [0][0][RTW89_QATAR][52] = 127, -+ [0][0][RTW89_UK][52] = 127, -+ [0][1][RTW89_FCC][0] = 34, -+ [0][1][RTW89_ETSI][0] = 12, -+ [0][1][RTW89_MKK][0] = 12, -+ [0][1][RTW89_IC][0] = 0, -+ [0][1][RTW89_KCC][0] = 28, -+ [0][1][RTW89_ACMA][0] = 12, -+ [0][1][RTW89_CHILE][0] = 14, -+ [0][1][RTW89_UKRAINE][0] = 12, -+ [0][1][RTW89_MEXICO][0] = 34, -+ [0][1][RTW89_CN][0] = 12, -+ [0][1][RTW89_QATAR][0] = 12, -+ [0][1][RTW89_UK][0] = 12, -+ [0][1][RTW89_FCC][2] = 38, -+ [0][1][RTW89_ETSI][2] = 12, -+ [0][1][RTW89_MKK][2] = 12, -+ [0][1][RTW89_IC][2] = 4, -+ [0][1][RTW89_KCC][2] = 28, -+ [0][1][RTW89_ACMA][2] = 12, -+ [0][1][RTW89_CHILE][2] = 12, -+ [0][1][RTW89_UKRAINE][2] = 12, -+ [0][1][RTW89_MEXICO][2] = 38, -+ [0][1][RTW89_CN][2] = 12, -+ [0][1][RTW89_QATAR][2] = 12, -+ [0][1][RTW89_UK][2] = 12, -+ [0][1][RTW89_FCC][4] = 34, -+ [0][1][RTW89_ETSI][4] = 12, -+ [0][1][RTW89_MKK][4] = 14, -+ [0][1][RTW89_IC][4] = 0, -+ [0][1][RTW89_KCC][4] = 28, -+ [0][1][RTW89_ACMA][4] = 12, -+ [0][1][RTW89_CHILE][4] = 12, -+ [0][1][RTW89_UKRAINE][4] = 12, -+ [0][1][RTW89_MEXICO][4] = 34, -+ [0][1][RTW89_CN][4] = 12, -+ [0][1][RTW89_QATAR][4] = 12, -+ [0][1][RTW89_UK][4] = 12, -+ [0][1][RTW89_FCC][6] = 34, -+ [0][1][RTW89_ETSI][6] = 12, -+ [0][1][RTW89_MKK][6] = 14, -+ [0][1][RTW89_IC][6] = 0, -+ [0][1][RTW89_KCC][6] = 2, -+ [0][1][RTW89_ACMA][6] = 12, -+ [0][1][RTW89_CHILE][6] = 12, -+ [0][1][RTW89_UKRAINE][6] = 12, -+ [0][1][RTW89_MEXICO][6] = 34, -+ [0][1][RTW89_CN][6] = 12, -+ [0][1][RTW89_QATAR][6] = 12, -+ [0][1][RTW89_UK][6] = 12, -+ [0][1][RTW89_FCC][8] = 34, -+ [0][1][RTW89_ETSI][8] = 12, -+ [0][1][RTW89_MKK][8] = 14, -+ [0][1][RTW89_IC][8] = 34, -+ [0][1][RTW89_KCC][8] = 30, -+ [0][1][RTW89_ACMA][8] = 12, -+ [0][1][RTW89_CHILE][8] = 50, -+ [0][1][RTW89_UKRAINE][8] = 12, -+ [0][1][RTW89_MEXICO][8] = 34, -+ [0][1][RTW89_CN][8] = 12, -+ [0][1][RTW89_QATAR][8] = 12, -+ [0][1][RTW89_UK][8] = 12, -+ [0][1][RTW89_FCC][10] = 34, -+ [0][1][RTW89_ETSI][10] = 12, -+ [0][1][RTW89_MKK][10] = 14, -+ [0][1][RTW89_IC][10] = 34, -+ [0][1][RTW89_KCC][10] = 30, -+ [0][1][RTW89_ACMA][10] = 12, -+ [0][1][RTW89_CHILE][10] = 50, -+ [0][1][RTW89_UKRAINE][10] = 12, -+ [0][1][RTW89_MEXICO][10] = 34, -+ [0][1][RTW89_CN][10] = 12, -+ [0][1][RTW89_QATAR][10] = 12, -+ [0][1][RTW89_UK][10] = 12, -+ [0][1][RTW89_FCC][12] = 38, -+ [0][1][RTW89_ETSI][12] = 12, -+ [0][1][RTW89_MKK][12] = 12, -+ [0][1][RTW89_IC][12] = 38, -+ [0][1][RTW89_KCC][12] = 30, -+ [0][1][RTW89_ACMA][12] = 12, -+ [0][1][RTW89_CHILE][12] = 50, -+ [0][1][RTW89_UKRAINE][12] = 12, -+ [0][1][RTW89_MEXICO][12] = 38, -+ [0][1][RTW89_CN][12] = 12, -+ [0][1][RTW89_QATAR][12] = 12, -+ [0][1][RTW89_UK][12] = 12, -+ [0][1][RTW89_FCC][14] = 34, -+ [0][1][RTW89_ETSI][14] = 12, -+ [0][1][RTW89_MKK][14] = 12, -+ [0][1][RTW89_IC][14] = 34, -+ [0][1][RTW89_KCC][14] = 30, -+ [0][1][RTW89_ACMA][14] = 12, -+ [0][1][RTW89_CHILE][14] = 48, -+ [0][1][RTW89_UKRAINE][14] = 12, -+ [0][1][RTW89_MEXICO][14] = 34, -+ [0][1][RTW89_CN][14] = 12, -+ [0][1][RTW89_QATAR][14] = 12, -+ [0][1][RTW89_UK][14] = 12, -+ [0][1][RTW89_FCC][15] = 34, -+ [0][1][RTW89_ETSI][15] = 12, -+ [0][1][RTW89_MKK][15] = 32, -+ [0][1][RTW89_IC][15] = 34, -+ [0][1][RTW89_KCC][15] = 30, -+ [0][1][RTW89_ACMA][15] = 12, -+ [0][1][RTW89_CHILE][15] = 52, -+ [0][1][RTW89_UKRAINE][15] = 12, -+ [0][1][RTW89_MEXICO][15] = 34, -+ [0][1][RTW89_CN][15] = 127, -+ [0][1][RTW89_QATAR][15] = 12, -+ [0][1][RTW89_UK][15] = 12, -+ [0][1][RTW89_FCC][17] = 34, -+ [0][1][RTW89_ETSI][17] = 12, -+ [0][1][RTW89_MKK][17] = 34, -+ [0][1][RTW89_IC][17] = 34, -+ [0][1][RTW89_KCC][17] = 30, -+ [0][1][RTW89_ACMA][17] = 12, -+ [0][1][RTW89_CHILE][17] = 52, -+ [0][1][RTW89_UKRAINE][17] = 12, -+ [0][1][RTW89_MEXICO][17] = 34, -+ [0][1][RTW89_CN][17] = 127, -+ [0][1][RTW89_QATAR][17] = 12, -+ [0][1][RTW89_UK][17] = 12, -+ [0][1][RTW89_FCC][19] = 38, -+ [0][1][RTW89_ETSI][19] = 12, -+ [0][1][RTW89_MKK][19] = 34, -+ [0][1][RTW89_IC][19] = 38, -+ [0][1][RTW89_KCC][19] = 30, -+ [0][1][RTW89_ACMA][19] = 12, -+ [0][1][RTW89_CHILE][19] = 52, -+ [0][1][RTW89_UKRAINE][19] = 12, -+ [0][1][RTW89_MEXICO][19] = 38, -+ [0][1][RTW89_CN][19] = 127, -+ [0][1][RTW89_QATAR][19] = 12, -+ [0][1][RTW89_UK][19] = 12, -+ [0][1][RTW89_FCC][21] = 38, -+ [0][1][RTW89_ETSI][21] = 12, -+ [0][1][RTW89_MKK][21] = 34, -+ [0][1][RTW89_IC][21] = 38, -+ [0][1][RTW89_KCC][21] = 30, -+ [0][1][RTW89_ACMA][21] = 12, -+ [0][1][RTW89_CHILE][21] = 52, -+ [0][1][RTW89_UKRAINE][21] = 12, -+ [0][1][RTW89_MEXICO][21] = 38, -+ [0][1][RTW89_CN][21] = 127, -+ [0][1][RTW89_QATAR][21] = 12, -+ [0][1][RTW89_UK][21] = 12, -+ [0][1][RTW89_FCC][23] = 38, -+ [0][1][RTW89_ETSI][23] = 12, -+ [0][1][RTW89_MKK][23] = 34, -+ [0][1][RTW89_IC][23] = 38, -+ [0][1][RTW89_KCC][23] = 30, -+ [0][1][RTW89_ACMA][23] = 12, -+ [0][1][RTW89_CHILE][23] = 52, -+ [0][1][RTW89_UKRAINE][23] = 12, -+ [0][1][RTW89_MEXICO][23] = 38, -+ [0][1][RTW89_CN][23] = 127, -+ [0][1][RTW89_QATAR][23] = 12, -+ [0][1][RTW89_UK][23] = 12, -+ [0][1][RTW89_FCC][25] = 38, -+ [0][1][RTW89_ETSI][25] = 12, -+ [0][1][RTW89_MKK][25] = 34, -+ [0][1][RTW89_IC][25] = 127, -+ [0][1][RTW89_KCC][25] = 30, -+ [0][1][RTW89_ACMA][25] = 127, -+ [0][1][RTW89_CHILE][25] = 52, -+ [0][1][RTW89_UKRAINE][25] = 12, -+ [0][1][RTW89_MEXICO][25] = 38, -+ [0][1][RTW89_CN][25] = 127, -+ [0][1][RTW89_QATAR][25] = 12, -+ [0][1][RTW89_UK][25] = 12, -+ [0][1][RTW89_FCC][27] = 38, -+ [0][1][RTW89_ETSI][27] = 12, -+ [0][1][RTW89_MKK][27] = 34, -+ [0][1][RTW89_IC][27] = 127, -+ [0][1][RTW89_KCC][27] = 30, -+ [0][1][RTW89_ACMA][27] = 127, -+ [0][1][RTW89_CHILE][27] = 52, -+ [0][1][RTW89_UKRAINE][27] = 12, -+ [0][1][RTW89_MEXICO][27] = 38, -+ [0][1][RTW89_CN][27] = 127, -+ [0][1][RTW89_QATAR][27] = 12, -+ [0][1][RTW89_UK][27] = 12, -+ [0][1][RTW89_FCC][29] = 38, -+ [0][1][RTW89_ETSI][29] = 12, -+ [0][1][RTW89_MKK][29] = 34, -+ [0][1][RTW89_IC][29] = 127, -+ [0][1][RTW89_KCC][29] = 30, -+ [0][1][RTW89_ACMA][29] = 127, -+ [0][1][RTW89_CHILE][29] = 52, -+ [0][1][RTW89_UKRAINE][29] = 12, -+ [0][1][RTW89_MEXICO][29] = 38, -+ [0][1][RTW89_CN][29] = 127, -+ [0][1][RTW89_QATAR][29] = 12, -+ [0][1][RTW89_UK][29] = 12, -+ [0][1][RTW89_FCC][31] = 38, -+ [0][1][RTW89_ETSI][31] = 12, -+ [0][1][RTW89_MKK][31] = 34, -+ [0][1][RTW89_IC][31] = 34, -+ [0][1][RTW89_KCC][31] = 30, -+ [0][1][RTW89_ACMA][31] = 12, -+ [0][1][RTW89_CHILE][31] = 52, -+ [0][1][RTW89_UKRAINE][31] = 12, -+ [0][1][RTW89_MEXICO][31] = 38, -+ [0][1][RTW89_CN][31] = 127, -+ [0][1][RTW89_QATAR][31] = 12, -+ [0][1][RTW89_UK][31] = 12, -+ [0][1][RTW89_FCC][33] = 34, -+ [0][1][RTW89_ETSI][33] = 12, -+ [0][1][RTW89_MKK][33] = 34, -+ [0][1][RTW89_IC][33] = 34, -+ [0][1][RTW89_KCC][33] = 30, -+ [0][1][RTW89_ACMA][33] = 12, -+ [0][1][RTW89_CHILE][33] = 52, -+ [0][1][RTW89_UKRAINE][33] = 12, -+ [0][1][RTW89_MEXICO][33] = 34, -+ [0][1][RTW89_CN][33] = 127, -+ [0][1][RTW89_QATAR][33] = 12, -+ [0][1][RTW89_UK][33] = 12, -+ [0][1][RTW89_FCC][35] = 34, -+ [0][1][RTW89_ETSI][35] = 12, -+ [0][1][RTW89_MKK][35] = 34, -+ [0][1][RTW89_IC][35] = 34, -+ [0][1][RTW89_KCC][35] = 30, -+ [0][1][RTW89_ACMA][35] = 12, -+ [0][1][RTW89_CHILE][35] = 52, -+ [0][1][RTW89_UKRAINE][35] = 12, -+ [0][1][RTW89_MEXICO][35] = 34, -+ [0][1][RTW89_CN][35] = 127, -+ [0][1][RTW89_QATAR][35] = 12, -+ [0][1][RTW89_UK][35] = 12, -+ [0][1][RTW89_FCC][37] = 38, -+ [0][1][RTW89_ETSI][37] = 127, -+ [0][1][RTW89_MKK][37] = 34, -+ [0][1][RTW89_IC][37] = 38, -+ [0][1][RTW89_KCC][37] = 30, -+ [0][1][RTW89_ACMA][37] = 38, -+ [0][1][RTW89_CHILE][37] = 52, -+ [0][1][RTW89_UKRAINE][37] = 127, -+ [0][1][RTW89_MEXICO][37] = 38, -+ [0][1][RTW89_CN][37] = 127, -+ [0][1][RTW89_QATAR][37] = 127, -+ [0][1][RTW89_UK][37] = 44, -+ [0][1][RTW89_FCC][38] = 82, -+ [0][1][RTW89_ETSI][38] = 16, -+ [0][1][RTW89_MKK][38] = 127, -+ [0][1][RTW89_IC][38] = 82, -+ [0][1][RTW89_KCC][38] = 30, -+ [0][1][RTW89_ACMA][38] = 84, -+ [0][1][RTW89_CHILE][38] = 52, -+ [0][1][RTW89_UKRAINE][38] = 16, -+ [0][1][RTW89_MEXICO][38] = 82, -+ [0][1][RTW89_CN][38] = 50, -+ [0][1][RTW89_QATAR][38] = 16, -+ [0][1][RTW89_UK][38] = 14, -+ [0][1][RTW89_FCC][40] = 82, -+ [0][1][RTW89_ETSI][40] = 16, -+ [0][1][RTW89_MKK][40] = 127, -+ [0][1][RTW89_IC][40] = 82, -+ [0][1][RTW89_KCC][40] = 30, -+ [0][1][RTW89_ACMA][40] = 84, -+ [0][1][RTW89_CHILE][40] = 52, -+ [0][1][RTW89_UKRAINE][40] = 16, -+ [0][1][RTW89_MEXICO][40] = 82, -+ [0][1][RTW89_CN][40] = 50, -+ [0][1][RTW89_QATAR][40] = 16, -+ [0][1][RTW89_UK][40] = 14, -+ [0][1][RTW89_FCC][42] = 82, -+ [0][1][RTW89_ETSI][42] = 16, -+ [0][1][RTW89_MKK][42] = 127, -+ [0][1][RTW89_IC][42] = 82, -+ [0][1][RTW89_KCC][42] = 30, -+ [0][1][RTW89_ACMA][42] = 84, -+ [0][1][RTW89_CHILE][42] = 54, -+ [0][1][RTW89_UKRAINE][42] = 16, -+ [0][1][RTW89_MEXICO][42] = 82, -+ [0][1][RTW89_CN][42] = 50, -+ [0][1][RTW89_QATAR][42] = 16, -+ [0][1][RTW89_UK][42] = 14, -+ [0][1][RTW89_FCC][44] = 82, -+ [0][1][RTW89_ETSI][44] = 16, -+ [0][1][RTW89_MKK][44] = 127, -+ [0][1][RTW89_IC][44] = 82, -+ [0][1][RTW89_KCC][44] = 30, -+ [0][1][RTW89_ACMA][44] = 84, -+ [0][1][RTW89_CHILE][44] = 54, -+ [0][1][RTW89_UKRAINE][44] = 16, -+ [0][1][RTW89_MEXICO][44] = 82, -+ [0][1][RTW89_CN][44] = 50, -+ [0][1][RTW89_QATAR][44] = 16, -+ [0][1][RTW89_UK][44] = 14, -+ [0][1][RTW89_FCC][46] = 82, -+ [0][1][RTW89_ETSI][46] = 16, -+ [0][1][RTW89_MKK][46] = 127, -+ [0][1][RTW89_IC][46] = 82, -+ [0][1][RTW89_KCC][46] = 30, -+ [0][1][RTW89_ACMA][46] = 84, -+ [0][1][RTW89_CHILE][46] = 54, -+ [0][1][RTW89_UKRAINE][46] = 16, -+ [0][1][RTW89_MEXICO][46] = 82, -+ [0][1][RTW89_CN][46] = 50, -+ [0][1][RTW89_QATAR][46] = 16, -+ [0][1][RTW89_UK][46] = 14, -+ [0][1][RTW89_FCC][48] = 20, -+ [0][1][RTW89_ETSI][48] = 127, -+ [0][1][RTW89_MKK][48] = 127, -+ [0][1][RTW89_IC][48] = 127, -+ [0][1][RTW89_KCC][48] = 127, -+ [0][1][RTW89_ACMA][48] = 127, -+ [0][1][RTW89_CHILE][48] = 127, -+ [0][1][RTW89_UKRAINE][48] = 127, -+ [0][1][RTW89_MEXICO][48] = 127, -+ [0][1][RTW89_CN][48] = 127, -+ [0][1][RTW89_QATAR][48] = 127, -+ [0][1][RTW89_UK][48] = 127, -+ [0][1][RTW89_FCC][50] = 20, -+ [0][1][RTW89_ETSI][50] = 127, -+ [0][1][RTW89_MKK][50] = 127, -+ [0][1][RTW89_IC][50] = 127, -+ [0][1][RTW89_KCC][50] = 127, -+ [0][1][RTW89_ACMA][50] = 127, -+ [0][1][RTW89_CHILE][50] = 127, -+ [0][1][RTW89_UKRAINE][50] = 127, -+ [0][1][RTW89_MEXICO][50] = 127, -+ [0][1][RTW89_CN][50] = 127, -+ [0][1][RTW89_QATAR][50] = 127, -+ [0][1][RTW89_UK][50] = 127, -+ [0][1][RTW89_FCC][52] = 20, -+ [0][1][RTW89_ETSI][52] = 127, -+ [0][1][RTW89_MKK][52] = 127, -+ [0][1][RTW89_IC][52] = 127, -+ [0][1][RTW89_KCC][52] = 127, -+ [0][1][RTW89_ACMA][52] = 127, -+ [0][1][RTW89_CHILE][52] = 127, -+ [0][1][RTW89_UKRAINE][52] = 127, -+ [0][1][RTW89_MEXICO][52] = 127, -+ [0][1][RTW89_CN][52] = 127, -+ [0][1][RTW89_QATAR][52] = 127, -+ [0][1][RTW89_UK][52] = 127, -+ [1][0][RTW89_FCC][0] = 62, -+ [1][0][RTW89_ETSI][0] = 34, -+ [1][0][RTW89_MKK][0] = 36, -+ [1][0][RTW89_IC][0] = 36, -+ [1][0][RTW89_KCC][0] = 52, -+ [1][0][RTW89_ACMA][0] = 34, -+ [1][0][RTW89_CHILE][0] = 40, -+ [1][0][RTW89_UKRAINE][0] = 34, -+ [1][0][RTW89_MEXICO][0] = 62, -+ [1][0][RTW89_CN][0] = 34, -+ [1][0][RTW89_QATAR][0] = 34, -+ [1][0][RTW89_UK][0] = 34, -+ [1][0][RTW89_FCC][2] = 62, -+ [1][0][RTW89_ETSI][2] = 34, -+ [1][0][RTW89_MKK][2] = 36, -+ [1][0][RTW89_IC][2] = 36, -+ [1][0][RTW89_KCC][2] = 52, -+ [1][0][RTW89_ACMA][2] = 34, -+ [1][0][RTW89_CHILE][2] = 42, -+ [1][0][RTW89_UKRAINE][2] = 34, -+ [1][0][RTW89_MEXICO][2] = 62, -+ [1][0][RTW89_CN][2] = 34, -+ [1][0][RTW89_QATAR][2] = 34, -+ [1][0][RTW89_UK][2] = 34, -+ [1][0][RTW89_FCC][4] = 62, -+ [1][0][RTW89_ETSI][4] = 34, -+ [1][0][RTW89_MKK][4] = 34, -+ [1][0][RTW89_IC][4] = 36, -+ [1][0][RTW89_KCC][4] = 52, -+ [1][0][RTW89_ACMA][4] = 34, -+ [1][0][RTW89_CHILE][4] = 42, -+ [1][0][RTW89_UKRAINE][4] = 34, -+ [1][0][RTW89_MEXICO][4] = 62, -+ [1][0][RTW89_CN][4] = 34, -+ [1][0][RTW89_QATAR][4] = 34, -+ [1][0][RTW89_UK][4] = 34, -+ [1][0][RTW89_FCC][6] = 62, -+ [1][0][RTW89_ETSI][6] = 34, -+ [1][0][RTW89_MKK][6] = 34, -+ [1][0][RTW89_IC][6] = 36, -+ [1][0][RTW89_KCC][6] = 26, -+ [1][0][RTW89_ACMA][6] = 34, -+ [1][0][RTW89_CHILE][6] = 42, -+ [1][0][RTW89_UKRAINE][6] = 34, -+ [1][0][RTW89_MEXICO][6] = 62, -+ [1][0][RTW89_CN][6] = 34, -+ [1][0][RTW89_QATAR][6] = 34, -+ [1][0][RTW89_UK][6] = 34, -+ [1][0][RTW89_FCC][8] = 62, -+ [1][0][RTW89_ETSI][8] = 34, -+ [1][0][RTW89_MKK][8] = 36, -+ [1][0][RTW89_IC][8] = 62, -+ [1][0][RTW89_KCC][8] = 54, -+ [1][0][RTW89_ACMA][8] = 34, -+ [1][0][RTW89_CHILE][8] = 64, -+ [1][0][RTW89_UKRAINE][8] = 34, -+ [1][0][RTW89_MEXICO][8] = 62, -+ [1][0][RTW89_CN][8] = 34, -+ [1][0][RTW89_QATAR][8] = 34, -+ [1][0][RTW89_UK][8] = 34, -+ [1][0][RTW89_FCC][10] = 62, -+ [1][0][RTW89_ETSI][10] = 34, -+ [1][0][RTW89_MKK][10] = 36, -+ [1][0][RTW89_IC][10] = 62, -+ [1][0][RTW89_KCC][10] = 54, -+ [1][0][RTW89_ACMA][10] = 34, -+ [1][0][RTW89_CHILE][10] = 64, -+ [1][0][RTW89_UKRAINE][10] = 34, -+ [1][0][RTW89_MEXICO][10] = 62, -+ [1][0][RTW89_CN][10] = 34, -+ [1][0][RTW89_QATAR][10] = 34, -+ [1][0][RTW89_UK][10] = 34, -+ [1][0][RTW89_FCC][12] = 64, -+ [1][0][RTW89_ETSI][12] = 34, -+ [1][0][RTW89_MKK][12] = 36, -+ [1][0][RTW89_IC][12] = 64, -+ [1][0][RTW89_KCC][12] = 54, -+ [1][0][RTW89_ACMA][12] = 34, -+ [1][0][RTW89_CHILE][12] = 64, -+ [1][0][RTW89_UKRAINE][12] = 34, -+ [1][0][RTW89_MEXICO][12] = 64, -+ [1][0][RTW89_CN][12] = 34, -+ [1][0][RTW89_QATAR][12] = 34, -+ [1][0][RTW89_UK][12] = 34, -+ [1][0][RTW89_FCC][14] = 62, -+ [1][0][RTW89_ETSI][14] = 34, -+ [1][0][RTW89_MKK][14] = 36, -+ [1][0][RTW89_IC][14] = 62, -+ [1][0][RTW89_KCC][14] = 54, -+ [1][0][RTW89_ACMA][14] = 34, -+ [1][0][RTW89_CHILE][14] = 64, -+ [1][0][RTW89_UKRAINE][14] = 34, -+ [1][0][RTW89_MEXICO][14] = 62, -+ [1][0][RTW89_CN][14] = 34, -+ [1][0][RTW89_QATAR][14] = 34, -+ [1][0][RTW89_UK][14] = 34, -+ [1][0][RTW89_FCC][15] = 62, -+ [1][0][RTW89_ETSI][15] = 34, -+ [1][0][RTW89_MKK][15] = 54, -+ [1][0][RTW89_IC][15] = 62, -+ [1][0][RTW89_KCC][15] = 54, -+ [1][0][RTW89_ACMA][15] = 34, -+ [1][0][RTW89_CHILE][15] = 62, -+ [1][0][RTW89_UKRAINE][15] = 34, -+ [1][0][RTW89_MEXICO][15] = 62, -+ [1][0][RTW89_CN][15] = 127, -+ [1][0][RTW89_QATAR][15] = 34, -+ [1][0][RTW89_UK][15] = 34, -+ [1][0][RTW89_FCC][17] = 62, -+ [1][0][RTW89_ETSI][17] = 34, -+ [1][0][RTW89_MKK][17] = 58, -+ [1][0][RTW89_IC][17] = 62, -+ [1][0][RTW89_KCC][17] = 54, -+ [1][0][RTW89_ACMA][17] = 34, -+ [1][0][RTW89_CHILE][17] = 62, -+ [1][0][RTW89_UKRAINE][17] = 34, -+ [1][0][RTW89_MEXICO][17] = 62, -+ [1][0][RTW89_CN][17] = 127, -+ [1][0][RTW89_QATAR][17] = 34, -+ [1][0][RTW89_UK][17] = 34, -+ [1][0][RTW89_FCC][19] = 62, -+ [1][0][RTW89_ETSI][19] = 34, -+ [1][0][RTW89_MKK][19] = 58, -+ [1][0][RTW89_IC][19] = 62, -+ [1][0][RTW89_KCC][19] = 54, -+ [1][0][RTW89_ACMA][19] = 34, -+ [1][0][RTW89_CHILE][19] = 62, -+ [1][0][RTW89_UKRAINE][19] = 34, -+ [1][0][RTW89_MEXICO][19] = 62, -+ [1][0][RTW89_CN][19] = 127, -+ [1][0][RTW89_QATAR][19] = 34, -+ [1][0][RTW89_UK][19] = 34, -+ [1][0][RTW89_FCC][21] = 62, -+ [1][0][RTW89_ETSI][21] = 34, -+ [1][0][RTW89_MKK][21] = 58, -+ [1][0][RTW89_IC][21] = 62, -+ [1][0][RTW89_KCC][21] = 54, -+ [1][0][RTW89_ACMA][21] = 34, -+ [1][0][RTW89_CHILE][21] = 64, -+ [1][0][RTW89_UKRAINE][21] = 34, -+ [1][0][RTW89_MEXICO][21] = 62, -+ [1][0][RTW89_CN][21] = 127, -+ [1][0][RTW89_QATAR][21] = 34, -+ [1][0][RTW89_UK][21] = 34, -+ [1][0][RTW89_FCC][23] = 62, -+ [1][0][RTW89_ETSI][23] = 34, -+ [1][0][RTW89_MKK][23] = 58, -+ [1][0][RTW89_IC][23] = 62, -+ [1][0][RTW89_KCC][23] = 54, -+ [1][0][RTW89_ACMA][23] = 34, -+ [1][0][RTW89_CHILE][23] = 64, -+ [1][0][RTW89_UKRAINE][23] = 34, -+ [1][0][RTW89_MEXICO][23] = 62, -+ [1][0][RTW89_CN][23] = 127, -+ [1][0][RTW89_QATAR][23] = 34, -+ [1][0][RTW89_UK][23] = 34, -+ [1][0][RTW89_FCC][25] = 62, -+ [1][0][RTW89_ETSI][25] = 34, -+ [1][0][RTW89_MKK][25] = 58, -+ [1][0][RTW89_IC][25] = 127, -+ [1][0][RTW89_KCC][25] = 54, -+ [1][0][RTW89_ACMA][25] = 127, -+ [1][0][RTW89_CHILE][25] = 64, -+ [1][0][RTW89_UKRAINE][25] = 34, -+ [1][0][RTW89_MEXICO][25] = 62, -+ [1][0][RTW89_CN][25] = 127, -+ [1][0][RTW89_QATAR][25] = 34, -+ [1][0][RTW89_UK][25] = 34, -+ [1][0][RTW89_FCC][27] = 62, -+ [1][0][RTW89_ETSI][27] = 34, -+ [1][0][RTW89_MKK][27] = 58, -+ [1][0][RTW89_IC][27] = 127, -+ [1][0][RTW89_KCC][27] = 54, -+ [1][0][RTW89_ACMA][27] = 127, -+ [1][0][RTW89_CHILE][27] = 64, -+ [1][0][RTW89_UKRAINE][27] = 34, -+ [1][0][RTW89_MEXICO][27] = 62, -+ [1][0][RTW89_CN][27] = 127, -+ [1][0][RTW89_QATAR][27] = 34, -+ [1][0][RTW89_UK][27] = 34, -+ [1][0][RTW89_FCC][29] = 62, -+ [1][0][RTW89_ETSI][29] = 34, -+ [1][0][RTW89_MKK][29] = 58, -+ [1][0][RTW89_IC][29] = 127, -+ [1][0][RTW89_KCC][29] = 54, -+ [1][0][RTW89_ACMA][29] = 127, -+ [1][0][RTW89_CHILE][29] = 66, -+ [1][0][RTW89_UKRAINE][29] = 34, -+ [1][0][RTW89_MEXICO][29] = 62, -+ [1][0][RTW89_CN][29] = 127, -+ [1][0][RTW89_QATAR][29] = 34, -+ [1][0][RTW89_UK][29] = 34, -+ [1][0][RTW89_FCC][31] = 62, -+ [1][0][RTW89_ETSI][31] = 34, -+ [1][0][RTW89_MKK][31] = 58, -+ [1][0][RTW89_IC][31] = 62, -+ [1][0][RTW89_KCC][31] = 54, -+ [1][0][RTW89_ACMA][31] = 34, -+ [1][0][RTW89_CHILE][31] = 66, -+ [1][0][RTW89_UKRAINE][31] = 34, -+ [1][0][RTW89_MEXICO][31] = 62, -+ [1][0][RTW89_CN][31] = 127, -+ [1][0][RTW89_QATAR][31] = 34, -+ [1][0][RTW89_UK][31] = 34, -+ [1][0][RTW89_FCC][33] = 62, -+ [1][0][RTW89_ETSI][33] = 34, -+ [1][0][RTW89_MKK][33] = 58, -+ [1][0][RTW89_IC][33] = 62, -+ [1][0][RTW89_KCC][33] = 54, -+ [1][0][RTW89_ACMA][33] = 34, -+ [1][0][RTW89_CHILE][33] = 66, -+ [1][0][RTW89_UKRAINE][33] = 34, -+ [1][0][RTW89_MEXICO][33] = 62, -+ [1][0][RTW89_CN][33] = 127, -+ [1][0][RTW89_QATAR][33] = 34, -+ [1][0][RTW89_UK][33] = 34, -+ [1][0][RTW89_FCC][35] = 62, -+ [1][0][RTW89_ETSI][35] = 34, -+ [1][0][RTW89_MKK][35] = 58, -+ [1][0][RTW89_IC][35] = 62, -+ [1][0][RTW89_KCC][35] = 54, -+ [1][0][RTW89_ACMA][35] = 34, -+ [1][0][RTW89_CHILE][35] = 66, -+ [1][0][RTW89_UKRAINE][35] = 34, -+ [1][0][RTW89_MEXICO][35] = 62, -+ [1][0][RTW89_CN][35] = 127, -+ [1][0][RTW89_QATAR][35] = 34, -+ [1][0][RTW89_UK][35] = 34, -+ [1][0][RTW89_FCC][37] = 64, -+ [1][0][RTW89_ETSI][37] = 127, -+ [1][0][RTW89_MKK][37] = 52, -+ [1][0][RTW89_IC][37] = 64, -+ [1][0][RTW89_KCC][37] = 54, -+ [1][0][RTW89_ACMA][37] = 64, -+ [1][0][RTW89_CHILE][37] = 64, -+ [1][0][RTW89_UKRAINE][37] = 127, -+ [1][0][RTW89_MEXICO][37] = 64, -+ [1][0][RTW89_CN][37] = 127, -+ [1][0][RTW89_QATAR][37] = 127, -+ [1][0][RTW89_UK][37] = 66, -+ [1][0][RTW89_FCC][38] = 84, -+ [1][0][RTW89_ETSI][38] = 28, -+ [1][0][RTW89_MKK][38] = 127, -+ [1][0][RTW89_IC][38] = 84, -+ [1][0][RTW89_KCC][38] = 56, -+ [1][0][RTW89_ACMA][38] = 84, -+ [1][0][RTW89_CHILE][38] = 64, -+ [1][0][RTW89_UKRAINE][38] = 28, -+ [1][0][RTW89_MEXICO][38] = 84, -+ [1][0][RTW89_CN][38] = 74, -+ [1][0][RTW89_QATAR][38] = 28, -+ [1][0][RTW89_UK][38] = 38, -+ [1][0][RTW89_FCC][40] = 84, -+ [1][0][RTW89_ETSI][40] = 28, -+ [1][0][RTW89_MKK][40] = 127, -+ [1][0][RTW89_IC][40] = 84, -+ [1][0][RTW89_KCC][40] = 56, -+ [1][0][RTW89_ACMA][40] = 84, -+ [1][0][RTW89_CHILE][40] = 64, -+ [1][0][RTW89_UKRAINE][40] = 28, -+ [1][0][RTW89_MEXICO][40] = 84, -+ [1][0][RTW89_CN][40] = 74, -+ [1][0][RTW89_QATAR][40] = 28, -+ [1][0][RTW89_UK][40] = 38, -+ [1][0][RTW89_FCC][42] = 84, -+ [1][0][RTW89_ETSI][42] = 28, -+ [1][0][RTW89_MKK][42] = 127, -+ [1][0][RTW89_IC][42] = 84, -+ [1][0][RTW89_KCC][42] = 56, -+ [1][0][RTW89_ACMA][42] = 84, -+ [1][0][RTW89_CHILE][42] = 64, -+ [1][0][RTW89_UKRAINE][42] = 28, -+ [1][0][RTW89_MEXICO][42] = 84, -+ [1][0][RTW89_CN][42] = 74, -+ [1][0][RTW89_QATAR][42] = 28, -+ [1][0][RTW89_UK][42] = 38, -+ [1][0][RTW89_FCC][44] = 84, -+ [1][0][RTW89_ETSI][44] = 28, -+ [1][0][RTW89_MKK][44] = 127, -+ [1][0][RTW89_IC][44] = 84, -+ [1][0][RTW89_KCC][44] = 56, -+ [1][0][RTW89_ACMA][44] = 84, -+ [1][0][RTW89_CHILE][44] = 64, -+ [1][0][RTW89_UKRAINE][44] = 28, -+ [1][0][RTW89_MEXICO][44] = 84, -+ [1][0][RTW89_CN][44] = 74, -+ [1][0][RTW89_QATAR][44] = 28, -+ [1][0][RTW89_UK][44] = 38, -+ [1][0][RTW89_FCC][46] = 84, -+ [1][0][RTW89_ETSI][46] = 28, -+ [1][0][RTW89_MKK][46] = 127, -+ [1][0][RTW89_IC][46] = 84, -+ [1][0][RTW89_KCC][46] = 56, -+ [1][0][RTW89_ACMA][46] = 84, -+ [1][0][RTW89_CHILE][46] = 64, -+ [1][0][RTW89_UKRAINE][46] = 28, -+ [1][0][RTW89_MEXICO][46] = 84, -+ [1][0][RTW89_CN][46] = 74, -+ [1][0][RTW89_QATAR][46] = 28, -+ [1][0][RTW89_UK][46] = 38, -+ [1][0][RTW89_FCC][48] = 44, -+ [1][0][RTW89_ETSI][48] = 127, -+ [1][0][RTW89_MKK][48] = 127, -+ [1][0][RTW89_IC][48] = 127, -+ [1][0][RTW89_KCC][48] = 127, -+ [1][0][RTW89_ACMA][48] = 127, -+ [1][0][RTW89_CHILE][48] = 127, -+ [1][0][RTW89_UKRAINE][48] = 127, -+ [1][0][RTW89_MEXICO][48] = 127, -+ [1][0][RTW89_CN][48] = 127, -+ [1][0][RTW89_QATAR][48] = 127, -+ [1][0][RTW89_UK][48] = 127, -+ [1][0][RTW89_FCC][50] = 44, -+ [1][0][RTW89_ETSI][50] = 127, -+ [1][0][RTW89_MKK][50] = 127, -+ [1][0][RTW89_IC][50] = 127, -+ [1][0][RTW89_KCC][50] = 127, -+ [1][0][RTW89_ACMA][50] = 127, -+ [1][0][RTW89_CHILE][50] = 127, -+ [1][0][RTW89_UKRAINE][50] = 127, -+ [1][0][RTW89_MEXICO][50] = 127, -+ [1][0][RTW89_CN][50] = 127, -+ [1][0][RTW89_QATAR][50] = 127, -+ [1][0][RTW89_UK][50] = 127, -+ [1][0][RTW89_FCC][52] = 44, -+ [1][0][RTW89_ETSI][52] = 127, -+ [1][0][RTW89_MKK][52] = 127, -+ [1][0][RTW89_IC][52] = 127, -+ [1][0][RTW89_KCC][52] = 127, -+ [1][0][RTW89_ACMA][52] = 127, -+ [1][0][RTW89_CHILE][52] = 127, -+ [1][0][RTW89_UKRAINE][52] = 127, -+ [1][0][RTW89_MEXICO][52] = 127, -+ [1][0][RTW89_CN][52] = 127, -+ [1][0][RTW89_QATAR][52] = 127, -+ [1][0][RTW89_UK][52] = 127, -+ [1][1][RTW89_FCC][0] = 42, -+ [1][1][RTW89_ETSI][0] = 22, -+ [1][1][RTW89_MKK][0] = 22, -+ [1][1][RTW89_IC][0] = 10, -+ [1][1][RTW89_KCC][0] = 36, -+ [1][1][RTW89_ACMA][0] = 22, -+ [1][1][RTW89_CHILE][0] = 22, -+ [1][1][RTW89_UKRAINE][0] = 22, -+ [1][1][RTW89_MEXICO][0] = 42, -+ [1][1][RTW89_CN][0] = 22, -+ [1][1][RTW89_QATAR][0] = 22, -+ [1][1][RTW89_UK][0] = 22, -+ [1][1][RTW89_FCC][2] = 44, -+ [1][1][RTW89_ETSI][2] = 22, -+ [1][1][RTW89_MKK][2] = 22, -+ [1][1][RTW89_IC][2] = 14, -+ [1][1][RTW89_KCC][2] = 36, -+ [1][1][RTW89_ACMA][2] = 22, -+ [1][1][RTW89_CHILE][2] = 22, -+ [1][1][RTW89_UKRAINE][2] = 22, -+ [1][1][RTW89_MEXICO][2] = 44, -+ [1][1][RTW89_CN][2] = 22, -+ [1][1][RTW89_QATAR][2] = 22, -+ [1][1][RTW89_UK][2] = 22, -+ [1][1][RTW89_FCC][4] = 42, -+ [1][1][RTW89_ETSI][4] = 22, -+ [1][1][RTW89_MKK][4] = 20, -+ [1][1][RTW89_IC][4] = 10, -+ [1][1][RTW89_KCC][4] = 36, -+ [1][1][RTW89_ACMA][4] = 22, -+ [1][1][RTW89_CHILE][4] = 20, -+ [1][1][RTW89_UKRAINE][4] = 22, -+ [1][1][RTW89_MEXICO][4] = 42, -+ [1][1][RTW89_CN][4] = 22, -+ [1][1][RTW89_QATAR][4] = 22, -+ [1][1][RTW89_UK][4] = 22, -+ [1][1][RTW89_FCC][6] = 42, -+ [1][1][RTW89_ETSI][6] = 22, -+ [1][1][RTW89_MKK][6] = 20, -+ [1][1][RTW89_IC][6] = 10, -+ [1][1][RTW89_KCC][6] = 10, -+ [1][1][RTW89_ACMA][6] = 22, -+ [1][1][RTW89_CHILE][6] = 20, -+ [1][1][RTW89_UKRAINE][6] = 22, -+ [1][1][RTW89_MEXICO][6] = 42, -+ [1][1][RTW89_CN][6] = 22, -+ [1][1][RTW89_QATAR][6] = 22, -+ [1][1][RTW89_UK][6] = 22, -+ [1][1][RTW89_FCC][8] = 44, -+ [1][1][RTW89_ETSI][8] = 22, -+ [1][1][RTW89_MKK][8] = 20, -+ [1][1][RTW89_IC][8] = 44, -+ [1][1][RTW89_KCC][8] = 36, -+ [1][1][RTW89_ACMA][8] = 22, -+ [1][1][RTW89_CHILE][8] = 54, -+ [1][1][RTW89_UKRAINE][8] = 22, -+ [1][1][RTW89_MEXICO][8] = 44, -+ [1][1][RTW89_CN][8] = 22, -+ [1][1][RTW89_QATAR][8] = 22, -+ [1][1][RTW89_UK][8] = 22, -+ [1][1][RTW89_FCC][10] = 44, -+ [1][1][RTW89_ETSI][10] = 22, -+ [1][1][RTW89_MKK][10] = 20, -+ [1][1][RTW89_IC][10] = 44, -+ [1][1][RTW89_KCC][10] = 36, -+ [1][1][RTW89_ACMA][10] = 22, -+ [1][1][RTW89_CHILE][10] = 54, -+ [1][1][RTW89_UKRAINE][10] = 22, -+ [1][1][RTW89_MEXICO][10] = 44, -+ [1][1][RTW89_CN][10] = 22, -+ [1][1][RTW89_QATAR][10] = 22, -+ [1][1][RTW89_UK][10] = 22, -+ [1][1][RTW89_FCC][12] = 46, -+ [1][1][RTW89_ETSI][12] = 22, -+ [1][1][RTW89_MKK][12] = 22, -+ [1][1][RTW89_IC][12] = 46, -+ [1][1][RTW89_KCC][12] = 40, -+ [1][1][RTW89_ACMA][12] = 22, -+ [1][1][RTW89_CHILE][12] = 52, -+ [1][1][RTW89_UKRAINE][12] = 22, -+ [1][1][RTW89_MEXICO][12] = 46, -+ [1][1][RTW89_CN][12] = 22, -+ [1][1][RTW89_QATAR][12] = 22, -+ [1][1][RTW89_UK][12] = 22, -+ [1][1][RTW89_FCC][14] = 42, -+ [1][1][RTW89_ETSI][14] = 22, -+ [1][1][RTW89_MKK][14] = 22, -+ [1][1][RTW89_IC][14] = 40, -+ [1][1][RTW89_KCC][14] = 40, -+ [1][1][RTW89_ACMA][14] = 22, -+ [1][1][RTW89_CHILE][14] = 54, -+ [1][1][RTW89_UKRAINE][14] = 22, -+ [1][1][RTW89_MEXICO][14] = 42, -+ [1][1][RTW89_CN][14] = 22, -+ [1][1][RTW89_QATAR][14] = 22, -+ [1][1][RTW89_UK][14] = 22, -+ [1][1][RTW89_FCC][15] = 42, -+ [1][1][RTW89_ETSI][15] = 22, -+ [1][1][RTW89_MKK][15] = 42, -+ [1][1][RTW89_IC][15] = 42, -+ [1][1][RTW89_KCC][15] = 38, -+ [1][1][RTW89_ACMA][15] = 22, -+ [1][1][RTW89_CHILE][15] = 54, -+ [1][1][RTW89_UKRAINE][15] = 22, -+ [1][1][RTW89_MEXICO][15] = 42, -+ [1][1][RTW89_CN][15] = 127, -+ [1][1][RTW89_QATAR][15] = 22, -+ [1][1][RTW89_UK][15] = 22, -+ [1][1][RTW89_FCC][17] = 42, -+ [1][1][RTW89_ETSI][17] = 22, -+ [1][1][RTW89_MKK][17] = 44, -+ [1][1][RTW89_IC][17] = 42, -+ [1][1][RTW89_KCC][17] = 38, -+ [1][1][RTW89_ACMA][17] = 22, -+ [1][1][RTW89_CHILE][17] = 54, -+ [1][1][RTW89_UKRAINE][17] = 22, -+ [1][1][RTW89_MEXICO][17] = 42, -+ [1][1][RTW89_CN][17] = 127, -+ [1][1][RTW89_QATAR][17] = 22, -+ [1][1][RTW89_UK][17] = 22, -+ [1][1][RTW89_FCC][19] = 42, -+ [1][1][RTW89_ETSI][19] = 22, -+ [1][1][RTW89_MKK][19] = 44, -+ [1][1][RTW89_IC][19] = 42, -+ [1][1][RTW89_KCC][19] = 38, -+ [1][1][RTW89_ACMA][19] = 22, -+ [1][1][RTW89_CHILE][19] = 54, -+ [1][1][RTW89_UKRAINE][19] = 22, -+ [1][1][RTW89_MEXICO][19] = 42, -+ [1][1][RTW89_CN][19] = 127, -+ [1][1][RTW89_QATAR][19] = 22, -+ [1][1][RTW89_UK][19] = 22, -+ [1][1][RTW89_FCC][21] = 42, -+ [1][1][RTW89_ETSI][21] = 22, -+ [1][1][RTW89_MKK][21] = 44, -+ [1][1][RTW89_IC][21] = 42, -+ [1][1][RTW89_KCC][21] = 38, -+ [1][1][RTW89_ACMA][21] = 22, -+ [1][1][RTW89_CHILE][21] = 54, -+ [1][1][RTW89_UKRAINE][21] = 22, -+ [1][1][RTW89_MEXICO][21] = 42, -+ [1][1][RTW89_CN][21] = 127, -+ [1][1][RTW89_QATAR][21] = 22, -+ [1][1][RTW89_UK][21] = 22, -+ [1][1][RTW89_FCC][23] = 42, -+ [1][1][RTW89_ETSI][23] = 22, -+ [1][1][RTW89_MKK][23] = 44, -+ [1][1][RTW89_IC][23] = 42, -+ [1][1][RTW89_KCC][23] = 38, -+ [1][1][RTW89_ACMA][23] = 22, -+ [1][1][RTW89_CHILE][23] = 54, -+ [1][1][RTW89_UKRAINE][23] = 22, -+ [1][1][RTW89_MEXICO][23] = 42, -+ [1][1][RTW89_CN][23] = 127, -+ [1][1][RTW89_QATAR][23] = 22, -+ [1][1][RTW89_UK][23] = 22, -+ [1][1][RTW89_FCC][25] = 42, -+ [1][1][RTW89_ETSI][25] = 22, -+ [1][1][RTW89_MKK][25] = 44, -+ [1][1][RTW89_IC][25] = 127, -+ [1][1][RTW89_KCC][25] = 38, -+ [1][1][RTW89_ACMA][25] = 127, -+ [1][1][RTW89_CHILE][25] = 54, -+ [1][1][RTW89_UKRAINE][25] = 22, -+ [1][1][RTW89_MEXICO][25] = 42, -+ [1][1][RTW89_CN][25] = 127, -+ [1][1][RTW89_QATAR][25] = 22, -+ [1][1][RTW89_UK][25] = 22, -+ [1][1][RTW89_FCC][27] = 42, -+ [1][1][RTW89_ETSI][27] = 22, -+ [1][1][RTW89_MKK][27] = 44, -+ [1][1][RTW89_IC][27] = 127, -+ [1][1][RTW89_KCC][27] = 38, -+ [1][1][RTW89_ACMA][27] = 127, -+ [1][1][RTW89_CHILE][27] = 54, -+ [1][1][RTW89_UKRAINE][27] = 22, -+ [1][1][RTW89_MEXICO][27] = 42, -+ [1][1][RTW89_CN][27] = 127, -+ [1][1][RTW89_QATAR][27] = 22, -+ [1][1][RTW89_UK][27] = 22, -+ [1][1][RTW89_FCC][29] = 42, -+ [1][1][RTW89_ETSI][29] = 22, -+ [1][1][RTW89_MKK][29] = 44, -+ [1][1][RTW89_IC][29] = 127, -+ [1][1][RTW89_KCC][29] = 38, -+ [1][1][RTW89_ACMA][29] = 127, -+ [1][1][RTW89_CHILE][29] = 54, -+ [1][1][RTW89_UKRAINE][29] = 22, -+ [1][1][RTW89_MEXICO][29] = 42, -+ [1][1][RTW89_CN][29] = 127, -+ [1][1][RTW89_QATAR][29] = 22, -+ [1][1][RTW89_UK][29] = 22, -+ [1][1][RTW89_FCC][31] = 42, -+ [1][1][RTW89_ETSI][31] = 22, -+ [1][1][RTW89_MKK][31] = 44, -+ [1][1][RTW89_IC][31] = 38, -+ [1][1][RTW89_KCC][31] = 38, -+ [1][1][RTW89_ACMA][31] = 22, -+ [1][1][RTW89_CHILE][31] = 54, -+ [1][1][RTW89_UKRAINE][31] = 22, -+ [1][1][RTW89_MEXICO][31] = 42, -+ [1][1][RTW89_CN][31] = 127, -+ [1][1][RTW89_QATAR][31] = 22, -+ [1][1][RTW89_UK][31] = 22, -+ [1][1][RTW89_FCC][33] = 40, -+ [1][1][RTW89_ETSI][33] = 22, -+ [1][1][RTW89_MKK][33] = 44, -+ [1][1][RTW89_IC][33] = 38, -+ [1][1][RTW89_KCC][33] = 38, -+ [1][1][RTW89_ACMA][33] = 22, -+ [1][1][RTW89_CHILE][33] = 54, -+ [1][1][RTW89_UKRAINE][33] = 22, -+ [1][1][RTW89_MEXICO][33] = 40, -+ [1][1][RTW89_CN][33] = 127, -+ [1][1][RTW89_QATAR][33] = 22, -+ [1][1][RTW89_UK][33] = 22, -+ [1][1][RTW89_FCC][35] = 40, -+ [1][1][RTW89_ETSI][35] = 22, -+ [1][1][RTW89_MKK][35] = 44, -+ [1][1][RTW89_IC][35] = 38, -+ [1][1][RTW89_KCC][35] = 38, -+ [1][1][RTW89_ACMA][35] = 22, -+ [1][1][RTW89_CHILE][35] = 54, -+ [1][1][RTW89_UKRAINE][35] = 22, -+ [1][1][RTW89_MEXICO][35] = 40, -+ [1][1][RTW89_CN][35] = 127, -+ [1][1][RTW89_QATAR][35] = 22, -+ [1][1][RTW89_UK][35] = 22, -+ [1][1][RTW89_FCC][37] = 48, -+ [1][1][RTW89_ETSI][37] = 127, -+ [1][1][RTW89_MKK][37] = 42, -+ [1][1][RTW89_IC][37] = 48, -+ [1][1][RTW89_KCC][37] = 38, -+ [1][1][RTW89_ACMA][37] = 48, -+ [1][1][RTW89_CHILE][37] = 54, -+ [1][1][RTW89_UKRAINE][37] = 127, -+ [1][1][RTW89_MEXICO][37] = 48, -+ [1][1][RTW89_CN][37] = 127, -+ [1][1][RTW89_QATAR][37] = 127, -+ [1][1][RTW89_UK][37] = 54, -+ [1][1][RTW89_FCC][38] = 84, -+ [1][1][RTW89_ETSI][38] = 16, -+ [1][1][RTW89_MKK][38] = 127, -+ [1][1][RTW89_IC][38] = 84, -+ [1][1][RTW89_KCC][38] = 38, -+ [1][1][RTW89_ACMA][38] = 82, -+ [1][1][RTW89_CHILE][38] = 54, -+ [1][1][RTW89_UKRAINE][38] = 16, -+ [1][1][RTW89_MEXICO][38] = 84, -+ [1][1][RTW89_CN][38] = 62, -+ [1][1][RTW89_QATAR][38] = 16, -+ [1][1][RTW89_UK][38] = 26, -+ [1][1][RTW89_FCC][40] = 84, -+ [1][1][RTW89_ETSI][40] = 16, -+ [1][1][RTW89_MKK][40] = 127, -+ [1][1][RTW89_IC][40] = 84, -+ [1][1][RTW89_KCC][40] = 38, -+ [1][1][RTW89_ACMA][40] = 82, -+ [1][1][RTW89_CHILE][40] = 54, -+ [1][1][RTW89_UKRAINE][40] = 16, -+ [1][1][RTW89_MEXICO][40] = 84, -+ [1][1][RTW89_CN][40] = 62, -+ [1][1][RTW89_QATAR][40] = 16, -+ [1][1][RTW89_UK][40] = 26, -+ [1][1][RTW89_FCC][42] = 84, -+ [1][1][RTW89_ETSI][42] = 16, -+ [1][1][RTW89_MKK][42] = 127, -+ [1][1][RTW89_IC][42] = 84, -+ [1][1][RTW89_KCC][42] = 38, -+ [1][1][RTW89_ACMA][42] = 84, -+ [1][1][RTW89_CHILE][42] = 54, -+ [1][1][RTW89_UKRAINE][42] = 16, -+ [1][1][RTW89_MEXICO][42] = 84, -+ [1][1][RTW89_CN][42] = 62, -+ [1][1][RTW89_QATAR][42] = 16, -+ [1][1][RTW89_UK][42] = 26, -+ [1][1][RTW89_FCC][44] = 84, -+ [1][1][RTW89_ETSI][44] = 16, -+ [1][1][RTW89_MKK][44] = 127, -+ [1][1][RTW89_IC][44] = 84, -+ [1][1][RTW89_KCC][44] = 38, -+ [1][1][RTW89_ACMA][44] = 84, -+ [1][1][RTW89_CHILE][44] = 56, -+ [1][1][RTW89_UKRAINE][44] = 16, -+ [1][1][RTW89_MEXICO][44] = 84, -+ [1][1][RTW89_CN][44] = 62, -+ [1][1][RTW89_QATAR][44] = 16, -+ [1][1][RTW89_UK][44] = 26, -+ [1][1][RTW89_FCC][46] = 84, -+ [1][1][RTW89_ETSI][46] = 16, -+ [1][1][RTW89_MKK][46] = 127, -+ [1][1][RTW89_IC][46] = 84, -+ [1][1][RTW89_KCC][46] = 38, -+ [1][1][RTW89_ACMA][46] = 84, -+ [1][1][RTW89_CHILE][46] = 56, -+ [1][1][RTW89_UKRAINE][46] = 16, -+ [1][1][RTW89_MEXICO][46] = 84, -+ [1][1][RTW89_CN][46] = 62, -+ [1][1][RTW89_QATAR][46] = 16, -+ [1][1][RTW89_UK][46] = 26, -+ [1][1][RTW89_FCC][48] = 32, -+ [1][1][RTW89_ETSI][48] = 127, -+ [1][1][RTW89_MKK][48] = 127, -+ [1][1][RTW89_IC][48] = 127, -+ [1][1][RTW89_KCC][48] = 127, -+ [1][1][RTW89_ACMA][48] = 127, -+ [1][1][RTW89_CHILE][48] = 127, -+ [1][1][RTW89_UKRAINE][48] = 127, -+ [1][1][RTW89_MEXICO][48] = 127, -+ [1][1][RTW89_CN][48] = 127, -+ [1][1][RTW89_QATAR][48] = 127, -+ [1][1][RTW89_UK][48] = 127, -+ [1][1][RTW89_FCC][50] = 32, -+ [1][1][RTW89_ETSI][50] = 127, -+ [1][1][RTW89_MKK][50] = 127, -+ [1][1][RTW89_IC][50] = 127, -+ [1][1][RTW89_KCC][50] = 127, -+ [1][1][RTW89_ACMA][50] = 127, -+ [1][1][RTW89_CHILE][50] = 127, -+ [1][1][RTW89_UKRAINE][50] = 127, -+ [1][1][RTW89_MEXICO][50] = 127, -+ [1][1][RTW89_CN][50] = 127, -+ [1][1][RTW89_QATAR][50] = 127, -+ [1][1][RTW89_UK][50] = 127, -+ [1][1][RTW89_FCC][52] = 32, -+ [1][1][RTW89_ETSI][52] = 127, -+ [1][1][RTW89_MKK][52] = 127, -+ [1][1][RTW89_IC][52] = 127, -+ [1][1][RTW89_KCC][52] = 127, -+ [1][1][RTW89_ACMA][52] = 127, -+ [1][1][RTW89_CHILE][52] = 127, -+ [1][1][RTW89_UKRAINE][52] = 127, -+ [1][1][RTW89_MEXICO][52] = 127, -+ [1][1][RTW89_CN][52] = 127, -+ [1][1][RTW89_QATAR][52] = 127, -+ [1][1][RTW89_UK][52] = 127, -+ [2][0][RTW89_FCC][0] = 70, -+ [2][0][RTW89_ETSI][0] = 48, -+ [2][0][RTW89_MKK][0] = 48, -+ [2][0][RTW89_IC][0] = 46, -+ [2][0][RTW89_KCC][0] = 66, -+ [2][0][RTW89_ACMA][0] = 48, -+ [2][0][RTW89_CHILE][0] = 44, -+ [2][0][RTW89_UKRAINE][0] = 48, -+ [2][0][RTW89_MEXICO][0] = 64, -+ [2][0][RTW89_CN][0] = 48, -+ [2][0][RTW89_QATAR][0] = 48, -+ [2][0][RTW89_UK][0] = 48, -+ [2][0][RTW89_FCC][2] = 70, -+ [2][0][RTW89_ETSI][2] = 48, -+ [2][0][RTW89_MKK][2] = 48, -+ [2][0][RTW89_IC][2] = 46, -+ [2][0][RTW89_KCC][2] = 66, -+ [2][0][RTW89_ACMA][2] = 48, -+ [2][0][RTW89_CHILE][2] = 44, -+ [2][0][RTW89_UKRAINE][2] = 48, -+ [2][0][RTW89_MEXICO][2] = 64, -+ [2][0][RTW89_CN][2] = 48, -+ [2][0][RTW89_QATAR][2] = 48, -+ [2][0][RTW89_UK][2] = 48, -+ [2][0][RTW89_FCC][4] = 70, -+ [2][0][RTW89_ETSI][4] = 48, -+ [2][0][RTW89_MKK][4] = 48, -+ [2][0][RTW89_IC][4] = 46, -+ [2][0][RTW89_KCC][4] = 66, -+ [2][0][RTW89_ACMA][4] = 48, -+ [2][0][RTW89_CHILE][4] = 44, -+ [2][0][RTW89_UKRAINE][4] = 48, -+ [2][0][RTW89_MEXICO][4] = 64, -+ [2][0][RTW89_CN][4] = 48, -+ [2][0][RTW89_QATAR][4] = 48, -+ [2][0][RTW89_UK][4] = 48, -+ [2][0][RTW89_FCC][6] = 70, -+ [2][0][RTW89_ETSI][6] = 48, -+ [2][0][RTW89_MKK][6] = 48, -+ [2][0][RTW89_IC][6] = 46, -+ [2][0][RTW89_KCC][6] = 38, -+ [2][0][RTW89_ACMA][6] = 48, -+ [2][0][RTW89_CHILE][6] = 44, -+ [2][0][RTW89_UKRAINE][6] = 48, -+ [2][0][RTW89_MEXICO][6] = 64, -+ [2][0][RTW89_CN][6] = 48, -+ [2][0][RTW89_QATAR][6] = 48, -+ [2][0][RTW89_UK][6] = 48, -+ [2][0][RTW89_FCC][8] = 70, -+ [2][0][RTW89_ETSI][8] = 48, -+ [2][0][RTW89_MKK][8] = 48, -+ [2][0][RTW89_IC][8] = 66, -+ [2][0][RTW89_KCC][8] = 64, -+ [2][0][RTW89_ACMA][8] = 48, -+ [2][0][RTW89_CHILE][8] = 66, -+ [2][0][RTW89_UKRAINE][8] = 48, -+ [2][0][RTW89_MEXICO][8] = 70, -+ [2][0][RTW89_CN][8] = 48, -+ [2][0][RTW89_QATAR][8] = 48, -+ [2][0][RTW89_UK][8] = 48, -+ [2][0][RTW89_FCC][10] = 70, -+ [2][0][RTW89_ETSI][10] = 48, -+ [2][0][RTW89_MKK][10] = 48, -+ [2][0][RTW89_IC][10] = 66, -+ [2][0][RTW89_KCC][10] = 64, -+ [2][0][RTW89_ACMA][10] = 48, -+ [2][0][RTW89_CHILE][10] = 66, -+ [2][0][RTW89_UKRAINE][10] = 48, -+ [2][0][RTW89_MEXICO][10] = 70, -+ [2][0][RTW89_CN][10] = 48, -+ [2][0][RTW89_QATAR][10] = 48, -+ [2][0][RTW89_UK][10] = 48, -+ [2][0][RTW89_FCC][12] = 70, -+ [2][0][RTW89_ETSI][12] = 48, -+ [2][0][RTW89_MKK][12] = 46, -+ [2][0][RTW89_IC][12] = 66, -+ [2][0][RTW89_KCC][12] = 64, -+ [2][0][RTW89_ACMA][12] = 48, -+ [2][0][RTW89_CHILE][12] = 66, -+ [2][0][RTW89_UKRAINE][12] = 48, -+ [2][0][RTW89_MEXICO][12] = 70, -+ [2][0][RTW89_CN][12] = 48, -+ [2][0][RTW89_QATAR][12] = 48, -+ [2][0][RTW89_UK][12] = 48, -+ [2][0][RTW89_FCC][14] = 70, -+ [2][0][RTW89_ETSI][14] = 48, -+ [2][0][RTW89_MKK][14] = 46, -+ [2][0][RTW89_IC][14] = 66, -+ [2][0][RTW89_KCC][14] = 64, -+ [2][0][RTW89_ACMA][14] = 48, -+ [2][0][RTW89_CHILE][14] = 66, -+ [2][0][RTW89_UKRAINE][14] = 48, -+ [2][0][RTW89_MEXICO][14] = 70, -+ [2][0][RTW89_CN][14] = 48, -+ [2][0][RTW89_QATAR][14] = 48, -+ [2][0][RTW89_UK][14] = 48, -+ [2][0][RTW89_FCC][15] = 70, -+ [2][0][RTW89_ETSI][15] = 48, -+ [2][0][RTW89_MKK][15] = 68, -+ [2][0][RTW89_IC][15] = 70, -+ [2][0][RTW89_KCC][15] = 64, -+ [2][0][RTW89_ACMA][15] = 48, -+ [2][0][RTW89_CHILE][15] = 62, -+ [2][0][RTW89_UKRAINE][15] = 48, -+ [2][0][RTW89_MEXICO][15] = 70, -+ [2][0][RTW89_CN][15] = 127, -+ [2][0][RTW89_QATAR][15] = 48, -+ [2][0][RTW89_UK][15] = 48, -+ [2][0][RTW89_FCC][17] = 70, -+ [2][0][RTW89_ETSI][17] = 48, -+ [2][0][RTW89_MKK][17] = 70, -+ [2][0][RTW89_IC][17] = 70, -+ [2][0][RTW89_KCC][17] = 64, -+ [2][0][RTW89_ACMA][17] = 48, -+ [2][0][RTW89_CHILE][17] = 62, -+ [2][0][RTW89_UKRAINE][17] = 48, -+ [2][0][RTW89_MEXICO][17] = 70, -+ [2][0][RTW89_CN][17] = 127, -+ [2][0][RTW89_QATAR][17] = 48, -+ [2][0][RTW89_UK][17] = 48, -+ [2][0][RTW89_FCC][19] = 70, -+ [2][0][RTW89_ETSI][19] = 48, -+ [2][0][RTW89_MKK][19] = 70, -+ [2][0][RTW89_IC][19] = 70, -+ [2][0][RTW89_KCC][19] = 64, -+ [2][0][RTW89_ACMA][19] = 48, -+ [2][0][RTW89_CHILE][19] = 62, -+ [2][0][RTW89_UKRAINE][19] = 48, -+ [2][0][RTW89_MEXICO][19] = 70, -+ [2][0][RTW89_CN][19] = 127, -+ [2][0][RTW89_QATAR][19] = 48, -+ [2][0][RTW89_UK][19] = 48, -+ [2][0][RTW89_FCC][21] = 70, -+ [2][0][RTW89_ETSI][21] = 48, -+ [2][0][RTW89_MKK][21] = 70, -+ [2][0][RTW89_IC][21] = 70, -+ [2][0][RTW89_KCC][21] = 64, -+ [2][0][RTW89_ACMA][21] = 48, -+ [2][0][RTW89_CHILE][21] = 64, -+ [2][0][RTW89_UKRAINE][21] = 48, -+ [2][0][RTW89_MEXICO][21] = 70, -+ [2][0][RTW89_CN][21] = 127, -+ [2][0][RTW89_QATAR][21] = 48, -+ [2][0][RTW89_UK][21] = 48, -+ [2][0][RTW89_FCC][23] = 70, -+ [2][0][RTW89_ETSI][23] = 48, -+ [2][0][RTW89_MKK][23] = 70, -+ [2][0][RTW89_IC][23] = 70, -+ [2][0][RTW89_KCC][23] = 64, -+ [2][0][RTW89_ACMA][23] = 48, -+ [2][0][RTW89_CHILE][23] = 64, -+ [2][0][RTW89_UKRAINE][23] = 48, -+ [2][0][RTW89_MEXICO][23] = 70, -+ [2][0][RTW89_CN][23] = 127, -+ [2][0][RTW89_QATAR][23] = 48, -+ [2][0][RTW89_UK][23] = 48, -+ [2][0][RTW89_FCC][25] = 70, -+ [2][0][RTW89_ETSI][25] = 48, -+ [2][0][RTW89_MKK][25] = 70, -+ [2][0][RTW89_IC][25] = 127, -+ [2][0][RTW89_KCC][25] = 64, -+ [2][0][RTW89_ACMA][25] = 127, -+ [2][0][RTW89_CHILE][25] = 64, -+ [2][0][RTW89_UKRAINE][25] = 48, -+ [2][0][RTW89_MEXICO][25] = 70, -+ [2][0][RTW89_CN][25] = 127, -+ [2][0][RTW89_QATAR][25] = 48, -+ [2][0][RTW89_UK][25] = 48, -+ [2][0][RTW89_FCC][27] = 70, -+ [2][0][RTW89_ETSI][27] = 48, -+ [2][0][RTW89_MKK][27] = 70, -+ [2][0][RTW89_IC][27] = 127, -+ [2][0][RTW89_KCC][27] = 64, -+ [2][0][RTW89_ACMA][27] = 127, -+ [2][0][RTW89_CHILE][27] = 64, -+ [2][0][RTW89_UKRAINE][27] = 48, -+ [2][0][RTW89_MEXICO][27] = 70, -+ [2][0][RTW89_CN][27] = 127, -+ [2][0][RTW89_QATAR][27] = 48, -+ [2][0][RTW89_UK][27] = 48, -+ [2][0][RTW89_FCC][29] = 70, -+ [2][0][RTW89_ETSI][29] = 48, -+ [2][0][RTW89_MKK][29] = 70, -+ [2][0][RTW89_IC][29] = 127, -+ [2][0][RTW89_KCC][29] = 64, -+ [2][0][RTW89_ACMA][29] = 127, -+ [2][0][RTW89_CHILE][29] = 66, -+ [2][0][RTW89_UKRAINE][29] = 48, -+ [2][0][RTW89_MEXICO][29] = 70, -+ [2][0][RTW89_CN][29] = 127, -+ [2][0][RTW89_QATAR][29] = 48, -+ [2][0][RTW89_UK][29] = 48, -+ [2][0][RTW89_FCC][31] = 70, -+ [2][0][RTW89_ETSI][31] = 48, -+ [2][0][RTW89_MKK][31] = 70, -+ [2][0][RTW89_IC][31] = 72, -+ [2][0][RTW89_KCC][31] = 64, -+ [2][0][RTW89_ACMA][31] = 48, -+ [2][0][RTW89_CHILE][31] = 66, -+ [2][0][RTW89_UKRAINE][31] = 48, -+ [2][0][RTW89_MEXICO][31] = 70, -+ [2][0][RTW89_CN][31] = 127, -+ [2][0][RTW89_QATAR][31] = 48, -+ [2][0][RTW89_UK][31] = 48, -+ [2][0][RTW89_FCC][33] = 72, -+ [2][0][RTW89_ETSI][33] = 48, -+ [2][0][RTW89_MKK][33] = 70, -+ [2][0][RTW89_IC][33] = 72, -+ [2][0][RTW89_KCC][33] = 64, -+ [2][0][RTW89_ACMA][33] = 48, -+ [2][0][RTW89_CHILE][33] = 66, -+ [2][0][RTW89_UKRAINE][33] = 48, -+ [2][0][RTW89_MEXICO][33] = 72, -+ [2][0][RTW89_CN][33] = 127, -+ [2][0][RTW89_QATAR][33] = 48, -+ [2][0][RTW89_UK][33] = 48, -+ [2][0][RTW89_FCC][35] = 72, -+ [2][0][RTW89_ETSI][35] = 48, -+ [2][0][RTW89_MKK][35] = 70, -+ [2][0][RTW89_IC][35] = 72, -+ [2][0][RTW89_KCC][35] = 64, -+ [2][0][RTW89_ACMA][35] = 48, -+ [2][0][RTW89_CHILE][35] = 66, -+ [2][0][RTW89_UKRAINE][35] = 48, -+ [2][0][RTW89_MEXICO][35] = 72, -+ [2][0][RTW89_CN][35] = 127, -+ [2][0][RTW89_QATAR][35] = 48, -+ [2][0][RTW89_UK][35] = 48, -+ [2][0][RTW89_FCC][37] = 70, -+ [2][0][RTW89_ETSI][37] = 127, -+ [2][0][RTW89_MKK][37] = 66, -+ [2][0][RTW89_IC][37] = 70, -+ [2][0][RTW89_KCC][37] = 64, -+ [2][0][RTW89_ACMA][37] = 76, -+ [2][0][RTW89_CHILE][37] = 66, -+ [2][0][RTW89_UKRAINE][37] = 127, -+ [2][0][RTW89_MEXICO][37] = 70, -+ [2][0][RTW89_CN][37] = 127, -+ [2][0][RTW89_QATAR][37] = 127, -+ [2][0][RTW89_UK][37] = 76, -+ [2][0][RTW89_FCC][38] = 84, -+ [2][0][RTW89_ETSI][38] = 28, -+ [2][0][RTW89_MKK][38] = 127, -+ [2][0][RTW89_IC][38] = 84, -+ [2][0][RTW89_KCC][38] = 66, -+ [2][0][RTW89_ACMA][38] = 84, -+ [2][0][RTW89_CHILE][38] = 64, -+ [2][0][RTW89_UKRAINE][38] = 28, -+ [2][0][RTW89_MEXICO][38] = 84, -+ [2][0][RTW89_CN][38] = 76, -+ [2][0][RTW89_QATAR][38] = 28, -+ [2][0][RTW89_UK][38] = 50, -+ [2][0][RTW89_FCC][40] = 84, -+ [2][0][RTW89_ETSI][40] = 28, -+ [2][0][RTW89_MKK][40] = 127, -+ [2][0][RTW89_IC][40] = 84, -+ [2][0][RTW89_KCC][40] = 66, -+ [2][0][RTW89_ACMA][40] = 84, -+ [2][0][RTW89_CHILE][40] = 64, -+ [2][0][RTW89_UKRAINE][40] = 28, -+ [2][0][RTW89_MEXICO][40] = 84, -+ [2][0][RTW89_CN][40] = 76, -+ [2][0][RTW89_QATAR][40] = 28, -+ [2][0][RTW89_UK][40] = 50, -+ [2][0][RTW89_FCC][42] = 84, -+ [2][0][RTW89_ETSI][42] = 28, -+ [2][0][RTW89_MKK][42] = 127, -+ [2][0][RTW89_IC][42] = 84, -+ [2][0][RTW89_KCC][42] = 66, -+ [2][0][RTW89_ACMA][42] = 84, -+ [2][0][RTW89_CHILE][42] = 66, -+ [2][0][RTW89_UKRAINE][42] = 28, -+ [2][0][RTW89_MEXICO][42] = 84, -+ [2][0][RTW89_CN][42] = 76, -+ [2][0][RTW89_QATAR][42] = 28, -+ [2][0][RTW89_UK][42] = 50, -+ [2][0][RTW89_FCC][44] = 84, -+ [2][0][RTW89_ETSI][44] = 28, -+ [2][0][RTW89_MKK][44] = 127, -+ [2][0][RTW89_IC][44] = 84, -+ [2][0][RTW89_KCC][44] = 66, -+ [2][0][RTW89_ACMA][44] = 84, -+ [2][0][RTW89_CHILE][44] = 64, -+ [2][0][RTW89_UKRAINE][44] = 28, -+ [2][0][RTW89_MEXICO][44] = 84, -+ [2][0][RTW89_CN][44] = 76, -+ [2][0][RTW89_QATAR][44] = 28, -+ [2][0][RTW89_UK][44] = 50, -+ [2][0][RTW89_FCC][46] = 84, -+ [2][0][RTW89_ETSI][46] = 28, -+ [2][0][RTW89_MKK][46] = 127, -+ [2][0][RTW89_IC][46] = 84, -+ [2][0][RTW89_KCC][46] = 66, -+ [2][0][RTW89_ACMA][46] = 84, -+ [2][0][RTW89_CHILE][46] = 64, -+ [2][0][RTW89_UKRAINE][46] = 28, -+ [2][0][RTW89_MEXICO][46] = 84, -+ [2][0][RTW89_CN][46] = 76, -+ [2][0][RTW89_QATAR][46] = 28, -+ [2][0][RTW89_UK][46] = 50, -+ [2][0][RTW89_FCC][48] = 56, -+ [2][0][RTW89_ETSI][48] = 127, -+ [2][0][RTW89_MKK][48] = 127, -+ [2][0][RTW89_IC][48] = 127, -+ [2][0][RTW89_KCC][48] = 127, -+ [2][0][RTW89_ACMA][48] = 127, -+ [2][0][RTW89_CHILE][48] = 127, -+ [2][0][RTW89_UKRAINE][48] = 127, -+ [2][0][RTW89_MEXICO][48] = 127, -+ [2][0][RTW89_CN][48] = 127, -+ [2][0][RTW89_QATAR][48] = 127, -+ [2][0][RTW89_UK][48] = 127, -+ [2][0][RTW89_FCC][50] = 56, -+ [2][0][RTW89_ETSI][50] = 127, -+ [2][0][RTW89_MKK][50] = 127, -+ [2][0][RTW89_IC][50] = 127, -+ [2][0][RTW89_KCC][50] = 127, -+ [2][0][RTW89_ACMA][50] = 127, -+ [2][0][RTW89_CHILE][50] = 127, -+ [2][0][RTW89_UKRAINE][50] = 127, -+ [2][0][RTW89_MEXICO][50] = 127, -+ [2][0][RTW89_CN][50] = 127, -+ [2][0][RTW89_QATAR][50] = 127, -+ [2][0][RTW89_UK][50] = 127, -+ [2][0][RTW89_FCC][52] = 56, -+ [2][0][RTW89_ETSI][52] = 127, -+ [2][0][RTW89_MKK][52] = 127, -+ [2][0][RTW89_IC][52] = 127, -+ [2][0][RTW89_KCC][52] = 127, -+ [2][0][RTW89_ACMA][52] = 127, -+ [2][0][RTW89_CHILE][52] = 127, -+ [2][0][RTW89_UKRAINE][52] = 127, -+ [2][0][RTW89_MEXICO][52] = 127, -+ [2][0][RTW89_CN][52] = 127, -+ [2][0][RTW89_QATAR][52] = 127, -+ [2][0][RTW89_UK][52] = 127, -+ [2][1][RTW89_FCC][0] = 50, -+ [2][1][RTW89_ETSI][0] = 36, -+ [2][1][RTW89_MKK][0] = 36, -+ [2][1][RTW89_IC][0] = 20, -+ [2][1][RTW89_KCC][0] = 46, -+ [2][1][RTW89_ACMA][0] = 36, -+ [2][1][RTW89_CHILE][0] = 32, -+ [2][1][RTW89_UKRAINE][0] = 36, -+ [2][1][RTW89_MEXICO][0] = 52, -+ [2][1][RTW89_CN][0] = 36, -+ [2][1][RTW89_QATAR][0] = 36, -+ [2][1][RTW89_UK][0] = 36, -+ [2][1][RTW89_FCC][2] = 50, -+ [2][1][RTW89_ETSI][2] = 36, -+ [2][1][RTW89_MKK][2] = 36, -+ [2][1][RTW89_IC][2] = 18, -+ [2][1][RTW89_KCC][2] = 46, -+ [2][1][RTW89_ACMA][2] = 36, -+ [2][1][RTW89_CHILE][2] = 32, -+ [2][1][RTW89_UKRAINE][2] = 36, -+ [2][1][RTW89_MEXICO][2] = 52, -+ [2][1][RTW89_CN][2] = 36, -+ [2][1][RTW89_QATAR][2] = 36, -+ [2][1][RTW89_UK][2] = 36, -+ [2][1][RTW89_FCC][4] = 50, -+ [2][1][RTW89_ETSI][4] = 36, -+ [2][1][RTW89_MKK][4] = 36, -+ [2][1][RTW89_IC][4] = 22, -+ [2][1][RTW89_KCC][4] = 46, -+ [2][1][RTW89_ACMA][4] = 36, -+ [2][1][RTW89_CHILE][4] = 30, -+ [2][1][RTW89_UKRAINE][4] = 36, -+ [2][1][RTW89_MEXICO][4] = 52, -+ [2][1][RTW89_CN][4] = 36, -+ [2][1][RTW89_QATAR][4] = 36, -+ [2][1][RTW89_UK][4] = 36, -+ [2][1][RTW89_FCC][6] = 50, -+ [2][1][RTW89_ETSI][6] = 36, -+ [2][1][RTW89_MKK][6] = 36, -+ [2][1][RTW89_IC][6] = 22, -+ [2][1][RTW89_KCC][6] = 22, -+ [2][1][RTW89_ACMA][6] = 36, -+ [2][1][RTW89_CHILE][6] = 30, -+ [2][1][RTW89_UKRAINE][6] = 36, -+ [2][1][RTW89_MEXICO][6] = 52, -+ [2][1][RTW89_CN][6] = 36, -+ [2][1][RTW89_QATAR][6] = 36, -+ [2][1][RTW89_UK][6] = 36, -+ [2][1][RTW89_FCC][8] = 50, -+ [2][1][RTW89_ETSI][8] = 36, -+ [2][1][RTW89_MKK][8] = 34, -+ [2][1][RTW89_IC][8] = 50, -+ [2][1][RTW89_KCC][8] = 48, -+ [2][1][RTW89_ACMA][8] = 36, -+ [2][1][RTW89_CHILE][8] = 54, -+ [2][1][RTW89_UKRAINE][8] = 36, -+ [2][1][RTW89_MEXICO][8] = 50, -+ [2][1][RTW89_CN][8] = 36, -+ [2][1][RTW89_QATAR][8] = 36, -+ [2][1][RTW89_UK][8] = 36, -+ [2][1][RTW89_FCC][10] = 50, -+ [2][1][RTW89_ETSI][10] = 36, -+ [2][1][RTW89_MKK][10] = 34, -+ [2][1][RTW89_IC][10] = 50, -+ [2][1][RTW89_KCC][10] = 48, -+ [2][1][RTW89_ACMA][10] = 36, -+ [2][1][RTW89_CHILE][10] = 54, -+ [2][1][RTW89_UKRAINE][10] = 36, -+ [2][1][RTW89_MEXICO][10] = 50, -+ [2][1][RTW89_CN][10] = 36, -+ [2][1][RTW89_QATAR][10] = 36, -+ [2][1][RTW89_UK][10] = 36, -+ [2][1][RTW89_FCC][12] = 52, -+ [2][1][RTW89_ETSI][12] = 36, -+ [2][1][RTW89_MKK][12] = 36, -+ [2][1][RTW89_IC][12] = 52, -+ [2][1][RTW89_KCC][12] = 48, -+ [2][1][RTW89_ACMA][12] = 36, -+ [2][1][RTW89_CHILE][12] = 54, -+ [2][1][RTW89_UKRAINE][12] = 36, -+ [2][1][RTW89_MEXICO][12] = 52, -+ [2][1][RTW89_CN][12] = 36, -+ [2][1][RTW89_QATAR][12] = 36, -+ [2][1][RTW89_UK][12] = 36, -+ [2][1][RTW89_FCC][14] = 52, -+ [2][1][RTW89_ETSI][14] = 36, -+ [2][1][RTW89_MKK][14] = 36, -+ [2][1][RTW89_IC][14] = 52, -+ [2][1][RTW89_KCC][14] = 48, -+ [2][1][RTW89_ACMA][14] = 36, -+ [2][1][RTW89_CHILE][14] = 54, -+ [2][1][RTW89_UKRAINE][14] = 36, -+ [2][1][RTW89_MEXICO][14] = 52, -+ [2][1][RTW89_CN][14] = 36, -+ [2][1][RTW89_QATAR][14] = 36, -+ [2][1][RTW89_UK][14] = 36, -+ [2][1][RTW89_FCC][15] = 50, -+ [2][1][RTW89_ETSI][15] = 36, -+ [2][1][RTW89_MKK][15] = 54, -+ [2][1][RTW89_IC][15] = 50, -+ [2][1][RTW89_KCC][15] = 48, -+ [2][1][RTW89_ACMA][15] = 36, -+ [2][1][RTW89_CHILE][15] = 56, -+ [2][1][RTW89_UKRAINE][15] = 36, -+ [2][1][RTW89_MEXICO][15] = 50, -+ [2][1][RTW89_CN][15] = 127, -+ [2][1][RTW89_QATAR][15] = 36, -+ [2][1][RTW89_UK][15] = 36, -+ [2][1][RTW89_FCC][17] = 50, -+ [2][1][RTW89_ETSI][17] = 36, -+ [2][1][RTW89_MKK][17] = 56, -+ [2][1][RTW89_IC][17] = 50, -+ [2][1][RTW89_KCC][17] = 48, -+ [2][1][RTW89_ACMA][17] = 36, -+ [2][1][RTW89_CHILE][17] = 56, -+ [2][1][RTW89_UKRAINE][17] = 36, -+ [2][1][RTW89_MEXICO][17] = 50, -+ [2][1][RTW89_CN][17] = 127, -+ [2][1][RTW89_QATAR][17] = 36, -+ [2][1][RTW89_UK][17] = 36, -+ [2][1][RTW89_FCC][19] = 50, -+ [2][1][RTW89_ETSI][19] = 36, -+ [2][1][RTW89_MKK][19] = 56, -+ [2][1][RTW89_IC][19] = 50, -+ [2][1][RTW89_KCC][19] = 48, -+ [2][1][RTW89_ACMA][19] = 36, -+ [2][1][RTW89_CHILE][19] = 56, -+ [2][1][RTW89_UKRAINE][19] = 36, -+ [2][1][RTW89_MEXICO][19] = 50, -+ [2][1][RTW89_CN][19] = 127, -+ [2][1][RTW89_QATAR][19] = 36, -+ [2][1][RTW89_UK][19] = 36, -+ [2][1][RTW89_FCC][21] = 50, -+ [2][1][RTW89_ETSI][21] = 36, -+ [2][1][RTW89_MKK][21] = 56, -+ [2][1][RTW89_IC][21] = 50, -+ [2][1][RTW89_KCC][21] = 48, -+ [2][1][RTW89_ACMA][21] = 36, -+ [2][1][RTW89_CHILE][21] = 58, -+ [2][1][RTW89_UKRAINE][21] = 36, -+ [2][1][RTW89_MEXICO][21] = 50, -+ [2][1][RTW89_CN][21] = 127, -+ [2][1][RTW89_QATAR][21] = 36, -+ [2][1][RTW89_UK][21] = 36, -+ [2][1][RTW89_FCC][23] = 50, -+ [2][1][RTW89_ETSI][23] = 36, -+ [2][1][RTW89_MKK][23] = 56, -+ [2][1][RTW89_IC][23] = 50, -+ [2][1][RTW89_KCC][23] = 48, -+ [2][1][RTW89_ACMA][23] = 36, -+ [2][1][RTW89_CHILE][23] = 58, -+ [2][1][RTW89_UKRAINE][23] = 36, -+ [2][1][RTW89_MEXICO][23] = 50, -+ [2][1][RTW89_CN][23] = 127, -+ [2][1][RTW89_QATAR][23] = 36, -+ [2][1][RTW89_UK][23] = 36, -+ [2][1][RTW89_FCC][25] = 50, -+ [2][1][RTW89_ETSI][25] = 36, -+ [2][1][RTW89_MKK][25] = 56, -+ [2][1][RTW89_IC][25] = 127, -+ [2][1][RTW89_KCC][25] = 48, -+ [2][1][RTW89_ACMA][25] = 127, -+ [2][1][RTW89_CHILE][25] = 58, -+ [2][1][RTW89_UKRAINE][25] = 36, -+ [2][1][RTW89_MEXICO][25] = 50, -+ [2][1][RTW89_CN][25] = 127, -+ [2][1][RTW89_QATAR][25] = 36, -+ [2][1][RTW89_UK][25] = 36, -+ [2][1][RTW89_FCC][27] = 50, -+ [2][1][RTW89_ETSI][27] = 36, -+ [2][1][RTW89_MKK][27] = 56, -+ [2][1][RTW89_IC][27] = 127, -+ [2][1][RTW89_KCC][27] = 48, -+ [2][1][RTW89_ACMA][27] = 127, -+ [2][1][RTW89_CHILE][27] = 58, -+ [2][1][RTW89_UKRAINE][27] = 36, -+ [2][1][RTW89_MEXICO][27] = 50, -+ [2][1][RTW89_CN][27] = 127, -+ [2][1][RTW89_QATAR][27] = 36, -+ [2][1][RTW89_UK][27] = 36, -+ [2][1][RTW89_FCC][29] = 50, -+ [2][1][RTW89_ETSI][29] = 36, -+ [2][1][RTW89_MKK][29] = 56, -+ [2][1][RTW89_IC][29] = 127, -+ [2][1][RTW89_KCC][29] = 48, -+ [2][1][RTW89_ACMA][29] = 127, -+ [2][1][RTW89_CHILE][29] = 56, -+ [2][1][RTW89_UKRAINE][29] = 36, -+ [2][1][RTW89_MEXICO][29] = 50, -+ [2][1][RTW89_CN][29] = 127, -+ [2][1][RTW89_QATAR][29] = 36, -+ [2][1][RTW89_UK][29] = 36, -+ [2][1][RTW89_FCC][31] = 50, -+ [2][1][RTW89_ETSI][31] = 36, -+ [2][1][RTW89_MKK][31] = 56, -+ [2][1][RTW89_IC][31] = 50, -+ [2][1][RTW89_KCC][31] = 48, -+ [2][1][RTW89_ACMA][31] = 36, -+ [2][1][RTW89_CHILE][31] = 56, -+ [2][1][RTW89_UKRAINE][31] = 36, -+ [2][1][RTW89_MEXICO][31] = 50, -+ [2][1][RTW89_CN][31] = 127, -+ [2][1][RTW89_QATAR][31] = 36, -+ [2][1][RTW89_UK][31] = 36, -+ [2][1][RTW89_FCC][33] = 50, -+ [2][1][RTW89_ETSI][33] = 36, -+ [2][1][RTW89_MKK][33] = 56, -+ [2][1][RTW89_IC][33] = 50, -+ [2][1][RTW89_KCC][33] = 48, -+ [2][1][RTW89_ACMA][33] = 36, -+ [2][1][RTW89_CHILE][33] = 56, -+ [2][1][RTW89_UKRAINE][33] = 36, -+ [2][1][RTW89_MEXICO][33] = 50, -+ [2][1][RTW89_CN][33] = 127, -+ [2][1][RTW89_QATAR][33] = 36, -+ [2][1][RTW89_UK][33] = 36, -+ [2][1][RTW89_FCC][35] = 50, -+ [2][1][RTW89_ETSI][35] = 36, -+ [2][1][RTW89_MKK][35] = 56, -+ [2][1][RTW89_IC][35] = 50, -+ [2][1][RTW89_KCC][35] = 48, -+ [2][1][RTW89_ACMA][35] = 36, -+ [2][1][RTW89_CHILE][35] = 56, -+ [2][1][RTW89_UKRAINE][35] = 36, -+ [2][1][RTW89_MEXICO][35] = 50, -+ [2][1][RTW89_CN][35] = 127, -+ [2][1][RTW89_QATAR][35] = 36, -+ [2][1][RTW89_UK][35] = 36, -+ [2][1][RTW89_FCC][37] = 50, -+ [2][1][RTW89_ETSI][37] = 127, -+ [2][1][RTW89_MKK][37] = 54, -+ [2][1][RTW89_IC][37] = 50, -+ [2][1][RTW89_KCC][37] = 48, -+ [2][1][RTW89_ACMA][37] = 60, -+ [2][1][RTW89_CHILE][37] = 56, -+ [2][1][RTW89_UKRAINE][37] = 127, -+ [2][1][RTW89_MEXICO][37] = 50, -+ [2][1][RTW89_CN][37] = 127, -+ [2][1][RTW89_QATAR][37] = 127, -+ [2][1][RTW89_UK][37] = 66, -+ [2][1][RTW89_FCC][38] = 84, -+ [2][1][RTW89_ETSI][38] = 16, -+ [2][1][RTW89_MKK][38] = 127, -+ [2][1][RTW89_IC][38] = 84, -+ [2][1][RTW89_KCC][38] = 48, -+ [2][1][RTW89_ACMA][38] = 84, -+ [2][1][RTW89_CHILE][38] = 58, -+ [2][1][RTW89_UKRAINE][38] = 16, -+ [2][1][RTW89_MEXICO][38] = 84, -+ [2][1][RTW89_CN][38] = 64, -+ [2][1][RTW89_QATAR][38] = 16, -+ [2][1][RTW89_UK][38] = 38, -+ [2][1][RTW89_FCC][40] = 84, -+ [2][1][RTW89_ETSI][40] = 16, -+ [2][1][RTW89_MKK][40] = 127, -+ [2][1][RTW89_IC][40] = 84, -+ [2][1][RTW89_KCC][40] = 48, -+ [2][1][RTW89_ACMA][40] = 84, -+ [2][1][RTW89_CHILE][40] = 58, -+ [2][1][RTW89_UKRAINE][40] = 16, -+ [2][1][RTW89_MEXICO][40] = 84, -+ [2][1][RTW89_CN][40] = 64, -+ [2][1][RTW89_QATAR][40] = 16, -+ [2][1][RTW89_UK][40] = 38, -+ [2][1][RTW89_FCC][42] = 84, -+ [2][1][RTW89_ETSI][42] = 16, -+ [2][1][RTW89_MKK][42] = 127, -+ [2][1][RTW89_IC][42] = 84, -+ [2][1][RTW89_KCC][42] = 48, -+ [2][1][RTW89_ACMA][42] = 84, -+ [2][1][RTW89_CHILE][42] = 58, -+ [2][1][RTW89_UKRAINE][42] = 16, -+ [2][1][RTW89_MEXICO][42] = 84, -+ [2][1][RTW89_CN][42] = 64, -+ [2][1][RTW89_QATAR][42] = 16, -+ [2][1][RTW89_UK][42] = 38, -+ [2][1][RTW89_FCC][44] = 84, -+ [2][1][RTW89_ETSI][44] = 16, -+ [2][1][RTW89_MKK][44] = 127, -+ [2][1][RTW89_IC][44] = 84, -+ [2][1][RTW89_KCC][44] = 48, -+ [2][1][RTW89_ACMA][44] = 84, -+ [2][1][RTW89_CHILE][44] = 58, -+ [2][1][RTW89_UKRAINE][44] = 16, -+ [2][1][RTW89_MEXICO][44] = 84, -+ [2][1][RTW89_CN][44] = 64, -+ [2][1][RTW89_QATAR][44] = 16, -+ [2][1][RTW89_UK][44] = 38, -+ [2][1][RTW89_FCC][46] = 84, -+ [2][1][RTW89_ETSI][46] = 16, -+ [2][1][RTW89_MKK][46] = 127, -+ [2][1][RTW89_IC][46] = 84, -+ [2][1][RTW89_KCC][46] = 48, -+ [2][1][RTW89_ACMA][46] = 84, -+ [2][1][RTW89_CHILE][46] = 58, -+ [2][1][RTW89_UKRAINE][46] = 16, -+ [2][1][RTW89_MEXICO][46] = 84, -+ [2][1][RTW89_CN][46] = 64, -+ [2][1][RTW89_QATAR][46] = 16, -+ [2][1][RTW89_UK][46] = 38, -+ [2][1][RTW89_FCC][48] = 44, -+ [2][1][RTW89_ETSI][48] = 127, -+ [2][1][RTW89_MKK][48] = 127, -+ [2][1][RTW89_IC][48] = 127, -+ [2][1][RTW89_KCC][48] = 127, -+ [2][1][RTW89_ACMA][48] = 127, -+ [2][1][RTW89_CHILE][48] = 127, -+ [2][1][RTW89_UKRAINE][48] = 127, -+ [2][1][RTW89_MEXICO][48] = 127, -+ [2][1][RTW89_CN][48] = 127, -+ [2][1][RTW89_QATAR][48] = 127, -+ [2][1][RTW89_UK][48] = 127, -+ [2][1][RTW89_FCC][50] = 44, -+ [2][1][RTW89_ETSI][50] = 127, -+ [2][1][RTW89_MKK][50] = 127, -+ [2][1][RTW89_IC][50] = 127, -+ [2][1][RTW89_KCC][50] = 127, -+ [2][1][RTW89_ACMA][50] = 127, -+ [2][1][RTW89_CHILE][50] = 127, -+ [2][1][RTW89_UKRAINE][50] = 127, -+ [2][1][RTW89_MEXICO][50] = 127, -+ [2][1][RTW89_CN][50] = 127, -+ [2][1][RTW89_QATAR][50] = 127, -+ [2][1][RTW89_UK][50] = 127, -+ [2][1][RTW89_FCC][52] = 44, -+ [2][1][RTW89_ETSI][52] = 127, -+ [2][1][RTW89_MKK][52] = 127, -+ [2][1][RTW89_IC][52] = 127, -+ [2][1][RTW89_KCC][52] = 127, -+ [2][1][RTW89_ACMA][52] = 127, -+ [2][1][RTW89_CHILE][52] = 127, -+ [2][1][RTW89_UKRAINE][52] = 127, -+ [2][1][RTW89_MEXICO][52] = 127, -+ [2][1][RTW89_CN][52] = 127, -+ [2][1][RTW89_QATAR][52] = 127, -+ [2][1][RTW89_UK][52] = 127, -+}; -+ -+const struct rtw89_phy_table rtw89_8852b_phy_bb_table = { -+ .regs = rtw89_8852b_phy_bb_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8852b_phy_bb_regs), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table = { -+ .regs = rtw89_8852b_phy_bb_reg_gain, -+ .n_regs = ARRAY_SIZE(rtw89_8852b_phy_bb_reg_gain), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_phy_table rtw89_8852b_phy_radioa_table = { -+ .regs = rtw89_8852b_phy_radioa_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8852b_phy_radioa_regs), -+ .rf_path = RF_PATH_A, -+ .config = rtw89_phy_config_rf_reg_v1, -+}; -+ -+const struct rtw89_phy_table rtw89_8852b_phy_radiob_table = { -+ .regs = rtw89_8852b_phy_radiob_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8852b_phy_radiob_regs), -+ .rf_path = RF_PATH_B, -+ .config = rtw89_phy_config_rf_reg_v1, -+}; -+ -+const struct rtw89_phy_table rtw89_8852b_phy_nctl_table = { -+ .regs = rtw89_8852b_phy_nctl_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8852b_phy_nctl_regs), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_txpwr_table rtw89_8852b_byr_table = { -+ .data = rtw89_8852b_txpwr_byrate, -+ .size = ARRAY_SIZE(rtw89_8852b_txpwr_byrate), -+ .load = rtw89_phy_load_txpwr_byrate, -+}; -+ -+const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg = { -+ .delta_swingidx_5gb_n = _txpwr_track_delta_swingidx_5gb_n, -+ .delta_swingidx_5gb_p = _txpwr_track_delta_swingidx_5gb_p, -+ .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, -+ .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, -+ .delta_swingidx_2gb_n = _txpwr_track_delta_swingidx_2gb_n, -+ .delta_swingidx_2gb_p = _txpwr_track_delta_swingidx_2gb_p, -+ .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, -+ .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, -+ .delta_swingidx_2g_cck_b_n = _txpwr_track_delta_swingidx_2g_cck_b_n, -+ .delta_swingidx_2g_cck_b_p = _txpwr_track_delta_swingidx_2g_cck_b_p, -+ .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, -+ .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, -+}; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-003-wifi-rtw89-8852b-add-tables-for-RFK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-003-wifi-rtw89-8852b-add-tables-for-RFK.patch deleted file mode 100644 index 05dd92c5d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-003-wifi-rtw89-8852b-add-tables-for-RFK.patch +++ /dev/null @@ -1,879 +0,0 @@ -From 2b379eb443e2a4bd6fb2cbd300e12aeff45cff57 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:30 +0800 -Subject: [PATCH 003/149] wifi: rtw89: 8852b: add tables for RFK - -These tables are used by RFK to assist to configure PHY and RF registers. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-4-pkshih@realtek.com ---- - .../realtek/rtw89/rtw8852b_rfk_table.c | 794 ++++++++++++++++++ - .../realtek/rtw89/rtw8852b_rfk_table.h | 62 ++ - 2 files changed, 856 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c -@@ -0,0 +1,794 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2019-2020 Realtek Corporation -+ */ -+ -+#include "rtw8852b_rfk_table.h" -+ -+static const struct rtw89_reg5_def rtw8852b_afe_init_defs[] = { -+ RTW89_DECL_RFK_WM(0xC0D4, 0xffffffff, 0x4486888c), -+ RTW89_DECL_RFK_WM(0xC0D8, 0xffffffff, 0xc6ba10e0), -+ RTW89_DECL_RFK_WM(0xc0dc, 0xffffffff, 0x30c52868), -+ RTW89_DECL_RFK_WM(0xc0e0, 0xffffffff, 0x05008128), -+ RTW89_DECL_RFK_WM(0xc0e4, 0xffffffff, 0x0000272b), -+ RTW89_DECL_RFK_WM(0xC1D4, 0xffffffff, 0x4486888c), -+ RTW89_DECL_RFK_WM(0xC1D8, 0xffffffff, 0xc6ba10e0), -+ RTW89_DECL_RFK_WM(0xc1dc, 0xffffffff, 0x30c52868), -+ RTW89_DECL_RFK_WM(0xc1e0, 0xffffffff, 0x05008128), -+ RTW89_DECL_RFK_WM(0xc1e4, 0xffffffff, 0x0000272b), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_afe_init_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_check_addc_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0), -+ RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1), -+ RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2), -+ RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0), -+ RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x2), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_check_addc_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0), -+ RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1), -+ RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2), -+ RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0), -+ RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x3), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf), -+ RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3), -+ RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0), -+ RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x1), -+ RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x1), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf), -+ RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3), -+ RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0), -+ RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x1), -+ RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x1), -+ RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x0), -+ RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x0), -+ RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s0_1_defs[] = { -+ RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x1), -+ RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x3), -+ RTW89_DECL_RFK_WM(0x12B8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1), -+ RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x1), -+ RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x3), -+ RTW89_DECL_RFK_WM(0xC004, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0xc024, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0xC004, 0x3ff00000, 0x30), -+ RTW89_DECL_RFK_WM(0xC004, 0xc0000000, 0x0), -+ RTW89_DECL_RFK_WM(0xC004, BIT(17), 0x1), -+ RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1), -+ RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x1), -+ RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x1), -+ RTW89_DECL_RFK_DELAY(1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_1_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s0_2_defs[] = { -+ RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x1), -+ RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_2_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s0_3_defs[] = { -+ RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x0), -+ RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x0), -+ RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x7), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_3_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s1_1_defs[] = { -+ RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x1), -+ RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x3), -+ RTW89_DECL_RFK_WM(0x32B8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1), -+ RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x1), -+ RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x3), -+ RTW89_DECL_RFK_WM(0xc104, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0xc124, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0xc104, 0x3ff00000, 0x30), -+ RTW89_DECL_RFK_WM(0xc104, 0xc0000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1), -+ RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1), -+ RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x1), -+ RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x1), -+ RTW89_DECL_RFK_DELAY(1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_1_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s1_2_defs[] = { -+ RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x1), -+ RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x1), -+ RTW89_DECL_RFK_DELAY(1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_2_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dack_s1_3_defs[] = { -+ RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x0), -+ RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x0), -+ RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x7), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_3_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dpk_afe_defs[] = { -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(28), 0x1), -+ RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x1), -+ RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x1), -+ RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x3), -+ RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x3), -+ RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x1ffffff), -+ RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x1), -+ RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x1), -+ RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x3ff), -+ RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3), -+ RTW89_DECL_RFK_WM(0x0c6c, BIT(0), 0x1), -+ RTW89_DECL_RFK_WM(0x58ac, BIT(27), 0x1), -+ RTW89_DECL_RFK_WM(0x78ac, BIT(27), 0x1), -+ RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x1), -+ RTW89_DECL_RFK_WM(0x2344, BIT(31), 0x1), -+ RTW89_DECL_RFK_WM(0x4490, BIT(31), 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0xbf), -+ RTW89_DECL_RFK_WM(0x32a0, 0x000f0000, 0xb), -+ RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x5), -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x3333), -+ RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x1), -+ RTW89_DECL_RFK_WM(0x5800, 0x0000ffff, 0x0000), -+ RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x1), -+ RTW89_DECL_RFK_WM(0x7800, 0x0000ffff, 0x0000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dpk_afe_restore_defs[] = { -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x0), -+ RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x0), -+ RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x0), -+ RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x63), -+ RTW89_DECL_RFK_WM(0x12a0, 0x000FF000, 0x00), -+ RTW89_DECL_RFK_WM(0x32a0, 0x000FF000, 0x00), -+ RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5864, BIT(29), 0x0), -+ RTW89_DECL_RFK_WM(0x7864, BIT(29), 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0000), -+ RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x0), -+ RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x0), -+ RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x0), -+ RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x0), -+ RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x1), -+ RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x2), -+ RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x0), -+ RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x1), -+ RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x2), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_restore_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_dpk_kip_defs[] = { -+ RTW89_DECL_RFK_WM(0x8008, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x8088, 0xffffffff, 0x80000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_kip_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_sys_defs[] = { -+ RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x5), -+ RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x5), -+ RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0x5555), -+ RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0x5555), -+ RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), -+ RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x19), -+ RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), -+ RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x2041), -+ RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), -+ RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), -+ RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), -+ RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), -+ RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), -+ RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), -+ RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), -+ RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), -+ RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), -+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), -+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_sys_a_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), -+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), -+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), -+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_a_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33), -+ RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33), -+ RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_sys_b_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44), -+ RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44), -+ RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0), -+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_sys_b_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), -+ RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), -+ RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), -+ RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), -+ RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), -+ RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x002d000), -+ RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), -+ RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800), -+ RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x1dc80280), -+ RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00002080), -+ RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), -+ RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), -+ RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), -+ RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), -+ RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), -+ RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), -+ RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), -+ RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), -+ RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), -+ RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), -+ RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), -+ RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), -+ RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), -+ RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), -+ RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), -+ RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800), -+ RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), -+ RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), -+ RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f), -+ RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40), -+ RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040), -+ RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000), -+ RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x002d000), -+ RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00), -+ RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800), -+ RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x1dc80280), -+ RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00002080), -+ RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1), -+ RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff), -+ RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16), -+ RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000), -+ RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628), -+ RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f), -+ RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f), -+ RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff), -+ RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000), -+ RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101), -+ RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00), -+ RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff), -+ RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100), -+ RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c), -+ RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f), -+ RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0x800), -+ RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff), -+ RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe), -+ RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_init_txpwr_he_tb_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe), -+ RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_he_tb_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x0ef), -+ RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_dck_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000), -+ RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x0ef), -+ RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dck_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x58b0, 0x00000400, 0x1), -+ RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000), -+ RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x1), -+ RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_dac_gain_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x000), -+ RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x1), -+ RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_dac_gain_defs_b); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0801008), -+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020), -+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0804008), -+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), -+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e28), -+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08081e28), -+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020), -+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), -+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e08), -+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_a_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0801008), -+ RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020), -+ RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0804008), -+ RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), -+ RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e28), -+ RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08081e28), -+ RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020), -+ RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008), -+ RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e08), -+ RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_b_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075), -+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e), -+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f), -+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), -+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), -+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee), -+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078), -+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072), -+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_all_defs[] = { -+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721), -+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101), -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_all_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_part_defs[] = { -+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da), -+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069), -+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_part_defs); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), -+ RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_a); -+ -+static const struct rtw89_reg5_def rtw8852b_tssi_slope_defs_b[] = { -+ RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1), -+ RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1), -+ RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_slope_defs_b); ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2019-2020 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8852B_RFK_TABLE_H__ -+#define __RTW89_8852B_RFK_TABLE_H__ -+ -+#include "phy.h" -+ -+extern const struct rtw89_rfk_tbl rtw8852b_afe_init_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_1_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_2_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_3_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_1_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_2_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_3_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_restore_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_dpk_kip_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_b_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_all_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_part_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_b_tbl; -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch deleted file mode 100644 index fe748f31d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch +++ /dev/null @@ -1,669 +0,0 @@ -From 9b43bd1ac0a8e29b678768f93645cc1b39571278 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 28 Sep 2022 16:43:31 +0800 -Subject: [PATCH 004/149] wifi: rtw89: phy: make generic txpwr setting - functions - -Previously, we thought control registers or setting things for TX power -series may change according to chip. So, setting functions are implemented -chip by chip. However, until now, the functions keep the same among chips, -at least 8852A, 8852C, and 8852B. There is a sufficient number of chips to -share generic setting functions. So, we now remake them including TX power -by rate, TX power offset, TX power limit, and TX power limit RU as generic -ones in phy.c. - -Besides, there are some code refinements in the generic ones, but almost -all of the logic doesn't change. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 4 + - drivers/net/wireless/realtek/rtw89/phy.c | 167 +++++++++++++++++- - drivers/net/wireless/realtek/rtw89/phy.h | 25 ++- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 145 +-------------- - drivers/net/wireless/realtek/rtw89/rtw8852a.h | 1 - - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 145 +-------------- - drivers/net/wireless/realtek/rtw89/rtw8852c.h | 1 - - 7 files changed, 184 insertions(+), 304 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -490,6 +490,8 @@ enum rtw89_bandwidth_section_num { - RTW89_BW80_SEC_NUM = 2, - }; - -+#define RTW89_TXPWR_LMT_PAGE_SIZE 40 -+ - struct rtw89_txpwr_limit { - s8 cck_20m[RTW89_BF_NUM]; - s8 cck_40m[RTW89_BF_NUM]; -@@ -504,6 +506,8 @@ struct rtw89_txpwr_limit { - - #define RTW89_RU_SEC_NUM 8 - -+#define RTW89_TXPWR_LMT_RU_PAGE_SIZE 24 -+ - struct rtw89_txpwr_limit_ru { - s8 ru26[RTW89_RU_SEC_NUM]; - s8 ru52[RTW89_RU_SEC_NUM]; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1443,23 +1443,21 @@ void rtw89_phy_write_reg3_tbl(struct rtw - } - EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl); - --const u8 rtw89_rs_idx_max[] = { -+static const u8 rtw89_rs_idx_max[] = { - [RTW89_RS_CCK] = RTW89_RATE_CCK_MAX, - [RTW89_RS_OFDM] = RTW89_RATE_OFDM_MAX, - [RTW89_RS_MCS] = RTW89_RATE_MCS_MAX, - [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_MAX, - [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_MAX, - }; --EXPORT_SYMBOL(rtw89_rs_idx_max); - --const u8 rtw89_rs_nss_max[] = { -+static const u8 rtw89_rs_nss_max[] = { - [RTW89_RS_CCK] = 1, - [RTW89_RS_OFDM] = 1, - [RTW89_RS_MCS] = RTW89_NSS_MAX, - [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_MAX, - [RTW89_RS_OFFSET] = 1, - }; --EXPORT_SYMBOL(rtw89_rs_nss_max); - - static const u8 _byr_of_rs[] = { - [RTW89_RS_CCK] = offsetof(struct rtw89_txpwr_byrate, cck), -@@ -1501,6 +1499,7 @@ EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrat - (txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \ - }) - -+static - s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, - const struct rtw89_rate_desc *rate_desc) - { -@@ -1523,7 +1522,6 @@ s8 rtw89_phy_read_txpwr_byrate(struct rt - - return _phy_txpwr_rf_to_mac(rtwdev, byr[idx]); - } --EXPORT_SYMBOL(rtw89_phy_read_txpwr_byrate); - - static u8 rtw89_channel_6g_to_idx(struct rtw89_dev *rtwdev, u8 channel_6g) - { -@@ -1783,6 +1781,7 @@ static void rtw89_phy_fill_txpwr_limit_1 - lmt->mcs_40m_2p5[i] = min_t(s8, val_2p5_n[i], val_2p5_p[i]); - } - -+static - void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - struct rtw89_txpwr_limit *lmt, -@@ -1813,7 +1812,6 @@ void rtw89_phy_fill_txpwr_limit(struct r - break; - } - } --EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit); - - static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, - u8 ru, u8 ntx, u8 ch) -@@ -1962,6 +1960,7 @@ rtw89_phy_fill_txpwr_limit_ru_160m(struc - } - } - -+static - void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - struct rtw89_txpwr_limit_ru *lmt_ru, -@@ -1992,7 +1991,161 @@ void rtw89_phy_fill_txpwr_limit_ru(struc - break; - } - } --EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit_ru); -+ -+void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ static const u8 rs[] = { -+ RTW89_RS_CCK, -+ RTW89_RS_OFDM, -+ RTW89_RS_MCS, -+ RTW89_RS_HEDCM, -+ }; -+ struct rtw89_rate_desc cur; -+ u8 band = chan->band_type; -+ u8 ch = chan->channel; -+ u32 addr, val; -+ s8 v[4] = {}; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "[TXPWR] set txpwr byrate with ch=%d\n", ch); -+ -+ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_CCK] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_OFDM] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_MCS] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); -+ -+ addr = R_AX_PWR_BY_RATE; -+ for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { -+ for (i = 0; i < ARRAY_SIZE(rs); i++) { -+ if (cur.nss >= rtw89_rs_nss_max[rs[i]]) -+ continue; -+ -+ cur.rs = rs[i]; -+ for (cur.idx = 0; cur.idx < rtw89_rs_idx_max[rs[i]]; -+ cur.idx++) { -+ v[cur.idx % 4] = -+ rtw89_phy_read_txpwr_byrate(rtwdev, -+ band, -+ &cur); -+ -+ if ((cur.idx + 1) % 4) -+ continue; -+ -+ val = FIELD_PREP(GENMASK(7, 0), v[0]) | -+ FIELD_PREP(GENMASK(15, 8), v[1]) | -+ FIELD_PREP(GENMASK(23, 16), v[2]) | -+ FIELD_PREP(GENMASK(31, 24), v[3]); -+ -+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, -+ val); -+ addr += 4; -+ } -+ } -+ } -+} -+EXPORT_SYMBOL(rtw89_phy_set_txpwr_byrate); -+ -+void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ struct rtw89_rate_desc desc = { -+ .nss = RTW89_NSS_1, -+ .rs = RTW89_RS_OFFSET, -+ }; -+ u8 band = chan->band_type; -+ s8 v[RTW89_RATE_OFFSET_MAX] = {}; -+ u32 val; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); -+ -+ for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) -+ v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); -+ -+ BUILD_BUG_ON(RTW89_RATE_OFFSET_MAX != 5); -+ val = FIELD_PREP(GENMASK(3, 0), v[0]) | -+ FIELD_PREP(GENMASK(7, 4), v[1]) | -+ FIELD_PREP(GENMASK(11, 8), v[2]) | -+ FIELD_PREP(GENMASK(15, 12), v[3]) | -+ FIELD_PREP(GENMASK(19, 16), v[4]); -+ -+ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, -+ GENMASK(19, 0), val); -+} -+EXPORT_SYMBOL(rtw89_phy_set_txpwr_offset); -+ -+void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ struct rtw89_txpwr_limit lmt; -+ u8 ch = chan->channel; -+ u8 bw = chan->band_width; -+ const s8 *ptr; -+ u32 addr, val; -+ u8 i, j; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); -+ -+ BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit) != -+ RTW89_TXPWR_LMT_PAGE_SIZE); -+ -+ addr = R_AX_PWR_LMT; -+ for (i = 0; i < RTW89_NTX_NUM; i++) { -+ rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt, i); -+ -+ ptr = (s8 *)&lmt; -+ for (j = 0; j < RTW89_TXPWR_LMT_PAGE_SIZE; -+ j += 4, addr += 4, ptr += 4) { -+ val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -+ FIELD_PREP(GENMASK(15, 8), ptr[1]) | -+ FIELD_PREP(GENMASK(23, 16), ptr[2]) | -+ FIELD_PREP(GENMASK(31, 24), ptr[3]); -+ -+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -+ } -+ } -+} -+EXPORT_SYMBOL(rtw89_phy_set_txpwr_limit); -+ -+void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ struct rtw89_txpwr_limit_ru lmt_ru; -+ u8 ch = chan->channel; -+ u8 bw = chan->band_width; -+ const s8 *ptr; -+ u32 addr, val; -+ u8 i, j; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); -+ -+ BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ru) != -+ RTW89_TXPWR_LMT_RU_PAGE_SIZE); -+ -+ addr = R_AX_PWR_RU_LMT; -+ for (i = 0; i < RTW89_NTX_NUM; i++) { -+ rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru, i); -+ -+ ptr = (s8 *)&lmt_ru; -+ for (j = 0; j < RTW89_TXPWR_LMT_RU_PAGE_SIZE; -+ j += 4, addr += 4, ptr += 4) { -+ val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -+ FIELD_PREP(GENMASK(15, 8), ptr[1]) | -+ FIELD_PREP(GENMASK(23, 16), ptr[2]) | -+ FIELD_PREP(GENMASK(31, 24), ptr[3]); -+ -+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -+ } -+ } -+} -+EXPORT_SYMBOL(rtw89_phy_set_txpwr_limit_ru); - - struct rtw89_phy_iter_ra_data { - struct rtw89_dev *rtwdev; ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -317,9 +317,6 @@ struct rtw89_nbi_reg_def { - struct rtw89_reg_def notch2_en; - }; - --extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX]; --extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX]; -- - static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, - u32 addr, u8 data) - { -@@ -460,18 +457,20 @@ void rtw89_phy_write32_idx(struct rtw89_ - u32 data, enum rtw89_phy_idx phy_idx); - void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, - const struct rtw89_txpwr_table *tbl); --s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, -- const struct rtw89_rate_desc *rate_desc); --void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- struct rtw89_txpwr_limit *lmt, -- u8 ntx); --void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- struct rtw89_txpwr_limit_ru *lmt_ru, -- u8 ntx); - s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, - u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch); -+void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); -+void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); -+void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); -+void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); - void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); - void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); - void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1410,151 +1410,14 @@ static void rtw8852a_set_txpwr_ref(struc - phy_idx); - } - --static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ -- u8 band = chan->band_type; -- u8 ch = chan->channel; -- static const u8 rs[] = { -- RTW89_RS_CCK, -- RTW89_RS_OFDM, -- RTW89_RS_MCS, -- RTW89_RS_HEDCM, -- }; -- s8 tmp; -- u8 i, j; -- u32 val, shf, addr = R_AX_PWR_BY_RATE; -- struct rtw89_rate_desc cur; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr byrate with ch=%d\n", ch); -- -- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { -- for (i = 0; i < ARRAY_SIZE(rs); i++) { -- if (cur.nss >= rtw89_rs_nss_max[rs[i]]) -- continue; -- -- val = 0; -- cur.rs = rs[i]; -- -- for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { -- cur.idx = j; -- shf = (j % 4) * 8; -- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band, -- &cur); -- val |= (tmp << shf); -- -- if ((j + 1) % 4) -- continue; -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- val = 0; -- addr += 4; -- } -- } -- } --} -- --static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ -- u8 band = chan->band_type; -- struct rtw89_rate_desc desc = { -- .nss = RTW89_NSS_1, -- .rs = RTW89_RS_OFFSET, -- }; -- u32 val = 0; -- s8 v; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); -- -- for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { -- v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); -- val |= ((v & 0xf) << (4 * desc.idx)); -- } -- -- rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, -- GENMASK(19, 0), val); --} -- --static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ --#define __MAC_TXPWR_LMT_PAGE_SIZE 40 -- u8 ch = chan->channel; -- u8 bw = chan->band_width; -- struct rtw89_txpwr_limit lmt[NTX_NUM_8852A]; -- u32 addr, val; -- const s8 *ptr; -- u8 i, j; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); -- -- for (i = 0; i < NTX_NUM_8852A; i++) { -- rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i); -- -- for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { -- addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; -- ptr = (s8 *)&lmt[i] + j; -- -- val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -- FIELD_PREP(GENMASK(15, 8), ptr[1]) | -- FIELD_PREP(GENMASK(23, 16), ptr[2]) | -- FIELD_PREP(GENMASK(31, 24), ptr[3]); -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- } -- } --#undef __MAC_TXPWR_LMT_PAGE_SIZE --} -- --static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ --#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 -- u8 ch = chan->channel; -- u8 bw = chan->band_width; -- struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A]; -- u32 addr, val; -- const s8 *ptr; -- u8 i, j; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); -- -- for (i = 0; i < NTX_NUM_8852A; i++) { -- rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i); -- -- for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { -- addr = R_AX_PWR_RU_LMT + j + -- __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; -- ptr = (s8 *)&lmt_ru[i] + j; -- -- val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -- FIELD_PREP(GENMASK(15, 8), ptr[1]) | -- FIELD_PREP(GENMASK(23, 16), ptr[2]) | -- FIELD_PREP(GENMASK(31, 24), ptr[3]); -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- } -- } -- --#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE --} -- - static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -- rtw8852a_set_txpwr_byrate(rtwdev, chan, phy_idx); -- rtw8852a_set_txpwr_offset(rtwdev, chan, phy_idx); -- rtw8852a_set_txpwr_limit(rtwdev, chan, phy_idx); -- rtw8852a_set_txpwr_limit_ru(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); - } - - static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h -@@ -8,7 +8,6 @@ - #include "core.h" - - #define RF_PATH_NUM_8852A 2 --#define NTX_NUM_8852A 2 - - enum rtw8852a_pmac_mode { - NONE_TEST, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2006,75 +2006,6 @@ static void rtw8852c_set_txpwr_ref(struc - phy_idx); - } - --static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ -- u8 band = chan->band_type; -- u8 ch = chan->channel; -- static const u8 rs[] = { -- RTW89_RS_CCK, -- RTW89_RS_OFDM, -- RTW89_RS_MCS, -- RTW89_RS_HEDCM, -- }; -- s8 tmp; -- u8 i, j; -- u32 val, shf, addr = R_AX_PWR_BY_RATE; -- struct rtw89_rate_desc cur; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr byrate with ch=%d\n", ch); -- -- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { -- for (i = 0; i < ARRAY_SIZE(rs); i++) { -- if (cur.nss >= rtw89_rs_nss_max[rs[i]]) -- continue; -- -- val = 0; -- cur.rs = rs[i]; -- -- for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { -- cur.idx = j; -- shf = (j % 4) * 8; -- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band, -- &cur); -- val |= (tmp << shf); -- -- if ((j + 1) % 4) -- continue; -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- val = 0; -- addr += 4; -- } -- } -- } --} -- --static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ -- u8 band = chan->band_type; -- struct rtw89_rate_desc desc = { -- .nss = RTW89_NSS_1, -- .rs = RTW89_RS_OFFSET, -- }; -- u32 val = 0; -- s8 v; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); -- -- for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { -- v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); -- val |= ((v & 0xf) << (4 * desc.idx)); -- } -- -- rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, -- GENMASK(19, 0), val); --} -- - static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, - u8 tx_shape_idx, - enum rtw89_phy_idx phy_idx) -@@ -2147,83 +2078,15 @@ static void rtw8852c_set_tx_shape(struct - tx_shape_ofdm); - } - --static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ --#define __MAC_TXPWR_LMT_PAGE_SIZE 40 -- u8 ch = chan->channel; -- u8 bw = chan->band_width; -- struct rtw89_txpwr_limit lmt[NTX_NUM_8852C]; -- u32 addr, val; -- const s8 *ptr; -- u8 i, j; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); -- -- for (i = 0; i < NTX_NUM_8852C; i++) { -- rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i); -- -- for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { -- addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; -- ptr = (s8 *)&lmt[i] + j; -- -- val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -- FIELD_PREP(GENMASK(15, 8), ptr[1]) | -- FIELD_PREP(GENMASK(23, 16), ptr[2]) | -- FIELD_PREP(GENMASK(31, 24), ptr[3]); -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- } -- } --#undef __MAC_TXPWR_LMT_PAGE_SIZE --} -- --static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, -- const struct rtw89_chan *chan, -- enum rtw89_phy_idx phy_idx) --{ --#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 -- u8 ch = chan->channel; -- u8 bw = chan->band_width; -- struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C]; -- u32 addr, val; -- const s8 *ptr; -- u8 i, j; -- -- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -- "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); -- -- for (i = 0; i < NTX_NUM_8852C; i++) { -- rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i); -- -- for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { -- addr = R_AX_PWR_RU_LMT + j + -- __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; -- ptr = (s8 *)&lmt_ru[i] + j; -- -- val = FIELD_PREP(GENMASK(7, 0), ptr[0]) | -- FIELD_PREP(GENMASK(15, 8), ptr[1]) | -- FIELD_PREP(GENMASK(23, 16), ptr[2]) | -- FIELD_PREP(GENMASK(31, 24), ptr[3]); -- -- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); -- } -- } -- --#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE --} -- - static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -- rtw8852c_set_txpwr_byrate(rtwdev, chan, phy_idx); -- rtw8852c_set_txpwr_offset(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); - rtw8852c_set_tx_shape(rtwdev, chan, phy_idx); -- rtw8852c_set_txpwr_limit(rtwdev, chan, phy_idx); -- rtw8852c_set_txpwr_limit_ru(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); - } - - static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h -@@ -9,7 +9,6 @@ - - #define RF_PATH_NUM_8852C 2 - #define BB_PATH_NUM_8852C 2 --#define NTX_NUM_8852C 2 - - struct rtw8852c_u_efuse { - u8 rsvd[0x38]; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-005-wifi-rtw89-debug-txpwr_table-considers-sign.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-005-wifi-rtw89-debug-txpwr_table-considers-sign.patch deleted file mode 100644 index 25dce54b6..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-005-wifi-rtw89-debug-txpwr_table-considers-sign.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b902161645879ac820dfbb561667cd08be569538 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 28 Sep 2022 16:43:32 +0800 -Subject: [PATCH 005/149] wifi: rtw89: debug: txpwr_table considers sign - -Previously, value of each field is just shown as unsigned. -Now, we start to show them with sign to make things more intuitive -during debugging. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -464,7 +464,7 @@ static const struct txpwr_map __txpwr_ma - }; - - static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, -- const u8 *buf, const u8 cur) -+ const s8 *buf, const u8 cur) - { - char *fmt; - -@@ -493,8 +493,9 @@ static int __print_txpwr_map(struct seq_ - const struct txpwr_map *map) - { - u8 fct = rtwdev->chip->txpwr_factor_mac; -- u8 *buf, cur, i; - u32 val, addr; -+ s8 *buf, tmp; -+ u8 cur, i; - int ret; - - buf = vzalloc(map->addr_to - map->addr_from + 4); -@@ -507,8 +508,11 @@ static int __print_txpwr_map(struct seq_ - val = MASKDWORD; - - cur = addr - map->addr_from; -- for (i = 0; i < 4; i++, val >>= 8) -- buf[cur + i] = FIELD_GET(MASKBYTE0, val) >> fct; -+ for (i = 0; i < 4; i++, val >>= 8) { -+ /* signed 7 bits, and reserved BIT(7) */ -+ tmp = sign_extend32(val, 6); -+ buf[cur + i] = tmp >> fct; -+ } - } - - for (cur = 0, i = 0; i < map->size; i++) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch deleted file mode 100644 index 7416411b0..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch +++ /dev/null @@ -1,303 +0,0 @@ -From 08484e1f6e6fd670c722756baea4833436ca8fb5 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:33 +0800 -Subject: [PATCH 006/149] wifi: rtw89: 8852b: add chip_ops::set_txpwr - -This chip_ops is to set TX power according to country, channel, rate and -so on. Since shared code is used to configure TX power, we only implement -specific part in this patch. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 5 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 200 +++++++++++++++++- - drivers/net/wireless/realtek/rtw89/rtw8852b.h | 13 ++ - 4 files changed, 218 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b.h - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4817,6 +4817,7 @@ int rtw89_mac_read_xtal_si(struct rtw89_ - - return 0; - } -+EXPORT_SYMBOL(rtw89_mac_read_xtal_si); - - static - void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -2991,6 +2991,7 @@ - - #define R_AX_PWR_RATE_CTRL 0xD200 - #define R_AX_PWR_RATE_CTRL_C1 0xF200 -+#define B_AX_PWR_REF GENMASK(27, 10) - #define B_AX_FORCE_PWR_BY_RATE_EN BIT(9) - #define B_AX_FORCE_PWR_BY_RATE_VALUE_MASK GENMASK(8, 0) - -@@ -3772,6 +3773,7 @@ - #define B_DCFO_WEIGHT_MSK GENMASK(27, 24) - #define R_DCFO_OPT 0x4494 - #define B_DCFO_OPT_EN BIT(29) -+#define B_TXSHAPE_TRIANGULAR_CFG GENMASK(25, 24) - #define R_BANDEDGE 0x4498 - #define B_BANDEDGE_EN BIT(30) - #define R_TXPATH_SEL 0x458C -@@ -4005,6 +4007,9 @@ - #define B_TXPWRB_VAL GENMASK(27, 19) - #define R_DPD_OFT_EN 0x5800 - #define B_DPD_OFT_EN BIT(28) -+#define B_DPD_TSSI_CW GENMASK(26, 18) -+#define B_DPD_PWR_CW GENMASK(17, 9) -+#define B_DPD_REF GENMASK(8, 0) - #define R_DPD_OFT_ADDR 0x5804 - #define B_DPD_OFT_ADDR GENMASK(31, 27) - #define R_TXPWRB_H 0x580c ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2,9 +2,14 @@ - /* Copyright(c) 2019-2022 Realtek Corporation - */ - --#include "core.h" -+#include "coex.h" -+#include "fw.h" - #include "mac.h" -+#include "phy.h" - #include "reg.h" -+#include "rtw8852b.h" -+#include "rtw8852b_table.h" -+#include "txrx.h" - - static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { - [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, -@@ -19,6 +24,195 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, s16 ref) -+{ -+ const u16 tssi_16dbm_cw = 0x12c; -+ const u8 base_cw_0db = 0x27; -+ const s8 ofst_int = 0; -+ s16 pwr_s10_3; -+ s16 rf_pwr_cw; -+ u16 bb_pwr_cw; -+ u32 pwr_cw; -+ u32 tssi_ofst_cw; -+ -+ pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); -+ bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); -+ rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); -+ rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); -+ pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; -+ -+ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", -+ tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); -+ -+ return FIELD_PREP(B_DPD_TSSI_CW, tssi_ofst_cw) | -+ FIELD_PREP(B_DPD_PWR_CW, pwr_cw) | -+ FIELD_PREP(B_DPD_REF, ref); -+} -+ -+static void rtw8852b_set_txpwr_ref(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ static const u32 addr[RF_PATH_NUM_8852B] = {0x5800, 0x7800}; -+ const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF; -+ const u8 ofst_ofdm = 0x4; -+ const u8 ofst_cck = 0x8; -+ const s16 ref_ofdm = 0; -+ const s16 ref_cck = 0; -+ u32 val; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); -+ -+ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, -+ B_AX_PWR_REF, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); -+ val = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) -+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, -+ phy_idx); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); -+ val = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) -+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, -+ phy_idx); -+} -+ -+static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, -+ u8 tx_shape_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2)) -+#define __DFIR_CFG_MASK 0xffffffff -+#define __DFIR_CFG_NR 8 -+#define __DECL_DFIR_PARAM(_name, _val...) \ -+ static const u32 param_ ## _name[] = {_val}; \ -+ static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR) -+ -+ __DECL_DFIR_PARAM(flat, -+ 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, -+ 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5); -+ __DECL_DFIR_PARAM(sharp, -+ 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090, -+ 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5); -+ __DECL_DFIR_PARAM(sharp_14, -+ 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, -+ 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ const u32 *param; -+ u32 addr; -+ int i; -+ -+ if (ch > 14) { -+ rtw89_warn(rtwdev, -+ "set tx shape dfir by unknown ch: %d on 2G\n", ch); -+ return; -+ } -+ -+ if (ch == 14) -+ param = param_sharp_14; -+ else -+ param = tx_shape_idx == 0 ? param_flat : param_sharp; -+ -+ for (i = 0; i < __DFIR_CFG_NR; i++) { -+ addr = __DFIR_CFG_ADDR(i); -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]); -+ rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i], -+ phy_idx); -+ } -+ -+#undef __DECL_DFIR_PARAM -+#undef __DFIR_CFG_NR -+#undef __DFIR_CFG_MASK -+#undef __DECL_CFG_ADDR -+} -+ -+static void rtw8852b_set_tx_shape(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 band = chan->band_type; -+ u8 regd = rtw89_regd_get(rtwdev, band); -+ u8 tx_shape_cck = rtw89_8852b_tx_shape[band][RTW89_RS_CCK][regd]; -+ u8 tx_shape_ofdm = rtw89_8852b_tx_shape[band][RTW89_RS_OFDM][regd]; -+ -+ if (band == RTW89_BAND_2G) -+ rtw8852b_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, -+ tx_shape_ofdm); -+} -+ -+static void rtw8852b_set_txpwr(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); -+ rtw8852b_set_tx_shape(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); -+} -+ -+static void rtw8852b_set_txpwr_ctrl(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8852b_set_txpwr_ref(rtwdev, phy_idx); -+} -+ -+static -+void rtw8852b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, -+ s8 pw_ofst, enum rtw89_mac_idx mac_idx) -+{ -+ u32 reg; -+ -+ if (pw_ofst < -16 || pw_ofst > 15) { -+ rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst); -+ return; -+ } -+ -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx); -+ rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); -+ -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx); -+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); -+ -+ pw_ofst = max_t(s8, pw_ofst - 3, -16); -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); -+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); -+} -+ -+static int -+rtw8852b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ int ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); -+ if (ret) -+ return ret; -+ -+ rtw8852b_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? -+ RTW89_MAC_1 : RTW89_MAC_0); -+ -+ return 0; -+} -+ - static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) - { - int ret; -@@ -75,10 +269,14 @@ static int rtw8852b_mac_disable_bb_rf(st - static const struct rtw89_chip_ops rtw8852b_chip_ops = { - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, -+ .set_txpwr = rtw8852b_set_txpwr, -+ .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, -+ .init_txpwr_unit = rtw8852b_init_txpwr_unit, - }; - - const struct rtw89_chip_info rtw8852b_chip_info = { - .chip_id = RTL8852B, -+ .ops = &rtw8852b_chip_ops, - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, - .dle_mem = rtw8852b_dle_mem_pcie, ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2019-2022 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8852B_H__ -+#define __RTW89_8852B_H__ -+ -+#include "core.h" -+ -+#define RF_PATH_NUM_8852B 2 -+#define BB_PATH_NUM_8852B 2 -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch deleted file mode 100644 index 66dd46c05..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 132dc4fe5b587c0a62fc90d78e7413944fa06669 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:34 +0800 -Subject: [PATCH 007/149] wifi: rtw89: 8852b: add chip_ops to read efuse - -efuse stores individual data about a chip itself, such as MAC address, -country code, RF and crystal calibration data, and so on. Define a struct -to help access efuse content, and copy them into a common struct. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 106 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8852b.h | 75 +++++++++++++ - 2 files changed, 181 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -24,6 +24,105 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse, -+ struct rtw8852b_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->e.mac_addr); -+ efuse->rfe_type = map->rfe_type; -+ efuse->xtal_cap = map->xtal_k; -+} -+ -+static void rtw8852b_efuse_parsing_tssi(struct rtw89_dev *rtwdev, -+ struct rtw8852b_efuse *map) -+{ -+ struct rtw89_tssi_info *tssi = &rtwdev->tssi; -+ struct rtw8852b_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; -+ u8 i, j; -+ -+ tssi->thermal[RF_PATH_A] = map->path_a_therm; -+ tssi->thermal[RF_PATH_B] = map->path_b_therm; -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, -+ sizeof(ofst[i]->cck_tssi)); -+ -+ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", -+ i, j, tssi->tssi_cck[i][j]); -+ -+ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, -+ sizeof(ofst[i]->bw40_tssi)); -+ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, -+ ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); -+ -+ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", -+ i, j, tssi->tssi_mcs[i][j]); -+ } -+} -+ -+static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) -+{ -+ if (high) -+ *high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), 3); -+ if (low) -+ *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3); -+ -+ return data != 0xff; -+} -+ -+static void rtw8852b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, -+ struct rtw8852b_efuse *map) -+{ -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ bool valid = false; -+ -+ valid |= _decode_efuse_gain(map->rx_gain_2g_cck, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], -+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]); -+ valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], -+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_low, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], -+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_mid, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], -+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_high, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], -+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]); -+ -+ gain->offset_valid = valid; -+} -+ -+static int rtw8852b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) -+{ -+ struct rtw89_efuse *efuse = &rtwdev->efuse; -+ struct rtw8852b_efuse *map; -+ -+ map = (struct rtw8852b_efuse *)log_map; -+ -+ efuse->country_code[0] = map->country_code[0]; -+ efuse->country_code[1] = map->country_code[1]; -+ rtw8852b_efuse_parsing_tssi(rtwdev, map); -+ rtw8852b_efuse_parsing_gain_offset(rtwdev, map); -+ -+ switch (rtwdev->hci.type) { -+ case RTW89_HCI_TYPE_PCIE: -+ rtw8852be_efuse_parsing(efuse, map); -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); -+ -+ return 0; -+} -+ - static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -269,6 +368,7 @@ static int rtw8852b_mac_disable_bb_rf(st - static const struct rtw89_chip_ops rtw8852b_chip_ops = { - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, -+ .read_efuse = rtw8852b_read_efuse, - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8852b_init_txpwr_unit, -@@ -280,6 +380,12 @@ const struct rtw89_chip_info rtw8852b_ch - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, - .dle_mem = rtw8852b_dle_mem_pcie, -+ .sec_ctrl_efuse_size = 4, -+ .physical_efuse_size = 1216, -+ .logical_efuse_size = 2048, -+ .limit_efuse_size = 1280, -+ .dav_phy_efuse_size = 96, -+ .dav_log_efuse_size = 16, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h -@@ -10,4 +10,79 @@ - #define RF_PATH_NUM_8852B 2 - #define BB_PATH_NUM_8852B 2 - -+struct rtw8852b_u_efuse { -+ u8 rsvd[0x88]; -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+struct rtw8852b_e_efuse { -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+struct rtw8852b_tssi_offset { -+ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; -+ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; -+ u8 rsvd[7]; -+ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; -+} __packed; -+ -+struct rtw8852b_efuse { -+ u8 rsvd[0x210]; -+ struct rtw8852b_tssi_offset path_a_tssi; -+ u8 rsvd1[10]; -+ struct rtw8852b_tssi_offset path_b_tssi; -+ u8 rsvd2[94]; -+ u8 channel_plan; -+ u8 xtal_k; -+ u8 rsvd3; -+ u8 iqk_lck; -+ u8 rsvd4[5]; -+ u8 reg_setting:2; -+ u8 tx_diversity:1; -+ u8 rx_diversity:2; -+ u8 ac_mode:1; -+ u8 module_type:2; -+ u8 rsvd5; -+ u8 shared_ant:1; -+ u8 coex_type:3; -+ u8 ant_iso:1; -+ u8 radio_on_off:1; -+ u8 rsvd6:2; -+ u8 eeprom_version; -+ u8 customer_id; -+ u8 tx_bb_swing_2g; -+ u8 tx_bb_swing_5g; -+ u8 tx_cali_pwr_trk_mode; -+ u8 trx_path_selection; -+ u8 rfe_type; -+ u8 country_code[2]; -+ u8 rsvd7[3]; -+ u8 path_a_therm; -+ u8 path_b_therm; -+ u8 rsvd8[2]; -+ u8 rx_gain_2g_ofdm; -+ u8 rsvd9; -+ u8 rx_gain_2g_cck; -+ u8 rsvd10; -+ u8 rx_gain_5g_low; -+ u8 rsvd11; -+ u8 rx_gain_5g_mid; -+ u8 rsvd12; -+ u8 rx_gain_5g_high; -+ u8 rsvd13[35]; -+ u8 path_a_cck_pwr_idx[6]; -+ u8 path_a_bw40_1tx_pwr_idx[5]; -+ u8 path_a_ofdm_1tx_pwr_idx_diff:4; -+ u8 path_a_bw20_1tx_pwr_idx_diff:4; -+ u8 path_a_bw20_2tx_pwr_idx_diff:4; -+ u8 path_a_bw40_2tx_pwr_idx_diff:4; -+ u8 path_a_cck_2tx_pwr_idx_diff:4; -+ u8 path_a_ofdm_2tx_pwr_idx_diff:4; -+ u8 rsvd14[0xf2]; -+ union { -+ struct rtw8852b_u_efuse u; -+ struct rtw8852b_e_efuse e; -+ }; -+} __packed; -+ - #endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch deleted file mode 100644 index ac866f4ab..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 134cf7c01517d5cfaab940cacbb41525659de5f6 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:35 +0800 -Subject: [PATCH 008/149] wifi: rtw89: 8852b: add chip_ops to read phy cap - -This efuse region is to store PHY calibration, and it is a separated region -from the region that stores MAC address. Then, use these data to configure -via chip_ops::power_trim that is a calibration mechanism of TX power. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-9-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 4 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 184 ++++++++++++++++++ - 2 files changed, 188 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -84,6 +84,7 @@ enum rtw89_subband { - RTW89_CH_6G_BAND_IDX7, /* Ultra-high */ - - RTW89_SUBBAND_NR, -+ RTW89_SUBBAND_2GHZ_5GHZ_NR = RTW89_CH_5G_BAND_4 + 1, - }; - - enum rtw89_gain_offset { -@@ -2196,6 +2197,7 @@ struct rtw89_sta { - - struct rtw89_efuse { - bool valid; -+ bool power_k_valid; - u8 xtal_cap; - u8 addr[ETH_ALEN]; - u8 rfe_type; -@@ -3425,8 +3427,10 @@ struct rtw89_phy_bb_gain_info { - - struct rtw89_phy_efuse_gain { - bool offset_valid; -+ bool comp_valid; - s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ - s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ -+ s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ - }; - - struct rtw89_dev { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -123,6 +123,186 @@ static int rtw8852b_read_efuse(struct rt - return 0; - } - -+static void rtw8852b_phycap_parsing_power_cal(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+#define PWR_K_CHK_OFFSET 0x5E9 -+#define PWR_K_CHK_VALUE 0xAA -+ u32 offset = PWR_K_CHK_OFFSET - rtwdev->chip->phycap_addr; -+ -+ if (phycap_map[offset] == PWR_K_CHK_VALUE) -+ rtwdev->efuse.power_k_valid = true; -+} -+ -+static void rtw8852b_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ struct rtw89_tssi_info *tssi = &rtwdev->tssi; -+ static const u32 tssi_trim_addr[RF_PATH_NUM_8852B] = {0x5D6, 0x5AB}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ bool pg = false; -+ u32 ofst; -+ u8 i, j; -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { -+ /* addrs are in decreasing order */ -+ ofst = tssi_trim_addr[i] - addr - j; -+ tssi->tssi_trim[i][j] = phycap_map[ofst]; -+ -+ if (phycap_map[ofst] != 0xff) -+ pg = true; -+ } -+ } -+ -+ if (!pg) { -+ memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM] no PG, set all trim info to 0\n"); -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) -+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", -+ i, j, tssi->tssi_trim[i][j], -+ tssi_trim_addr[i] - j); -+} -+ -+static void rtw8852b_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, -+ u8 *phycap_map) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ static const u32 thm_trim_addr[RF_PATH_NUM_8852B] = {0x5DF, 0x5DC}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", -+ i, info->thermal_trim[i]); -+ -+ if (info->thermal_trim[i] != 0xff) -+ info->pg_thermal_trim = true; -+ } -+} -+ -+static void rtw8852b_thermal_trim(struct rtw89_dev *rtwdev) -+{ -+#define __thm_setting(raw) \ -+({ \ -+ u8 __v = (raw); \ -+ ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ -+}) -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ u8 i, val; -+ -+ if (!info->pg_thermal_trim) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] no PG, do nothing\n"); -+ -+ return; -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ val = __thm_setting(info->thermal_trim[i]); -+ rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", -+ i, val); -+ } -+#undef __thm_setting -+} -+ -+static void rtw8852b_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, -+ u8 *phycap_map) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ static const u32 pabias_trim_addr[RF_PATH_NUM_8852B] = {0x5DE, 0x5DB}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", -+ i, info->pa_bias_trim[i]); -+ -+ if (info->pa_bias_trim[i] != 0xff) -+ info->pg_pa_bias_trim = true; -+ } -+} -+ -+static void rtw8852b_pa_bias_trim(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ u8 pabias_2g, pabias_5g; -+ u8 i; -+ -+ if (!info->pg_pa_bias_trim) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] no PG, do nothing\n"); -+ -+ return; -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); -+ pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", -+ i, pabias_2g, pabias_5g); -+ -+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); -+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); -+ } -+} -+ -+static void rtw8852b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = { -+ {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8}, -+ {0x590, 0x58F, 0, 0x58E, 0x58D}, -+ }; -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ u32 phycap_addr = rtwdev->chip->phycap_addr; -+ bool valid = false; -+ int path, i; -+ u8 data; -+ -+ for (path = 0; path < 2; path++) -+ for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) { -+ if (comp_addrs[path][i] == 0) -+ continue; -+ -+ data = phycap_map[comp_addrs[path][i] - phycap_addr]; -+ valid |= _decode_efuse_gain(data, NULL, -+ &gain->comp[path][i]); -+ } -+ -+ gain->comp_valid = valid; -+} -+ -+static int rtw8852b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ rtw8852b_phycap_parsing_power_cal(rtwdev, phycap_map); -+ rtw8852b_phycap_parsing_tssi(rtwdev, phycap_map); -+ rtw8852b_phycap_parsing_thermal_trim(rtwdev, phycap_map); -+ rtw8852b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); -+ rtw8852b_phycap_parsing_gain_comp(rtwdev, phycap_map); -+ -+ return 0; -+} -+ -+static void rtw8852b_power_trim(struct rtw89_dev *rtwdev) -+{ -+ rtw8852b_thermal_trim(rtwdev); -+ rtw8852b_pa_bias_trim(rtwdev); -+} -+ - static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -369,6 +549,8 @@ static const struct rtw89_chip_ops rtw88 - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, - .read_efuse = rtw8852b_read_efuse, -+ .read_phycap = rtw8852b_read_phycap, -+ .power_trim = rtw8852b_power_trim, - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8852b_init_txpwr_unit, -@@ -386,6 +568,8 @@ const struct rtw89_chip_info rtw8852b_ch - .limit_efuse_size = 1280, - .dav_phy_efuse_size = 96, - .dav_log_efuse_size = 16, -+ .phycap_addr = 0x580, -+ .phycap_size = 128, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch deleted file mode 100644 index e7852735e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 9695dc2e4be90315471ea4c672836929f5c403fe Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 28 Sep 2022 16:43:36 +0800 -Subject: [PATCH 009/149] wifi: rtw89: 8852be: add 8852BE PCI entry - -8852BE has two variants with different ID. One is 10ec:b852 that is a main -model with 2x2 antenna, and the other is 10ec:b85b that is a 1x1 model. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220928084336.34981-10-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.h | 2 + - .../net/wireless/realtek/rtw89/rtw8852be.c | 64 +++++++++++++++++++ - 2 files changed, 66 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h -@@ -85,4 +85,6 @@ struct rtw8852b_efuse { - }; - } __packed; - -+extern const struct rtw89_chip_info rtw8852b_chip_info; -+ - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c -@@ -7,18 +7,82 @@ - - #include "pci.h" - #include "reg.h" -+#include "rtw8852b.h" - - static const struct rtw89_pci_info rtw8852b_pci_info = { -+ .txbd_trunc_mode = MAC_AX_BD_TRUNC, -+ .rxbd_trunc_mode = MAC_AX_BD_TRUNC, -+ .rxbd_mode = MAC_AX_RXBD_PKT, -+ .tag_mode = MAC_AX_TAG_MULTI, -+ .tx_burst = MAC_AX_TX_BURST_2048B, -+ .rx_burst = MAC_AX_RX_BURST_128B, -+ .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, -+ .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, -+ .multi_tag_num = MAC_AX_TAG_NUM_8, -+ .lbc_en = MAC_AX_PCIE_ENABLE, -+ .lbc_tmr = MAC_AX_LBC_TMR_2MS, -+ .autok_en = MAC_AX_PCIE_DISABLE, -+ .io_rcy_en = MAC_AX_PCIE_DISABLE, -+ .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, -+ -+ .init_cfg_reg = R_AX_PCIE_INIT_CFG1, -+ .txhci_en_bit = B_AX_TXHCI_EN, -+ .rxhci_en_bit = B_AX_RXHCI_EN, -+ .rxbd_mode_bit = B_AX_RXBD_MODE, -+ .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, -+ .max_tag_num_mask = B_AX_MAX_TAG_NUM, -+ .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, -+ .txbd_rwptr_clr2_reg = 0, - .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1}, - .dma_stop2 = {0}, - .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1}, - .dma_busy2_reg = 0, - .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, - -+ .rpwm_addr = R_AX_PCIE_HRPWM, -+ .cpwm_addr = R_AX_CPWM, - .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) | - BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) | - BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), -+ .bd_idx_addr_low_power = NULL, -+ .dma_addr_set = &rtw89_pci_ch_dma_addr_set, -+ -+ .ltr_set = rtw89_pci_ltr_set, -+ .fill_txaddr_info = rtw89_pci_fill_txaddr_info, -+ .config_intr_mask = rtw89_pci_config_intr_mask, -+ .enable_intr = rtw89_pci_enable_intr, -+ .disable_intr = rtw89_pci_disable_intr, -+ .recognize_intrs = rtw89_pci_recognize_intrs, -+}; -+ -+static const struct rtw89_driver_info rtw89_8852be_info = { -+ .chip = &rtw8852b_chip_info, -+ .bus = { -+ .pci = &rtw8852b_pci_info, -+ }, -+}; -+ -+static const struct pci_device_id rtw89_8852be_id_table[] = { -+ { -+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb852), -+ .driver_data = (kernel_ulong_t)&rtw89_8852be_info, -+ }, -+ { -+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb85b), -+ .driver_data = (kernel_ulong_t)&rtw89_8852be_info, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(pci, rtw89_8852be_id_table); -+ -+static struct pci_driver rtw89_8852be_driver = { -+ .name = "rtw89_8852be", -+ .id_table = rtw89_8852be_id_table, -+ .probe = rtw89_pci_probe, -+ .remove = rtw89_pci_remove, -+ .driver.pm = &rtw89_pm_ops, - }; -+module_pci_driver(rtw89_8852be_driver); - - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver"); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch deleted file mode 100644 index 208b6f5fb..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 68b0ce5bb4002cd657963cb876f0ff51729f9bfc Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:33:17 +0800 -Subject: [PATCH 010/149] wifi: rtw89: 8852c: correct set of IQK backup - registers - -IQK can change the values of this register set, so need to backup and -restore the values. During we rewrite IQK, the policy is changed. Some -values are controlled and filled by IQK, and don't need to restore after -IQK. Therefore, remove this kind of registers from this array. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930133318.6335-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -22,8 +22,7 @@ static const u32 _tssi_de_mcs_5m[RF_PATH - static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830}; - - static const u32 rtw8852c_backup_bb_regs[] = { -- 0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x823c, 0x8224, 0x8220, -- 0xc1d4, 0xc1d8, 0xc1e8 -+ 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x8220, 0xc1d4, 0xc1d8, 0xc1e8 - }; - - static const u32 rtw8852c_backup_rf_regs[] = { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch deleted file mode 100644 index 014ff029e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 3be11416204a7aecbdba8c843849f204c631b8e6 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:33:18 +0800 -Subject: [PATCH 011/149] wifi: rtw89: 8852c: rfk: correct miscoding delay of - DPK - -Using mdelay() can work well, but calibration causes too much time. Use -proper udelay() to get shorter time and the same result. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930133318.6335-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -1666,7 +1666,7 @@ static u8 _dpk_one_shot(struct rtw89_dev - - ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, - 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); -- mdelay(10); -+ udelay(10); - rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch deleted file mode 100644 index 91a4a883d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch +++ /dev/null @@ -1,1440 +0,0 @@ -From a9ee25c32fd4569f63cd34def9a013fb3dad8e01 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:36:58 +0800 -Subject: [PATCH 012/149] wifi: rtw89: 8852c: update BB parameters to v28 - -Update BB parameters along with internal tag HALBB_027_067_07. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930133659.7789-1-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8852c_table.c | 988 ++++++++++++++++-- - 1 file changed, 879 insertions(+), 109 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -10,6 +10,8 @@ static const struct rtw89_reg2_def rtw89 - {0xF0FF0000, 0x00000000}, - {0xF03300FF, 0x00000001}, - {0xF03400FF, 0x00000002}, -+ {0xF03500FF, 0x00000003}, -+ {0xF03600FF, 0x00000004}, - {0x70C, 0x00000020}, - {0x704, 0x601E0100}, - {0x4000, 0x00000000}, -@@ -200,7 +202,7 @@ static const struct rtw89_reg2_def rtw89 - {0x4264, 0x00000000}, - {0x4268, 0x00000000}, - {0x426C, 0x0418317C}, -- {0x46C0, 0x00000001}, -+ {0x46C0, 0x00000000}, - {0x4270, 0x00D6135C}, - {0x46C4, 0x00000033}, - {0x4274, 0x00000000}, -@@ -342,7 +344,7 @@ static const struct rtw89_reg2_def rtw89 - {0x442C, 0x00000000}, - {0x4430, 0x00000000}, - {0x4434, 0x00000000}, -- {0x4438, 0x590642D0}, -+ {0x4438, 0x59096398}, - {0x443C, 0x398668A0}, - {0x4440, 0x6C100808}, - {0x4444, 0x4A145344}, -@@ -566,9 +568,9 @@ static const struct rtw89_reg2_def rtw89 - {0x4BA8, 0x002B6456}, - {0x45E0, 0x00000000}, - {0x45E4, 0x00000000}, -- {0x45E8, 0x00E2E1E1}, -+ {0x45E8, 0x00C8E1E1}, - {0x45EC, 0xCBCBB6B6}, -- {0x45F0, 0x59100FCA}, -+ {0x45F0, 0x5F900FCA}, - {0x4BAC, 0x12CAB6DE}, - {0x4BB0, 0x00001110}, - {0x45F4, 0x08882550}, -@@ -584,9 +586,17 @@ static const struct rtw89_reg2_def rtw89 - {0x4660, 0x41250EF4}, - {0x4664, 0x6750E458}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x45DC, 0xE1CB38E8}, -- {0x4660, 0x4A2E1800}, -- {0x4664, 0x6750E462}, -+ {0x45DC, 0xD1B942F4}, -+ {0x4660, 0x41250EF4}, -+ {0x4664, 0x6750E458}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x45DC, 0xD1B942F4}, -+ {0x4660, 0x41250EF4}, -+ {0x4664, 0x6750E458}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x45DC, 0xD1B942F4}, -+ {0x4660, 0x41250EF4}, -+ {0x4664, 0x6750E458}, - {0xA0000000, 0x00000000}, - {0x45DC, 0xE1CB38E8}, - {0x4660, 0x4A2E1800}, -@@ -603,7 +613,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4688, 0x1A10FF04}, - {0x468C, 0x282A3000}, - {0x4690, 0x2A29292A}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4694, 0x04FA2A2A}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4694, 0x04FA2A2A}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4694, 0x06FA2A2A}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4694, 0x04FA2A2A}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x4694, 0x04FA2A2A}, -+ {0xA0000000, 0x00000000}, -+ {0x4694, 0x04FA2A2A}, -+ {0xB0000000, 0x00000000}, - {0x4698, 0xEE0F04D1}, - {0x469C, 0x89291436}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -@@ -612,6 +634,10 @@ static const struct rtw89_reg2_def rtw89 - {0x46A0, 0x0701E79E}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x46A0, 0x0701E79E}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46A0, 0x0701E79E}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46A0, 0x0701E79E}, - {0xA0000000, 0x00000000}, - {0x46A0, 0x0701E79E}, - {0xB0000000, 0x00000000}, -@@ -620,11 +646,17 @@ static const struct rtw89_reg2_def rtw89 - {0x46A8, 0x2212FF14}, - {0x46AC, 0x60423537}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46A8, 0x649EFF14}, -+ {0x46AC, 0xA1B37C4E}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x46A8, 0x4D1E7F14}, - {0x46AC, 0x60B37C4E}, -- {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x46A8, 0x2212FF14}, -- {0x46AC, 0x60423537}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46A8, 0x649EFF14}, -+ {0x46AC, 0xA1B37C4E}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46A8, 0x649EFF14}, -+ {0x46AC, 0xA1B37C4E}, - {0xA0000000, 0x00000000}, - {0x46A8, 0x2212FF14}, - {0x46AC, 0x60423537}, -@@ -637,11 +669,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4720, 0x3FFFFD63}, - {0x4724, 0xB58D11FF}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x46BC, 0x5107C252}, -- {0x4720, 0x27795843}, -+ {0x46BC, 0x510FC252}, -+ {0x4720, 0x27795303}, - {0x4724, 0xB58D11F5}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x46BC, 0x5107C252}, -+ {0x46BC, 0x510FC252}, -+ {0x4720, 0x27795843}, -+ {0x4724, 0xB58D11F5}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46BC, 0x510FC252}, -+ {0x4720, 0x27795303}, -+ {0x4724, 0xB58D11F5}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x46BC, 0x510FC252}, - {0x4720, 0x27795303}, - {0x4724, 0xB58D11F5}, - {0xA0000000, 0x00000000}, -@@ -656,11 +696,17 @@ static const struct rtw89_reg2_def rtw89 - {0x4734, 0x00000020}, - {0x4738, 0x8325C500}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4734, 0x003D4C20}, -+ {0x4734, 0x003D5420}, - {0x4738, 0x8F25C500}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4734, 0x003D4C20}, -+ {0x4738, 0x8F25C500}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4734, 0x003D5420}, -+ {0x4738, 0x8F25C500}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x4734, 0x003D5420}, -- {0x4738, 0x8725C500}, -+ {0x4738, 0x8F25C500}, - {0xA0000000, 0x00000000}, - {0x4734, 0x00000020}, - {0x4738, 0x8325C500}, -@@ -678,8 +724,14 @@ static const struct rtw89_reg2_def rtw89 - {0x4BB4, 0x05EBC8AF}, - {0x4BB8, 0x99543D24}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4BB4, 0xFBD5B89F}, -- {0x4BB8, 0x99563918}, -+ {0x4BB4, 0x05EBC8AF}, -+ {0x4BB8, 0x99543D24}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4BB4, 0x05EBC8AF}, -+ {0x4BB8, 0x99543D24}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4BB4, 0x05EBC8AF}, -+ {0x4BB8, 0x99543D24}, - {0xA0000000, 0x00000000}, - {0x4BB4, 0xFBD5B89F}, - {0x4BB8, 0x99563918}, -@@ -729,10 +781,10 @@ static const struct rtw89_reg2_def rtw89 - {0x4C58, 0x00001146}, - {0x4C5C, 0x00000000}, - {0x4C60, 0x00000000}, -- {0x4C64, 0xE2E1E1DE}, -+ {0x4C64, 0xC8E1E1DE}, - {0x4C68, 0xB6B600B6}, - {0x4C6C, 0xCACBCBCA}, -- {0x4C70, 0x8091010F}, -+ {0x4C70, 0x80F9010F}, - {0x4C74, 0x00000B11}, - {0x46C8, 0x08882550}, - {0x46CC, 0x08CC2660}, -@@ -747,9 +799,17 @@ static const struct rtw89_reg2_def rtw89 - {0x4744, 0x412504E8}, - {0x4748, 0x6850E459}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4740, 0xE4CD38E8}, -- {0x4744, 0x4C321B04}, -- {0x4748, 0x6750E466}, -+ {0x4740, 0xC5AD42F4}, -+ {0x4744, 0x412504E8}, -+ {0x4748, 0x6850E459}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4740, 0xC5AD42F4}, -+ {0x4744, 0x412504E8}, -+ {0x4748, 0x6850E459}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4740, 0xC5AD42F4}, -+ {0x4744, 0x412504E8}, -+ {0x4748, 0x6850E459}, - {0xA0000000, 0x00000000}, - {0x4740, 0xE4CD38E8}, - {0x4744, 0x4C321B04}, -@@ -766,7 +826,19 @@ static const struct rtw89_reg2_def rtw89 - {0x476C, 0x1A10FF04}, - {0x4770, 0x282A3000}, - {0x4774, 0x2A29292A}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x4778, 0x04FA2A2A}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4778, 0x04FA2A2A}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4778, 0x06FA2A2A}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4778, 0x04FA2A2A}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4778, 0x04FA2A2A}, -+ {0xA0000000, 0x00000000}, -+ {0x4778, 0x04FA2A2A}, -+ {0xB0000000, 0x00000000}, - {0x477C, 0xEE0F04D1}, - {0x49F0, 0x89291436}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -@@ -775,6 +847,10 @@ static const struct rtw89_reg2_def rtw89 - {0x49F4, 0x0701E79E}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x49F4, 0x0701E79E}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x49F4, 0x0701E79E}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x49F4, 0x0701E79E}, - {0xA0000000, 0x00000000}, - {0x49F4, 0x0701E79E}, - {0xB0000000, 0x00000000}, -@@ -783,11 +859,17 @@ static const struct rtw89_reg2_def rtw89 - {0x4A5C, 0x2212FF14}, - {0x4A60, 0x60423537}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4A5C, 0x649EFF14}, -+ {0x4A60, 0xA1B37C4E}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x4A5C, 0x4D1E7F14}, - {0x4A60, 0x60B37C4E}, -- {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4A5C, 0x2212FF14}, -- {0x4A60, 0x60423537}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4A5C, 0x649EFF14}, -+ {0x4A60, 0xA1B37C4E}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4A5C, 0x649EFF14}, -+ {0x4A60, 0xA1B37C4E}, - {0xA0000000, 0x00000000}, - {0x4A5C, 0x2212FF14}, - {0x4A60, 0x60423537}, -@@ -800,11 +882,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4A74, 0x3FFFFD63}, - {0x4A78, 0xB58D11FF}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4A70, 0x5107C252}, -- {0x4A74, 0x27795843}, -+ {0x4A70, 0x510FC252}, -+ {0x4A74, 0x27795303}, - {0x4A78, 0xB58D11F5}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4A70, 0x5107C252}, -+ {0x4A70, 0x510FC252}, -+ {0x4A74, 0x27795843}, -+ {0x4A78, 0xB58D11F5}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4A70, 0x510FC252}, -+ {0x4A74, 0x27795303}, -+ {0x4A78, 0xB58D11F5}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4A70, 0x510FC252}, - {0x4A74, 0x27795303}, - {0x4A78, 0xB58D11F5}, - {0xA0000000, 0x00000000}, -@@ -819,11 +909,17 @@ static const struct rtw89_reg2_def rtw89 - {0x4AA0, 0x00000020}, - {0x4AA4, 0x8325C500}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4AA0, 0x003D4C20}, -+ {0x4AA0, 0x003D5420}, - {0x4AA4, 0x8F25C500}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4AA0, 0x003D4C20}, -+ {0x4AA4, 0x8F25C500}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4AA0, 0x003D5420}, -+ {0x4AA4, 0x8F25C500}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x4AA0, 0x003D5420}, -- {0x4AA4, 0x8725C500}, -+ {0x4AA4, 0x8F25C500}, - {0xA0000000, 0x00000000}, - {0x4AA0, 0x00000020}, - {0x4AA4, 0x8325C500}, -@@ -841,8 +937,14 @@ static const struct rtw89_reg2_def rtw89 - {0x4C78, 0x07ECC9B0}, - {0x4C7C, 0x995B4126}, - {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x4C78, 0xFBD5B89F}, -- {0x4C7C, 0x99563918}, -+ {0x4C78, 0x07ECC9B0}, -+ {0x4C7C, 0x995B4126}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4C78, 0x07ECC9B0}, -+ {0x4C7C, 0x995B4126}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4C78, 0x07ECC9B0}, -+ {0x4C7C, 0x995B4126}, - {0xA0000000, 0x00000000}, - {0x4C78, 0xFBD5B89F}, - {0x4C7C, 0x99563918}, -@@ -907,17 +1009,46 @@ static const struct rtw89_reg2_def rtw89 - {0x47B4, 0x00000005}, - {0x4D2C, 0x0008C0C1}, - {0x47B8, 0x00001759}, -- {0x47BC, 0x4B702400}, -- {0x47C0, 0x831508BA}, -+ {0x47BC, 0x4B002402}, -+ {0x47C0, 0x831508BC}, - {0x4A14, 0x000000E9}, -- {0x4D30, 0x00000001}, -+ {0x4D30, 0x00000000}, - {0x4E94, 0x000000FC}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x47C4, 0x9ABBCACB}, -+ {0x47C8, 0x56767578}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x47C4, 0x9ABBCACB}, -+ {0x47C8, 0x56767578}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x47C4, 0x9ABBCACB}, -+ {0x47C8, 0x56767578}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x47C4, 0x9ABBCACB}, -+ {0x47C8, 0x56767578}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x47C4, 0x9ABBCACB}, -+ {0x47C8, 0x56767578}, -+ {0xA0000000, 0x00000000}, - {0x47C4, 0x9ABBCACB}, - {0x47C8, 0x56767578}, -+ {0xB0000000, 0x00000000}, - {0x47CC, 0xBBCCBBB3}, - {0x47D0, 0x57889989}, - {0x47D4, 0x00000F45}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4D34, 0x7BB167AB}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4D34, 0x7BB1579A}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4D34, 0x7BB167AB}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4D34, 0x7BB1579A}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4D34, 0x7BB1579A}, -+ {0xA0000000, 0x00000000}, - {0x4D34, 0x7BB167AB}, -+ {0xB0000000, 0x00000000}, - {0x4D38, 0xBBBBBB05}, - {0x4D3C, 0x777777BB}, - {0x4D40, 0x00015277}, -@@ -942,7 +1073,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4D48, 0x8C413016}, - {0x4D4C, 0xA140B028}, - {0x4D50, 0x00150A31}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x481C, 0x576DF814}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x481C, 0x576DF814}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x481C, 0x576BF814}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x481C, 0x576DF814}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x481C, 0x576DF814}, -+ {0xA0000000, 0x00000000}, -+ {0x481C, 0x576DF814}, -+ {0xB0000000, 0x00000000}, - {0x4820, 0xA08877AC}, - {0x4824, 0x0000007A}, - {0x4D54, 0x00001184}, -@@ -967,7 +1110,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4D78, 0x994C1502}, - {0x4D7C, 0x00017912}, - {0x4EDC, 0x00000001}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x484C, 0x0000CA62}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x484C, 0x00008A62}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x484C, 0x0000CA62}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, - {0x484C, 0x00008A62}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x484C, 0x00008A62}, -+ {0xA0000000, 0x00000000}, -+ {0x484C, 0x0000CA62}, -+ {0xB0000000, 0x00000000}, - {0x4D80, 0x00000002}, - {0x4850, 0x00000008}, - {0x4854, 0x009B902A}, -@@ -1014,7 +1169,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4DA0, 0x8C413016}, - {0x4DA4, 0xA140B028}, - {0x4DA8, 0x00150A31}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x48D4, 0x576DF814}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x48D4, 0x576BF814}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x48D4, 0x576BF814}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x48D4, 0x576BF814}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x48D4, 0x576BF814}, -+ {0xA0000000, 0x00000000}, - {0x48D4, 0x576DF814}, -+ {0xB0000000, 0x00000000}, - {0x48D8, 0xA08877AC}, - {0x48DC, 0x0000007A}, - {0x4DAC, 0x00001184}, -@@ -1039,7 +1206,19 @@ static const struct rtw89_reg2_def rtw89 - {0x4DD0, 0x994C1502}, - {0x4DD4, 0x00017912}, - {0x4EE4, 0x00000001}, -- {0x4904, 0x00008A62}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0xA0000000, 0x00000000}, -+ {0x4904, 0x0000CA62}, -+ {0xB0000000, 0x00000000}, - {0x4DD8, 0x00000002}, - {0x4908, 0x00000008}, - {0x490C, 0x80040000}, -@@ -1096,8 +1275,8 @@ static const struct rtw89_reg2_def rtw89 - {0x4988, 0x00000000}, - {0x498C, 0x00000000}, - {0x4E34, 0x00FC0000}, -- {0x4E38, 0x0000F800}, -- {0x4E3C, 0x00000001}, -+ {0x4E38, 0x00000000}, -+ {0x4E3C, 0x00000003}, - {0x4990, 0x00000000}, - {0x4994, 0x00000000}, - {0x4998, 0x00000000}, -@@ -1134,7 +1313,7 @@ static const struct rtw89_reg2_def rtw89 - {0x710, 0xEF810000}, - {0xC54, 0x1AE1436A}, - {0xC58, 0x41000000}, -- {0xC68, 0x10000050}, -+ {0xC68, 0x90000050}, - {0xC6C, 0x20061020}, - {0x704, 0x601E0100}, - {0xC74, 0x00000000}, -@@ -1225,12 +1404,12 @@ static const struct rtw89_reg2_def rtw89 - {0x328, 0xE000E000}, - {0x32C, 0x0041E000}, - {0x35C, 0x000004C4}, -- {0xC0D4, 0xA7C41460}, -+ {0xC0D4, 0xA7441460}, - {0xC0D8, 0xC6BA7F67}, - {0xC0DC, 0x30C52868}, - {0xC0E0, 0x75008128}, - {0xC0E4, 0x0000272B}, -- {0xC1D4, 0xA7C41460}, -+ {0xC1D4, 0xA7441460}, - {0xC1D8, 0xC6BA7F67}, - {0xC1DC, 0x30C52868}, - {0xC1E0, 0x75008128}, -@@ -1290,7 +1469,7 @@ static const struct rtw89_reg2_def rtw89 - {0xC8C, 0x02F2FC08}, - {0xC70, 0x071BFC00}, - {0x980, 0x10002251}, -- {0x988, 0x3C3C4107}, -+ {0x988, 0x3C3C8107}, - {0x904, 0x00000005}, - {0x994, 0x00000010}, - {0x000, 0x0580801F}, -@@ -1359,7 +1538,19 @@ static const struct rtw89_reg2_def rtw89 - {0x2310, 0xBC80536C}, - {0x2314, 0x0363A0F3}, - {0x2318, 0x000000BB}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x724, 0x00111200}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x724, 0x20111100}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x724, 0x20111100}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x724, 0x01100100}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x724, 0x01100100}, -+ {0xA0000000, 0x00000000}, - {0x724, 0x00111200}, -+ {0xB0000000, 0x00000000}, - {0x704, 0x601E0D00}, - {0xC78, 0xBFFFFFFF}, - {0x704, 0x601E0D02}, -@@ -1393,7 +1584,7 @@ static const struct rtw89_reg2_def rtw89 - {0xC60, 0x017FFFF3}, - {0xC70, 0x071BFE00}, - {0xC70, 0x071BFE60}, -- {0xC6C, 0x20061021}, -+ {0xC6C, 0x26061021}, - {0x58AC, 0x08000000}, - {0x78AC, 0x08000000}, - {0x8120, 0x10000000}, -@@ -1452,7 +1643,7 @@ static const struct rtw89_reg2_def rtw89 - {0x12A0, 0x24903056}, - {0x12AC, 0x12333121}, - {0x12B8, 0x30020000}, -- {0x2000, 0x18BBBF84}, -+ {0x2000, 0x20BBBF04}, - {0x2C14, 0x85000005}, - {0x3200, 0x00010142}, - {0x32A0, 0x24903056}, -@@ -1469,7 +1660,21 @@ static const struct rtw89_reg2_def rtw89 - {0x76C8, 0x0E800400}, - {0x984, 0x000000E0}, - {0x2008, 0x000FFFFF}, -+ {0x1210, 0x8049E304}, -+ {0x3210, 0x8049E304}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x58B0, 0x00000800}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x58B0, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x58B0, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x58B0, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x58B0, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x58B0, 0x00000800}, -+ {0xB0000000, 0x00000000}, - {0x5A00, 0x00000000}, - {0x5A04, 0x00000000}, - {0x5A08, 0x00000000}, -@@ -1479,7 +1684,19 @@ static const struct rtw89_reg2_def rtw89 - {0x5A18, 0x00000000}, - {0x5A1C, 0x00000000}, - {0x5A20, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x5A24, 0x00050000}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A24, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A24, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A24, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A24, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x5A24, 0x00050000}, -+ {0xB0000000, 0x00000000}, - {0x5A28, 0x00000000}, - {0x5A2C, 0x00000000}, - {0x5A30, 0x00000000}, -@@ -1487,14 +1704,38 @@ static const struct rtw89_reg2_def rtw89 - {0x5A38, 0x00000000}, - {0x5A3C, 0x00000000}, - {0x5A40, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A44, 0x00000005}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A44, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A44, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A44, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A44, 0x00000000}, -+ {0xA0000000, 0x00000000}, - {0x5A44, 0x00000005}, -+ {0xB0000000, 0x00000000}, - {0x5A48, 0x00000000}, - {0x5A4C, 0x00000000}, - {0x5A50, 0x00000000}, - {0x5A54, 0x00000000}, - {0x5A58, 0x00000000}, - {0x5A5C, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x5A60, 0x00050000}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A60, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A60, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A60, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5A60, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x5A60, 0x00050000}, -+ {0xB0000000, 0x00000000}, - {0x5A64, 0x00000000}, - {0x5A68, 0x00000000}, - {0x5A6C, 0x00000000}, -@@ -1514,12 +1755,49 @@ static const struct rtw89_reg2_def rtw89 - {0x5AA4, 0x00000000}, - {0x5AA8, 0x00000000}, - {0x5AAC, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x5AB0, 0x00050005}, - {0x5AB4, 0x00050005}, - {0x5AB8, 0x00050005}, - {0x5ABC, 0x00050005}, - {0x5AC0, 0x00000005}, - {0x78B0, 0x00000800}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5AB0, 0x00000000}, -+ {0x5AB4, 0x00000000}, -+ {0x5AB8, 0x00000000}, -+ {0x5ABC, 0x00000000}, -+ {0x5AC0, 0x00000000}, -+ {0x78B0, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5AB0, 0x00000000}, -+ {0x5AB4, 0x00000000}, -+ {0x5AB8, 0x00000000}, -+ {0x5ABC, 0x00000000}, -+ {0x5AC0, 0x00000000}, -+ {0x78B0, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5AB0, 0x00000000}, -+ {0x5AB4, 0x00000000}, -+ {0x5AB8, 0x00000000}, -+ {0x5ABC, 0x00000000}, -+ {0x5AC0, 0x00000000}, -+ {0x78B0, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x5AB0, 0x00000000}, -+ {0x5AB4, 0x00000000}, -+ {0x5AB8, 0x00000000}, -+ {0x5ABC, 0x00000000}, -+ {0x5AC0, 0x00000000}, -+ {0x78B0, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x5AB0, 0x00050005}, -+ {0x5AB4, 0x00050005}, -+ {0x5AB8, 0x00050005}, -+ {0x5ABC, 0x00050005}, -+ {0x5AC0, 0x00000005}, -+ {0x78B0, 0x00000800}, -+ {0xB0000000, 0x00000000}, - {0x7A00, 0x00000000}, - {0x7A04, 0x00000000}, - {0x7A08, 0x00000000}, -@@ -1529,7 +1807,19 @@ static const struct rtw89_reg2_def rtw89 - {0x7A18, 0x00000000}, - {0x7A1C, 0x00000000}, - {0x7A20, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x7A24, 0x00050000}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A24, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A24, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A24, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A24, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x7A24, 0x00050000}, -+ {0xB0000000, 0x00000000}, - {0x7A28, 0x00000000}, - {0x7A2C, 0x00000000}, - {0x7A30, 0x00000000}, -@@ -1537,14 +1827,38 @@ static const struct rtw89_reg2_def rtw89 - {0x7A38, 0x00000000}, - {0x7A3C, 0x00000000}, - {0x7A40, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x7A44, 0x00000005}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A44, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A44, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A44, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A44, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x7A44, 0x00000005}, -+ {0xB0000000, 0x00000000}, - {0x7A48, 0x00000000}, - {0x7A4C, 0x00000000}, - {0x7A50, 0x00000000}, - {0x7A54, 0x00000000}, - {0x7A58, 0x00000000}, - {0x7A5C, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A60, 0x00050000}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A60, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A60, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A60, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7A60, 0x00000000}, -+ {0xA0000000, 0x00000000}, - {0x7A60, 0x00050000}, -+ {0xB0000000, 0x00000000}, - {0x7A64, 0x00000000}, - {0x7A68, 0x00000000}, - {0x7A6C, 0x00000000}, -@@ -1564,143 +1878,223 @@ static const struct rtw89_reg2_def rtw89 - {0x7AA4, 0x00000000}, - {0x7AA8, 0x00000000}, - {0x7AAC, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x7AB0, 0x00050005}, - {0x7AB4, 0x00050005}, - {0x7AB8, 0x00050005}, - {0x7ABC, 0x00050005}, - {0x7AC0, 0x00000005}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7AB0, 0x00000000}, -+ {0x7AB4, 0x00000000}, -+ {0x7AB8, 0x00000000}, -+ {0x7ABC, 0x00000000}, -+ {0x7AC0, 0x00000000}, -+ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7AB0, 0x00000000}, -+ {0x7AB4, 0x00000000}, -+ {0x7AB8, 0x00000000}, -+ {0x7ABC, 0x00000000}, -+ {0x7AC0, 0x00000000}, -+ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7AB0, 0x00000000}, -+ {0x7AB4, 0x00000000}, -+ {0x7AB8, 0x00000000}, -+ {0x7ABC, 0x00000000}, -+ {0x7AC0, 0x00000000}, -+ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x7AB0, 0x00000000}, -+ {0x7AB4, 0x00000000}, -+ {0x7AB8, 0x00000000}, -+ {0x7ABC, 0x00000000}, -+ {0x7AC0, 0x00000000}, -+ {0xA0000000, 0x00000000}, -+ {0x7AB0, 0x00050005}, -+ {0x7AB4, 0x00050005}, -+ {0x7AB8, 0x00050005}, -+ {0x7ABC, 0x00050005}, -+ {0x7AC0, 0x00000005}, -+ {0xB0000000, 0x00000000}, - {0x0F0, 0x00010000}, -- {0x0F4, 0x00000018}, -- {0x0F8, 0x20220120}, -+ {0x0F4, 0x00000028}, -+ {0x0F8, 0x20220610}, - }; - - static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { - {0xF0FF0000, 0x00000000}, - {0xF03300FF, 0x00000001}, -- {0x000, 0x01E3C39F}, -- {0x001, 0x00694727}, -- {0x002, 0x00005536}, -- {0x100, 0x02E3C39F}, -- {0x101, 0x0069472A}, -+ {0x000, 0x0EEECAA6}, -+ {0x001, 0x006C4B2C}, -+ {0x002, 0x00005636}, -+ {0x100, 0x0DEFCAA9}, -+ {0x101, 0x00694B2C}, - {0x102, 0x00005536}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x10000, 0x1A02E1C9}, - {0x10001, 0x00644A30}, - {0x10002, 0x00006750}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x10000, 0x0EF4D1B9}, -- {0x10001, 0x00584125}, -- {0x10002, 0x00006750}, -+ {0x10000, 0x0BF1CEB6}, -+ {0x10001, 0x00434328}, -+ {0x10002, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x10000, 0x1A02E1C9}, -- {0x10001, 0x00644A30}, -- {0x10002, 0x00006750}, -+ {0x10000, 0x1D08E8D0}, -+ {0x10001, 0x00644C32}, -+ {0x10002, 0x00006650}, - {0xB0000000, 0x00000000}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x10100, 0x1901E1C8}, - {0x10101, 0x0061482D}, - {0x10102, 0x00006750}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x10100, 0x04E8C5AD}, -- {0x10101, 0x00594125}, -- {0x10102, 0x00006850}, -+ {0x10100, 0x0BF0CEB8}, -+ {0x10101, 0x00424227}, -+ {0x10102, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x10100, 0x1901E1C8}, -- {0x10101, 0x0061482D}, -- {0x10102, 0x00006750}, -+ {0x10100, 0x1F0AECD5}, -+ {0x10101, 0x00634B31}, -+ {0x10102, 0x00006550}, - {0xB0000000, 0x00000000}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x20000, 0x1601E2CA}, - {0x20001, 0x005D452A}, - {0x20002, 0x00006750}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x20000, 0x0EF4D3BB}, -- {0x20001, 0x00563F25}, -- {0x20002, 0x00006850}, -+ {0x20000, 0x0EF5D3BB}, -+ {0x20001, 0x00454529}, -+ {0x20002, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x20000, 0x1601E2CA}, -- {0x20001, 0x005D452A}, -- {0x20002, 0x00006750}, -+ {0x20000, 0x1904E6CE}, -+ {0x20001, 0x0060482D}, -+ {0x20002, 0x00006650}, - {0xB0000000, 0x00000000}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x20100, 0x1901E1C8}, - {0x20101, 0x0061482D}, - {0x20102, 0x00006750}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x20100, 0x0BF1CFB7}, -- {0x20101, 0x00574025}, -- {0x20102, 0x00006750}, -+ {0x20100, 0x12F8D7C1}, -+ {0x20101, 0x004A4A2E}, -+ {0x20102, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x20100, 0x1901E1C8}, -+ {0x20100, 0x1F0AECD5}, - {0x20101, 0x0061482D}, -- {0x20102, 0x00006750}, -+ {0x20102, 0x00006550}, - {0xB0000000, 0x00000000}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x30000, 0x1700E1CA}, - {0x30001, 0x005E472B}, - {0x30002, 0x00006750}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x30000, 0x05EFCEB7}, -- {0x30001, 0x004B351A}, -- {0x30002, 0x00006850}, -+ {0x30000, 0x0DF6D5BE}, -+ {0x30001, 0x00414126}, -+ {0x30002, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x30000, 0x1700E1CA}, -- {0x30001, 0x005E472B}, -- {0x30002, 0x00006750}, -+ {0x30000, 0x14FEE0CA}, -+ {0x30001, 0x005C4328}, -+ {0x30002, 0x00006650}, - {0xB0000000, 0x00000000}, - {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x30100, 0x14FEE0C9}, - {0x30101, 0x00594428}, - {0x30102, 0x00006650}, - {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -- {0x30100, 0x0CF2D1B9}, -- {0x30101, 0x00563F24}, -- {0x30102, 0x00006750}, -+ {0x30100, 0x0EF5D5C0}, -+ {0x30101, 0x0045452A}, -+ {0x30102, 0x00005050}, - {0xA0000000, 0x00000000}, -- {0x30100, 0x14FEE0C9}, -- {0x30101, 0x00594428}, -+ {0x30100, 0x1F0AECD8}, -+ {0x30101, 0x00654C31}, - {0x30102, 0x00006650}, - {0xB0000000, 0x00000000}, -- {0x40000, 0x13FCDDC8}, -- {0x40001, 0x005D4328}, -- {0x40002, 0x00006850}, -- {0x40100, 0x14FEE3CF}, -- {0x40101, 0x00583E24}, -- {0x40102, 0x00006850}, -- {0x50000, 0x0DF4D6C6}, -- {0x50001, 0x00604227}, -- {0x50002, 0x00006850}, -- {0x50100, 0x1903E7D5}, -- {0x50101, 0x0061462B}, -- {0x50102, 0x00006850}, -- {0x60000, 0x0FF5D7C6}, -- {0x60001, 0x005D4429}, -- {0x60002, 0x00006850}, -- {0x60100, 0x12FADECF}, -- {0x60101, 0x005B4126}, -- {0x60102, 0x00006850}, -- {0x70000, 0x09F1D2C3}, -- {0x70001, 0x00554026}, -- {0x70002, 0x00006750}, -- {0x70100, 0x0CF5DACC}, -- {0x70101, 0x00563E25}, -- {0x70102, 0x00006750}, -+ {0x40000, 0x15FEE0CB}, -+ {0x40001, 0x0060462B}, -+ {0x40002, 0x00006450}, -+ {0x40100, 0x1902E5D2}, -+ {0x40101, 0x0063482E}, -+ {0x40102, 0x00006450}, -+ {0x50000, 0x1C04E6D3}, -+ {0x50001, 0x006B5034}, -+ {0x50002, 0x00006450}, -+ {0x50100, 0x2009EDDB}, -+ {0x50101, 0x006B5035}, -+ {0x50102, 0x00006450}, -+ {0x60000, 0x16FEE1CF}, -+ {0x60001, 0x00634A2E}, -+ {0x60002, 0x00006550}, -+ {0x60100, 0x14FDE2D2}, -+ {0x60101, 0x005E4429}, -+ {0x60102, 0x00006450}, -+ {0x70000, 0x0BF3D6C6}, -+ {0x70001, 0x00573F24}, -+ {0x70002, 0x00006550}, -+ {0x70100, 0x08F0D6C7}, -+ {0x70101, 0x0052391E}, -+ {0x70102, 0x00006450}, - {0x2000000, 0x02E4C4A0}, - {0x2000001, 0x006A4828}, - {0x2000100, 0x02E4C5A1}, - {0x2000101, 0x00664629}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2010000, 0x05EBC8AF}, - {0x2010001, 0x00543D24}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2010000, 0x08EDCAB2}, -+ {0x2010001, 0x00434327}, -+ {0xA0000000, 0x00000000}, -+ {0x2010000, 0x05EBC8AF}, -+ {0x2010001, 0x00543D24}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2010100, 0x07ECC9B0}, - {0x2010101, 0x005B4126}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2010100, 0x08ECCBB2}, -+ {0x2010101, 0x003C3C20}, -+ {0xA0000000, 0x00000000}, -+ {0x2010100, 0x07ECC9B0}, -+ {0x2010101, 0x005B4126}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2020000, 0x05EDCCB2}, - {0x2020001, 0x004D361C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2020000, 0x0CF4D2BA}, -+ {0x2020001, 0x00404025}, -+ {0xA0000000, 0x00000000}, -+ {0x2020000, 0x05EDCCB2}, -+ {0x2020001, 0x004D361C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2020100, 0x06ECCBB2}, - {0x2020101, 0x00553D22}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2020100, 0x09EECDB8}, -+ {0x2020101, 0x00444428}, -+ {0xA0000000, 0x00000000}, -+ {0x2020100, 0x06ECCBB2}, -+ {0x2020101, 0x00553D22}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2030000, 0x02ECCCB3}, - {0x2030001, 0x00483118}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2030000, 0x0DF8D6BF}, -+ {0x2030001, 0x003F3F24}, -+ {0xA0000000, 0x00000000}, -+ {0x2030000, 0x02ECCCB3}, -+ {0x2030001, 0x00483118}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x2030100, 0x04ECCCB2}, - {0x2030101, 0x004F381C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x2030100, 0x08EFCDBA}, -+ {0x2030101, 0x00414126}, -+ {0xA0000000, 0x00000000}, -+ {0x2030100, 0x04ECCCB2}, -+ {0x2030101, 0x004F381C}, -+ {0xB0000000, 0x00000000}, - {0x3000000, 0x00000000}, - {0x3000001, 0x00000000}, - {0x3000002, 0x00000000}, -@@ -1709,30 +2103,102 @@ static const struct rtw89_reg2_def rtw89 - {0x3000101, 0x00000000}, - {0x3000102, 0x00000000}, - {0x3000103, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3010000, 0x0E0CFB0A}, -+ {0x3010001, 0x00100F06}, -+ {0x3010002, 0x34333333}, -+ {0x3010003, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3010000, 0x0E0CFB0A}, -+ {0x3010001, 0x00100F06}, -+ {0x3010002, 0x34333327}, -+ {0x3010003, 0x3434343C}, -+ {0xA0000000, 0x00000000}, - {0x3010000, 0x0E0CFB0A}, - {0x3010001, 0x00100F06}, - {0x3010002, 0x34333333}, - {0x3010003, 0x3434343C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x3010100, 0x0E0CFB0A}, - {0x3010101, 0x00100F06}, - {0x3010102, 0x34333333}, - {0x3010103, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3010100, 0x0E0CFB0A}, -+ {0x3010101, 0x00100F06}, -+ {0x3010102, 0x34333327}, -+ {0x3010103, 0x3434343C}, -+ {0xA0000000, 0x00000000}, -+ {0x3010100, 0x0E0CFB0A}, -+ {0x3010101, 0x00100F06}, -+ {0x3010102, 0x34333333}, -+ {0x3010103, 0x3434343C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x3020000, 0x0E0CFB0A}, - {0x3020001, 0x00100F06}, - {0x3020002, 0x34333333}, - {0x3020003, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3020000, 0x0E0CFB0A}, -+ {0x3020001, 0x00100F06}, -+ {0x3020002, 0x34333327}, -+ {0x3020003, 0x3434343C}, -+ {0xA0000000, 0x00000000}, -+ {0x3020000, 0x0E0CFB0A}, -+ {0x3020001, 0x00100F06}, -+ {0x3020002, 0x34333333}, -+ {0x3020003, 0x3434343C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x3020100, 0x0E0CFB0A}, - {0x3020101, 0x00100F06}, - {0x3020102, 0x34333333}, - {0x3020103, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3020100, 0x0E0CFB0A}, -+ {0x3020101, 0x00100F06}, -+ {0x3020102, 0x34333327}, -+ {0x3020103, 0x3434343C}, -+ {0xA0000000, 0x00000000}, -+ {0x3020100, 0x0E0CFB0A}, -+ {0x3020101, 0x00100F06}, -+ {0x3020102, 0x34333333}, -+ {0x3020103, 0x3434343C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x3030000, 0x0E0CFB0A}, - {0x3030001, 0x00100F06}, - {0x3030002, 0x34333333}, - {0x3030003, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3030000, 0x0E0CFB0A}, -+ {0x3030001, 0x00100F06}, -+ {0x3030002, 0x34333327}, -+ {0x3030003, 0x3434343C}, -+ {0xA0000000, 0x00000000}, -+ {0x3030000, 0x0E0CFB0A}, -+ {0x3030001, 0x00100F06}, -+ {0x3030002, 0x34333333}, -+ {0x3030003, 0x3434343C}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, - {0x3030100, 0x0E0CFB0A}, - {0x3030101, 0x00100F06}, - {0x3030102, 0x34333333}, - {0x3030103, 0x3434343C}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x3030100, 0x0E0CFB0A}, -+ {0x3030101, 0x00100F06}, -+ {0x3030102, 0x34333327}, -+ {0x3030103, 0x3434343C}, -+ {0xA0000000, 0x00000000}, -+ {0x3030100, 0x0E0CFB0A}, -+ {0x3030101, 0x00100F06}, -+ {0x3030102, 0x34333333}, -+ {0x3030103, 0x3434343C}, -+ {0xB0000000, 0x00000000}, - {0x3040000, 0x0E0CFB0A}, - {0x3040001, 0x00100F06}, - {0x3040002, 0x343B3333}, -@@ -1765,6 +2231,310 @@ static const struct rtw89_reg2_def rtw89 - {0x3070101, 0x00100F06}, - {0x3070102, 0x3C3B3333}, - {0x3070103, 0x34343C3C}, -+ {0x4000000, 0x00000000}, -+ {0x4000001, 0x76543210}, -+ {0x4000002, 0x77777777}, -+ {0x4000003, 0x35374425}, -+ {0x4000004, 0x00000043}, -+ {0x4000005, 0x000038E8}, -+ {0x4000100, 0x00000000}, -+ {0x4000101, 0x76543210}, -+ {0x4000102, 0x77777777}, -+ {0x4000103, 0x35374425}, -+ {0x4000104, 0x00000043}, -+ {0x4000105, 0x000038E8}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4010000, 0x00000000}, -+ {0x4010001, 0x76543210}, -+ {0x4010002, 0x77777777}, -+ {0x4010003, 0x35374425}, -+ {0x4010004, 0x00000042}, -+ {0x4010005, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4010000, 0x0000FC50}, -+ {0x4010001, 0x51403210}, -+ {0x4010002, 0x76543276}, -+ {0x4010003, 0x3A4DAA3C}, -+ {0x4010004, 0x00000093}, -+ {0x4010005, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4010000, 0x00000000}, -+ {0x4010001, 0x76543210}, -+ {0x4010002, 0x77777777}, -+ {0x4010003, 0x35374425}, -+ {0x4010004, 0x00000042}, -+ {0x4010005, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4010100, 0x00000000}, -+ {0x4010101, 0x76543210}, -+ {0x4010102, 0x77777777}, -+ {0x4010103, 0x35374425}, -+ {0x4010104, 0x00000042}, -+ {0x4010105, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4010100, 0x0000FC50}, -+ {0x4010101, 0x51403210}, -+ {0x4010102, 0x76543276}, -+ {0x4010103, 0x3A4DAA3C}, -+ {0x4010104, 0x00000093}, -+ {0x4010105, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4010100, 0x00000000}, -+ {0x4010101, 0x76543210}, -+ {0x4010102, 0x77777777}, -+ {0x4010103, 0x35374425}, -+ {0x4010104, 0x00000042}, -+ {0x4010105, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4020000, 0x00000000}, -+ {0x4020001, 0x76543210}, -+ {0x4020002, 0x77777777}, -+ {0x4020003, 0x35374425}, -+ {0x4020004, 0x00000042}, -+ {0x4020005, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4020000, 0x0000FC50}, -+ {0x4020001, 0x51403210}, -+ {0x4020002, 0x76543276}, -+ {0x4020003, 0x4B4DAA3C}, -+ {0x4020004, 0x000000A3}, -+ {0x4020005, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4020000, 0x00000000}, -+ {0x4020001, 0x76543210}, -+ {0x4020002, 0x77777777}, -+ {0x4020003, 0x35374425}, -+ {0x4020004, 0x00000042}, -+ {0x4020005, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4020100, 0x00000000}, -+ {0x4020101, 0x76543210}, -+ {0x4020102, 0x77777777}, -+ {0x4020103, 0x35374425}, -+ {0x4020104, 0x00000042}, -+ {0x4020105, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4020100, 0x0000FC50}, -+ {0x4020101, 0x51403210}, -+ {0x4020102, 0x76543276}, -+ {0x4020103, 0x3A4DAA3C}, -+ {0x4020104, 0x00000093}, -+ {0x4020105, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4020100, 0x00000000}, -+ {0x4020101, 0x76543210}, -+ {0x4020102, 0x77777777}, -+ {0x4020103, 0x35374425}, -+ {0x4020104, 0x00000042}, -+ {0x4020105, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4030000, 0x00000000}, -+ {0x4030001, 0x76543210}, -+ {0x4030002, 0x77777777}, -+ {0x4030003, 0x35374425}, -+ {0x4030004, 0x00000042}, -+ {0x4030005, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4030000, 0x0000FC50}, -+ {0x4030001, 0x51403210}, -+ {0x4030002, 0x76543276}, -+ {0x4030003, 0x3A4DAA3C}, -+ {0x4030004, 0x00000093}, -+ {0x4030005, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4030000, 0x00000000}, -+ {0x4030001, 0x76543210}, -+ {0x4030002, 0x77777777}, -+ {0x4030003, 0x35374425}, -+ {0x4030004, 0x00000042}, -+ {0x4030005, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4030100, 0x00000000}, -+ {0x4030101, 0x76543210}, -+ {0x4030102, 0x77777777}, -+ {0x4030103, 0x35374425}, -+ {0x4030104, 0x00000042}, -+ {0x4030105, 0x000038E8}, -+ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x4030100, 0x0000FC50}, -+ {0x4030101, 0x51403210}, -+ {0x4030102, 0x76543276}, -+ {0x4030103, 0x3A4DAA3C}, -+ {0x4030104, 0x00000093}, -+ {0x4030105, 0x000040E4}, -+ {0xA0000000, 0x00000000}, -+ {0x4030100, 0x00000000}, -+ {0x4030101, 0x76543210}, -+ {0x4030102, 0x77777777}, -+ {0x4030103, 0x35374425}, -+ {0x4030104, 0x00000042}, -+ {0x4030105, 0x000038E8}, -+ {0xB0000000, 0x00000000}, -+ {0x1000000, 0x00000008}, -+ {0x1000010, 0x00000008}, -+ {0x1000011, 0x00000000}, -+ {0x1000100, 0x00000004}, -+ {0x1000110, 0x00000004}, -+ {0x1000111, 0x00000000}, -+ {0x1010000, 0x00000004}, -+ {0x1010010, 0x00000004}, -+ {0x1010011, 0x00000000}, -+ {0x1010020, 0x00000004}, -+ {0x1010021, 0x00000000}, -+ {0x1010029, 0x00000000}, -+ {0x1010030, 0x00000000}, -+ {0x1010031, 0x00000000}, -+ {0x1010035, 0x00000000}, -+ {0x1010039, 0x00000000}, -+ {0x101003D, 0x00000000}, -+ {0x1010100, 0x00000010}, -+ {0x1010110, 0x00000010}, -+ {0x1010111, 0x00000000}, -+ {0x1010120, 0x00000010}, -+ {0x1010121, 0x00000000}, -+ {0x1010129, 0x00000000}, -+ {0x1010030, 0x00000000}, -+ {0x1010031, 0x00000000}, -+ {0x1010035, 0x00000000}, -+ {0x1010039, 0x00000000}, -+ {0x101003D, 0x00000000}, -+ {0x1020000, 0x000000FA}, -+ {0x1020010, 0x000000FA}, -+ {0x1020011, 0x00000000}, -+ {0x1020020, 0x000000FA}, -+ {0x1020021, 0x00000000}, -+ {0x1020029, 0x00000000}, -+ {0x1020030, 0x00000000}, -+ {0x1020031, 0x00000000}, -+ {0x1020035, 0x00000000}, -+ {0x1020039, 0x00000000}, -+ {0x102003D, 0x00000000}, -+ {0x1020100, 0x0000000D}, -+ {0x1020110, 0x0000000D}, -+ {0x1020111, 0x00000000}, -+ {0x1020120, 0x0000000D}, -+ {0x1020121, 0x00000000}, -+ {0x1020129, 0x00000000}, -+ {0x1020030, 0x00000000}, -+ {0x1020031, 0x00000000}, -+ {0x1020035, 0x00000000}, -+ {0x1020039, 0x00000000}, -+ {0x102003D, 0x00000000}, -+ {0x1030000, 0x000000E4}, -+ {0x1030010, 0x000000E4}, -+ {0x1030011, 0x00000000}, -+ {0x1030020, 0x0000E8E8}, -+ {0x1030021, 0x00000000}, -+ {0x1030029, 0x00000000}, -+ {0x1030030, 0x00000000}, -+ {0x1030031, 0x00000000}, -+ {0x1030035, 0x00000000}, -+ {0x1030039, 0x00000000}, -+ {0x103003D, 0x00000000}, -+ {0x1030100, 0x00000018}, -+ {0x1030110, 0x00000018}, -+ {0x1030111, 0x00000000}, -+ {0x1030120, 0x00000018}, -+ {0x1030121, 0x00000000}, -+ {0x1030129, 0x00000000}, -+ {0x1030030, 0x00000000}, -+ {0x1030031, 0x00000000}, -+ {0x1030035, 0x00000000}, -+ {0x1030039, 0x00000000}, -+ {0x103003D, 0x00000000}, -+ {0x1040000, 0x000000EE}, -+ {0x1040010, 0x000000EE}, -+ {0x1040011, 0x00000000}, -+ {0x1040020, 0x000000EE}, -+ {0x1040021, 0x00000000}, -+ {0x1040029, 0x00000000}, -+ {0x1040030, 0x000000EE}, -+ {0x1040031, 0x00000000}, -+ {0x1040035, 0x00000000}, -+ {0x1040039, 0x00000000}, -+ {0x104003D, 0x00000000}, -+ {0x1040100, 0x00000000}, -+ {0x1040110, 0x00000005}, -+ {0x1040111, 0x00000000}, -+ {0x1040120, 0x00000008}, -+ {0x1040121, 0x00000000}, -+ {0x1040129, 0x00000000}, -+ {0x1040030, 0x00000008}, -+ {0x1040031, 0x00000000}, -+ {0x1040035, 0x00000000}, -+ {0x1040039, 0x00000000}, -+ {0x104003D, 0x00000000}, -+ {0x1050000, 0x00000008}, -+ {0x1050010, 0x0000000B}, -+ {0x1050011, 0x00000000}, -+ {0x1050020, 0x00000015}, -+ {0x1050021, 0x00000000}, -+ {0x1050029, 0x00000000}, -+ {0x1050030, 0x00000010}, -+ {0x1050031, 0x00000000}, -+ {0x1050035, 0x00000000}, -+ {0x1050039, 0x00000000}, -+ {0x105003D, 0x00000000}, -+ {0x1050100, 0x00000016}, -+ {0x1050110, 0x00000016}, -+ {0x1050111, 0x0000F8F8}, -+ {0x1050120, 0x0000001A}, -+ {0x1050121, 0x00000000}, -+ {0x1050129, 0x00000000}, -+ {0x1050030, 0x0000001A}, -+ {0x1050031, 0x00000000}, -+ {0x1050035, 0x00000000}, -+ {0x1050039, 0x00000000}, -+ {0x105003D, 0x00000000}, -+ {0x1060000, 0x000000F8}, -+ {0x1060010, 0x000000F8}, -+ {0x1060011, 0x00000000}, -+ {0x1060020, 0x00000000}, -+ {0x1060021, 0x00000000}, -+ {0x1060029, 0x00000000}, -+ {0x1060030, 0x00000000}, -+ {0x1060031, 0x00000000}, -+ {0x1060035, 0x00000000}, -+ {0x1060039, 0x00000000}, -+ {0x106003D, 0x00000000}, -+ {0x1060100, 0x000000F6}, -+ {0x1060110, 0x000000F6}, -+ {0x1060111, 0x00000000}, -+ {0x1060120, 0x000000F6}, -+ {0x1060121, 0x00000000}, -+ {0x1060129, 0x00000000}, -+ {0x1060030, 0x00000000}, -+ {0x1060031, 0x00000000}, -+ {0x1060035, 0x00000000}, -+ {0x1060039, 0x00000000}, -+ {0x106003D, 0x00000000}, -+ {0x1070000, 0x000000E8}, -+ {0x1070010, 0x000000E8}, -+ {0x1070011, 0x00000000}, -+ {0x1070020, 0x000000E8}, -+ {0x1070021, 0x00000000}, -+ {0x1070029, 0x00000000}, -+ {0x1070030, 0x000000F0}, -+ {0x1070031, 0x00000000}, -+ {0x1070035, 0x00000000}, -+ {0x1070039, 0x00000000}, -+ {0x107003D, 0x00000000}, -+ {0x1070100, 0x000000E4}, -+ {0x1070110, 0x000000E4}, -+ {0x1070111, 0x00000000}, -+ {0x1070120, 0x000000E4}, -+ {0x1070121, 0x00000000}, -+ {0x1070129, 0x00000000}, -+ {0x1070030, 0x000000F0}, -+ {0x1070031, 0x00000000}, -+ {0x1070035, 0x00000000}, -+ {0x1070039, 0x00000000}, -+ {0x107003D, 0x00000000}, - }; - - static const struct rtw89_reg2_def rtw89_8852c_phy_radioa_regs[] = { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch deleted file mode 100644 index 1b0fe1a22..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c6a9d360874a41dc972c44c0949916da55199f85 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:36:59 +0800 -Subject: [PATCH 013/149] wifi: rtw89: phy: ignore warning of bb gain cfg_type - 4 - -The new BB parameters add new cfg_tpe 4 to improve performance of eFEM -modules (rfe_type >= 50), but we are using iFEM modules for now, so this -warning can be ignored. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930133659.7789-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1036,6 +1036,7 @@ static void rtw89_phy_config_bb_gain(str - { - const struct rtw89_chip_info *chip = rtwdev->chip; - union rtw89_phy_bb_gain_arg arg = { .addr = reg->addr }; -+ struct rtw89_efuse *efuse = &rtwdev->efuse; - - if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR) - return; -@@ -1061,6 +1062,11 @@ static void rtw89_phy_config_bb_gain(str - case 3: - rtw89_phy_cfg_bb_gain_op1db(rtwdev, arg, reg->data); - break; -+ case 4: -+ /* This cfg_type is only used by rfe_type >= 50 with eFEM */ -+ if (efuse->rfe_type < 50) -+ break; -+ fallthrough; - default: - rtw89_warn(rtwdev, - "bb gain {0x%x:0x%x} with unknown cfg type: %d\n", diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch deleted file mode 100644 index ef32f6280..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d187691ab63f53f199a07904422e0911bc6f9390 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:44:16 +0800 -Subject: [PATCH 014/149] wifi: rtw89: 8852c: set pin MUX to enable BT firmware - log - -8852CE is a combo chip, and WiFi driver controls pin MUX. To output BT -firmware log to specific hardware pin, set pin MUX to achieve. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930134417.10282-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 4 ++++ - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 +++ - 2 files changed, 7 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -229,6 +229,10 @@ - - #define R_AX_GPIO0_7_FUNC_SEL 0x02D0 - -+#define R_AX_LED1_FUNC_SEL 0x02DC -+#define B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK GENMASK(27, 24) -+#define PINMUX_EESK_FUNC_SEL_BT_LOG 0x1 -+ - #define R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN 0x02E4 - #define B_AX_LED1_PULL_LOW_EN BIT(18) - #define B_AX_EESK_PULL_LOW_EN BIT(17) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -273,6 +273,9 @@ static int rtw8852c_pwr_on_func(struct r - B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | - B_AX_TMAC_EN | B_AX_RMAC_EN); - -+ rtw89_write32_mask(rtwdev, R_AX_LED1_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK, -+ PINMUX_EESK_FUNC_SEL_BT_LOG); -+ - return 0; - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch deleted file mode 100644 index cd9c3f74d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 732dd91db3d3a1b7a767598549ffed358c9fbb89 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 30 Sep 2022 21:44:17 +0800 -Subject: [PATCH 015/149] wifi: rtw89: add to dump TX FIFO 0/1 for 8852C - -MAC maintains TX FIFO to transmit packets with meta data to BB layer. To -debug abnormal transmission, we need to dump the content to dig problem. -Since FIFO of 8852C locates on different address with different size and -need additional switch to enable read operation, this patch adds the -changes accordingly. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20220930134417.10282-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 21 +++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.c | 2 ++ - drivers/net/wireless/realtek/rtw89/mac.h | 4 ++++ - 3 files changed, 27 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -781,13 +781,34 @@ rtw89_debug_priv_mac_mem_dump_get(struct - { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -+ bool grant_read = false; -+ -+ if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM) -+ return -ENOENT; -+ -+ if (rtwdev->chip->chip_id == RTL8852C) { -+ switch (debugfs_priv->mac_mem.sel) { -+ case RTW89_MAC_MEM_TXD_FIFO_0_V1: -+ case RTW89_MAC_MEM_TXD_FIFO_1_V1: -+ case RTW89_MAC_MEM_TXDATA_FIFO_0: -+ case RTW89_MAC_MEM_TXDATA_FIFO_1: -+ grant_read = true; -+ break; -+ default: -+ break; -+ } -+ } - - mutex_lock(&rtwdev->mutex); - rtw89_leave_ps_mode(rtwdev); -+ if (grant_read) -+ rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); - rtw89_debug_dump_mac_mem(m, rtwdev, - debugfs_priv->mac_mem.sel, - debugfs_priv->mac_mem.start, - debugfs_priv->mac_mem.len); -+ if (grant_read) -+ rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); - mutex_unlock(&rtwdev->mutex); - - return 0; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -31,6 +31,8 @@ const u32 rtw89_mac_mem_base_addrs[RTW89 - [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR, - [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR, - [RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR, -+ [RTW89_MAC_MEM_TXD_FIFO_0_V1] = TXD_FIFO_0_BASE_ADDR_V1, -+ [RTW89_MAC_MEM_TXD_FIFO_1_V1] = TXD_FIFO_1_BASE_ADDR_V1, - }; - - static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset, ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -245,6 +245,8 @@ enum rtw89_mac_dbg_port_sel { - #define BCN_IE_CAM1_BASE_ADDR 0x188A0000 - #define TXD_FIFO_0_BASE_ADDR 0x18856200 - #define TXD_FIFO_1_BASE_ADDR 0x188A1080 -+#define TXD_FIFO_0_BASE_ADDR_V1 0x18856400 /* for 8852C */ -+#define TXD_FIFO_1_BASE_ADDR_V1 0x188A1080 /* for 8852C */ - #define TXDATA_FIFO_0_BASE_ADDR 0x18856000 - #define TXDATA_FIFO_1_BASE_ADDR 0x188A1000 - #define CPU_LOCAL_BASE_ADDR 0x18003000 -@@ -271,6 +273,8 @@ enum rtw89_mac_mem_sel { - RTW89_MAC_MEM_TXDATA_FIFO_1, - RTW89_MAC_MEM_CPU_LOCAL, - RTW89_MAC_MEM_BSSID_CAM, -+ RTW89_MAC_MEM_TXD_FIFO_0_V1, -+ RTW89_MAC_MEM_TXD_FIFO_1_V1, - - /* keep last */ - RTW89_MAC_MEM_NUM, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-016-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-016-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch deleted file mode 100644 index c821469c2..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-016-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a790cc3a4fad75048295571a350b95b87e022a5a Mon Sep 17 00:00:00 2001 -From: Alexander Wetzel -Date: Sun, 9 Oct 2022 18:30:39 +0200 -Subject: [PATCH 016/149] wifi: mac80211: add wake_tx_queue callback to drivers - -mac80211 is fully switching over to the internal TX queue (iTXQ) -implementation. Update all drivers not yet providing the now mandatory -wake_tx_queue() callback. - -As an side effect the netdev interfaces of all updated drivers will -switch to the noqueue qdisc. - -Signed-off-by: Alexander Wetzel -[add staging drivers] -Signed-off-by: Johannes Berg ---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru - - const struct ieee80211_ops rtw89_ops = { - .tx = rtw89_ops_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw89_ops_wake_tx_queue, - .start = rtw89_ops_start, - .stop = rtw89_ops_stop, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-017-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-017-wifi-realtek-remove-duplicated-wake_tx_queue.patch deleted file mode 100644 index 2b159056a..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-017-wifi-realtek-remove-duplicated-wake_tx_queue.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 53d0ce0c56d9330f137936b8850d4a5f2f70907d Mon Sep 17 00:00:00 2001 -From: Johannes Berg -Date: Mon, 10 Oct 2022 19:17:46 +0200 -Subject: [PATCH 017/149] wifi: realtek: remove duplicated wake_tx_queue - -By accident, the previous patch duplicated the initialization -of the wake_tx_queue callback. Fix that by removing the new -initializations. - -Fixes: a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers") -Signed-off-by: Johannes Berg ---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru - - const struct ieee80211_ops rtw89_ops = { - .tx = rtw89_ops_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw89_ops_wake_tx_queue, - .start = rtw89_ops_start, - .stop = rtw89_ops_stop, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-018-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-018-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch deleted file mode 100644 index 2fa9b25e4..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-018-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 127da1aa61859c1eb27d7fc2d5b936e9e528815d Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 5 Oct 2022 16:32:07 +0800 -Subject: [PATCH 018/149] wifi: rtw89: coex: move chip_ops::btc_bt_aci_imp to a - generic code - -This chunk is to set fixed BT LNA2 at level5 when WiFi/BT shared BTG RFC -to improve BT anti-interference ability from adjacent channel. Since all -chips use the same setting, remove chip_ops::btc_bt_aci_imp. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 9 +++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 1 - - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 14 -------------- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 -------------- - 4 files changed, 7 insertions(+), 31 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1809,13 +1809,18 @@ static void _set_rf_trx_para(struct rtw8 - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_bt_info *bt = &btc->cx.bt; -+ struct rtw89_btc_bt_link_info *b = &bt->link_info; - struct rtw89_btc_rf_trx_para para; - u32 wl_stb_chg = 0; - u8 level_id = 0; - - if (!dm->freerun) { -- dm->trx_para_level = 0; -- chip->ops->btc_bt_aci_imp(rtwdev); -+ /* fix LNA2 = level-5 for BT ACI issue at BTG */ -+ if ((btc->dm.wl_btg_rx && b->profile_cnt.now != 0) || -+ dm->bt_only == 1) -+ dm->trx_para_level = 1; -+ else -+ dm->trx_para_level = 0; - } - - level_id = (u8)dm->trx_para_level; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2363,7 +2363,6 @@ struct rtw89_chip_ops { - void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); - void (*btc_set_wl_txpwr_ctrl)(struct rtw89_dev *rtwdev, u32 txpwr_val); - s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); -- void (*btc_bt_aci_imp)(struct rtw89_dev *rtwdev); - void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); - void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); - void (*btc_set_policy)(struct rtw89_dev *rtwdev, u16 policy_type); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1871,19 +1871,6 @@ static struct rtw89_btc_fbtc_mreg rtw89_ - }; - - static --void rtw8852a_btc_bt_aci_imp(struct rtw89_dev *rtwdev) --{ -- struct rtw89_btc *btc = &rtwdev->btc; -- struct rtw89_btc_dm *dm = &btc->dm; -- struct rtw89_btc_bt_info *bt = &btc->cx.bt; -- struct rtw89_btc_bt_link_info *b = &bt->link_info; -- -- /* fix LNA2 = level-5 for BT ACI issue at BTG */ -- if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) -- dm->trx_para_level = 1; --} -- --static - void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -2041,7 +2028,6 @@ static const struct rtw89_chip_ops rtw88 - .btc_set_wl_pri = rtw8852a_btc_set_wl_pri, - .btc_set_wl_txpwr_ctrl = rtw8852a_btc_set_wl_txpwr_ctrl, - .btc_get_bt_rssi = rtw8852a_btc_get_bt_rssi, -- .btc_bt_aci_imp = rtw8852a_btc_bt_aci_imp, - .btc_update_bt_cnt = rtw8852a_btc_update_bt_cnt, - .btc_wl_s1_standby = rtw8852a_btc_wl_s1_standby, - .btc_set_wl_rx_gain = rtw8852a_btc_set_wl_rx_gain, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2685,19 +2685,6 @@ static const struct rtw89_btc_fbtc_mreg - }; - - static --void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev) --{ -- struct rtw89_btc *btc = &rtwdev->btc; -- struct rtw89_btc_dm *dm = &btc->dm; -- struct rtw89_btc_bt_info *bt = &btc->cx.bt; -- struct rtw89_btc_bt_link_info *b = &bt->link_info; -- -- /* fix LNA2 = level-5 for BT ACI issue at BTG */ -- if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) -- dm->trx_para_level = 1; --} -- --static - void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev) - { - /* Feature move to firmware */ -@@ -2893,7 +2880,6 @@ static const struct rtw89_chip_ops rtw88 - .btc_set_wl_pri = rtw8852c_btc_set_wl_pri, - .btc_set_wl_txpwr_ctrl = rtw8852c_btc_set_wl_txpwr_ctrl, - .btc_get_bt_rssi = rtw8852c_btc_get_bt_rssi, -- .btc_bt_aci_imp = rtw8852c_btc_bt_aci_imp, - .btc_update_bt_cnt = rtw8852c_btc_update_bt_cnt, - .btc_wl_s1_standby = rtw8852c_btc_wl_s1_standby, - .btc_set_wl_rx_gain = rtw8852c_btc_set_wl_rx_gain, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-019-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-019-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch deleted file mode 100644 index 5940e2a38..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-019-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0935bb1527d711b1af8e89d4ba200c302fb5ab2b Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Wed, 5 Oct 2022 16:32:08 +0800 -Subject: [PATCH 019/149] wifi: rtw89: parse PHY status only when PPDU is - to_self - -Without this fix, some non-self packets are used to count CFO (center -frequency offset), and average CFO has unstable variation. Then, it causes -unexpected performance. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1255,6 +1255,9 @@ static int rtw89_core_rx_parse_phy_sts(s - if (phy_ppdu->ie < RTW89_CCK_PKT) - return -EINVAL; - -+ if (!phy_ppdu->to_self) -+ return 0; -+ - pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; - end = (u8 *)phy_ppdu->buf + phy_ppdu->len; - while (pos < end) { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-020-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-020-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch deleted file mode 100644 index 7744b9490..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-020-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d0c820cc5bcf768598ca3e9f6e29f3e4e5589827 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 5 Oct 2022 16:32:09 +0800 -Subject: [PATCH 020/149] wifi: rtw89: 8852b: set proper configuration before - loading NCTL - -Before loading RF NCTL table, we need to configure IQK/DPK clock and reset -them, and then polling NCTL state ready. Since 8852BE needs additional -one setting, add it by this patch. Also, give them proper names. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 12 +++++++----- - drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ - 2 files changed, 9 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1368,13 +1368,15 @@ static void rtw89_phy_init_rf_nctl(struc - int ret; - - /* IQK/DPK clock & reset */ -- rtw89_phy_write32_set(rtwdev, 0x0c60, 0x3); -- rtw89_phy_write32_set(rtwdev, 0x0c6c, 0x1); -- rtw89_phy_write32_set(rtwdev, 0x58ac, 0x8000000); -- rtw89_phy_write32_set(rtwdev, 0x78ac, 0x8000000); -+ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x3); -+ rtw89_phy_write32_set(rtwdev, R_GNT_BT_WGT_EN, 0x1); -+ rtw89_phy_write32_set(rtwdev, R_P0_PATH_RST, 0x8000000); -+ rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000); -+ if (chip->chip_id == RTL8852B) -+ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2); - - /* check 0x8080 */ -- rtw89_phy_write32(rtwdev, 0x8000, 0x8); -+ rtw89_phy_write32(rtwdev, R_NCTL_CFG, 0x8); - - ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10, - 1000, false, rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4041,6 +4041,7 @@ - #define B_P0_RFM_TX_OPT BIT(6) - #define B_P0_RFM_BT_EN BIT(5) - #define B_P0_RFM_OUT GENMASK(4, 0) -+#define R_P0_PATH_RST 0x58AC - #define R_P0_TXDPD 0x58D4 - #define B_P0_TXDPD GENMASK(31, 28) - #define R_P0_TXPW_RSTB 0x58DC -@@ -4085,6 +4086,7 @@ - #define R_P1_RFCTM 0x7864 - #define R_P1_RFCTM_RDY BIT(26) - #define B_P1_RFCTM_VAL GENMASK(25, 20) -+#define R_P1_PATH_RST 0x78AC - #define R_P1_TXPW_RSTB 0x78DC - #define B_P1_TXPW_RSTB_MANON BIT(30) - #define B_P1_TXPW_RSTB_TSSI BIT(31) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-021-wifi-rtw89-8852b-add-HFC-quota-arrays.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-021-wifi-rtw89-8852b-add-HFC-quota-arrays.patch deleted file mode 100644 index a5a9c8f83..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-021-wifi-rtw89-8852b-add-HFC-quota-arrays.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3e870b4817333a1a4b01805073da3e00449acf43 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 5 Oct 2022 16:32:10 +0800 -Subject: [PATCH 021/149] wifi: rtw89: 8852b: add HFC quota arrays - -HFC is short for HCI flow control. These arrays are used to set quota -according to operating modes, which are SCC or download firmware. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 32 +++++++++++++++++++ - 1 file changed, 32 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -11,6 +11,37 @@ - #include "rtw8852b_table.h" - #include "txrx.h" - -+static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = { -+ {5, 343, grp_0}, /* ACH 0 */ -+ {5, 343, grp_0}, /* ACH 1 */ -+ {5, 343, grp_0}, /* ACH 2 */ -+ {5, 343, grp_0}, /* ACH 3 */ -+ {0, 0, grp_0}, /* ACH 4 */ -+ {0, 0, grp_0}, /* ACH 5 */ -+ {0, 0, grp_0}, /* ACH 6 */ -+ {0, 0, grp_0}, /* ACH 7 */ -+ {4, 344, grp_0}, /* B0MGQ */ -+ {4, 344, grp_0}, /* B0HIQ */ -+ {0, 0, grp_0}, /* B1MGQ */ -+ {0, 0, grp_0}, /* B1HIQ */ -+ {40, 0, 0} /* FWCMDQ */ -+}; -+ -+static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_pcie = { -+ 448, /* Group 0 */ -+ 0, /* Group 1 */ -+ 448, /* Public Max */ -+ 0 /* WP threshold */ -+}; -+ -+static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_pcie[] = { -+ [RTW89_QTA_SCC] = {rtw8852b_hfc_chcfg_pcie, &rtw8852b_hfc_pubcfg_pcie, -+ &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, -+ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, -+ RTW89_HCIFC_POH}, -+ [RTW89_QTA_INVALID] = {NULL}, -+}; -+ - static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { - [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, - &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -@@ -561,6 +592,7 @@ const struct rtw89_chip_info rtw8852b_ch - .ops = &rtw8852b_chip_ops, - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, -+ .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, - .dle_mem = rtw8852b_dle_mem_pcie, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-022-wifi-rtw89-make-generic-functions-to-convert-subband.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-022-wifi-rtw89-make-generic-functions-to-convert-subband.patch deleted file mode 100644 index 74f0ba0ef..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-022-wifi-rtw89-make-generic-functions-to-convert-subband.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 6e5125bcbaf810520969c121c7f12f20b8f3987d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 5 Oct 2022 16:32:11 +0800 -Subject: [PATCH 022/149] wifi: rtw89: make generic functions to convert - subband gain index - -The gain tables use different domain index, so we need to convert the index -from subband of chandef. Since these conversion functions can share with -8852b, make generic functions for further use. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.h | 44 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 46 +------------------ - 2 files changed, 46 insertions(+), 44 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -374,6 +374,50 @@ static inline u32 rtw89_phy_read32_mask( - return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask); - } - -+static inline -+enum rtw89_gain_offset rtw89_subband_to_gain_offset_band_of_ofdm(enum rtw89_subband subband) -+{ -+ switch (subband) { -+ default: -+ case RTW89_CH_2G: -+ return RTW89_GAIN_OFFSET_2G_OFDM; -+ case RTW89_CH_5G_BAND_1: -+ return RTW89_GAIN_OFFSET_5G_LOW; -+ case RTW89_CH_5G_BAND_3: -+ return RTW89_GAIN_OFFSET_5G_MID; -+ case RTW89_CH_5G_BAND_4: -+ return RTW89_GAIN_OFFSET_5G_HIGH; -+ } -+} -+ -+static inline -+enum rtw89_phy_bb_gain_band rtw89_subband_to_bb_gain_band(enum rtw89_subband subband) -+{ -+ switch (subband) { -+ default: -+ case RTW89_CH_2G: -+ return RTW89_BB_GAIN_BAND_2G; -+ case RTW89_CH_5G_BAND_1: -+ return RTW89_BB_GAIN_BAND_5G_L; -+ case RTW89_CH_5G_BAND_3: -+ return RTW89_BB_GAIN_BAND_5G_M; -+ case RTW89_CH_5G_BAND_4: -+ return RTW89_BB_GAIN_BAND_5G_H; -+ case RTW89_CH_6G_BAND_IDX0: -+ case RTW89_CH_6G_BAND_IDX1: -+ return RTW89_BB_GAIN_BAND_6G_L; -+ case RTW89_CH_6G_BAND_IDX2: -+ case RTW89_CH_6G_BAND_IDX3: -+ return RTW89_BB_GAIN_BAND_6G_M; -+ case RTW89_CH_6G_BAND_IDX4: -+ case RTW89_CH_6G_BAND_IDX5: -+ return RTW89_BB_GAIN_BAND_6G_H; -+ case RTW89_CH_6G_BAND_IDX6: -+ case RTW89_CH_6G_BAND_IDX7: -+ return RTW89_BB_GAIN_BAND_6G_UH; -+ } -+} -+ - enum rtw89_rfk_flag { - RTW89_RFK_F_WRF = 0, - RTW89_RFK_F_WM = 1, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -788,40 +788,12 @@ static const struct rtw8852c_bb_gain_op1 - .mask_tia0_lna6 = 0xff000000, - }; - --static enum rtw89_phy_bb_gain_band --rtw8852c_mapping_gain_band(enum rtw89_subband subband) --{ -- switch (subband) { -- default: -- case RTW89_CH_2G: -- return RTW89_BB_GAIN_BAND_2G; -- case RTW89_CH_5G_BAND_1: -- return RTW89_BB_GAIN_BAND_5G_L; -- case RTW89_CH_5G_BAND_3: -- return RTW89_BB_GAIN_BAND_5G_M; -- case RTW89_CH_5G_BAND_4: -- return RTW89_BB_GAIN_BAND_5G_H; -- case RTW89_CH_6G_BAND_IDX0: -- case RTW89_CH_6G_BAND_IDX1: -- return RTW89_BB_GAIN_BAND_6G_L; -- case RTW89_CH_6G_BAND_IDX2: -- case RTW89_CH_6G_BAND_IDX3: -- return RTW89_BB_GAIN_BAND_6G_M; -- case RTW89_CH_6G_BAND_IDX4: -- case RTW89_CH_6G_BAND_IDX5: -- return RTW89_BB_GAIN_BAND_6G_H; -- case RTW89_CH_6G_BAND_IDX6: -- case RTW89_CH_6G_BAND_IDX7: -- return RTW89_BB_GAIN_BAND_6G_UH; -- } --} -- - static void rtw8852c_set_gain_error(struct rtw89_dev *rtwdev, - enum rtw89_subband subband, - enum rtw89_rf_path path) - { - const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; -- u8 gain_band = rtw8852c_mapping_gain_band(subband); -+ u8 gain_band = rtw89_subband_to_bb_gain_band(subband); - s32 val; - u32 reg; - u32 mask; -@@ -979,21 +951,7 @@ static void rtw8852c_set_gain_offset(str - rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f); - } - -- switch (chan->subband_type) { -- default: -- case RTW89_CH_2G: -- gain_band = RTW89_GAIN_OFFSET_2G_OFDM; -- break; -- case RTW89_CH_5G_BAND_1: -- gain_band = RTW89_GAIN_OFFSET_5G_LOW; -- break; -- case RTW89_CH_5G_BAND_3: -- gain_band = RTW89_GAIN_OFFSET_5G_MID; -- break; -- case RTW89_CH_5G_BAND_4: -- gain_band = RTW89_GAIN_OFFSET_5G_HIGH; -- break; -- } -+ gain_band = rtw89_subband_to_gain_offset_band_of_ofdm(chan->subband_type); - - offset_q0 = -efuse_gain->offset[path][gain_band]; - offset_base_q4 = efuse_gain->offset_base[phy_idx]; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-023-wifi-rtw89-8852b-add-chip_ops-set_channel.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-023-wifi-rtw89-8852b-add-chip_ops-set_channel.patch deleted file mode 100644 index da36af2d0..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-023-wifi-rtw89-8852b-add-chip_ops-set_channel.patch +++ /dev/null @@ -1,1082 +0,0 @@ -From 6b0698984eb02f3e0dfd3c152df69f87c903e07f Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 5 Oct 2022 16:32:12 +0800 -Subject: [PATCH 023/149] wifi: rtw89: 8852b: add chip_ops::set_channel - -set_channel is main function to configure channel and bandwidth for all -layers, namely MAC, BB and RF. Additionally, MAC layer enables CCK rate -checking to avoid wrong rate from driver. BB layer configures SCO -(Sample Clock Offset) for CCK, TX gain error/offset, and reset baseband -hardware circuit after all configurations done. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221005083212.45683-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/phy.c | 9 + - drivers/net/wireless/realtek/rtw89/phy.h | 2 + - drivers/net/wireless/realtek/rtw89/reg.h | 58 +- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 564 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 256 ++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 14 + - 7 files changed, 903 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3429,6 +3429,7 @@ struct rtw89_phy_efuse_gain { - bool comp_valid; - s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ - s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ -+ s8 rssi_base[RTW89_PHY_MAX]; /* S(8, 4) */ - s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ - }; - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1427,6 +1427,15 @@ void rtw89_phy_write32_idx(struct rtw89_ - } - EXPORT_SYMBOL(rtw89_phy_write32_idx); - -+u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, -+ enum rtw89_phy_idx phy_idx) -+{ -+ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) -+ addr += rtw89_phy0_phy1_offset(rtwdev, addr); -+ return rtw89_phy_read32_mask(rtwdev, addr, mask); -+} -+EXPORT_SYMBOL(rtw89_phy_read32_idx); -+ - void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, - u32 val) - { ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -499,6 +499,8 @@ void rtw89_phy_config_rf_reg_v1(struct r - void rtw89_phy_dm_init(struct rtw89_dev *rtwdev); - void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, - u32 data, enum rtw89_phy_idx phy_idx); -+u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, -+ enum rtw89_phy_idx phy_idx); - void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, - const struct rtw89_txpwr_table *tbl); - s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3313,6 +3313,10 @@ - #define CFGCH_BAND1_2G 0 - #define CFGCH_BAND1_5G 1 - #define CFGCH_BAND1_6G 3 -+#define RR_CFGCH_POW_LCK BIT(15) -+#define RR_CFGCH_TRX_AH BIT(14) -+#define RR_CFGCH_BCN BIT(13) -+#define RR_CFGCH_BW2 BIT(12) - #define RR_CFGCH_BAND0 GENMASK(9, 8) - #define CFGCH_BAND0_2G 0 - #define CFGCH_BAND0_5G 1 -@@ -3450,14 +3454,31 @@ - #define RR_TIA_N6 BIT(8) - #define RR_MIXER 0x9f - #define RR_MIXER_GN GENMASK(4, 3) -+#define RR_POW 0xa0 -+#define RR_POW_SYN GENMASK(3, 2) - #define RR_LOGEN 0xa3 - #define RR_LOGEN_RPT GENMASK(19, 16) -+#define RR_SX 0xaf -+#define RR_LDO 0xb1 -+#define RR_LDO_SEL GENMASK(8, 6) -+#define RR_VCO 0xb2 -+#define RR_LPF 0xb7 -+#define RR_LPF_BUSY BIT(8) - #define RR_XTALX2 0xb8 - #define RR_MALSEL 0xbe -+#define RR_SYNFB 0xc5 -+#define RR_SYNFB_LK BIT(15) -+#define RR_LCKST 0xcf -+#define RR_LCKST_BIN BIT(0) - #define RR_LCK_TRG 0xd3 - #define RR_LCK_TRGSEL BIT(8) -+#define RR_MMD 0xd5 -+#define RR_MMD_RST_EN BIT(8) -+#define RR_MMD_RST_SYN BIT(6) - #define RR_IQKPLL 0xdc - #define RR_IQKPLL_MOD GENMASK(9, 8) -+#define RR_SYNLUT 0xdd -+#define RR_SYNLUT_MOD BIT(4) - #define RR_RCKD 0xde - #define RR_RCKD_POW GENMASK(19, 13) - #define RR_RCKD_BW BIT(2) -@@ -3626,6 +3647,8 @@ - #define R_P0_RFMODE 0x12AC - #define B_P0_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4) - #define B_P0_RFMODE_MUX GENMASK(11, 4) -+#define R_P0_RFMODE_ORI_RX 0x12AC -+#define B_P0_RFMODE_ORI_RX_ALL GENMASK(23, 12) - #define R_P0_NRBW 0x12B8 - #define B_P0_NRBW_DBG BIT(30) - #define R_S0_RXDC 0x12D4 -@@ -3719,6 +3742,8 @@ - #define B_RXCCA_DIS_V1 BIT(0) - #define R_RXSC 0x237C - #define B_RXSC_EN BIT(0) -+#define R_RX_RPL_OFST 0x23AC -+#define B_RX_RPL_OFST_CCK_MASK GENMASK(6, 0) - #define R_RXSCOBC 0x23B0 - #define B_RXSCOBC_TH GENMASK(18, 0) - #define R_RXSCOCCK 0x23B4 -@@ -3735,6 +3760,8 @@ - #define R_P1_RFMODE 0x32AC - #define B_P1_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4) - #define B_P1_RFMODE_MUX GENMASK(11, 4) -+#define R_P1_RFMODE_ORI_RX 0x32AC -+#define B_P1_RFMODE_ORI_RX_ALL GENMASK(23, 12) - #define R_P1_DBGMOD 0x32B8 - #define B_P1_DBGMOD_ON BIT(30) - #define R_S1_RXDC 0x32D4 -@@ -3768,7 +3795,10 @@ - #define R_T2F_GI_COMB 0x4424 - #define B_T2F_GI_COMB_EN BIT(2) - #define R_BT_DYN_DC_EST_EN 0x441C -+#define R_BT_DYN_DC_EST_EN_V1 0x4420 - #define B_BT_DYN_DC_EST_EN_MSK BIT(31) -+#define R_ASSIGN_SBD_OPT_V1 0x4440 -+#define B_ASSIGN_SBD_OPT_EN_V1 BIT(31) - #define R_ASSIGN_SBD_OPT 0x4450 - #define B_ASSIGN_SBD_OPT_EN BIT(24) - #define R_DCFO_COMP_S0 0x448C -@@ -3918,20 +3948,42 @@ - #define R_2P4G_BAND 0x4970 - #define B_2P4G_BAND_SEL BIT(1) - #define R_FC0_BW 0x4974 --#define B_FC0_BW_INV GENMASK(6, 0) -+#define R_FC0_BW_V1 0x49C0 - #define B_FC0_BW_SET GENMASK(31, 30) - #define B_ANT_RX_BT_SEG0 GENMASK(25, 22) - #define B_ANT_RX_1RCCA_SEG1 GENMASK(21, 18) - #define B_ANT_RX_1RCCA_SEG0 GENMASK(17, 14) -+#define B_FC0_BW_INV GENMASK(6, 0) - #define R_CHBW_MOD 0x4978 -+#define R_CHBW_MOD_V1 0x49C4 - #define B_BT_SHARE BIT(14) - #define B_CHBW_MOD_SBW GENMASK(13, 12) - #define B_CHBW_MOD_PRICH GENMASK(11, 8) - #define B_ANT_RX_SEG0 GENMASK(3, 0) -+#define R_P0_RPL1 0x49B0 -+#define B_P0_RPL1_41_MASK GENMASK(31, 24) -+#define B_P0_RPL1_40_MASK GENMASK(23, 16) -+#define B_P0_RPL1_20_MASK GENMASK(15, 8) -+#define B_P0_RPL1_MASK (B_P0_RPL1_41_MASK | B_P0_RPL1_40_MASK | B_P0_RPL1_20_MASK) -+#define B_P0_RPL1_SHIFT 8 -+#define B_P0_RPL1_BIAS_MASK GENMASK(7, 0) -+#define R_P0_RPL2 0x49B4 -+#define B_P0_RTL2_8A_MASK GENMASK(31, 24) -+#define B_P0_RTL2_81_MASK GENMASK(23, 16) -+#define B_P0_RTL2_80_MASK GENMASK(15, 8) -+#define B_P0_RTL2_42_MASK GENMASK(7, 0) -+#define R_P0_RPL3 0x49B8 -+#define B_P0_RTL3_89_MASK GENMASK(31, 24) -+#define B_P0_RTL3_84_MASK GENMASK(23, 16) -+#define B_P0_RTL3_83_MASK GENMASK(15, 8) -+#define B_P0_RTL3_82_MASK GENMASK(7, 0) - #define R_PD_BOOST_EN 0x49E8 - #define B_PD_BOOST_EN BIT(7) - #define R_P1_BACKOFF_IBADC_V1 0x49F0 - #define B_P1_BACKOFF_IBADC_V1 GENMASK(31, 26) -+#define R_P1_RPL1 0x4A00 -+#define R_P1_RPL2 0x4A04 -+#define R_P1_RPL3 0x4A08 - #define R_BK_FC0_INV_V1 0x4A1C - #define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0) - #define R_CCK_FC0_INV_V1 0x4A20 -@@ -3942,8 +3994,10 @@ - #define B_P1_AGC_EN BIT(31) - #define R_PATH1_TIA_INIT_V1 0x4AA8 - #define B_PATH1_TIA_INIT_IDX_MSK_V1 BIT(9) -+#define R_P0_AGC_RSVD 0x4ACC - #define R_PATH0_RXBB_V1 0x4AD4 - #define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0) -+#define R_P1_AGC_RSVD 0x4AD8 - #define R_PATH1_RXBB_V1 0x4AE0 - #define B_PATH1_RXBB_MSK_V1 GENMASK(31, 0) - #define R_PATH0_BT_BACKOFF_V1 0x4AE4 -@@ -3959,6 +4013,7 @@ - #define B_PATH0_NOTCH2_EN BIT(12) - #define B_PATH0_NOTCH2_VAL GENMASK(11, 0) - #define R_PATH0_5MDET 0x4C4C -+#define R_PATH0_5MDET_V1 0x46F8 - #define B_PATH0_5MDET_EN BIT(12) - #define B_PATH0_5MDET_SB2 BIT(8) - #define B_PATH0_5MDET_SB0 BIT(6) -@@ -3972,6 +4027,7 @@ - #define B_PATH1_NOTCH2_EN BIT(12) - #define B_PATH1_NOTCH2_VAL GENMASK(11, 0) - #define R_PATH1_5MDET 0x4D10 -+#define R_PATH1_5MDET_V1 0x47B8 - #define B_PATH1_5MDET_EN BIT(12) - #define B_PATH1_5MDET_SB2 BIT(8) - #define B_PATH1_5MDET_SB0 BIT(6) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -8,6 +8,7 @@ - #include "phy.h" - #include "reg.h" - #include "rtw8852b.h" -+#include "rtw8852b_rfk.h" - #include "rtw8852b_table.h" - #include "txrx.h" - -@@ -334,6 +335,568 @@ static void rtw8852b_power_trim(struct r - rtw8852b_pa_bias_trim(rtwdev); - } - -+static void rtw8852b_set_channel_mac(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ u8 mac_idx) -+{ -+ u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); -+ u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx); -+ u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx); -+ u8 txsc20 = 0, txsc40 = 0; -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_80: -+ txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); -+ fallthrough; -+ case RTW89_CHANNEL_WIDTH_40: -+ txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); -+ break; -+ default: -+ break; -+ } -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); -+ rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); -+ rtw89_write32(rtwdev, sub_carr, txsc20); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); -+ rtw89_write32(rtwdev, sub_carr, 0); -+ break; -+ default: -+ break; -+ } -+ -+ if (chan->channel > 14) { -+ rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE); -+ rtw89_write8_set(rtwdev, chk_rate, -+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); -+ } else { -+ rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE); -+ rtw89_write8_clr(rtwdev, chk_rate, -+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); -+ } -+} -+ -+static const u32 rtw8852b_sco_barker_threshold[14] = { -+ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, -+ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 -+}; -+ -+static const u32 rtw8852b_sco_cck_threshold[14] = { -+ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, -+ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed -+}; -+ -+static void rtw8852b_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch) -+{ -+ u8 ch_element = primary_ch - 1; -+ -+ rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, -+ rtw8852b_sco_barker_threshold[ch_element]); -+ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, -+ rtw8852b_sco_cck_threshold[ch_element]); -+} -+ -+static u8 rtw8852b_sco_mapping(u8 central_ch) -+{ -+ if (central_ch == 1) -+ return 109; -+ else if (central_ch >= 2 && central_ch <= 6) -+ return 108; -+ else if (central_ch >= 7 && central_ch <= 10) -+ return 107; -+ else if (central_ch >= 11 && central_ch <= 14) -+ return 106; -+ else if (central_ch == 36 || central_ch == 38) -+ return 51; -+ else if (central_ch >= 40 && central_ch <= 58) -+ return 50; -+ else if (central_ch >= 60 && central_ch <= 64) -+ return 49; -+ else if (central_ch == 100 || central_ch == 102) -+ return 48; -+ else if (central_ch >= 104 && central_ch <= 126) -+ return 47; -+ else if (central_ch >= 128 && central_ch <= 151) -+ return 46; -+ else if (central_ch >= 153 && central_ch <= 177) -+ return 45; -+ else -+ return 0; -+} -+ -+struct rtw8852b_bb_gain { -+ u32 gain_g[BB_PATH_NUM_8852B]; -+ u32 gain_a[BB_PATH_NUM_8852B]; -+ u32 gain_mask; -+}; -+ -+static const struct rtw8852b_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { -+ { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740}, -+ .gain_mask = 0xff000000 }, -+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, -+ .gain_mask = 0x000000ff }, -+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, -+ .gain_mask = 0x0000ff00 }, -+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744}, -+ .gain_mask = 0xff000000 }, -+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, -+ .gain_mask = 0x000000ff }, -+}; -+ -+static const struct rtw8852b_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { -+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748}, -+ .gain_mask = 0xff000000 }, -+}; -+ -+static void rtw8852b_set_gain_error(struct rtw89_dev *rtwdev, -+ enum rtw89_subband subband, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; -+ u8 gain_band = rtw89_subband_to_bb_gain_band(subband); -+ s32 val; -+ u32 reg; -+ u32 mask; -+ int i; -+ -+ for (i = 0; i < LNA_GAIN_NUM; i++) { -+ if (subband == RTW89_CH_2G) -+ reg = bb_gain_lna[i].gain_g[path]; -+ else -+ reg = bb_gain_lna[i].gain_a[path]; -+ -+ mask = bb_gain_lna[i].gain_mask; -+ val = gain->lna_gain[gain_band][path][i]; -+ rtw89_phy_write32_mask(rtwdev, reg, mask, val); -+ } -+ -+ for (i = 0; i < TIA_GAIN_NUM; i++) { -+ if (subband == RTW89_CH_2G) -+ reg = bb_gain_tia[i].gain_g[path]; -+ else -+ reg = bb_gain_tia[i].gain_a[path]; -+ -+ mask = bb_gain_tia[i].gain_mask; -+ val = gain->tia_gain[gain_band][path][i]; -+ rtw89_phy_write32_mask(rtwdev, reg, mask, val); -+ } -+} -+ -+static void rtw8852b_set_gain_offset(struct rtw89_dev *rtwdev, -+ enum rtw89_subband subband, -+ enum rtw89_phy_idx phy_idx) -+{ -+ static const u32 gain_err_addr[2] = {R_P0_AGC_RSVD, R_P1_AGC_RSVD}; -+ static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1, -+ R_PATH1_G_TIA1_LNA6_OP1DB_V1}; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; -+ enum rtw89_gain_offset gain_ofdm_band; -+ s32 offset_a, offset_b; -+ s32 offset_ofdm, offset_cck; -+ s32 tmp; -+ u8 path; -+ -+ if (!efuse_gain->comp_valid) -+ goto next; -+ -+ for (path = RF_PATH_A; path < BB_PATH_NUM_8852B; path++) { -+ tmp = efuse_gain->comp[path][subband]; -+ tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX); -+ rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp); -+ } -+ -+next: -+ if (!efuse_gain->offset_valid) -+ return; -+ -+ gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband); -+ -+ offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; -+ offset_b = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band]; -+ -+ tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp); -+ -+ tmp = -((offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_B], B_PATH0_R_G_OFST_MASK, tmp); -+ -+ if (hal->antenna_rx == RF_B) { -+ offset_ofdm = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band]; -+ offset_cck = -efuse_gain->offset[RF_PATH_B][0]; -+ } else { -+ offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; -+ offset_cck = -efuse_gain->offset[RF_PATH_A][0]; -+ } -+ -+ tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0]; -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); -+ -+ tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0]; -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); -+ -+ if (subband == RTW89_CH_2G) { -+ tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1); -+ tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1); -+ rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST, -+ B_RX_RPL_OFST_CCK_MASK, tmp); -+ } -+} -+ -+static -+void rtw8852b_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband) -+{ -+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; -+ u8 band = rtw89_subband_to_bb_gain_band(subband); -+ u32 val; -+ -+ val = FIELD_PREP(B_P0_RPL1_20_MASK, (gain->rpl_ofst_20[band][RF_PATH_A] + -+ gain->rpl_ofst_20[band][RF_PATH_B]) / 2) | -+ FIELD_PREP(B_P0_RPL1_40_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][0] + -+ gain->rpl_ofst_40[band][RF_PATH_B][0]) / 2) | -+ FIELD_PREP(B_P0_RPL1_41_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][1] + -+ gain->rpl_ofst_40[band][RF_PATH_B][1]) / 2); -+ val >>= B_P0_RPL1_SHIFT; -+ rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val); -+ -+ val = FIELD_PREP(B_P0_RTL2_42_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][2] + -+ gain->rpl_ofst_40[band][RF_PATH_B][2]) / 2) | -+ FIELD_PREP(B_P0_RTL2_80_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][0] + -+ gain->rpl_ofst_80[band][RF_PATH_B][0]) / 2) | -+ FIELD_PREP(B_P0_RTL2_81_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][1] + -+ gain->rpl_ofst_80[band][RF_PATH_B][1]) / 2) | -+ FIELD_PREP(B_P0_RTL2_8A_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][10] + -+ gain->rpl_ofst_80[band][RF_PATH_B][10]) / 2); -+ rtw89_phy_write32(rtwdev, R_P0_RPL2, val); -+ rtw89_phy_write32(rtwdev, R_P1_RPL2, val); -+ -+ val = FIELD_PREP(B_P0_RTL3_82_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][2] + -+ gain->rpl_ofst_80[band][RF_PATH_B][2]) / 2) | -+ FIELD_PREP(B_P0_RTL3_83_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][3] + -+ gain->rpl_ofst_80[band][RF_PATH_B][3]) / 2) | -+ FIELD_PREP(B_P0_RTL3_84_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][4] + -+ gain->rpl_ofst_80[band][RF_PATH_B][4]) / 2) | -+ FIELD_PREP(B_P0_RTL3_89_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][9] + -+ gain->rpl_ofst_80[band][RF_PATH_B][9]) / 2); -+ rtw89_phy_write32(rtwdev, R_P0_RPL3, val); -+ rtw89_phy_write32(rtwdev, R_P1_RPL3, val); -+} -+ -+static void rtw8852b_ctrl_ch(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 central_ch = chan->channel; -+ u8 subband = chan->subband_type; -+ u8 sco_comp; -+ bool is_2g = central_ch <= 14; -+ -+ /* Path A */ -+ if (is_2g) -+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, -+ B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx); -+ else -+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, -+ B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx); -+ -+ /* Path B */ -+ if (is_2g) -+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, -+ B_PATH1_BAND_SEL_MSK_V1, 1, phy_idx); -+ else -+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1, -+ B_PATH1_BAND_SEL_MSK_V1, 0, phy_idx); -+ -+ /* SCO compensate FC setting */ -+ sco_comp = rtw8852b_sco_mapping(central_ch); -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx); -+ -+ if (chan->band_type == RTW89_BAND_6G) -+ return; -+ -+ /* CCK parameters */ -+ if (central_ch == 14) { -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5); -+ } -+ -+ rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_A); -+ rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_B); -+ rtw8852b_set_gain_offset(rtwdev, subband, phy_idx); -+ rtw8852b_set_rxsc_rpl_comp(rtwdev, subband); -+} -+ -+static void rtw8852b_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) -+{ -+ static const u32 adc_sel[2] = {0xC0EC, 0xC1EC}; -+ static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4}; -+ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); -+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); -+ break; -+ case RTW89_CHANNEL_WIDTH_10: -+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); -+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); -+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); -+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); -+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); -+ break; -+ default: -+ rtw89_warn(rtwdev, "Fail to set ADC\n"); -+ } -+} -+ -+static void rtw8852b_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u32 rx_path_0; -+ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ -+ /*Set RF mode at 3 */ -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_10: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ -+ /*Set RF mode at 3 */ -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ -+ /*Set RF mode at 3 */ -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, -+ pri_ch, phy_idx); -+ -+ /*Set RF mode at 3 */ -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx); -+ /*CCK primary channel */ -+ if (pri_ch == RTW89_SC_20_UPPER) -+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); -+ -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, -+ pri_ch, phy_idx); -+ -+ /*Set RF mode at A */ -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx); -+ break; -+ default: -+ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, -+ pri_ch); -+ } -+ -+ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_A); -+ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_B); -+ -+ rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, -+ phy_idx); -+ if (rx_path_0 == 0x1) -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, -+ B_P1_RFMODE_ORI_RX_ALL, 0x111, phy_idx); -+ else if (rx_path_0 == 0x2) -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, -+ B_P0_RFMODE_ORI_RX_ALL, 0x111, phy_idx); -+} -+ -+static void rtw8852b_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en) -+{ -+ if (cck_en) { -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); -+ } -+} -+ -+static void rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 pri_ch = chan->primary_channel; -+ bool mask_5m_low; -+ bool mask_5m_en; -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_40: -+ /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */ -+ mask_5m_en = true; -+ mask_5m_low = pri_ch == 2; -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ -+ mask_5m_en = pri_ch == 3 || pri_ch == 4; -+ mask_5m_low = pri_ch == 4; -+ break; -+ default: -+ mask_5m_en = false; -+ break; -+ } -+ -+ if (!mask_5m_en) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x0); -+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, -+ B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx); -+ return; -+ } -+ -+ if (mask_5m_low) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x0); -+ } -+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, -+ B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx); -+} -+ -+static void rtw8852b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ fsleep(1); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+} -+ -+static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ bool cck_en = chan->channel <= 14; -+ u8 pri_ch_idx = chan->pri_ch_idx; -+ -+ if (cck_en) -+ rtw8852b_ctrl_sco_cck(rtwdev, chan->primary_channel); -+ -+ rtw8852b_ctrl_ch(rtwdev, chan, phy_idx); -+ rtw8852b_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); -+ rtw8852b_ctrl_cck_en(rtwdev, cck_en); -+ if (chan->band_type == RTW89_BAND_5G) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, -+ B_PATH1_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, -+ B_PATH1_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); -+ } -+ rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, -+ chan->primary_channel); -+ rtw8852b_5m_mask(rtwdev, chan, phy_idx); -+ rtw8852b_bb_reset_all(rtwdev, phy_idx); -+} -+ -+static void rtw8852b_set_channel(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_mac_idx mac_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8852b_set_channel_mac(rtwdev, chan, mac_idx); -+ rtw8852b_set_channel_bb(rtwdev, chan, phy_idx); -+ rtw8852b_set_channel_rf(rtwdev, chan, phy_idx); -+} -+ - static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -579,6 +1142,7 @@ static int rtw8852b_mac_disable_bb_rf(st - static const struct rtw89_chip_ops rtw8852b_chip_ops = { - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, -+ .set_channel = rtw8852b_set_channel, - .read_efuse = rtw8852b_read_efuse, - .read_phycap = rtw8852b_read_phycap, - .power_trim = rtw8852b_power_trim, ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -0,0 +1,256 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2019-2022 Realtek Corporation -+ */ -+ -+#include "coex.h" -+#include "debug.h" -+#include "mac.h" -+#include "phy.h" -+#include "reg.h" -+#include "rtw8852b.h" -+#include "rtw8852b_rfk.h" -+#include "rtw8852b_rfk_table.h" -+#include "rtw8852b_table.h" -+ -+static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 val; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n", -+ rtwdev->dbcc_en, phy_idx); -+ -+ if (!rtwdev->dbcc_en) { -+ val = RF_AB; -+ } else { -+ if (phy_idx == RTW89_PHY_0) -+ val = RF_A; -+ else -+ val = RF_B; -+ } -+ return val; -+} -+ -+static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ enum rtw89_bandwidth bw, bool dav) -+{ -+ u32 rf_reg18; -+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); -+ -+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); -+ if (rf_reg18 == INV_RF_DATA) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]Invalid RF_0x18 for Path-%d\n", path); -+ return; -+ } -+ rf_reg18 &= ~RR_CFGCH_BW; -+ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ case RTW89_CHANNEL_WIDTH_10: -+ case RTW89_CHANNEL_WIDTH_20: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); -+ } -+ -+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | -+ RR_CFGCH_BW2) & RFREG_MASK; -+ rf_reg18 |= RR_CFGCH_BW2; -+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", -+ bw, path, reg18_addr, -+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); -+} -+ -+static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_bandwidth bw) -+{ -+ _bw_setting(rtwdev, RF_PATH_A, bw, true); -+ _bw_setting(rtwdev, RF_PATH_B, bw, true); -+ _bw_setting(rtwdev, RF_PATH_A, bw, false); -+ _bw_setting(rtwdev, RF_PATH_B, bw, false); -+} -+ -+static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) -+{ -+ u32 bak; -+ u32 tmp; -+ int ret; -+ -+ bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, -+ false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); -+ -+ return !!ret; -+} -+ -+static void _lck_check(struct rtw89_dev *rtwdev) -+{ -+ u32 tmp; -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); -+ } -+ -+ udelay(10); -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); -+ _set_s0_arfc18(rtwdev, tmp); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); -+ } -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); -+ -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); -+ _set_s0_arfc18(rtwdev, tmp); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); -+ } -+} -+ -+static void _set_ch(struct rtw89_dev *rtwdev, u32 val) -+{ -+ bool timeout; -+ -+ timeout = _set_s0_arfc18(rtwdev, val); -+ if (!timeout) -+ _lck_check(rtwdev); -+} -+ -+static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ u8 central_ch, bool dav) -+{ -+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; -+ bool is_2g_ch = central_ch <= 14; -+ u32 rf_reg18; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); -+ -+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); -+ rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | -+ RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); -+ -+ if (!is_2g_ch) -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | -+ FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); -+ -+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | -+ RR_CFGCH_BW2) & RFREG_MASK; -+ rf_reg18 |= RR_CFGCH_BW2; -+ -+ if (path == RF_PATH_A && dav) -+ _set_ch(rtwdev, rf_reg18); -+ else -+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); -+ -+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); -+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", -+ central_ch, path, reg18_addr, -+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); -+} -+ -+static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) -+{ -+ _ch_setting(rtwdev, RF_PATH_A, central_ch, true); -+ _ch_setting(rtwdev, RF_PATH_B, central_ch, true); -+ _ch_setting(rtwdev, RF_PATH_A, central_ch, false); -+ _ch_setting(rtwdev, RF_PATH_B, central_ch, false); -+} -+ -+static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, -+ enum rtw89_rf_path path) -+{ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); -+ -+ if (bw == RTW89_CHANNEL_WIDTH_20) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); -+ else if (bw == RTW89_CHANNEL_WIDTH_40) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); -+ else if (bw == RTW89_CHANNEL_WIDTH_80) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); -+ else -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path, -+ rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); -+} -+ -+static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_bandwidth bw) -+{ -+ u8 kpath, path; -+ -+ kpath = _kpath(rtwdev, phy); -+ -+ for (path = 0; path < RF_PATH_NUM_8852B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ _set_rxbb_bw(rtwdev, bw, path); -+ } -+} -+ -+static void rtw8852b_ctrl_bw_ch(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, u8 central_ch, -+ enum rtw89_band band, enum rtw89_bandwidth bw) -+{ -+ _ctrl_ch(rtwdev, central_ch); -+ _ctrl_bw(rtwdev, phy, bw); -+ _rxbb_bw(rtwdev, phy, bw); -+} -+ -+void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8852b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, -+ chan->band_width); -+} ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -0,0 +1,14 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2019-2022 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8852B_RFK_H__ -+#define __RTW89_8852B_RFK_H__ -+ -+#include "core.h" -+ -+void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-024-wifi-rtw89-correct-6-GHz-scan-behavior.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-024-wifi-rtw89-correct-6-GHz-scan-behavior.patch deleted file mode 100644 index 3708066ae..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-024-wifi-rtw89-correct-6-GHz-scan-behavior.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 54997c24767b51bd762ff942431e8d37b535dc2e Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 7 Oct 2022 12:58:59 +0800 -Subject: [PATCH 024/149] wifi: rtw89: correct 6 GHz scan behavior - -Change active scan behavior to fit 6GHz requirements. There are many -different rules on active scan between 6GHz and 2GHz/5GHz, so if the -SSID is not specified, do fast passive scanning and limit number of -probe requests we send for now until new firmware can support all -rules. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221007045900.10823-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 28 +++++++++++++++++++------ - drivers/net/wireless/realtek/rtw89/fw.h | 1 + - 2 files changed, 23 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2567,6 +2567,9 @@ static void rtw89_hw_scan_add_chan(struc - struct rtw89_mac_chinfo *ch_info) - { - struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; -+ struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -+ struct cfg80211_scan_request *req = rtwvif->scan_req; - struct rtw89_pktofld_info *info; - u8 band, probe_count = 0; - -@@ -2578,13 +2581,13 @@ static void rtw89_hw_scan_add_chan(struc - ch_info->tx_pwr_idx = 0; - ch_info->tx_null = false; - ch_info->pause_data = false; -+ ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; - - if (ssid_num) { - ch_info->num_pkt = ssid_num; - band = rtw89_hw_to_nl80211_band(ch_info->ch_band); - - list_for_each_entry(info, &scan_info->pkt_list[band], list) { -- ch_info->probe_id = info->id; - ch_info->pkt_id[probe_count] = info->id; - if (++probe_count >= ssid_num) - break; -@@ -2593,9 +2596,16 @@ static void rtw89_hw_scan_add_chan(struc - rtw89_err(rtwdev, "SSID num differs from list len\n"); - } - -+ if (ch_info->ch_band == RTW89_BAND_6G) { -+ if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { -+ ch_info->tx_pkt = false; -+ if (!req->duration_mandatory) -+ ch_info->period -= RTW89_DWELL_TIME; -+ } -+ } -+ - switch (chan_type) { - case RTW89_CHAN_OPERATE: -- ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; - ch_info->central_ch = scan_info->op_chan; - ch_info->pri_ch = scan_info->op_pri_ch; - ch_info->ch_band = scan_info->op_band; -@@ -2604,8 +2614,9 @@ static void rtw89_hw_scan_add_chan(struc - ch_info->num_pkt = 0; - break; - case RTW89_CHAN_DFS: -- ch_info->period = max_t(u8, ch_info->period, -- RTW89_DFS_CHAN_TIME); -+ if (ch_info->ch_band != RTW89_BAND_6G) -+ ch_info->period = max_t(u8, ch_info->period, -+ RTW89_DFS_CHAN_TIME); - ch_info->dwell_time = RTW89_DWELL_TIME; - break; - case RTW89_CHAN_ACTIVE: -@@ -2639,8 +2650,13 @@ static int rtw89_hw_scan_add_chan_list(s - goto out; - } - -- ch_info->period = req->duration_mandatory ? -- req->duration : RTW89_CHANNEL_TIME; -+ if (req->duration_mandatory) -+ ch_info->period = req->duration; -+ else if (channel->band == NL80211_BAND_6GHZ) -+ ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME; -+ else -+ ch_info->period = RTW89_CHANNEL_TIME; -+ - ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band); - ch_info->central_ch = channel->hw_value; - ch_info->pri_ch = channel->hw_value; ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -197,6 +197,7 @@ struct rtw89_h2creg_sch_tx_en { - - #define RTW89_H2C_MAX_SIZE 2048 - #define RTW89_CHANNEL_TIME 45 -+#define RTW89_CHANNEL_TIME_6G 20 - #define RTW89_DFS_CHAN_TIME 105 - #define RTW89_OFF_CHAN_TIME 100 - #define RTW89_DWELL_TIME 20 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-025-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-025-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch deleted file mode 100644 index 93e69c8a1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-025-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 478132050360a5cf19cc1b3fc9fcf1e56a483481 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 7 Oct 2022 12:59:00 +0800 -Subject: [PATCH 025/149] wifi: rtw89: fix wrong bandwidth settings after scan - -Set channel in driver side to configure Tx power and channel index -correctly after scan. Before this, beacons with bandwidth larger than -20M bandwidth will be dropped by mac80211 due to frequency mismatch. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221007045900.10823-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2775,6 +2775,7 @@ void rtw89_hw_scan_complete(struct rtw89 - - if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK) - rtw89_store_op_chan(rtwdev, false); -+ rtw89_set_channel(rtwdev); - } - - void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-026-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-026-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch deleted file mode 100644 index 25bd49c12..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-026-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch +++ /dev/null @@ -1,125 +0,0 @@ -From d0a95ef3ed86762d2356fd5443bebe7a6ef140c7 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:53:55 +0800 -Subject: [PATCH 026/149] wifi: rtw89: 8852b: add chip_ops::set_channel_help - -This chip_ops is to assist set_channel, because we need setup and restore -hardware before and after set_channel. - -Before set_channel, we stop transmitting, reset PPDU status, disable TSSI, -and disable ADC. After set_channel, do opposite things in reverse order. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 84 +++++++++++++++++++ - 1 file changed, 84 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -854,6 +854,30 @@ static void rtw8852b_bb_reset_all(struct - rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); - } - -+static void rtw8852b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, -+ enum rtw89_phy_idx phy_idx, bool en) -+{ -+ if (en) { -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, -+ B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, -+ B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+ if (band == RTW89_BAND_2G) -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, -+ B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, -+ B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ fsleep(1); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); -+ } -+} -+ - static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -@@ -897,6 +921,65 @@ static void rtw8852b_set_channel(struct - rtw8852b_set_channel_rf(rtwdev, chan, phy_idx); - } - -+static void rtw8852b_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, -+ enum rtw89_rf_path path) -+{ -+ static const u32 tssi_trk[2] = {R_P0_TSSI_TRK, R_P1_TSSI_TRK}; -+ static const u32 ctrl_bbrst[2] = {R_P0_TXPW_RSTB, R_P1_TXPW_RSTB}; -+ -+ if (en) { -+ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], B_P0_TXPW_RSTB_MANON, 0x0); -+ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], B_P0_TXPW_RSTB_MANON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x1); -+ } -+} -+ -+static void rtw8852b_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, -+ u8 phy_idx) -+{ -+ if (!rtwdev->dbcc_en) { -+ rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_A); -+ rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_B); -+ } else { -+ if (phy_idx == RTW89_PHY_0) -+ rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_A); -+ else -+ rtw8852b_tssi_cont_en(rtwdev, en, RF_PATH_B); -+ } -+} -+ -+static void rtw8852b_adc_en(struct rtw89_dev *rtwdev, bool en) -+{ -+ if (en) -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf); -+} -+ -+static void rtw8852b_set_channel_help(struct rtw89_dev *rtwdev, bool enter, -+ struct rtw89_channel_help_params *p, -+ const struct rtw89_chan *chan, -+ enum rtw89_mac_idx mac_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+ if (enter) { -+ rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); -+ rtw8852b_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); -+ rtw8852b_adc_en(rtwdev, false); -+ fsleep(40); -+ rtw8852b_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); -+ } else { -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); -+ rtw8852b_adc_en(rtwdev, true); -+ rtw8852b_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); -+ rtw8852b_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); -+ rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); -+ } -+} -+ - static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -1143,6 +1226,7 @@ static const struct rtw89_chip_ops rtw88 - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, - .set_channel = rtw8852b_set_channel, -+ .set_channel_help = rtw8852b_set_channel_help, - .read_efuse = rtw8852b_read_efuse, - .read_phycap = rtw8852b_read_phycap, - .power_trim = rtw8852b_power_trim, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-027-wifi-rtw89-8852b-add-power-on-off-functions.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-027-wifi-rtw89-8852b-add-power-on-off-functions.patch deleted file mode 100644 index 201ad1b8d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-027-wifi-rtw89-8852b-add-power-on-off-functions.patch +++ /dev/null @@ -1,313 +0,0 @@ -From b23b36efbdac603c491197dae1d27a3c5ac4b01c Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:53:56 +0800 -Subject: [PATCH 027/149] wifi: rtw89: 8852b: add power on/off functions - -We need power on function to enable hardware circuits of MAC/BB/RF, and -then download firmware and load PHY parameters. After more settings, it -starts to work. When it enters idle, use power off function to have the -lowest power consumption. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 18 ++ - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 192 ++++++++++++++++++ - 3 files changed, 211 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -1014,6 +1014,7 @@ enum rtw89_mac_xtal_si_offset { - #define XTAL_SI_PON_EI BIT(1) - #define XTAL_SI_PON_WEI BIT(0) - XTAL_SI_SRAM_CTRL = 0xA1, -+#define XTAL_SI_SRAM_DIS BIT(1) - #define FULL_BIT_MASK GENMASK(7, 0) - }; - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -34,6 +34,9 @@ - #define R_AX_SYS_CLK_CTRL 0x0008 - #define B_AX_CPU_CLK_EN BIT(14) - -+#define R_AX_SYS_SWR_CTRL1 0x0010 -+#define B_AX_SYM_CTRL_SPS_PWMFREQ BIT(10) -+ - #define R_AX_SYS_ADIE_PAD_PWR_CTRL 0x0018 - #define B_AX_SYM_PADPDN_WL_PTA_1P3 BIT(6) - #define B_AX_SYM_PADPDN_WL_RFC_1P3 BIT(5) -@@ -42,6 +45,9 @@ - #define B_AX_R_DIS_PRST BIT(6) - #define B_AX_WLOCK_1C_BIT6 BIT(5) - -+#define R_AX_AFE_LDO_CTRL 0x0020 -+#define B_AX_AON_OFF_PC_EN BIT(23) -+ - #define R_AX_EFUSE_CTRL_1 0x0038 - #define B_AX_EF_PGPD_MASK GENMASK(30, 28) - #define B_AX_EF_RDT BIT(27) -@@ -118,6 +124,9 @@ - #define B_AX_R_AX_BG_LPF BIT(2) - #define B_AX_R_AX_BG GENMASK(1, 0) - -+#define R_AX_HCI_LDO_CTRL 0x007A -+#define B_AX_R_AX_VADJ_MASK GENMASK(3, 0) -+ - #define R_AX_PLATFORM_ENABLE 0x0088 - #define B_AX_AXIDMA_EN BIT(3) - #define B_AX_WCPU_EN BIT(1) -@@ -125,6 +134,7 @@ - - #define R_AX_WLLPS_CTRL 0x0090 - #define B_AX_DIS_WLBT_LPSEN_LOPC BIT(1) -+#define SW_LPS_OPTION 0x0001A0B2 - - #define R_AX_SCOREBOARD 0x00AC - #define B_AX_TOGGLE BIT(31) -@@ -229,6 +239,9 @@ - - #define R_AX_GPIO0_7_FUNC_SEL 0x02D0 - -+#define R_AX_EECS_EESK_FUNC_SEL 0x02D8 -+#define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4) -+ - #define R_AX_LED1_FUNC_SEL 0x02DC - #define B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK GENMASK(27, 24) - #define PINMUX_EESK_FUNC_SEL_BT_LOG 0x1 -@@ -253,6 +266,10 @@ - #define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) - #define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) - -+#define R_AX_SPS_DIG_OFF_CTRL0 0x0400 -+#define B_AX_C3_L1_MASK GENMASK(5, 4) -+#define B_AX_C1_L1_MASK GENMASK(1, 0) -+ - #define R_AX_AFE_OFF_CTRL1 0x0444 - #define B_AX_S1_LDO_VSEL_F_MASK GENMASK(25, 24) - #define B_AX_S1_LDO2PWRCUT_F BIT(23) -@@ -449,6 +466,7 @@ - #define B_AX_DISPATCHER_EN BIT(18) - #define B_AX_BBRPT_EN BIT(17) - #define B_AX_MAC_SEC_EN BIT(16) -+#define B_AX_DMACREG_GCKEN BIT(15) - #define B_AX_MAC_UN_EN BIT(15) - #define B_AX_H_AXIDMA_EN BIT(14) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -56,6 +56,194 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) -+{ -+ u32 val32; -+ u32 ret; -+ -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | -+ B_AX_AFSM_PCIE_SUS_EN); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); -+ rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_AFE_LDO_CTRL, B_AX_AON_OFF_PC_EN); -+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_AON_OFF_PC_EN, -+ 1000, 20000, false, rtwdev, R_AX_AFE_LDO_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C1_L1_MASK, 0x1); -+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C3_L1_MASK, 0x3); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, -+ XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, -+ XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, -+ XTAL_SI_OFF_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, -+ XTAL_SI_OFF_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, -+ XTAL_SI_PON_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, -+ XTAL_SI_PON_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); -+ -+ fsleep(1000); -+ -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); -+ rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ -+ if (!rtwdev->efuse.valid || rtwdev->efuse.power_k_valid) -+ goto func_en; -+ -+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VOL_L1_MASK, 0x9); -+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VREFPFM_L_MASK, 0xA); -+ -+ if (rtwdev->hal.cv == CHIP_CBV) { -+ rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ rtw89_write16_mask(rtwdev, R_AX_HCI_LDO_CTRL, B_AX_R_AX_VADJ_MASK, 0xA); -+ rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ } -+ -+func_en: -+ rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, -+ B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | -+ B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | -+ B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | -+ B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | -+ B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | -+ B_AX_DMACREG_GCKEN); -+ rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, -+ B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | -+ B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | -+ B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN | -+ B_AX_RMAC_EN); -+ -+ rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_MASK, -+ PINMUX_EESK_FUNC_SEL_BT_LOG); -+ -+ return 0; -+} -+ -+static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev) -+{ -+ u32 val32; -+ u32 ret; -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, -+ XTAL_SI_RFC2RF); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, -+ XTAL_SI_SRAM2RFC); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); -+ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); -+ rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ); -+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x3); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); -+ -+ return 0; -+} -+ - static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse, - struct rtw8852b_efuse *map) - { -@@ -1233,6 +1421,8 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8852b_init_txpwr_unit, -+ .pwr_on_func = rtw8852b_pwr_on_func, -+ .pwr_off_func = rtw8852b_pwr_off_func, - }; - - const struct rtw89_chip_info rtw8852b_chip_info = { -@@ -1242,6 +1432,8 @@ const struct rtw89_chip_info rtw8852b_ch - .dle_scc_rsvd_size = 98304, - .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, - .dle_mem = rtw8852b_dle_mem_pcie, -+ .pwr_on_seq = NULL, -+ .pwr_off_seq = NULL, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 2048, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-028-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-028-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch deleted file mode 100644 index 283ffef27..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-028-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch +++ /dev/null @@ -1,75 +0,0 @@ -From a804479839e1cf502a76c407f3e07135ddbe5032 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:53:57 +0800 -Subject: [PATCH 028/149] wifi: rtw89: 8852b: add basic baseband chip_ops - -chip_ops::bb_reset is to reset baseband state after loading parameters, -because its state could be unpredictable at that moment. The other is -chip_ops::bb_sethw that is to set some baseband settings not including in -parameter tables. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 42 +++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1066,6 +1066,46 @@ static void rtw8852b_bb_reset_en(struct - } - } - -+static void rtw8852b_bb_reset(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); -+ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); -+ rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); -+ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); -+ rtw8852b_bb_reset_all(rtwdev, phy_idx); -+ rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); -+ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); -+ rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); -+ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); -+} -+ -+static void rtw8852b_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u32 addr; -+ -+ for (addr = R_AX_PWR_MACID_LMT_TABLE0; -+ addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) -+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); -+} -+ -+static void rtw8852b_bb_sethw(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ -+ rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); -+ rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP); -+ -+ rtw8852b_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); -+ -+ /* read these registers after loading BB parameters */ -+ gain->offset_base[RTW89_PHY_0] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK); -+ gain->rssi_base[RTW89_PHY_0] = -+ rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); -+} -+ - static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -@@ -1413,6 +1453,8 @@ static int rtw8852b_mac_disable_bb_rf(st - static const struct rtw89_chip_ops rtw8852b_chip_ops = { - .enable_bb_rf = rtw8852b_mac_enable_bb_rf, - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, -+ .bb_reset = rtw8852b_bb_reset, -+ .bb_sethw = rtw8852b_bb_sethw, - .set_channel = rtw8852b_set_channel, - .set_channel_help = rtw8852b_set_channel_help, - .read_efuse = rtw8852b_read_efuse, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-029-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-029-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch deleted file mode 100644 index 9c6e0ce4e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-029-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8f88474ce3eca2dd8fb4e08d4b6ab71e76312e3e Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:53:58 +0800 -Subject: [PATCH 029/149] wifi: rtw89: 8852b: add chip_ops to get thermal - -Thermal value reflects temperature that will affect RF performance, so -we re-calibrate RF characteristics if delta of thermal over a threshold. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1397,6 +1397,23 @@ rtw8852b_init_txpwr_unit(struct rtw89_de - return 0; - } - -+static u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) -+{ -+ if (rtwdev->is_tssi_mode[rf_path]) { -+ u32 addr = 0x1c10 + (rf_path << 13); -+ -+ return rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000); -+ } -+ -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); -+ -+ fsleep(200); -+ -+ return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); -+} -+ - static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) - { - int ret; -@@ -1463,6 +1480,7 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8852b_init_txpwr_unit, -+ .get_thermal = rtw8852b_get_thermal, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, - }; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-030-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-030-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch deleted file mode 100644 index 50910559b..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-030-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 98bf0ddf20fc2d70d11f1af6e041ee4fad1392ac Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:53:59 +0800 -Subject: [PATCH 030/149] wifi: rtw89: 8852b: add chip_ops related to BT - coexistence - -These chip_ops are used to assist BT coexistence module to control chip -specific operations, such as initial, pre-AGC, BT grant, set wifi priority -and tx power, RX gain, and get BT counter. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 305 ++++++++++++++++++ - 2 files changed, 306 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3151,6 +3151,7 @@ - #define BTC_BREAK_PARAM 0xf0ffffff - - #define R_BTC_BT_COEX_MSK_TABLE 0xDA30 -+#define B_BTC_PRI_MASK_RXCCK_V1 BIT(28) - #define B_BTC_PRI_MASK_TX_RESP_V1 BIT(3) - - #define R_AX_BT_COEX_CFG_2 0xDA34 ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -56,6 +56,44 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static const struct rtw89_reg3_def rtw8852b_btc_preagc_en_defs[] = { -+ {0x46D0, GENMASK(1, 0), 0x3}, -+ {0x4790, GENMASK(1, 0), 0x3}, -+ {0x4AD4, GENMASK(31, 0), 0xf}, -+ {0x4AE0, GENMASK(31, 0), 0xf}, -+ {0x4688, GENMASK(31, 24), 0x80}, -+ {0x476C, GENMASK(31, 24), 0x80}, -+ {0x4694, GENMASK(7, 0), 0x80}, -+ {0x4694, GENMASK(15, 8), 0x80}, -+ {0x4778, GENMASK(7, 0), 0x80}, -+ {0x4778, GENMASK(15, 8), 0x80}, -+ {0x4AE4, GENMASK(23, 0), 0x780D1E}, -+ {0x4AEC, GENMASK(23, 0), 0x780D1E}, -+ {0x469C, GENMASK(31, 26), 0x34}, -+ {0x49F0, GENMASK(31, 26), 0x34}, -+}; -+ -+static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_en_defs); -+ -+static const struct rtw89_reg3_def rtw8852b_btc_preagc_dis_defs[] = { -+ {0x46D0, GENMASK(1, 0), 0x0}, -+ {0x4790, GENMASK(1, 0), 0x0}, -+ {0x4AD4, GENMASK(31, 0), 0x60}, -+ {0x4AE0, GENMASK(31, 0), 0x60}, -+ {0x4688, GENMASK(31, 24), 0x1a}, -+ {0x476C, GENMASK(31, 24), 0x1a}, -+ {0x4694, GENMASK(7, 0), 0x2a}, -+ {0x4694, GENMASK(15, 8), 0x2a}, -+ {0x4778, GENMASK(7, 0), 0x2a}, -+ {0x4778, GENMASK(15, 8), 0x2a}, -+ {0x4AE4, GENMASK(23, 0), 0x79E99E}, -+ {0x4AEC, GENMASK(23, 0), 0x79E99E}, -+ {0x469C, GENMASK(31, 26), 0x26}, -+ {0x49F0, GENMASK(31, 26), 0x26}, -+}; -+ -+static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_dis_defs); -+ - static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) - { - u32 val32; -@@ -1397,6 +1435,55 @@ rtw8852b_init_txpwr_unit(struct rtw89_de - return 0; - } - -+static void rtw8852b_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) -+{ -+ rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852b_btc_preagc_en_defs_tbl : -+ &rtw8852b_btc_preagc_dis_defs_tbl); -+} -+ -+static void rtw8852b_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) -+{ -+ if (btg) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, -+ B_PATH1_G_LNA6_OP1DB_V1, 0x20); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, -+ B_PATH1_BT_SHARE_V1, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, -+ B_PATH1_BTG_PATH_V1, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1, -+ B_PATH1_G_LNA6_OP1DB_V1, 0x1a); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1, -+ B_PATH1_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1, -+ B_PATH1_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); -+ } -+} -+ - static u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) - { - if (rtwdev->is_tssi_mode[rf_path]) { -@@ -1414,6 +1501,212 @@ static u8 rtw8852b_get_thermal(struct rt - return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); - } - -+static void rtw8852b_btc_set_rfe(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_module *module = &btc->mdinfo; -+ -+ module->rfe_type = rtwdev->efuse.rfe_type; -+ module->cv = rtwdev->hal.cv; -+ module->bt_solo = 0; -+ module->switch_type = BTC_SWITCH_INTERNAL; -+ -+ if (module->rfe_type > 0) -+ module->ant.num = module->rfe_type % 2 ? 2 : 3; -+ else -+ module->ant.num = 2; -+ -+ module->ant.diversity = 0; -+ module->ant.isolation = 10; -+ -+ if (module->ant.num == 3) { -+ module->ant.type = BTC_ANT_DEDICATED; -+ module->bt_pos = BTC_BT_ALONE; -+ } else { -+ module->ant.type = BTC_ANT_SHARED; -+ module->bt_pos = BTC_BT_BTG; -+ } -+} -+ -+static -+void rtw8852b_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) -+{ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); -+} -+ -+static void rtw8852b_btc_init_cfg(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_module *module = &btc->mdinfo; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_mac_ax_coex coex_params = { -+ .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, -+ .direction = RTW89_MAC_AX_COEX_INNER, -+ }; -+ -+ /* PTA init */ -+ rtw89_mac_coex_init(rtwdev, &coex_params); -+ -+ /* set WL Tx response = Hi-Pri */ -+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); -+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); -+ -+ /* set rf gnt debug off */ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0); -+ -+ /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ -+ if (module->ant.type == BTC_ANT_SHARED) { -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); -+ /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */ -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x55f); -+ } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); -+ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x5ff); -+ } -+ -+ /* set PTA break table */ -+ rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); -+ -+ /* enable BT counter 0xda40[16,2] = 2b'11 */ -+ rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); -+ btc->cx.wl.status.map.init_ok = true; -+} -+ -+static -+void rtw8852b_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) -+{ -+ u32 bitmap; -+ u32 reg; -+ -+ switch (map) { -+ case BTC_PRI_MASK_TX_RESP: -+ reg = R_BTC_BT_COEX_MSK_TABLE; -+ bitmap = B_BTC_PRI_MASK_TX_RESP_V1; -+ break; -+ case BTC_PRI_MASK_BEACON: -+ reg = R_AX_WL_PRI_MSK; -+ bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; -+ break; -+ case BTC_PRI_MASK_RX_CCK: -+ reg = R_BTC_BT_COEX_MSK_TABLE; -+ bitmap = B_BTC_PRI_MASK_RXCCK_V1; -+ break; -+ default: -+ return; -+ } -+ -+ if (state) -+ rtw89_write32_set(rtwdev, reg, bitmap); -+ else -+ rtw89_write32_clr(rtwdev, reg, bitmap); -+} -+ -+union rtw8852b_btc_wl_txpwr_ctrl { -+ u32 txpwr_val; -+ struct { -+ union { -+ u16 ctrl_all_time; -+ struct { -+ s16 data:9; -+ u16 rsvd:6; -+ u16 flag:1; -+ } all_time; -+ }; -+ union { -+ u16 ctrl_gnt_bt; -+ struct { -+ s16 data:9; -+ u16 rsvd:7; -+ } gnt_bt; -+ }; -+ }; -+} __packed; -+ -+static void -+rtw8852b_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) -+{ -+ union rtw8852b_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; -+ s32 val; -+ -+#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ -+do { \ -+ u32 _wrt = FIELD_PREP(_msk, _val); \ -+ BUILD_BUG_ON(!!(_msk & _en)); \ -+ if (_cond) \ -+ _wrt |= _en; \ -+ else \ -+ _wrt &= ~_en; \ -+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ -+ _msk | _en, _wrt); \ -+} while (0) -+ -+ switch (arg.ctrl_all_time) { -+ case 0xffff: -+ val = 0; -+ break; -+ default: -+ val = arg.all_time.data; -+ break; -+ } -+ -+ __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, -+ val, B_AX_FORCE_PWR_BY_RATE_EN, -+ arg.ctrl_all_time != 0xffff); -+ -+ switch (arg.ctrl_gnt_bt) { -+ case 0xffff: -+ val = 0; -+ break; -+ default: -+ val = arg.gnt_bt.data; -+ break; -+ } -+ -+ __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, -+ B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); -+ -+#undef __write_ctrl -+} -+ -+static -+s8 rtw8852b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) -+{ -+ return clamp_t(s8, val, -100, 0) + 100; -+} -+ -+static -+void rtw8852b_btc_update_bt_cnt(struct rtw89_dev *rtwdev) -+{ -+ /* Feature move to firmware */ -+} -+ -+static void rtw8852b_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) -+{ -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x31); -+ -+ /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ -+ if (state) -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x579); -+ else -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); -+} -+ -+static void rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) -+{ -+} -+ - static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) - { - int ret; -@@ -1481,8 +1774,20 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8852b_init_txpwr_unit, - .get_thermal = rtw8852b_get_thermal, -+ .ctrl_btg = rtw8852b_ctrl_btg, -+ .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, -+ -+ .btc_set_rfe = rtw8852b_btc_set_rfe, -+ .btc_init_cfg = rtw8852b_btc_init_cfg, -+ .btc_set_wl_pri = rtw8852b_btc_set_wl_pri, -+ .btc_set_wl_txpwr_ctrl = rtw8852b_btc_set_wl_txpwr_ctrl, -+ .btc_get_bt_rssi = rtw8852b_btc_get_bt_rssi, -+ .btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt, -+ .btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby, -+ .btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain, -+ .btc_set_policy = rtw89_btc_set_policy, - }; - - const struct rtw89_chip_info rtw8852b_chip_info = { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-031-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-031-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch deleted file mode 100644 index 58694e18d..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-031-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch +++ /dev/null @@ -1,62 +0,0 @@ -From bf958f76cf97663d79b4f90a08d38c5b9bb56082 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:54:00 +0800 -Subject: [PATCH 031/149] wifi: rtw89: 8852b: add chip_ops to query PPDU - -Add to parse PPDU to get frequency and RSSI of received packets. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 32 +++++++++++++++++++ - 1 file changed, 32 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1707,6 +1707,37 @@ static void rtw8852b_btc_set_wl_rx_gain( - { - } - -+static void rtw8852b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu, -+ struct ieee80211_rx_status *status) -+{ -+ u16 chan = phy_ppdu->chan_idx; -+ u8 band; -+ -+ if (chan == 0) -+ return; -+ -+ band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; -+ status->freq = ieee80211_channel_to_frequency(chan, band); -+ status->band = band; -+} -+ -+static void rtw8852b_query_ppdu(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu, -+ struct ieee80211_rx_status *status) -+{ -+ u8 path; -+ u8 *rx_power = phy_ppdu->rssi; -+ -+ status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B])); -+ for (path = 0; path < rtwdev->chip->rf_path_num; path++) { -+ status->chains |= BIT(path); -+ status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); -+ } -+ if (phy_ppdu->valid) -+ rtw8852b_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); -+} -+ - static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) - { - int ret; -@@ -1775,6 +1806,7 @@ static const struct rtw89_chip_ops rtw88 - .init_txpwr_unit = rtw8852b_init_txpwr_unit, - .get_thermal = rtw8852b_get_thermal, - .ctrl_btg = rtw8852b_ctrl_btg, -+ .query_ppdu = rtw8852b_query_ppdu, - .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-032-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-032-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch deleted file mode 100644 index 70bf8a4c6..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-032-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 8915a256538d0e81fe02c5f68368e5787df261d5 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:54:01 +0800 -Subject: [PATCH 032/149] wifi: rtw89: 8852b: add chip_ops to configure TX/RX - path - -To support variant models, such as 1x1 or 1T2R, we need this chip_ops to -change the path accordingly. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 4 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 112 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8852b.h | 3 + - 3 files changed, 119 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3668,6 +3668,8 @@ - #define B_P0_RFMODE_MUX GENMASK(11, 4) - #define R_P0_RFMODE_ORI_RX 0x12AC - #define B_P0_RFMODE_ORI_RX_ALL GENMASK(23, 12) -+#define R_P0_RFMODE_FTM_RX 0x12B0 -+#define B_P0_RFMODE_FTM_RX GENMASK(11, 0) - #define R_P0_NRBW 0x12B8 - #define B_P0_NRBW_DBG BIT(30) - #define R_S0_RXDC 0x12D4 -@@ -3781,6 +3783,8 @@ - #define B_P1_RFMODE_MUX GENMASK(11, 4) - #define R_P1_RFMODE_ORI_RX 0x32AC - #define B_P1_RFMODE_ORI_RX_ALL GENMASK(23, 12) -+#define R_P1_RFMODE_FTM_RX 0x32B0 -+#define B_P1_RFMODE_FTM_RX GENMASK(11, 0) - #define R_P1_DBGMOD 0x32B8 - #define B_P1_DBGMOD_ON BIT(30) - #define R_S1_RXDC 0x32D4 ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1484,6 +1484,117 @@ static void rtw8852b_ctrl_btg(struct rtw - } - } - -+void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path_bit rx_path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u32 rst_mask0; -+ u32 rst_mask1; -+ -+ if (rx_path == RF_A) { -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); -+ } else if (rx_path == RF_B) { -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 2); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 2); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 2); -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); -+ } else if (rx_path == RF_AB) { -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 3); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 3); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 3); -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); -+ } -+ -+ rtw8852b_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0); -+ -+ if (chan->band_type == RTW89_BAND_2G && -+ (rx_path == RF_B || rx_path == RF_AB)) -+ rtw8852b_ctrl_btg(rtwdev, true); -+ else -+ rtw8852b_ctrl_btg(rtwdev, false); -+ -+ rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; -+ rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; -+ if (rx_path == RF_A) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); -+ } -+} -+ -+static void rtw8852b_bb_ctrl_rf_mode_rx_path(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path_bit rx_path) -+{ -+ if (rx_path == RF_A) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, -+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, -+ B_P0_RFMODE_FTM_RX, 0x333); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, -+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1111111); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, -+ B_P1_RFMODE_FTM_RX, 0x111); -+ } else if (rx_path == RF_B) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, -+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1111111); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, -+ B_P0_RFMODE_FTM_RX, 0x111); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, -+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, -+ B_P1_RFMODE_FTM_RX, 0x333); -+ } else if (rx_path == RF_AB) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, -+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX, -+ B_P0_RFMODE_FTM_RX, 0x333); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, -+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX, -+ B_P1_RFMODE_FTM_RX, 0x333); -+ } -+} -+ -+static void rtw8852b_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_hal *hal = &rtwdev->hal; -+ enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB; -+ -+ rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path); -+ rtw8852b_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path); -+ -+ if (rtwdev->hal.rx_nss == 1) { -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1); -+ } -+ -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); -+} -+ - static u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) - { - if (rtwdev->is_tssi_mode[rf_path]) { -@@ -1808,6 +1919,7 @@ static const struct rtw89_chip_ops rtw88 - .ctrl_btg = rtw8852b_ctrl_btg, - .query_ppdu = rtw8852b_query_ppdu, - .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, -+ .cfg_txrx_path = rtw8852b_bb_cfg_txrx_path, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h -@@ -87,4 +87,7 @@ struct rtw8852b_efuse { - - extern const struct rtw89_chip_info rtw8852b_chip_info; - -+void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path_bit rx_path); -+ - #endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-033-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-033-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch deleted file mode 100644 index 1133e9fc5..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-033-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch +++ /dev/null @@ -1,388 +0,0 @@ -From 572fd2ab377b123e52b442d015f9605409a21ad9 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:54:02 +0800 -Subject: [PATCH 033/149] wifi: rtw89: 8852b: add functions to control BB to - assist RF calibrations - -When we are going to do RF calibrations, they need BB helpers to control -TX PLCP, power, path and mode. Also, it they need helpers to backup and -restore some registers before and after RF calibrations. Then, use flow of -RF calibrations will be like backup registers, configure calibration, -configure TX parameters, measure calibration result, and finally restore -registers. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-9-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 288 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8852b.h | 44 +++ - 2 files changed, 332 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -56,6 +56,129 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static const struct rtw89_reg3_def rtw8852b_pmac_ht20_mcs7_tbl[] = { -+ {0x4580, 0x0000ffff, 0x0}, -+ {0x4580, 0xffff0000, 0x0}, -+ {0x4584, 0x0000ffff, 0x0}, -+ {0x4584, 0xffff0000, 0x0}, -+ {0x4580, 0x0000ffff, 0x1}, -+ {0x4578, 0x00ffffff, 0x2018b}, -+ {0x4570, 0x03ffffff, 0x7}, -+ {0x4574, 0x03ffffff, 0x32407}, -+ {0x45b8, 0x00000010, 0x0}, -+ {0x45b8, 0x00000100, 0x0}, -+ {0x45b8, 0x00000080, 0x0}, -+ {0x45b8, 0x00000008, 0x0}, -+ {0x45a0, 0x0000ff00, 0x0}, -+ {0x45a0, 0xff000000, 0x1}, -+ {0x45a4, 0x0000ff00, 0x2}, -+ {0x45a4, 0xff000000, 0x3}, -+ {0x45b8, 0x00000020, 0x0}, -+ {0x4568, 0xe0000000, 0x0}, -+ {0x45b8, 0x00000002, 0x1}, -+ {0x456c, 0xe0000000, 0x0}, -+ {0x45b4, 0x00006000, 0x0}, -+ {0x45b4, 0x00001800, 0x1}, -+ {0x45b8, 0x00000040, 0x0}, -+ {0x45b8, 0x00000004, 0x0}, -+ {0x45b8, 0x00000200, 0x0}, -+ {0x4598, 0xf8000000, 0x0}, -+ {0x45b8, 0x00100000, 0x0}, -+ {0x45a8, 0x00000fc0, 0x0}, -+ {0x45b8, 0x00200000, 0x0}, -+ {0x45b0, 0x00000038, 0x0}, -+ {0x45b0, 0x000001c0, 0x0}, -+ {0x45a0, 0x000000ff, 0x0}, -+ {0x45b8, 0x00400000, 0x0}, -+ {0x4590, 0x000007ff, 0x0}, -+ {0x45b0, 0x00000e00, 0x0}, -+ {0x45ac, 0x0000001f, 0x0}, -+ {0x45b8, 0x00800000, 0x0}, -+ {0x45a8, 0x0003f000, 0x0}, -+ {0x45b8, 0x01000000, 0x0}, -+ {0x45b0, 0x00007000, 0x0}, -+ {0x45b0, 0x00038000, 0x0}, -+ {0x45a0, 0x00ff0000, 0x0}, -+ {0x45b8, 0x02000000, 0x0}, -+ {0x4590, 0x003ff800, 0x0}, -+ {0x45b0, 0x001c0000, 0x0}, -+ {0x45ac, 0x000003e0, 0x0}, -+ {0x45b8, 0x04000000, 0x0}, -+ {0x45a8, 0x00fc0000, 0x0}, -+ {0x45b8, 0x08000000, 0x0}, -+ {0x45b0, 0x00e00000, 0x0}, -+ {0x45b0, 0x07000000, 0x0}, -+ {0x45a4, 0x000000ff, 0x0}, -+ {0x45b8, 0x10000000, 0x0}, -+ {0x4594, 0x000007ff, 0x0}, -+ {0x45b0, 0x38000000, 0x0}, -+ {0x45ac, 0x00007c00, 0x0}, -+ {0x45b8, 0x20000000, 0x0}, -+ {0x45a8, 0x3f000000, 0x0}, -+ {0x45b8, 0x40000000, 0x0}, -+ {0x45b4, 0x00000007, 0x0}, -+ {0x45b4, 0x00000038, 0x0}, -+ {0x45a4, 0x00ff0000, 0x0}, -+ {0x45b8, 0x80000000, 0x0}, -+ {0x4594, 0x003ff800, 0x0}, -+ {0x45b4, 0x000001c0, 0x0}, -+ {0x4598, 0xf8000000, 0x0}, -+ {0x45b8, 0x00100000, 0x0}, -+ {0x45a8, 0x00000fc0, 0x7}, -+ {0x45b8, 0x00200000, 0x0}, -+ {0x45b0, 0x00000038, 0x0}, -+ {0x45b0, 0x000001c0, 0x0}, -+ {0x45a0, 0x000000ff, 0x0}, -+ {0x45b4, 0x06000000, 0x0}, -+ {0x45b0, 0x00000007, 0x0}, -+ {0x45b8, 0x00080000, 0x0}, -+ {0x45a8, 0x0000003f, 0x0}, -+ {0x457c, 0xffe00000, 0x1}, -+ {0x4530, 0xffffffff, 0x0}, -+ {0x4588, 0x00003fff, 0x0}, -+ {0x4598, 0x000001ff, 0x0}, -+ {0x4534, 0xffffffff, 0x0}, -+ {0x4538, 0xffffffff, 0x0}, -+ {0x453c, 0xffffffff, 0x0}, -+ {0x4588, 0x0fffc000, 0x0}, -+ {0x4598, 0x0003fe00, 0x0}, -+ {0x4540, 0xffffffff, 0x0}, -+ {0x4544, 0xffffffff, 0x0}, -+ {0x4548, 0xffffffff, 0x0}, -+ {0x458c, 0x00003fff, 0x0}, -+ {0x4598, 0x07fc0000, 0x0}, -+ {0x454c, 0xffffffff, 0x0}, -+ {0x4550, 0xffffffff, 0x0}, -+ {0x4554, 0xffffffff, 0x0}, -+ {0x458c, 0x0fffc000, 0x0}, -+ {0x459c, 0x000001ff, 0x0}, -+ {0x4558, 0xffffffff, 0x0}, -+ {0x455c, 0xffffffff, 0x0}, -+ {0x4530, 0xffffffff, 0x4e790001}, -+ {0x4588, 0x00003fff, 0x0}, -+ {0x4598, 0x000001ff, 0x1}, -+ {0x4534, 0xffffffff, 0x0}, -+ {0x4538, 0xffffffff, 0x4b}, -+ {0x45ac, 0x38000000, 0x7}, -+ {0x4588, 0xf0000000, 0x0}, -+ {0x459c, 0x7e000000, 0x0}, -+ {0x45b8, 0x00040000, 0x0}, -+ {0x45b8, 0x00020000, 0x0}, -+ {0x4590, 0xffc00000, 0x0}, -+ {0x45b8, 0x00004000, 0x0}, -+ {0x4578, 0xff000000, 0x0}, -+ {0x45b8, 0x00000400, 0x0}, -+ {0x45b8, 0x00000800, 0x0}, -+ {0x45b8, 0x00001000, 0x0}, -+ {0x45b8, 0x00002000, 0x0}, -+ {0x45b4, 0x00018000, 0x0}, -+ {0x45ac, 0x07800000, 0x0}, -+ {0x45b4, 0x00000600, 0x2}, -+ {0x459c, 0x0001fe00, 0x80}, -+ {0x45ac, 0x00078000, 0x3}, -+ {0x459c, 0x01fe0000, 0x1}, -+}; -+ - static const struct rtw89_reg3_def rtw8852b_btc_preagc_en_defs[] = { - {0x46D0, GENMASK(1, 0), 0x3}, - {0x4790, GENMASK(1, 0), 0x3}, -@@ -1435,6 +1558,171 @@ rtw8852b_init_txpwr_unit(struct rtw89_de - return 0; - } - -+void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_reg3_def *def = rtw8852b_pmac_ht20_mcs7_tbl; -+ u8 i; -+ -+ for (i = 0; i < ARRAY_SIZE(rtw8852b_pmac_ht20_mcs7_tbl); i++, def++) -+ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); -+} -+ -+static void rtw8852b_stop_pmac_tx(struct rtw89_dev *rtwdev, -+ struct rtw8852b_bb_pmac_info *tx_info, -+ enum rtw89_phy_idx idx) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx"); -+ if (tx_info->mode == CONT_TX) -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, idx); -+ else if (tx_info->mode == PKTS_TX) -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, idx); -+} -+ -+static void rtw8852b_start_pmac_tx(struct rtw89_dev *rtwdev, -+ struct rtw8852b_bb_pmac_info *tx_info, -+ enum rtw89_phy_idx idx) -+{ -+ enum rtw8852b_pmac_mode mode = tx_info->mode; -+ u32 pkt_cnt = tx_info->tx_cnt; -+ u16 period = tx_info->period; -+ -+ if (mode == CONT_TX && !tx_info->is_cck) { -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, idx); -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start"); -+ } else if (mode == PKTS_TX) { -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, -+ B_PMAC_TX_PRD_MSK, period, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK, -+ pkt_cnt, idx); -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start"); -+ } -+ -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx); -+} -+ -+void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev, -+ struct rtw8852b_bb_pmac_info *tx_info, -+ enum rtw89_phy_idx idx) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ if (!tx_info->en_pmac_tx) { -+ rtw8852b_stop_pmac_tx(rtwdev, tx_info, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx); -+ if (chan->band_type == RTW89_BAND_2G) -+ rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS); -+ return; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable"); -+ -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx); -+ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx); -+ -+ rtw8852b_start_pmac_tx(rtwdev, tx_info, idx); -+} -+ -+void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, -+ u16 tx_cnt, u16 period, u16 tx_time, -+ enum rtw89_phy_idx idx) -+{ -+ struct rtw8852b_bb_pmac_info tx_info = {0}; -+ -+ tx_info.en_pmac_tx = enable; -+ tx_info.is_cck = 0; -+ tx_info.mode = PKTS_TX; -+ tx_info.tx_cnt = tx_cnt; -+ tx_info.period = period; -+ tx_info.tx_time = tx_time; -+ -+ rtw8852b_bb_set_pmac_tx(rtwdev, &tx_info, idx); -+} -+ -+void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, -+ enum rtw89_phy_idx idx) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm); -+ -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx); -+} -+ -+void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) -+{ -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path); -+ -+ if (tx_path == RF_PATH_A) { -+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 1); -+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0); -+ } else if (tx_path == RF_PATH_B) { -+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2); -+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0); -+ } else if (tx_path == RF_PATH_AB) { -+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 3); -+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4); -+ } else { -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path"); -+ } -+} -+ -+void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx idx, u8 mode) -+{ -+ if (mode != 0) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch"); -+ -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx); -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx); -+} -+ -+void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, -+ struct rtw8852b_bb_tssi_bak *bak) -+{ -+ s32 tmp; -+ -+ bak->tx_path = rtw89_phy_read32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, idx); -+ bak->rx_path = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, idx); -+ bak->p0_rfmode = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, idx); -+ bak->p0_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, idx); -+ bak->p1_rfmode = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, idx); -+ bak->p1_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, idx); -+ tmp = rtw89_phy_read32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, idx); -+ bak->tx_pwr = sign_extend32(tmp, 8); -+} -+ -+void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, -+ const struct rtw8852b_bb_tssi_bak *bak) -+{ -+ rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, bak->tx_path, idx); -+ if (bak->tx_path == RF_AB) -+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x4); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x0); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, bak->rx_path, idx); -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, bak->p0_rfmode, idx); -+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, bak->p0_rfmode_ftm, idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, bak->p1_rfmode, idx); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, bak->p1_rfmode_ftm, idx); -+ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, bak->tx_pwr, idx); -+} -+ - static void rtw8852b_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) - { - rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852b_btc_preagc_en_defs_tbl : ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h -@@ -10,6 +10,13 @@ - #define RF_PATH_NUM_8852B 2 - #define BB_PATH_NUM_8852B 2 - -+enum rtw8852b_pmac_mode { -+ NONE_TEST, -+ PKTS_TX, -+ PKTS_RX, -+ CONT_TX -+}; -+ - struct rtw8852b_u_efuse { - u8 rsvd[0x88]; - u8 mac_addr[ETH_ALEN]; -@@ -85,9 +92,46 @@ struct rtw8852b_efuse { - }; - } __packed; - -+struct rtw8852b_bb_pmac_info { -+ u8 en_pmac_tx:1; -+ u8 is_cck:1; -+ u8 mode:3; -+ u8 rsvd:3; -+ u16 tx_cnt; -+ u16 period; -+ u16 tx_time; -+ u8 duty_cycle; -+}; -+ -+struct rtw8852b_bb_tssi_bak { -+ u8 tx_path; -+ u8 rx_path; -+ u32 p0_rfmode; -+ u32 p0_rfmode_ftm; -+ u32 p1_rfmode; -+ u32 p1_rfmode_ftm; -+ s16 tx_pwr; /* S9 */ -+}; -+ - extern const struct rtw89_chip_info rtw8852b_chip_info; - -+void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev); -+void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev, -+ struct rtw8852b_bb_pmac_info *tx_info, -+ enum rtw89_phy_idx idx); -+void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, -+ u16 tx_cnt, u16 period, u16 tx_time, -+ enum rtw89_phy_idx idx); -+void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, -+ enum rtw89_phy_idx idx); -+void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path); - void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, - enum rtw89_rf_path_bit rx_path); -+void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx idx, u8 mode); -+void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, -+ struct rtw8852b_bb_tssi_bak *bak); -+void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, -+ const struct rtw8852b_bb_tssi_bak *bak); - - #endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-034-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-034-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch deleted file mode 100644 index bad691291..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-034-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch +++ /dev/null @@ -1,300 +0,0 @@ -From b8fe87b816851d08a31c7c9589855c8535672299 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sun, 9 Oct 2022 20:54:03 +0800 -Subject: [PATCH 034/149] wifi: rtw89: 8852b: add basic attributes of chip_info - -Add 8852b specific constant tables and basic attributes containing -common chip_ops, firmware name, supported TX/RX NSS, number of CAM, -coexistence version, control register set, and so on. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221009125403.19662-10-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 235 ++++++++++++++++++ - 1 file changed, 235 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -217,6 +217,150 @@ static const struct rtw89_reg3_def rtw88 - - static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_dis_defs); - -+static const u32 rtw8852b_h2c_regs[RTW89_H2CREG_MAX] = { -+ R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, -+ R_AX_H2CREG_DATA3 -+}; -+ -+static const u32 rtw8852b_c2h_regs[RTW89_C2HREG_MAX] = { -+ R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, -+ R_AX_C2HREG_DATA3 -+}; -+ -+static const struct rtw89_page_regs rtw8852b_page_regs = { -+ .hci_fc_ctrl = R_AX_HCI_FC_CTRL, -+ .ch_page_ctrl = R_AX_CH_PAGE_CTRL, -+ .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, -+ .ach_page_info = R_AX_ACH0_PAGE_INFO, -+ .pub_page_info3 = R_AX_PUB_PAGE_INFO3, -+ .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, -+ .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, -+ .pub_page_info1 = R_AX_PUB_PAGE_INFO1, -+ .pub_page_info2 = R_AX_PUB_PAGE_INFO2, -+ .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, -+ .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, -+ .wp_page_info1 = R_AX_WP_PAGE_INFO1, -+}; -+ -+static const struct rtw89_reg_def rtw8852b_dcfo_comp = { -+ R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK -+}; -+ -+static const struct rtw89_imr_info rtw8852b_imr_info = { -+ .wdrls_imr_set = B_AX_WDRLS_IMR_SET, -+ .wsec_imr_reg = R_AX_SEC_DEBUG, -+ .wsec_imr_set = B_AX_IMR_ERROR, -+ .mpdu_tx_imr_set = 0, -+ .mpdu_rx_imr_set = 0, -+ .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, -+ .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, -+ .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, -+ .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, -+ .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, -+ .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, -+ .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, -+ .wde_imr_clr = B_AX_WDE_IMR_CLR, -+ .wde_imr_set = B_AX_WDE_IMR_SET, -+ .ple_imr_clr = B_AX_PLE_IMR_CLR, -+ .ple_imr_set = B_AX_PLE_IMR_SET, -+ .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, -+ .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, -+ .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, -+ .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, -+ .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, -+ .other_disp_imr_set = 0, -+ .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, -+ .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, -+ .bbrpt_err_imr_set = 0, -+ .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, -+ .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL, -+ .ptcl_imr_set = B_AX_PTCL_IMR_SET, -+ .cdma_imr_0_reg = R_AX_DLE_CTRL, -+ .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, -+ .cdma_imr_0_set = B_AX_DLE_IMR_SET, -+ .cdma_imr_1_reg = 0, -+ .cdma_imr_1_clr = 0, -+ .cdma_imr_1_set = 0, -+ .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, -+ .phy_intf_imr_clr = 0, -+ .phy_intf_imr_set = 0, -+ .rmac_imr_reg = R_AX_RMAC_ERR_ISR, -+ .rmac_imr_clr = B_AX_RMAC_IMR_CLR, -+ .rmac_imr_set = B_AX_RMAC_IMR_SET, -+ .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, -+ .tmac_imr_clr = B_AX_TMAC_IMR_CLR, -+ .tmac_imr_set = B_AX_TMAC_IMR_SET, -+}; -+ -+static const struct rtw89_rrsr_cfgs rtw8852b_rrsr_cfgs = { -+ .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, -+ .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, -+}; -+ -+static const struct rtw89_dig_regs rtw8852b_dig_regs = { -+ .seg0_pd_reg = R_SEG0R_PD_V1, -+ .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, -+ .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, -+ .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, -+ .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, -+ .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, -+ .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, -+ .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, -+ .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, -+ .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+}; -+ -+static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = { -+ {15, 0, 0, 7}, /* 0 -> original */ -+ {15, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ -+ {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {6, 1, 0, 7}, -+ {13, 1, 0, 7}, -+ {13, 1, 0, 7} -+}; -+ -+static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_dl[] = { -+ {15, 0, 0, 7}, /* 0 -> original */ -+ {15, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {15, 1, 0, 7}, -+ {15, 1, 0, 7}, -+ {15, 1, 0, 7} -+}; -+ -+static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = { -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), -+ RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178), -+}; -+ -+static const u8 rtw89_btc_8852b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; -+static const u8 rtw89_btc_8852b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; -+ - static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) - { - u32 val32; -@@ -2195,10 +2339,13 @@ static const struct rtw89_chip_ops rtw88 - .disable_bb_rf = rtw8852b_mac_disable_bb_rf, - .bb_reset = rtw8852b_bb_reset, - .bb_sethw = rtw8852b_bb_sethw, -+ .read_rf = rtw89_phy_read_rf_v1, -+ .write_rf = rtw89_phy_write_rf_v1, - .set_channel = rtw8852b_set_channel, - .set_channel_help = rtw8852b_set_channel_help, - .read_efuse = rtw8852b_read_efuse, - .read_phycap = rtw8852b_read_phycap, -+ .fem_setup = NULL, - .power_trim = rtw8852b_power_trim, - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, -@@ -2208,8 +2355,16 @@ static const struct rtw89_chip_ops rtw88 - .query_ppdu = rtw8852b_query_ppdu, - .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, - .cfg_txrx_path = rtw8852b_bb_cfg_txrx_path, -+ .set_txpwr_ul_tb_offset = rtw8852b_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, -+ .fill_txdesc = rtw89_core_fill_txdesc, -+ .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, -+ .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, -+ .mac_cfg_gnt = rtw89_mac_cfg_gnt, -+ .stop_sch_tx = rtw89_mac_stop_sch_tx, -+ .resume_sch_tx = rtw89_mac_resume_sch_tx, -+ .h2c_dctl_sec_cam = NULL, - - .btc_set_rfe = rtw8852b_btc_set_rfe, - .btc_init_cfg = rtw8852b_btc_init_cfg, -@@ -2225,12 +2380,46 @@ static const struct rtw89_chip_ops rtw88 - const struct rtw89_chip_info rtw8852b_chip_info = { - .chip_id = RTL8852B, - .ops = &rtw8852b_chip_ops, -+ .fw_name = "rtw89/rtw8852b_fw.bin", - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, -+ .max_amsdu_limit = 3500, -+ .dis_2g_40m_ul_ofdma = true, -+ .rsvd_ple_ofst = 0x2f800, - .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, - .dle_mem = rtw8852b_dle_mem_pcie, -+ .rf_base_addr = {0xe000, 0xf000}, - .pwr_on_seq = NULL, - .pwr_off_seq = NULL, -+ .bb_table = &rtw89_8852b_phy_bb_table, -+ .bb_gain_table = &rtw89_8852b_phy_bb_gain_table, -+ .rf_table = {&rtw89_8852b_phy_radioa_table, -+ &rtw89_8852b_phy_radiob_table,}, -+ .nctl_table = &rtw89_8852b_phy_nctl_table, -+ .byr_table = &rtw89_8852b_byr_table, -+ .txpwr_lmt_2g = &rtw89_8852b_txpwr_lmt_2g, -+ .txpwr_lmt_5g = &rtw89_8852b_txpwr_lmt_5g, -+ .txpwr_lmt_ru_2g = &rtw89_8852b_txpwr_lmt_ru_2g, -+ .txpwr_lmt_ru_5g = &rtw89_8852b_txpwr_lmt_ru_5g, -+ .txpwr_factor_rf = 2, -+ .txpwr_factor_mac = 1, -+ .dig_table = NULL, -+ .dig_regs = &rtw8852b_dig_regs, -+ .tssi_dbw_table = NULL, -+ .support_chanctx_num = 0, -+ .support_bands = BIT(NL80211_BAND_2GHZ) | -+ BIT(NL80211_BAND_5GHZ), -+ .support_bw160 = false, -+ .hw_sec_hdr = false, -+ .rf_path_num = 2, -+ .tx_nss = 2, -+ .rx_nss = 2, -+ .acam_num = 128, -+ .bcam_num = 10, -+ .scam_num = 128, -+ .bacam_num = 2, -+ .bacam_dynamic_num = 4, -+ .bacam_v1 = false, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 2048, -@@ -2239,6 +2428,52 @@ const struct rtw89_chip_info rtw8852b_ch - .dav_log_efuse_size = 16, - .phycap_addr = 0x580, - .phycap_size = 128, -+ .para_ver = 0, -+ .wlcx_desired = 0x05050000, -+ .btcx_desired = 0x5, -+ .scbd = 0x1, -+ .mailbox = 0x1, -+ .btc_fwinfo_buf = 1024, -+ -+ .fcxbtcrpt_ver = 1, -+ .fcxtdma_ver = 1, -+ .fcxslots_ver = 1, -+ .fcxcysta_ver = 2, -+ .fcxstep_ver = 2, -+ .fcxnullsta_ver = 1, -+ .fcxmreg_ver = 1, -+ .fcxgpiodbg_ver = 1, -+ .fcxbtver_ver = 1, -+ .fcxbtscan_ver = 1, -+ .fcxbtafh_ver = 1, -+ .fcxbtdevinfo_ver = 1, -+ .afh_guard_ch = 6, -+ .wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres, -+ .bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres, -+ .rssi_tol = 2, -+ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852b_mon_reg), -+ .mon_reg = rtw89_btc_8852b_mon_reg, -+ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852b_rf_ul), -+ .rf_para_ulink = rtw89_btc_8852b_rf_ul, -+ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852b_rf_dl), -+ .rf_para_dlink = rtw89_btc_8852b_rf_dl, -+ .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | -+ BIT(RTW89_PS_MODE_CLK_GATED) | -+ BIT(RTW89_PS_MODE_PWR_GATED), -+ .low_power_hci_modes = 0, -+ .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, -+ .hci_func_en_addr = R_AX_HCI_FUNC_EN, -+ .h2c_desc_size = sizeof(struct rtw89_txwd_body), -+ .txwd_body_size = sizeof(struct rtw89_txwd_body), -+ .h2c_ctrl_reg = R_AX_H2CREG_CTRL, -+ .h2c_regs = rtw8852b_h2c_regs, -+ .c2h_ctrl_reg = R_AX_C2HREG_CTRL, -+ .c2h_regs = rtw8852b_c2h_regs, -+ .page_regs = &rtw8852b_page_regs, -+ .dcfo_comp = &rtw8852b_dcfo_comp, -+ .dcfo_comp_sft = 3, -+ .imr_info = &rtw8852b_imr_info, -+ .rrsr_cfgs = &rtw8852b_rrsr_cfgs, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-035-wifi-rtw89-8852b-rfk-add-DACK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-035-wifi-rtw89-8852b-rfk-add-DACK.patch deleted file mode 100644 index 634b7d4f8..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-035-wifi-rtw89-8852b-rfk-add-DACK.patch +++ /dev/null @@ -1,537 +0,0 @@ -From 16be5e3be0e5794b5e7227c63b440f3fdb9c22ce Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Oct 2022 16:32:30 +0800 -Subject: [PATCH 035/149] wifi: rtw89: 8852b: rfk: add DACK - -DACK (digital-to-analog converters calibration) is used to calibrate DAC -to output good quality signals. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221012083234.20224-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 21 + - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 432 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + - 3 files changed, 454 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3526,6 +3526,7 @@ - #define B_ANAPAR_ADCCLK BIT(30) - #define B_ANAPAR_FLTRST BIT(22) - #define B_ANAPAR_CRXBB GENMASK(18, 16) -+#define B_ANAPAR_EN BIT(16) - #define B_ANAPAR_14 GENMASK(15, 0) - #define R_RFE_E_A2 0x0334 - #define R_RFE_O_SEL_A2 0x0338 -@@ -4380,6 +4381,8 @@ - #define B_DACK_S0P3_OK BIT(2) - #define R_DACK_DADCK01 0xC084 - #define B_DACK_DADCK01 GENMASK(31, 24) -+#define R_DRCK_FH 0xC094 -+#define B_DRCK_LAT BIT(9) - #define R_DRCK 0xC0C4 - #define B_DRCK_IDLE BIT(9) - #define B_DRCK_EN BIT(6) -@@ -4387,15 +4390,28 @@ - #define R_DRCK_RES 0xC0C8 - #define B_DRCK_RES GENMASK(19, 15) - #define B_DRCK_POL BIT(3) -+#define R_DRCK_V1 0xC0CC -+#define B_DRCK_V1_SEL BIT(9) -+#define B_DRCK_V1_KICK BIT(6) -+#define B_DRCK_V1_CV GENMASK(4, 0) -+#define R_DRCK_RS 0xC0D0 -+#define B_DRCK_RS_LPS GENMASK(19, 15) -+#define B_DRCK_RS_DONE BIT(3) - #define R_PATH0_SAMPL_DLY_T_V1 0xC0D4 - #define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) - #define R_P0_CFCH_BW0 0xC0D4 - #define B_P0_CFCH_BW0 GENMASK(27, 26) - #define R_P0_CFCH_BW1 0xC0D8 - #define B_P0_CFCH_BW1 GENMASK(8, 5) -+#define R_ADDCK0D 0xC0F0 -+#define B_ADDCK0D_VAL2 GENMASK(31, 26) -+#define B_ADDCK0D_VAL GENMASK(25, 16) - #define R_ADDCK0 0xC0F4 -+#define B_ADDCK0_TRG BIT(11) - #define B_ADDCK0 GENMASK(9, 8) -+#define B_ADDCK0_MAN GENMASK(5, 4) - #define B_ADDCK0_EN BIT(4) -+#define B_ADDCK0_VAL GENMASK(3, 0) - #define B_ADDCK0_RST BIT(2) - #define R_ADDCK0_RL 0xC0F8 - #define B_ADDCK0_RLS GENMASK(29, 28) -@@ -4436,8 +4452,13 @@ - #define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) - #define R_PATH1_BW_SEL_V1 0xC1D8 - #define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5) -+#define R_ADDCK1D 0xC1F0 -+#define B_ADDCK1D_VAL2 GENMASK(31, 26) -+#define B_ADDCK1D_VAL GENMASK(25, 16) - #define R_ADDCK1 0xC1F4 -+#define B_ADDCK1_TRG BIT(11) - #define B_ADDCK1 GENMASK(9, 8) -+#define B_ADDCK1_MAN GENMASK(5, 4) - #define B_ADDCK1_EN BIT(4) - #define B_ADDCK1_RST BIT(2) - #define R_ADDCK1_RL 0xC1F8 ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -12,6 +12,8 @@ - #include "rtw8852b_rfk_table.h" - #include "rtw8852b_table.h" - -+#define ADDC_T_AVG 100 -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - u8 val; -@@ -30,6 +32,436 @@ static u8 _kpath(struct rtw89_dev *rtwde - return val; - } - -+static void _afe_init(struct rtw89_dev *rtwdev) -+{ -+ rtw89_write32(rtwdev, R_AX_PHYREG_SET, 0xf); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_afe_init_defs_tbl); -+} -+ -+static void _drck(struct rtw89_dev *rtwdev) -+{ -+ u32 rck_d; -+ u32 val; -+ int ret; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, -+ false, rtwdev, R_DRCK_RS, B_DRCK_RS_DONE); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); -+ rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RS, B_DRCK_RS_LPS); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_SEL, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_CV, rck_d); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0cc = 0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_DRCK_V1, MASKDWORD)); -+} -+ -+static void _addck_backup(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); -+ dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); -+ dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0); -+ dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0); -+ dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1); -+} -+ -+static void _addck_reload(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ -+ /* S0 */ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL, dack->addck_d[0][0]); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_VAL, dack->addck_d[0][1] >> 6); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL2, dack->addck_d[0][1] & 0x3f); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x3); -+ -+ /* S1 */ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL, dack->addck_d[1][0]); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK0_VAL, dack->addck_d[1][1] >> 6); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL2, dack->addck_d[1][1] & 0x3f); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, 0x3); -+} -+ -+static void _dack_backup_s0(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u8 i; -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); -+ dack->msbk_d[0][0][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); -+ rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); -+ dack->msbk_d[0][1][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); -+ } -+ -+ dack->biask_d[0][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); -+ dack->biask_d[0][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); -+ -+ dack->dadck_d[0][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00); -+ dack->dadck_d[0][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01); -+} -+ -+static void _dack_backup_s1(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u8 i; -+ -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); -+ -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i); -+ dack->msbk_d[1][0][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S); -+ rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i); -+ dack->msbk_d[1][1][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S); -+ } -+ -+ dack->biask_d[1][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10); -+ dack->biask_d[1][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11); -+ -+ dack->dadck_d[1][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10); -+ dack->dadck_d[1][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11); -+} -+ -+static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ s32 dc_re = 0, dc_im = 0; -+ u32 tmp; -+ u32 i; -+ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_check_addc_defs_a_tbl, -+ &rtw8852b_check_addc_defs_b_tbl); -+ -+ for (i = 0; i < ADDC_T_AVG; i++) { -+ tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); -+ dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), 11); -+ dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11); -+ } -+ -+ dc_re /= ADDC_T_AVG; -+ dc_im /= ADDC_T_AVG; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); -+} -+ -+static void _addck(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 val; -+ int ret; -+ -+ /* S0 */ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x30, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); -+ _check_addc(rtwdev, RF_PATH_A); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x0); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, -+ false, rtwdev, R_ADDCKR0, BIT(0)); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); -+ dack->addck_timeout[0] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); -+ _check_addc(rtwdev, RF_PATH_A); -+ -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); -+ -+ /* S1 */ -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); -+ _check_addc(rtwdev, RF_PATH_B); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x0); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, -+ false, rtwdev, R_ADDCKR1, BIT(0)); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); -+ dack->addck_timeout[1] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); -+ _check_addc(rtwdev, RF_PATH_B); -+ -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); -+} -+ -+static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_check_dadc_en_defs_a_tbl, -+ &rtw8852b_check_dadc_en_defs_b_tbl); -+ -+ _check_addc(rtwdev, path); -+ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_check_dadc_dis_defs_a_tbl, -+ &rtw8852b_check_dadc_dis_defs_b_tbl); -+} -+ -+static bool _dack_s0_check_done(struct rtw89_dev *rtwdev, bool part1) -+{ -+ if (part1) { -+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0) -+ return false; -+ } else { -+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) -+ return false; -+ } -+ -+ return true; -+} -+ -+static void _dack_s0(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ bool done; -+ int ret; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_1_defs_tbl); -+ -+ ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000, -+ false, rtwdev, true); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); -+ dack->msbk_timeout[0] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_2_defs_tbl); -+ -+ ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000, -+ false, rtwdev, false); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n"); -+ dack->dadck_timeout[0] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_3_defs_tbl); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); -+ -+ _dack_backup_s0(rtwdev); -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); -+} -+ -+static bool _dack_s1_check_done(struct rtw89_dev *rtwdev, bool part1) -+{ -+ if (part1) { -+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 && -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0) -+ return false; -+ } else { -+ if (rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK_S1P2_OK) == 0 && -+ rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK_S1P3_OK) == 0) -+ return false; -+ } -+ -+ return true; -+} -+ -+static void _dack_s1(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ bool done; -+ int ret; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_1_defs_tbl); -+ -+ ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000, -+ false, rtwdev, true); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); -+ dack->msbk_timeout[1] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_2_defs_tbl); -+ -+ ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000, -+ false, rtwdev, false); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); -+ dack->dadck_timeout[1] = true; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_3_defs_tbl); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); -+ -+ _check_dadc(rtwdev, RF_PATH_B); -+ _dack_backup_s1(rtwdev); -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0); -+} -+ -+static void _dack(struct rtw89_dev *rtwdev) -+{ -+ _dack_s0(rtwdev); -+ _dack_s1(rtwdev); -+} -+ -+static void _dack_dump(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u8 i; -+ u8 t; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->addck_d[0][0], dack->addck_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->addck_d[1][0], dack->addck_d[1][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->dadck_d[0][0], dack->dadck_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->dadck_d[1][0], dack->dadck_d[1][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", -+ dack->biask_d[0][0], dack->biask_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", -+ dack->biask_d[1][0], dack->biask_d[1][1]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); -+ for (i = 0; i < 0x10; i++) { -+ t = dack->msbk_d[0][0][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ t = dack->msbk_d[0][1][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ t = dack->msbk_d[1][0][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ t = dack->msbk_d[1][1][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+} -+ -+static void _dac_cal(struct rtw89_dev *rtwdev, bool force) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 rf0_0, rf1_0; -+ -+ dack->dack_done = false; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x1\n"); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); -+ -+ rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); -+ rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); -+ _afe_init(rtwdev); -+ _drck(rtwdev); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1); -+ _addck(rtwdev); -+ _addck_backup(rtwdev); -+ _addck_reload(rtwdev); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); -+ _dack(rtwdev); -+ _dack_dump(rtwdev); -+ dack->dack_done = true; -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); -+ dack->dack_cnt++; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); -+} -+ -+void rtw8852b_dack(struct rtw89_dev *rtwdev) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); -+ _dac_cal(rtwdev, false); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -7,6 +7,7 @@ - - #include "core.h" - -+void rtw8852b_dack(struct rtw89_dev *rtwdev); - void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-036-wifi-rtw89-8852b-rfk-add-RCK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-036-wifi-rtw89-8852b-rfk-add-RCK.patch deleted file mode 100644 index 649327476..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-036-wifi-rtw89-8852b-rfk-add-RCK.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 10298b53bff642e586e5b82616914c9fa3d9a906 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Oct 2022 16:32:31 +0800 -Subject: [PATCH 036/149] wifi: rtw89: 8852b: rfk: add RCK - -RCK is synchronize RC calibration. Driver triggers this calibration and -sets the result to register. This calibration is needed once when interface -is going to up. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221012083234.20224-3-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 43 +++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + - 2 files changed, 44 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -32,6 +32,41 @@ static u8 _kpath(struct rtw89_dev *rtwde - return val; - } - -+static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ u32 rf_reg5; -+ u32 rck_val; -+ u32 val; -+ int ret; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); -+ -+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); -+ -+ /* RCK trigger */ -+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, -+ false, rtwdev, path, RR_RCKS, BIT(3)); -+ -+ rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", -+ rck_val, ret); -+ -+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", -+ rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); -+} -+ - static void _afe_init(struct rtw89_dev *rtwdev) - { - rtw89_write32(rtwdev, R_AX_PHYREG_SET, 0xf); -@@ -453,6 +488,14 @@ static void _dac_cal(struct rtw89_dev *r - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); - } - -+void rtw8852b_rck(struct rtw89_dev *rtwdev) -+{ -+ u8 path; -+ -+ for (path = 0; path < RF_PATH_NUM_8852B; path++) -+ _rck(rtwdev, path); -+} -+ - void rtw8852b_dack(struct rtw89_dev *rtwdev) - { - u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -7,6 +7,7 @@ - - #include "core.h" - -+void rtw8852b_rck(struct rtw89_dev *rtwdev); - void rtw8852b_dack(struct rtw89_dev *rtwdev); - void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-037-wifi-rtw89-8852b-rfk-add-RX-DCK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-037-wifi-rtw89-8852b-rfk-add-RX-DCK.patch deleted file mode 100644 index d30b165bf..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-037-wifi-rtw89-8852b-rfk-add-RX-DCK.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 212671074ab2f3e33fd5e95392c7356410ad7f8d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Oct 2022 16:32:32 +0800 -Subject: [PATCH 037/149] wifi: rtw89: 8852b: rfk: add RX DCK - -RX DCK is receiver DC calibration. With this calibration, we have proper -DC offset to reflect correct received signal strength indicator. Do this -calibration when bringing up interface and going to run on AP channel. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221012083234.20224-4-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 75 +++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + - 2 files changed, 76 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -12,6 +12,7 @@ - #include "rtw8852b_rfk_table.h" - #include "rtw8852b_table.h" - -+#define RTW8852B_RXDCK_VER 0x1 - #define ADDC_T_AVG 100 - - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -@@ -32,6 +33,47 @@ static u8 _kpath(struct rtw89_dev *rtwde - return val; - } - -+static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); -+ mdelay(1); -+} -+ -+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ u8 path, dck_tune; -+ u32 rf_reg5; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n", -+ RTW8852B_RXDCK_VER, rtwdev->hal.cv); -+ -+ for (path = 0; path < RF_PATH_NUM_8852B; path++) { -+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); -+ dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ rtw89_phy_write32_mask(rtwdev, -+ R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, 0x1); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); -+ _set_rx_dck(rtwdev, phy, path); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ rtw89_phy_write32_mask(rtwdev, -+ R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, 0x0); -+ } -+} -+ - static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - u32 rf_reg5; -@@ -488,6 +530,24 @@ static void _dac_cal(struct rtw89_dev *r - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); - } - -+static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) -+{ -+ u32 rf_mode; -+ u8 path; -+ int ret; -+ -+ for (path = 0; path < RF_PATH_MAX; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, -+ rf_mode != 2, 2, 5000, false, -+ rtwdev, path, RR_MOD, RR_MOD_MASK); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret); -+ } -+} -+ - void rtw8852b_rck(struct rtw89_dev *rtwdev) - { - u8 path; -@@ -505,6 +565,21 @@ void rtw8852b_dack(struct rtw89_dev *rtw - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); - } - -+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ _rx_dck(rtwdev, phy_idx); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -9,6 +9,7 @@ - - void rtw8852b_rck(struct rtw89_dev *rtwdev); - void rtw8852b_dack(struct rtw89_dev *rtwdev); -+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-038-wifi-rtw89-8852b-rfk-add-IQK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-038-wifi-rtw89-8852b-rfk-add-IQK.patch deleted file mode 100644 index 485d85bd6..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-038-wifi-rtw89-8852b-rfk-add-IQK.patch +++ /dev/null @@ -1,1199 +0,0 @@ -From f2abe804e8230ff20a834e204bde529935df5467 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Oct 2022 16:32:33 +0800 -Subject: [PATCH 038/149] wifi: rtw89: 8852b: rfk: add IQK - -IQ signal calibration is a very important calibration to yield good RF -performance. We do this calibration only if we are going to run on AP -channel. During scanning phase, without this calibration RF performance -is still acceptable because it transmits with low data rate at this phase. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221012083234.20224-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 19 + - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1046 +++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + - 3 files changed, 1066 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3295,6 +3295,7 @@ - #define RR_MOD_IQK GENMASK(19, 4) - #define RR_MOD_DPK GENMASK(19, 5) - #define RR_MOD_MASK GENMASK(19, 16) -+#define RR_MOD_RGM GENMASK(13, 4) - #define RR_MOD_V_DOWN 0x0 - #define RR_MOD_V_STANDBY 0x1 - #define RR_MOD_V_TX 0x2 -@@ -3368,6 +3369,7 @@ - #define RR_RXK_PLLEN BIT(5) - #define RR_LUTWA 0x33 - #define RR_LUTWA_MASK GENMASK(9, 0) -+#define RR_LUTWA_M1 GENMASK(7, 0) - #define RR_LUTWA_M2 GENMASK(4, 0) - #define RR_LUTWD1 0x3e - #define RR_LUTWD0 0x3f -@@ -3417,6 +3419,8 @@ - #define RR_TXA2_LDO GENMASK(19, 16) - #define RR_TRXIQ 0x66 - #define RR_RSV6 0x6d -+#define RR_TXVBUF 0x7c -+#define RR_TXVBUF_DACEN BIT(5) - #define RR_TXPOW 0x7f - #define RR_TXPOW_TXA BIT(8) - #define RR_TXPOW_TXAS BIT(7) -@@ -3440,7 +3444,9 @@ - #define RR_RXA2 0x8c - #define RR_RXA2_C1 GENMASK(12, 10) - #define RR_RXA2_C2 GENMASK(9, 3) -+#define RR_RXA2_CC2 GENMASK(8, 7) - #define RR_RXA2_IATT GENMASK(7, 4) -+#define RR_RXA2_HATT GENMASK(6, 0) - #define RR_RXA2_ATT GENMASK(3, 0) - #define RR_RXIQGEN 0x8d - #define RR_RXIQGEN_ATTL GENMASK(12, 8) -@@ -3452,6 +3458,7 @@ - #define RR_RXBB2_IDAC GENMASK(11, 9) - #define RR_RXBB2_EBW GENMASK(6, 5) - #define RR_XALNA2 0x90 -+#define RR_XALNA2_SW2 GENMASK(9, 8) - #define RR_XALNA2_SW GENMASK(1, 0) - #define RR_DCK 0x92 - #define RR_DCK_DONE GENMASK(7, 5) -@@ -3532,6 +3539,8 @@ - #define R_RFE_O_SEL_A2 0x0338 - #define R_RFE_SEL0_A2 0x033C - #define R_RFE_SEL32_A2 0x0340 -+#define R_CIRST 0x035c -+#define B_CIRST_SYN GENMASK(11, 10) - #define R_SWSI_DATA_V1 0x0370 - #define B_SWSI_DATA_VAL_V1 GENMASK(19, 0) - #define B_SWSI_DATA_ADDR_V1 GENMASK(27, 20) -@@ -3779,6 +3788,11 @@ - #define B_P1_EN_SOUND_WO_NDP BIT(1) - #define R_S1_HW_SI_DIS 0x3200 - #define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) -+#define R_P1_RXCK 0x32A0 -+#define B_P1_RXCK_BW3 BIT(30) -+#define B_P1_TXCK_ALL GENMASK(19, 12) -+#define B_P1_RXCK_ON BIT(19) -+#define B_P1_RXCK_VAL GENMASK(18, 16) - #define R_P1_RFMODE 0x32AC - #define B_P1_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4) - #define B_P1_RFMODE_MUX GENMASK(11, 4) -@@ -4109,6 +4123,7 @@ - #define R_P0_TSSI_AVG 0x5820 - #define B_P0_TSSI_AVG GENMASK(15, 12) - #define R_P0_RFCTM 0x5864 -+#define B_P0_RFCTM_EN BIT(29) - #define B_P0_RFCTM_VAL GENMASK(25, 20) - #define R_P0_RFCTM_RDY BIT(26) - #define R_P0_TRSW 0x5868 -@@ -4268,6 +4283,7 @@ - #define B_COEF_SEL_MDPD BIT(8) - #define R_CFIR_SYS 0x8120 - #define R_IQK_RES 0x8124 -+#define B_IQK_RES_K BIT(28) - #define B_IQK_RES_TXCFIR GENMASK(11, 8) - #define B_IQK_RES_RXCFIR GENMASK(3, 0) - #define R_TXIQC 0x8138 -@@ -4324,6 +4340,9 @@ - #define B_RPT_PER_TSSI GENMASK(28, 16) - #define B_RPT_PER_OF GENMASK(15, 8) - #define B_RPT_PER_TH GENMASK(5, 0) -+#define R_IQRSN 0x8220 -+#define B_IQRSN_K1 BIT(28) -+#define B_IQRSN_K2 BIT(16) - #define R_RXCFIR_P0C0 0x8D40 - #define R_RXCFIR_P0C1 0x8D84 - #define R_RXCFIR_P0C2 0x8DC8 ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -13,8 +13,189 @@ - #include "rtw8852b_table.h" - - #define RTW8852B_RXDCK_VER 0x1 -+#define RTW8852B_IQK_VER 0x2a -+#define RTW8852B_IQK_SS 2 -+#define RTW8852B_RXK_GROUP_NR 4 - #define ADDC_T_AVG 100 - -+enum rtw8852b_iqk_type { -+ ID_TXAGC = 0x0, -+ ID_FLOK_COARSE = 0x1, -+ ID_FLOK_FINE = 0x2, -+ ID_TXK = 0x3, -+ ID_RXAGC = 0x4, -+ ID_RXK = 0x5, -+ ID_NBTXK = 0x6, -+ ID_NBRXK = 0x7, -+ ID_FLOK_VBUFFER = 0x8, -+ ID_A_FLOK_COARSE = 0x9, -+ ID_G_FLOK_COARSE = 0xa, -+ ID_A_FLOK_FINE = 0xb, -+ ID_G_FLOK_FINE = 0xc, -+ ID_IQK_RESTORE = 0x10, -+}; -+ -+static const u32 _a_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x190, 0x198, 0x350, 0x352}; -+static const u32 _a_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x0f, 0x0f, 0x3f, 0x7f}; -+static const u32 _a_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x1, 0x0, 0x0}; -+static const u32 _g_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x212, 0x21c, 0x350, 0x360}; -+static const u32 _g_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x00, 0x00, 0x28, 0x5f}; -+static const u32 _g_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x2, 0x1}; -+static const u32 _a_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0}; -+static const u32 _a_track_range[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x6, 0x6}; -+static const u32 _a_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e}; -+static const u32 _a_itqt[RTW8852B_RXK_GROUP_NR] = {0x12, 0x12, 0x12, 0x1b}; -+static const u32 _g_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0}; -+static const u32 _g_track_range[RTW8852B_RXK_GROUP_NR] = {0x4, 0x4, 0x6, 0x6}; -+static const u32 _g_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e}; -+static const u32 _g_itqt[RTW8852B_RXK_GROUP_NR] = {0x09, 0x12, 0x1b, 0x24}; -+ -+static const u32 rtw8852b_backup_bb_regs[] = {0x2344, 0x5800, 0x7800}; -+static const u32 rtw8852b_backup_rf_regs[] = { -+ 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x1e, 0x0, 0x2, 0x5, 0x10005 -+}; -+ -+#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852b_backup_bb_regs) -+#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852b_backup_rf_regs) -+ -+static const struct rtw89_reg3_def rtw8852b_set_nondbcc_path01[] = { -+ {0x20fc, 0xffff0000, 0x0303}, -+ {0x5864, 0x18000000, 0x3}, -+ {0x7864, 0x18000000, 0x3}, -+ {0x12b8, 0x40000000, 0x1}, -+ {0x32b8, 0x40000000, 0x1}, -+ {0x030c, 0xff000000, 0x13}, -+ {0x032c, 0xffff0000, 0x0041}, -+ {0x12b8, 0x10000000, 0x1}, -+ {0x58c8, 0x01000000, 0x1}, -+ {0x78c8, 0x01000000, 0x1}, -+ {0x5864, 0xc0000000, 0x3}, -+ {0x7864, 0xc0000000, 0x3}, -+ {0x2008, 0x01ffffff, 0x1ffffff}, -+ {0x0c1c, 0x00000004, 0x1}, -+ {0x0700, 0x08000000, 0x1}, -+ {0x0c70, 0x000003ff, 0x3ff}, -+ {0x0c60, 0x00000003, 0x3}, -+ {0x0c6c, 0x00000001, 0x1}, -+ {0x58ac, 0x08000000, 0x1}, -+ {0x78ac, 0x08000000, 0x1}, -+ {0x0c3c, 0x00000200, 0x1}, -+ {0x2344, 0x80000000, 0x1}, -+ {0x4490, 0x80000000, 0x1}, -+ {0x12a0, 0x00007000, 0x7}, -+ {0x12a0, 0x00008000, 0x1}, -+ {0x12a0, 0x00070000, 0x3}, -+ {0x12a0, 0x00080000, 0x1}, -+ {0x32a0, 0x00070000, 0x3}, -+ {0x32a0, 0x00080000, 0x1}, -+ {0x0700, 0x01000000, 0x1}, -+ {0x0700, 0x06000000, 0x2}, -+ {0x20fc, 0xffff0000, 0x3333}, -+}; -+ -+static const struct rtw89_reg3_def rtw8852b_restore_nondbcc_path01[] = { -+ {0x20fc, 0xffff0000, 0x0303}, -+ {0x12b8, 0x40000000, 0x0}, -+ {0x32b8, 0x40000000, 0x0}, -+ {0x5864, 0xc0000000, 0x0}, -+ {0x7864, 0xc0000000, 0x0}, -+ {0x2008, 0x01ffffff, 0x0000000}, -+ {0x0c1c, 0x00000004, 0x0}, -+ {0x0700, 0x08000000, 0x0}, -+ {0x0c70, 0x0000001f, 0x03}, -+ {0x0c70, 0x000003e0, 0x03}, -+ {0x12a0, 0x000ff000, 0x00}, -+ {0x32a0, 0x000ff000, 0x00}, -+ {0x0700, 0x07000000, 0x0}, -+ {0x20fc, 0xffff0000, 0x0000}, -+ {0x58c8, 0x01000000, 0x0}, -+ {0x78c8, 0x01000000, 0x0}, -+ {0x0c3c, 0x00000200, 0x0}, -+ {0x2344, 0x80000000, 0x0}, -+}; -+ -+static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { -+ backup_bb_reg_val[i] = -+ rtw89_phy_read32_mask(rtwdev, rtw8852b_backup_bb_regs[i], -+ MASKDWORD); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]backup bb reg : %x, value =%x\n", -+ rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]); -+ } -+} -+ -+static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], -+ u8 rf_path) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { -+ backup_rf_reg_val[i] = -+ rtw89_read_rf(rtwdev, rf_path, -+ rtw8852b_backup_rf_regs[i], RFREG_MASK); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path, -+ rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]); -+ } -+} -+ -+static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, -+ const u32 backup_bb_reg_val[]) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { -+ rtw89_phy_write32_mask(rtwdev, rtw8852b_backup_bb_regs[i], -+ MASKDWORD, backup_bb_reg_val[i]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]restore bb reg : %x, value =%x\n", -+ rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]); -+ } -+} -+ -+static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, -+ const u32 backup_rf_reg_val[], u8 rf_path) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { -+ rtw89_write_rf(rtwdev, rf_path, rtw8852b_backup_rf_regs[i], -+ RFREG_MASK, backup_rf_reg_val[i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, -+ rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]); -+ } -+} -+ -+static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) -+{ -+ bool fail = true; -+ u32 val; -+ int ret; -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, -+ 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL1 IQK timeout!!!\n"); -+ -+ udelay(200); -+ -+ if (!ret) -+ fail = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); -+ val = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8008 = 0x%x\n", path, val); -+ -+ return fail; -+} -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - u8 val; -@@ -530,6 +711,803 @@ static void _dac_cal(struct rtw89_dev *r - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); - } - -+static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u32 tmp; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); -+ tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); -+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); -+ tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); -+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); -+ break; -+ default: -+ break; -+ } -+} -+ -+static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path, u8 ktype) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u32 iqk_cmd; -+ bool fail; -+ -+ switch (ktype) { -+ case ID_FLOK_COARSE: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ iqk_cmd = 0x108 | (1 << (4 + path)); -+ break; -+ case ID_FLOK_FINE: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ iqk_cmd = 0x208 | (1 << (4 + path)); -+ break; -+ case ID_FLOK_VBUFFER: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ iqk_cmd = 0x308 | (1 << (4 + path)); -+ break; -+ case ID_TXK: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ iqk_cmd = 0x008 | (1 << (path + 4)) | -+ (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); -+ break; -+ case ID_RXAGC: -+ iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); -+ break; -+ case ID_RXK: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ iqk_cmd = 0x008 | (1 << (path + 4)) | -+ (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); -+ break; -+ case ID_NBTXK: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011); -+ iqk_cmd = 0x308 | (1 << (4 + path)); -+ break; -+ case ID_NBRXK: -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ iqk_cmd = 0x608 | (1 << (4 + path)); -+ break; -+ default: -+ return false; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); -+ udelay(1); -+ fail = _iqk_check_cal(rtwdev, path); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ -+ return fail; -+} -+ -+static bool _rxk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool fail; -+ u8 gp; -+ -+ for (gp = 0; gp < RTW8852B_RXK_GROUP_NR; gp++) { -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, -+ _g_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, -+ _g_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, -+ _g_idxattc1[gp]); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, -+ _a_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, -+ _a_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, -+ _a_idxattc1[gp]); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_SET, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_GP_V1, gp); -+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, -+ BIT(16 + gp + path * 4), fail); -+ kfail |= fail; -+ } -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); -+ -+ if (kfail) { -+ iqk_info->nb_rxcfir[path] = 0x40000002; -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), -+ B_IQK_RES_RXCFIR, 0x0); -+ iqk_info->is_wb_rxiqk[path] = false; -+ } else { -+ iqk_info->nb_rxcfir[path] = 0x40000000; -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), -+ B_IQK_RES_RXCFIR, 0x5); -+ iqk_info->is_wb_rxiqk[path] = true; -+ } -+ -+ return kfail; -+} -+ -+static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ const u8 gp = 0x3; -+ bool kfail = false; -+ bool fail; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, -+ _g_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, -+ _g_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, -+ _g_idxattc1[gp]); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, -+ _a_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, -+ _a_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, -+ _a_idxattc1[gp]); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, gp); -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); -+ udelay(1); -+ -+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); -+ kfail |= fail; -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); -+ -+ if (!kfail) -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD) | 0x2; -+ else -+ iqk_info->nb_rxcfir[path] = 0x40000002; -+ -+ return kfail; -+} -+ -+static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ -+ if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x0); -+ } -+} -+ -+static bool _txk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool fail; -+ u8 gp; -+ -+ for (gp = 0x0; gp < RTW8852B_RXK_GROUP_NR; gp++) { -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, -+ _g_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, -+ _g_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, -+ _g_gain_bb[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, _g_itqt[gp]); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, -+ _a_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, -+ _a_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, -+ _a_gain_bb[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, _a_itqt[gp]); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_SET, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), -+ B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, -+ BIT(8 + gp + path * 4), fail); -+ kfail |= fail; -+ } -+ -+ if (kfail) { -+ iqk_info->nb_txcfir[path] = 0x40000002; -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), -+ B_IQK_RES_TXCFIR, 0x0); -+ iqk_info->is_wb_txiqk[path] = false; -+ } else { -+ iqk_info->nb_txcfir[path] = 0x40000000; -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), -+ B_IQK_RES_TXCFIR, 0x5); -+ iqk_info->is_wb_txiqk[path] = true; -+ } -+ -+ return kfail; -+} -+ -+static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail; -+ u8 gp = 0x3; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, -+ _g_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, -+ _g_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, -+ _g_gain_bb[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, _g_itqt[gp]); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, -+ _a_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, -+ _a_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, -+ _a_gain_bb[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, _a_itqt[gp]); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ kfail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); -+ -+ if (!kfail) -+ iqk_info->nb_txcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD) | 0x2; -+ else -+ iqk_info->nb_txcfir[path] = 0x40000002; -+ -+ return kfail; -+} -+ -+static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); -+ else -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXVBUF, RR_TXVBUF_DACEN, 0x1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x7c = %x\n", path, -+ rtw89_read_rf(rtwdev, path, RR_TXVBUF, RFREG_MASK)); -+} -+ -+static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool is_fail1, is_fail2; -+ u32 vbuff_i; -+ u32 vbuff_q; -+ u32 core_i; -+ u32 core_q; -+ u32 tmp; -+ u8 ch; -+ -+ tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); -+ core_i = FIELD_GET(RR_TXMO_COI, tmp); -+ core_q = FIELD_GET(RR_TXMO_COQ, tmp); -+ ch = (iqk_info->iqk_times / 2) % RTW89_IQK_CHS_NR; -+ -+ if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) -+ is_fail1 = true; -+ else -+ is_fail1 = false; -+ -+ iqk_info->lok_idac[ch][path] = tmp; -+ -+ tmp = rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK); -+ vbuff_i = FIELD_GET(RR_LOKVB_COI, tmp); -+ vbuff_q = FIELD_GET(RR_LOKVB_COQ, tmp); -+ -+ if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d) -+ is_fail2 = true; -+ else -+ is_fail2 = false; -+ -+ iqk_info->lok_vbuf[ch][path] = tmp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, lok_idac[%x][%x] = 0x%x\n", path, ch, path, -+ iqk_info->lok_idac[ch][path]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, lok_vbuf[%x][%x] = 0x%x\n", path, ch, path, -+ iqk_info->lok_vbuf[ch][path]); -+ -+ return is_fail1 | is_fail2; -+} -+ -+static bool _iqk_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool tmp; -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x4); -+ break; -+ default: -+ break; -+ } -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9); -+ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE); -+ iqk_info->lok_cor_fail[0][path] = tmp; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24); -+ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); -+ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE); -+ iqk_info->lok_fin_fail[0][path] = tmp; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12); -+ break; -+ default: -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24); -+ _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER); -+ -+ return _lok_finetune_check(rtwdev, path); -+} -+ -+static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW2, 0x00); -+ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x00); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); -+ udelay(1); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); -+ rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x80); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e); -+ udelay(1); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); -+} -+ -+static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u32 tmp; -+ bool flag; -+ -+ iqk_info->thermal[path] = -+ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -+ iqk_info->thermal_rek_en = false; -+ -+ flag = iqk_info->lok_cor_fail[0][path]; -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag); -+ flag = iqk_info->lok_fin_fail[0][path]; -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), flag); -+ flag = iqk_info->iqk_tx_fail[0][path]; -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), flag); -+ flag = iqk_info->iqk_rx_fail[0][path]; -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), flag); -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); -+ iqk_info->bp_iqkenable[path] = tmp; -+ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); -+ iqk_info->bp_txkresult[path] = tmp; -+ tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); -+ iqk_info->bp_rxkresult[path] = tmp; -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, iqk_info->iqk_times); -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4)); -+ if (tmp) -+ iqk_info->iqk_fail_cnt++; -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4), -+ iqk_info->iqk_fail_cnt); -+} -+ -+static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool lok_is_fail = false; -+ const int try = 3; -+ u8 ibias = 0x1; -+ u8 i; -+ -+ _iqk_txclk_setting(rtwdev, path); -+ -+ /* LOK */ -+ for (i = 0; i < try; i++) { -+ _lok_res_table(rtwdev, path, ibias++); -+ _iqk_txk_setting(rtwdev, path); -+ lok_is_fail = _iqk_lok(rtwdev, phy_idx, path); -+ if (!lok_is_fail) -+ break; -+ } -+ -+ if (lok_is_fail) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] LOK (%d) fail\n", path); -+ -+ /* TXK */ -+ if (iqk_info->is_nbiqk) -+ iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); -+ -+ /* RX */ -+ _iqk_rxclk_setting(rtwdev, path); -+ _iqk_rxk_setting(rtwdev, path); -+ if (iqk_info->is_nbiqk) -+ iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); -+ -+ _iqk_info_iqk(rtwdev, phy_idx, path); -+} -+ -+static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u32 reg_rf18; -+ u32 reg_35c; -+ u8 idx; -+ u8 get_empty_table = false; -+ -+ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { -+ if (iqk_info->iqk_mcc_ch[idx][path] == 0) { -+ get_empty_table = true; -+ break; -+ } -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx); -+ -+ if (!get_empty_table) { -+ idx = iqk_info->iqk_table_idx[path] + 1; -+ if (idx > 1) -+ idx = 0; -+ } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx); -+ -+ reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); -+ reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN); -+ -+ iqk_info->iqk_band[path] = chan->band_type; -+ iqk_info->iqk_bw[path] = chan->band_width; -+ iqk_info->iqk_ch[path] = chan->channel; -+ iqk_info->iqk_mcc_ch[idx][path] = chan->channel; -+ iqk_info->iqk_table_idx[path] = idx; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x, idx = %x\n", -+ path, reg_rf18, idx); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x\n", -+ path, reg_rf18); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", -+ iqk_info->iqk_times, idx); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n", -+ idx, path, iqk_info->iqk_mcc_ch[idx][path]); -+ -+ if (reg_35c == 0x01) -+ iqk_info->syn1to2 = 0x1; -+ else -+ iqk_info->syn1to2 = 0x0; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", path, -+ iqk_info->syn1to2); -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852B_IQK_VER); -+ /* 2GHz/5GHz/6GHz = 0/1/2 */ -+ rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16), -+ iqk_info->iqk_band[path]); -+ /* 20/40/80 = 0/1/2 */ -+ rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16), -+ iqk_info->iqk_bw[path]); -+ rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16), -+ iqk_info->iqk_ch[path]); -+} -+ -+static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ _iqk_by_path(rtwdev, phy_idx, path); -+} -+ -+static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool fail; -+ -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, -+ iqk_info->nb_txcfir[path]); -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, -+ iqk_info->nb_rxcfir[path]); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, -+ 0x00000e19 + (path << 4)); -+ fail = _iqk_check_cal(rtwdev, path); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s result =%x\n", __func__, fail); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS, B_IQK_RES_K, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0x3); -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); -+} -+ -+static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ const struct rtw89_reg3_def *def; -+ int size; -+ u8 kpath; -+ int i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__); -+ -+ kpath = _kpath(rtwdev, phy_idx); -+ -+ switch (kpath) { -+ case RF_A: -+ case RF_B: -+ return; -+ default: -+ size = ARRAY_SIZE(rtw8852b_restore_nondbcc_path01); -+ def = rtw8852b_restore_nondbcc_path01; -+ break; -+ } -+ -+ for (i = 0; i < size; i++, def++) -+ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); -+} -+ -+static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u8 idx; -+ -+ idx = iqk_info->iqk_table_idx[path]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (3)idx = %x\n", idx); -+ -+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x54 = 0x%x\n", path, 1 << path, -+ rtw89_phy_read32_mask(rtwdev, R_CFIR_LUT + (path << 8), MASKDWORD)); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x04 = 0x%x\n", path, 1 << path, -+ rtw89_phy_read32_mask(rtwdev, R_COEF_SEL + (path << 8), MASKDWORD)); -+} -+ -+static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ const struct rtw89_reg3_def *def; -+ int size; -+ u8 kpath; -+ int i; -+ -+ kpath = _kpath(rtwdev, phy_idx); -+ -+ switch (kpath) { -+ case RF_A: -+ case RF_B: -+ return; -+ default: -+ size = ARRAY_SIZE(rtw8852b_set_nondbcc_path01); -+ def = rtw8852b_set_nondbcc_path01; -+ break; -+ } -+ -+ for (i = 0; i < size; i++, def++) -+ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); -+} -+ -+static void _iqk_init(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u8 idx, path; -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0); -+ if (iqk_info->is_iqk_init) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ iqk_info->is_iqk_init = true; -+ iqk_info->is_nbiqk = false; -+ iqk_info->iqk_fft_en = false; -+ iqk_info->iqk_sram_en = false; -+ iqk_info->iqk_cfir_en = false; -+ iqk_info->iqk_xym_en = false; -+ iqk_info->thermal_rek_en = false; -+ iqk_info->iqk_times = 0x0; -+ -+ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { -+ iqk_info->iqk_channel[idx] = 0x0; -+ for (path = 0; path < RTW8852B_IQK_SS; path++) { -+ iqk_info->lok_cor_fail[idx][path] = false; -+ iqk_info->lok_fin_fail[idx][path] = false; -+ iqk_info->iqk_tx_fail[idx][path] = false; -+ iqk_info->iqk_rx_fail[idx][path] = false; -+ iqk_info->iqk_mcc_ch[idx][path] = 0x0; -+ iqk_info->iqk_table_idx[path] = 0x0; -+ } -+ } -+} -+ - static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) - { - u32 rf_mode; -@@ -548,6 +1526,58 @@ static void _wait_rx_mode(struct rtw89_d - } - } - -+static void _doiqk(struct rtw89_dev *rtwdev, bool force, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u32 backup_bb_val[BACKUP_BB_REGS_NR]; -+ u32 backup_rf_val[RTW8852B_IQK_SS][BACKUP_RF_REGS_NR]; -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]==========IQK strat!!!!!==========\n"); -+ iqk_info->iqk_times++; -+ iqk_info->kcount = 0; -+ iqk_info->version = RTW8852B_IQK_VER; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); -+ _iqk_get_ch_info(rtwdev, phy_idx, path); -+ -+ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); -+ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ _iqk_macbb_setting(rtwdev, phy_idx, path); -+ _iqk_preset(rtwdev, path); -+ _iqk_start_iqk(rtwdev, phy_idx, path); -+ _iqk_restore(rtwdev, path); -+ _iqk_afebb_restore(rtwdev, phy_idx, path); -+ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); -+ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); -+} -+ -+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) -+{ -+ u8 kpath = _kpath(rtwdev, phy_idx); -+ -+ switch (kpath) { -+ case RF_A: -+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); -+ break; -+ case RF_B: -+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); -+ break; -+ case RF_AB: -+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); -+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); -+ break; -+ default: -+ break; -+ } -+} -+ - void rtw8852b_rck(struct rtw89_dev *rtwdev) - { - u8 path; -@@ -565,6 +1595,22 @@ void rtw8852b_dack(struct rtw89_dev *rtw - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); - } - -+void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ _iqk_init(rtwdev); -+ _iqk(rtwdev, phy_idx, false); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); -+} -+ - void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -9,6 +9,7 @@ - - void rtw8852b_rck(struct rtw89_dev *rtwdev); - void rtw8852b_dack(struct rtw89_dev *rtwdev); -+void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-039-wifi-rtw89-8852b-rfk-add-TSSI.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-039-wifi-rtw89-8852b-rfk-add-TSSI.patch deleted file mode 100644 index 8282c4099..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-039-wifi-rtw89-8852b-rfk-add-TSSI.patch +++ /dev/null @@ -1,1407 +0,0 @@ -From 7f18a70d7b4d2a0e54ce542c222aeffc464ed9f3 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Oct 2022 16:32:34 +0800 -Subject: [PATCH 039/149] wifi: rtw89: 8852b: rfk: add TSSI - -TSSI is transmitter signal strength indication, which is a close-loop -hardware circuit to feedback actual transmitting power as a reference for -next transmission. - -When we setup channel to connect an AP, it does full calibration. When -switching bands or channels, it needs to reset hardware status to prevent -use wrong feedback of previous transmission. - -To do TX power compensation reflecting current temperature, it loads tables -of compensation values into registers according to channel and band group. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221012083234.20224-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 15 + - drivers/net/wireless/realtek/rtw89/reg.h | 43 + - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1174 +++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 4 + - 4 files changed, 1236 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3164,6 +3164,14 @@ struct rtw89_cfo_tracking_info { - u8 lock_cnt; - }; - -+enum rtw89_tssi_alimk_band { -+ TSSI_ALIMK_2G = 0, -+ TSSI_ALIMK_5GL, -+ TSSI_ALIMK_5GM, -+ TSSI_ALIMK_5GH, -+ TSSI_ALIMK_MAX -+}; -+ - /* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ - #define TSSI_TRIM_CH_GROUP_NUM 8 - #define TSSI_TRIM_CH_GROUP_NUM_6G 16 -@@ -3174,6 +3182,8 @@ struct rtw89_cfo_tracking_info { - #define TSSI_MCS_6G_CH_GROUP_NUM 32 - #define TSSI_MCS_CH_GROUP_NUM \ - (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM) -+#define TSSI_MAX_CH_NUM 67 -+#define TSSI_ALIMK_VALUE_NUM 8 - - struct rtw89_tssi_info { - u8 thermal[RF_PATH_MAX]; -@@ -3186,6 +3196,11 @@ struct rtw89_tssi_info { - bool tssi_tracking_check[RF_PATH_MAX]; - u8 default_txagc_offset[RF_PATH_MAX]; - u32 base_thermal[RF_PATH_MAX]; -+ bool check_backup_aligmk[RF_PATH_MAX][TSSI_MAX_CH_NUM]; -+ u32 alignment_backup_by_ch[RF_PATH_MAX][TSSI_MAX_CH_NUM][TSSI_ALIMK_VALUE_NUM]; -+ u32 alignment_value[RF_PATH_MAX][TSSI_ALIMK_MAX][TSSI_ALIMK_VALUE_NUM]; -+ bool alignment_done[RF_PATH_MAX][TSSI_ALIMK_MAX]; -+ u32 tssi_alimk_time; - }; - - struct rtw89_power_trim_info { ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3389,6 +3389,8 @@ - #define RR_TXGA_TRK_EN BIT(7) - #define RR_TXGA_LOK_EXT GENMASK(4, 0) - #define RR_TXGA_LOK_EN BIT(0) -+#define RR_TXGA_V1 0x10055 -+#define RR_TXGA_V1_TRK_EN BIT(7) - #define RR_GAINTX 0x56 - #define RR_GAINTX_ALL GENMASK(15, 0) - #define RR_GAINTX_PAD GENMASK(9, 5) -@@ -3732,6 +3734,9 @@ - #define B_TXAGC_TP GENMASK(2, 0) - #define R_TSSI_THER 0x1C10 - #define B_TSSI_THER GENMASK(29, 24) -+#define R_TSSI_CWRPT 0x1C18 -+#define B_TSSI_CWRPT_RDY BIT(16) -+#define B_TSSI_CWRPT GENMASK(8, 0) - #define R_TXAGC_BTP 0x1CA0 - #define B_TXAGC_BTP GENMASK(31, 24) - #define R_TXAGC_BB 0x1C60 -@@ -4094,6 +4099,20 @@ - #define B_CFO_COMP_VALID_BIT BIT(29) - #define B_CFO_COMP_WEIGHT_MSK GENMASK(27, 24) - #define B_CFO_COMP_VAL_MSK GENMASK(11, 0) -+#define R_TSSI_PA_K1 0x5600 -+#define R_TSSI_PA_K2 0x5604 -+#define R_P0_TSSI_ALIM1 0x5630 -+#define B_P0_TSSI_ALIM1 GENMASK(29, 0) -+#define B_P0_TSSI_ALIM11 GENMASK(29, 20) -+#define B_P0_TSSI_ALIM12 GENMASK(19, 10) -+#define B_P0_TSSI_ALIM13 GENMASK(9, 0) -+#define R_P0_TSSI_ALIM3 0x5634 -+#define B_P0_TSSI_ALIM31 GENMASK(9, 0) -+#define R_TSSI_PA_K5 0x5638 -+#define R_P0_TSSI_ALIM2 0x563c -+#define B_P0_TSSI_ALIM2 GENMASK(29, 0) -+#define R_P0_TSSI_ALIM4 0x5640 -+#define R_TSSI_PA_K8 0x5644 - #define R_UPD_CLK 0x5670 - #define B_DAC_VAL BIT(31) - #define B_ACK_VAL GENMASK(30, 29) -@@ -4108,6 +4127,8 @@ - #define B_DPD_TSSI_CW GENMASK(26, 18) - #define B_DPD_PWR_CW GENMASK(17, 9) - #define B_DPD_REF GENMASK(8, 0) -+#define R_P0_TSSIC 0x5814 -+#define B_P0_TSSIC_BYPASS BIT(11) - #define R_DPD_OFT_ADDR 0x5804 - #define B_DPD_OFT_ADDR GENMASK(31, 27) - #define R_TXPWRB_H 0x580c -@@ -4116,11 +4137,15 @@ - #define B_P0_TMETER GENMASK(15, 10) - #define B_P0_TMETER_DIS BIT(16) - #define B_P0_TMETER_TRK BIT(24) -+#define R_P1_TSSIC 0x7814 -+#define B_P1_TSSIC_BYPASS BIT(11) - #define R_P0_TSSI_TRK 0x5818 - #define B_P0_TSSI_TRK_EN BIT(30) -+#define B_P0_TSSI_RFC GENMASK(28, 27) - #define B_P0_TSSI_OFT_EN BIT(28) - #define B_P0_TSSI_OFT GENMASK(7, 0) - #define R_P0_TSSI_AVG 0x5820 -+#define B_P0_TSSI_EN BIT(31) - #define B_P0_TSSI_AVG GENMASK(15, 12) - #define R_P0_RFCTM 0x5864 - #define B_P0_RFCTM_EN BIT(29) -@@ -4143,7 +4168,9 @@ - #define B_P0_TXPW_RSTB_MANON BIT(30) - #define B_P0_TXPW_RSTB_TSSI BIT(31) - #define R_P0_TSSI_MV_AVG 0x58E4 -+#define B_P0_TSSI_MV_MIX GENMASK(19, 11) - #define B_P0_TSSI_MV_AVG GENMASK(13, 11) -+#define B_P0_TSSI_MV_CLR BIT(14) - #define R_TXGAIN_SCALE 0x58F0 - #define B_TXGAIN_SCALE_EN BIT(19) - #define B_TXGAIN_SCALE_OFT GENMASK(31, 24) -@@ -4168,25 +4195,41 @@ - #define B_S0_DACKQ8_K GENMASK(15, 8) - #define R_RPL_BIAS_COMP1 0x6DF0 - #define B_RPL_BIAS_COMP1_MASK GENMASK(7, 0) -+#define R_P1_TSSI_ALIM1 0x7630 -+#define B_P1_TSSI_ALIM1 GENMASK(29, 0) -+#define B_P1_TSSI_ALIM11 GENMASK(29, 20) -+#define B_P1_TSSI_ALIM12 GENMASK(19, 10) -+#define B_P1_TSSI_ALIM13 GENMASK(9, 0) -+#define R_P1_TSSI_ALIM3 0x7634 -+#define B_P1_TSSI_ALIM31 GENMASK(9, 0) -+#define R_P1_TSSI_ALIM2 0x763c -+#define B_P1_TSSI_ALIM2 GENMASK(29, 0) -+#define R_P1_TSSIC 0x7814 -+#define B_P1_TSSIC_BYPASS BIT(11) - #define R_P1_TMETER 0x7810 - #define B_P1_TMETER GENMASK(15, 10) - #define B_P1_TMETER_DIS BIT(16) - #define B_P1_TMETER_TRK BIT(24) - #define R_P1_TSSI_TRK 0x7818 - #define B_P1_TSSI_TRK_EN BIT(30) -+#define B_P1_TSSI_RFC GENMASK(28, 27) - #define B_P1_TSSI_OFT_EN BIT(28) - #define B_P1_TSSI_OFT GENMASK(7, 0) - #define R_P1_TSSI_AVG 0x7820 -+#define B_P1_TSSI_EN BIT(31) - #define B_P1_TSSI_AVG GENMASK(15, 12) - #define R_P1_RFCTM 0x7864 - #define R_P1_RFCTM_RDY BIT(26) - #define B_P1_RFCTM_VAL GENMASK(25, 20) -+#define B_P1_RFCTM_DEL GENMASK(19, 11) - #define R_P1_PATH_RST 0x78AC - #define R_P1_TXPW_RSTB 0x78DC - #define B_P1_TXPW_RSTB_MANON BIT(30) - #define B_P1_TXPW_RSTB_TSSI BIT(31) - #define R_P1_TSSI_MV_AVG 0x78E4 -+#define B_P1_TSSI_MV_MIX GENMASK(19, 11) - #define B_P1_TSSI_MV_AVG GENMASK(13, 11) -+#define B_P1_TSSI_MV_CLR BIT(14) - #define R_TSSI_THOF 0x7C00 - #define R_S1_DACKI 0x7E00 - #define B_S1_DACKI_AR GENMASK(31, 28) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -16,6 +16,9 @@ - #define RTW8852B_IQK_VER 0x2a - #define RTW8852B_IQK_SS 2 - #define RTW8852B_RXK_GROUP_NR 4 -+#define RTW8852B_TSSI_PATH_NR 2 -+ -+#define _TSSI_DE_MASK GENMASK(21, 12) - #define ADDC_T_AVG 100 - - enum rtw8852b_iqk_type { -@@ -35,6 +38,21 @@ enum rtw8852b_iqk_type { - ID_IQK_RESTORE = 0x10, - }; - -+static const u32 _tssi_trigger[RTW8852B_TSSI_PATH_NR] = {0x5820, 0x7820}; -+static const u32 _tssi_cw_rpt_addr[RTW8852B_TSSI_PATH_NR] = {0x1c18, 0x3c18}; -+static const u32 _tssi_cw_default_addr[RTW8852B_TSSI_PATH_NR][4] = { -+ {0x5634, 0x5630, 0x5630, 0x5630}, -+ {0x7634, 0x7630, 0x7630, 0x7630} }; -+static const u32 _tssi_cw_default_mask[4] = { -+ 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff}; -+static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852B] = {0x5858, 0x7858}; -+static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852B] = {0x5860, 0x7860}; -+static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852B] = {0x5838, 0x7838}; -+static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852B] = {0x5840, 0x7840}; -+static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852B] = {0x5848, 0x7848}; -+static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852B] = {0x5850, 0x7850}; -+static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852B] = {0x5828, 0x7828}; -+static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852B] = {0x5830, 0x7830}; - static const u32 _a_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x190, 0x198, 0x350, 0x352}; - static const u32 _a_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x0f, 0x0f, 0x3f, 0x7f}; - static const u32 _a_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x1, 0x0, 0x0}; -@@ -1526,6 +1544,15 @@ static void _wait_rx_mode(struct rtw89_d - } - } - -+static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx, -+ bool is_pause) -+{ -+ if (!is_pause) -+ return; -+ -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, band_idx)); -+} -+ - static void _doiqk(struct rtw89_dev *rtwdev, bool force, - enum rtw89_phy_idx phy_idx, u8 path) - { -@@ -1578,6 +1605,1027 @@ static void _iqk(struct rtw89_dev *rtwde - } - } - -+static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ if (band == RTW89_BAND_2G) -+ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); -+ else -+ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); -+} -+ -+static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_tssi_sys_defs_tbl); -+ -+ if (path == RF_PATH_A) -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8852b_tssi_sys_a_defs_2g_tbl, -+ &rtw8852b_tssi_sys_a_defs_5g_tbl); -+ else -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8852b_tssi_sys_b_defs_2g_tbl, -+ &rtw8852b_tssi_sys_b_defs_5g_tbl); -+} -+ -+static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_tssi_init_txpwr_defs_a_tbl, -+ &rtw8852b_tssi_init_txpwr_defs_b_tbl); -+} -+ -+static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl, -+ &rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl); -+} -+ -+static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_tssi_dck_defs_a_tbl, -+ &rtw8852b_tssi_dck_defs_b_tbl); -+} -+ -+static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+#define RTW8852B_TSSI_GET_VAL(ptr, idx) \ -+({ \ -+ s8 *__ptr = (ptr); \ -+ u8 __idx = (idx), __i, __v; \ -+ u32 __val = 0; \ -+ for (__i = 0; __i < 4; __i++) { \ -+ __v = (__ptr[__idx + __i]); \ -+ __val |= (__v << (8 * __i)); \ -+ } \ -+ __val; \ -+}) -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u8 subband = chan->subband_type; -+ const s8 *thm_up_a = NULL; -+ const s8 *thm_down_a = NULL; -+ const s8 *thm_up_b = NULL; -+ const s8 *thm_down_b = NULL; -+ u8 thermal = 0xff; -+ s8 thm_ofst[64] = {0}; -+ u32 tmp = 0; -+ u8 i, j; -+ -+ switch (subband) { -+ default: -+ case RTW89_CH_2G: -+ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_p; -+ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_n; -+ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_p; -+ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_n; -+ break; -+ case RTW89_CH_5G_BAND_1: -+ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[0]; -+ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[0]; -+ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[0]; -+ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[0]; -+ break; -+ case RTW89_CH_5G_BAND_3: -+ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[1]; -+ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[1]; -+ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[1]; -+ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[1]; -+ break; -+ case RTW89_CH_5G_BAND_4: -+ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[2]; -+ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[2]; -+ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[2]; -+ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[2]; -+ break; -+ } -+ -+ if (path == RF_PATH_A) { -+ thermal = tssi_info->thermal[RF_PATH_A]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); -+ -+ if (thermal == 0xff) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); -+ -+ for (i = 0; i < 64; i += 4) { -+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ R_P0_TSSI_BASE + i, 0x0); -+ } -+ -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, -+ thermal); -+ -+ i = 0; -+ for (j = 0; j < 32; j++) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ -thm_down_a[i++] : -+ -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; -+ -+ i = 1; -+ for (j = 63; j >= 32; j--) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ thm_up_a[i++] : -+ thm_up_a[DELTA_SWINGIDX_SIZE - 1]; -+ -+ for (i = 0; i < 64; i += 4) { -+ tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i); -+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ 0x5c00 + i, tmp); -+ } -+ } -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); -+ -+ } else { -+ thermal = tssi_info->thermal[RF_PATH_B]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); -+ -+ if (thermal == 0xff) { -+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); -+ -+ for (i = 0; i < 64; i += 4) { -+ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ 0x7c00 + i, 0x0); -+ } -+ -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, -+ thermal); -+ -+ i = 0; -+ for (j = 0; j < 32; j++) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ -thm_down_b[i++] : -+ -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; -+ -+ i = 1; -+ for (j = 63; j >= 32; j--) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ thm_up_b[i++] : -+ thm_up_b[DELTA_SWINGIDX_SIZE - 1]; -+ -+ for (i = 0; i < 64; i += 4) { -+ tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i); -+ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ 0x7c00 + i, tmp); -+ } -+ } -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); -+ } -+#undef RTW8852B_TSSI_GET_VAL -+} -+ -+static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_tssi_dac_gain_defs_a_tbl, -+ &rtw8852b_tssi_dac_gain_defs_b_tbl); -+} -+ -+static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ if (path == RF_PATH_A) -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8852b_tssi_slope_a_defs_2g_tbl, -+ &rtw8852b_tssi_slope_a_defs_5g_tbl); -+ else -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8852b_tssi_slope_b_defs_2g_tbl, -+ &rtw8852b_tssi_slope_b_defs_5g_tbl); -+} -+ -+static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, bool all) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ const struct rtw89_rfk_tbl *tbl = NULL; -+ u8 ch = chan->channel; -+ -+ if (path == RF_PATH_A) { -+ if (band == RTW89_BAND_2G) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_a_2g_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_a_2g_part_defs_tbl; -+ } else if (ch >= 36 && ch <= 64) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_a_5g1_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_a_5g1_part_defs_tbl; -+ } else if (ch >= 100 && ch <= 144) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_a_5g2_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_a_5g2_part_defs_tbl; -+ } else if (ch >= 149 && ch <= 177) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_a_5g3_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_a_5g3_part_defs_tbl; -+ } -+ } else { -+ if (ch >= 1 && ch <= 14) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_b_2g_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_b_2g_part_defs_tbl; -+ } else if (ch >= 36 && ch <= 64) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_b_5g1_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_b_5g1_part_defs_tbl; -+ } else if (ch >= 100 && ch <= 144) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_b_5g2_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_b_5g2_part_defs_tbl; -+ } else if (ch >= 149 && ch <= 177) { -+ if (all) -+ tbl = &rtw8852b_tssi_align_b_5g3_all_defs_tbl; -+ else -+ tbl = &rtw8852b_tssi_align_b_5g3_part_defs_tbl; -+ } -+ } -+ -+ if (tbl) -+ rtw89_rfk_parser(rtwdev, tbl); -+} -+ -+static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, -+ &rtw8852b_tssi_slope_defs_a_tbl, -+ &rtw8852b_tssi_slope_defs_b_tbl); -+} -+ -+static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ if (path == RF_PATH_A) -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, 0x0); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, 0x0); -+} -+ -+static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "======>%s path=%d\n", __func__, -+ path); -+ -+ if (path == RF_PATH_A) -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_MIX, 0x010); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_RFCTM_DEL, 0x010); -+} -+ -+static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8852B; i++) { -+ _tssi_set_tssi_track(rtwdev, phy, i); -+ _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); -+ -+ if (i == RF_PATH_A) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, -+ B_P0_TSSI_MV_CLR, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, -+ B_P0_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, -+ B_P0_TSSI_EN, 0x1); -+ rtw89_write_rf(rtwdev, i, RR_TXGA_V1, -+ RR_TXGA_V1_TRK_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, -+ B_P0_TSSI_RFC, 0x3); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, -+ B_P0_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, -+ B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, -+ B_P0_TSSI_OFT_EN, 0x1); -+ -+ rtwdev->is_tssi_mode[RF_PATH_A] = true; -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, -+ B_P1_TSSI_MV_CLR, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, -+ B_P1_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, -+ B_P1_TSSI_EN, 0x1); -+ rtw89_write_rf(rtwdev, i, RR_TXGA_V1, -+ RR_TXGA_V1_TRK_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, -+ B_P1_TSSI_RFC, 0x3); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, -+ B_P1_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, -+ B_P1_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, -+ B_P1_TSSI_OFT_EN, 0x1); -+ -+ rtwdev->is_tssi_mode[RF_PATH_B] = true; -+ } -+ } -+} -+ -+static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, 0x1); -+ -+ rtwdev->is_tssi_mode[RF_PATH_A] = false; -+ rtwdev->is_tssi_mode[RF_PATH_B] = false; -+} -+ -+static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 2: -+ return 0; -+ case 3 ... 5: -+ return 1; -+ case 6 ... 8: -+ return 2; -+ case 9 ... 11: -+ return 3; -+ case 12 ... 13: -+ return 4; -+ case 14: -+ return 5; -+ } -+ -+ return 0; -+} -+ -+#define TSSI_EXTRA_GROUP_BIT (BIT(31)) -+#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) -+#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) -+#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) -+#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) -+ -+static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 2: -+ return 0; -+ case 3 ... 5: -+ return 1; -+ case 6 ... 8: -+ return 2; -+ case 9 ... 11: -+ return 3; -+ case 12 ... 14: -+ return 4; -+ case 36 ... 40: -+ return 5; -+ case 41 ... 43: -+ return TSSI_EXTRA_GROUP(5); -+ case 44 ... 48: -+ return 6; -+ case 49 ... 51: -+ return TSSI_EXTRA_GROUP(6); -+ case 52 ... 56: -+ return 7; -+ case 57 ... 59: -+ return TSSI_EXTRA_GROUP(7); -+ case 60 ... 64: -+ return 8; -+ case 100 ... 104: -+ return 9; -+ case 105 ... 107: -+ return TSSI_EXTRA_GROUP(9); -+ case 108 ... 112: -+ return 10; -+ case 113 ... 115: -+ return TSSI_EXTRA_GROUP(10); -+ case 116 ... 120: -+ return 11; -+ case 121 ... 123: -+ return TSSI_EXTRA_GROUP(11); -+ case 124 ... 128: -+ return 12; -+ case 129 ... 131: -+ return TSSI_EXTRA_GROUP(12); -+ case 132 ... 136: -+ return 13; -+ case 137 ... 139: -+ return TSSI_EXTRA_GROUP(13); -+ case 140 ... 144: -+ return 14; -+ case 149 ... 153: -+ return 15; -+ case 154 ... 156: -+ return TSSI_EXTRA_GROUP(15); -+ case 157 ... 161: -+ return 16; -+ case 162 ... 164: -+ return TSSI_EXTRA_GROUP(16); -+ case 165 ... 169: -+ return 17; -+ case 170 ... 172: -+ return TSSI_EXTRA_GROUP(17); -+ case 173 ... 177: -+ return 18; -+ } -+ -+ return 0; -+} -+ -+static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 8: -+ return 0; -+ case 9 ... 14: -+ return 1; -+ case 36 ... 48: -+ return 2; -+ case 52 ... 64: -+ return 3; -+ case 100 ... 112: -+ return 4; -+ case 116 ... 128: -+ return 5; -+ case 132 ... 144: -+ return 6; -+ case 149 ... 177: -+ return 7; -+ } -+ -+ return 0; -+} -+ -+static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u32 gidx, gidx_1st, gidx_2nd; -+ s8 de_1st; -+ s8 de_2nd; -+ s8 val; -+ -+ gidx = _tssi_get_ofdm_group(rtwdev, ch); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); -+ -+ if (IS_TSSI_EXTRA_GROUP(gidx)) { -+ gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); -+ gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); -+ de_1st = tssi_info->tssi_mcs[path][gidx_1st]; -+ de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; -+ val = (de_1st + de_2nd) / 2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", -+ path, val, de_1st, de_2nd); -+ } else { -+ val = tssi_info->tssi_mcs[path][gidx]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); -+ } -+ -+ return val; -+} -+ -+static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u32 tgidx, tgidx_1st, tgidx_2nd; -+ s8 tde_1st; -+ s8 tde_2nd; -+ s8 val; -+ -+ tgidx = _tssi_get_trim_group(rtwdev, ch); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", -+ path, tgidx); -+ -+ if (IS_TSSI_EXTRA_GROUP(tgidx)) { -+ tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); -+ tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); -+ tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; -+ tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; -+ val = (tde_1st + tde_2nd) / 2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", -+ path, val, tde_1st, tde_2nd); -+ } else { -+ val = tssi_info->tssi_trim[path][tgidx]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", -+ path, val); -+ } -+ -+ return val; -+} -+ -+static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u8 gidx; -+ s8 ofdm_de; -+ s8 trim_de; -+ s32 val; -+ u32 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", -+ phy, ch); -+ -+ for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) { -+ gidx = _tssi_get_cck_group(rtwdev, ch); -+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); -+ val = tssi_info->tssi_cck[i][gidx] + trim_de; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", -+ i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); -+ -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", -+ _tssi_de_cck_long[i], -+ rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], -+ _TSSI_DE_MASK)); -+ -+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i); -+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); -+ val = ofdm_de + trim_de; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", -+ i, ofdm_de, trim_de); -+ -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", -+ _tssi_de_mcs_20m[i], -+ rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], -+ _TSSI_DE_MASK)); -+ } -+} -+ -+static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" -+ "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", -+ R_TSSI_PA_K1 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K2 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM1 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM3 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K5 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM2 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM4 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K8 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD)); -+} -+ -+static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 channel = chan->channel; -+ u8 band; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s phy=%d path=%d\n", __func__, phy, path); -+ -+ if (channel >= 1 && channel <= 14) -+ band = TSSI_ALIMK_2G; -+ else if (channel >= 36 && channel <= 64) -+ band = TSSI_ALIMK_5GL; -+ else if (channel >= 100 && channel <= 144) -+ band = TSSI_ALIMK_5GM; -+ else if (channel >= 149 && channel <= 177) -+ band = TSSI_ALIMK_5GH; -+ else -+ band = TSSI_ALIMK_2G; -+ -+ if (tssi_info->alignment_done[path][band]) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][0]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][1]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][2]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][3]); -+ } -+ -+ _tssi_alimentk_dump_result(rtwdev, path); -+} -+ -+static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm, -+ u8 enable) -+{ -+ enum rtw89_rf_path_bit rx_path; -+ -+ if (path == RF_PATH_A) -+ rx_path = RF_A; -+ else if (path == RF_PATH_B) -+ rx_path = RF_B; -+ else if (path == RF_PATH_AB) -+ rx_path = RF_AB; -+ else -+ rx_path = RF_ABCD; /* don't change path, but still set others */ -+ -+ if (enable) { -+ rtw8852b_bb_set_plcp_tx(rtwdev); -+ rtw8852b_bb_cfg_tx_path(rtwdev, path); -+ rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path); -+ rtw8852b_bb_set_power(rtwdev, pwr_dbm, phy); -+ } -+ -+ rtw8852b_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy); -+} -+ -+static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, const u32 reg[], -+ u32 reg_backup[], u32 reg_num) -+{ -+ u32 i; -+ -+ for (i = 0; i < reg_num; i++) { -+ reg_backup[i] = rtw89_phy_read32_mask(rtwdev, reg[i], MASKDWORD); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i], -+ reg_backup[i]); -+ } -+} -+ -+static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, const u32 reg[], -+ u32 reg_backup[], u32 reg_num) -+ -+{ -+ u32 i; -+ -+ for (i = 0; i < reg_num; i++) { -+ rtw89_phy_write32_mask(rtwdev, reg[i], MASKDWORD, reg_backup[i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i], -+ reg_backup[i]); -+ } -+} -+ -+static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel) -+{ -+ u8 channel_index; -+ -+ if (channel >= 1 && channel <= 14) -+ channel_index = channel - 1; -+ else if (channel >= 36 && channel <= 64) -+ channel_index = (channel - 36) / 2 + 14; -+ else if (channel >= 100 && channel <= 144) -+ channel_index = ((channel - 100) / 2) + 15 + 14; -+ else if (channel >= 149 && channel <= 177) -+ channel_index = ((channel - 149) / 2) + 38 + 14; -+ else -+ channel_index = 0; -+ -+ return channel_index; -+} -+ -+static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, const s16 *power, -+ u32 *tssi_cw_rpt) -+{ -+ u32 tx_counter, tx_counter_tmp; -+ const int retry = 100; -+ u32 tmp; -+ int j, k; -+ -+ for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) { -+ rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x1); -+ -+ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_trigger[path], MASKDWORD); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] 0x%x = 0x%08x path=%d\n", -+ _tssi_trigger[path], tmp, path); -+ -+ if (j == 0) -+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true); -+ else -+ _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true); -+ -+ tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); -+ tx_counter_tmp -= tx_counter; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] First HWTXcounter=%d path=%d\n", -+ tx_counter_tmp, path); -+ -+ for (k = 0; k < retry; k++) { -+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], -+ B_TSSI_CWRPT_RDY); -+ if (tmp) -+ break; -+ -+ udelay(30); -+ -+ tx_counter_tmp = -+ rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); -+ tx_counter_tmp -= tx_counter; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n", -+ k, tx_counter_tmp, path); -+ } -+ -+ if (k >= retry) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n", -+ k, path); -+ -+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false); -+ return false; -+ } -+ -+ tssi_cw_rpt[j] = -+ rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], B_TSSI_CWRPT); -+ -+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false); -+ -+ tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); -+ tx_counter_tmp -= tx_counter; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] Final HWTXcounter=%d path=%d\n", -+ tx_counter_tmp, path); -+ } -+ -+ return true; -+} -+ -+static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4, -+ 0x78e4, 0x49c0, 0x0d18, 0x0d80}; -+ static const s16 power_2g[4] = {48, 20, 4, 4}; -+ static const s16 power_5g[4] = {48, 20, 4, 4}; -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3; -+ u32 tssi_cw_rpt[RTW8852B_TSSI_PATH_NR] = {0}; -+ u8 channel = chan->channel; -+ u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel); -+ struct rtw8852b_bb_tssi_bak tssi_bak; -+ s32 aliment_diff, tssi_cw_default; -+ u32 start_time, finish_time; -+ u32 bb_reg_backup[8] = {0}; -+ const s16 *power; -+ u8 band; -+ bool ok; -+ u32 tmp; -+ u8 j; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======> %s channel=%d path=%d\n", __func__, channel, -+ path); -+ -+ if (tssi_info->check_backup_aligmk[path][ch_idx]) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, -+ tssi_info->alignment_backup_by_ch[path][ch_idx][0]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, -+ tssi_info->alignment_backup_by_ch[path][ch_idx][1]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, -+ tssi_info->alignment_backup_by_ch[path][ch_idx][2]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, -+ tssi_info->alignment_backup_by_ch[path][ch_idx][3]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======> %s Reload TSSI Alignment !!!\n", __func__); -+ _tssi_alimentk_dump_result(rtwdev, path); -+ return; -+ } -+ -+ start_time = ktime_get_ns(); -+ -+ if (chan->band_type == RTW89_BAND_2G) -+ power = power_2g; -+ else -+ power = power_5g; -+ -+ if (channel >= 1 && channel <= 14) -+ band = TSSI_ALIMK_2G; -+ else if (channel >= 36 && channel <= 64) -+ band = TSSI_ALIMK_5GL; -+ else if (channel >= 100 && channel <= 144) -+ band = TSSI_ALIMK_5GM; -+ else if (channel >= 149 && channel <= 177) -+ band = TSSI_ALIMK_5GH; -+ else -+ band = TSSI_ALIMK_2G; -+ -+ rtw8852b_bb_backup_tssi(rtwdev, phy, &tssi_bak); -+ _tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x8); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); -+ -+ ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt); -+ if (!ok) -+ goto out; -+ -+ for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j, -+ power[j], j, tssi_cw_rpt[j]); -+ } -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][1], -+ _tssi_cw_default_mask[1]); -+ tssi_cw_default = sign_extend32(tmp, 8); -+ tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) - -+ tssi_cw_rpt[1] + tssi_cw_default; -+ aliment_diff = tssi_alim_offset_1 - tssi_cw_default; -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][2], -+ _tssi_cw_default_mask[2]); -+ tssi_cw_default = sign_extend32(tmp, 8); -+ tssi_alim_offset_2 = tssi_cw_default + aliment_diff; -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][3], -+ _tssi_cw_default_mask[3]); -+ tssi_cw_default = sign_extend32(tmp, 8); -+ tssi_alim_offset_3 = tssi_cw_default + aliment_diff; -+ -+ if (path == RF_PATH_A) { -+ tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | -+ FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | -+ FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, tmp); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, tmp); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13)); -+ } else { -+ tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) | -+ FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) | -+ FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, tmp); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, tmp); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31), -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11), -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12), -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13)); -+ } -+ -+ tssi_info->alignment_done[path][band] = true; -+ tssi_info->alignment_value[path][band][0] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); -+ tssi_info->alignment_value[path][band][1] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); -+ tssi_info->alignment_value[path][band][2] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); -+ tssi_info->alignment_value[path][band][3] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); -+ -+ tssi_info->check_backup_aligmk[path][ch_idx] = true; -+ tssi_info->alignment_backup_by_ch[path][ch_idx][0] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD); -+ tssi_info->alignment_backup_by_ch[path][ch_idx][1] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD); -+ tssi_info->alignment_backup_by_ch[path][ch_idx][2] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD); -+ tssi_info->alignment_backup_by_ch[path][ch_idx][3] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n", -+ path, band, R_P0_TSSI_ALIM1 + (path << 13), -+ tssi_info->alignment_value[path][band][0]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n", -+ path, band, R_P0_TSSI_ALIM3 + (path << 13), -+ tssi_info->alignment_value[path][band][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n", -+ path, band, R_P0_TSSI_ALIM2 + (path << 13), -+ tssi_info->alignment_value[path][band][2]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n", -+ path, band, R_P0_TSSI_ALIM4 + (path << 13), -+ tssi_info->alignment_value[path][band][3]); -+ -+out: -+ _tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup)); -+ rtw8852b_bb_restore_tssi(rtwdev, phy, &tssi_bak); -+ rtw8852b_bb_tx_mode_switch(rtwdev, phy, 0); -+ -+ finish_time = ktime_get_ns(); -+ tssi_info->tssi_alimk_time += finish_time - start_time; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K] %s processing time = %d ms\n", __func__, -+ tssi_info->tssi_alimk_time); -+} -+ - void rtw8852b_rck(struct rtw89_dev *rtwdev) - { - u8 path; -@@ -1626,6 +2674,132 @@ void rtw8852b_rx_dck(struct rtw89_dev *r - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); - } - -+void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB); -+ u32 tx_en; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); -+ -+ _tssi_disable(rtwdev, phy); -+ -+ for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) { -+ _tssi_rf_setting(rtwdev, phy, i); -+ _tssi_set_sys(rtwdev, phy, i); -+ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); -+ _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); -+ _tssi_set_dck(rtwdev, phy, i); -+ _tssi_set_tmeter_tbl(rtwdev, phy, i); -+ _tssi_set_dac_gain_tbl(rtwdev, phy, i); -+ _tssi_slope_cal_org(rtwdev, phy, i); -+ _tssi_alignment_default(rtwdev, phy, i, true); -+ _tssi_set_tssi_slope(rtwdev, phy, i); -+ -+ rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _tmac_tx_pause(rtwdev, phy, true); -+ if (hwtx_en) -+ _tssi_alimentk(rtwdev, phy, i); -+ _tmac_tx_pause(rtwdev, phy, false); -+ rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en); -+ } -+ -+ _tssi_enable(rtwdev, phy); -+ _tssi_set_efuse_to_de(rtwdev, phy); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); -+} -+ -+void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ u8 channel = chan->channel; -+ u8 band; -+ u32 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s phy=%d channel=%d\n", __func__, phy, channel); -+ -+ if (channel >= 1 && channel <= 14) -+ band = TSSI_ALIMK_2G; -+ else if (channel >= 36 && channel <= 64) -+ band = TSSI_ALIMK_5GL; -+ else if (channel >= 100 && channel <= 144) -+ band = TSSI_ALIMK_5GM; -+ else if (channel >= 149 && channel <= 177) -+ band = TSSI_ALIMK_5GH; -+ else -+ band = TSSI_ALIMK_2G; -+ -+ _tssi_disable(rtwdev, phy); -+ -+ for (i = RF_PATH_A; i < RTW8852B_TSSI_PATH_NR; i++) { -+ _tssi_rf_setting(rtwdev, phy, i); -+ _tssi_set_sys(rtwdev, phy, i); -+ _tssi_set_tmeter_tbl(rtwdev, phy, i); -+ -+ if (tssi_info->alignment_done[i][band]) -+ _tssi_alimentk_done(rtwdev, phy, i); -+ else -+ _tssi_alignment_default(rtwdev, phy, i, true); -+ } -+ -+ _tssi_enable(rtwdev, phy); -+ _tssi_set_efuse_to_de(rtwdev, phy); -+} -+ -+static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, bool enable) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 channel = chan->channel; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", -+ __func__, channel); -+ -+ if (enable) { -+ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) -+ rtw8852b_tssi(rtwdev, phy, true); -+ return; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", -+ __func__, -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); -+ -+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_A); -+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_B); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n", -+ __func__, -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT), -+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======> %s SCAN_END\n", __func__); -+} -+ -+void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, -+ enum rtw89_phy_idx phy_idx) -+{ -+ if (scan_start) -+ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true); -+ else -+ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -11,6 +11,10 @@ void rtw8852b_rck(struct rtw89_dev *rtwd - void rtw8852b_dack(struct rtw89_dev *rtwdev); - void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); -+void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en); -+void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); -+void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, -+ enum rtw89_phy_idx phy_idx); - void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-040-wifi-rtw89-8852b-rfk-add-DPK.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-040-wifi-rtw89-8852b-rfk-add-DPK.patch deleted file mode 100644 index 04d423476..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-040-wifi-rtw89-8852b-rfk-add-DPK.patch +++ /dev/null @@ -1,1330 +0,0 @@ -From 5b8471ace5b1247b2eb6a824341e11a8e871080f Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 14 Oct 2022 14:02:34 +0800 -Subject: [PATCH 040/149] wifi: rtw89: 8852b: rfk: add DPK - -DPK is short for digital pre-distortion calibration. It can adjusts digital -waveform according to PA linear characteristics dynamically to enhance -TX EVM. - -Do this calibration when we are going to run on AP channel. To prevent -power offset out of boundary, it monitors thermal and set proper boundary -to register. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221014060237.29050-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 17 + - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1148 +++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8852b_rfk.h | 3 + - 4 files changed, 1169 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3049,6 +3049,7 @@ struct rtw89_dpk_bkup_para { - struct rtw89_dpk_info { - bool is_dpk_enable; - bool is_dpk_reload_en; -+ u8 dpk_gs[RTW89_PHY_MAX]; - u16 dc_i[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; - u16 dc_q[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; - u8 corr_val[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3298,6 +3298,7 @@ - #define RR_MOD_RGM GENMASK(13, 4) - #define RR_MOD_V_DOWN 0x0 - #define RR_MOD_V_STANDBY 0x1 -+#define RR_TXAGC 0x10001 - #define RR_MOD_V_TX 0x2 - #define RR_MOD_V_RX 0x3 - #define RR_MOD_V_TXIQK 0x4 -@@ -3433,6 +3434,7 @@ - #define RR_RXBB_VOBUF GENMASK(15, 12) - #define RR_RXBB_C2G GENMASK(16, 10) - #define RR_RXBB_C1G GENMASK(9, 8) -+#define RR_RXBB_FATT GENMASK(7, 0) - #define RR_RXBB_ATTR GENMASK(7, 4) - #define RR_RXBB_ATTC GENMASK(2, 0) - #define RR_RXG 0x84 -@@ -3443,7 +3445,9 @@ - #define RR_RXAE_IQKMOD GENMASK(3, 0) - #define RR_RXA 0x8a - #define RR_RXA_DPK GENMASK(9, 8) -+#define RR_RXA_LNA 0x8b - #define RR_RXA2 0x8c -+#define RR_RAA2_SWATT GENMASK(15, 9) - #define RR_RXA2_C1 GENMASK(12, 10) - #define RR_RXA2_C2 GENMASK(9, 3) - #define RR_RXA2_CC2 GENMASK(8, 7) -@@ -3478,6 +3482,7 @@ - #define RR_IQGEN_BIAS GENMASK(11, 8) - #define RR_TXIQK 0x98 - #define RR_TXIQK_ATT2 GENMASK(15, 12) -+#define RR_TXIQK_ATT1 GENMASK(6, 0) - #define RR_TIA 0x9e - #define RR_TIA_N6 BIT(8) - #define RR_MIXER 0x9f -@@ -3853,6 +3858,9 @@ - #define B_TXSHAPE_TRIANGULAR_CFG GENMASK(25, 24) - #define R_BANDEDGE 0x4498 - #define B_BANDEDGE_EN BIT(30) -+#define R_DPD_BF 0x44a0 -+#define B_DPD_BF_OFDM GENMASK(16, 12) -+#define B_DPD_BF_SCA GENMASK(6, 0) - #define R_TXPATH_SEL 0x458C - #define B_TXPATH_SEL_MSK GENMASK(31, 28) - #define R_TXPWR 0x4594 -@@ -4299,6 +4307,7 @@ - #define B_KPATH_CFG_ED GENMASK(21, 20) - #define R_KIP_RPT1 0x80D4 - #define B_KIP_RPT1_SEL GENMASK(21, 16) -+#define B_KIP_RPT1_SEL_V1 GENMASK(19, 16) - #define R_SRAM_IQRX 0x80D8 - #define R_GAPK 0x80E0 - #define B_GAPK_ADR BIT(0) -@@ -4320,6 +4329,7 @@ - #define B_PRT_COM_GL GENMASK(7, 4) - #define B_PRT_COM_CORI GENMASK(7, 0) - #define B_PRT_COM_RXBB GENMASK(5, 0) -+#define B_PRT_COM_RXBB_V1 GENMASK(4, 0) - #define B_PRT_COM_DONE BIT(0) - #define R_COEF_SEL 0x8104 - #define B_COEF_SEL_IQC BIT(0) -@@ -4358,13 +4368,18 @@ - #define B_DPD_LBK BIT(7) - #define R_DPD_CH0 0x81AC - #define R_DPD_BND 0x81B4 -+#define B_DPD_BND_1 GENMASK(24, 16) -+#define B_DPD_BND_0 GENMASK(8, 0) - #define R_DPD_CH0A 0x81BC - #define B_DPD_MEN GENMASK(31, 28) - #define B_DPD_ORDER GENMASK(26, 24) -+#define B_DPD_ORDER_V1 GENMASK(26, 25) -+#define B_DPD_CFG GENMASK(22, 0) - #define B_DPD_SEL GENMASK(13, 8) - #define R_TXAGC_RFK 0x81C4 - #define B_TXAGC_RFK_CH0 GENMASK(5, 0) - #define R_DPD_COM 0x81C8 -+#define B_DPD_COM_OF BIT(15) - #define R_KIP_IQP 0x81CC - #define B_KIP_IQP_SW GENMASK(13, 12) - #define B_KIP_IQP_IQSW GENMASK(5, 0) -@@ -4464,6 +4479,7 @@ - #define R_P0_CFCH_BW0 0xC0D4 - #define B_P0_CFCH_BW0 GENMASK(27, 26) - #define R_P0_CFCH_BW1 0xC0D8 -+#define B_P0_CFCH_EX BIT(13) - #define B_P0_CFCH_BW1 GENMASK(8, 5) - #define R_ADDCK0D 0xC0F0 - #define B_ADDCK0D_VAL2 GENMASK(31, 26) -@@ -4513,6 +4529,7 @@ - #define R_PATH0_BW_SEL_V1 0xC0D8 - #define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) - #define R_PATH1_BW_SEL_V1 0xC1D8 -+#define B_PATH1_BW_SEL_EX BIT(13) - #define B_PATH1_BW_SEL_MSK_V1 GENMASK(8, 5) - #define R_ADDCK1D 0xC1F0 - #define B_ADDCK1D_VAL2 GENMASK(31, 26) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -17,9 +17,49 @@ - #define RTW8852B_IQK_SS 2 - #define RTW8852B_RXK_GROUP_NR 4 - #define RTW8852B_TSSI_PATH_NR 2 -+#define RTW8852B_RF_REL_VERSION 34 -+#define RTW8852B_DPK_VER 0x0d -+#define RTW8852B_DPK_RF_PATH 2 -+#define RTW8852B_DPK_KIP_REG_NUM 2 - - #define _TSSI_DE_MASK GENMASK(21, 12) - #define ADDC_T_AVG 100 -+#define DPK_TXAGC_LOWER 0x2e -+#define DPK_TXAGC_UPPER 0x3f -+#define DPK_TXAGC_INVAL 0xff -+#define RFREG_MASKRXBB 0x003e0 -+#define RFREG_MASKMODE 0xf0000 -+ -+enum rtw8852b_dpk_id { -+ LBK_RXIQK = 0x06, -+ SYNC = 0x10, -+ MDPK_IDL = 0x11, -+ MDPK_MPA = 0x12, -+ GAIN_LOSS = 0x13, -+ GAIN_CAL = 0x14, -+ DPK_RXAGC = 0x15, -+ KIP_PRESET = 0x16, -+ KIP_RESTORE = 0x17, -+ DPK_TXAGC = 0x19, -+ D_KIP_PRESET = 0x28, -+ D_TXAGC = 0x29, -+ D_RXAGC = 0x2a, -+ D_SYNC = 0x2b, -+ D_GAIN_LOSS = 0x2c, -+ D_MDPK_IDL = 0x2d, -+ D_GAIN_NORM = 0x2f, -+ D_KIP_THERMAL = 0x30, -+ D_KIP_RESTORE = 0x31 -+}; -+ -+enum dpk_agc_step { -+ DPK_AGC_STEP_SYNC_DGAIN, -+ DPK_AGC_STEP_GAIN_ADJ, -+ DPK_AGC_STEP_GAIN_LOSS_IDX, -+ DPK_AGC_STEP_GL_GT_CRITERION, -+ DPK_AGC_STEP_GL_LT_CRITERION, -+ DPK_AGC_STEP_SET_TX_GAIN, -+}; - - enum rtw8852b_iqk_type { - ID_TXAGC = 0x0, -@@ -190,6 +230,24 @@ static void _rfk_restore_rf_reg(struct r - } - } - -+static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_bybb) -+{ -+ if (is_bybb) -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); -+ else -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+} -+ -+static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_bybb) -+{ -+ if (is_bybb) -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); -+ else -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); -+} -+ - static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) - { - bool fail = true; -@@ -1605,6 +1663,1069 @@ static void _iqk(struct rtw89_dev *rtwde - } - } - -+static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[], -+ u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) { -+ reg_bkup[path][i] = -+ rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", -+ reg[i] + (path << 8), reg_bkup[path][i]); -+ } -+} -+ -+static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[], -+ const u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) { -+ rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD, -+ reg_bkup[path][i]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", -+ reg[i] + (path << 8), reg_bkup[path][i]); -+ } -+} -+ -+static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) -+{ -+ u8 order; -+ u8 val; -+ -+ order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); -+ val = 0x3 >> order; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); -+ -+ return val; -+} -+ -+static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 val, kidx = dpk->cur_idx[path]; -+ -+ val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ MASKBYTE3, _dpk_order_convert(rtwdev) << 1 | val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, -+ kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); -+} -+ -+static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, enum rtw8852b_dpk_id id) -+{ -+ u16 dpk_cmd; -+ u32 val; -+ int ret; -+ -+ dpk_cmd = (id << 8) | (0x19 + (path << 4)); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, -+ 1, 20000, false, -+ rtwdev, 0xbff8, MASKBYTE0); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n"); -+ -+ udelay(1); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00030000); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, -+ 1, 2000, false, -+ rtwdev, 0x80fc, MASKLWORD); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n"); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] one-shot for %s = 0x%x\n", -+ id == 0x06 ? "LBK_RXIQK" : -+ id == 0x10 ? "SYNC" : -+ id == 0x11 ? "MDPK_IDL" : -+ id == 0x12 ? "MDPK_MPA" : -+ id == 0x13 ? "GAIN_LOSS" : -+ id == 0x14 ? "PWR_CAL" : -+ id == 0x15 ? "DPK_RXAGC" : -+ id == 0x16 ? "KIP_PRESET" : -+ id == 0x17 ? "KIP_RESOTRE" : "DPK_TXAGC", -+ dpk_cmd); -+} -+ -+static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); -+ _set_rx_dck(rtwdev, phy, path); -+} -+ -+static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ u8 kidx = dpk->cur_idx[path]; -+ -+ dpk->bp[path][kidx].band = chan->band_type; -+ dpk->bp[path][kidx].ch = chan->channel; -+ dpk->bp[path][kidx].bw = chan->band_width; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", -+ path, dpk->cur_idx[path], phy, -+ rtwdev->is_tssi_mode[path] ? "on" : "off", -+ rtwdev->dbcc_en ? "on" : "off", -+ dpk->bp[path][kidx].band == 0 ? "2G" : -+ dpk->bp[path][kidx].band == 1 ? "5G" : "6G", -+ dpk->bp[path][kidx].ch, -+ dpk->bp[path][kidx].bw == 0 ? "20M" : -+ dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); -+} -+ -+static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kpath) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_defs_tbl); -+ -+ if (chan->band_width == RTW89_CHANNEL_WIDTH_80) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x1); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); -+} -+ -+static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kpath) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_restore_defs_tbl); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); -+ -+ if (chan->band_width == RTW89_CHANNEL_WIDTH_80) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x0); -+ } -+} -+ -+static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_pause) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, is_pause); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, -+ is_pause ? "pause" : "resume"); -+} -+ -+static void _dpk_kip_restore(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_kip_defs_tbl); -+ -+ if (rtwdev->hal.cv > CHIP_CAV) -+ rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), B_DPD_COM_OF, 0x1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); -+} -+ -+static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ u8 cur_rxbb; -+ u32 tmp; -+ -+ cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB); -+ -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, 0x0); -+ -+ tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); -+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0xd); -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); -+ -+ if (cur_rxbb >= 0x11) -+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x13); -+ else if (cur_rxbb <= 0xa) -+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x00); -+ else -+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x05); -+ -+ rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80014); -+ udelay(70); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x025); -+ -+ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0x5); -+} -+ -+static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1); -+ -+ udelay(200); -+ -+ dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", -+ dpk->bp[path][kidx].ther_dpk); -+} -+ -+static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_FATT, 0xf2); -+ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); -+ } else { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SWATT, 0x5); -+ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_RXA_LNA, RFREG_MASK, 0x920FC); -+ rtw89_write_rf(rtwdev, path, RR_XALNA2, RFREG_MASK, 0x002C0); -+ rtw89_write_rf(rtwdev, path, RR_IQGEN, RFREG_MASK, 0x38800); -+ } -+ -+ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); -+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] ARF 0x0/0x11/0x1a = 0x%x/ 0x%x/ 0x%x\n", -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), -+ rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK), -+ rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); -+} -+ -+static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_bypass) -+{ -+ if (is_bypass) { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ B_RXIQC_BYPASS2, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ B_RXIQC_BYPASS, 0x1); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD)); -+ } else { -+ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); -+ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD)); -+ } -+} -+ -+static -+void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) -+ rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); -+ else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) -+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", -+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : -+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); -+} -+ -+static void _dpk_table_select(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, u8 kidx, u8 gain) -+{ -+ u8 val; -+ -+ val = 0x80 + kidx * 0x20 + gain * 0x10; -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, -+ gain, val); -+} -+ -+static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+#define DPK_SYNC_TH_DC_I 200 -+#define DPK_SYNC_TH_DC_Q 200 -+#define DPK_SYNC_TH_CORR 170 -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u16 dc_i, dc_q; -+ u8 corr_val, corr_idx; -+ -+ rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); -+ -+ corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); -+ corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", -+ path, corr_idx, corr_val); -+ -+ dpk->corr_idx[path][kidx] = corr_idx; -+ dpk->corr_val[path][kidx] = corr_val; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); -+ -+ dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); -+ dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); -+ -+ dc_i = abs(sign_extend32(dc_i, 11)); -+ dc_q = abs(sign_extend32(dc_q, 11)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", -+ path, dc_i, dc_q); -+ -+ dpk->dc_i[path][kidx] = dc_i; -+ dpk->dc_q[path][kidx] = dc_q; -+ -+ if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || -+ corr_val < DPK_SYNC_TH_CORR) -+ return true; -+ else -+ return false; -+} -+ -+static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ _dpk_one_shot(rtwdev, phy, path, SYNC); -+ -+ return _dpk_sync_check(rtwdev, path, kidx); -+} -+ -+static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) -+{ -+ u16 dgain; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); -+ -+ dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); -+ -+ return dgain; -+} -+ -+static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) -+{ -+ static const u16 bnd[15] = { -+ 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556, -+ 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220 -+ }; -+ s8 offset; -+ -+ if (dgain >= bnd[0]) -+ offset = 0x6; -+ else if (bnd[0] > dgain && dgain >= bnd[1]) -+ offset = 0x6; -+ else if (bnd[1] > dgain && dgain >= bnd[2]) -+ offset = 0x5; -+ else if (bnd[2] > dgain && dgain >= bnd[3]) -+ offset = 0x4; -+ else if (bnd[3] > dgain && dgain >= bnd[4]) -+ offset = 0x3; -+ else if (bnd[4] > dgain && dgain >= bnd[5]) -+ offset = 0x2; -+ else if (bnd[5] > dgain && dgain >= bnd[6]) -+ offset = 0x1; -+ else if (bnd[6] > dgain && dgain >= bnd[7]) -+ offset = 0x0; -+ else if (bnd[7] > dgain && dgain >= bnd[8]) -+ offset = 0xff; -+ else if (bnd[8] > dgain && dgain >= bnd[9]) -+ offset = 0xfe; -+ else if (bnd[9] > dgain && dgain >= bnd[10]) -+ offset = 0xfd; -+ else if (bnd[10] > dgain && dgain >= bnd[11]) -+ offset = 0xfc; -+ else if (bnd[11] > dgain && dgain >= bnd[12]) -+ offset = 0xfb; -+ else if (bnd[12] > dgain && dgain >= bnd[13]) -+ offset = 0xfa; -+ else if (bnd[13] > dgain && dgain >= bnd[14]) -+ offset = 0xf9; -+ else if (bnd[14] > dgain) -+ offset = 0xf8; -+ else -+ offset = 0x0; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain offset = %d\n", offset); -+ -+ return offset; -+} -+ -+static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); -+ -+ return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); -+} -+ -+static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ _dpk_table_select(rtwdev, path, kidx, 1); -+ _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS); -+} -+ -+static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ _dpk_tpg_sel(rtwdev, path, kidx); -+ _dpk_one_shot(rtwdev, phy, path, KIP_PRESET); -+} -+ -+static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP Power/CLK on\n"); -+} -+ -+static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 txagc) -+{ -+ rtw89_write_rf(rtwdev, path, RR_TXAGC, RFREG_MASK, txagc); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ _dpk_one_shot(rtwdev, phy, path, DPK_TXAGC); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set TXAGC = 0x%x\n", txagc); -+} -+ -+static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ u32 tmp; -+ -+ tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, tmp); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); -+ _dpk_one_shot(rtwdev, phy, path, DPK_RXAGC); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL_V1, 0x8); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] set RXBB = 0x%x (RF0x0[9:5] = 0x%x)\n", -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB_V1), -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB)); -+} -+ -+static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, s8 gain_offset) -+{ -+ u8 txagc; -+ -+ txagc = rtw89_read_rf(rtwdev, path, RR_TXAGC, RFREG_MASK); -+ -+ if (txagc - gain_offset < DPK_TXAGC_LOWER) -+ txagc = DPK_TXAGC_LOWER; -+ else if (txagc - gain_offset > DPK_TXAGC_UPPER) -+ txagc = DPK_TXAGC_UPPER; -+ else -+ txagc = txagc - gain_offset; -+ -+ _dpk_kip_set_txagc(rtwdev, phy, path, txagc); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", -+ gain_offset, txagc); -+ return txagc; -+} -+ -+static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) -+{ -+ u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; -+ u8 i; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); -+ -+ if (is_check) { -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); -+ val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); -+ val1_i = abs(sign_extend32(val1_i, 11)); -+ val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); -+ val1_q = abs(sign_extend32(val1_q, 11)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); -+ val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); -+ val2_i = abs(sign_extend32(val2_i, 11)); -+ val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); -+ val2_q = abs(sign_extend32(val2_q, 11)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", -+ phy_div(val1_i * val1_i + val1_q * val1_q, -+ val2_i * val2_i + val2_q * val2_q)); -+ } else { -+ for (i = 0; i < 32; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] PAS_Read[%02d]= 0x%08x\n", i, -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); -+ } -+ } -+ -+ if (val1_i * val1_i + val1_q * val1_q >= -+ (val2_i * val2_i + val2_q * val2_q) * 8 / 5) -+ return true; -+ -+ return false; -+} -+ -+static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx, u8 init_txagc, -+ bool loss_only) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 step = DPK_AGC_STEP_SYNC_DGAIN; -+ u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; -+ u8 goout = 0, agc_cnt = 0, limited_rxbb = 0; -+ u16 dgain = 0; -+ s8 offset; -+ int limit = 200; -+ -+ tmp_txagc = init_txagc; -+ -+ do { -+ switch (step) { -+ case DPK_AGC_STEP_SYNC_DGAIN: -+ if (_dpk_sync(rtwdev, phy, path, kidx)) { -+ tmp_txagc = 0xff; -+ goout = 1; -+ break; -+ } -+ -+ dgain = _dpk_dgain_read(rtwdev); -+ -+ if (loss_only == 1 || limited_rxbb == 1) -+ step = DPK_AGC_STEP_GAIN_LOSS_IDX; -+ else -+ step = DPK_AGC_STEP_GAIN_ADJ; -+ break; -+ -+ case DPK_AGC_STEP_GAIN_ADJ: -+ tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, -+ RFREG_MASKRXBB); -+ offset = _dpk_dgain_mapping(rtwdev, dgain); -+ -+ if (tmp_rxbb + offset > 0x1f) { -+ tmp_rxbb = 0x1f; -+ limited_rxbb = 1; -+ } else if (tmp_rxbb + offset < 0) { -+ tmp_rxbb = 0; -+ limited_rxbb = 1; -+ } else { -+ tmp_rxbb = tmp_rxbb + offset; -+ } -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB, -+ tmp_rxbb); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb); -+ if (offset || agc_cnt == 0) { -+ if (chan->band_width < RTW89_CHANNEL_WIDTH_80) -+ _dpk_bypass_rxcfir(rtwdev, path, true); -+ else -+ _dpk_lbk_rxiqk(rtwdev, phy, path); -+ } -+ if (dgain > 1922 || dgain < 342) -+ step = DPK_AGC_STEP_SYNC_DGAIN; -+ else -+ step = DPK_AGC_STEP_GAIN_LOSS_IDX; -+ -+ agc_cnt++; -+ break; -+ -+ case DPK_AGC_STEP_GAIN_LOSS_IDX: -+ _dpk_gainloss(rtwdev, phy, path, kidx); -+ tmp_gl_idx = _dpk_gainloss_read(rtwdev); -+ -+ if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || -+ tmp_gl_idx >= 7) -+ step = DPK_AGC_STEP_GL_GT_CRITERION; -+ else if (tmp_gl_idx == 0) -+ step = DPK_AGC_STEP_GL_LT_CRITERION; -+ else -+ step = DPK_AGC_STEP_SET_TX_GAIN; -+ break; -+ -+ case DPK_AGC_STEP_GL_GT_CRITERION: -+ if (tmp_txagc == 0x2e) { -+ goout = 1; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Txagc@lower bound!!\n"); -+ } else { -+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0x3); -+ } -+ step = DPK_AGC_STEP_GAIN_LOSS_IDX; -+ agc_cnt++; -+ break; -+ -+ case DPK_AGC_STEP_GL_LT_CRITERION: -+ if (tmp_txagc == 0x3f) { -+ goout = 1; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Txagc@upper bound!!\n"); -+ } else { -+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0xfe); -+ } -+ step = DPK_AGC_STEP_GAIN_LOSS_IDX; -+ agc_cnt++; -+ break; -+ case DPK_AGC_STEP_SET_TX_GAIN: -+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path, tmp_gl_idx); -+ goout = 1; -+ agc_cnt++; -+ break; -+ -+ default: -+ goout = 1; -+ break; -+ } -+ } while (!goout && agc_cnt < 6 && limit-- > 0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, -+ tmp_rxbb); -+ -+ return tmp_txagc; -+} -+ -+static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) -+{ -+ switch (order) { -+ case 0: -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); -+ break; -+ case 1: -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); -+ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); -+ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); -+ break; -+ case 2: -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); -+ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); -+ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Wrong MDPD order!!(0x%x)\n", order); -+ break; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Set MDPD order to 0x%x for IDL\n", order); -+} -+ -+static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx, u8 gain) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 && -+ dpk->bp[path][kidx].band == RTW89_BAND_5G) -+ _dpk_set_mdpd_para(rtwdev, 0x2); -+ else -+ _dpk_set_mdpd_para(rtwdev, 0x0); -+ -+ _dpk_one_shot(rtwdev, phy, path, MDPK_IDL); -+} -+ -+static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ const u16 pwsf = 0x78; -+ u8 gs = dpk->dpk_gs[phy]; -+ -+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), -+ B_COEF_SEL_MDPD, kidx); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, -+ pwsf, gs); -+ -+ dpk->bp[path][kidx].txagc_dpk = txagc; -+ rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), -+ 0x3F << ((gain << 3) + (kidx << 4)), txagc); -+ -+ dpk->bp[path][kidx].pwsf = pwsf; -+ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), -+ 0x1FF << (gain << 4), pwsf); -+ -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); -+ -+ dpk->bp[path][kidx].gs = gs; -+ if (dpk->dpk_gs[phy] == 0x7f) -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ MASKDWORD, 0x007f7f7f); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ MASKDWORD, 0x005b5b5b); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ B_DPD_ORDER_V1, _dpk_order_convert(rtwdev)); -+ rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, 0x0); -+} -+ -+static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ bool is_reload = false; -+ u8 idx, cur_band, cur_ch; -+ -+ cur_band = chan->band_type; -+ cur_ch = chan->channel; -+ -+ for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { -+ if (cur_band != dpk->bp[path][idx].band || -+ cur_ch != dpk->bp[path][idx].ch) -+ continue; -+ -+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), -+ B_COEF_SEL_MDPD, idx); -+ dpk->cur_idx[path] = idx; -+ is_reload = true; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] reload S%d[%d] success\n", path, idx); -+ } -+ -+ return is_reload; -+} -+ -+static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 gain) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 txagc = 0x38, kidx = dpk->cur_idx[path]; -+ bool is_fail = false; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx); -+ -+ _rfk_rf_direct_cntrl(rtwdev, path, false); -+ _rfk_drf_direct_cntrl(rtwdev, path, false); -+ -+ _dpk_kip_pwr_clk_on(rtwdev, path); -+ _dpk_kip_set_txagc(rtwdev, phy, path, txagc); -+ _dpk_rf_setting(rtwdev, gain, path, kidx); -+ _dpk_rx_dck(rtwdev, phy, path); -+ -+ _dpk_kip_preset(rtwdev, phy, path, kidx); -+ _dpk_kip_set_rxagc(rtwdev, phy, path); -+ _dpk_table_select(rtwdev, path, kidx, gain); -+ -+ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust txagc = 0x%x\n", txagc); -+ -+ if (txagc == 0xff) { -+ is_fail = true; -+ } else { -+ _dpk_get_thermal(rtwdev, kidx, path); -+ -+ _dpk_idl_mpa(rtwdev, phy, path, kidx, gain); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); -+ -+ _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc); -+ } -+ -+ if (!is_fail) -+ dpk->bp[path][kidx].path_ok = true; -+ else -+ dpk->bp[path][kidx].path_ok = false; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, -+ is_fail ? "Check" : "Success"); -+ -+ return is_fail; -+} -+ -+static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, -+ enum rtw89_phy_idx phy, u8 kpath) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120}; -+ u32 kip_bkup[RTW8852B_DPK_RF_PATH][RTW8852B_DPK_KIP_REG_NUM] = {}; -+ u32 backup_rf_val[RTW8852B_DPK_RF_PATH][BACKUP_RF_REGS_NR]; -+ u32 backup_bb_val[BACKUP_BB_REGS_NR]; -+ bool is_fail = true, reloaded[RTW8852B_DPK_RF_PATH] = {}; -+ u8 path; -+ -+ if (dpk->is_dpk_reload_en) { -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { -+ reloaded[path] = _dpk_reload_check(rtwdev, phy, path); -+ if (!reloaded[path] && dpk->bp[path][0].ch) -+ dpk->cur_idx[path] = !dpk->cur_idx[path]; -+ else -+ _dpk_onoff(rtwdev, path, false); -+ } -+ } else { -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) -+ dpk->cur_idx[path] = 0; -+ } -+ -+ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); -+ -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { -+ _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); -+ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ _dpk_information(rtwdev, phy, path); -+ if (rtwdev->is_tssi_mode[path]) -+ _dpk_tssi_pause(rtwdev, path, true); -+ } -+ -+ _dpk_bb_afe_setting(rtwdev, phy, path, kpath); -+ -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { -+ is_fail = _dpk_main(rtwdev, phy, path, 1); -+ _dpk_onoff(rtwdev, path, is_fail); -+ } -+ -+ _dpk_bb_afe_restore(rtwdev, phy, path, kpath); -+ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); -+ -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { -+ _dpk_kip_restore(rtwdev, path); -+ _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); -+ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ if (rtwdev->is_tssi_mode[path]) -+ _dpk_tssi_pause(rtwdev, path, false); -+ } -+} -+ -+static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_fem_info *fem = &rtwdev->fem; -+ -+ if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); -+ return true; -+ } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); -+ return true; -+ } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Skip DPK due to 6G_ext_PA exist!!\n"); -+ return true; -+ } -+ -+ return false; -+} -+ -+static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ u8 path, kpath; -+ -+ kpath = _kpath(rtwdev, phy); -+ -+ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { -+ if (kpath & BIT(path)) -+ _dpk_onoff(rtwdev, path, true); -+ } -+} -+ -+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", -+ RTW8852B_DPK_VER, rtwdev->hal.cv, -+ RTW8852B_RF_REL_VERSION); -+ -+ if (_dpk_bypass_check(rtwdev, phy)) -+ _dpk_force_bypass(rtwdev, phy); -+ else -+ _dpk_cal_select(rtwdev, force, phy, RF_AB); -+} -+ -+static void _dpk_track(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst; -+ s8 delta_ther[2] = {}; -+ u8 trk_idx, txagc_rf; -+ u8 path, kidx; -+ u16 pwsf[2]; -+ u8 cur_ther; -+ u32 tmp; -+ -+ for (path = 0; path < RF_PATH_NUM_8852B; path++) { -+ kidx = dpk->cur_idx[path]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", -+ path, kidx, dpk->bp[path][kidx].ch); -+ -+ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] thermal now = %d\n", cur_ther); -+ -+ if (dpk->bp[path][kidx].ch && cur_ther) -+ delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; -+ -+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) -+ delta_ther[path] = delta_ther[path] * 3 / 2; -+ else -+ delta_ther[path] = delta_ther[path] * 5 / 2; -+ -+ txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), -+ 0x0000003f); -+ -+ if (rtwdev->is_tssi_mode[path]) { -+ trk_idx = rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", -+ txagc_rf, trk_idx); -+ -+ txagc_bb = -+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), -+ MASKBYTE2); -+ txagc_bb_tp = -+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13), -+ B_TXAGC_TP); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", -+ txagc_bb_tp, txagc_bb); -+ -+ txagc_ofst = -+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), -+ MASKBYTE3); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", -+ txagc_ofst, delta_ther[path]); -+ tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), -+ B_DPD_COM_OF); -+ if (tmp == 0x1) { -+ txagc_ofst = 0; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] HW txagc offset mode\n"); -+ } -+ -+ if (txagc_rf && cur_ther) -+ ini_diff = txagc_ofst + (delta_ther[path]); -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, -+ R_P0_TXDPD + (path << 13), -+ B_P0_TXDPD); -+ if (tmp == 0x0) { -+ pwsf[0] = dpk->bp[path][kidx].pwsf + -+ txagc_bb_tp - txagc_bb + ini_diff; -+ pwsf[1] = dpk->bp[path][kidx].pwsf + -+ txagc_bb_tp - txagc_bb + ini_diff; -+ } else { -+ pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff; -+ pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff; -+ } -+ -+ } else { -+ pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; -+ pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; -+ } -+ -+ tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS); -+ if (!tmp && txagc_rf) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", -+ pwsf[0], pwsf[1]); -+ -+ rtw89_phy_write32_mask(rtwdev, -+ R_DPD_BND + (path << 8) + (kidx << 2), -+ B_DPD_BND_0, pwsf[0]); -+ rtw89_phy_write32_mask(rtwdev, -+ R_DPD_BND + (path << 8) + (kidx << 2), -+ B_DPD_BND_1, pwsf[1]); -+ } -+ } -+} -+ -+static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 tx_scale, ofdm_bkof, path, kpath; -+ -+ kpath = _kpath(rtwdev, phy); -+ -+ ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM); -+ tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA); -+ -+ if (ofdm_bkof + tx_scale >= 44) { -+ /* move dpd backoff to bb, and set dpd backoff to 0 */ -+ dpk->dpk_gs[phy] = 0x7f; -+ for (path = 0; path < RF_PATH_NUM_8852B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8), -+ B_DPD_CFG, 0x7f7f7f); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK] Set S%d DPD backoff to 0dB\n", path); -+ } -+ } else { -+ dpk->dpk_gs[phy] = 0x5b; -+ } -+} -+ - static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, - enum rtw89_rf_path path) - { -@@ -2626,6 +3747,11 @@ out: - tssi_info->tssi_alimk_time); - } - -+void rtw8852b_dpk_init(struct rtw89_dev *rtwdev) -+{ -+ _set_dpd_backoff(rtwdev, RTW89_PHY_0); -+} -+ - void rtw8852b_rck(struct rtw89_dev *rtwdev) - { - u8 path; -@@ -2674,6 +3800,28 @@ void rtw8852b_rx_dck(struct rtw89_dev *r - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); - } - -+void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ rtwdev->dpk.is_dpk_enable = true; -+ rtwdev->dpk.is_dpk_reload_en = false; -+ _dpk(rtwdev, phy_idx, false); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); -+} -+ -+void rtw8852b_dpk_track(struct rtw89_dev *rtwdev) -+{ -+ _dpk_track(rtwdev); -+} -+ - void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en) - { - u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h -@@ -11,6 +11,9 @@ void rtw8852b_rck(struct rtw89_dev *rtwd - void rtw8852b_dack(struct rtw89_dev *rtwdev); - void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); -+void rtw8852b_dpk_init(struct rtw89_dev *rtwdev); -+void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); -+void rtw8852b_dpk_track(struct rtw89_dev *rtwdev); - void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en); - void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); - void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-041-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-041-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch deleted file mode 100644 index 370078859..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-041-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch +++ /dev/null @@ -1,75 +0,0 @@ -From ef8acbcac6816e4caf20934932b4881d775c6f37 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 14 Oct 2022 14:02:35 +0800 -Subject: [PATCH 041/149] wifi: rtw89: 8852b: add chip_ops related to RF - calibration - -Since RF calibrations are added, add chip_ops to call them. These chip_ops -include initial, full calibration, configuration when switching band and -scanning, and track work in period of 2 seconds. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221014060237.29050-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 42 +++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1513,6 +1513,43 @@ static void rtw8852b_set_channel_help(st - } - } - -+static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev) -+{ -+ rtwdev->is_tssi_mode[RF_PATH_A] = false; -+ rtwdev->is_tssi_mode[RF_PATH_B] = false; -+ -+ rtw8852b_dpk_init(rtwdev); -+ rtw8852b_rck(rtwdev); -+ rtw8852b_dack(rtwdev); -+ rtw8852b_rx_dck(rtwdev, RTW89_PHY_0); -+} -+ -+static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev) -+{ -+ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; -+ -+ rtw8852b_rx_dck(rtwdev, phy_idx); -+ rtw8852b_iqk(rtwdev, phy_idx); -+ rtw8852b_tssi(rtwdev, phy_idx, true); -+ rtw8852b_dpk(rtwdev, phy_idx); -+} -+ -+static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8852b_tssi_scan(rtwdev, phy_idx); -+} -+ -+static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, bool start) -+{ -+ rtw8852b_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); -+} -+ -+static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev) -+{ -+ rtw8852b_dpk_track(rtwdev); -+} -+ - static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -2346,6 +2383,11 @@ static const struct rtw89_chip_ops rtw88 - .read_efuse = rtw8852b_read_efuse, - .read_phycap = rtw8852b_read_phycap, - .fem_setup = NULL, -+ .rfk_init = rtw8852b_rfk_init, -+ .rfk_channel = rtw8852b_rfk_channel, -+ .rfk_band_changed = rtw8852b_rfk_band_changed, -+ .rfk_scan = rtw8852b_rfk_scan, -+ .rfk_track = rtw8852b_rfk_track, - .power_trim = rtw8852b_power_trim, - .set_txpwr = rtw8852b_set_txpwr, - .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-042-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-042-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch deleted file mode 100644 index 815fd97dd..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-042-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 3b66519b023b9de3239576b938bbdf43f95bc862 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 14 Oct 2022 14:02:36 +0800 -Subject: [PATCH 042/149] wifi: rtw89: phy: add dummy C2H handler to avoid - warning message - -The C2H class 2 function 3 is to report retry count of low rate, but driver -doesn't implement yet, so add a dummy case to avoid message: - - rtw89_8852be 0000:03:00.0: c2h class 2 not support - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221014060237.29050-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 4 ++++ - drivers/net/wireless/realtek/rtw89/phy.h | 9 +++++++++ - 2 files changed, 13 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2276,6 +2276,10 @@ void rtw89_phy_c2h_handle(struct rtw89_d - if (func < RTW89_PHY_C2H_FUNC_RA_MAX) - handler = rtw89_phy_c2h_ra_handler[func]; - break; -+ case RTW89_PHY_C2H_CLASS_DM: -+ if (func == RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY) -+ return; -+ fallthrough; - default: - rtw89_info(rtwdev, "c2h class %d not support\n", class); - return; ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -114,6 +114,15 @@ enum rtw89_phy_c2h_ra_func { - RTW89_PHY_C2H_FUNC_RA_MAX, - }; - -+enum rtw89_phy_c2h_dm_func { -+ RTW89_PHY_C2H_DM_FUNC_FW_TEST, -+ RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT, -+ RTW89_PHY_C2H_DM_FUNC_SIGB, -+ RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY, -+ RTW89_PHY_C2H_DM_FUNC_MCC_DIG, -+ RTW89_PHY_C2H_DM_FUNC_NUM, -+}; -+ - enum rtw89_phy_c2h_class { - RTW89_PHY_C2H_CLASS_RUA, - RTW89_PHY_C2H_CLASS_RA, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-043-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-043-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch deleted file mode 100644 index f093ae9dd..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-043-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch +++ /dev/null @@ -1,69 +0,0 @@ -From b5db4ef38e21dd9b6b95ae96cea5032b00e04f24 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 14 Oct 2022 14:02:37 +0800 -Subject: [PATCH 043/149] wifi: rtw89: 8852b: add 8852be to Makefile and - Kconfig - -Now, basic materials for 8852be are ready, so add 8852be to Kconfig and -Makefile. Current version can support STA, AP and monitor modes. - -We still fine tune some features, such as BT coexistence, performance, and -power consumption. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221014060237.29050-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/Kconfig | 14 ++++++++++++++ - drivers/net/wireless/realtek/rtw89/Makefile | 9 +++++++++ - 2 files changed, 23 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/Kconfig -+++ b/drivers/net/wireless/realtek/rtw89/Kconfig -@@ -23,6 +23,10 @@ config RTW89_8852A - tristate - depends on m - -+config RTW89_8852B -+ tristate -+ depends on m -+ - config RTW89_8852C - tristate - depends on m -@@ -38,6 +42,17 @@ config RTW89_8852AE - Select this option will enable support for 8852AE chipset - - 802.11ax PCIe wireless network (Wi-Fi 6) adapter -+config RTW89_8852BE -+ tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter" -+ depends on m -+ depends on PCI -+ select RTW89_CORE -+ select RTW89_PCI -+ select RTW89_8852B -+ help -+ Select this option will enable support for 8852BE chipset -+ -+ 802.11ax PCIe wireless network (Wi-Fi 6) adapter - - config RTW89_8852CE - tristate "Realtek 8852CE PCI wireless network (Wi-Fi 6E) adapter" ---- a/drivers/net/wireless/realtek/rtw89/Makefile -+++ b/drivers/net/wireless/realtek/rtw89/Makefile -@@ -24,6 +24,15 @@ rtw89_8852a-objs := rtw8852a.o \ - obj-$(CPTCFG_RTW89_8852AE) += rtw89_8852ae.o - rtw89_8852ae-objs := rtw8852ae.o - -+obj-$(CPTCFG_RTW89_8852B) += rtw89_8852b.o -+rtw89_8852b-objs := rtw8852b.o \ -+ rtw8852b_table.o \ -+ rtw8852b_rfk.o \ -+ rtw8852b_rfk_table.o -+ -+obj-$(CPTCFG_RTW89_8852BE) += rtw89_8852be.o -+rtw89_8852be-objs := rtw8852be.o -+ - obj-$(CPTCFG_RTW89_8852C) += rtw89_8852c.o - rtw89_8852c-objs := rtw8852c.o \ - rtw8852c_table.o \ diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-044-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-044-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch deleted file mode 100644 index f83455fc9..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-044-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 4feda7f317cb7e4b6fcdaffb0d1ad363ee28fdea Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 20 Oct 2022 13:25:49 +0800 -Subject: [PATCH 044/149] wifi: rtw89: fw: adapt to new firmware format of - dynamic header - -Since firmware size is limited, we create variant firmwares for variant -application areas. To help driver to know firmware's capabilities, firmware -dynamic header is introduced to have more information, such as firmware -features and firmware compile flags. - -Since this driver rtw89 only uses single one specific firmware at runtime, -this patch is just to ignore this dynamic header, not actually use the -content. - -This patch can be backward compatible, and no this kind of firmware is -added to linux-firmware yet, so I can prepare this in advance. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221020052549.33783-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 22 +++++++++++++++++++--- - drivers/net/wireless/realtek/rtw89/fw.h | 12 ++++++++++++ - 2 files changed, 31 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -85,15 +85,31 @@ static int rtw89_fw_hdr_parser(struct rt - { - struct rtw89_fw_hdr_section_info *section_info; - const u8 *fw_end = fw + len; -+ const u8 *fwdynhdr; - const u8 *bin; -+ u32 base_hdr_len; - u32 i; - - if (!info) - return -EINVAL; - - info->section_num = GET_FW_HDR_SEC_NUM(fw); -- info->hdr_len = RTW89_FW_HDR_SIZE + -- info->section_num * RTW89_FW_SECTION_HDR_SIZE; -+ base_hdr_len = RTW89_FW_HDR_SIZE + -+ info->section_num * RTW89_FW_SECTION_HDR_SIZE; -+ info->dynamic_hdr_en = GET_FW_HDR_DYN_HDR(fw); -+ -+ if (info->dynamic_hdr_en) { -+ info->hdr_len = GET_FW_HDR_LEN(fw); -+ info->dynamic_hdr_len = info->hdr_len - base_hdr_len; -+ fwdynhdr = fw + base_hdr_len; -+ if (GET_FW_DYNHDR_LEN(fwdynhdr) != info->dynamic_hdr_len) { -+ rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); -+ return -EINVAL; -+ } -+ } else { -+ info->hdr_len = base_hdr_len; -+ info->dynamic_hdr_len = 0; -+ } - - bin = fw + info->hdr_len; - -@@ -534,7 +550,7 @@ int rtw89_fw_download(struct rtw89_dev * - goto fwdl_err; - } - -- ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len); -+ ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len - info.dynamic_hdr_len); - if (ret) { - ret = -EBUSY; - goto fwdl_err; ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -176,6 +176,8 @@ struct rtw89_fw_hdr_section_info { - struct rtw89_fw_bin_info { - u8 section_num; - u32 hdr_len; -+ bool dynamic_hdr_en; -+ u32 dynamic_hdr_len; - struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM]; - }; - -@@ -495,6 +497,8 @@ static inline void RTW89_SET_EDCA_PARAM( - le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 16)) - #define GET_FW_HDR_SUBINDEX(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(31, 24)) -+#define GET_FW_HDR_LEN(fwhdr) \ -+ le32_get_bits(*((const __le32 *)(fwhdr) + 3), GENMASK(23, 16)) - #define GET_FW_HDR_MONTH(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(7, 0)) - #define GET_FW_HDR_DATE(fwhdr) \ -@@ -507,8 +511,16 @@ static inline void RTW89_SET_EDCA_PARAM( - le32_get_bits(*((const __le32 *)(fwhdr) + 5), GENMASK(31, 0)) - #define GET_FW_HDR_SEC_NUM(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 6), GENMASK(15, 8)) -+#define GET_FW_HDR_DYN_HDR(fwhdr) \ -+ le32_get_bits(*((const __le32 *)(fwhdr) + 7), BIT(16)) - #define GET_FW_HDR_CMD_VERSERION(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 7), GENMASK(31, 24)) -+ -+#define GET_FW_DYNHDR_LEN(fwdynhdr) \ -+ le32_get_bits(*((const __le32 *)(fwdynhdr)), GENMASK(31, 0)) -+#define GET_FW_DYNHDR_COUNT(fwdynhdr) \ -+ le32_get_bits(*((const __le32 *)(fwdynhdr) + 1), GENMASK(31, 0)) -+ - static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val) - { - le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0)); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-045-wifi-rtw89-declare-support-bands-with-const.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-045-wifi-rtw89-declare-support-bands-with-const.patch deleted file mode 100644 index 927d7e06e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-045-wifi-rtw89-declare-support-bands-with-const.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a29dba478b6f4e8d3fbfe0b2f097cad1e0b93cf6 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 20 Oct 2022 13:27:01 +0800 -Subject: [PATCH 045/149] wifi: rtw89: declare support bands with const - -They are just default declarations and we won't modify them directly. -Instead, we actually do moification on their memdup now. So, they -should be declared with const. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221020052702.33988-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -171,7 +171,7 @@ bool rtw89_ra_report_to_bitrate(struct r - return true; - } - --static struct ieee80211_supported_band rtw89_sband_2ghz = { -+static const struct ieee80211_supported_band rtw89_sband_2ghz = { - .band = NL80211_BAND_2GHZ, - .channels = rtw89_channels_2ghz, - .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), -@@ -181,7 +181,7 @@ static struct ieee80211_supported_band r - .vht_cap = {0}, - }; - --static struct ieee80211_supported_band rtw89_sband_5ghz = { -+static const struct ieee80211_supported_band rtw89_sband_5ghz = { - .band = NL80211_BAND_5GHZ, - .channels = rtw89_channels_5ghz, - .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), -@@ -193,7 +193,7 @@ static struct ieee80211_supported_band r - .vht_cap = {0}, - }; - --static struct ieee80211_supported_band rtw89_sband_6ghz = { -+static const struct ieee80211_supported_band rtw89_sband_6ghz = { - .band = NL80211_BAND_6GHZ, - .channels = rtw89_channels_6ghz, - .n_channels = ARRAY_SIZE(rtw89_channels_6ghz), diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-046-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-046-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch deleted file mode 100644 index 662d90ae3..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-046-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e69ae29e00cec66609bd555398aa4f59f2a9ae84 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 20 Oct 2022 13:27:02 +0800 -Subject: [PATCH 046/149] wifi: rtw89: 8852c: make table of RU mask constant - -This table must be constant, so change it as expectation. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221020052702.33988-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -1683,12 +1683,12 @@ static void rtw8852c_set_channel_bb(stru - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -+ static const u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0, -+ B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1}; - struct rtw89_hal *hal = &rtwdev->hal; - bool cck_en = chan->band_type == RTW89_BAND_2G; - u8 pri_ch_idx = chan->pri_ch_idx; - u32 mask, reg; -- u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0, -- B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1}; - u8 ntx_path; - - if (chan->band_type == RTW89_BAND_2G) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-047-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-047-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch deleted file mode 100644 index 9292ebea7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-047-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 25f49617b5c9c9afa829030f14606be6351d4771 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Fri, 21 Oct 2022 17:16:01 +0800 -Subject: [PATCH 047/149] wifi: rtw89: add BW info for both TX and RX in - phy_info - -In order to debug performance issue intuitively, add bandwidth information -into debugfs entry phy_info. After applying this patch, it looks like: - - TX rate [0]: HE 2SS MCS-11 GI:0.8 BW:80 (hw_rate=0x19b) ==> agg_wait=1 (3500) - RX rate [0]: HE 2SS MCS-9 GI:0.8 BW:80 (hw_rate=0x199) - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221021091601.39884-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -51,6 +51,22 @@ struct rtw89_debugfs_priv { - }; - }; - -+static const u16 rtw89_rate_info_bw_to_mhz_map[] = { -+ [RATE_INFO_BW_20] = 20, -+ [RATE_INFO_BW_40] = 40, -+ [RATE_INFO_BW_80] = 80, -+ [RATE_INFO_BW_160] = 160, -+ [RATE_INFO_BW_320] = 320, -+}; -+ -+static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw) -+{ -+ if (bw < ARRAY_SIZE(rtw89_rate_info_bw_to_mhz_map)) -+ return rtw89_rate_info_bw_to_mhz_map[bw]; -+ -+ return 0; -+} -+ - static int rtw89_debugfs_single_show(struct seq_file *m, void *v) - { - struct rtw89_debugfs_priv *debugfs_priv = m->private; -@@ -2386,6 +2402,7 @@ static void rtw89_sta_info_get_iter(void - else - seq_printf(m, "Legacy %d", rate->legacy); - seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : ""); -+ seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); - seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate); - seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait, - sta->deflink.agg.max_rc_amsdu_len); -@@ -2411,6 +2428,7 @@ static void rtw89_sta_info_get_iter(void - he_gi_str[rate->he_gi] : "N/A"); - break; - } -+ seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); - seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate); - - rssi = ewma_rssi_read(&rtwsta->avg_rssi); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-048-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-048-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch deleted file mode 100644 index fb9a70341..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-048-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 46245bc42aff5e67b0498fa365a4baeaaaaeda86 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 21 Oct 2022 17:18:28 +0800 -Subject: [PATCH 048/149] wifi: rtw89: check if sta's mac_id is valid under - AP/TDLS - -Add boundary check of mac_id when adding sta under AP/TDLS. -And, return -ENOSPC if the acquired mac_id is invalid. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221021091828.40157-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2413,6 +2413,8 @@ int rtw89_core_sta_add(struct rtw89_dev - } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtwsta->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map, - RTW89_MAX_MAC_ID_NUM); -+ if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) -+ return -ENOSPC; - } - - return 0; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-049-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-049-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch deleted file mode 100644 index 3b4ca5451..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-049-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch +++ /dev/null @@ -1,102 +0,0 @@ -From d9112042d9942648825d3ebe837dd33dbd7c6ddb Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Thu, 27 Oct 2022 13:27:01 +0800 -Subject: [PATCH 049/149] wifi: rtw89: collect and send RF parameters to - firmware for WoWLAN - -For WoWLAN mode, we only collect and send RF parameters to Firmware -without writing RF registers. So we add one function to practice it. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 +- - drivers/net/wireless/realtek/rtw89/phy.c | 31 +++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/phy.h | 2 +- - 3 files changed, 31 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2962,7 +2962,7 @@ int rtw89_core_start(struct rtw89_dev *r - return ret; - - rtw89_phy_init_bb_reg(rtwdev); -- rtw89_phy_init_rf_reg(rtwdev); -+ rtw89_phy_init_rf_reg(rtwdev, false); - - rtw89_btc_ntfy_init(rtwdev, BTC_MODE_NORMAL); - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -801,6 +801,11 @@ bool rtw89_phy_write_rf_v1(struct rtw89_ - } - EXPORT_SYMBOL(rtw89_phy_write_rf_v1); - -+static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev) -+{ -+ return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1; -+} -+ - static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx) - { -@@ -1123,6 +1128,24 @@ out: - return ret; - } - -+static void rtw89_phy_config_rf_reg_noio(struct rtw89_dev *rtwdev, -+ const struct rtw89_reg2_def *reg, -+ enum rtw89_rf_path rf_path, -+ void *extra_data) -+{ -+ u32 addr = reg->addr; -+ -+ if (addr == 0xfe || addr == 0xfd || addr == 0xfc || addr == 0xfb || -+ addr == 0xfa || addr == 0xf9) -+ return; -+ -+ if (rtw89_chip_rf_v1(rtwdev) && addr < 0x100) -+ return; -+ -+ rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, -+ (struct rtw89_fw_h2c_rf_reg_info *)extra_data); -+} -+ - static void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, - const struct rtw89_reg2_def *reg, - enum rtw89_rf_path rf_path, -@@ -1335,7 +1358,7 @@ static u32 rtw89_phy_nctl_poll(struct rt - return rtw89_phy_read32(rtwdev, 0x8080); - } - --void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev) -+void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio) - { - void (*config)(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, - enum rtw89_rf_path rf_path, void *data); -@@ -1351,7 +1374,11 @@ void rtw89_phy_init_rf_reg(struct rtw89_ - for (path = RF_PATH_A; path < chip->rf_path_num; path++) { - rf_table = chip->rf_table[path]; - rf_reg_info->rf_path = rf_table->rf_path; -- config = rf_table->config ? rf_table->config : rtw89_phy_config_rf_reg; -+ if (noio) -+ config = rtw89_phy_config_rf_reg_noio; -+ else -+ config = rf_table->config ? rf_table->config : -+ rtw89_phy_config_rf_reg; - rtw89_phy_init_reg(rtwdev, rf_table, config, (void *)rf_reg_info); - if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info)) - rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n", ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -500,7 +500,7 @@ bool rtw89_phy_write_rf(struct rtw89_dev - bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, - u32 addr, u32 mask, u32 data); - void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); --void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev); -+void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio); - void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, - const struct rtw89_reg2_def *reg, - enum rtw89_rf_path rf_path, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-050-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-050-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch deleted file mode 100644 index b1ec800ff..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-050-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 5f05bdb0a770b5d03d3453c0b0743bb3dcd1a2ba Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Thu, 27 Oct 2022 13:27:02 +0800 -Subject: [PATCH 050/149] wifi: rtw89: move enable_cpu/disable_cpu into - fw_download - -For WoWLAN mode, we need to download WoWLAN firmware by calling -fw_download(). Another, to disable/enable WiFi CPU is needed before -calling fw_download. Since Firmware runs on WiFi CPU, it is intuitive -to combine enable_cpu/disable_cpu functions into fw_download. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 5 +++++ - drivers/net/wireless/realtek/rtw89/mac.c | 10 ++-------- - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - 3 files changed, 9 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -531,6 +531,11 @@ int rtw89_fw_download(struct rtw89_dev * - u8 val; - int ret; - -+ rtw89_mac_disable_cpu(rtwdev); -+ ret = rtw89_mac_enable_cpu(rtwdev, 0, true); -+ if (ret) -+ return ret; -+ - if (!fw || !len) { - rtw89_err(rtwdev, "fw type %d isn't recognized\n", type); - return -ENOENT; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3114,7 +3114,7 @@ static void rtw89_disable_fw_watchdog(st - rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL); - } - --static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) -+void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) - { - clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); - -@@ -3129,8 +3129,7 @@ static void rtw89_mac_disable_cpu(struct - rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); - } - --static int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, -- bool dlfw) -+int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) - { - u32 val; - int ret; -@@ -3269,11 +3268,6 @@ int rtw89_mac_partial_init(struct rtw89_ - return ret; - } - -- rtw89_mac_disable_cpu(rtwdev); -- ret = rtw89_mac_enable_cpu(rtwdev, 0, true); -- if (ret) -- return ret; -- - ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL); - if (ret) - return ret; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -815,6 +815,8 @@ int rtw89_mac_port_update(struct rtw89_d - void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); - int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); -+void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev); -+int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw); - int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); - int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-051-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-051-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch deleted file mode 100644 index 7e8aa744f..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-051-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 7a68ec3da79ea702fdeeb94c31f743fd37446a32 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Thu, 27 Oct 2022 13:27:03 +0800 -Subject: [PATCH 051/149] wifi: rtw89: add function to adjust and restore PLE - quota - -PLE RX quota, which is the setting of RX buffer, is needed to be adjusted -dynamically for WoWLAN mode, and restored when back to normal mode. -The action is not needed for rtw8852c chip. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 32 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 4 +++ - 4 files changed, 39 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2389,6 +2389,7 @@ enum rtw89_dma_ch { - enum rtw89_qta_mode { - RTW89_QTA_SCC, - RTW89_QTA_DLFW, -+ RTW89_QTA_WOW, - - /* keep last */ - RTW89_QTA_INVALID, ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1306,6 +1306,8 @@ const struct rtw89_mac_size_set rtw89_ma - .ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,}, - /* PCIE 64 */ - .ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,}, -+ /* 8852A PCIE WOW */ -+ .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, - }; - EXPORT_SYMBOL(rtw89_mac_size); - -@@ -1476,6 +1478,36 @@ static void ple_quota_cfg(struct rtw89_d - SET_QUOTA(tx_rpt, PLE, 11); - } - -+int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow) -+{ -+ const struct rtw89_ple_quota *min_cfg, *max_cfg; -+ const struct rtw89_dle_mem *cfg; -+ u32 val; -+ -+ if (rtwdev->chip->chip_id == RTL8852C) -+ return 0; -+ -+ if (rtwdev->mac.qta_mode != RTW89_QTA_SCC) { -+ rtw89_err(rtwdev, "[ERR]support SCC mode only\n"); -+ return -EINVAL; -+ } -+ -+ if (wow) -+ cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_WOW); -+ else -+ cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_SCC); -+ if (!cfg) { -+ rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); -+ return -EINVAL; -+ } -+ -+ min_cfg = cfg->ple_min_qt; -+ max_cfg = cfg->ple_max_qt; -+ SET_QUOTA(cma0_dma, PLE, 6); -+ SET_QUOTA(cma1_dma, PLE, 7); -+ -+ return 0; -+} - #undef SET_QUOTA - - static void dle_quota_cfg(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -719,6 +719,7 @@ struct rtw89_mac_size_set { - const struct rtw89_ple_quota ple_qt46; - const struct rtw89_ple_quota ple_qt47; - const struct rtw89_ple_quota ple_qt58; -+ const struct rtw89_ple_quota ple_qt_52a_wow; - }; - - extern const struct rtw89_mac_size_set rtw89_mac_size; -@@ -1026,5 +1027,6 @@ void rtw89_mac_pkt_drop_vif(struct rtw89 - u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); - int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, - struct rtw89_cpuio_ctrl *ctrl_para, bool wd); -+int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -48,6 +48,10 @@ static const struct rtw89_dle_mem rtw885 - &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, - &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, - &rtw89_mac_size.ple_qt5}, -+ [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size0, -+ &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, -+ &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, -+ &rtw89_mac_size.ple_qt_52a_wow}, - [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, - &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, - &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-052-wifi-rtw89-add-drop-tx-packet-function.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-052-wifi-rtw89-add-drop-tx-packet-function.patch deleted file mode 100644 index 7ad82065b..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-052-wifi-rtw89-add-drop-tx-packet-function.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 41d567699283b86ce7443a5bf07114f1bde8e203 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Thu, 27 Oct 2022 13:27:04 +0800 -Subject: [PATCH 052/149] wifi: rtw89: add drop tx packet function - -When entering WoWLAN mode, we need to drop all transmit packets, -including those in mac buffer, to avoid memory leakage, so implement -the drop_tx function. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 + - drivers/net/wireless/realtek/rtw89/fw.c | 9 +++ - drivers/net/wireless/realtek/rtw89/fw.h | 20 +++++ - drivers/net/wireless/realtek/rtw89/mac.c | 75 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 13 ++++ - drivers/net/wireless/realtek/rtw89/reg.h | 13 ++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + - 8 files changed, 137 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2624,6 +2624,8 @@ struct rtw89_chip_info { - u32 rsvd_ple_ofst; - const struct rtw89_hfc_param_ini *hfc_param_ini; - const struct rtw89_dle_mem *dle_mem; -+ u8 wde_qempty_acq_num; -+ u8 wde_qempty_mgq_sel; - u32 rf_base_addr[2]; - u8 support_chanctx_num; - u8 support_bands; -@@ -2949,6 +2951,7 @@ struct rtw89_pkt_drop_params { - u8 port; - u8 mbssid; - bool tf_trs; -+ u32 macid_band_sel[4]; - }; - - struct rtw89_pkt_stat { ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2902,6 +2902,7 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_d - case RTW89_PKT_DROP_SEL_MACID_BK_ONCE: - case RTW89_PKT_DROP_SEL_MACID_VI_ONCE: - case RTW89_PKT_DROP_SEL_MACID_VO_ONCE: -+ case RTW89_PKT_DROP_SEL_BAND_ONCE: - break; - default: - rtw89_debug(rtwdev, RTW89_DBG_FW, -@@ -2917,6 +2918,14 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_d - RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port); - RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid); - RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs); -+ RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data, -+ params->macid_band_sel[0]); -+ RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data, -+ params->macid_band_sel[1]); -+ RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data, -+ params->macid_band_sel[2]); -+ RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data, -+ params->macid_band_sel[3]); - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, - H2C_CAT_MAC, ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -1873,6 +1873,26 @@ static inline void RTW89_SET_FWCMD_PKT_D - le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(15, 8)); - } - -+static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 4, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 5, val, GENMASK(31, 0)); -+} -+ - enum rtw89_btc_btf_h2c_class { - BTFC_SET = 0x10, - BTFC_GET = 0x11, ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1335,6 +1335,60 @@ static const struct rtw89_dle_mem *get_d - return cfg; - } - -+static bool mac_is_txq_empty(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_mac_dle_dfi_qempty qempty; -+ u32 qnum, qtmp, val32, msk32; -+ int i, j, ret; -+ -+ qnum = rtwdev->chip->wde_qempty_acq_num; -+ qempty.dle_type = DLE_CTRL_TYPE_WDE; -+ -+ for (i = 0; i < qnum; i++) { -+ qempty.grpsel = i; -+ ret = dle_dfi_qempty(rtwdev, &qempty); -+ if (ret) { -+ rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret); -+ return false; -+ } -+ qtmp = qempty.qempty; -+ for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) { -+ val32 = FIELD_GET(QEMP_ACQ_GRP_QSEL_MASK, qtmp); -+ if (val32 != QEMP_ACQ_GRP_QSEL_MASK) -+ return false; -+ qtmp >>= QEMP_ACQ_GRP_QSEL_SH; -+ } -+ } -+ -+ qempty.grpsel = rtwdev->chip->wde_qempty_mgq_sel; -+ ret = dle_dfi_qempty(rtwdev, &qempty); -+ if (ret) { -+ rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret); -+ return false; -+ } -+ msk32 = B_CMAC0_MGQ_NORMAL | B_CMAC0_MGQ_NO_PWRSAV | B_CMAC0_CPUMGQ; -+ if ((qempty.qempty & msk32) != msk32) -+ return false; -+ -+ if (rtwdev->dbcc_en) { -+ msk32 |= B_CMAC1_MGQ_NORMAL | B_CMAC1_MGQ_NO_PWRSAV | B_CMAC1_CPUMGQ; -+ if ((qempty.qempty & msk32) != msk32) -+ return false; -+ } -+ -+ msk32 = B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU | -+ B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_PLE_EMPTY_QTA_DMAC_H2C | -+ B_AX_WDE_EMPTY_QUE_OTHERS | B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | -+ B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | B_AX_PLE_EMPTY_QTA_DMAC_CPUIO | -+ B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_HIF | -+ B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | -+ B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL | -+ B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX; -+ val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0); -+ -+ return (val32 & msk32) == msk32; -+} -+ - static inline u32 dle_used_size(const struct rtw89_dle_size *wde, - const struct rtw89_dle_size *ple) - { -@@ -4891,3 +4945,24 @@ void rtw89_mac_pkt_drop_vif(struct rtw89 - rtw89_mac_pkt_drop_vif_iter, - rtwvif); - } -+ -+int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, -+ enum rtw89_mac_idx band) -+{ -+ struct rtw89_pkt_drop_params params = {0}; -+ bool empty; -+ int i, ret = 0, try_cnt = 3; -+ -+ params.mac_band = band; -+ params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE; -+ -+ for (i = 0; i < try_cnt; i++) { -+ ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50, -+ 50000, false, rtwdev); -+ if (ret) -+ rtw89_fw_h2c_pkt_drop(rtwdev, ¶ms); -+ else -+ return 0; -+ } -+ return ret; -+} ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -420,6 +420,17 @@ enum rtw89_mac_bf_rrsc_rate { - #define S_AX_PLE_PAGE_SEL_128 1 - #define S_AX_PLE_PAGE_SEL_256 2 - -+#define B_CMAC0_MGQ_NORMAL BIT(2) -+#define B_CMAC0_MGQ_NO_PWRSAV BIT(3) -+#define B_CMAC0_CPUMGQ BIT(4) -+#define B_CMAC1_MGQ_NORMAL BIT(10) -+#define B_CMAC1_MGQ_NO_PWRSAV BIT(11) -+#define B_CMAC1_CPUMGQ BIT(12) -+ -+#define QEMP_ACQ_GRP_MACID_NUM 8 -+#define QEMP_ACQ_GRP_QSEL_SH 4 -+#define QEMP_ACQ_GRP_QSEL_MASK 0xF -+ - #define SDIO_LOCAL_BASE_ADDR 0x80000000 - - #define PWR_CMD_WRITE 0 -@@ -1028,5 +1039,7 @@ u16 rtw89_mac_dle_buf_req(struct rtw89_d - int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, - struct rtw89_cpuio_ctrl *ctrl_para, bool wd); - int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); -+int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, -+ enum rtw89_mac_idx band); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -545,6 +545,19 @@ - #define B_AX_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) - #define B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) - -+#define R_AX_DLE_EMPTY1 0x8434 -+#define B_AX_PLE_EMPTY_QTA_DMAC_WDRLS BIT(20) -+#define B_AX_PLE_EMPTY_QTA_CMAC1_DMA_BBRPT BIT(19) -+#define B_AX_PLE_EMPTY_QTA_CMAC1_DMA_RX BIT(18) -+#define B_AX_PLE_EMPTY_QTA_CMAC0_DMA_RX BIT(17) -+#define B_AX_PLE_EMPTY_QTA_DMAC_C2H BIT(16) -+#define B_AX_PLE_EMPTY_QUE_DMAC_PLRLS BIT(5) -+#define B_AX_PLE_EMPTY_QUE_DMAC_CPUIO BIT(4) -+#define B_AX_PLE_EMPTY_QUE_DMAC_SEC_RX BIT(3) -+#define B_AX_PLE_EMPTY_QUE_DMAC_MPDU_RX BIT(2) -+#define B_AX_PLE_EMPTY_QUE_DMAC_HDP BIT(1) -+#define B_AX_WDE_EMPTY_QUE_DMAC_WDRLS BIT(0) -+ - #define R_AX_DMAC_ERR_IMR 0x8520 - #define B_AX_DLE_CPUIO_ERR_INT_EN BIT(10) - #define B_AX_APB_BRIDGE_ERR_INT_EN BIT(9) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2049,6 +2049,8 @@ const struct rtw89_chip_info rtw8852a_ch - .rsvd_ple_ofst = 0x6f800, - .hfc_param_ini = rtw8852a_hfc_param_ini_pcie, - .dle_mem = rtw8852a_dle_mem_pcie, -+ .wde_qempty_acq_num = 16, -+ .wde_qempty_mgq_sel = 16, - .rf_base_addr = {0xc000, 0xd000}, - .pwr_on_seq = pwr_on_seq_8852a, - .pwr_off_seq = pwr_off_seq_8852a, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2855,6 +2855,8 @@ const struct rtw89_chip_info rtw8852c_ch - .rsvd_ple_ofst = 0x6f800, - .hfc_param_ini = rtw8852c_hfc_param_ini_pcie, - .dle_mem = rtw8852c_dle_mem_pcie, -+ .wde_qempty_acq_num = 16, -+ .wde_qempty_mgq_sel = 16, - .rf_base_addr = {0xe000, 0xf000}, - .pwr_on_seq = NULL, - .pwr_off_seq = NULL, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-053-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-053-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch deleted file mode 100644 index a76fd0b00..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-053-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch +++ /dev/null @@ -1,509 +0,0 @@ -From ee88d748f1ace450cc0e8ca6a93cb11e7e8d6ad9 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Thu, 27 Oct 2022 13:27:05 +0800 -Subject: [PATCH 053/149] wifi: rtw89: add related H2C for WoWLAN mode - -In this patch we define some H2C, which will be called during suspend -flow, to enable WoWLAN function provided by WoWLAN firmware. - -These H2C includes keep alive used to send null packet to AP periodically -to avoid being disconnected by AP, disconnect detection used to configure -how we check if AP is offline, wake up control used to decide which WiFi -events could trigger resume flow, and global control used to enable WoWLAN -function. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 30 +++ - drivers/net/wireless/realtek/rtw89/fw.c | 229 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 160 +++++++++++++++ - 3 files changed, 419 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -477,6 +477,20 @@ enum rtw89_regulation_type { - RTW89_REGD_NUM, - }; - -+enum rtw89_fw_pkt_ofld_type { -+ RTW89_PKT_OFLD_TYPE_PROBE_RSP = 0, -+ RTW89_PKT_OFLD_TYPE_PS_POLL = 1, -+ RTW89_PKT_OFLD_TYPE_NULL_DATA = 2, -+ RTW89_PKT_OFLD_TYPE_QOS_NULL = 3, -+ RTW89_PKT_OFLD_TYPE_CTS2SELF = 4, -+ RTW89_PKT_OFLD_TYPE_ARP_RSP = 5, -+ RTW89_PKT_OFLD_TYPE_NDP = 6, -+ RTW89_PKT_OFLD_TYPE_EAPOL_KEY = 7, -+ RTW89_PKT_OFLD_TYPE_SA_QUERY = 8, -+ RTW89_PKT_OFLD_TYPE_PROBE_REQ = 12, -+ RTW89_PKT_OFLD_TYPE_NUM, -+}; -+ - struct rtw89_txpwr_byrate { - s8 cck[RTW89_RATE_CCK_MAX]; - s8 ofdm[RTW89_RATE_OFDM_MAX]; -@@ -636,6 +650,13 @@ enum rtw89_sc_offset { - RTW89_SC_40_LOWER = 10, - }; - -+enum rtw89_wow_flags { -+ RTW89_WOW_FLAG_EN_MAGIC_PKT, -+ RTW89_WOW_FLAG_EN_REKEY_PKT, -+ RTW89_WOW_FLAG_EN_DISCONNECT, -+ RTW89_WOW_FLAG_NUM, -+}; -+ - struct rtw89_chan { - u8 channel; - u8 primary_channel; -@@ -3453,6 +3474,13 @@ struct rtw89_phy_efuse_gain { - s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ - }; - -+struct rtw89_wow_param { -+ struct ieee80211_vif *wow_vif; -+ DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); -+ u8 pattern_cnt; -+ struct list_head pkt_list; -+}; -+ - struct rtw89_dev { - struct ieee80211_hw *hw; - struct device *dev; -@@ -3541,6 +3569,8 @@ struct rtw89_dev { - enum rtw89_ps_mode ps_mode; - bool lps_enabled; - -+ struct rtw89_wow_param wow; -+ - /* napi structure */ - struct net_device netdev; - struct napi_struct napi; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -869,6 +869,56 @@ fail: - return ret; - } - -+static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ enum rtw89_fw_pkt_ofld_type type, -+ u8 *id) -+{ -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_pktofld_info *info; -+ struct sk_buff *skb; -+ int ret; -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ -+ switch (type) { -+ case RTW89_PKT_OFLD_TYPE_PS_POLL: -+ skb = ieee80211_pspoll_get(rtwdev->hw, vif); -+ break; -+ case RTW89_PKT_OFLD_TYPE_PROBE_RSP: -+ skb = ieee80211_proberesp_get(rtwdev->hw, vif); -+ break; -+ case RTW89_PKT_OFLD_TYPE_NULL_DATA: -+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false); -+ break; -+ case RTW89_PKT_OFLD_TYPE_QOS_NULL: -+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true); -+ break; -+ default: -+ goto err; -+ } -+ -+ if (!skb) -+ goto err; -+ -+ list_add_tail(&info->list, &rtw_wow->pkt_list); -+ ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); -+ kfree_skb(skb); -+ -+ if (ret) -+ return ret; -+ -+ *id = info->id; -+ return 0; -+ -+err: -+ kfree(info); -+ return -ENOMEM; -+} -+ - #define H2C_GENERAL_PKT_LEN 6 - #define H2C_GENERAL_PKT_ID_UND 0xff - int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) -@@ -2945,3 +2995,182 @@ fail: - dev_kfree_skb_any(skb); - return ret; - } -+ -+#define H2C_KEEP_ALIVE_LEN 4 -+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool enable) -+{ -+ struct sk_buff *skb; -+ u8 pkt_id = 0; -+ int ret; -+ -+ if (enable) { -+ ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif, -+ RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id); -+ if (ret) -+ return -EPERM; -+ } -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_KEEP_ALIVE_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_KEEP_ALIVE_LEN); -+ -+ RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable); -+ RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id); -+ RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5); -+ RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MAC_WOW, -+ H2C_FUNC_KEEP_ALIVE, 0, 1, -+ H2C_KEEP_ALIVE_LEN); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+#define H2C_DISCONNECT_DETECT_LEN 8 -+int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool enable) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct sk_buff *skb; -+ u8 macid = rtwvif->mac_id; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_DISCONNECT_DETECT_LEN); -+ -+ if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { -+ RTW89_SET_DISCONNECT_DETECT_ENABLE(skb->data, enable); -+ RTW89_SET_DISCONNECT_DETECT_DISCONNECT(skb->data, !enable); -+ RTW89_SET_DISCONNECT_DETECT_MAC_ID(skb->data, macid); -+ RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(skb->data, 100); -+ RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(skb->data, 5); -+ } -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MAC_WOW, -+ H2C_FUNC_DISCONNECT_DETECT, 0, 1, -+ H2C_DISCONNECT_DETECT_LEN); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+#define H2C_WOW_GLOBAL_LEN 8 -+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool enable) -+{ -+ struct sk_buff *skb; -+ u8 macid = rtwvif->mac_id; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_WOW_GLOBAL_LEN); -+ -+ RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable); -+ RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MAC_WOW, -+ H2C_FUNC_WOW_GLOBAL, 0, 1, -+ H2C_WOW_GLOBAL_LEN); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+#define H2C_WAKEUP_CTRL_LEN 4 -+int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ bool enable) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct sk_buff *skb; -+ u8 macid = rtwvif->mac_id; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_WAKEUP_CTRL_LEN); -+ -+ if (rtw_wow->pattern_cnt) -+ RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable); -+ if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) -+ RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable); -+ if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) -+ RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable); -+ -+ RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MAC_WOW, -+ H2C_FUNC_WAKEUP_CTRL, 0, 1, -+ H2C_WAKEUP_CTRL_LEN); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -1893,6 +1893,146 @@ static inline void RTW89_SET_FWCMD_PKT_D - le32p_replace_bits((__le32 *)cmd + 5, val, GENMASK(31, 0)); - } - -+static inline void RTW89_SET_KEEP_ALIVE_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_KEEP_ALIVE_PERIOD(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(24, 16)); -+} -+ -+static inline void RTW89_SET_KEEP_ALIVE_MACID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_EN(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(1)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_DISCONNECT(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(2)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_MAC_ID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_CHECK_PERIOD(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_TRY_PKT_COUNT(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); -+} -+ -+static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_LIMIT(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_DROP_ALL_PKT(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(1)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_RX_PARSE_AFTER_WAKE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(2)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_WAKE_BAR_PULLED(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(3)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_MAC_ID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_PAIRWISE_SEC_ALGO(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_GROUP_SEC_ALGO(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); -+} -+ -+static inline void RTW89_SET_WOW_GLOBAL_REMOTECTRL_INFO_CONTENT(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(1)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_HW_UNICAST_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(2)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_FW_UNICAST_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(3)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(4)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_REKEYP_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(5)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_EAP_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(6)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_ALL_DATA_ENABLE(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(7)); -+} -+ -+static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); -+} -+ - enum rtw89_btc_btf_h2c_class { - BTFC_SET = 0x10, - BTFC_GET = 0x11, -@@ -2709,6 +2849,14 @@ struct rtw89_fw_h2c_rf_reg_info { - #define H2C_FUNC_LOG_CFG 0x0 - #define H2C_FUNC_MAC_GENERAL_PKT 0x1 - -+/* CLASS 1 - WOW */ -+#define H2C_CL_MAC_WOW 0x1 -+#define H2C_FUNC_KEEP_ALIVE 0x0 -+#define H2C_FUNC_DISCONNECT_DETECT 0x1 -+#define H2C_FUNC_WOW_GLOBAL 0x2 -+#define H2C_FUNC_WAKEUP_CTRL 0x8 -+#define H2C_FUNC_WOW_CAM_UPD 0xC -+ - /* CLASS 2 - PS */ - #define H2C_CL_MAC_PS 0x2 - #define H2C_FUNC_MAC_LPS_PARM 0x0 -@@ -2878,6 +3026,18 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_de - u8 act, u8 noa_id); - int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, - bool en); -+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool enable); -+int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool enable); -+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool enable); -+int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool enable); -+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool enable); -+int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool enable); - - static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) - { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-054-wifi-rtw89-add-WoWLAN-function-support.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-054-wifi-rtw89-add-WoWLAN-function-support.patch deleted file mode 100644 index de85cd97f..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-054-wifi-rtw89-add-WoWLAN-function-support.patch +++ /dev/null @@ -1,1158 +0,0 @@ -From 19e28c7fcc7408be8479f91d47146245c8be293e Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Thu, 27 Oct 2022 13:27:06 +0800 -Subject: [PATCH 054/149] wifi: rtw89: add WoWLAN function support - -WoWLAN is a feature which allows devices to be woken up from suspend -state through WLAN events. - -When user enables WoWLAN feature and then let the device enter suspend -state, WoWLAN firmware will be loaded by the driver and periodically -monitors WiFi packets. Power consumption of WiFi chip will be reduced -in this state. - -We now implement WoWLAN function in rtw8852ae and rtw8852ce chip. -Currently supported WLAN events include receiving magic packet, -rekey packet and deauth packet, and disconnecting from AP. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/Makefile | 2 + - drivers/net/wireless/realtek/rtw89/core.c | 8 + - drivers/net/wireless/realtek/rtw89/core.h | 77 ++- - drivers/net/wireless/realtek/rtw89/debug.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 18 +- - drivers/net/wireless/realtek/rtw89/mac.h | 14 + - drivers/net/wireless/realtek/rtw89/mac80211.c | 55 ++ - drivers/net/wireless/realtek/rtw89/pci.c | 23 +- - drivers/net/wireless/realtek/rtw89/ps.c | 2 +- - drivers/net/wireless/realtek/rtw89/ps.h | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 8 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 9 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 9 + - drivers/net/wireless/realtek/rtw89/wow.c | 633 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/wow.h | 21 + - 15 files changed, 874 insertions(+), 7 deletions(-) - create mode 100644 drivers/net/wireless/realtek/rtw89/wow.c - create mode 100644 drivers/net/wireless/realtek/rtw89/wow.h - ---- a/drivers/net/wireless/realtek/rtw89/Makefile -+++ b/drivers/net/wireless/realtek/rtw89/Makefile -@@ -15,6 +15,8 @@ rtw89_core-y += core.o \ - chan.o \ - ser.o - -+rtw89_core-$(CPTCFG_PM) += wow.o -+ - obj-$(CPTCFG_RTW89_8852A) += rtw89_8852a.o - rtw89_8852a-objs := rtw8852a.o \ - rtw8852a_table.o \ ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2204,6 +2204,9 @@ static void rtw89_track_work(struct work - track_work.work); - bool tfc_changed; - -+ if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags)) -+ return; -+ - mutex_lock(&rtwdev->mutex); - - if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) -@@ -3042,6 +3045,7 @@ int rtw89_core_init(struct rtw89_dev *rt - continue; - INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); - } -+ INIT_LIST_HEAD(&rtwdev->wow.pkt_list); - INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); - INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); - INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); -@@ -3276,6 +3280,10 @@ static int rtw89_core_register_hw(struct - hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID; - hw->wiphy->max_scan_ie_len = RTW89_SCANOFLD_MAX_IE_LEN; - -+#ifdef CONFIG_PM -+ hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; -+#endif -+ - hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); - hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); - hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -178,7 +178,9 @@ enum rtw89_upd_mode { - RTW89_ROLE_REMOVE, - RTW89_ROLE_TYPE_CHANGE, - RTW89_ROLE_INFO_CHANGE, -- RTW89_ROLE_CON_DISCONN -+ RTW89_ROLE_CON_DISCONN, -+ RTW89_ROLE_BAND_SW, -+ RTW89_ROLE_FW_RESTORE, - }; - - enum rtw89_self_role { -@@ -2307,6 +2309,16 @@ struct rtw89_hci_ops { - */ - void (*recovery_start)(struct rtw89_dev *rtwdev); - void (*recovery_complete)(struct rtw89_dev *rtwdev); -+ -+ void (*ctrl_txdma_ch)(struct rtw89_dev *rtwdev, bool enable); -+ void (*ctrl_txdma_fw_ch)(struct rtw89_dev *rtwdev, bool enable); -+ void (*ctrl_trxhci)(struct rtw89_dev *rtwdev, bool enable); -+ int (*poll_txdma_ch)(struct rtw89_dev *rtwdev); -+ void (*clr_idx_all)(struct rtw89_dev *rtwdev); -+ void (*clear)(struct rtw89_dev *rtwdev, struct pci_dev *pdev); -+ void (*disable_intr)(struct rtw89_dev *rtwdev); -+ void (*enable_intr)(struct rtw89_dev *rtwdev); -+ int (*rst_bdram)(struct rtw89_dev *rtwdev); - }; - - struct rtw89_hci_info { -@@ -2748,6 +2760,7 @@ struct rtw89_chip_info { - const struct rtw89_imr_info *imr_info; - const struct rtw89_rrsr_cfgs *rrsr_cfgs; - u32 dma_ch_mask; -+ const struct wiphy_wowlan_support *wowlan_stub; - }; - - union rtw89_bus_info { -@@ -2944,6 +2957,8 @@ enum rtw89_flags { - RTW89_FLAG_LOW_POWER_MODE, - RTW89_FLAG_INACTIVE_PS, - RTW89_FLAG_CRASH_SIMULATING, -+ RTW89_FLAG_WOWLAN, -+ RTW89_FLAG_FORBIDDEN_TRACK_WROK, - - NUM_OF_RTW89_FLAGS, - }; -@@ -3653,6 +3668,66 @@ static inline void rtw89_hci_recovery_co - rtwdev->hci.ops->recovery_complete(rtwdev); - } - -+static inline void rtw89_hci_enable_intr(struct rtw89_dev *rtwdev) -+{ -+ if (rtwdev->hci.ops->enable_intr) -+ rtwdev->hci.ops->enable_intr(rtwdev); -+} -+ -+static inline void rtw89_hci_disable_intr(struct rtw89_dev *rtwdev) -+{ -+ if (rtwdev->hci.ops->disable_intr) -+ rtwdev->hci.ops->disable_intr(rtwdev); -+} -+ -+static inline void rtw89_hci_ctrl_txdma_ch(struct rtw89_dev *rtwdev, bool enable) -+{ -+ if (rtwdev->hci.ops->ctrl_txdma_ch) -+ rtwdev->hci.ops->ctrl_txdma_ch(rtwdev, enable); -+} -+ -+static inline void rtw89_hci_ctrl_txdma_fw_ch(struct rtw89_dev *rtwdev, bool enable) -+{ -+ if (rtwdev->hci.ops->ctrl_txdma_fw_ch) -+ rtwdev->hci.ops->ctrl_txdma_fw_ch(rtwdev, enable); -+} -+ -+static inline void rtw89_hci_ctrl_trxhci(struct rtw89_dev *rtwdev, bool enable) -+{ -+ if (rtwdev->hci.ops->ctrl_trxhci) -+ rtwdev->hci.ops->ctrl_trxhci(rtwdev, enable); -+} -+ -+static inline int rtw89_hci_poll_txdma_ch(struct rtw89_dev *rtwdev) -+{ -+ int ret = 0; -+ -+ if (rtwdev->hci.ops->poll_txdma_ch) -+ ret = rtwdev->hci.ops->poll_txdma_ch(rtwdev); -+ return ret; -+} -+ -+static inline void rtw89_hci_clr_idx_all(struct rtw89_dev *rtwdev) -+{ -+ if (rtwdev->hci.ops->clr_idx_all) -+ rtwdev->hci.ops->clr_idx_all(rtwdev); -+} -+ -+static inline int rtw89_hci_rst_bdram(struct rtw89_dev *rtwdev) -+{ -+ int ret = 0; -+ -+ if (rtwdev->hci.ops->rst_bdram) -+ ret = rtwdev->hci.ops->rst_bdram(rtwdev); -+ return ret; -+} -+ -+static inline void rtw89_hci_clear(struct rtw89_dev *rtwdev, struct pci_dev *pdev) -+{ -+ if (rtwdev->hci.ops->clear) -+ rtwdev->hci.ops->clear(rtwdev, pdev); -+} -+ - static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) - { - return rtwdev->hci.ops->read8(rtwdev, addr); ---- a/drivers/net/wireless/realtek/rtw89/debug.h -+++ b/drivers/net/wireless/realtek/rtw89/debug.h -@@ -26,6 +26,7 @@ enum rtw89_debug_mask { - RTW89_DBG_HW_SCAN = BIT(15), - RTW89_DBG_SAR = BIT(16), - RTW89_DBG_STATE = BIT(17), -+ RTW89_DBG_WOW = BIT(18), - - RTW89_DBG_UNEXP = BIT(31), - }; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1564,6 +1564,16 @@ int rtw89_mac_resize_ple_rx_quota(struct - } - #undef SET_QUOTA - -+void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable) -+{ -+ u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC; -+ -+ if (enable) -+ rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32); -+ else -+ rtw89_write32_clr(rtwdev, R_AX_SEC_ENG_CTRL, msk32); -+} -+ - static void dle_quota_cfg(struct rtw89_dev *rtwdev, - const struct rtw89_dle_mem *cfg, - u16 ext_wde_min_qt_wcpu) -@@ -1913,10 +1923,10 @@ static int scheduler_init(struct rtw89_d - return 0; - } - --static int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, -- enum rtw89_machdr_frame_type type, -- enum rtw89_mac_fwd_target fwd_target, -- u8 mac_idx) -+int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, -+ enum rtw89_machdr_frame_type type, -+ enum rtw89_mac_fwd_target fwd_target, -+ u8 mac_idx) - { - u32 reg; - u32 val; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -980,6 +980,16 @@ static inline void rtw89_mac_ctrl_hci_dm - B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); - } - -+static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev) -+{ -+ u32 val; -+ -+ val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, -+ B_AX_WLMAC_PWR_STE_MASK); -+ -+ return !!val; -+} -+ - int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, - bool resume, u32 tx_time); - int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, -@@ -1038,8 +1048,12 @@ void rtw89_mac_pkt_drop_vif(struct rtw89 - u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); - int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, - struct rtw89_cpuio_ctrl *ctrl_para, bool wd); -+int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, -+ enum rtw89_machdr_frame_type type, -+ enum rtw89_mac_fwd_target fwd_target, u8 mac_idx); - int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); - int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev, - enum rtw89_mac_idx band); -+void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool wow); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -14,6 +14,7 @@ - #include "sar.h" - #include "ser.h" - #include "util.h" -+#include "wow.h" - - static void rtw89_ops_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, -@@ -916,6 +917,55 @@ static int rtw89_ops_set_tid_config(stru - return 0; - } - -+#ifdef CONFIG_PM -+static int rtw89_ops_suspend(struct ieee80211_hw *hw, -+ struct cfg80211_wowlan *wowlan) -+{ -+ struct rtw89_dev *rtwdev = hw->priv; -+ int ret; -+ -+ set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); -+ cancel_delayed_work_sync(&rtwdev->track_work); -+ -+ mutex_lock(&rtwdev->mutex); -+ ret = rtw89_wow_suspend(rtwdev, wowlan); -+ mutex_unlock(&rtwdev->mutex); -+ -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret); -+ clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int rtw89_ops_resume(struct ieee80211_hw *hw) -+{ -+ struct rtw89_dev *rtwdev = hw->priv; -+ int ret; -+ -+ mutex_lock(&rtwdev->mutex); -+ ret = rtw89_wow_resume(rtwdev); -+ if (ret) -+ rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret); -+ mutex_unlock(&rtwdev->mutex); -+ -+ clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); -+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, -+ RTW89_TRACK_WORK_PERIOD); -+ -+ return ret ? 1 : 0; -+} -+ -+static void rtw89_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled) -+{ -+ struct rtw89_dev *rtwdev = hw->priv; -+ -+ device_set_wakeup_enable(rtwdev->dev, enabled); -+} -+#endif -+ - const struct ieee80211_ops rtw89_ops = { - .tx = rtw89_ops_tx, - .wake_tx_queue = rtw89_ops_wake_tx_queue, -@@ -953,5 +1003,10 @@ const struct ieee80211_ops rtw89_ops = { - .set_sar_specs = rtw89_ops_set_sar_specs, - .sta_rc_update = rtw89_ops_sta_rc_update, - .set_tid_config = rtw89_ops_set_tid_config, -+#ifdef CONFIG_PM -+ .suspend = rtw89_ops_suspend, -+ .resume = rtw89_ops_resume, -+ .set_wakeup = rtw89_ops_set_wakeup, -+#endif - }; - EXPORT_SYMBOL(rtw89_ops); ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -186,6 +186,17 @@ static void rtw89_pci_ctrl_txdma_ch_pcie - } - } - -+static void rtw89_pci_ctrl_txdma_fw_ch_pcie(struct rtw89_dev *rtwdev, bool enable) -+{ -+ const struct rtw89_pci_info *info = rtwdev->pci_info; -+ const struct rtw89_reg_def *dma_stop1 = &info->dma_stop1; -+ -+ if (enable) -+ rtw89_write32_clr(rtwdev, dma_stop1->addr, B_AX_STOP_CH12); -+ else -+ rtw89_write32_set(rtwdev, dma_stop1->addr, B_AX_STOP_CH12); -+} -+ - static bool - rtw89_skb_put_rx_data(struct rtw89_dev *rtwdev, bool fs, bool ls, - struct sk_buff *new, -@@ -2513,7 +2524,7 @@ static int rtw89_pci_ops_mac_pre_init(st - - /* disable all channels except to FW CMD channel to download firmware */ - rtw89_pci_ctrl_txdma_ch_pcie(rtwdev, false); -- rtw89_write32_clr(rtwdev, info->dma_stop1.addr, B_AX_STOP_CH12); -+ rtw89_pci_ctrl_txdma_fw_ch_pcie(rtwdev, true); - - /* start DMA activities */ - rtw89_pci_ctrl_dma_all(rtwdev, true); -@@ -3771,6 +3782,16 @@ static const struct rtw89_hci_ops rtw89_ - - .recovery_start = rtw89_pci_ops_recovery_start, - .recovery_complete = rtw89_pci_ops_recovery_complete, -+ -+ .ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_pcie, -+ .ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_pcie, -+ .ctrl_trxhci = rtw89_pci_ctrl_dma_trx, -+ .poll_txdma_ch = rtw89_poll_txdma_ch_idle_pcie, -+ .clr_idx_all = rtw89_pci_clr_idx_all, -+ .clear = rtw89_pci_clear_resource, -+ .disable_intr = rtw89_pci_disable_intr_lock, -+ .enable_intr = rtw89_pci_enable_intr_lock, -+ .rst_bdram = rtw89_pci_rst_bdram_pcie, - }; - - int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ---- a/drivers/net/wireless/realtek/rtw89/ps.c -+++ b/drivers/net/wireless/realtek/rtw89/ps.c -@@ -59,7 +59,7 @@ static void rtw89_ps_power_mode_change(s - rtw89_mac_power_mode_change(rtwdev, enter); - } - --static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) - { - if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) - return; ---- a/drivers/net/wireless/realtek/rtw89/ps.h -+++ b/drivers/net/wireless/realtek/rtw89/ps.h -@@ -8,6 +8,7 @@ - void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - void rtw89_leave_lps(struct rtw89_dev *rtwdev); - void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); -+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); - void rtw89_enter_ips(struct rtw89_dev *rtwdev); - void rtw89_leave_ips(struct rtw89_dev *rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -952,6 +952,9 @@ - B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ - B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN) - -+#define R_AX_RX_FUNCTION_STOP 0x8920 -+#define B_AX_HDR_RX_STOP BIT(0) -+ - #define R_AX_HCI_FC_CTRL 0x8A00 - #define B_AX_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) - #define B_AX_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8) -@@ -1570,6 +1573,8 @@ - #define R_AX_ACTION_FWD0 0x9C04 - #define TRXCFG_MPDU_PROC_ACT_FRWD 0x02A95A95 - -+#define R_AX_ACTION_FWD1 0x9C08 -+ - #define R_AX_TF_FWD 0x9C14 - #define TRXCFG_MPDU_PROC_TF_FRWD 0x0000AA55 - -@@ -1581,6 +1586,9 @@ - #define R_AX_CUT_AMSDU_CTRL 0x9C40 - #define TRXCFG_MPDU_PROC_CUT_CTRL 0x010E05F0 - -+#define R_AX_WOW_CTRL 0x9C50 -+#define B_AX_WOW_WOWEN BIT(1) -+ - #define R_AX_MPDU_RX_ERR_ISR 0x9CF0 - #define R_AX_MPDU_RX_ERR_IMR 0x9CF4 - #define B_AX_RPT_ERR_INT_EN BIT(3) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1990,6 +1990,12 @@ static void rtw8852a_query_ppdu(struct r - rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); - } - -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = { -+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+}; -+#endif -+ - static const struct rtw89_chip_ops rtw8852a_chip_ops = { - .enable_bb_rf = rtw89_mac_enable_bb_rf, - .disable_bb_rf = rtw89_mac_disable_bb_rf, -@@ -2139,6 +2145,9 @@ const struct rtw89_chip_info rtw8852a_ch - .imr_info = &rtw8852a_imr_info, - .rrsr_cfgs = &rtw8852a_rrsr_cfgs, - .dma_ch_mask = 0, -+#ifdef CONFIG_PM -+ .wowlan_stub = &rtw_wowlan_stub_8852a, -+#endif - }; - EXPORT_SYMBOL(rtw8852a_chip_info); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2796,6 +2796,12 @@ static int rtw8852c_mac_disable_bb_rf(st - return 0; - } - -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = { -+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+}; -+#endif -+ - static const struct rtw89_chip_ops rtw8852c_chip_ops = { - .enable_bb_rf = rtw8852c_mac_enable_bb_rf, - .disable_bb_rf = rtw8852c_mac_disable_bb_rf, -@@ -2949,6 +2955,9 @@ const struct rtw89_chip_info rtw8852c_ch - .imr_info = &rtw8852c_imr_info, - .rrsr_cfgs = &rtw8852c_rrsr_cfgs, - .dma_ch_mask = 0, -+#ifdef CONFIG_PM -+ .wowlan_stub = &rtw_wowlan_stub_8852c, -+#endif - }; - EXPORT_SYMBOL(rtw8852c_chip_info); - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -0,0 +1,633 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2019-2022 Realtek Corporation -+ */ -+#include "cam.h" -+#include "core.h" -+#include "debug.h" -+#include "fw.h" -+#include "mac.h" -+#include "phy.h" -+#include "ps.h" -+#include "reg.h" -+#include "util.h" -+#include "wow.h" -+ -+static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) -+{ -+ __rtw89_leave_ps_mode(rtwdev); -+} -+ -+static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) -+{ -+ struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; -+ -+ __rtw89_enter_ps_mode(rtwdev, rtwvif); -+} -+ -+static void rtw89_wow_enter_lps(struct rtw89_dev *rtwdev) -+{ -+ struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; -+ -+ rtw89_enter_lps(rtwdev, rtwvif); -+} -+ -+static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev) -+{ -+ rtw89_leave_lps(rtwdev); -+} -+ -+static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow) -+{ -+ int ret; -+ -+ if (enable_wow) { -+ ret = rtw89_mac_resize_ple_rx_quota(rtwdev, true); -+ if (ret) { -+ rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret); -+ return ret; -+ } -+ rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP); -+ rtw89_write32_clr(rtwdev, R_AX_RX_FLTR_OPT, B_AX_SNIFFER_MODE); -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); -+ rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0); -+ rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0); -+ rtw89_write32(rtwdev, R_AX_TF_FWD, 0); -+ rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0); -+ } else { -+ ret = rtw89_mac_resize_ple_rx_quota(rtwdev, false); -+ if (ret) { -+ rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret); -+ return ret; -+ } -+ rtw89_write32_clr(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP); -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); -+ rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD); -+ rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD); -+ } -+ -+ return 0; -+} -+ -+static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable) -+{ -+ enum rtw89_mac_fwd_target fwd_target = enable ? -+ RTW89_FWD_DONT_CARE : -+ RTW89_FWD_TO_HOST; -+ -+ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); -+ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); -+ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); -+} -+ -+static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) -+{ -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; -+ struct cfg80211_wowlan_nd_info nd_info; -+ struct cfg80211_wowlan_wakeup wakeup = { -+ .pattern_idx = -1, -+ }; -+ u32 wow_reason_reg; -+ u8 reason; -+ -+ if (chip_id == RTL8852A || chip_id == RTL8852B) -+ wow_reason_reg = R_AX_C2HREG_DATA3 + 3; -+ else -+ wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3; -+ -+ reason = rtw89_read8(rtwdev, wow_reason_reg); -+ -+ switch (reason) { -+ case RTW89_WOW_RSN_RX_DEAUTH: -+ wakeup.disconnect = true; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx deauth\n"); -+ break; -+ case RTW89_WOW_RSN_DISCONNECT: -+ wakeup.disconnect = true; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: AP is off\n"); -+ break; -+ case RTW89_WOW_RSN_RX_MAGIC_PKT: -+ wakeup.magic_pkt = true; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx magic packet\n"); -+ break; -+ case RTW89_WOW_RSN_RX_GTK_REKEY: -+ wakeup.gtk_rekey_failure = true; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n"); -+ break; -+ case RTW89_WOW_RSN_RX_PATTERN_MATCH: -+ /* Current firmware and driver don't report pattern index -+ * Use pattern_idx to 0 defaultly. -+ */ -+ wakeup.pattern_idx = 0; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n"); -+ break; -+ case RTW89_WOW_RSN_RX_NLO: -+ /* Current firmware and driver don't report ssid index. -+ * Use 0 for n_matches based on its comment. -+ */ -+ nd_info.n_matches = 0; -+ wakeup.net_detect = &nd_info; -+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "Rx NLO\n"); -+ break; -+ default: -+ rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); -+ ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL, -+ GFP_KERNEL); -+ return; -+ } -+ -+ ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup, -+ GFP_KERNEL); -+} -+ -+static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ -+ /* Current wowlan function support setting of only one STATION vif. -+ * So when one suitable vif is found, stop the iteration. -+ */ -+ if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION) -+ return; -+ -+ switch (rtwvif->net_type) { -+ case RTW89_NET_TYPE_INFRA: -+ rtw_wow->wow_vif = vif; -+ break; -+ case RTW89_NET_TYPE_NO_LINK: -+ default: -+ break; -+ } -+} -+ -+static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ -+ rtw_wow->wow_vif = NULL; -+ rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); -+ rtw_wow->pattern_cnt = 0; -+} -+ -+static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, -+ struct cfg80211_wowlan *wowlan) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_vif *rtwvif; -+ -+ if (wowlan->disconnect) -+ set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); -+ if (wowlan->magic_pkt) -+ set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_wow_vif_iter(rtwdev, rtwvif); -+ -+ if (!rtw_wow->wow_vif) -+ return -EPERM; -+ -+ return 0; -+} -+ -+static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; -+ struct ieee80211_sta *wow_sta; -+ struct rtw89_sta *rtwsta = NULL; -+ bool is_conn = true; -+ int ret; -+ -+ wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); -+ if (wow_sta) -+ rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; -+ else -+ is_conn = false; -+ -+ if (wow) { -+ if (rtw_wow->pattern_cnt) -+ rtwvif->wowlan_pattern = true; -+ if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) -+ rtwvif->wowlan_magic = true; -+ } else { -+ rtwvif->wowlan_pattern = false; -+ rtwvif->wowlan_magic = false; -+ } -+ -+ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); -+ return ret; -+ } -+ -+ if (wow) { -+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", -+ ret); -+ return ret; -+ } -+ } -+ -+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c join info\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c cam\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to fw wow global\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable) -+{ -+ u8 polling; -+ int ret; -+ -+ ret = read_poll_timeout_atomic(rtw89_read8_mask, polling, -+ wow_enable == !!polling, -+ 50, 50000, false, rtwdev, -+ R_AX_WOW_CTRL, B_AX_WOW_WOWEN); -+ if (ret) -+ rtw89_err(rtwdev, "failed to check wow status %s\n", -+ wow_enable ? "enabled" : "disabled"); -+ return ret; -+} -+ -+static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct list_head *pkt_list = &rtw_wow->pkt_list; -+ struct rtw89_pktofld_info *info, *tmp; -+ -+ list_for_each_entry_safe(info, tmp, pkt_list, list) { -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, -+ info->id); -+ list_del(&info->list); -+ kfree(info); -+ } -+} -+ -+static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) -+{ -+ enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; -+ struct ieee80211_sta *wow_sta; -+ struct rtw89_sta *rtwsta = NULL; -+ bool is_conn = true; -+ int ret; -+ -+ rtw89_hci_disable_intr(rtwdev); -+ -+ wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); -+ if (wow_sta) -+ rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; -+ else -+ is_conn = false; -+ -+ ret = rtw89_fw_download(rtwdev, fw_type); -+ if (ret) { -+ rtw89_warn(rtwdev, "download fw failed\n"); -+ return ret; -+ } -+ -+ rtw89_phy_init_rf_reg(rtwdev, true); -+ -+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, -+ RTW89_ROLE_FW_RESTORE); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n"); -+ return ret; -+ } -+ -+ if (!is_conn) -+ rtw89_cam_reset_keys(rtwdev); -+ -+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c join info\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c cam\n"); -+ return ret; -+ } -+ -+ if (is_conn) { -+ rtw89_phy_ra_assoc(rtwdev, wow_sta); -+ rtw89_phy_set_bss_color(rtwdev, wow_vif); -+ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); -+ } -+ -+ rtw89_mac_hw_mgnt_sec(rtwdev, wow); -+ rtw89_hci_enable_intr(rtwdev); -+ -+ return 0; -+} -+ -+static int rtw89_wow_enable_trx_pre(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ rtw89_hci_ctrl_txdma_ch(rtwdev, false); -+ rtw89_hci_ctrl_txdma_fw_ch(rtwdev, true); -+ -+ rtw89_mac_ptk_drop_by_band_and_wait(rtwdev, RTW89_MAC_0); -+ -+ ret = rtw89_hci_poll_txdma_ch(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "txdma ch busy\n"); -+ return ret; -+ } -+ rtw89_wow_set_rx_filter(rtwdev, true); -+ -+ ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); -+ if (ret) { -+ rtw89_err(rtwdev, "cfg ppdu status\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int rtw89_wow_enable_trx_post(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ rtw89_hci_disable_intr(rtwdev); -+ rtw89_hci_ctrl_trxhci(rtwdev, false); -+ -+ ret = rtw89_hci_poll_txdma_ch(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to poll txdma ch idle pcie\n"); -+ return ret; -+ } -+ -+ ret = rtw89_wow_config_mac(rtwdev, true); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to config mac\n"); -+ return ret; -+ } -+ -+ rtw89_wow_set_rx_filter(rtwdev, false); -+ rtw89_hci_reset(rtwdev); -+ -+ return 0; -+} -+ -+static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ rtw89_hci_clr_idx_all(rtwdev); -+ -+ ret = rtw89_hci_rst_bdram(rtwdev); -+ if (ret) { -+ rtw89_warn(rtwdev, "reset bdram busy\n"); -+ return ret; -+ } -+ -+ rtw89_hci_ctrl_trxhci(rtwdev, true); -+ rtw89_hci_ctrl_txdma_ch(rtwdev, true); -+ -+ ret = rtw89_wow_config_mac(rtwdev, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to config mac\n"); -+ return ret; -+ } -+ rtw89_hci_enable_intr(rtwdev); -+ -+ return 0; -+} -+ -+static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); -+ if (ret) -+ rtw89_err(rtwdev, "cfg ppdu status\n"); -+ -+ return ret; -+} -+ -+static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; -+ int ret; -+ -+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_cfg_wake(rtwdev, true); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to config wake\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_check_fw_status(rtwdev, true); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to check enable fw ready\n"); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ -+static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; -+ int ret; -+ -+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); -+ goto out; -+ } -+ -+ rtw89_wow_release_pkt_list(rtwdev); -+ -+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_cfg_wake(rtwdev, false); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable config wake\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_check_fw_status(rtwdev, false); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ -+static int rtw89_wow_enable(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); -+ -+ ret = rtw89_wow_enable_trx_pre(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to enable trx_pre\n"); -+ goto out; -+ } -+ -+ rtw89_wow_swap_fw(rtwdev, true); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); -+ goto out; -+ } -+ -+ rtw89_wow_fw_start(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); -+ goto out; -+ } -+ -+ rtw89_wow_enter_lps(rtwdev); -+ -+ rtw89_wow_enable_trx_post(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to enable trx_post\n"); -+ goto out; -+ } -+ -+ return 0; -+ -+out: -+ clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); -+ return ret; -+} -+ -+static int rtw89_wow_disable(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ ret = rtw89_wow_disable_trx_pre(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); -+ goto out; -+ } -+ -+ rtw89_wow_leave_lps(rtwdev); -+ -+ ret = rtw89_wow_fw_stop(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to swap to normal fw\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_swap_fw(rtwdev, false); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); -+ goto out; -+ } -+ -+ ret = rtw89_wow_disable_trx_post(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); -+ goto out; -+ } -+ -+out: -+ clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); -+ return ret; -+} -+ -+int rtw89_wow_resume(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { -+ rtw89_err(rtwdev, "wow is not enabled\n"); -+ ret = -EPERM; -+ goto out; -+ } -+ -+ if (!rtw89_mac_get_power_state(rtwdev)) { -+ rtw89_err(rtwdev, "chip is no power when resume\n"); -+ ret = -EPERM; -+ goto out; -+ } -+ -+ rtw89_wow_leave_deep_ps(rtwdev); -+ -+ rtw89_wow_show_wakeup_reason(rtwdev); -+ -+ ret = rtw89_wow_disable(rtwdev); -+ if (ret) -+ rtw89_err(rtwdev, "failed to disable wow\n"); -+ -+out: -+ rtw89_wow_clear_wakeups(rtwdev); -+ return ret; -+} -+ -+int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan) -+{ -+ int ret; -+ -+ ret = rtw89_wow_set_wakeups(rtwdev, wowlan); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to set wakeup event\n"); -+ return ret; -+ } -+ -+ rtw89_wow_leave_lps(rtwdev); -+ -+ ret = rtw89_wow_enable(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to enable wow\n"); -+ return ret; -+ } -+ -+ rtw89_wow_enter_deep_ps(rtwdev); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/wow.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2019-2022 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_WOW_H__ -+#define __RTW89_WOW_H__ -+ -+enum rtw89_wake_reason { -+ RTW89_WOW_RSN_RX_PTK_REKEY = 0x1, -+ RTW89_WOW_RSN_RX_GTK_REKEY = 0x2, -+ RTW89_WOW_RSN_RX_DEAUTH = 0x8, -+ RTW89_WOW_RSN_DISCONNECT = 0x10, -+ RTW89_WOW_RSN_RX_MAGIC_PKT = 0x21, -+ RTW89_WOW_RSN_RX_PATTERN_MATCH = 0x23, -+ RTW89_WOW_RSN_RX_NLO = 0x55, -+}; -+ -+int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan); -+int rtw89_wow_resume(struct rtw89_dev *rtwdev); -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-055-wifi-rtw89-add-WoWLAN-pattern-match-support.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-055-wifi-rtw89-add-WoWLAN-pattern-match-support.patch deleted file mode 100644 index d714ed811..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-055-wifi-rtw89-add-WoWLAN-pattern-match-support.patch +++ /dev/null @@ -1,498 +0,0 @@ -From d2b68e95b5bc97d81d150a46447167bf21bd555f Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Thu, 27 Oct 2022 13:27:07 +0800 -Subject: [PATCH 055/149] wifi: rtw89: add WoWLAN pattern match support - -Pattern match is an option of WoWLAN to allow the device to be woken up -from suspend mode when receiving packets matched user-designed patterns. - -The patterns are written into hardware via WoWLAN firmware in suspend -flow if users have set up them. If packets matched designed pattern are -received, WoWLAN firmware will send an interrupt and then wake up the -device. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221027052707.14605-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 18 ++ - drivers/net/wireless/realtek/rtw89/fw.c | 52 ++++ - drivers/net/wireless/realtek/rtw89/fw.h | 67 +++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 3 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 + - drivers/net/wireless/realtek/rtw89/util.h | 11 + - drivers/net/wireless/realtek/rtw89/wow.c | 228 +++++++++++++++++- - 7 files changed, 381 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3489,9 +3489,27 @@ struct rtw89_phy_efuse_gain { - s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ - }; - -+#define RTW89_MAX_PATTERN_NUM 18 -+#define RTW89_MAX_PATTERN_MASK_SIZE 4 -+#define RTW89_MAX_PATTERN_SIZE 128 -+ -+struct rtw89_wow_cam_info { -+ bool r_w; -+ u8 idx; -+ u32 mask[RTW89_MAX_PATTERN_MASK_SIZE]; -+ u16 crc; -+ bool negative_pattern_match; -+ bool skip_mac_hdr; -+ bool uc; -+ bool mc; -+ bool bc; -+ bool valid; -+}; -+ - struct rtw89_wow_param { - struct ieee80211_vif *wow_vif; - DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); -+ struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; - u8 pattern_cnt; - struct list_head pkt_list; - }; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -3174,3 +3174,55 @@ fail: - - return ret; - } -+ -+#define H2C_WOW_CAM_UPD_LEN 24 -+int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, -+ struct rtw89_wow_cam_info *cam_info) -+{ -+ struct sk_buff *skb; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_WOW_CAM_UPD_LEN); -+ -+ RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); -+ RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); -+ if (cam_info->valid) { -+ RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); -+ RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); -+ RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); -+ RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); -+ RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); -+ RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, -+ cam_info->negative_pattern_match); -+ RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, -+ cam_info->skip_mac_hdr); -+ RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); -+ RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); -+ RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); -+ } -+ RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MAC_WOW, -+ H2C_FUNC_WOW_CAM_UPD, 0, 1, -+ H2C_WOW_CAM_UPD_LEN); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2033,6 +2033,71 @@ static inline void RTW89_SET_WOW_WAKEUP_ - le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); - } - -+static inline void RTW89_SET_WOW_CAM_UPD_R_W(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_IDX(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 1)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_WKFM1(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 1, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_WKFM2(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 2, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_WKFM3(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 3, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_WKFM4(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 4, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_CRC(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, GENMASK(15, 0)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(22)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(23)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_UC(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(24)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_MC(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(25)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_BC(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(26)); -+} -+ -+static inline void RTW89_SET_WOW_CAM_UPD_VALID(void *h2c, u32 val) -+{ -+ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(31)); -+} -+ - enum rtw89_btc_btf_h2c_class { - BTFC_SET = 0x10, - BTFC_GET = 0x11, -@@ -3039,6 +3104,8 @@ int rtw89_fw_h2c_wow_global(struct rtw89 - int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); - -+int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, -+ struct rtw89_wow_cam_info *cam_info); - static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1993,6 +1993,9 @@ static void rtw8852a_query_ppdu(struct r - #ifdef CONFIG_PM - static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = { - .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+ .n_patterns = RTW89_MAX_PATTERN_NUM, -+ .pattern_max_len = RTW89_MAX_PATTERN_SIZE, -+ .pattern_min_len = 1, - }; - #endif - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2799,6 +2799,9 @@ static int rtw8852c_mac_disable_bb_rf(st - #ifdef CONFIG_PM - static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = { - .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+ .n_patterns = RTW89_MAX_PATTERN_NUM, -+ .pattern_max_len = RTW89_MAX_PATTERN_SIZE, -+ .pattern_min_len = 1, - }; - #endif - ---- a/drivers/net/wireless/realtek/rtw89/util.h -+++ b/drivers/net/wireless/realtek/rtw89/util.h -@@ -44,4 +44,15 @@ static inline s32 s32_div_u32_round_clos - return s32_div_u32_round_down(dividend + divisor / 2, divisor, NULL); - } - -+static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask) -+{ -+ int i; -+ -+ eth_zero_addr(dst); -+ for (i = 0; i < ETH_ALEN; i++) { -+ if (mask & BIT(i)) -+ dst[i] = src[i]; -+ } -+} -+ - #endif ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -162,6 +162,227 @@ static void rtw89_wow_vif_iter(struct rt - } - } - -+static u16 __rtw89_cal_crc16(u8 data, u16 crc) -+{ -+ u8 shift_in, data_bit; -+ u8 crc_bit4, crc_bit11, crc_bit15; -+ u16 crc_result; -+ int index; -+ -+ for (index = 0; index < 8; index++) { -+ crc_bit15 = crc & BIT(15) ? 1 : 0; -+ data_bit = data & BIT(index) ? 1 : 0; -+ shift_in = crc_bit15 ^ data_bit; -+ -+ crc_result = crc << 1; -+ -+ if (shift_in == 0) -+ crc_result &= ~BIT(0); -+ else -+ crc_result |= BIT(0); -+ -+ crc_bit11 = (crc & BIT(11) ? 1 : 0) ^ shift_in; -+ -+ if (crc_bit11 == 0) -+ crc_result &= ~BIT(12); -+ else -+ crc_result |= BIT(12); -+ -+ crc_bit4 = (crc & BIT(4) ? 1 : 0) ^ shift_in; -+ -+ if (crc_bit4 == 0) -+ crc_result &= ~BIT(5); -+ else -+ crc_result |= BIT(5); -+ -+ crc = crc_result; -+ } -+ return crc; -+} -+ -+static u16 rtw89_calc_crc(u8 *pdata, int length) -+{ -+ u16 crc = 0xffff; -+ int i; -+ -+ for (i = 0; i < length; i++) -+ crc = __rtw89_cal_crc16(pdata[i], crc); -+ -+ /* get 1' complement */ -+ return ~crc; -+} -+ -+static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif, -+ struct rtw89_wow_cam_info *rtw_pattern, -+ const u8 *pattern, u8 da_mask) -+{ -+ u8 da[ETH_ALEN]; -+ -+ ether_addr_copy_mask(da, pattern, da_mask); -+ -+ /* Each pattern is divided into different kinds by DA address -+ * a. DA is broadcast address: set bc = 0; -+ * b. DA is multicast address: set mc = 0 -+ * c. DA is unicast address same as dev's mac address: set uc = 0 -+ * d. DA is unmasked. Also called wildcard type: set uc = bc = mc = 0 -+ * e. Others is invalid type. -+ */ -+ -+ if (is_broadcast_ether_addr(da)) -+ rtw_pattern->bc = true; -+ else if (is_multicast_ether_addr(da)) -+ rtw_pattern->mc = true; -+ else if (ether_addr_equal(da, rtwvif->mac_addr) && -+ da_mask == GENMASK(5, 0)) -+ rtw_pattern->uc = true; -+ else if (!da_mask) /*da_mask == 0 mean wildcard*/ -+ return 0; -+ else -+ return -EPERM; -+ -+ return 0; -+} -+ -+static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ const struct cfg80211_pkt_pattern *pkt_pattern, -+ struct rtw89_wow_cam_info *rtw_pattern) -+{ -+ u8 mask_hw[RTW89_MAX_PATTERN_MASK_SIZE * 4] = {0}; -+ u8 content[RTW89_MAX_PATTERN_SIZE] = {0}; -+ const u8 *mask; -+ const u8 *pattern; -+ u8 mask_len; -+ u16 count; -+ u32 len; -+ int i, ret; -+ -+ pattern = pkt_pattern->pattern; -+ len = pkt_pattern->pattern_len; -+ mask = pkt_pattern->mask; -+ mask_len = DIV_ROUND_UP(len, 8); -+ memset(rtw_pattern, 0, sizeof(*rtw_pattern)); -+ -+ ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern, -+ mask[0] & GENMASK(5, 0)); -+ if (ret) -+ return ret; -+ -+ /* translate mask from os to mask for hw -+ * pattern from OS uses 'ethenet frame', like this: -+ * | 6 | 6 | 2 | 20 | Variable | 4 | -+ * |--------+--------+------+-----------+------------+-----| -+ * | 802.3 Mac Header | IP Header | TCP Packet | FCS | -+ * | DA | SA | Type | -+ * -+ * BUT, packet catched by our HW is in '802.11 frame', begin from LLC -+ * | 24 or 30 | 6 | 2 | 20 | Variable | 4 | -+ * |-------------------+--------+------+-----------+------------+-----| -+ * | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | -+ * | Others | Tpye | -+ * -+ * Therefore, we need translate mask_from_OS to mask_to_hw. -+ * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, -+ * because new mask[0~5] means 'SA', but our HW packet begins from LLC, -+ * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. -+ */ -+ -+ /* Shift 6 bits */ -+ for (i = 0; i < mask_len - 1; i++) { -+ mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)) | -+ u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2; -+ } -+ mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); -+ -+ /* Set bit 0-5 to zero */ -+ mask_hw[0] &= ~GENMASK(5, 0); -+ -+ memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask)); -+ -+ /* To get the wake up pattern from the mask. -+ * We do not count first 12 bits which means -+ * DA[6] and SA[6] in the pattern to match HW design. -+ */ -+ count = 0; -+ for (i = 12; i < len; i++) { -+ if ((mask[i / 8] >> (i % 8)) & 0x01) { -+ content[count] = pattern[i]; -+ count++; -+ } -+ } -+ -+ rtw_pattern->crc = rtw89_calc_crc(content, count); -+ -+ return 0; -+} -+ -+static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct cfg80211_wowlan *wowlan) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; -+ int i; -+ int ret; -+ -+ if (!wowlan->n_patterns || !wowlan->patterns) -+ return 0; -+ -+ for (i = 0; i < wowlan->n_patterns; i++) { -+ rtw_pattern = &rtw_wow->patterns[i]; -+ ret = rtw89_wow_pattern_generate(rtwdev, rtwvif, -+ &wowlan->patterns[i], -+ rtw_pattern); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to generate pattern(%d)\n", i); -+ rtw_wow->pattern_cnt = 0; -+ return ret; -+ } -+ -+ rtw_pattern->r_w = true; -+ rtw_pattern->idx = i; -+ rtw_pattern->negative_pattern_match = false; -+ rtw_pattern->skip_mac_hdr = true; -+ rtw_pattern->valid = true; -+ } -+ rtw_wow->pattern_cnt = wowlan->n_patterns; -+ -+ return 0; -+} -+ -+static void rtw89_wow_pattern_clear_cam(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; -+ int i = 0; -+ -+ for (i = 0; i < rtw_wow->pattern_cnt; i++) { -+ rtw_pattern = &rtw_wow->patterns[i]; -+ rtw_pattern->valid = false; -+ rtw89_fw_wow_cam_update(rtwdev, rtw_pattern); -+ } -+} -+ -+static void rtw89_wow_pattern_write(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; -+ int i; -+ -+ for (i = 0; i < rtw_wow->pattern_cnt; i++) -+ rtw89_fw_wow_cam_update(rtwdev, rtw_pattern + i); -+} -+ -+static void rtw89_wow_pattern_clear(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -+ -+ rtw89_wow_pattern_clear_cam(rtwdev); -+ -+ rtw_wow->pattern_cnt = 0; -+ memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); -+} -+ - static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) - { - struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -@@ -188,7 +409,8 @@ static int rtw89_wow_set_wakeups(struct - if (!rtw_wow->wow_vif) - return -EPERM; - -- return 0; -+ rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; -+ return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan); - } - - static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) -@@ -442,6 +664,8 @@ static int rtw89_wow_fw_start(struct rtw - struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; - int ret; - -+ rtw89_wow_pattern_write(rtwdev); -+ - ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true); - if (ret) { - rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); -@@ -476,6 +700,8 @@ static int rtw89_wow_fw_stop(struct rtw8 - struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; - int ret; - -+ rtw89_wow_pattern_clear(rtwdev); -+ - ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false); - if (ret) { - rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-056-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-056-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch deleted file mode 100644 index b6bd100d4..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-056-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 8fa681703175ba0ea283dd564a64edaef3472ee6 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Thu, 20 Oct 2022 08:26:46 +0100 -Subject: [PATCH 056/149] wifi: rtw89: 8852b: Fix spelling mistake KIP_RESOTRE - -> KIP_RESTORE - -Ther is a spelling mistake in a rtw89_debug message. Fix it. - -Signed-off-by: Colin Ian King -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221020072646.1513307-1-colin.i.king@gmail.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -1754,7 +1754,7 @@ static void _dpk_one_shot(struct rtw89_d - id == 0x14 ? "PWR_CAL" : - id == 0x15 ? "DPK_RXAGC" : - id == 0x16 ? "KIP_PRESET" : -- id == 0x17 ? "KIP_RESOTRE" : "DPK_TXAGC", -+ id == 0x17 ? "KIP_RESTORE" : "DPK_TXAGC", - dpk_cmd); - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-057-wifi-rtw89-dump-dispatch-status-via-debug-port.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-057-wifi-rtw89-dump-dispatch-status-via-debug-port.patch deleted file mode 100644 index c802833d3..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-057-wifi-rtw89-dump-dispatch-status-via-debug-port.patch +++ /dev/null @@ -1,704 +0,0 @@ -From d6197c9121dd72f35e5702aa55ee5c1583e0bfdb Mon Sep 17 00:00:00 2001 -From: Chia-Yuan Li -Date: Wed, 2 Nov 2022 09:42:59 +0800 -Subject: [PATCH 057/149] wifi: rtw89: dump dispatch status via debug port - -Dispatch is a component to decide packets forward to host, DMAC or -HAXIDMA. It contains CDT standing for CPU dispatcher, HDT standing -for host dispatcher, WDE standing for descriptor engine and PLE standing -for payload engine. STF is one kind of modes, it can be used if packet -send to hardware and doesn't need release report. - -These debug port information can help to clarify the reason if -packets stuck in dispatch. - -Signed-off-by: Chia-Yuan Li -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221102014300.14091-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 575 +++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 45 ++ - drivers/net/wireless/realtek/rtw89/reg.h | 5 + - 3 files changed, 625 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -1121,6 +1121,303 @@ static const struct rtw89_mac_dbg_port_i - .rd_msk = B_AX_PTCL_DBG_INFO_MASK - }; - -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx0_5 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0xD, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx6 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x5, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx7 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x9, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx8 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x3, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx9_C = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x1, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_txD = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx0 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0xB, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx1 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x4, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx3 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x8, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx4 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x7, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx5_8 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x1, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx9 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x3, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_txA_C = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx0 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x8, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx1_2 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx3 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x6, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx4 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx5 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 2, -+ .sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_0 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x3, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_1 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x6, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_2 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x0, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p1 = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x8, -+ .end = 0xE, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_stf_ctrl = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x5, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_addr_ctrl = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x6, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_wde_intf = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0xF, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_ple_intf = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x9, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ -+static const struct rtw89_mac_dbg_port_info dbg_port_dspt_flow_ctrl = { -+ .sel_addr = R_AX_DISPATCHER_DBG_PORT, -+ .sel_byte = 1, -+ .sel_msk = B_AX_DISPATCHER_CH_SEL_MASK, -+ .srt = 0x0, -+ .end = 0x3, -+ .rd_addr = R_AX_DBG_PORT_SEL, -+ .rd_byte = 4, -+ .rd_msk = B_AX_DEBUG_ST_MASK -+}; -+ - static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = { - .sel_addr = R_AX_SCH_DBG_SEL, - .sel_byte = 1, -@@ -1610,6 +1907,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_ - struct rtw89_dev *rtwdev, u32 sel) - { - const struct rtw89_mac_dbg_port_info *info; -+ u32 index; - u32 val32; - u16 val16; - u8 val8; -@@ -1885,6 +2183,235 @@ rtw89_debug_mac_dbg_port_sel(struct seq_ - info = &dbg_port_pktinfo; - seq_puts(m, "Enable pktinfo dump.\n"); - break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0: -+ rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, -+ B_AX_DBG_SEL0, 0x80); -+ rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, -+ B_AX_SEL_0XC0_MASK, 1); -+ fallthrough; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX1: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX2: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX3: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX4: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX5: -+ info = &dbg_port_dspt_hdt_tx0_5; -+ index = sel - RTW89_DBG_PORT_SEL_DSPT_HDT_TX0; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, index); -+ seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6: -+ info = &dbg_port_dspt_hdt_tx6; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 6); -+ seq_puts(m, "Enable Dispatcher hdt tx6 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7: -+ info = &dbg_port_dspt_hdt_tx7; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 7); -+ seq_puts(m, "Enable Dispatcher hdt tx7 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8: -+ info = &dbg_port_dspt_hdt_tx8; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 8); -+ seq_puts(m, "Enable Dispatcher hdt tx8 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TXB: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TXC: -+ info = &dbg_port_dspt_hdt_tx9_C; -+ index = sel + 9 - RTW89_DBG_PORT_SEL_DSPT_HDT_TX9; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, index); -+ seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD: -+ info = &dbg_port_dspt_hdt_txD; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 0); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 0xD); -+ seq_puts(m, "Enable Dispatcher hdt txD dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0: -+ info = &dbg_port_dspt_cdt_tx0; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 0); -+ seq_puts(m, "Enable Dispatcher cdt tx0 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1: -+ info = &dbg_port_dspt_cdt_tx1; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 1); -+ seq_puts(m, "Enable Dispatcher cdt tx1 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3: -+ info = &dbg_port_dspt_cdt_tx3; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 3); -+ seq_puts(m, "Enable Dispatcher cdt tx3 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4: -+ info = &dbg_port_dspt_cdt_tx4; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 4); -+ seq_puts(m, "Enable Dispatcher cdt tx4 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX7: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX8: -+ info = &dbg_port_dspt_cdt_tx5_8; -+ index = sel + 5 - RTW89_DBG_PORT_SEL_DSPT_CDT_TX5; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, index); -+ seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9: -+ info = &dbg_port_dspt_cdt_tx9; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 9); -+ seq_puts(m, "Enable Dispatcher cdt tx9 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_TXC: -+ info = &dbg_port_dspt_cdt_txA_C; -+ index = sel + 0xA - RTW89_DBG_PORT_SEL_DSPT_CDT_TXA; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 1); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, index); -+ seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0: -+ info = &dbg_port_dspt_hdt_rx0; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 2); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 0); -+ seq_puts(m, "Enable Dispatcher hdt rx0 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1: -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2: -+ info = &dbg_port_dspt_hdt_rx1_2; -+ index = sel + 1 - RTW89_DBG_PORT_SEL_DSPT_HDT_RX1; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 2); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, index); -+ seq_printf(m, "Enable Dispatcher hdt rx%x dump.\n", index); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3: -+ info = &dbg_port_dspt_hdt_rx3; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 2); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 3); -+ seq_puts(m, "Enable Dispatcher hdt rx3 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4: -+ info = &dbg_port_dspt_hdt_rx4; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 2); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 4); -+ seq_puts(m, "Enable Dispatcher hdt rx4 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5: -+ info = &dbg_port_dspt_hdt_rx5; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 2); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 5); -+ seq_puts(m, "Enable Dispatcher hdt rx5 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0: -+ info = &dbg_port_dspt_cdt_rx_p0_0; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 3); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 0); -+ seq_puts(m, "Enable Dispatcher cdt rx part0 0 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0: -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1: -+ info = &dbg_port_dspt_cdt_rx_p0_1; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 3); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 1); -+ seq_puts(m, "Enable Dispatcher cdt rx part0 1 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2: -+ info = &dbg_port_dspt_cdt_rx_p0_2; -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 3); -+ rtw89_write16_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_CH_SEL_MASK, 2); -+ seq_puts(m, "Enable Dispatcher cdt rx part0 2 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1: -+ info = &dbg_port_dspt_cdt_rx_p1; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 3); -+ seq_puts(m, "Enable Dispatcher cdt rx part1 dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL: -+ info = &dbg_port_dspt_stf_ctrl; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 4); -+ seq_puts(m, "Enable Dispatcher stf control dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL: -+ info = &dbg_port_dspt_addr_ctrl; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 5); -+ seq_puts(m, "Enable Dispatcher addr control dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF: -+ info = &dbg_port_dspt_wde_intf; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 6); -+ seq_puts(m, "Enable Dispatcher wde interface dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF: -+ info = &dbg_port_dspt_ple_intf; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 7); -+ seq_puts(m, "Enable Dispatcher ple interface dump.\n"); -+ break; -+ case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL: -+ info = &dbg_port_dspt_flow_ctrl; -+ rtw89_write8_mask(rtwdev, info->sel_addr, -+ B_AX_DISPATCHER_INTN_SEL_MASK, 8); -+ seq_puts(m, "Enable Dispatcher flow control dump.\n"); -+ break; - case RTW89_DBG_PORT_SEL_PCIE_TXDMA: - info = &dbg_port_pcie_txdma; - val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); -@@ -1963,6 +2490,10 @@ static bool is_dbg_port_valid(struct rtw - sel >= RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG && - sel <= RTW89_DBG_PORT_SEL_PKTINFO) - return false; -+ if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) && -+ sel >= RTW89_DBG_PORT_SEL_DSPT_HDT_TX0 && -+ sel <= RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL) -+ return false; - if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL) && - sel >= RTW89_DBG_PORT_SEL_PTCL_C0 && - sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C0) -@@ -2033,6 +2564,50 @@ static int rtw89_debug_mac_dbg_port_dump - case_DBG_SEL(PLE_QUEMGN_QLNKTBL); - case_DBG_SEL(PLE_QUEMGN_QEMPTY); - case_DBG_SEL(PKTINFO); -+ case_DBG_SEL(DSPT_HDT_TX0); -+ case_DBG_SEL(DSPT_HDT_TX1); -+ case_DBG_SEL(DSPT_HDT_TX2); -+ case_DBG_SEL(DSPT_HDT_TX3); -+ case_DBG_SEL(DSPT_HDT_TX4); -+ case_DBG_SEL(DSPT_HDT_TX5); -+ case_DBG_SEL(DSPT_HDT_TX6); -+ case_DBG_SEL(DSPT_HDT_TX7); -+ case_DBG_SEL(DSPT_HDT_TX8); -+ case_DBG_SEL(DSPT_HDT_TX9); -+ case_DBG_SEL(DSPT_HDT_TXA); -+ case_DBG_SEL(DSPT_HDT_TXB); -+ case_DBG_SEL(DSPT_HDT_TXC); -+ case_DBG_SEL(DSPT_HDT_TXD); -+ case_DBG_SEL(DSPT_HDT_TXE); -+ case_DBG_SEL(DSPT_HDT_TXF); -+ case_DBG_SEL(DSPT_CDT_TX0); -+ case_DBG_SEL(DSPT_CDT_TX1); -+ case_DBG_SEL(DSPT_CDT_TX3); -+ case_DBG_SEL(DSPT_CDT_TX4); -+ case_DBG_SEL(DSPT_CDT_TX5); -+ case_DBG_SEL(DSPT_CDT_TX6); -+ case_DBG_SEL(DSPT_CDT_TX7); -+ case_DBG_SEL(DSPT_CDT_TX8); -+ case_DBG_SEL(DSPT_CDT_TX9); -+ case_DBG_SEL(DSPT_CDT_TXA); -+ case_DBG_SEL(DSPT_CDT_TXB); -+ case_DBG_SEL(DSPT_CDT_TXC); -+ case_DBG_SEL(DSPT_HDT_RX0); -+ case_DBG_SEL(DSPT_HDT_RX1); -+ case_DBG_SEL(DSPT_HDT_RX2); -+ case_DBG_SEL(DSPT_HDT_RX3); -+ case_DBG_SEL(DSPT_HDT_RX4); -+ case_DBG_SEL(DSPT_HDT_RX5); -+ case_DBG_SEL(DSPT_CDT_RX_P0); -+ case_DBG_SEL(DSPT_CDT_RX_P0_0); -+ case_DBG_SEL(DSPT_CDT_RX_P0_1); -+ case_DBG_SEL(DSPT_CDT_RX_P0_2); -+ case_DBG_SEL(DSPT_CDT_RX_P1); -+ case_DBG_SEL(DSPT_STF_CTRL); -+ case_DBG_SEL(DSPT_ADDR_CTRL); -+ case_DBG_SEL(DSPT_WDE_INTF); -+ case_DBG_SEL(DSPT_PLE_INTF); -+ case_DBG_SEL(DSPT_FLOW_CTRL); - case_DBG_SEL(PCIE_TXDMA); - case_DBG_SEL(PCIE_RXDMA); - case_DBG_SEL(PCIE_CVT); ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -211,6 +211,51 @@ enum rtw89_mac_dbg_port_sel { - RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL, - RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY, - RTW89_DBG_PORT_SEL_PKTINFO, -+ /* DISPATCHER related */ -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX0, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX1, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX2, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX3, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX4, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX5, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX6, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX7, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX8, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TX9, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXA, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXB, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXC, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXD, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXE, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_TXF, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX0, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX1, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX3, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX4, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX5, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX6, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX7, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX8, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TX9, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TXA, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TXB, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_TXC, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX0, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX1, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX2, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX3, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX4, -+ RTW89_DBG_PORT_SEL_DSPT_HDT_RX5, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2, -+ RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1, -+ RTW89_DBG_PORT_SEL_DSPT_STF_CTRL, -+ RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL, -+ RTW89_DBG_PORT_SEL_DSPT_WDE_INTF, -+ RTW89_DBG_PORT_SEL_DSPT_PLE_INTF, -+ RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL, - /* PCIE related */ - RTW89_DBG_PORT_SEL_PCIE_TXDMA, - RTW89_DBG_PORT_SEL_PCIE_RXDMA, ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -952,6 +952,11 @@ - B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ - B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN) - -+#define R_AX_DISPATCHER_DBG_PORT 0x8860 -+#define B_AX_DISPATCHER_DBG_SEL_MASK GENMASK(11, 8) -+#define B_AX_DISPATCHER_INTN_SEL_MASK GENMASK(7, 4) -+#define B_AX_DISPATCHER_CH_SEL_MASK GENMASK(3, 0) -+ - #define R_AX_RX_FUNCTION_STOP 0x8920 - #define B_AX_HDR_RX_STOP BIT(0) - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-058-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-058-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch deleted file mode 100644 index 9d64de7f7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-058-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch +++ /dev/null @@ -1,1375 +0,0 @@ -From f7333fc2135b96dc36965a8e711a9275432256df Mon Sep 17 00:00:00 2001 -From: Chia-Yuan Li -Date: Wed, 2 Nov 2022 09:43:00 +0800 -Subject: [PATCH 058/149] wifi: rtw89: update D-MAC and C-MAC dump to diagnose - SER - -To detect TX or RX stuck, we implement SER (system error recovery) in -firmware to recover abnormal states of hardware, and report events to -driver. This kind of events could happen rarely per day. - -SER might be true-positive or false-negative cases, and it could be failed -to recover true-positive case. We dump related registers to kernel message -at that moment and collect them from users, because they occur rarely, -randomly and hard to make sure we reproduce the same symptom. To address -problems accurately, add more registers by this patch. - -It also might be false-positive cases that looks like TX or RX get stuck, -we need to dump registers from debugfs manually, so also add similar -things to debugfs as well. - -Signed-off-by: Chia-Yuan Li -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221102014300.14091-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 426 ++++++++++++++++----- - drivers/net/wireless/realtek/rtw89/mac.c | 374 +++++++++++++----- - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/pci.h | 12 + - drivers/net/wireless/realtek/rtw89/reg.h | 229 ++++++++++- - 5 files changed, 845 insertions(+), 197 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -8,6 +8,7 @@ - #include "debug.h" - #include "fw.h" - #include "mac.h" -+#include "pci.h" - #include "ps.h" - #include "reg.h" - #include "sar.h" -@@ -995,7 +996,9 @@ static int rtw89_debug_mac_dump_dle_dbg( - static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, - struct seq_file *m) - { -- int ret; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u32 dmac_err; -+ int i, ret; - - ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); - if (ret) { -@@ -1003,98 +1006,347 @@ static int rtw89_debug_mac_dump_dmac_dbg - return ret; - } - -- seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR)); -- seq_printf(m, "[0]R_AX_WDRLS_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); -- seq_printf(m, "[1]R_AX_SEC_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_ERR_IMR_ISR)); -- seq_printf(m, "[2.1]R_AX_MPDU_TX_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); -- seq_printf(m, "[2.2]R_AX_MPDU_RX_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); -- seq_printf(m, "[3]R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); -- seq_printf(m, "[4]R_AX_WDE_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -- seq_printf(m, "[5.1]R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); -- seq_printf(m, "[5.2]R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); -- seq_printf(m, "[6]R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -- seq_printf(m, "[7]R_AX_PKTIN_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); -- seq_printf(m, "[8.1]R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); -- seq_printf(m, "[8.2]R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); -- seq_printf(m, "[8.3]R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); -- seq_printf(m, "[10]R_AX_CPUIO_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); -- seq_printf(m, "[11.1]R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); -- seq_printf(m, "[11.2]R_AX_BBRPT_CHINFO_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR_ISR)); -- seq_printf(m, "[11.3]R_AX_BBRPT_DFS_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR_ISR)); -- seq_printf(m, "[11.4]R_AX_LA_ERRFLAG=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_LA_ERRFLAG)); -+ dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); -+ seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); -+ seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); -+ -+ if (dmac_err) { -+ seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); -+ seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); -+ seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); -+ seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); -+ seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); -+ } -+ } -+ -+ if (dmac_err & B_AX_WDRLS_ERR_FLAG) { -+ seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); -+ seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); -+ if (chip->chip_id == RTL8852C) -+ seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); -+ else -+ seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); -+ } -+ -+ if (dmac_err & B_AX_WSEC_ERR_FLAG) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); -+ seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); -+ seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -+ seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -+ seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -+ seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -+ seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); -+ seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -+ seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -+ -+ rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, -+ B_AX_DBG_SEL0, 0x8B); -+ rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, -+ B_AX_DBG_SEL1, 0x8B); -+ rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, -+ B_AX_SEL_0XC0_MASK, 1); -+ for (i = 0; i < 0x10; i++) { -+ rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL, -+ B_AX_SEC_DBG_PORT_FIELD_MASK, i); -+ seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", -+ i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); -+ } -+ } else { -+ seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); -+ seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -+ seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -+ seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -+ seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -+ seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); -+ seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -+ seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -+ seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); -+ seq_printf(m, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); -+ } -+ } -+ -+ if (dmac_err & B_AX_MPDU_ERR_FLAG) { -+ seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); -+ seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); -+ seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); -+ seq_printf(m, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); -+ } -+ -+ if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { -+ seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); -+ seq_printf(m, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); -+ } -+ -+ if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { -+ seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); -+ seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -+ seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); -+ seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -+ } -+ -+ if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); -+ seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); -+ seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); -+ seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); -+ } else { -+ seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); -+ seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); -+ } -+ } -+ -+ if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { -+ seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); -+ seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -+ seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); -+ seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -+ seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); -+ seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); -+ seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); -+ seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); -+ seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); -+ seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); -+ seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); -+ seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL0)); -+ seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL1)); -+ seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL2)); -+ } else { -+ seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); -+ seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); -+ seq_printf(m, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); -+ } -+ } -+ -+ if (dmac_err & B_AX_PKTIN_ERR_FLAG) { -+ seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); -+ seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); -+ } -+ -+ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { -+ seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); -+ seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); -+ seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); -+ seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); -+ seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); -+ seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); -+ } -+ -+ if (dmac_err & B_AX_BBRPT_ERR_FLAG) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); -+ seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); -+ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -+ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -+ seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -+ seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); -+ } else { -+ seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); -+ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -+ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -+ seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -+ seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); -+ } -+ } -+ -+ if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); -+ seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); -+ } - - return 0; - } - --static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, -- struct seq_file *m) -+static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, -+ struct seq_file *m, -+ enum rtw89_mac_idx band) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u32 offset = 0; -+ u32 cmac_err; - int ret; - -- ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL); -+ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); - if (ret) { -- seq_puts(m, "[CMAC] : CMAC 0 not enabled\n"); -+ if (band) -+ seq_puts(m, "[CMAC] : CMAC1 not enabled\n"); -+ else -+ seq_puts(m, "[CMAC] : CMAC0 not enabled\n"); - return ret; - } - -- seq_printf(m, "R_AX_CMAC_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR)); -- seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR)); -- seq_printf(m, "[1]R_AX_PTCL_ISR0=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); -- seq_printf(m, "[3]R_AX_DLE_CTRL=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_DLE_CTRL)); -- seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); -- seq_printf(m, "[5]R_AX_TXPWR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); -- seq_printf(m, "[6]R_AX_RMAC_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR)); -- seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); -+ if (band) -+ offset = RTW89_MAC_AX_BAND_REG_OFFSET; - -- ret = rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL); -- if (ret) { -- seq_puts(m, "[CMAC] : CMAC 1 not enabled\n"); -- return ret; -+ cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); -+ seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); -+ seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); -+ seq_printf(m, "R_AX_CK_EN [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CK_EN + offset)); -+ -+ if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { -+ seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); -+ seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); -+ } -+ -+ if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { -+ seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); -+ seq_printf(m, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); -+ } -+ -+ if (cmac_err & B_AX_DMA_TOP_ERR_IND) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); -+ seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); -+ } else { -+ seq_printf(m, "R_AX_DLE_CTRL [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); -+ } - } - -- seq_printf(m, "R_AX_CMAC_ERR_ISR_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR_C1)); -- seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR_C1)); -- seq_printf(m, "[1]R_AX_PTCL_ISR0_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PTCL_ISR0_C1)); -- seq_printf(m, "[3]R_AX_DLE_CTRL_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_DLE_CTRL_C1)); -- seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR_C1=0x%02x\n", -- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR_C1)); -- seq_printf(m, "[5]R_AX_TXPWR_ISR_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPWR_ISR_C1)); -- seq_printf(m, "[6]R_AX_RMAC_ERR_ISR_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR_C1)); -- seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR_C1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR_C1)); -+ if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); -+ seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); -+ } else { -+ seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); -+ } -+ } -+ -+ if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { -+ seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); -+ seq_printf(m, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); -+ } -+ -+ if (cmac_err & B_AX_WMAC_TX_ERR_IND) { -+ if (chip->chip_id == RTL8852C) { -+ seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); -+ seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); -+ } else { -+ seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); -+ } -+ seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); -+ } -+ -+ seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); -+ -+ return 0; -+} -+ -+static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, -+ struct seq_file *m) -+{ -+ rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0); -+ if (rtwdev->dbcc_en) -+ rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1); - - return 0; - } -@@ -1828,7 +2080,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x03, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -1839,7 +2091,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x04, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -1850,7 +2102,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x01, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -1861,7 +2113,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x05, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -1872,7 +2124,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x05, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -1883,7 +2135,7 @@ static const struct rtw89_mac_dbg_port_i - static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = { - .sel_addr = R_AX_PCIE_DBG_CTRL, - .sel_byte = 2, -- .sel_msk = B_AX_DBG_SEL_MASK, -+ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, - .srt = 0x00, - .end = 0x06, - .rd_addr = R_AX_DBG_PORT_SEL, -@@ -2464,7 +2716,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_ - info = &dbg_port_pcie_misc2; - val16 = rtw89_read16(rtwdev, R_AX_PCIE_DBG_CTRL); - val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL, -- B_AX_DBG_SEL_MASK); -+ B_AX_PCIE_DBG_SEL_MASK); - rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); - seq_puts(m, "Enable pcie misc2 dump.\n"); - break; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -7,6 +7,7 @@ - #include "debug.h" - #include "fw.h" - #include "mac.h" -+#include "pci.h" - #include "ps.h" - #include "reg.h" - #include "util.h" -@@ -274,106 +275,163 @@ static void rtw89_mac_dump_l0_to_l1(stru - } - } - --static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, -- enum mac_ax_err_info err) -+static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev) - { -- u32 dmac_err, cmac_err; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u32 dmac_err; -+ int i, ret; - -- if (err != MAC_AX_ERR_L1_ERR_DMAC && -- err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && -- err != MAC_AX_ERR_L0_ERR_CMAC0 && -- err != MAC_AX_ERR_L0_ERR_CMAC1) -+ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); -+ if (ret) { -+ rtw89_warn(rtwdev, "[DMAC] : DMAC not enabled\n"); - return; -+ } - -- rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); -- rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); -- -- cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR); -- rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR =0x%08x\n", cmac_err); - dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); -- rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR =0x%08x\n", dmac_err); -+ rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); -+ rtw89_info(rtwdev, "R_AX_DMAC_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); - - if (dmac_err) { -- rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG =0x%08x ", -- rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG)); -- rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG)); -+ rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); -+ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); -+ rtw89_info(rtwdev, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); -+ rtw89_info(rtwdev, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); -+ rtw89_info(rtwdev, "R_AX_PLE_DBGERR_STS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); -+ } - } - - if (dmac_err & B_AX_WDRLS_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR =0x%08x ", -+ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR =0x%08x\n", -+ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); -+ if (chip->chip_id == RTL8852C) -+ rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); -+ else -+ rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); - } - - if (dmac_err & B_AX_WSEC_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D00 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D04 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D10 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D14 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D18 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D20 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D24 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D28 =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); -- rtw89_info(rtwdev, "SEC_local_Register 0x9D2C =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); -+ rtw89_info(rtwdev, "R_AX_SEC_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); -+ rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -+ rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -+ rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -+ rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -+ rtw89_info(rtwdev, "R_AX_SEC_DEBUG1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); -+ rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -+ rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -+ -+ rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, -+ B_AX_DBG_SEL0, 0x8B); -+ rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, -+ B_AX_DBG_SEL1, 0x8B); -+ rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, -+ B_AX_SEL_0XC0_MASK, 1); -+ for (i = 0; i < 0x10; i++) { -+ rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL, -+ B_AX_SEC_DBG_PORT_FIELD_MASK, i); -+ rtw89_info(rtwdev, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", -+ i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); -+ } -+ } else { -+ rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); -+ rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -+ rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -+ rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -+ rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -+ rtw89_info(rtwdev, "R_AX_SEC_CAM_WDATA=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); -+ rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -+ rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -+ rtw89_info(rtwdev, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); -+ rtw89_info(rtwdev, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); -+ } - } - - if (dmac_err & B_AX_MPDU_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR =0x%08x ", -+ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR =0x%08x\n", -+ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); -- rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR =0x%08x ", -+ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR =0x%08x\n", -+ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); - } - - if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR =0x%08x ", -+ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR= 0x%08x\n", -+ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); - } - - if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", -+ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); - rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -- rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", -+ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); - rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -- dump_err_status_dispatcher(rtwdev); - } - - if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); -- rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); -+ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); -+ } - } - - if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", -+ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); - rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -- rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", -+ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); - rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -@@ -393,86 +451,190 @@ static void rtw89_mac_dump_err_status(st - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); - rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); -- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); -- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); -- rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); -- dump_err_status_dispatcher(rtwdev); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL0)); -+ rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL1)); -+ rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RX_CTRL2)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); -+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); -+ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); -+ } - } - - if (dmac_err & B_AX_PKTIN_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", -- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); -- rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", -+ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", -+ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR=0x%08x\n", - rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); - } - -- if (dmac_err & B_AX_DISPATCH_ERR_FLAG) -- dump_err_status_dispatcher(rtwdev); -- -- if (dmac_err & B_AX_DLE_CPUIO_ERR_FLAG) { -- rtw89_info(rtwdev, "R_AX_CPUIO_ERR_IMR=0x%08x ", -- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_CPUIO_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); -+ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { -+ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); -+ } -+ -+ if (dmac_err & B_AX_BBRPT_ERR_FLAG) { -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -+ rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); -+ } -+ } -+ -+ if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); -+ rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); - } -+} - -- if (dmac_err & BIT(11)) { -- rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); -+static void rtw89_mac_dump_cmac_err_status(struct rtw89_dev *rtwdev, -+ u8 band) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u32 offset = 0; -+ u32 cmac_err; -+ int ret; -+ -+ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); -+ if (ret) { -+ if (band) -+ rtw89_warn(rtwdev, "[CMAC] : CMAC1 not enabled\n"); -+ else -+ rtw89_warn(rtwdev, "[CMAC] : CMAC0 not enabled\n"); -+ return; - } - -+ if (band) -+ offset = RTW89_MAC_AX_BAND_REG_OFFSET; -+ -+ cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); -+ rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); -+ rtw89_info(rtwdev, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); -+ rtw89_info(rtwdev, "R_AX_CK_EN [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CK_EN + offset)); -+ - if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR=0x%08x ", -- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR)); -- rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR=0x%04x\n", -- rtw89_read16(rtwdev, R_AX_SCHEDULE_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); -+ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); - } - - if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_PTCL_IMR0=0x%08x ", -- rtw89_read32(rtwdev, R_AX_PTCL_IMR0)); -- rtw89_info(rtwdev, "R_AX_PTCL_ISR0=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); -+ rtw89_info(rtwdev, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); -+ rtw89_info(rtwdev, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); - } - - if (cmac_err & B_AX_DMA_TOP_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_DLE_CTRL=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_DLE_CTRL)); -- } -- -- if (cmac_err & B_AX_PHYINTF_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR)); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); -+ rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_DLE_CTRL [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); -+ } -+ } -+ -+ if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) { -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); -+ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); -+ } - } - - if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_TXPWR_IMR=0x%08x ", -- rtw89_read32(rtwdev, R_AX_TXPWR_IMR)); -- rtw89_info(rtwdev, "R_AX_TXPWR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); -- } -- -- if (cmac_err & B_AX_WMAC_RX_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x ", -- rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); -- rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); -+ rtw89_info(rtwdev, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); -+ rtw89_info(rtwdev, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); - } - - if (cmac_err & B_AX_WMAC_TX_ERR_IND) { -- rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR=0x%08x ", -- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); -- rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x\n", -- rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); -+ if (chip->chip_id == RTL8852C) { -+ rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); -+ rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); -+ } else { -+ rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); -+ } -+ rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); - } - -+ rtw89_info(rtwdev, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, -+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); -+} -+ -+static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, -+ enum mac_ax_err_info err) -+{ -+ if (err != MAC_AX_ERR_L1_ERR_DMAC && -+ err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && -+ err != MAC_AX_ERR_L0_ERR_CMAC0 && -+ err != MAC_AX_ERR_L0_ERR_CMAC1) -+ return; -+ -+ rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); -+ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", -+ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); -+ -+ rtw89_mac_dump_dmac_err_status(rtwdev); -+ rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_0); -+ if (rtwdev->dbcc_en) -+ rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_1); -+ - rtwdev->hci.ops->dump_err_status(rtwdev); - - if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -440,6 +440,7 @@ enum rtw89_mac_bf_rrsc_rate { - #define ACCESS_CMAC(_addr) \ - ({typeof(_addr) __addr = (_addr); \ - __addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; }) -+#define RTW89_MAC_AX_BAND_REG_OFFSET 0x2000 - - #define PTCL_IDLE_POLL_CNT 10000 - #define SW_CVR_DUR_US 8 ---- a/drivers/net/wireless/realtek/rtw89/pci.h -+++ b/drivers/net/wireless/realtek/rtw89/pci.h -@@ -202,6 +202,18 @@ - #define B_AX_RXP1DMA_INT BIT(1) - #define B_AX_RXDMA_INT BIT(0) - -+#define R_AX_HAXI_IDCT_MSK 0x10B8 -+#define B_AX_TXBD_LEN0_ERR_IDCT_MSK BIT(3) -+#define B_AX_TXBD_4KBOUND_ERR_IDCT_MSK BIT(2) -+#define B_AX_RXMDA_STUCK_IDCT_MSK BIT(1) -+#define B_AX_TXMDA_STUCK_IDCT_MSK BIT(0) -+ -+#define R_AX_HAXI_IDCT 0x10BC -+#define B_AX_TXBD_LEN0_ERR_IDCT BIT(3) -+#define B_AX_TXBD_4KBOUND_ERR_IDCT BIT(2) -+#define B_AX_RXMDA_STUCK_IDCT BIT(1) -+#define B_AX_TXMDA_STUCK_IDCT BIT(0) -+ - #define R_AX_HAXI_HIMR10 0x11E0 - #define B_AX_TXDMA_CH11_INT_EN_V1 BIT(1) - #define B_AX_TXDMA_CH10_INT_EN_V1 BIT(0) ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -326,8 +326,7 @@ - - #define R_AX_PCIE_DBG_CTRL 0x11C0 - #define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) --#define B_AX_DBG_SEL_MASK GENMASK(15, 13) --#define B_AX_PCIE_DBG_SEL BIT(12) -+#define B_AX_PCIE_DBG_SEL_MASK GENMASK(15, 13) - #define B_AX_MRD_TIMEOUT_EN BIT(10) - #define B_AX_ASFF_FULL_NO_STK BIT(1) - #define B_AX_EN_STUCK_DBG BIT(0) -@@ -574,6 +573,10 @@ - #define DMAC_ERR_IMR_DIS 0 - - #define R_AX_DMAC_ERR_ISR 0x8524 -+#define B_AX_HAXIDMA_ERR_FLAG BIT(14) -+#define B_AX_PAXIDMA_ERR_FLAG BIT(13) -+#define B_AX_HCI_BUF_ERR_FLAG BIT(12) -+#define B_AX_BBRPT_ERR_FLAG BIT(11) - #define B_AX_DLE_CPUIO_ERR_FLAG BIT(10) - #define B_AX_APB_BRIDGE_ERR_FLAG BIT(9) - #define B_AX_DISPATCH_ERR_FLAG BIT(8) -@@ -1041,7 +1044,13 @@ - #define R_AX_WDE_ERRFLAG_MSG 0x8C30 - #define B_AX_WDE_ERR_FLAG_MSG_MASK GENMASK(31, 0) - --#define R_AX_WDE_ERR_FLAG_CFG 0x8C34 -+#define R_AX_WDE_ERR_FLAG_CFG_NUM1 0x8C34 -+#define B_AX_WDE_ERR_FLAG_NUM1_VLD BIT(31) -+#define B_AX_WDE_ERR_FLAG_NUM1_MSTIDX_MASK GENMASK(27, 24) -+#define B_AX_WDE_ERR_FLAG_NUM1_ISRIDX_MASK GENMASK(20, 16) -+#define B_AX_WDE_DATCHN_FRZTMR_MODE BIT(2) -+#define B_AX_WDE_QUEMGN_FRZTMR_MODE BIT(1) -+#define B_AX_WDE_BUFMGN_FRZTMR_MODE BIT(0) - - #define R_AX_WDE_ERR_IMR 0x8C38 - #define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27) -@@ -1225,7 +1234,59 @@ - #define B_AX_PLE_START_BOUND_MASK GENMASK(13, 8) - #define B_AX_PLE_PAGE_SEL_MASK GENMASK(1, 0) - #define B_AX_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16) --#define R_AX_PLE_ERR_FLAG_CFG 0x9034 -+ -+#define R_AX_PLE_DBGERR_LOCKEN 0x9020 -+#define B_AX_PLE_LOCKEN_DLEPIF07 BIT(7) -+#define B_AX_PLE_LOCKEN_DLEPIF06 BIT(6) -+#define B_AX_PLE_LOCKEN_DLEPIF05 BIT(5) -+#define B_AX_PLE_LOCKEN_DLEPIF04 BIT(4) -+#define B_AX_PLE_LOCKEN_DLEPIF03 BIT(3) -+#define B_AX_PLE_LOCKEN_DLEPIF02 BIT(2) -+#define B_AX_PLE_LOCKEN_DLEPIF01 BIT(1) -+#define B_AX_PLE_LOCKEN_DLEPIF00 BIT(0) -+ -+#define R_AX_PLE_DBGERR_STS 0x9024 -+#define B_AX_PLE_LOCKON_DLEPIF07 BIT(7) -+#define B_AX_PLE_LOCKON_DLEPIF06 BIT(6) -+#define B_AX_PLE_LOCKON_DLEPIF05 BIT(5) -+#define B_AX_PLE_LOCKON_DLEPIF04 BIT(4) -+#define B_AX_PLE_LOCKON_DLEPIF03 BIT(3) -+#define B_AX_PLE_LOCKON_DLEPIF02 BIT(2) -+#define B_AX_PLE_LOCKON_DLEPIF01 BIT(1) -+#define B_AX_PLE_LOCKON_DLEPIF00 BIT(0) -+ -+#define R_AX_PLE_ERR_FLAG_CFG_NUM1 0x9034 -+#define B_AX_PLE_ERR_FLAG_NUM1_VLD BIT(31) -+#define B_AX_PLE_ERR_FLAG_NUM1_MSTIDX_MASK GENMASK(27, 24) -+#define B_AX_PLE_ERR_FLAG_NUM1_ISRIDX_MASK GENMASK(20, 16) -+#define B_AX_PLE_DATCHN_FRZTMR_MODE BIT(2) -+#define B_AX_PLE_QUEMGN_FRZTMR_MODE BIT(1) -+#define B_AX_PLE_BUFMGN_FRZTMR_MODE BIT(0) -+ -+#define R_AX_PLE_ERRFLAG_MSG 0x9030 -+#define B_AX_PLE_ERR_FLAG_MSG_MASK GENMASK(31, 0) -+#define B_AX_PLE_DATCHN_CAMREQ_ERR_INT_EN BIT(29) -+#define B_AX_PLE_DATCHN_ADRERR_ERR_INT_EN BIT(28) -+#define B_AX_PLE_BUFMGN_FRZTO_ERR_INT_EN_V1 BIT(9) -+#define B_AX_PLE_GETNPG_PGOFST_ERR_INT_EN_V1 BIT(8) -+#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN_V1 BIT(7) -+#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_INT_EN_V1 BIT(6) -+#define B_AX_PLE_BUFRTN_SIZE_ERR_INT_EN_V1 BIT(5) -+#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_INT_EN_V1 BIT(4) -+#define B_AX_PLE_BUFREQ_UNAVAL_ERR_INT_EN_V1 BIT(3) -+#define B_AX_PLE_BUFREQ_SIZELMT_INT_EN BIT(2) -+#define B_AX_PLE_BUFREQ_SIZE0_INT_EN BIT(1) -+#define B_AX_PLE_DATCHN_CAMREQ_ERR BIT(29) -+#define B_AX_PLE_DATCHN_ADRERR_ERR BIT(28) -+#define B_AX_PLE_BUFMGN_FRZTO_ERR_V1 BIT(9) -+#define B_AX_PLE_GETNPG_PGOFST_ERR_V1 BIT(8) -+#define B_AX_PLE_GETNPG_STRPG_ERR_V1 BIT(7) -+#define B_AX_PLE_BUFREQ_SRCHTAILPG_ERR_V1 BIT(6) -+#define B_AX_PLE_BUFRTN_SIZE_ERR_V1 BIT(5) -+#define B_AX_PLE_BUFRTN_INVLD_PKTID_ERR_V1 BIT(4) -+#define B_AX_PLE_BUFREQ_UNAVAL_ERR_V1 BIT(3) -+#define B_AX_PLE_BUFREQ_SIZELMT_ERR BIT(2) -+#define B_AX_PLE_BUFREQ_SIZE0_ERR BIT(1) - - #define R_AX_PLE_ERR_IMR 0x9038 - #define B_AX_PLE_DATCHN_RRDY_ERR_INT_EN BIT(27) -@@ -1436,6 +1497,19 @@ - #define B_AX_BBRPT_COM_NULL_PLPKTID_ERR BIT(16) - #define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN BIT(0) - -+#define R_AX_BBRPT_COM_ERR_ISR 0x960C -+#define B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_V1 BIT(0) -+ -+#define R_AX_BBRPT_CHINFO_ERR_ISR 0x962C -+#define B_AX_BBPRT_CHIF_TO_ERR_V1 BIT(7) -+#define B_AX_BBPRT_CHIF_NULL_ERR_V1 BIT(6) -+#define B_AX_BBPRT_CHIF_LEFT2_ERR_V1 BIT(5) -+#define B_AX_BBPRT_CHIF_LEFT1_ERR_V1 BIT(4) -+#define B_AX_BBPRT_CHIF_HDRL_ERR_V1 BIT(3) -+#define B_AX_BBPRT_CHIF_BOVF_ERR_V1 BIT(2) -+#define B_AX_BBPRT_CHIF_OVF_ERR_V1 BIT(1) -+#define B_AX_BBPRT_CHIF_BB_TO_ERR_V1 BIT(0) -+ - #define R_AX_BBRPT_CHINFO_ERR_IMR 0x9628 - #define B_AX_BBPRT_CHIF_TO_ERR_INT_EN BIT(7) - #define B_AX_BBPRT_CHIF_NULL_ERR_INT_EN BIT(6) -@@ -1487,6 +1561,9 @@ - #define B_AX_BBRPT_DFS_TO_ERR BIT(16) - #define B_AX_BBRPT_DFS_TO_ERR_INT_EN BIT(0) - -+#define R_AX_BBRPT_DFS_ERR_ISR 0x963C -+#define B_AX_BBRPT_DFS_TO_ERR_V1 BIT(0) -+ - #define R_AX_LA_ERRFLAG 0x966C - #define B_AX_LA_ISR_DATA_LOSS_ERR BIT(16) - #define B_AX_LA_IMR_DATA_LOSS_ERR BIT(0) -@@ -1602,6 +1679,7 @@ - #define B_AX_MPDU_RX_IMR_SET_V1 B_AX_RPT_ERR_INT_EN - - #define R_AX_SEC_ENG_CTRL 0x9D00 -+#define B_AX_SEC_DBG_PORT_FIELD_MASK GENMASK(19, 16) - #define B_AX_TX_PARTIAL_MODE BIT(11) - #define B_AX_CLK_EN_CGCMP BIT(10) - #define B_AX_CLK_EN_WAPI BIT(9) -@@ -1631,12 +1709,21 @@ - #define R_AX_SEC_TX_DEBUG 0x9D20 - #define R_AX_SEC_RX_DEBUG 0x9D24 - #define R_AX_SEC_TRX_PKT_CNT 0x9D28 -+ -+#define R_AX_SEC_DEBUG2 0x9D28 -+#define B_AX_DBG_READ_SH 2 -+#define B_AX_DBG_READ_MSK 0x3fffffff -+ - #define R_AX_SEC_TRX_BLK_CNT 0x9D2C - - #define R_AX_SEC_ERROR_FLAG_IMR 0x9D2C - #define B_AX_RX_HANG_IMR BIT(1) - #define B_AX_TX_HANG_IMR BIT(0) - -+#define R_AX_SEC_ERROR_FLAG 0x9D30 -+#define B_AX_RX_HANG_ERROR_V1 BIT(1) -+#define B_AX_TX_HANG_ERROR_V1 BIT(0) -+ - #define R_AX_SS_CTRL 0x9E10 - #define B_AX_SS_INIT_DONE_1 BIT(31) - #define B_AX_SS_WARM_INIT_FLG BIT(29) -@@ -1771,6 +1858,28 @@ - B_AX_B0_IMR_ERR_PRELD_RLSPKTSZERR | \ - B_AX_B0_IMR_ERR_PRELD_ENTNUMCFG) - -+#define R_AX_TXPKTCTL_B0_ERRFLAG_ISR 0x9F7C -+#define B_AX_B0_ISR_ERR_PRELD_EVT3 BIT(23) -+#define B_AX_B0_ISR_ERR_PRELD_EVT2 BIT(22) -+#define B_AX_B0_ISR_ERR_PRELD_ENTNUMCFG BIT(21) -+#define B_AX_B0_ISR_ERR_PRELD_RLSPKTSZERR BIT(20) -+#define B_AX_B0_ISR_ERR_MPDUIF_ERR1 BIT(19) -+#define B_AX_B0_ISR_ERR_MPDUIF_DATAERR BIT(18) -+#define B_AX_B0_ISR_ERR_MPDUINFO_ERR1 BIT(17) -+#define B_AX_B0_ISR_ERR_MPDUINFO_RECFG BIT(16) -+#define B_AX_B0_ISR_ERR_CMDPSR_TBLSZ BIT(11) -+#define B_AX_B0_ISR_ERR_CMDPSR_FRZTO BIT(10) -+#define B_AX_B0_ISR_ERR_CMDPSR_CMDTYPE BIT(9) -+#define B_AX_B0_ISR_ERR_CMDPSR_1STCMDERR BIT(8) -+#define B_AX_B0_ISR_ERR_USRCTL_EVT7 BIT(7) -+#define B_AX_B0_ISR_ERR_USRCTL_EVT6 BIT(6) -+#define B_AX_B0_ISR_ERR_USRCTL_EVT5 BIT(5) -+#define B_AX_B0_ISR_ERR_USRCTL_EVT4 BIT(4) -+#define B_AX_B0_ISR_ERR_USRCTL_RLSBMPLEN BIT(3) -+#define B_AX_B0_ISR_ERR_USRCTL_RDNRLSCMD BIT(2) -+#define B_AX_B0_ISR_ERR_USRCTL_NOINIT BIT(1) -+#define B_AX_B0_ISR_ERR_USRCTL_REINIT BIT(0) -+ - #define R_AX_TXPKTCTL_B1_PRELD_CFG0 0x9F88 - #define B_AX_B1_PRELD_FEN BIT(31) - #define B_AX_B1_PRELD_USEMAXSZ_MASK GENMASK(25, 16) -@@ -1818,6 +1927,28 @@ - B_AX_B1_IMR_ERR_PRELD_RLSPKTSZERR | \ - B_AX_B1_IMR_ERR_PRELD_ENTNUMCFG) - -+#define R_AX_TXPKTCTL_B1_ERRFLAG_ISR 0x9FBC -+#define B_AX_B1_ISR_ERR_PRELD_EVT3 BIT(23) -+#define B_AX_B1_ISR_ERR_PRELD_EVT2 BIT(22) -+#define B_AX_B1_ISR_ERR_PRELD_ENTNUMCFG BIT(21) -+#define B_AX_B1_ISR_ERR_PRELD_RLSPKTSZERR BIT(20) -+#define B_AX_B1_ISR_ERR_MPDUIF_ERR1 BIT(19) -+#define B_AX_B1_ISR_ERR_MPDUIF_DATAERR BIT(18) -+#define B_AX_B1_ISR_ERR_MPDUINFO_ERR1 BIT(17) -+#define B_AX_B1_ISR_ERR_MPDUINFO_RECFG BIT(16) -+#define B_AX_B1_ISR_ERR_CMDPSR_TBLSZ BIT(11) -+#define B_AX_B1_ISR_ERR_CMDPSR_FRZTO BIT(10) -+#define B_AX_B1_ISR_ERR_CMDPSR_CMDTYPE BIT(9) -+#define B_AX_B1_ISR_ERR_CMDPSR_1STCMDERR BIT(8) -+#define B_AX_B1_ISR_ERR_USRCTL_EVT7 BIT(7) -+#define B_AX_B1_ISR_ERR_USRCTL_EVT6 BIT(6) -+#define B_AX_B1_ISR_ERR_USRCTL_EVT5 BIT(5) -+#define B_AX_B1_ISR_ERR_USRCTL_EVT4 BIT(4) -+#define B_AX_B1_ISR_ERR_USRCTL_RLSBMPLEN BIT(3) -+#define B_AX_B1_ISR_ERR_USRCTL_RDNRLSCMD BIT(2) -+#define B_AX_B1_ISR_ERR_USRCTL_NOINIT BIT(1) -+#define B_AX_B1_ISR_ERR_USRCTL_REINIT BIT(0) -+ - #define R_AX_AFE_CTRL1 0x0024 - - #define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) -@@ -2386,6 +2517,41 @@ - #define B_AX_DLE_IMR_SET (B_AX_RXSTS_FSM_HANG_ERROR_IMR | \ - B_AX_RXDATA_FSM_HANG_ERROR_IMR) - -+#define R_AX_RX_ERR_FLAG 0xC800 -+#define R_AX_RX_ERR_FLAG_C1 0xE800 -+#define B_AX_RX_GET_NO_PAGE_ERR BIT(31) -+#define B_AX_RX_GET_NULL_PKT_ERR BIT(30) -+#define B_AX_RX_RU0_FSM_HANG_ERR BIT(29) -+#define B_AX_RX_RU1_FSM_HANG_ERR BIT(28) -+#define B_AX_RX_RU2_FSM_HANG_ERR BIT(27) -+#define B_AX_RX_RU3_FSM_HANG_ERR BIT(26) -+#define B_AX_RX_RU4_FSM_HANG_ERR BIT(25) -+#define B_AX_RX_RU5_FSM_HANG_ERR BIT(24) -+#define B_AX_RX_RU6_FSM_HANG_ERR BIT(23) -+#define B_AX_RX_RU7_FSM_HANG_ERR BIT(22) -+#define B_AX_RX_RXSTS_FSM_HANG_ERR BIT(21) -+#define B_AX_RX_CSI_FSM_HANG_ERR BIT(20) -+#define B_AX_RX_TXRPT_FSM_HANG_ERR BIT(19) -+#define B_AX_RX_F2PCMD_FSM_HANG_ERR BIT(18) -+#define B_AX_RX_RU0_ZERO_LEN_ERR BIT(17) -+#define B_AX_RX_RU1_ZERO_LEN_ERR BIT(16) -+#define B_AX_RX_RU2_ZERO_LEN_ERR BIT(15) -+#define B_AX_RX_RU3_ZERO_LEN_ERR BIT(14) -+#define B_AX_RX_RU4_ZERO_LEN_ERR BIT(13) -+#define B_AX_RX_RU5_ZERO_LEN_ERR BIT(12) -+#define B_AX_RX_RU6_ZERO_LEN_ERR BIT(11) -+#define B_AX_RX_RU7_ZERO_LEN_ERR BIT(10) -+#define B_AX_RX_RXSTS_ZERO_LEN_ERR BIT(9) -+#define B_AX_RX_CSI_ZERO_LEN_ERR BIT(8) -+#define B_AX_PLE_DATA_OPT_FSM_HANG BIT(7) -+#define B_AX_PLE_RXDATA_REQ_BUF_FSM_HANG BIT(6) -+#define B_AX_PLE_TXRPT_REQ_BUF_FSM_HANG BIT(5) -+#define B_AX_PLE_WD_OPT_FSM_HANG BIT(4) -+#define B_AX_PLE_ENQ_FSM_HANG BIT(3) -+#define B_AX_RXDATA_ENQUE_ORDER_ERR BIT(2) -+#define B_AX_RXSTS_ENQUE_ORDER_ERR BIT(1) -+#define B_AX_RX_CSI_PKT_NUM_ERR BIT(0) -+ - #define R_AX_RXDMA_CTRL_0 0xC804 - #define R_AX_RXDMA_CTRL_0_C1 0xE804 - #define B_AX_RXDMA_DBGOUT_EN BIT(31) -@@ -2408,6 +2574,49 @@ - B_AX_RU2_PTR_FULL_MODE | B_AX_RU3_PTR_FULL_MODE | \ - B_AX_CSI_PTR_FULL_MODE | B_AX_RXSTS_PTR_FULL_MODE) - -+#define R_AX_RX_CTRL0 0xC808 -+#define R_AX_RX_CTRL0_C1 0xE808 -+#define B_AX_DLE_CLOCK_FORCE_V1 BIT(31) -+#define B_AX_TXDMA_CLOCK_FORCE_V1 BIT(30) -+#define B_AX_RXDMA_CLOCK_FORCE_V1 BIT(29) -+#define B_AX_RXDMA_DEFAULT_PAGE_V1_MASK GENMASK(28, 24) -+#define B_AX_RXDMA_CSI_TGT_QUEID_MASK GENMASK(23, 18) -+#define B_AX_RXDMA_CSI_TGT_PRID_MASK GENMASK(17, 15) -+#define B_AX_RXDMA_DIS_CSI_RELEASE_V1 BIT(14) -+#define B_AX_CSI_PTR_FULL_MODE_V1 BIT(13) -+#define B_AX_RXDATA_PTR_FULL_MODE BIT(12) -+#define B_AX_RXSTS_PTR_FULL_MODE_V1 BIT(11) -+#define B_AX_TXRPT_FULL_RSV_DEPTH_V1_MASK GENMASK(10, 8) -+#define B_AX_RXDATA_FULL_RSV_DEPTH_MASK GENMASK(7, 5) -+#define B_AX_RXSTS_FULL_RSV_DEPTH_V1_MASK GENMASK(4, 2) -+#define B_AX_ORDER_FIFO_MASK GENMASK(1, 0) -+ -+#define R_AX_RX_CTRL1 0xC80C -+#define R_AX_RX_CTRL1_C1 0xE80C -+#define B_AX_RXDMA_TXRPT_QUEUE_ID_SW_EN BIT(31) -+#define B_AX_RXDMA_TXRPT_QUEUE_ID_SW_V1_MASK GENMASK(30, 25) -+#define B_AX_RXDMA_F2PCMD_QUEUE_ID_SW_EN BIT(24) -+#define B_AX_RXDMA_F2PCMD_QUEUE_ID_SW_V1_MASK GENMASK(23, 18) -+#define B_AX_RXDMA_TXRPT_QUEUE_ID_TGT_SW_EN BIT(17) -+#define B_AX_RXDMA_TXRPT_QUEUE_ID_TGT_SW_1_MASK GENMASK(16, 11) -+#define B_AX_RXDMA_F2PCMD_QUEUE_ID_TGT_SW_EN BIT(10) -+#define B_AX_RXDMA_F2PCMD_QUEUE_ID_TGT_SW_1_MASK GENMASK(9, 4) -+#define B_AX_ORDER_FIFO_OUT BIT(3) -+#define B_AX_ORDER_FIFO_EMPTY BIT(2) -+#define B_AX_DBG_SEL_MASK GENMASK(1, 0) -+ -+#define R_AX_RX_CTRL2 0xC810 -+#define R_AX_RX_CTRL2_C1 0xE810 -+#define B_AX_DLE_WDE_STATE_V1_MASK GENMASK(31, 30) -+#define B_AX_DLE_PLE_STATE_V1_MASK GENMASK(29, 28) -+#define B_AX_DLE_REQ_BUF_STATE_MASK GENMASK(27, 26) -+#define B_AX_DLE_ENQ_STATE_V1 BIT(25) -+#define B_AX_RX_DBG_SEL_MASK GENMASK(24, 19) -+#define B_AX_MACRX_CS_MASK GENMASK(18, 14) -+#define B_AX_RXSTS_CS_MASK GENMASK(13, 9) -+#define B_AX_ERR_INDICATOR BIT(5) -+#define B_AX_TXRPT_CS_MASK GENMASK(4, 0) -+ - #define R_AX_RXDMA_PKT_INFO_0 0xC814 - #define R_AX_RXDMA_PKT_INFO_1 0xC818 - #define R_AX_RXDMA_PKT_INFO_2 0xC81C -@@ -2715,6 +2924,18 @@ - B_AX_TMAC_MIMO_CTRL | \ - B_AX_RMAC_FTM) - -+#define R_AX_TRXPTCL_ERROR_INDICA 0xCCC0 -+#define R_AX_TRXPTCL_ERROR_INDICA_C1 0xECC0 -+#define B_AX_FTM_ERROR_FLAG_CLR BIT(8) -+#define B_AX_CSI_ERROR_FLAG_CLR BIT(7) -+#define B_AX_MIMOCTRL_ERROR_FLAG_CLR BIT(6) -+#define B_AX_RXTB_ERROR_FLAG_CLR BIT(5) -+#define B_AX_HWSIGB_GEN_ERROR_FLAG_CLR BIT(4) -+#define B_AX_TXPLCP_ERROR_FLAG_CLR BIT(3) -+#define B_AX_RESP_ERROR_FLAG_CLR BIT(2) -+#define B_AX_TXCTL_ERROR_FLAG_CLR BIT(1) -+#define B_AX_MACTX_ERROR_FLAG_CLR BIT(0) -+ - #define R_AX_WMAC_TX_TF_INFO_0 0xCCD0 - #define R_AX_WMAC_TX_TF_INFO_0_C1 0xECD0 - #define B_AX_WMAC_TX_TF_INFO_SEL_MASK GENMASK(2, 0) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-060-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-060-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch deleted file mode 100644 index 6d1716834..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-060-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 901c247f9687b5aecc950a931a3b0e1930d02bfd Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 8 Nov 2022 09:42:30 +0800 -Subject: [PATCH 060/149] wifi: rtw89: 8852b: change debug mask of message of - no TX resource - -8852B has smaller TX FIFO than others in WiFi chip, so it would be buffer -full frequently, but it doesn't affect TX performance. However, it shows -verbose debug messages with RTW89_DBG_UNEXP mask that is used to indicate -abnormal behavior, so change debug mask to RTW89_DBG_TXRX for 8852B. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221108014230.11068-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/pci.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -971,8 +971,10 @@ static u32 __rtw89_pci_check_and_reclaim - struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; - struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; - struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; -+ const struct rtw89_chip_info *chip = rtwdev->chip; - u32 bd_cnt, wd_cnt, min_cnt = 0; - struct rtw89_pci_rx_ring *rx_ring; -+ enum rtw89_debug_mask debug_mask; - u32 cnt; - - rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ]; -@@ -996,10 +998,20 @@ static u32 __rtw89_pci_check_and_reclaim - bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); - wd_cnt = wd_ring->curr_num; - min_cnt = min(bd_cnt, wd_cnt); -- if (min_cnt == 0) -- rtw89_debug(rtwdev, rtwpci->low_power ? RTW89_DBG_TXRX : RTW89_DBG_UNEXP, -+ if (min_cnt == 0) { -+ /* This message can be frequently shown in low power mode or -+ * high traffic with 8852B, and we have recognized it as normal -+ * behavior, so print with mask RTW89_DBG_TXRX in these situations. -+ */ -+ if (rtwpci->low_power || chip->chip_id == RTL8852B) -+ debug_mask = RTW89_DBG_TXRX; -+ else -+ debug_mask = RTW89_DBG_UNEXP; -+ -+ rtw89_debug(rtwdev, debug_mask, - "still no tx resource after reclaim: wd_cnt=%d bd_cnt=%d\n", - wd_cnt, bd_cnt); -+ } - - out_unlock: - spin_unlock_bh(&rtwpci->trx_lock); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-061-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-061-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch deleted file mode 100644 index 1c6d146a3..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-061-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 61ec34dee266f1cea092986d861a2cb136571199 Mon Sep 17 00:00:00 2001 -From: Christophe JAILLET -Date: Sun, 13 Nov 2022 16:42:21 +0100 -Subject: [PATCH 061/149] wifi: rtw89: Fix some error handling path in - rtw89_wow_enable() - -'ret' is not updated after several function calls in rtw89_wow_enable(). -This prevent error handling from working. - -Add the missing assignments. - -Fixes: 19e28c7fcc74 ("wifi: rtw89: add WoWLAN function support") -Signed-off-by: Christophe JAILLET -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/32320176eeff1c635baeea25ef0e87d116859e65.1668354083.git.christophe.jaillet@wanadoo.fr ---- - drivers/net/wireless/realtek/rtw89/wow.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -744,13 +744,13 @@ static int rtw89_wow_enable(struct rtw89 - goto out; - } - -- rtw89_wow_swap_fw(rtwdev, true); -+ ret = rtw89_wow_swap_fw(rtwdev, true); - if (ret) { - rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); - goto out; - } - -- rtw89_wow_fw_start(rtwdev); -+ ret = rtw89_wow_fw_start(rtwdev); - if (ret) { - rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); - goto out; -@@ -758,7 +758,7 @@ static int rtw89_wow_enable(struct rtw89 - - rtw89_wow_enter_lps(rtwdev); - -- rtw89_wow_enable_trx_post(rtwdev); -+ ret = rtw89_wow_enable_trx_post(rtwdev); - if (ret) { - rtw89_err(rtwdev, "wow: failed to enable trx_post\n"); - goto out; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-063-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-063-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch deleted file mode 100644 index 6af33c279..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-063-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 79ca91a3c1f1e5d871f393791e7538f9386a7711 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 17 Nov 2022 14:18:32 +0800 -Subject: [PATCH 063/149] wifi: rtw89: 8852b: correct TX power controlled by - BT-coexistence - -When coexistence mechanism is under free-run mode, it could adjust WiFi -and BT TX power to avoid interference with each other. For other cases, -it should keep original TX power from regular predefined tables, so -set correct values to 255 for these cases. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221117061832.42057-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 30 +++++++++---------- - 1 file changed, 15 insertions(+), 15 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -318,27 +318,27 @@ static const struct rtw89_dig_regs rtw88 - }; - - static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = { -- {15, 0, 0, 7}, /* 0 -> original */ -- {15, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ -- {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -- {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -- {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 0, 0, 7}, /* 0 -> original */ -+ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ -+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ - {6, 1, 0, 7}, - {13, 1, 0, 7}, - {13, 1, 0, 7} - }; - - static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_dl[] = { -- {15, 0, 0, 7}, /* 0 -> original */ -- {15, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ -- {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -- {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -- {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -- {15, 1, 0, 7}, -- {15, 1, 0, 7}, -- {15, 1, 0, 7} -+ {255, 0, 0, 7}, /* 0 -> original */ -+ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, -+ {255, 1, 0, 7}, -+ {255, 1, 0, 7} - }; - - static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-064-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-064-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch deleted file mode 100644 index d6c190b59..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-064-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 10cd4092f67eaf0cade4f50c68ecb055d4ee3a93 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Thu, 17 Nov 2022 14:30:00 +0800 -Subject: [PATCH 064/149] wifi: rtw89: read CFO from FD or preamble CFO field - of phy status ie_type 1 accordingly - -Add macro to get FD(frequency domain) CFO field from ie_type 1, and correct -the naming for preamble CFO field. Each IC could assign the CFO source to -either FD CFO or preamble CFO in chip_info. Based on the suggestion from HW -designer, rtw8852b and its derived versions will have better CFO tracking -performance with FD CFO. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221117063001.42967-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 +++++- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - drivers/net/wireless/realtek/rtw89/txrx.h | 4 +++- - 6 files changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1196,7 +1196,11 @@ static void rtw89_core_parse_phy_status_ - if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) - return; - /* sign conversion for S(12,2) */ -- cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_CFO(addr), 11); -+ if (rtwdev->chip->cfo_src_fd) -+ cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_FD_CFO(addr), 11); -+ else -+ cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_PREMB_CFO(addr), 11); -+ - rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); - } - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2755,6 +2755,7 @@ struct rtw89_chip_info { - u32 c2h_ctrl_reg; - const u32 *c2h_regs; - const struct rtw89_page_regs *page_regs; -+ bool cfo_src_fd; - const struct rtw89_reg_def *dcfo_comp; - u8 dcfo_comp_sft; - const struct rtw89_imr_info *imr_info; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2143,6 +2143,7 @@ const struct rtw89_chip_info rtw8852a_ch - .c2h_ctrl_reg = R_AX_C2HREG_CTRL, - .c2h_regs = rtw8852a_c2h_regs, - .page_regs = &rtw8852a_page_regs, -+ .cfo_src_fd = false, - .dcfo_comp = &rtw8852a_dcfo_comp, - .dcfo_comp_sft = 3, - .imr_info = &rtw8852a_imr_info, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2512,6 +2512,7 @@ const struct rtw89_chip_info rtw8852b_ch - .c2h_ctrl_reg = R_AX_C2HREG_CTRL, - .c2h_regs = rtw8852b_c2h_regs, - .page_regs = &rtw8852b_page_regs, -+ .cfo_src_fd = true, - .dcfo_comp = &rtw8852b_dcfo_comp, - .dcfo_comp_sft = 3, - .imr_info = &rtw8852b_imr_info, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2953,6 +2953,7 @@ const struct rtw89_chip_info rtw8852c_ch - .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, - .c2h_regs = rtw8852c_c2h_regs, - .page_regs = &rtw8852c_page_regs, -+ .cfo_src_fd = false, - .dcfo_comp = &rtw8852c_dcfo_comp, - .dcfo_comp_sft = 5, - .imr_info = &rtw8852c_imr_info, ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -298,7 +298,9 @@ - le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5)) - #define RTW89_GET_PHY_STS_IE01_CH_IDX(ie) \ - le32_get_bits(*((const __le32 *)ie), GENMASK(23, 16)) --#define RTW89_GET_PHY_STS_IE01_CFO(ie) \ -+#define RTW89_GET_PHY_STS_IE01_FD_CFO(ie) \ -+ le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(19, 8)) -+#define RTW89_GET_PHY_STS_IE01_PREMB_CFO(ie) \ - le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(31, 20)) - - enum rtw89_tx_channel { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-065-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-065-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch deleted file mode 100644 index 6c817d8c2..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-065-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 29136c95fdc5d9bbfb56131408388fefdba4ed95 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Thu, 17 Nov 2022 14:30:01 +0800 -Subject: [PATCH 065/149] wifi: rtw89: switch BANDEDGE and TX_SHAPE based on - OFDMA trigger frame - -There are some registers for transmit waveform control, two of them used -in this change are for BANDEDGE and TX_SHAPE control. BANDEDGE controls -whether to apply band edge filter to transmit waveform. TX_SHAPE controls -whether to apply triangular mask to transmit waveform. It is found for -some chip, these two should be turned off during OFDMA UL traffic for -better performance. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221117063001.42967-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 + - drivers/net/wireless/realtek/rtw89/core.h | 9 ++ - drivers/net/wireless/realtek/rtw89/debug.h | 1 + - drivers/net/wireless/realtek/rtw89/phy.c | 127 +++++++++++++++++- - drivers/net/wireless/realtek/rtw89/phy.h | 5 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 8 files changed, 146 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2237,6 +2237,7 @@ static void rtw89_track_work(struct work - rtw89_phy_ra_update(rtwdev); - rtw89_phy_cfo_track(rtwdev); - rtw89_phy_tx_path_div_track(rtwdev); -+ rtw89_phy_ul_tb_ctrl_track(rtwdev); - - if (rtwdev->lps_enabled && !rtwdev->btc.lps) - rtw89_enter_lps_track(rtwdev); -@@ -2560,6 +2561,7 @@ int rtw89_core_sta_assoc(struct rtw89_de - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, - BTC_ROLE_MSTS_STA_CONN_END); - rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); -+ rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); - } - - return ret; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2261,6 +2261,8 @@ struct rtw89_vif { - bool wowlan_magic; - bool is_hesta; - bool last_a_ctrl; -+ bool dyn_tb_bedge_en; -+ u8 def_tri_idx; - struct work_struct update_beacon_work; - struct rtw89_addr_cam_entry addr_cam; - struct rtw89_bssid_cam_entry bssid_cam; -@@ -2646,6 +2648,11 @@ struct rtw89_dig_regs { - struct rtw89_reg_def p1_s20_pagcugc_en; - }; - -+struct rtw89_phy_ul_tb_info { -+ bool dyn_tb_tri_en; -+ u8 def_if_bandedge; -+}; -+ - struct rtw89_chip_info { - enum rtw89_core_chip_id chip_id; - const struct rtw89_chip_ops *ops; -@@ -2663,6 +2670,7 @@ struct rtw89_chip_info { - u8 support_chanctx_num; - u8 support_bands; - bool support_bw160; -+ bool support_ul_tb_ctrl; - bool hw_sec_hdr; - u8 rf_path_num; - u8 tx_nss; -@@ -3585,6 +3593,7 @@ struct rtw89_dev { - struct rtw89_phy_ch_info ch_info; - struct rtw89_phy_bb_gain_info bb_gain; - struct rtw89_phy_efuse_gain efuse_gain; -+ struct rtw89_phy_ul_tb_info ul_tb_info; - - struct delayed_work track_work; - struct delayed_work coex_act1_work; ---- a/drivers/net/wireless/realtek/rtw89/debug.h -+++ b/drivers/net/wireless/realtek/rtw89/debug.h -@@ -27,6 +27,7 @@ enum rtw89_debug_mask { - RTW89_DBG_SAR = BIT(16), - RTW89_DBG_STATE = BIT(17), - RTW89_DBG_WOW = BIT(18), -+ RTW89_DBG_UL_TB = BIT(19), - - RTW89_DBG_UNEXP = BIT(31), - }; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2,6 +2,7 @@ - /* Copyright(c) 2019-2020 Realtek Corporation - */ - -+#include "coex.h" - #include "debug.h" - #include "fw.h" - #include "mac.h" -@@ -9,7 +10,7 @@ - #include "ps.h" - #include "reg.h" - #include "sar.h" --#include "coex.h" -+#include "util.h" - - static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, - const struct rtw89_ra_report *report) -@@ -2794,6 +2795,129 @@ void rtw89_phy_cfo_parse(struct rtw89_de - cfo->packet_count++; - } - -+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; -+ -+ if (!chip->support_ul_tb_ctrl) -+ return; -+ -+ rtwvif->def_tri_idx = -+ rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG); -+ -+ if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV) -+ rtwvif->dyn_tb_bedge_en = false; -+ else if (chan->band_type >= RTW89_BAND_5G && -+ chan->band_width >= RTW89_CHANNEL_WIDTH_40) -+ rtwvif->dyn_tb_bedge_en = true; -+ else -+ rtwvif->dyn_tb_bedge_en = false; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n", -+ ul_tb_info->def_if_bandedge, rtwvif->def_tri_idx); -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n", -+ rtwvif->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en); -+} -+ -+struct rtw89_phy_ul_tb_check_data { -+ bool valid; -+ bool high_tf_client; -+ bool low_tf_client; -+ bool dyn_tb_bedge_en; -+ u8 def_tri_idx; -+}; -+ -+static -+void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_phy_ul_tb_check_data *ul_tb_data) -+{ -+ struct rtw89_traffic_stats *stats = &rtwdev->stats; -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ -+ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) -+ return; -+ -+ if (!vif->cfg.assoc) -+ return; -+ -+ if (stats->rx_tf_periodic > UL_TB_TF_CNT_L2H_TH) -+ ul_tb_data->high_tf_client = true; -+ else if (stats->rx_tf_periodic < UL_TB_TF_CNT_H2L_TH) -+ ul_tb_data->low_tf_client = true; -+ -+ ul_tb_data->valid = true; -+ ul_tb_data->def_tri_idx = rtwvif->def_tri_idx; -+ ul_tb_data->dyn_tb_bedge_en = rtwvif->dyn_tb_bedge_en; -+} -+ -+void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; -+ struct rtw89_phy_ul_tb_check_data ul_tb_data = {}; -+ struct rtw89_vif *rtwvif; -+ -+ if (!chip->support_ul_tb_ctrl) -+ return; -+ -+ if (rtwdev->total_sta_assoc != 1) -+ return; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif, &ul_tb_data); -+ -+ if (!ul_tb_data.valid) -+ return; -+ -+ if (ul_tb_data.dyn_tb_bedge_en) { -+ if (ul_tb_data.high_tf_client) { -+ rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0); -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] Turn off if_bandedge\n"); -+ } else if (ul_tb_data.low_tf_client) { -+ rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, -+ ul_tb_info->def_if_bandedge); -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] Set to default if_bandedge = %d\n", -+ ul_tb_info->def_if_bandedge); -+ } -+ } -+ -+ if (ul_tb_info->dyn_tb_tri_en) { -+ if (ul_tb_data.high_tf_client) { -+ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, -+ B_TXSHAPE_TRIANGULAR_CFG, 0); -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] Turn off Tx triangle\n"); -+ } else if (ul_tb_data.low_tf_client) { -+ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, -+ B_TXSHAPE_TRIANGULAR_CFG, -+ ul_tb_data.def_tri_idx); -+ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, -+ "[ULTB] Set to default tx_shap_idx = %d\n", -+ ul_tb_data.def_tri_idx); -+ } -+ } -+} -+ -+static void rtw89_phy_ul_tb_info_init(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; -+ -+ if (!chip->support_ul_tb_ctrl) -+ return; -+ -+ ul_tb_info->dyn_tb_tri_en = true; -+ ul_tb_info->def_if_bandedge = -+ rtw89_phy_read32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN); -+} -+ - static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) - { - struct rtw89_phy_stat *phystat = &rtwdev->phystat; -@@ -3980,6 +4104,7 @@ void rtw89_phy_dm_init(struct rtw89_dev - rtw89_physts_parsing_init(rtwdev); - rtw89_phy_dig_init(rtwdev); - rtw89_phy_cfo_init(rtwdev); -+ rtw89_phy_ul_tb_info_init(rtwdev); - - rtw89_phy_init_rf_nctl(rtwdev); - rtw89_chip_rfk_init(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -64,6 +64,9 @@ - #define MAX_CFO_TOLERANCE 30 - #define CFO_TF_CNT_TH 300 - -+#define UL_TB_TF_CNT_L2H_TH 100 -+#define UL_TB_TF_CNT_H2L_TH 70 -+ - #define CCX_MAX_PERIOD 2097 - #define CCX_MAX_PERIOD_UNIT 32 - #define MS_TO_4US_RATIO 250 -@@ -550,5 +553,7 @@ void rtw89_phy_set_bss_color(struct rtw8 - void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, - enum rtw89_mac_idx mac_idx, - enum rtw89_tssi_bandedge_cfg bandedge_cfg); -+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -+void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2082,6 +2082,7 @@ const struct rtw89_chip_info rtw8852a_ch - .support_bands = BIT(NL80211_BAND_2GHZ) | - BIT(NL80211_BAND_5GHZ), - .support_bw160 = false, -+ .support_ul_tb_ctrl = false, - .hw_sec_hdr = false, - .rf_path_num = 2, - .tx_nss = 2, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2452,6 +2452,7 @@ const struct rtw89_chip_info rtw8852b_ch - .support_bands = BIT(NL80211_BAND_2GHZ) | - BIT(NL80211_BAND_5GHZ), - .support_bw160 = false, -+ .support_ul_tb_ctrl = true, - .hw_sec_hdr = false, - .rf_path_num = 2, - .tx_nss = 2, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2891,6 +2891,7 @@ const struct rtw89_chip_info rtw8852c_ch - BIT(NL80211_BAND_5GHZ) | - BIT(NL80211_BAND_6GHZ), - .support_bw160 = true, -+ .support_ul_tb_ctrl = false, - .hw_sec_hdr = true, - .rf_path_num = 2, - .tx_nss = 2, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-066-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-066-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch deleted file mode 100644 index a84eaa396..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-066-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch +++ /dev/null @@ -1,73 +0,0 @@ -From ac3a9f1838d8f5e5f9c8b6e2582b65c48a1e7bc1 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 17 Nov 2022 16:52:35 +0800 -Subject: [PATCH 066/149] wifi: rtw89: avoid inaccessible IO operations during - doing change_interface() - -During doing change_interface(), hardware is power-off, so some components -are inaccessible and return error. This causes things unexpected, and we -don't have a warning message for that. So, ignore some IO operations in -this situation, and add a warning message to indicate something wrong. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221117085235.53777-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 7 +++++++ - drivers/net/wireless/realtek/rtw89/mac80211.c | 11 ++++++++++- - 3 files changed, 18 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2968,6 +2968,7 @@ enum rtw89_flags { - RTW89_FLAG_CRASH_SIMULATING, - RTW89_FLAG_WOWLAN, - RTW89_FLAG_FORBIDDEN_TRACK_WROK, -+ RTW89_FLAG_CHANGING_INTERFACE, - - NUM_OF_RTW89_FLAGS, - }; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3600,6 +3600,13 @@ int rtw89_mac_set_macid_pause(struct rtw - u8 grp = macid >> 5; - int ret; - -+ /* If this is called by change_interface() in the case of P2P, it could -+ * be power-off, so ignore this operation. -+ */ -+ if (test_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags) && -+ !test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) -+ return 0; -+ - ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); - if (ret) - return ret; ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -174,6 +174,9 @@ static int rtw89_ops_change_interface(st - enum nl80211_iftype type, bool p2p) - { - struct rtw89_dev *rtwdev = hw->priv; -+ int ret; -+ -+ set_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags); - - rtw89_debug(rtwdev, RTW89_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", - vif->addr, vif->type, type, vif->p2p, p2p); -@@ -183,7 +186,13 @@ static int rtw89_ops_change_interface(st - vif->type = type; - vif->p2p = p2p; - -- return rtw89_ops_add_interface(hw, vif); -+ ret = rtw89_ops_add_interface(hw, vif); -+ if (ret) -+ rtw89_warn(rtwdev, "failed to change interface %d\n", ret); -+ -+ clear_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags); -+ -+ return ret; - } - - static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-068-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-068-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch deleted file mode 100644 index 4eb6b5ee7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-068-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch +++ /dev/null @@ -1,47 +0,0 @@ -From cd9b6b3baf5278c73c91e242d41387684fc7f8d8 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 25 Nov 2022 15:24:14 +0800 -Subject: [PATCH 068/149] wifi: rtw89: enable mac80211 virtual monitor - interface - -For running with mac80211 channel context ops and using only as monitor, -we need to enable WANT_MONITOR_VIF to let mac80211 process virtual monitor -interface. Then, we are able to set channel on the monitor from user space. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221125072416.94752-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1405,6 +1405,9 @@ static void rtw89_vif_rx_stats_iter(void - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - const u8 *bssid = iter_data->bssid; - -+ if (!vif->bss_conf.bssid) -+ return; -+ - if (ieee80211_is_trigger(hdr->frame_control)) { - rtw89_stats_trigger_frame(rtwdev, vif, skb); - return; -@@ -2386,6 +2389,8 @@ void rtw89_vif_type_mapping(struct ieee8 - rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; - rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; - break; -+ case NL80211_IFTYPE_MONITOR: -+ break; - default: - WARN_ON(1); - break; -@@ -3269,6 +3274,7 @@ static int rtw89_core_register_hw(struct - ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); - ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); - ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); -+ ieee80211_hw_set(hw, WANT_MONITOR_VIF); - - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-069-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-069-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch deleted file mode 100644 index bba2a5438..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-069-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 51e8ed4e44b5efcf8da2c1f3478e52120a12cdf8 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 25 Nov 2022 15:24:15 +0800 -Subject: [PATCH 069/149] wifi: rtw89: add HE radiotap for monitor mode - -With basic HE radiotap, we can check data rate in sniffer data. To store -the radiotap data, we reserve headroom of aligned 64 bytes, and then -update HE radiotap in monitor mode, so it doesn't affect performance in -normal mode. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221125072416.94752-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 22 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 18 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/pci.c | 2 +- - 3 files changed, 41 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1480,6 +1480,27 @@ static void rtw89_core_hw_to_sband_rate( - rx_status->rate_idx -= 4; - } - -+static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev, -+ struct sk_buff *skb, -+ struct ieee80211_rx_status *rx_status) -+{ -+ static const struct ieee80211_radiotap_he known_he = { -+ .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | -+ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), -+ .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), -+ }; -+ struct ieee80211_radiotap_he *he; -+ -+ if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)) -+ return; -+ -+ if (rx_status->encoding == RX_ENC_HE) { -+ rx_status->flag |= RX_FLAG_RADIOTAP_HE; -+ he = skb_push(skb, sizeof(*he)); -+ *he = known_he; -+ } -+} -+ - static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, - struct rtw89_rx_phy_ppdu *phy_ppdu, - struct rtw89_rx_desc_info *desc_info, -@@ -1494,6 +1515,7 @@ static void rtw89_core_rx_to_mac80211(st - - rtw89_core_hw_to_sband_rate(rx_status); - rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); -+ rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status); - /* In low power mode, it does RX in thread context. */ - local_bh_disable(); - ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, napi); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -35,6 +35,7 @@ extern const struct ieee80211_ops rtw89_ - #define RSSI_FACTOR 1 - #define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI) - #define RTW89_TX_DIV_RSSI_RAW_TH (2 << RSSI_FACTOR) -+#define RTW89_RADIOTAP_ROOM ALIGN(sizeof(struct ieee80211_radiotap_he), 64) - - #define RTW89_HTC_MASK_VARIANT GENMASK(1, 0) - #define RTW89_HTC_VARIANT_HE 3 -@@ -4383,6 +4384,23 @@ static inline struct rtw89_fw_suit *rtw8 - return &fw_info->normal; - } - -+static inline struct sk_buff *rtw89_alloc_skb_for_rx(struct rtw89_dev *rtwdev, -+ unsigned int length) -+{ -+ struct sk_buff *skb; -+ -+ if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) { -+ skb = dev_alloc_skb(length + RTW89_RADIOTAP_ROOM); -+ if (!skb) -+ return NULL; -+ -+ skb_reserve(skb, RTW89_RADIOTAP_ROOM); -+ return skb; -+ } -+ -+ return dev_alloc_skb(length); -+} -+ - int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); - int rtw89_h2c_tx(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -267,7 +267,7 @@ static u32 rtw89_pci_rxbd_deliver_skbs(s - - rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); - -- new = dev_alloc_skb(desc_info->pkt_size); -+ new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size); - if (!new) - goto err_sync_device; - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-070-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-070-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch deleted file mode 100644 index eaa254e04..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-070-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch +++ /dev/null @@ -1,53 +0,0 @@ -From a215b2b7055f02d8f7666f457d442e77097bb604 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 25 Nov 2022 15:24:16 +0800 -Subject: [PATCH 070/149] wifi: rtw89: 8852b: turn off PoP function in monitor - mode - -PoP stands for Packet on Packet that can improve performance in noisy -environment, but it could get RX stuck suddenly. In normal mode, firmware -can help to resolve the stuck, but firmware doesn't work in monitor mode. -Therefore, turn off PoP to avoid RX stuck. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221125072416.94752-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 7 +++++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4238,6 +4238,8 @@ - #define R_P1_NBIIDX 0x4770 - #define B_P1_NBIIDX_VAL GENMASK(11, 0) - #define B_P1_NBIIDX_NOTCH_EN BIT(12) -+#define R_PKT_CTRL 0x47D4 -+#define B_PKT_POP_EN BIT(8) - #define R_SEG0R_PD 0x481C - #define R_SEG0R_PD_V1 0x4860 - #define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1411,6 +1411,12 @@ static void rtw8852b_bb_sethw(struct rtw - rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); - } - -+static void rtw8852b_bb_set_pop(struct rtw89_dev *rtwdev) -+{ -+ if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) -+ rtw89_phy_write32_clr(rtwdev, R_PKT_CTRL, B_PKT_POP_EN); -+} -+ - static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -@@ -1441,6 +1447,7 @@ static void rtw8852b_set_channel_bb(stru - rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, - chan->primary_channel); - rtw8852b_5m_mask(rtwdev, chan, phy_idx); -+ rtw8852b_bb_set_pop(rtwdev); - rtw8852b_bb_reset_all(rtwdev, phy_idx); - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-071-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-071-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch deleted file mode 100644 index 9c16952af..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-071-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 38f25dec521edfa289fa0b829676927b13fede91 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:25 +0800 -Subject: [PATCH 071/149] wifi: rtw89: rfk: rename rtw89_mcc_info to - rtw89_rfk_mcc_info - -The `rtw89_mcc_info mcc` is only for RFK MCC stuffs instead of common -MCC management info. Replace it with `rtw89_rfk_mcc_info rfk_mcc` to -avoid confusion and reserve `struct rtw89_mcc_info mcc` for MCC management -code. - -(No logic changes.) - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 4 ++-- - drivers/net/wireless/realtek/rtw89/fw.c | 10 +++++----- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- - .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 20 +++++++++---------- - 4 files changed, 19 insertions(+), 19 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3032,7 +3032,7 @@ struct rtw89_dack_info { - #define RTW89_IQK_CHS_NR 2 - #define RTW89_IQK_PATH_NR 4 - --struct rtw89_mcc_info { -+struct rtw89_rfk_mcc_info { - u8 ch[RTW89_IQK_CHS_NR]; - u8 band[RTW89_IQK_CHS_NR]; - u8 table_idx; -@@ -3578,7 +3578,7 @@ struct rtw89_dev { - struct rtw89_dack_info dack; - struct rtw89_iqk_info iqk; - struct rtw89_dpk_info dpk; -- struct rtw89_mcc_info mcc; -+ struct rtw89_rfk_mcc_info rfk_mcc; - struct rtw89_lck_info lck; - struct rtw89_rx_dck_info rx_dck; - bool is_tssi_mode[RF_PATH_MAX]; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2263,7 +2263,7 @@ fail: - int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) - { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; -+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; - struct rtw89_fw_h2c_rf_get_mccch *mccch; - struct sk_buff *skb; - int ret; -@@ -2276,10 +2276,10 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw8 - skb_put(skb, sizeof(*mccch)); - mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; - -- mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]); -- mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]); -- mccch->band_0 = cpu_to_le32(mcc_info->band[0]); -- mccch->band_1 = cpu_to_le32(mcc_info->band[1]); -+ mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); -+ mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); -+ mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]); -+ mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]); - mccch->current_channel = cpu_to_le32(chan->channel); - mccch->current_band_type = cpu_to_le32(chan->band_type); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -1832,11 +1832,11 @@ static void rtw8852c_set_channel_help(st - - static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) - { -- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; -+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; - - rtwdev->is_tssi_mode[RF_PATH_A] = false; - rtwdev->is_tssi_mode[RF_PATH_B] = false; -- memset(mcc_info, 0, sizeof(*mcc_info)); -+ memset(rfk_mcc, 0, sizeof(*rfk_mcc)); - rtw8852c_lck_init(rtwdev); - - rtw8852c_rck(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -1030,9 +1030,9 @@ static bool _iqk_nbtxk(struct rtw89_dev - - static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) - { -- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; -+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; - struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -- u8 idx = mcc_info->table_idx; -+ u8 idx = rfk_mcc->table_idx; - bool is_fail1, is_fail2; - u32 val; - u32 core_i; -@@ -1375,10 +1375,10 @@ static void _iqk_afebb_restore(struct rt - - static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) - { -- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; -+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; - u8 idx = 0; - -- idx = mcc_info->table_idx; -+ idx = rfk_mcc->table_idx; - rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx); - rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx); - rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -@@ -3823,20 +3823,20 @@ void rtw8852c_set_channel_rf(struct rtw8 - void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; -- u8 idx = mcc_info->table_idx; -+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; -+ u8 idx = rfk_mcc->table_idx; - int i; - - for (i = 0; i < RTW89_IQK_CHS_NR; i++) { -- if (mcc_info->ch[idx] == 0) -+ if (rfk_mcc->ch[idx] == 0) - break; - if (++idx >= RTW89_IQK_CHS_NR) - idx = 0; - } - -- mcc_info->table_idx = idx; -- mcc_info->ch[idx] = chan->channel; -- mcc_info->band[idx] = chan->band_type; -+ rfk_mcc->table_idx = idx; -+ rfk_mcc->ch[idx] = chan->channel; -+ rfk_mcc->band[idx] = chan->band_type; - } - - void rtw8852c_rck(struct rtw89_dev *rtwdev) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-072-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-072-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch deleted file mode 100644 index a400a19f2..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-072-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 860e8263ae92667a2002163886fd2ebd8c67f699 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:26 +0800 -Subject: [PATCH 072/149] wifi: rtw89: check if atomic before queuing c2h - -Before queuing C2H work, we check atomicity of the C2H's handler first now. -If atomic or lock-free, handle it directly; otherwise, handle it with mutex -in work as previous. This prepares for MAC MCC C2Hs which require to be -processed directly. And, their handlers will be functions which can be -considered atomic. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 47 ++++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/fw.h | 14 +++++++ - drivers/net/wireless/realtek/rtw89/mac.c | 10 +++++ - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - 4 files changed, 68 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -11,6 +11,9 @@ - #include "phy.h" - #include "reg.h" - -+static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, -+ struct sk_buff *skb); -+ - static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, - bool header) - { -@@ -2382,8 +2385,43 @@ void rtw89_fw_free_all_early_h2c(struct - mutex_unlock(&rtwdev->mutex); - } - -+static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) -+{ -+ struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); -+ -+ attr->category = RTW89_GET_C2H_CATEGORY(c2h->data); -+ attr->class = RTW89_GET_C2H_CLASS(c2h->data); -+ attr->func = RTW89_GET_C2H_FUNC(c2h->data); -+ attr->len = RTW89_GET_C2H_LEN(c2h->data); -+} -+ -+static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev, -+ struct sk_buff *c2h) -+{ -+ struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); -+ u8 category = attr->category; -+ u8 class = attr->class; -+ u8 func = attr->func; -+ -+ switch (category) { -+ default: -+ return false; -+ case RTW89_C2H_CAT_MAC: -+ return rtw89_mac_c2h_chk_atomic(rtwdev, class, func); -+ } -+} -+ - void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) - { -+ rtw89_fw_c2h_parse_attr(c2h); -+ if (!rtw89_fw_c2h_chk_atomic(rtwdev, c2h)) -+ goto enqueue; -+ -+ rtw89_fw_c2h_cmd_handle(rtwdev, c2h); -+ dev_kfree_skb_any(c2h); -+ return; -+ -+enqueue: - skb_queue_tail(&rtwdev->c2h_queue, c2h); - ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); - } -@@ -2391,10 +2429,11 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_d - static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, - struct sk_buff *skb) - { -- u8 category = RTW89_GET_C2H_CATEGORY(skb->data); -- u8 class = RTW89_GET_C2H_CLASS(skb->data); -- u8 func = RTW89_GET_C2H_FUNC(skb->data); -- u16 len = RTW89_GET_C2H_LEN(skb->data); -+ struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); -+ u8 category = attr->category; -+ u8 class = attr->class; -+ u8 func = attr->func; -+ u16 len = attr->len; - bool dump = true; - - if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2778,6 +2778,20 @@ static inline void RTW89_SET_FWCMD_TSF32 - #define RTW89_GET_C2H_LEN(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(13, 0)) - -+struct rtw89_fw_c2h_attr { -+ u8 category; -+ u8 class; -+ u8 func; -+ u16 len; -+}; -+ -+static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) -+{ -+ static_assert(sizeof(skb->cb) >= sizeof(struct rtw89_fw_c2h_attr)); -+ -+ return (struct rtw89_fw_c2h_attr *)skb->cb; -+} -+ - #define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) - #define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4208,6 +4208,16 @@ void (* const rtw89_mac_c2h_info_handler - [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, - }; - -+bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) -+{ -+ switch (class) { -+ default: -+ return false; -+ case RTW89_MAC_C2H_CLASS_MCC: -+ return true; -+ } -+} -+ - void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, - u32 len, u8 class, u8 func) - { ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -894,6 +894,7 @@ static inline int rtw89_chip_disable_bb_ - - u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev); - int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err); -+bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func); - void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, - u32 len, u8 class, u8 func); - int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-073-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-073-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch deleted file mode 100644 index a714815e5..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-073-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 22b10cdb73921cfb28ccde5ce8b47d7fc434e7c6 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:27 +0800 -Subject: [PATCH 073/149] wifi: rtw89: introduce helpers to wait/complete on - condition - -MCC (multi-channel concurrency) related H2Cs (host to chip commands) -require to wait for C2H (chip to host events) responses to judge the -execution result and data. We introduce helpers to assist this process. -Besides, we would like the helpers to be generic for use in driver even -outside of MCC H2C/C2H, so we make a independent patch for them. - -In the following, I describe the things first. -``` -(A) C2H is generated by FW, and then transferred upto driver. Hence, - driver cannot get it immediately without a bit waitting/blocking. - For this, we choose to use wait_for_completion_*() instead of - busy polling. -(B) From the driver management perspective, a scenario, e.g. MCC, - may have mulitple kind of H2C functions requiring this process - to wait for corresponding C2Hs. But, the driver management flow - uses mutex to protect each behavior. So, one scenario triggers - one H2C function at one time. To avoid rampant instances of - struct completion for each H2C function, we choose to use one - struct completion with one condition flag for one scenario. -(C) C2Hs, which H2Cs will be waitting for, cannot be ordered with - driver management flow, i.e. cannot enqueue work to the same - ordered workqueue and cannot lock by the same mutex, to prevent - H2C side from getting no C2H responses. So, those C2Hs are parsed - in interrupt context directly as done in previous commit. -(D) Following (C), the above underline H2Cs and C2Hs will be handled - in different contexts without sync. So, we use atomic_cmpxchg() - to compare and change the condition in atomic. -``` - -So, we introduce struct rtw89_wait_info which combines struct completion -and atomic_t. Then, the below are the descriptions for helper functions. -* rtw89_wait_for_cond() to wait for a completion based on a condition. -* rtw89_complete_cond() to complete a given condition and carry data. -Each rtw89_wait_info instance independently determines the meaning of -its waitting conditions. But, RTW89_WAIT_COND_IDLE (UINT_MAX) is reserved. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 35 +++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 25 ++++++++++++++++ - 2 files changed, 60 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2974,6 +2974,41 @@ void rtw89_core_update_beacon_work(struc - mutex_unlock(&rtwdev->mutex); - } - -+int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) -+{ -+ struct completion *cmpl = &wait->completion; -+ unsigned long timeout; -+ unsigned int cur; -+ -+ cur = atomic_cmpxchg(&wait->cond, RTW89_WAIT_COND_IDLE, cond); -+ if (cur != RTW89_WAIT_COND_IDLE) -+ return -EBUSY; -+ -+ timeout = wait_for_completion_timeout(cmpl, RTW89_WAIT_FOR_COND_TIMEOUT); -+ if (timeout == 0) { -+ atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); -+ return -ETIMEDOUT; -+ } -+ -+ if (wait->data.err) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, -+ const struct rtw89_completion_data *data) -+{ -+ unsigned int cur; -+ -+ cur = atomic_cmpxchg(&wait->cond, cond, RTW89_WAIT_COND_IDLE); -+ if (cur != cond) -+ return; -+ -+ wait->data = *data; -+ complete(&wait->completion); -+} -+ - int rtw89_core_start(struct rtw89_dev *rtwdev) - { - int ret; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2812,6 +2812,28 @@ struct rtw89_mac_info { - u8 cpwm_seq_num; - }; - -+#define RTW89_COMPLETION_BUF_SIZE 24 -+#define RTW89_WAIT_COND_IDLE UINT_MAX -+ -+struct rtw89_completion_data { -+ bool err; -+ u8 buf[RTW89_COMPLETION_BUF_SIZE]; -+}; -+ -+struct rtw89_wait_info { -+ atomic_t cond; -+ struct completion completion; -+ struct rtw89_completion_data data; -+}; -+ -+#define RTW89_WAIT_FOR_COND_TIMEOUT msecs_to_jiffies(100) -+ -+static inline void rtw89_init_wait(struct rtw89_wait_info *wait) -+{ -+ init_completion(&wait->completion); -+ atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); -+} -+ - enum rtw89_fw_type { - RTW89_FW_NORMAL = 1, - RTW89_FW_WOWLAN = 3, -@@ -4469,6 +4491,9 @@ int rtw89_regd_init(struct rtw89_dev *rt - void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); - void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, - struct rtw89_traffic_stats *stats); -+int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond); -+void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, -+ const struct rtw89_completion_data *data); - int rtw89_core_start(struct rtw89_dev *rtwdev); - void rtw89_core_stop(struct rtw89_dev *rtwdev); - void rtw89_core_update_beacon_work(struct work_struct *work); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-074-wifi-rtw89-mac-process-MCC-related-C2H.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-074-wifi-rtw89-mac-process-MCC-related-C2H.patch deleted file mode 100644 index 52d130a19..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-074-wifi-rtw89-mac-process-MCC-related-C2H.patch +++ /dev/null @@ -1,382 +0,0 @@ -From ef9dff4cb491210518ad3d249919a0971eff601b Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:28 +0800 -Subject: [PATCH 074/149] wifi: rtw89: mac: process MCC related C2H - -Process C2H(s) related to MCC (multi-channel concurrency). These handling, -which either call rtw89_complete_cond() or show message in debug mode, can -be considered atomic/lock-free. So, they should be safe to be processed -directly after C2H pre-check in previous patch. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 + - drivers/net/wireless/realtek/rtw89/core.h | 5 + - drivers/net/wireless/realtek/rtw89/fw.h | 68 +++++++++ - drivers/net/wireless/realtek/rtw89/mac.c | 171 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 34 +++++ - 5 files changed, 280 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3132,6 +3132,8 @@ int rtw89_core_init(struct rtw89_dev *rt - mutex_init(&rtwdev->rf_mutex); - rtwdev->total_sta_assoc = 0; - -+ rtw89_init_wait(&rtwdev->mcc.wait); -+ - INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); - INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); - skb_queue_head_init(&rtwdev->c2h_queue); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3547,6 +3547,10 @@ struct rtw89_wow_param { - struct list_head pkt_list; - }; - -+struct rtw89_mcc_info { -+ struct rtw89_wait_info wait; -+}; -+ - struct rtw89_dev { - struct ieee80211_hw *hw; - struct device *dev; -@@ -3557,6 +3561,7 @@ struct rtw89_dev { - const struct rtw89_chip_info *chip; - const struct rtw89_pci_info *pci_info; - struct rtw89_hal hal; -+ struct rtw89_mcc_info mcc; - struct rtw89_mac_info mac; - struct rtw89_fw_info fw; - struct rtw89_hci_info hci; ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2859,6 +2859,55 @@ static inline struct rtw89_fw_c2h_attr * - #define RTW89_GET_MAC_C2H_SCANOFLD_BAND(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(25, 24)) - -+#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) -+#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ -+#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) -+#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 2)) -+#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ -+struct rtw89_mac_mcc_tsf_rpt { -+ u32 macid_x; -+ u32 macid_y; -+ u32 tsf_x_low; -+ u32 tsf_x_high; -+ u32 tsf_y_low; -+ u32 tsf_y_high; -+}; -+ -+static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE); -+ -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 0)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(17, 16)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) -+#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) -+ -+#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(5, 0)) -+#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 6)) -+#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) -+#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) -+ - #define RTW89_FW_HDR_SIZE 32 - #define RTW89_FW_SECTION_HDR_SIZE 16 - -@@ -2980,6 +3029,25 @@ struct rtw89_fw_h2c_rf_reg_info { - #define H2C_CL_BA_CAM 0xc - #define H2C_FUNC_MAC_BA_CAM 0x0 - -+/* CLASS 14 - MCC */ -+#define H2C_CL_MCC 0xe -+enum rtw89_mcc_h2c_func { -+ H2C_FUNC_ADD_MCC = 0x0, -+ H2C_FUNC_START_MCC = 0x1, -+ H2C_FUNC_STOP_MCC = 0x2, -+ H2C_FUNC_DEL_MCC_GROUP = 0x3, -+ H2C_FUNC_RESET_MCC_GROUP = 0x4, -+ H2C_FUNC_MCC_REQ_TSF = 0x5, -+ H2C_FUNC_MCC_MACID_BITMAP = 0x6, -+ H2C_FUNC_MCC_SYNC = 0x7, -+ H2C_FUNC_MCC_SET_DURATION = 0x8, -+ -+ NUM_OF_RTW89_MCC_H2C_FUNC, -+}; -+ -+#define RTW89_MCC_WAIT_COND(group, func) \ -+ ((group) * NUM_OF_RTW89_MCC_H2C_FUNC + (func)) -+ - #define H2C_CAT_OUTSRC 0x2 - - #define H2C_CL_OUTSRC_RA 0x1 ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4187,6 +4187,164 @@ rtw89_mac_c2h_tsf32_toggle_rpt(struct rt - { - } - -+static void -+rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) -+{ -+ u8 group = RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h->data); -+ u8 func = RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h->data); -+ -+ switch (func) { -+ case H2C_FUNC_ADD_MCC: -+ case H2C_FUNC_START_MCC: -+ case H2C_FUNC_STOP_MCC: -+ case H2C_FUNC_DEL_MCC_GROUP: -+ case H2C_FUNC_RESET_MCC_GROUP: -+ case H2C_FUNC_MCC_REQ_TSF: -+ case H2C_FUNC_MCC_MACID_BITMAP: -+ case H2C_FUNC_MCC_SYNC: -+ case H2C_FUNC_MCC_SET_DURATION: -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "invalid MCC C2H RCV ACK: func %d\n", func); -+ return; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "MCC C2H RCV ACK: group %d, func %d\n", group, func); -+} -+ -+static void -+rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) -+{ -+ u8 group = RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h->data); -+ u8 func = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h->data); -+ u8 retcode = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h->data); -+ struct rtw89_completion_data data = {}; -+ unsigned int cond; -+ bool next = false; -+ -+ switch (func) { -+ case H2C_FUNC_MCC_REQ_TSF: -+ next = true; -+ break; -+ case H2C_FUNC_MCC_MACID_BITMAP: -+ case H2C_FUNC_MCC_SYNC: -+ case H2C_FUNC_MCC_SET_DURATION: -+ break; -+ case H2C_FUNC_ADD_MCC: -+ case H2C_FUNC_START_MCC: -+ case H2C_FUNC_STOP_MCC: -+ case H2C_FUNC_DEL_MCC_GROUP: -+ case H2C_FUNC_RESET_MCC_GROUP: -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "invalid MCC C2H REQ ACK: func %d\n", func); -+ return; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "MCC C2H REQ ACK: group %d, func %d, return code %d\n", -+ group, func, retcode); -+ -+ if (!retcode && next) -+ return; -+ -+ data.err = !!retcode; -+ cond = RTW89_MCC_WAIT_COND(group, func); -+ rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); -+} -+ -+static void -+rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) -+{ -+ u8 group = RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h->data); -+ struct rtw89_completion_data data = {}; -+ struct rtw89_mac_mcc_tsf_rpt *rpt; -+ unsigned int cond; -+ -+ rpt = (struct rtw89_mac_mcc_tsf_rpt *)data.buf; -+ rpt->macid_x = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h->data); -+ rpt->macid_y = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h->data); -+ rpt->tsf_x_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h->data); -+ rpt->tsf_x_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h->data); -+ rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data); -+ rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF); -+ rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); -+} -+ -+static void -+rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) -+{ -+ u8 group = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h->data); -+ u8 macid = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h->data); -+ u8 status = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h->data); -+ u32 tsf_low = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h->data); -+ u32 tsf_high = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h->data); -+ struct rtw89_completion_data data = {}; -+ unsigned int cond; -+ bool rsp = true; -+ bool err; -+ u8 func; -+ -+ switch (status) { -+ case RTW89_MAC_MCC_ADD_ROLE_OK: -+ case RTW89_MAC_MCC_ADD_ROLE_FAIL: -+ func = H2C_FUNC_ADD_MCC; -+ err = status == RTW89_MAC_MCC_ADD_ROLE_FAIL; -+ break; -+ case RTW89_MAC_MCC_START_GROUP_OK: -+ case RTW89_MAC_MCC_START_GROUP_FAIL: -+ func = H2C_FUNC_START_MCC; -+ err = status == RTW89_MAC_MCC_START_GROUP_FAIL; -+ break; -+ case RTW89_MAC_MCC_STOP_GROUP_OK: -+ case RTW89_MAC_MCC_STOP_GROUP_FAIL: -+ func = H2C_FUNC_STOP_MCC; -+ err = status == RTW89_MAC_MCC_STOP_GROUP_FAIL; -+ break; -+ case RTW89_MAC_MCC_DEL_GROUP_OK: -+ case RTW89_MAC_MCC_DEL_GROUP_FAIL: -+ func = H2C_FUNC_DEL_MCC_GROUP; -+ err = status == RTW89_MAC_MCC_DEL_GROUP_FAIL; -+ break; -+ case RTW89_MAC_MCC_RESET_GROUP_OK: -+ case RTW89_MAC_MCC_RESET_GROUP_FAIL: -+ func = H2C_FUNC_RESET_MCC_GROUP; -+ err = status == RTW89_MAC_MCC_RESET_GROUP_FAIL; -+ break; -+ case RTW89_MAC_MCC_SWITCH_CH_OK: -+ case RTW89_MAC_MCC_SWITCH_CH_FAIL: -+ case RTW89_MAC_MCC_TXNULL0_OK: -+ case RTW89_MAC_MCC_TXNULL0_FAIL: -+ case RTW89_MAC_MCC_TXNULL1_OK: -+ case RTW89_MAC_MCC_TXNULL1_FAIL: -+ case RTW89_MAC_MCC_SWITCH_EARLY: -+ case RTW89_MAC_MCC_TBTT: -+ case RTW89_MAC_MCC_DURATION_START: -+ case RTW89_MAC_MCC_DURATION_END: -+ rsp = false; -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "invalid MCC C2H STS RPT: status %d\n", status); -+ return; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "MCC C2H STS RPT: group %d, macid %d, status %d, tsf {%d, %d}\n", -+ group, macid, status, tsf_low, tsf_high); -+ -+ if (!rsp) -+ return; -+ -+ data.err = err; -+ cond = RTW89_MCC_WAIT_COND(group, func); -+ rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); -+} -+ - static - void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, - struct sk_buff *c2h, u32 len) = { -@@ -4208,6 +4366,15 @@ void (* const rtw89_mac_c2h_info_handler - [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, - }; - -+static -+void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev, -+ struct sk_buff *c2h, u32 len) = { -+ [RTW89_MAC_C2H_FUNC_MCC_RCV_ACK] = rtw89_mac_c2h_mcc_rcv_ack, -+ [RTW89_MAC_C2H_FUNC_MCC_REQ_ACK] = rtw89_mac_c2h_mcc_req_ack, -+ [RTW89_MAC_C2H_FUNC_MCC_TSF_RPT] = rtw89_mac_c2h_mcc_tsf_rpt, -+ [RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt, -+}; -+ - bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) - { - switch (class) { -@@ -4233,6 +4400,10 @@ void rtw89_mac_c2h_handle(struct rtw89_d - if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX) - handler = rtw89_mac_c2h_ofld_handler[func]; - break; -+ case RTW89_MAC_C2H_CLASS_MCC: -+ if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC) -+ handler = rtw89_mac_c2h_mcc_handler[func]; -+ break; - case RTW89_MAC_C2H_CLASS_FWDBG: - return; - default: ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -368,6 +368,15 @@ enum rtw89_mac_c2h_info_func { - RTW89_MAC_C2H_FUNC_INFO_MAX, - }; - -+enum rtw89_mac_c2h_mcc_func { -+ RTW89_MAC_C2H_FUNC_MCC_RCV_ACK = 0, -+ RTW89_MAC_C2H_FUNC_MCC_REQ_ACK = 1, -+ RTW89_MAC_C2H_FUNC_MCC_TSF_RPT = 2, -+ RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT = 3, -+ -+ NUM_OF_RTW89_MAC_C2H_FUNC_MCC, -+}; -+ - enum rtw89_mac_c2h_class { - RTW89_MAC_C2H_CLASS_INFO, - RTW89_MAC_C2H_CLASS_OFLD, -@@ -378,6 +387,31 @@ enum rtw89_mac_c2h_class { - RTW89_MAC_C2H_CLASS_MAX, - }; - -+enum rtw89_mac_mcc_status { -+ RTW89_MAC_MCC_ADD_ROLE_OK = 0, -+ RTW89_MAC_MCC_START_GROUP_OK = 1, -+ RTW89_MAC_MCC_STOP_GROUP_OK = 2, -+ RTW89_MAC_MCC_DEL_GROUP_OK = 3, -+ RTW89_MAC_MCC_RESET_GROUP_OK = 4, -+ RTW89_MAC_MCC_SWITCH_CH_OK = 5, -+ RTW89_MAC_MCC_TXNULL0_OK = 6, -+ RTW89_MAC_MCC_TXNULL1_OK = 7, -+ -+ RTW89_MAC_MCC_SWITCH_EARLY = 10, -+ RTW89_MAC_MCC_TBTT = 11, -+ RTW89_MAC_MCC_DURATION_START = 12, -+ RTW89_MAC_MCC_DURATION_END = 13, -+ -+ RTW89_MAC_MCC_ADD_ROLE_FAIL = 20, -+ RTW89_MAC_MCC_START_GROUP_FAIL = 21, -+ RTW89_MAC_MCC_STOP_GROUP_FAIL = 22, -+ RTW89_MAC_MCC_DEL_GROUP_FAIL = 23, -+ RTW89_MAC_MCC_RESET_GROUP_FAIL = 24, -+ RTW89_MAC_MCC_SWITCH_CH_FAIL = 25, -+ RTW89_MAC_MCC_TXNULL0_FAIL = 26, -+ RTW89_MAC_MCC_TXNULL1_FAIL = 27, -+}; -+ - struct rtw89_mac_ax_coex { - #define RTW89_MAC_AX_COEX_RTK_MODE 0 - #define RTW89_MAC_AX_COEX_CSR_MODE 1 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-075-wifi-rtw89-fw-implement-MCC-related-H2C.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-075-wifi-rtw89-fw-implement-MCC-related-H2C.patch deleted file mode 100644 index 53339dcf1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-075-wifi-rtw89-fw-implement-MCC-related-H2C.patch +++ /dev/null @@ -1,741 +0,0 @@ -From c008c4b011baa26b9545f7be10e746c97409d45b Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:29 +0800 -Subject: [PATCH 075/149] wifi: rtw89: fw: implement MCC related H2C - -These MCC H2C(s) require to wait for MCC C2H to determine if the -execution is successful. Through rtw89_wait_for_cond(), we make -them wait for either a completion with data from MCC C2H handlers, -which calls rtw89_complete_cond(), or timeout. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 329 +++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 369 +++++++++++++++++++++++- - 2 files changed, 697 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -3265,3 +3265,332 @@ fail: - - return ret; - } -+ -+static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, -+ struct rtw89_wait_info *wait, unsigned int cond) -+{ -+ int ret; -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ dev_kfree_skb_any(skb); -+ return -EBUSY; -+ } -+ -+ return rtw89_wait_for_cond(wait, cond); -+} -+ -+#define H2C_ADD_MCC_LEN 16 -+int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_add_req *p) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ADD_MCC_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for add mcc\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_ADD_MCC_LEN); -+ RTW89_SET_FWCMD_ADD_MCC_MACID(skb->data, p->macid); -+ RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(skb->data, p->central_ch_seg0); -+ RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(skb->data, p->central_ch_seg1); -+ RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(skb->data, p->primary_ch); -+ RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(skb->data, p->bandwidth); -+ RTW89_SET_FWCMD_ADD_MCC_GROUP(skb->data, p->group); -+ RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(skb->data, p->c2h_rpt); -+ RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(skb->data, p->dis_tx_null); -+ RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(skb->data, p->dis_sw_retry); -+ RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(skb->data, p->in_curr_ch); -+ RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(skb->data, p->sw_retry_count); -+ RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(skb->data, p->tx_null_early); -+ RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(skb->data, p->btc_in_2g); -+ RTW89_SET_FWCMD_ADD_MCC_PTA_EN(skb->data, p->pta_en); -+ RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(skb->data, p->rfk_by_pass); -+ RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(skb->data, p->ch_band_type); -+ RTW89_SET_FWCMD_ADD_MCC_DURATION(skb->data, p->duration); -+ RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(skb->data, p->courtesy_en); -+ RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(skb->data, p->courtesy_num); -+ RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(skb->data, p->courtesy_target); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_ADD_MCC, 0, 0, -+ H2C_ADD_MCC_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_ADD_MCC); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_START_MCC_LEN 12 -+int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_start_req *p) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_START_MCC_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for start mcc\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_START_MCC_LEN); -+ RTW89_SET_FWCMD_START_MCC_GROUP(skb->data, p->group); -+ RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(skb->data, p->btc_in_group); -+ RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(skb->data, p->old_group_action); -+ RTW89_SET_FWCMD_START_MCC_OLD_GROUP(skb->data, p->old_group); -+ RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(skb->data, p->notify_cnt); -+ RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(skb->data, p->notify_rxdbg_en); -+ RTW89_SET_FWCMD_START_MCC_MACID(skb->data, p->macid); -+ RTW89_SET_FWCMD_START_MCC_TSF_LOW(skb->data, p->tsf_low); -+ RTW89_SET_FWCMD_START_MCC_TSF_HIGH(skb->data, p->tsf_high); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_START_MCC, 0, 0, -+ H2C_START_MCC_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_START_MCC); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_STOP_MCC_LEN 4 -+int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, -+ bool prev_groups) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_STOP_MCC_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for stop mcc\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_STOP_MCC_LEN); -+ RTW89_SET_FWCMD_STOP_MCC_MACID(skb->data, macid); -+ RTW89_SET_FWCMD_STOP_MCC_GROUP(skb->data, group); -+ RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(skb->data, prev_groups); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_STOP_MCC, 0, 0, -+ H2C_STOP_MCC_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_STOP_MCC); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_DEL_MCC_GROUP_LEN 4 -+int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, -+ bool prev_groups) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DEL_MCC_GROUP_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for del mcc group\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_DEL_MCC_GROUP_LEN); -+ RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(skb->data, group); -+ RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(skb->data, prev_groups); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_DEL_MCC_GROUP, 0, 0, -+ H2C_DEL_MCC_GROUP_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_DEL_MCC_GROUP); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_RESET_MCC_GROUP_LEN 4 -+int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RESET_MCC_GROUP_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for reset mcc group\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_RESET_MCC_GROUP_LEN); -+ RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(skb->data, group); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_RESET_MCC_GROUP, 0, 0, -+ H2C_RESET_MCC_GROUP_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_RESET_MCC_GROUP); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_MCC_REQ_TSF_LEN 4 -+int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_tsf_req *req, -+ struct rtw89_mac_mcc_tsf_rpt *rpt) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct rtw89_mac_mcc_tsf_rpt *tmp; -+ struct sk_buff *skb; -+ unsigned int cond; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_REQ_TSF_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for mcc req tsf\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_MCC_REQ_TSF_LEN); -+ RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(skb->data, req->group); -+ RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(skb->data, req->macid_x); -+ RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(skb->data, req->macid_y); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_MCC_REQ_TSF, 0, 0, -+ H2C_MCC_REQ_TSF_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(req->group, H2C_FUNC_MCC_REQ_TSF); -+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+ if (ret) -+ return ret; -+ -+ tmp = (struct rtw89_mac_mcc_tsf_rpt *)wait->data.buf; -+ *rpt = *tmp; -+ -+ return 0; -+} -+ -+#define H2C_MCC_MACID_BITMAP_DSC_LEN 4 -+int rtw89_fw_h2c_mcc_macid_bitamp(struct rtw89_dev *rtwdev, u8 group, u8 macid, -+ u8 *bitmap) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ u8 map_len; -+ u8 h2c_len; -+ -+ BUILD_BUG_ON(RTW89_MAX_MAC_ID_NUM % 8); -+ map_len = RTW89_MAX_MAC_ID_NUM / 8; -+ h2c_len = H2C_MCC_MACID_BITMAP_DSC_LEN + map_len; -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, h2c_len); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for mcc macid bitmap\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, h2c_len); -+ RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(skb->data, group); -+ RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(skb->data, macid); -+ RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(skb->data, map_len); -+ RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(skb->data, bitmap, map_len); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_MCC_MACID_BITMAP, 0, 0, -+ h2c_len); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_MACID_BITMAP); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_MCC_SYNC_LEN 4 -+int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, -+ u8 target, u8 offset) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SYNC_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for mcc sync\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_MCC_SYNC_LEN); -+ RTW89_SET_FWCMD_MCC_SYNC_GROUP(skb->data, group); -+ RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(skb->data, source); -+ RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(skb->data, target); -+ RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(skb->data, offset); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_MCC_SYNC, 0, 0, -+ H2C_MCC_SYNC_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_SYNC); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} -+ -+#define H2C_MCC_SET_DURATION_LEN 20 -+int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_duration *p) -+{ -+ struct rtw89_wait_info *wait = &rtwdev->mcc.wait; -+ struct sk_buff *skb; -+ unsigned int cond; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_MCC_SET_DURATION_LEN); -+ if (!skb) { -+ rtw89_err(rtwdev, -+ "failed to alloc skb for mcc set duration\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, H2C_MCC_SET_DURATION_LEN); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(skb->data, p->group); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(skb->data, p->btc_in_group); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(skb->data, p->start_macid); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(skb->data, p->macid_x); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(skb->data, p->macid_y); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(skb->data, -+ p->start_tsf_low); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(skb->data, -+ p->start_tsf_high); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(skb->data, p->duration_x); -+ RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(skb->data, p->duration_y); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, -+ H2C_CL_MCC, -+ H2C_FUNC_MCC_SET_DURATION, 0, 0, -+ H2C_MCC_SET_DURATION_LEN); -+ -+ cond = RTW89_MCC_WAIT_COND(p->group, H2C_FUNC_MCC_SET_DURATION); -+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -+} ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2767,6 +2767,355 @@ static inline void RTW89_SET_FWCMD_TSF32 - le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 16)); - } - -+enum rtw89_fw_mcc_c2h_rpt_cfg { -+ RTW89_FW_MCC_C2H_RPT_OFF = 0, -+ RTW89_FW_MCC_C2H_RPT_FAIL_ONLY = 1, -+ RTW89_FW_MCC_C2H_RPT_ALL = 2, -+}; -+ -+struct rtw89_fw_mcc_add_req { -+ u8 macid; -+ u8 central_ch_seg0; -+ u8 central_ch_seg1; -+ u8 primary_ch; -+ enum rtw89_bandwidth bandwidth: 4; -+ u32 group: 2; -+ u32 c2h_rpt: 2; -+ u32 dis_tx_null: 1; -+ u32 dis_sw_retry: 1; -+ u32 in_curr_ch: 1; -+ u32 sw_retry_count: 3; -+ u32 tx_null_early: 4; -+ u32 btc_in_2g: 1; -+ u32 pta_en: 1; -+ u32 rfk_by_pass: 1; -+ u32 ch_band_type: 2; -+ u32 rsvd0: 9; -+ u32 duration; -+ u8 courtesy_en; -+ u8 courtesy_num; -+ u8 courtesy_target; -+ u8 rsvd1; -+}; -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_MACID(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG0(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_CENTRAL_CH_SEG1(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_PRIMARY_CH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_BANDWIDTH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(3, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(5, 4)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_C2H_RPT(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(7, 6)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_DIS_TX_NULL(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(8)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_DIS_SW_RETRY(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(9)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_IN_CURR_CH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(10)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_SW_RETRY_COUNT(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(13, 11)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_TX_NULL_EARLY(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(17, 14)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_BTC_IN_2G(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(18)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_PTA_EN(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(19)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_RFK_BY_PASS(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, BIT(20)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_CH_BAND_TYPE(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(22, 21)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_DURATION(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_EN(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 3, val, BIT(0)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_NUM(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_ADD_MCC_COURTESY_TARGET(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(23, 16)); -+} -+ -+struct rtw89_fw_mcc_start_req { -+ u32 group: 2; -+ u32 btc_in_group: 1; -+ u32 old_group_action: 2; -+ u32 old_group: 2; -+ u32 rsvd0: 9; -+ u32 notify_cnt: 3; -+ u32 rsvd1: 2; -+ u32 notify_rxdbg_en: 1; -+ u32 rsvd2: 2; -+ u32 macid: 8; -+ u32 tsf_low; -+ u32 tsf_high; -+}; -+ -+static inline void RTW89_SET_FWCMD_START_MCC_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_BTC_IN_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, BIT(2)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_OLD_GROUP_ACTION(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(4, 3)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_OLD_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(6, 5)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_NOTIFY_CNT(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(18, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_NOTIFY_RXDBG_EN(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, BIT(21)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_MACID(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_TSF_LOW(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_START_MCC_TSF_HIGH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_STOP_MCC_MACID(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_STOP_MCC_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(9, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_STOP_MCC_PREV_GROUPS(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, BIT(10)); -+} -+ -+static inline void RTW89_SET_FWCMD_DEL_MCC_GROUP_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_DEL_MCC_GROUP_PREV_GROUPS(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, BIT(2)); -+} -+ -+static inline void RTW89_SET_FWCMD_RESET_MCC_GROUP_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+struct rtw89_fw_mcc_tsf_req { -+ u8 group: 2; -+ u8 rsvd0: 6; -+ u8 macid_x; -+ u8 macid_y; -+ u8 rsvd1; -+}; -+ -+static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_X(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_REQ_TSF_MACID_Y(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_MACID(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP_LENGTH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_MACID_BITMAP_BITMAP(void *cmd, -+ u8 *bitmap, u8 len) -+{ -+ memcpy((__le32 *)cmd + 1, bitmap, len); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SYNC_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SYNC_MACID_SOURCE(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SYNC_MACID_TARGET(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SYNC_SYNC_OFFSET(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); -+} -+ -+struct rtw89_fw_mcc_duration { -+ u32 group: 2; -+ u32 btc_in_group: 1; -+ u32 rsvd0: 5; -+ u32 start_macid: 8; -+ u32 macid_x: 8; -+ u32 macid_y: 8; -+ u32 start_tsf_low; -+ u32 start_tsf_high; -+ u32 duration_x; -+ u32 duration_y; -+}; -+ -+static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(1, 0)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_BTC_IN_GROUP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, BIT(2)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_MACID(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(15, 8)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_X(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(23, 16)); -+} -+ -+static inline void RTW89_SET_FWCMD_MCC_SET_DURATION_MACID_Y(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 24)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_LOW(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(31, 0)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_START_TSF_HIGH(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_X(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(31, 0)); -+} -+ -+static -+inline void RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)cmd + 4, val, GENMASK(31, 0)); -+} -+ - #define RTW89_C2H_HEADER_LEN 8 - - #define RTW89_GET_C2H_CATEGORY(c2h) \ -@@ -3185,9 +3534,27 @@ int rtw89_fw_h2c_wow_global(struct rtw89 - bool enable); - int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, bool enable); -- - int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, - struct rtw89_wow_cam_info *cam_info); -+int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_add_req *p); -+int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_start_req *p); -+int rtw89_fw_h2c_stop_mcc(struct rtw89_dev *rtwdev, u8 group, u8 macid, -+ bool prev_groups); -+int rtw89_fw_h2c_del_mcc_group(struct rtw89_dev *rtwdev, u8 group, -+ bool prev_groups); -+int rtw89_fw_h2c_reset_mcc_group(struct rtw89_dev *rtwdev, u8 group); -+int rtw89_fw_h2c_mcc_req_tsf(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_tsf_req *req, -+ struct rtw89_mac_mcc_tsf_rpt *rpt); -+int rtw89_fw_h2c_mcc_macid_bitamp(struct rtw89_dev *rtwdev, u8 group, u8 macid, -+ u8 *bitmap); -+int rtw89_fw_h2c_mcc_sync(struct rtw89_dev *rtwdev, u8 group, u8 source, -+ u8 target, u8 offset); -+int rtw89_fw_h2c_mcc_set_duration(struct rtw89_dev *rtwdev, -+ const struct rtw89_fw_mcc_duration *p); -+ - static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-076-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-076-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch deleted file mode 100644 index 4780e43a1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-076-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 75ee07b03fc6ec0a7ac7407f9ea7b3e981efb28f Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 29 Nov 2022 16:31:30 +0800 -Subject: [PATCH 076/149] wifi: rtw89: link rtw89_vif and chanctx stuffs - -First, introduce struct rtw89_sub_entity for chanctx related stuffs. -Second, add enum rtw89_sub_entity_idx to rtw89_vif for vif operation -to access its/right chanctx stuffs after future multi-channel support. - -Besides, RTW89_SUB_ENTITY_0 is the default chanctx entry throughout -driver, i.e. it's used for things which may not have a target chanctx -yet. So, we need to ensure that RTW89_SUB_ENTITY_0 is always working. -If there is at least one alive chanctx, then one of them must take -RTW89_SUB_ENTITY_0. If no alive chanctx, RTW89_SUB_ENTITY_0 will be -filled by rtw89_config_default_chandef(). - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221129083130.45708-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/chan.c | 40 +++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 20 ++++++---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + - 3 files changed, 50 insertions(+), 11 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/chan.c -+++ b/drivers/net/wireless/realtek/rtw89/chan.c -@@ -4,6 +4,7 @@ - - #include "chan.h" - #include "debug.h" -+#include "util.h" - - static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band, - u8 center_chan) -@@ -108,8 +109,8 @@ bool rtw89_assign_entity_chan(struct rtw - const struct rtw89_chan *new) - { - struct rtw89_hal *hal = &rtwdev->hal; -- struct rtw89_chan *chan = &hal->chan[idx]; -- struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx]; -+ struct rtw89_chan *chan = &hal->sub[idx].chan; -+ struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd; - bool band_changed; - - rcd->prev_primary_channel = chan->primary_channel; -@@ -127,7 +128,7 @@ static void __rtw89_config_entity_chande - { - struct rtw89_hal *hal = &rtwdev->hal; - -- hal->chandef[idx] = *chandef; -+ hal->sub[idx].chandef = *chandef; - - if (from_stack) - set_bit(idx, hal->entity_map); -@@ -195,6 +196,7 @@ int rtw89_chanctx_ops_add(struct rtw89_d - rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); - rtw89_set_channel(rtwdev); - cfg->idx = idx; -+ hal->sub[idx].cfg = cfg; - return 0; - } - -@@ -203,8 +205,34 @@ void rtw89_chanctx_ops_remove(struct rtw - { - struct rtw89_hal *hal = &rtwdev->hal; - struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; -+ struct rtw89_vif *rtwvif; -+ u8 drop, roll; - -- clear_bit(cfg->idx, hal->entity_map); -+ drop = cfg->idx; -+ if (drop != RTW89_SUB_ENTITY_0) -+ goto out; -+ -+ roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1); -+ -+ /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */ -+ if (roll == NUM_OF_RTW89_SUB_ENTITY) -+ goto out; -+ -+ /* RTW89_SUB_ENTITY_0 is going to release, and another exists. -+ * Make another roll down to RTW89_SUB_ENTITY_0 to replace. -+ */ -+ hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0; -+ hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll]; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) { -+ if (rtwvif->sub_entity_idx == roll) -+ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; -+ } -+ -+ drop = roll; -+ -+out: -+ clear_bit(drop, hal->entity_map); - rtw89_set_channel(rtwdev); - } - -@@ -225,6 +253,9 @@ int rtw89_chanctx_ops_assign_vif(struct - struct rtw89_vif *rtwvif, - struct ieee80211_chanctx_conf *ctx) - { -+ struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; -+ -+ rtwvif->sub_entity_idx = cfg->idx; - return 0; - } - -@@ -232,4 +263,5 @@ void rtw89_chanctx_ops_unassign_vif(stru - struct rtw89_vif *rtwvif, - struct ieee80211_chanctx_conf *ctx) - { -+ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; - } ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2240,6 +2240,8 @@ struct rtw89_phy_rate_pattern { - struct rtw89_vif { - struct list_head list; - struct rtw89_dev *rtwdev; -+ enum rtw89_sub_entity_idx sub_entity_idx; -+ - u8 mac_id; - u8 port; - u8 mac_addr[ETH_ALEN]; -@@ -2953,6 +2955,13 @@ enum rtw89_entity_mode { - RTW89_ENTITY_MODE_SCC, - }; - -+struct rtw89_sub_entity { -+ struct cfg80211_chan_def chandef; -+ struct rtw89_chan chan; -+ struct rtw89_chan_rcd rcd; -+ struct rtw89_chanctx_cfg *cfg; -+}; -+ - struct rtw89_hal { - u32 rx_fltr; - u8 cv; -@@ -2966,13 +2975,10 @@ struct rtw89_hal { - bool support_igi; - - DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY); -- struct cfg80211_chan_def chandef[NUM_OF_RTW89_SUB_ENTITY]; -+ struct rtw89_sub_entity sub[NUM_OF_RTW89_SUB_ENTITY]; - - bool entity_active; - enum rtw89_entity_mode entity_mode; -- -- struct rtw89_chan chan[NUM_OF_RTW89_SUB_ENTITY]; -- struct rtw89_chan_rcd chan_rcd[NUM_OF_RTW89_SUB_ENTITY]; - }; - - #define RTW89_MAX_MAC_ID_NUM 128 -@@ -4138,7 +4144,7 @@ const struct cfg80211_chan_def *rtw89_ch - { - struct rtw89_hal *hal = &rtwdev->hal; - -- return &hal->chandef[idx]; -+ return &hal->sub[idx].chandef; - } - - static inline -@@ -4147,7 +4153,7 @@ const struct rtw89_chan *rtw89_chan_get( - { - struct rtw89_hal *hal = &rtwdev->hal; - -- return &hal->chan[idx]; -+ return &hal->sub[idx].chan; - } - - static inline -@@ -4156,7 +4162,7 @@ const struct rtw89_chan_rcd *rtw89_chan_ - { - struct rtw89_hal *hal = &rtwdev->hal; - -- return &hal->chan_rcd[idx]; -+ return &hal->sub[idx].rcd; - } - - static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -131,6 +131,7 @@ static int rtw89_ops_add_interface(struc - rtwvif->bcn_hit_cond = 0; - rtwvif->mac_idx = RTW89_MAC_0; - rtwvif->phy_idx = RTW89_PHY_0; -+ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; - rtwvif->hit_rule = 0; - ether_addr_copy(rtwvif->mac_addr, vif->addr); - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-077-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-077-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch deleted file mode 100644 index 335d620f0..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-077-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 3ddfe3bdd3cf199676737fbd8cb7878b962acd2a Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Dec 2022 14:05:20 +0800 -Subject: [PATCH 077/149] wifi: rtw89: don't request partial firmware if - SECURITY_LOADPIN_ENFORCE - -Kernel logs on platform enabling SECURITY_LOADPIN_ENFORCE ------- -``` -LoadPin: firmware old-api-denied obj= pid=810 cmdline="modprobe -q -- rtw89_8852ce" -rtw89_8852ce 0000:01:00.0: loading /lib/firmware/rtw89/rtw8852c_fw.bin failed with error -1 -rtw89_8852ce 0000:01:00.0: Direct firmware load for rtw89/rtw8852c_fw.bin failed with error -1 -rtw89_8852ce 0000:01:00.0: failed to early request firmware: -1 -``` - -Trace ------- -``` -request_partial_firmware_into_buf() -> _request_firmware() ->> fw_get_filesystem_firmware() ->>> kernel_read_file_from_path_initns() ->>>> kernel_read_file() ->>>>> security_kernel_read_file() -// It will iterate enabled LSMs' hooks for kernel_read_file. -// With loadpin, it hooks loadpin_read_file. -``` - -If SECURITY_LOADPIN_ENFORCE is enabled, doing kernel_read_file() on partial -files will be denied and return -EPERM (-1). Then, the outer API based on it, -e.g. request_partial_firmware_into_buf(), will get the error. - -In the case, we cannot get the firmware stuffs right, even though there might -be no error other than a permission issue on reading a partial file. So we have -to request full firmware if SECURITY_LOADPIN_ENFORCE is enabled. It makes us -still have a chance to do early firmware work on this kind of platforms. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202060521.501512-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 30 +++++++++++++++++-------- - drivers/net/wireless/realtek/rtw89/fw.h | 15 +++++++++++++ - 2 files changed, 36 insertions(+), 9 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -277,25 +277,37 @@ void rtw89_early_fw_feature_recognize(st - const struct rtw89_chip_info *chip, - u32 *early_feat_map) - { -- union { -- struct rtw89_mfw_hdr mfw_hdr; -- u8 fw_hdr[RTW89_FW_HDR_SIZE]; -- } buf = {}; -+ union rtw89_compat_fw_hdr buf = {}; - const struct firmware *firmware; -+ bool full_req = false; - u32 ver_code; - int ret; - int i; - -- ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, -- device, &buf, sizeof(buf), 0); -+ /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will -+ * be denied (-EPERM). Then, we don't get right firmware things as -+ * expected. So, in this case, we have to request full firmware here. -+ */ -+ if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE)) -+ full_req = true; -+ -+ if (full_req) -+ ret = request_firmware(&firmware, chip->fw_name, device); -+ else -+ ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, -+ device, &buf, sizeof(buf), -+ 0); -+ - if (ret) { - dev_err(device, "failed to early request firmware: %d\n", ret); - return; - } - -- ver_code = buf.mfw_hdr.sig != RTW89_MFW_SIG ? -- RTW89_FW_HDR_VER_CODE(&buf.fw_hdr) : -- RTW89_MFW_HDR_VER_CODE(&buf.mfw_hdr); -+ if (full_req) -+ ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); -+ else -+ ver_code = rtw89_compat_fw_hdr_ver_code(&buf); -+ - if (!ver_code) - goto out; - ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3291,6 +3291,21 @@ struct fwcmd_hdr { - __le32 hdr1; - }; - -+union rtw89_compat_fw_hdr { -+ struct rtw89_mfw_hdr mfw_hdr; -+ u8 fw_hdr[RTW89_FW_HDR_SIZE]; -+}; -+ -+static inline u32 rtw89_compat_fw_hdr_ver_code(const void *fw_buf) -+{ -+ const union rtw89_compat_fw_hdr *compat = (typeof(compat))fw_buf; -+ -+ if (compat->mfw_hdr.sig == RTW89_MFW_SIG) -+ return RTW89_MFW_HDR_VER_CODE(&compat->mfw_hdr); -+ else -+ return RTW89_FW_HDR_VER_CODE(&compat->fw_hdr); -+} -+ - #define RTW89_H2C_RF_PAGE_SIZE 500 - #define RTW89_H2C_RF_PAGE_NUM 3 - struct rtw89_fw_h2c_rf_reg_info { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-078-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-078-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch deleted file mode 100644 index 9aaa123c6..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-078-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 13eb07e0be1b95f1e1fab721fb0f38117edfe80b Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Dec 2022 14:05:21 +0800 -Subject: [PATCH 078/149] wifi: rtw89: request full firmware only once if it's - early requested - -Under some condition, we now have to do early request full firmware when -rtw89_early_fw_feature_recognize(). In this case, we can avoid requesting -full firmware twice during probing driver. So, we pass out full firmware -from rtw89_early_fw_feature_recognize() if it's requested successfully. -And then, if firmware is settled, we have no need to request full firmware -again during normal initizating flow. - -Setting firmware flow is updated to be as the following. - - platform | early recognizing | normally initizating ------------------------------------------------------------------------ - deny reading | request full FW | (no more FW requesting) - partial file | | (obtain FW from early pahse) ------------------------------------------------------------------------ - able to read | request partial FW | async request full FW - partial file | (quite small chunk) | - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202060521.501512-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 ++++- - drivers/net/wireless/realtek/rtw89/fw.c | 28 +++++++++++++++++++---- - drivers/net/wireless/realtek/rtw89/fw.h | 7 +++--- - 3 files changed, 32 insertions(+), 9 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3423,6 +3423,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - u32 bus_data_size, - const struct rtw89_chip_info *chip) - { -+ const struct firmware *firmware; - struct ieee80211_hw *hw; - struct rtw89_dev *rtwdev; - struct ieee80211_ops *ops; -@@ -3430,7 +3431,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - u32 early_feat_map = 0; - bool no_chanctx; - -- rtw89_early_fw_feature_recognize(device, chip, &early_feat_map); -+ firmware = rtw89_early_fw_feature_recognize(device, chip, &early_feat_map); - - ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); - if (!ops) -@@ -3457,6 +3458,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - rtwdev->dev = device; - rtwdev->ops = ops; - rtwdev->chip = chip; -+ rtwdev->fw.firmware = firmware; - - rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n", - no_chanctx ? "without" : "with"); -@@ -3465,6 +3467,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - - err: - kfree(ops); -+ release_firmware(firmware); - return NULL; - } - EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); -@@ -3472,6 +3475,7 @@ EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); - void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev) - { - kfree(rtwdev->ops); -+ release_firmware(rtwdev->fw.firmware); - ieee80211_free_hw(rtwdev->hw); - } - EXPORT_SYMBOL(rtw89_free_ieee80211_hw); ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -273,9 +273,10 @@ static void rtw89_fw_recognize_features( - } - } - --void rtw89_early_fw_feature_recognize(struct device *device, -- const struct rtw89_chip_info *chip, -- u32 *early_feat_map) -+const struct firmware * -+rtw89_early_fw_feature_recognize(struct device *device, -+ const struct rtw89_chip_info *chip, -+ u32 *early_feat_map) - { - union rtw89_compat_fw_hdr buf = {}; - const struct firmware *firmware; -@@ -300,7 +301,7 @@ void rtw89_early_fw_feature_recognize(st - - if (ret) { - dev_err(device, "failed to early request firmware: %d\n", ret); -- return; -+ return NULL; - } - - if (full_req) -@@ -322,7 +323,11 @@ void rtw89_early_fw_feature_recognize(st - } - - out: -+ if (full_req) -+ return firmware; -+ - release_firmware(firmware); -+ return NULL; - } - - int rtw89_fw_recognize(struct rtw89_dev *rtwdev) -@@ -629,6 +634,13 @@ int rtw89_load_firmware(struct rtw89_dev - fw->rtwdev = rtwdev; - init_completion(&fw->completion); - -+ if (fw->firmware) { -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "full firmware has been early requested\n"); -+ complete_all(&fw->completion); -+ return 0; -+ } -+ - ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, - GFP_KERNEL, fw, rtw89_load_firmware_cb); - if (ret) { -@@ -645,8 +657,14 @@ void rtw89_unload_firmware(struct rtw89_ - - rtw89_wait_firmware_completion(rtwdev); - -- if (fw->firmware) -+ if (fw->firmware) { - release_firmware(fw->firmware); -+ -+ /* assign NULL back in case rtw89_free_ieee80211_hw() -+ * try to release the same one again. -+ */ -+ fw->firmware = NULL; -+ } - } - - #define H2C_CAM_LEN 60 ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3444,9 +3444,10 @@ struct rtw89_fw_h2c_rf_get_mccch { - - int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); - int rtw89_fw_recognize(struct rtw89_dev *rtwdev); --void rtw89_early_fw_feature_recognize(struct device *device, -- const struct rtw89_chip_info *chip, -- u32 *early_feat_map); -+const struct firmware * -+rtw89_early_fw_feature_recognize(struct device *device, -+ const struct rtw89_chip_info *chip, -+ u32 *early_feat_map); - int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); - int rtw89_load_firmware(struct rtw89_dev *rtwdev); - void rtw89_unload_firmware(struct rtw89_dev *rtwdev); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-079-wifi-rtw89-add-mac-TSF-sync-function.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-079-wifi-rtw89-add-mac-TSF-sync-function.patch deleted file mode 100644 index 8edb1ae10..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-079-wifi-rtw89-add-mac-TSF-sync-function.patch +++ /dev/null @@ -1,117 +0,0 @@ -From fb2b8cec81d75b2b20bdbc2fca7a60a68bc78aac Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 2 Dec 2022 14:15:24 +0800 -Subject: [PATCH 079/149] wifi: rtw89: add mac TSF sync function - -If the interface is in AP/P2P GO mode, we adjust the TSF with random -offset to avoid TBTT of different vifs to overlap and collide. -For every new interface added, we adjust the value and resync for all -interfaces. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202061527.505668-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 44 ++++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - drivers/net/wireless/realtek/rtw89/reg.h | 17 +++++++++ - 3 files changed, 63 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3913,6 +3913,49 @@ static void rtw89_mac_port_cfg_tbtt_shif - B_AX_TBTT_SHIFT_OFST_MASK, val); - } - -+static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_vif *rtwvif_src, u8 offset, -+ int *n_offset) -+{ -+ u32 val, reg; -+ -+ if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) -+ return; -+ -+ /* adjust offset randomly to avoid beacon conflict */ -+ offset = offset - offset / 4 + get_random_u32() % (offset / 2); -+ val = RTW89_PORT_OFFSET_MS_TO_32US((*n_offset)++, offset); -+ reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, -+ rtwvif->mac_idx); -+ -+ rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); -+ rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); -+ rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); -+} -+ -+static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_vif *src = NULL, *tmp; -+ u8 offset = 100, vif_aps = 0; -+ int n_offset = 1; -+ -+ rtw89_for_each_rtwvif(rtwdev, tmp) { -+ if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA) -+ src = tmp; -+ if (tmp->net_type == RTW89_NET_TYPE_AP_MODE) -+ vif_aps++; -+ } -+ -+ if (vif_aps == 0) -+ return; -+ -+ offset /= (vif_aps + 1); -+ -+ rtw89_for_each_rtwvif(rtwdev, tmp) -+ rtw89_mac_port_tsf_sync(rtwdev, tmp, src, offset, &n_offset); -+} -+ - int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) - { - int ret; -@@ -3991,6 +4034,7 @@ int rtw89_mac_port_update(struct rtw89_d - rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); - rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); - rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); -+ rtw89_mac_port_tsf_resync_all(rtwdev); - fsleep(BCN_ERLY_SET_DLY); - rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); - ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -168,6 +168,8 @@ enum rtw89_mac_ax_l0_to_l1_event { - MAC_AX_L0_TO_L1_EVENT_MAX = 15, - }; - -+#define RTW89_PORT_OFFSET_MS_TO_32US(n, shift_ms) ((n) * (shift_ms) * 1000 / 32) -+ - enum rtw89_mac_dbg_port_sel { - /* CMAC 0 related */ - RTW89_DBG_PORT_SEL_PTCL_C0 = 0, ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -2048,6 +2048,23 @@ - #define B_AX_PTCL_TOP_ERR_IND BIT(1) - #define B_AX_SCHEDULE_TOP_ERR_IND BIT(0) - -+#define R_AX_PORT0_TSF_SYNC 0xC2A0 -+#define R_AX_PORT0_TSF_SYNC_C1 0xE2A0 -+#define R_AX_PORT1_TSF_SYNC 0xC2A4 -+#define R_AX_PORT1_TSF_SYNC_C1 0xE2A4 -+#define R_AX_PORT2_TSF_SYNC 0xC2A8 -+#define R_AX_PORT2_TSF_SYNC_C1 0xE2A8 -+#define R_AX_PORT3_TSF_SYNC 0xC2AC -+#define R_AX_PORT3_TSF_SYNC_C1 0xE2AC -+#define R_AX_PORT4_TSF_SYNC 0xC2B0 -+#define R_AX_PORT4_TSF_SYNC_C1 0xE2B0 -+#define B_AX_SYNC_NOW BIT(30) -+#define B_AX_SYNC_ONCE BIT(29) -+#define B_AX_SYNC_AUTO BIT(28) -+#define B_AX_SYNC_PORT_SRC GENMASK(26, 24) -+#define B_AX_SYNC_PORT_OFFSET_SIGN BIT(18) -+#define B_AX_SYNC_PORT_OFFSET_VAL GENMASK(17, 0) -+ - #define R_AX_MACID_SLEEP_0 0xC2C0 - #define R_AX_MACID_SLEEP_0_C1 0xE2C0 - #define B_AX_MACID31_0_SLEEP_SH 0 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-080-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-080-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch deleted file mode 100644 index d44ad64da..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-080-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch +++ /dev/null @@ -1,80 +0,0 @@ -From d592b9f742643f07db53ac34baf6bbd3ce9478dc Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 2 Dec 2022 14:15:25 +0800 -Subject: [PATCH 080/149] wifi: rtw89: stop mac port function when stop_ap() - -Disable hardware beacon related functions when ap stops. So hardware won't -transmit beacons while interface is already removed. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202061527.505668-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 16 +++++++++++++--- - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + - 3 files changed, 15 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3877,11 +3877,16 @@ static void rtw89_mac_port_cfg_hiq_drop( - } - - static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, -- struct rtw89_vif *rtwvif) -+ struct rtw89_vif *rtwvif, bool enable) - { - const struct rtw89_port_reg *p = &rtw_port_base; - -- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN); -+ if (enable) -+ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, -+ B_AX_PORT_FUNC_EN); -+ else -+ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, -+ B_AX_PORT_FUNC_EN); - } - - static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, -@@ -4033,7 +4038,7 @@ int rtw89_mac_port_update(struct rtw89_d - rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif); - rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); - rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); -- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); -+ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true); - rtw89_mac_port_tsf_resync_all(rtwdev); - fsleep(BCN_ERLY_SET_DLY); - rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); -@@ -4085,6 +4090,11 @@ void rtw89_mac_set_he_obss_narrow_bw_ru( - rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_RU26_DIS); - } - -+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false); -+} -+ - int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) - { - int ret; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -908,6 +908,7 @@ int rtw89_mac_add_vif(struct rtw89_dev * - int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); -+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); - void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev); - int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw); ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -454,6 +454,7 @@ void rtw89_ops_stop_ap(struct ieee80211_ - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - - mutex_lock(&rtwdev->mutex); -+ rtw89_mac_stop_ap(rtwdev, rtwvif); - rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); - rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); - mutex_unlock(&rtwdev->mutex); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-081-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-081-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch deleted file mode 100644 index 3202ef9ad..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-081-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8fc5d4338620b81b1b265c725b38aced8acf8d72 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 2 Dec 2022 14:15:26 +0800 -Subject: [PATCH 081/149] wifi: rtw89: fix unsuccessful interface_add flow - -Remove according vifs from list if we couldn't set this interface up. -Otherwise the rtwvif_list could contain unreferenced objects. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202061527.505668-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -125,6 +125,7 @@ static int rtw89_ops_add_interface(struc - RTW89_PORT_NUM); - if (rtwvif->port == RTW89_PORT_NUM) { - ret = -ENOSPC; -+ list_del_init(&rtwvif->list); - goto out; - } - -@@ -138,6 +139,7 @@ static int rtw89_ops_add_interface(struc - ret = rtw89_mac_add_vif(rtwdev, rtwvif); - if (ret) { - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); -+ list_del_init(&rtwvif->list); - goto out; - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.2-082-wifi-rtw89-add-join-info-upon-create-interface.patch b/package/kernel/mac80211/patches/rtl/201-v6.2-082-wifi-rtw89-add-join-info-upon-create-interface.patch deleted file mode 100644 index a2f8eecd8..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.2-082-wifi-rtw89-add-join-info-upon-create-interface.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a0e78d5c6082fc953fef5af7293be0145c67dba4 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 2 Dec 2022 14:15:27 +0800 -Subject: [PATCH 082/149] wifi: rtw89: add join info upon create interface - -To support multiple vifs, fw need more information of each role. -Send this info to make things work as expected. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221202061527.505668-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3980,6 +3980,10 @@ int rtw89_mac_vif_init(struct rtw89_dev - if (ret) - return ret; - -+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); -+ if (ret) -+ return ret; -+ - ret = rtw89_cam_init(rtwdev, rtwvif); - if (ret) - return ret; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-083-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-083-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch deleted file mode 100644 index 7590349fd..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-083-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 25ed1a172298eed1cab329792d8e4d7363a411fc Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 9 Dec 2022 09:21:10 +0800 -Subject: [PATCH 083/149] wifi: rtw89: consider ER SU as a TX capability - -ER (Extended Range) SU is to have a larger coverage. We set this as a RA -capability, and then firmware can choose ER SU to transmit packets to -reception at cell edge. For 8852C, it needs to fill this capability in -TXWD, so update rtw89_build_txwd_info0_v1(). - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221209012110.7242-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 13 ++++++++++++- - drivers/net/wireless/realtek/rtw89/core.h | 2 ++ - drivers/net/wireless/realtek/rtw89/phy.c | 1 + - drivers/net/wireless/realtek/rtw89/txrx.h | 2 ++ - 4 files changed, 17 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -689,7 +689,9 @@ rtw89_core_tx_update_data_info(struct rt - struct rtw89_core_tx_request *tx_req) - { - struct ieee80211_vif *vif = tx_req->vif; -+ struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; -@@ -707,6 +709,7 @@ rtw89_core_tx_update_data_info(struct rt - desc_info->qsel = qsel; - desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); - desc_info->port = desc_info->hiq ? rtwvif->port : 0; -+ desc_info->er_cap = rtwsta ? rtwsta->er_cap : false; - - /* enable wd_info for AMPDU */ - desc_info->en_wd_info = true; -@@ -1006,7 +1009,9 @@ static __le32 rtw89_build_txwd_info0(str - static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info) - { - u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) | -- FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port); -+ FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port) | -+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_ER, desc_info->er_cap) | -+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW_ER, 0); - - return cpu_to_le32(dword); - } -@@ -2585,6 +2590,12 @@ int rtw89_core_sta_assoc(struct rtw89_de - rtw89_mac_bf_monitor_calc(rtwdev, sta, false); - - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { -+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; -+ -+ if (bss_conf->he_support && -+ !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) -+ rtwsta->er_cap = true; -+ - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, - BTC_ROLE_MSTS_STA_CONN_END); - rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -816,6 +816,7 @@ struct rtw89_tx_desc_info { - #define RTW89_MGMT_HW_SEQ_MODE 1 - bool hiq; - u8 port; -+ bool er_cap; - }; - - struct rtw89_core_tx_request { -@@ -2194,6 +2195,7 @@ struct rtw89_sec_cam_entry { - struct rtw89_sta { - u8 mac_id; - bool disassoc; -+ bool er_cap; - struct rtw89_dev *rtwdev; - struct rtw89_vif *rtwvif; - struct rtw89_ra_info ra; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -367,6 +367,7 @@ static void rtw89_phy_ra_sta_update(stru - } - - ra->bw_cap = bw_mode; -+ ra->er_cap = rtwsta->er_cap; - ra->mode_ctrl = mode; - ra->macid = rtwsta->mac_id; - ra->stbc_cap = stbc_en; ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -75,7 +75,9 @@ - #define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) - #define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25) - #define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16) -+#define RTW89_TXWD_INFO0_DATA_ER BIT(15) - #define RTW89_TXWD_INFO0_DISDATAFB BIT(10) -+#define RTW89_TXWD_INFO0_DATA_BW_ER BIT(8) - #define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4) - - /* TX WD INFO DWORD 1 */ diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-084-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-084-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch deleted file mode 100644 index 6e6239fa7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-084-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 18ddf102d4b8768cd058105168f29f96cd0c6d2d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 9 Dec 2022 09:22:15 +0800 -Subject: [PATCH 084/149] wifi: rtw89: fw: adapt to new firmware format of - security section - -Normally, system image should ensure firmware integrity, but we provide -an advance feature to ensure this by security section along with firmware. -To enable this feature, custom ID is programmed into efuse, and driver -will download proper security section to firmware. - -Since I don't have this kind hardware modules on hand yet, but new format -is used by newer firmware. Therefore, I prepare this patch in advance to -consider size of security section as a factor of checking rule of firmware -size, but don't actually download security section to firmware. - -This patch is backward compatible, so it will be safe to have this change -before adding an new format firmware to linux-firmware repository. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221209012215.7342-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 11 ++++++++++- - drivers/net/wireless/realtek/rtw89/fw.h | 13 +++++++++++-- - 2 files changed, 21 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -91,6 +91,7 @@ static int rtw89_fw_hdr_parser(struct rt - const u8 *fwdynhdr; - const u8 *bin; - u32 base_hdr_len; -+ u32 mssc_len = 0; - u32 i; - - if (!info) -@@ -120,6 +121,14 @@ static int rtw89_fw_hdr_parser(struct rt - fw += RTW89_FW_HDR_SIZE; - section_info = info->section_info; - for (i = 0; i < info->section_num; i++) { -+ section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw); -+ if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { -+ section_info->mssc = GET_FWSECTION_HDR_MSSC(fw); -+ mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; -+ } else { -+ section_info->mssc = 0; -+ } -+ - section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); - if (GET_FWSECTION_HDR_CHECKSUM(fw)) - section_info->len += FWDL_SECTION_CHKSUM_LEN; -@@ -132,7 +141,7 @@ static int rtw89_fw_hdr_parser(struct rt - section_info++; - } - -- if (fw_end != bin) { -+ if (fw_end != bin + mssc_len) { - rtw89_err(rtwdev, "[ERR]fw bin size\n"); - return -EINVAL; - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -171,6 +171,8 @@ struct rtw89_fw_hdr_section_info { - const u8 *addr; - u32 len; - u32 dladdr; -+ u32 mssc; -+ u8 type; - }; - - struct rtw89_fw_bin_info { -@@ -480,14 +482,21 @@ static inline void RTW89_SET_EDCA_PARAM( - #define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8) - #define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0) - -+#define FWDL_SECURITY_SECTION_TYPE 9 -+#define FWDL_SECURITY_SIGLEN 512 -+ -+#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ -+ le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) -+#define GET_FWSECTION_HDR_SECTIONTYPE(fwhdr) \ -+ le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(27, 24)) - #define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0)) - #define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28)) - #define GET_FWSECTION_HDR_REDL(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29)) --#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) -+#define GET_FWSECTION_HDR_MSSC(fwhdr) \ -+ le32_get_bits(*((const __le32 *)(fwhdr) + 2), GENMASK(31, 0)) - - #define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ - le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0)) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-087-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-087-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch deleted file mode 100644 index 96981f873..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-087-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 9c22d603e255ece73e61e3b3f93dae8ab82c17ff Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 9 Dec 2022 10:09:40 +0800 -Subject: [PATCH 087/149] wifi: rtw89: 8852c: rfk: recover RX DCK failure - -RX DCK stands for RX DC calibration that affects CCA, so abnormal -calibration values resulted from calibration failure can cause TX get -stuck. - -To solve this, redo calibration if result is bad (over thresholds). When -retry count is over, do recovery that sets high gain fields of RX DCK -results from low gain fields. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221209020940.9573-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 10 + - .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 253 +++++++++++++++++- - 2 files changed, 256 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3559,6 +3559,7 @@ - #define RR_MOD_IQK GENMASK(19, 4) - #define RR_MOD_DPK GENMASK(19, 5) - #define RR_MOD_MASK GENMASK(19, 16) -+#define RR_MOD_DCK GENMASK(14, 10) - #define RR_MOD_RGM GENMASK(13, 4) - #define RR_MOD_V_DOWN 0x0 - #define RR_MOD_V_STANDBY 0x1 -@@ -3572,6 +3573,7 @@ - #define RR_MOD_NBW GENMASK(15, 14) - #define RR_MOD_M_RXG GENMASK(13, 4) - #define RR_MOD_M_RXBB GENMASK(9, 5) -+#define RR_MOD_LO_SEL BIT(1) - #define RR_MODOPT 0x01 - #define RR_MODOPT_M_TXPWR GENMASK(5, 0) - #define RR_WLSEL 0x02 -@@ -3638,6 +3640,7 @@ - #define RR_LUTWA_M2 GENMASK(4, 0) - #define RR_LUTWD1 0x3e - #define RR_LUTWD0 0x3f -+#define RR_LUTWD0_MB GENMASK(11, 6) - #define RR_LUTWD0_LB GENMASK(5, 0) - #define RR_TM 0x42 - #define RR_TM_TRI BIT(19) -@@ -3731,10 +3734,14 @@ - #define RR_XALNA2_SW2 GENMASK(9, 8) - #define RR_XALNA2_SW GENMASK(1, 0) - #define RR_DCK 0x92 -+#define RR_DCK_S1 GENMASK(19, 16) -+#define RR_DCK_TIA GENMASK(15, 9) - #define RR_DCK_DONE GENMASK(7, 5) - #define RR_DCK_FINE BIT(1) - #define RR_DCK_LV BIT(0) - #define RR_DCK1 0x93 -+#define RR_DCK1_S1 GENMASK(19, 16) -+#define RR_DCK1_TIA GENMASK(15, 9) - #define RR_DCK1_DONE BIT(5) - #define RR_DCK1_CLR GENMASK(3, 0) - #define RR_DCK1_SEL BIT(3) -@@ -3783,11 +3790,14 @@ - #define RR_LUTDBG 0xdf - #define RR_LUTDBG_TIA BIT(12) - #define RR_LUTDBG_LOK BIT(2) -+#define RR_LUTPLL 0xec -+#define RR_CAL_RW BIT(19) - #define RR_LUTWE2 0xee - #define RR_LUTWE2_RTXBW BIT(2) - #define RR_LUTWE 0xef - #define RR_LUTWE_LOK BIT(2) - #define RR_RFC 0xf0 -+#define RR_WCAL BIT(16) - #define RR_RFC_CKEN BIT(1) - - #define R_UPD_P0 0x0000 ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -59,6 +59,9 @@ static const u32 dpk_par_regs[RTW89_DPK_ - {0x81a8, 0x81c4, 0x81c8, 0x81e8}, - }; - -+static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10}; -+static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c}; -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", -@@ -1536,6 +1539,155 @@ static void _iqk(struct rtw89_dev *rtwde - } - } - -+static void _rx_dck_value_rewrite(struct rtw89_dev *rtwdev, u8 path, u8 addr, -+ u8 val_i, u8 val_q) -+{ -+ u32 ofst_val; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] rewrite val_i = 0x%x, val_q = 0x%x\n", val_i, val_q); -+ -+ /* val_i and val_q are 7 bits, and target is 6 bits. */ -+ ofst_val = u32_encode_bits(val_q >> 1, RR_LUTWD0_MB) | -+ u32_encode_bits(val_i >> 1, RR_LUTWD0_LB); -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, MASKBYTE0, addr); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ofst_val); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RFC, RR_WCAL, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_LUTPLL, RR_CAL_RW, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] Final val_i = 0x%x, val_q = 0x%x\n", -+ u32_get_bits(ofst_val, RR_LUTWD0_LB) << 1, -+ u32_get_bits(ofst_val, RR_LUTWD0_MB) << 1); -+} -+ -+static bool _rx_dck_rek_check(struct rtw89_dev *rtwdev, u8 path) -+{ -+ u8 i_even_bs, q_even_bs; -+ u8 i_odd_bs, q_odd_bs; -+ u8 i_even, q_even; -+ u8 i_odd, q_odd; -+ const u8 th = 10; -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8852C; i++) { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]); -+ i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n", -+ _dck_addr_bs[i], i_even_bs, q_even_bs); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]); -+ i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n", -+ _dck_addr[i], i_even, q_even); -+ -+ if (abs(i_even_bs - i_even) > th || abs(q_even_bs - q_even) > th) -+ return true; -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1); -+ i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n", -+ _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1); -+ i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n", -+ _dck_addr[i] + 1, i_odd, q_odd); -+ -+ if (abs(i_odd_bs - i_odd) > th || abs(q_odd_bs - q_odd) > th) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void _rx_dck_fix_if_need(struct rtw89_dev *rtwdev, u8 path, u8 addr, -+ u8 val_i_bs, u8 val_q_bs, u8 val_i, u8 val_q) -+{ -+ const u8 th = 10; -+ -+ if ((abs(val_i_bs - val_i) < th) && (abs(val_q_bs - val_q) <= th)) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] offset check PASS!!\n"); -+ return; -+ } -+ -+ if (abs(val_i_bs - val_i) > th) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] val_i over TH (0x%x / 0x%x)\n", val_i_bs, val_i); -+ val_i = val_i_bs; -+ } -+ -+ if (abs(val_q_bs - val_q) > th) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] val_q over TH (0x%x / 0x%x)\n", val_q_bs, val_q); -+ val_q = val_q_bs; -+ } -+ -+ _rx_dck_value_rewrite(rtwdev, path, addr, val_i, val_q); -+} -+ -+static void _rx_dck_recover(struct rtw89_dev *rtwdev, u8 path) -+{ -+ u8 i_even_bs, q_even_bs; -+ u8 i_odd_bs, q_odd_bs; -+ u8 i_even, q_even; -+ u8 i_odd, q_odd; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] ===> recovery\n"); -+ -+ for (i = 0; i < RF_PATH_NUM_8852C; i++) { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i]); -+ i_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_even_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr_bs[i] + 1); -+ i_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_odd_bs = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n", -+ _dck_addr_bs[i], i_even_bs, q_even_bs); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i]); -+ i_even = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_even = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n", -+ _dck_addr[i], i_even, q_even); -+ _rx_dck_fix_if_need(rtwdev, path, _dck_addr[i], -+ i_even_bs, q_even_bs, i_even, q_even); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n", -+ _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DCK, _dck_addr[i] + 1); -+ i_odd = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_TIA); -+ q_odd = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_TIA); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n", -+ _dck_addr[i] + 1, i_odd, q_odd); -+ _rx_dck_fix_if_need(rtwdev, path, _dck_addr[i] + 1, -+ i_odd_bs, q_odd_bs, i_odd, q_odd); -+ } -+} -+ - static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path) - { - int ret; -@@ -1573,6 +1725,37 @@ static void _set_rx_dck(struct rtw89_dev - } - } - -+static -+u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) -+{ -+ u8 target_ch = 0; -+ -+ if (chan->band_type == RTW89_BAND_5G) { -+ if (chan->channel >= 36 && chan->channel <= 64) { -+ target_ch = 100; -+ } else if (chan->channel >= 100 && chan->channel <= 144) { -+ target_ch = chan->channel + 32; -+ if (target_ch > 144) -+ target_ch = chan->channel + 33; -+ } else if (chan->channel >= 149 && chan->channel <= 177) { -+ target_ch = chan->channel - 33; -+ } -+ } else if (chan->band_type == RTW89_BAND_6G) { -+ if (chan->channel >= 1 && chan->channel <= 125) -+ target_ch = chan->channel + 32; -+ else -+ target_ch = chan->channel - 32; -+ } else { -+ target_ch = chan->channel; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] cur_ch / target_ch = %d / %d\n", -+ chan->channel, target_ch); -+ -+ return target_ch; -+} -+ - #define RTW8852C_RF_REL_VERSION 34 - #define RTW8852C_DPK_VER 0x10 - #define RTW8852C_DPK_TH_AVG_NUM 4 -@@ -3874,11 +4057,14 @@ void rtw8852c_iqk(struct rtw89_dev *rtwd - - #define RXDCK_VER_8852C 0xe - --void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) -+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ bool is_afe, u8 retry_limit) - { - struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; - u8 path, kpath; - u32 rf_reg5; -+ bool is_fail; -+ u8 rek_cnt; - - kpath = _kpath(rtwdev, phy); - rtw89_debug(rtwdev, RTW89_DBG_RFK, -@@ -3895,7 +4081,27 @@ void rtw8852c_rx_dck(struct rtw89_dev *r - B_P0_TSSI_TRK_EN, 0x1); - rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); - rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); -- _set_rx_dck(rtwdev, phy, path, is_afe); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_LO_SEL, rtwdev->dbcc_en); -+ -+ for (rek_cnt = 0; rek_cnt < retry_limit; rek_cnt++) { -+ _set_rx_dck(rtwdev, phy, path, is_afe); -+ -+ /* To reduce IO of dck_rek_check(), the last try is seen -+ * as failure always, and then do recovery procedure. -+ */ -+ if (rek_cnt == retry_limit - 1) { -+ _rx_dck_recover(rtwdev, path); -+ break; -+ } -+ -+ is_fail = _rx_dck_rek_check(rtwdev, path); -+ if (!is_fail) -+ break; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] rek_cnt[%d]=%d", -+ path, rek_cnt); -+ - rx_dck->thermal[path] = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); - rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); - -@@ -3905,15 +4111,31 @@ void rtw8852c_rx_dck(struct rtw89_dev *r - } - } - --#define RTW8852C_RX_DCK_TH 8 -+void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) -+{ -+ _rx_dck(rtwdev, phy, is_afe, 1); -+} -+ -+#define RTW8852C_RX_DCK_TH 12 - - void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev) - { -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; -+ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u8 dck_channel; - u8 cur_thermal; -+ u32 tx_en; - int delta; - int path; - -+ if (chan->band_type == RTW89_BAND_2G) -+ return; -+ -+ if (rtwdev->scanning) -+ return; -+ - for (path = 0; path < RF_PATH_NUM_8852C; path++) { - cur_thermal = - ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -@@ -3923,11 +4145,28 @@ void rtw8852c_rx_dck_track(struct rtw89_ - "[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n", - path, cur_thermal, delta); - -- if (delta >= RTW8852C_RX_DCK_TH) { -- rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false); -- return; -- } -+ if (delta >= RTW8852C_RX_DCK_TH) -+ goto trigger_rx_dck; -+ } -+ -+ return; -+ -+trigger_rx_dck: -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ -+ for (path = 0; path < RF_PATH_NUM_8852C; path++) { -+ dck_channel = _rx_dck_channel_calc(rtwdev, chan); -+ _ctrl_ch(rtwdev, RTW89_PHY_0, dck_channel, chan->band_type); - } -+ -+ _rx_dck(rtwdev, RTW89_PHY_0, false, 20); -+ -+ for (path = 0; path < RF_PATH_NUM_8852C; path++) -+ _ctrl_ch(rtwdev, RTW89_PHY_0, chan->channel, chan->band_type); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); - } - - void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-088-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-088-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch deleted file mode 100644 index d71d18f10..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-088-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 6140635a73c00c0b3a8a58d13890dcf27d0af32a Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 17 Dec 2022 22:17:39 +0800 -Subject: [PATCH 088/149] wifi: rtw89: coex: add BTC format version derived - from firmware version - -Originally, each chip maintains its own format version followed firmware -it uses. As new chip is added, firmware changes format of exchange -messages to have rich information to handle more conditions. - -When old chip is going to upgrade firmware, it could use new format and -driver needs to maintain compatibility with old firmware. So, add this -version array to achieve this goal. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 95 +++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/coex.h | 1 + - drivers/net/wireless/realtek/rtw89/core.h | 26 +++++++ - drivers/net/wireless/realtek/rtw89/fw.c | 2 + - 4 files changed, 124 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -120,6 +120,70 @@ static const u32 cxtbl[] = { - 0xfafadafa /* 19 */ - }; - -+static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { -+ /* firmware version must be in decreasing order for each chip */ -+ {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), -+ .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, -+ .info_buf = 1280, .max_role_num = 5, -+ }, -+ {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0), -+ .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, -+ .info_buf = 1280, .max_role_num = 5, -+ }, -+ {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0), -+ .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, -+ .info_buf = 1280, .max_role_num = 5, -+ }, -+ {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), -+ .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, -+ .info_buf = 1800, .max_role_num = 6, -+ }, -+ {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0), -+ .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 1, .fcxctrl = 1, -+ .info_buf = 1280, .max_role_num = 5, -+ }, -+ {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0), -+ .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, -+ .info_buf = 1280, .max_role_num = 5, -+ }, -+ {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0), -+ .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, -+ .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, -+ .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, -+ .info_buf = 1024, .max_role_num = 5, -+ }, -+ -+ /* keep it to be the last as default entry */ -+ {0, RTW89_FW_VER_CODE(0, 0, 0, 0), -+ .fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2, -+ .fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1, -+ .fwlrole = 0, .frptmap = 0, .fcxctrl = 0, -+ .info_buf = 1024, .max_role_num = 5, -+ }, -+}; -+ -+#define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1) -+ - struct rtw89_btc_btf_tlv { - u8 type; - u8 len; -@@ -7008,3 +7072,34 @@ void rtw89_btc_dump_info(struct rtw89_de - else - _show_summary_v1(rtwdev, m); - } -+ -+void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *btc_ver_def; -+ const struct rtw89_fw_suit *fw_suit; -+ u32 suit_ver_code; -+ int i; -+ -+ fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); -+ suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); -+ -+ for (i = 0; i < ARRAY_SIZE(rtw89_btc_ver_defs); i++) { -+ btc_ver_def = &rtw89_btc_ver_defs[i]; -+ -+ if (chip->chip_id != btc_ver_def->chip_id) -+ continue; -+ -+ if (suit_ver_code >= btc_ver_def->fw_ver_code) { -+ btc->ver = btc_ver_def; -+ goto out; -+ } -+ } -+ -+ btc->ver = &rtw89_btc_ver_defs[RTW89_DEFAULT_BTC_VER_IDX]; -+ -+out: -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n", -+ (int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code); -+} ---- a/drivers/net/wireless/realtek/rtw89/coex.h -+++ b/drivers/net/wireless/realtek/rtw89/coex.h -@@ -164,6 +164,7 @@ void rtw89_coex_rfk_chk_work(struct work - void rtw89_coex_power_on(struct rtw89_dev *rtwdev); - void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type); - void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type); -+void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev); - - static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2019,9 +2019,35 @@ struct rtw89_btc_btf_fwinfo { - struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; - }; - -+struct rtw89_btc_ver { -+ enum rtw89_core_chip_id chip_id; -+ u32 fw_ver_code; -+ -+ u8 fcxbtcrpt; -+ u8 fcxtdma; -+ u8 fcxslots; -+ u8 fcxcysta; -+ u8 fcxstep; -+ u8 fcxnullsta; -+ u8 fcxmreg; -+ u8 fcxgpiodbg; -+ u8 fcxbtver; -+ u8 fcxbtscan; -+ u8 fcxbtafh; -+ u8 fcxbtdevinfo; -+ u8 fwlrole; -+ u8 frptmap; -+ u8 fcxctrl; -+ -+ u16 info_buf; -+ u8 max_role_num; -+}; -+ - #define RTW89_BTC_POLICY_MAXLEN 512 - - struct rtw89_btc { -+ const struct rtw89_btc_ver *ver; -+ - struct rtw89_btc_cx cx; - struct rtw89_btc_dm dm; - struct rtw89_btc_ctrl ctrl; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -352,6 +352,8 @@ int rtw89_fw_recognize(struct rtw89_dev - - rtw89_fw_recognize_features(rtwdev); - -+ rtw89_coex_recognize_ver(rtwdev); -+ - return 0; - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-089-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-089-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch deleted file mode 100644 index 4f8144d98..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-089-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch +++ /dev/null @@ -1,390 +0,0 @@ -From 1fc4a874ff02ba8c07f8abf97c0bef686406f6df Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 17 Dec 2022 22:17:40 +0800 -Subject: [PATCH 089/149] wifi: rtw89: coex: use new introduction BTC version - format - -Previous patch has added format version derived from firmware version. -Use the format version, and remove constant version number from chip_info. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 32 +++++++------- - drivers/net/wireless/realtek/rtw89/core.h | 42 +++++++------------ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 14 ------- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 15 +------ - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 ------- - 5 files changed, 32 insertions(+), 85 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -976,6 +976,7 @@ static u32 _chk_btc_report(struct rtw89_ - { - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; -@@ -1022,7 +1023,7 @@ static u32 _chk_btc_report(struct rtw89_ - pfinfo = &pfwinfo->rpt_ctrl.finfo_v1; - pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); - } -- pcinfo->req_fver = chip->fcxbtcrpt_ver; -+ pcinfo->req_fver = ver->fcxbtcrpt; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1035,7 +1036,7 @@ static u32 _chk_btc_report(struct rtw89_ - pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo_v1; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); - } -- pcinfo->req_fver = chip->fcxtdma_ver; -+ pcinfo->req_fver = ver->fcxtdma; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1043,7 +1044,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); -- pcinfo->req_fver = chip->fcxslots_ver; -+ pcinfo->req_fver = ver->fcxslots; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1059,7 +1060,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); - } -- pcinfo->req_fver = chip->fcxcysta_ver; -+ pcinfo->req_fver = ver->fcxcysta; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1076,7 +1077,7 @@ static u32 _chk_btc_report(struct rtw89_ - trace_step + - offsetof(struct rtw89_btc_fbtc_steps_v1, step); - } -- pcinfo->req_fver = chip->fcxstep_ver; -+ pcinfo->req_fver = ver->fcxstep; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1089,7 +1090,7 @@ static u32 _chk_btc_report(struct rtw89_ - pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); - } -- pcinfo->req_fver = chip->fcxnullsta_ver; -+ pcinfo->req_fver = ver->fcxnullsta; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1097,7 +1098,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); -- pcinfo->req_fver = chip->fcxmreg_ver; -+ pcinfo->req_fver = ver->fcxmreg; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1105,7 +1106,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); -- pcinfo->req_fver = chip->fcxgpiodbg_ver; -+ pcinfo->req_fver = ver->fcxgpiodbg; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1113,7 +1114,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btver.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); -- pcinfo->req_fver = chip->fcxbtver_ver; -+ pcinfo->req_fver = ver->fcxbtver; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1121,7 +1122,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); -- pcinfo->req_fver = chip->fcxbtscan_ver; -+ pcinfo->req_fver = ver->fcxbtscan; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1129,7 +1130,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); -- pcinfo->req_fver = chip->fcxbtafh_ver; -+ pcinfo->req_fver = ver->fcxbtafh; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1137,7 +1138,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); -- pcinfo->req_fver = chip->fcxbtdevinfo_ver; -+ pcinfo->req_fver = ver->fcxbtdevinfo; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; - break; -@@ -1394,7 +1395,7 @@ static void _parse_btc_report(struct rtw - struct rtw89_btc_btf_fwinfo *pfwinfo, - u8 *pbuf, u32 buf_len) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver; - struct rtw89_btc_prpt *btc_prpt = NULL; - u32 index = 0, rpt_len = 0; - -@@ -1404,7 +1405,7 @@ static void _parse_btc_report(struct rtw - - while (pbuf) { - btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; -- if (index + 2 >= chip->btc_fwinfo_buf) -+ if (index + 2 >= ver->info_buf) - break; - /* At least 3 bytes: type(1) & len(2) */ - rpt_len = le16_to_cpu(btc_prpt->len); -@@ -1424,6 +1425,7 @@ static void _append_tdma(struct rtw89_de - { - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_btf_tlv *tlv; - struct rtw89_btc_fbtc_tdma *v; -@@ -1448,7 +1450,7 @@ static void _append_tdma(struct rtw89_de - } else { - tlv->len = sizeof(*v1); - v1 = (struct rtw89_btc_fbtc_tdma_v1 *)&tlv->val[0]; -- v1->fver = chip->fcxtdma_ver; -+ v1->fver = ver->fcxtdma; - v1->tdma = dm->tdma; - btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v1); - } ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1438,7 +1438,7 @@ struct rtw89_btc_cx { - }; - - struct rtw89_btc_fbtc_tdma { -- u8 type; /* chip_info::fcxtdma_ver */ -+ u8 type; /* btc_ver::fcxtdma */ - u8 rxflctrl; - u8 txpause; - u8 wtgle_n; -@@ -1449,7 +1449,7 @@ struct rtw89_btc_fbtc_tdma { - } __packed; - - struct rtw89_btc_fbtc_tdma_v1 { -- u8 fver; /* chip_info::fcxtdma_ver */ -+ u8 fver; /* btc_ver::fcxtdma */ - u8 rsvd; - __le16 rsvd1; - struct rtw89_btc_fbtc_tdma tdma; -@@ -1474,7 +1474,7 @@ enum rtw89_btc_bt_sta_counter { - }; - - struct rtw89_btc_fbtc_rpt_ctrl { -- u16 fver; /* chip_info::fcxbtcrpt_ver */ -+ u16 fver; /* btc_ver::fcxbtcrpt */ - u16 rpt_cnt; /* tmr counters */ - u32 wl_fw_coex_ver; /* match which driver's coex version */ - u32 wl_fw_cx_offload; -@@ -1607,7 +1607,7 @@ enum { /* STEP TYPE */ - - #define BTC_DBG_MAX1 32 - struct rtw89_btc_fbtc_gpio_dbg { -- u8 fver; /* chip_info::fcxgpiodbg_ver */ -+ u8 fver; /* btc_ver::fcxgpiodbg */ - u8 rsvd; - u16 rsvd2; - u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ -@@ -1616,7 +1616,7 @@ struct rtw89_btc_fbtc_gpio_dbg { - } __packed; - - struct rtw89_btc_fbtc_mreg_val { -- u8 fver; /* chip_info::fcxmreg_ver */ -+ u8 fver; /* btc_ver::fcxmreg */ - u8 reg_num; - __le16 rsvd; - __le32 mreg_val[CXMREG_MAX]; -@@ -1639,7 +1639,7 @@ struct rtw89_btc_fbtc_slot { - } __packed; - - struct rtw89_btc_fbtc_slots { -- u8 fver; /* chip_info::fcxslots_ver */ -+ u8 fver; /* btc_ver::fcxslots */ - u8 tbl_num; - __le16 rsvd; - __le32 update_map; -@@ -1653,7 +1653,7 @@ struct rtw89_btc_fbtc_step { - } __packed; - - struct rtw89_btc_fbtc_steps { -- u8 fver; /* chip_info::fcxstep_ver */ -+ u8 fver; /* btc_ver::fcxstep */ - u8 rsvd; - __le16 cnt; - __le16 pos_old; -@@ -1670,7 +1670,7 @@ struct rtw89_btc_fbtc_steps_v1 { - } __packed; - - struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ -- u8 fver; /* chip_info::fcxcysta_ver */ -+ u8 fver; /* btc_ver::fcxcysta */ - u8 rsvd; - __le16 cycles; /* total cycle number */ - __le16 cycles_a2dp[CXT_FLCTRL_MAX]; -@@ -1750,7 +1750,7 @@ struct rtw89_btc_fbtc_cysta_v1 { /* stat - } __packed; - - struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ -- u8 fver; /* chip_info::fcxnullsta_ver */ -+ u8 fver; /* btc_ver::fcxnullsta */ - u8 rsvd; - __le16 rsvd2; - __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ -@@ -1759,7 +1759,7 @@ struct rtw89_btc_fbtc_cynullsta { /* cyc - } __packed; - - struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ -- u8 fver; /* chip_info::fcxnullsta_ver */ -+ u8 fver; /* btc_ver::fcxnullsta */ - u8 rsvd; - __le16 rsvd2; - __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ -@@ -1768,7 +1768,7 @@ struct rtw89_btc_fbtc_cynullsta_v1 { /* - } __packed; - - struct rtw89_btc_fbtc_btver { -- u8 fver; /* chip_info::fcxbtver_ver */ -+ u8 fver; /* btc_ver::fcxbtver */ - u8 rsvd; - __le16 rsvd2; - __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ -@@ -1777,14 +1777,14 @@ struct rtw89_btc_fbtc_btver { - } __packed; - - struct rtw89_btc_fbtc_btscan { -- u8 fver; /* chip_info::fcxbtscan_ver */ -+ u8 fver; /* btc_ver::fcxbtscan */ - u8 rsvd; - __le16 rsvd2; - u8 scan[6]; - } __packed; - - struct rtw89_btc_fbtc_btafh { -- u8 fver; /* chip_info::fcxbtafh_ver */ -+ u8 fver; /* btc_ver::fcxbtafh */ - u8 rsvd; - __le16 rsvd2; - u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ -@@ -1793,7 +1793,7 @@ struct rtw89_btc_fbtc_btafh { - } __packed; - - struct rtw89_btc_fbtc_btdevinfo { -- u8 fver; /* chip_info::fcxbtdevinfo_ver */ -+ u8 fver; /* btc_ver::fcxbtdevinfo */ - u8 rsvd; - __le16 vendor_id; - __le32 dev_name; /* only 24 bits valid */ -@@ -2756,20 +2756,6 @@ struct rtw89_chip_info { - u8 btcx_desired; - u8 scbd; - u8 mailbox; -- u16 btc_fwinfo_buf; -- -- u8 fcxbtcrpt_ver; -- u8 fcxtdma_ver; -- u8 fcxslots_ver; -- u8 fcxcysta_ver; -- u8 fcxstep_ver; -- u8 fcxnullsta_ver; -- u8 fcxmreg_ver; -- u8 fcxgpiodbg_ver; -- u8 fcxbtver_ver; -- u8 fcxbtscan_ver; -- u8 fcxbtafh_ver; -- u8 fcxbtdevinfo_ver; - - u8 afh_guard_ch; - const u8 *wl_rssi_thres; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2106,20 +2106,6 @@ const struct rtw89_chip_info rtw8852a_ch - .btcx_desired = 0x7, - .scbd = 0x1, - .mailbox = 0x1, -- .btc_fwinfo_buf = 1024, -- -- .fcxbtcrpt_ver = 1, -- .fcxtdma_ver = 1, -- .fcxslots_ver = 1, -- .fcxcysta_ver = 2, -- .fcxstep_ver = 2, -- .fcxnullsta_ver = 1, -- .fcxmreg_ver = 1, -- .fcxgpiodbg_ver = 1, -- .fcxbtver_ver = 1, -- .fcxbtscan_ver = 1, -- .fcxbtafh_ver = 1, -- .fcxbtdevinfo_ver = 1, - - .afh_guard_ch = 6, - .wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2483,20 +2483,7 @@ const struct rtw89_chip_info rtw8852b_ch - .btcx_desired = 0x5, - .scbd = 0x1, - .mailbox = 0x1, -- .btc_fwinfo_buf = 1024, - -- .fcxbtcrpt_ver = 1, -- .fcxtdma_ver = 1, -- .fcxslots_ver = 1, -- .fcxcysta_ver = 2, -- .fcxstep_ver = 2, -- .fcxnullsta_ver = 1, -- .fcxmreg_ver = 1, -- .fcxgpiodbg_ver = 1, -- .fcxbtver_ver = 1, -- .fcxbtscan_ver = 1, -- .fcxbtafh_ver = 1, -- .fcxbtdevinfo_ver = 1, - .afh_guard_ch = 6, - .wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres, - .bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2915,20 +2915,6 @@ const struct rtw89_chip_info rtw8852c_ch - .btcx_desired = 0x7, - .scbd = 0x1, - .mailbox = 0x1, -- .btc_fwinfo_buf = 1280, -- -- .fcxbtcrpt_ver = 4, -- .fcxtdma_ver = 3, -- .fcxslots_ver = 1, -- .fcxcysta_ver = 3, -- .fcxstep_ver = 3, -- .fcxnullsta_ver = 2, -- .fcxmreg_ver = 1, -- .fcxgpiodbg_ver = 1, -- .fcxbtver_ver = 1, -- .fcxbtscan_ver = 1, -- .fcxbtafh_ver = 1, -- .fcxbtdevinfo_ver = 1, - - .afh_guard_ch = 6, - .wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-090-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-090-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch deleted file mode 100644 index be9f7effe..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-090-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch +++ /dev/null @@ -1,80 +0,0 @@ -From bc20f9235f644846520a68340ea0730d09022e0a Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Sat, 17 Dec 2022 22:17:41 +0800 -Subject: [PATCH 090/149] wifi: rtw89: coex: Enable Bluetooth report when show - debug info - -Ask WiFi firmware to send Bluetooth version report when we want to show -Bluetooth debug info. If there is no request for debug log, driver will -not enable the report. This modification can save some C2H/H2C resources. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 32 ++++++++++++++--------- - 1 file changed, 19 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -5066,11 +5066,6 @@ static void _update_bt_info(struct rtw89 - - a2dp->sink = btinfo.hb3.a2dp_sink; - -- if (b->profile_cnt.now || b->status.map.ble_connect) -- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 1); -- else -- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 0); -- - if (!a2dp->exist_last && a2dp->exist) { - a2dp->vendor_id = 0; - a2dp->flush_time = 0; -@@ -5080,12 +5075,6 @@ static void _update_bt_info(struct rtw89 - RTW89_COEX_BT_DEVINFO_WORK_PERIOD); - } - -- if (a2dp->exist && (a2dp->flush_time == 0 || a2dp->vendor_id == 0 || -- a2dp->play_latency == 1)) -- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 1); -- else -- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 0); -- - _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); - } - -@@ -5218,8 +5207,7 @@ void rtw89_btc_ntfy_radio_state(struct r - - if (rf_state == BTC_RFCTRL_WL_ON) { - btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; -- rtw89_btc_fw_en_rpt(rtwdev, -- RPT_EN_MREG | RPT_EN_BT_VER_INFO, true); -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); - val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; - _write_scbd(rtwdev, val, true); - _update_bt_scbd(rtwdev, true); -@@ -5866,6 +5854,24 @@ static void _show_bt_info(struct rtw89_d - "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], - cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], - cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); -+ -+ if (bt->enable.now && bt->ver_info.fw == 0) -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); -+ else -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false); -+ -+ if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true); -+ else -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false); -+ -+ if (bt_linfo->a2dp_desc.exist && -+ (bt_linfo->a2dp_desc.flush_time == 0 || -+ bt_linfo->a2dp_desc.vendor_id == 0 || -+ bt_linfo->a2dp_desc.play_latency == 1)) -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true); -+ else -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false); - } - - #define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-091-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-091-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch deleted file mode 100644 index 6b195b869..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-091-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 52c7c983174cd8e2f92e157ef806be3629d5d73b Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Sat, 17 Dec 2022 22:17:42 +0800 -Subject: [PATCH 091/149] wifi: rtw89: coex: Update BTC firmware report bitmap - definition - -The different version use different bit definition to enable firmware -report. WiFi firmware will report information from Bluetooth firmware or -some Wi-Fi firmware mechanism/status to driver by these bits. To solve the -difference, add a function to map bitmap and versions. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 177 ++++++++++++++++++++-- - 1 file changed, 164 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -191,16 +191,20 @@ struct rtw89_btc_btf_tlv { - } __packed; - - enum btc_btf_set_report_en { -- RPT_EN_TDMA = BIT(0), -- RPT_EN_CYCLE = BIT(1), -- RPT_EN_MREG = BIT(2), -- RPT_EN_BT_VER_INFO = BIT(3), -- RPT_EN_BT_SCAN_INFO = BIT(4), -- RPT_EN_BT_AFH_MAP = BIT(5), -- RPT_EN_BT_DEVICE_INFO = BIT(6), -- RPT_EN_WL_ALL = GENMASK(2, 0), -- RPT_EN_BT_ALL = GENMASK(6, 3), -- RPT_EN_ALL = GENMASK(6, 0), -+ RPT_EN_TDMA, -+ RPT_EN_CYCLE, -+ RPT_EN_MREG, -+ RPT_EN_BT_VER_INFO, -+ RPT_EN_BT_SCAN_INFO, -+ RPT_EN_BT_DEVICE_INFO, -+ RPT_EN_BT_AFH_MAP, -+ RPT_EN_BT_AFH_MAP_LE, -+ RPT_EN_FW_STEP_INFO, -+ RPT_EN_TEST, -+ RPT_EN_WL_ALL, -+ RPT_EN_BT_ALL, -+ RPT_EN_ALL, -+ RPT_EN_MONITER, - }; - - #define BTF_SET_REPORT_VER 1 -@@ -1507,22 +1511,169 @@ static void _append_slot(struct rtw89_de - __func__, cnt); - } - -+static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; -+ u32 bit_map = 0; -+ -+ switch (rpt_map) { -+ case RPT_EN_TDMA: -+ bit_map = BIT(0); -+ break; -+ case RPT_EN_CYCLE: -+ bit_map = BIT(1); -+ break; -+ case RPT_EN_MREG: -+ bit_map = BIT(2); -+ break; -+ case RPT_EN_BT_VER_INFO: -+ bit_map = BIT(3); -+ break; -+ case RPT_EN_BT_SCAN_INFO: -+ bit_map = BIT(4); -+ break; -+ case RPT_EN_BT_DEVICE_INFO: -+ switch (ver->frptmap) { -+ case 0: -+ case 1: -+ case 2: -+ bit_map = BIT(6); -+ break; -+ case 3: -+ bit_map = BIT(5); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_BT_AFH_MAP: -+ switch (ver->frptmap) { -+ case 0: -+ case 1: -+ case 2: -+ bit_map = BIT(5); -+ break; -+ case 3: -+ bit_map = BIT(6); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_BT_AFH_MAP_LE: -+ switch (ver->frptmap) { -+ case 2: -+ bit_map = BIT(8); -+ break; -+ case 3: -+ bit_map = BIT(7); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_FW_STEP_INFO: -+ switch (ver->frptmap) { -+ case 1: -+ case 2: -+ bit_map = BIT(7); -+ break; -+ case 3: -+ bit_map = BIT(8); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_TEST: -+ bit_map = BIT(31); -+ break; -+ case RPT_EN_WL_ALL: -+ switch (ver->frptmap) { -+ case 0: -+ case 1: -+ case 2: -+ bit_map = GENMASK(2, 0); -+ break; -+ case 3: -+ bit_map = GENMASK(2, 0) | BIT(8); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_BT_ALL: -+ switch (ver->frptmap) { -+ case 0: -+ case 1: -+ bit_map = GENMASK(6, 3); -+ break; -+ case 2: -+ bit_map = GENMASK(6, 3) | BIT(8); -+ break; -+ case 3: -+ bit_map = GENMASK(7, 3); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_ALL: -+ switch (ver->frptmap) { -+ case 0: -+ bit_map = GENMASK(6, 0); -+ break; -+ case 1: -+ bit_map = GENMASK(7, 0); -+ break; -+ case 2: -+ case 3: -+ bit_map = GENMASK(8, 0); -+ break; -+ default: -+ break; -+ } -+ break; -+ case RPT_EN_MONITER: -+ switch (ver->frptmap) { -+ case 0: -+ case 1: -+ bit_map = GENMASK(6, 2); -+ break; -+ case 2: -+ bit_map = GENMASK(6, 2) | BIT(8); -+ break; -+ case 3: -+ bit_map = GENMASK(8, 2); -+ break; -+ default: -+ break; -+ } -+ break; -+ } -+ -+ return bit_map; -+} -+ - static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, - u32 rpt_map, bool rpt_state) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; - struct rtw89_btc_btf_set_report r = {0}; -- u32 val = 0; -+ u32 val, bit_map; -+ -+ bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map); - - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): rpt_map=%x, rpt_state=%x\n", - __func__, rpt_map, rpt_state); - - if (rpt_state) -- val = fwinfo->rpt_en_map | rpt_map; -+ val = fwinfo->rpt_en_map | bit_map; - else -- val = fwinfo->rpt_en_map & ~rpt_map; -+ val = fwinfo->rpt_en_map & ~bit_map; - - if (val == fwinfo->rpt_en_map) - return; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-092-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-092-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch deleted file mode 100644 index 19a9bf1cc..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-092-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch +++ /dev/null @@ -1,209 +0,0 @@ -From 0cdfcfce85b6f067f1639550a0aacf2c112a3441 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Sat, 17 Dec 2022 22:17:43 +0800 -Subject: [PATCH 092/149] wifi: rtw89: coex: Add v2 BT AFH report and related - variable - -Wi-Fi firmware update AFH report feature to version 2. If there is BT BLE -device connect to DUT, the mechanism will send H2C to request BT BLE -channel map, it will help to debug. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 54 ++++++++++++++++++++--- - drivers/net/wireless/realtek/rtw89/core.h | 26 ++++++++++- - 2 files changed, 72 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -854,17 +854,18 @@ static void _chk_btc_err(struct rtw89_de - static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; - struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; - struct rtw89_btc_fbtc_btver *pver = NULL; - struct rtw89_btc_fbtc_btscan *pscan = NULL; -- struct rtw89_btc_fbtc_btafh *pafh = NULL; -+ struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL; -+ struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL; - struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; - - pver = (struct rtw89_btc_fbtc_btver *)pfinfo; - pscan = (struct rtw89_btc_fbtc_btscan *)pfinfo; -- pafh = (struct rtw89_btc_fbtc_btafh *)pfinfo; - pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; - - rtw89_debug(rtwdev, RTW89_DBG_BTC, -@@ -881,9 +882,23 @@ static void _update_bt_report(struct rtw - memcpy(bt->scan_info, pscan->scan, BTC_SCAN_MAX1); - break; - case BTC_RPT_TYPE_BT_AFH: -- memcpy(&bt_linfo->afh_map[0], pafh->afh_l, 4); -- memcpy(&bt_linfo->afh_map[4], pafh->afh_m, 4); -- memcpy(&bt_linfo->afh_map[8], pafh->afh_h, 2); -+ if (ver->fcxbtafh == 2) { -+ pafh_v2 = (struct rtw89_btc_fbtc_btafh_v2 *)pfinfo; -+ if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LEGACY) { -+ memcpy(&bt_linfo->afh_map[0], pafh_v2->afh_l, 4); -+ memcpy(&bt_linfo->afh_map[4], pafh_v2->afh_m, 4); -+ memcpy(&bt_linfo->afh_map[8], pafh_v2->afh_h, 2); -+ } -+ if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LE) { -+ memcpy(&bt_linfo->afh_map_le[0], pafh_v2->afh_le_a, 4); -+ memcpy(&bt_linfo->afh_map_le[4], pafh_v2->afh_le_b, 1); -+ } -+ } else if (ver->fcxbtafh == 1) { -+ pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo; -+ memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4); -+ memcpy(&bt_linfo->afh_map[4], pafh_v1->afh_m, 4); -+ memcpy(&bt_linfo->afh_map[8], pafh_v1->afh_h, 2); -+ } - break; - case BTC_RPT_TYPE_BT_DEVICE: - a2dp->device_name = le32_to_cpu(pdev->dev_name); -@@ -1132,8 +1147,15 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_BT_AFH: - pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; -- pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); -+ if (ver->fcxbtafh == 1) { -+ pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1); -+ } else if (ver->fcxbtafh == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2); -+ } else { -+ goto err; -+ } - pcinfo->req_fver = ver->fcxbtafh; - pcinfo->rx_len = rpt_len; - pcinfo->rx_cnt++; -@@ -1393,6 +1415,11 @@ static u32 _chk_btc_report(struct rtw89_ - _update_bt_report(rtwdev, rpt_type, pfinfo); - - return (rpt_len + BTC_RPT_HDR_SIZE); -+ -+err: -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], %s(): Undefined version for type=%d\n", __func__, rpt_type); -+ return 0; - } - - static void _parse_btc_report(struct rtw89_dev *rtwdev, -@@ -5919,12 +5946,14 @@ static void _show_bt_profile_info(struct - static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_bt_info *bt = &cx->bt; - struct rtw89_btc_wl_info *wl = &cx->wl; - struct rtw89_btc_module *module = &btc->mdinfo; - struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; - u8 *afh = bt_linfo->afh_map; -+ u8 *afh_le = bt_linfo->afh_map_le; - - if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) - return; -@@ -5974,6 +6003,12 @@ static void _show_bt_info(struct rtw89_d - afh[0], afh[1], afh[2], afh[3], afh[4], - afh[5], afh[6], afh[7], afh[8], afh[9]); - -+ if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) -+ seq_printf(m, -+ "LE[%02x%02x_%02x_%02x%02x]", -+ afh_le[0], afh_le[1], afh_le[2], -+ afh_le[3], afh_le[4]); -+ - seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", - wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); - -@@ -6016,6 +6051,11 @@ static void _show_bt_info(struct rtw89_d - else - rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false); - -+ if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, true); -+ else -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, false); -+ - if (bt_linfo->a2dp_desc.exist && - (bt_linfo->a2dp_desc.flush_time == 0 || - bt_linfo->a2dp_desc.vendor_id == 0 || ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1264,6 +1264,7 @@ union rtw89_btc_bt_state_map { - - #define BTC_BT_RSSI_THMAX 4 - #define BTC_BT_AFH_GROUP 12 -+#define BTC_BT_AFH_LE_GROUP 5 - - struct rtw89_btc_bt_link_info { - struct rtw89_btc_u8_sta_chg profile_cnt; -@@ -1279,6 +1280,7 @@ struct rtw89_btc_bt_link_info { - u8 golden_rx_shift[BTC_PROFILE_MAX]; - u8 rssi_state[BTC_BT_RSSI_THMAX]; - u8 afh_map[BTC_BT_AFH_GROUP]; -+ u8 afh_map_le[BTC_BT_AFH_LE_GROUP]; - - u32 role_sw: 1; - u32 slave_role: 1; -@@ -1605,6 +1607,11 @@ enum { /* STEP TYPE */ - CXSTEP_MAX, - }; - -+enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */ -+ RPT_BT_AFH_SEQ_LEGACY = 0x10, -+ RPT_BT_AFH_SEQ_LE = 0x20 -+}; -+ - #define BTC_DBG_MAX1 32 - struct rtw89_btc_fbtc_gpio_dbg { - u8 fver; /* btc_ver::fcxgpiodbg */ -@@ -1792,6 +1799,18 @@ struct rtw89_btc_fbtc_btafh { - u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */ - } __packed; - -+struct rtw89_btc_fbtc_btafh_v2 { -+ u8 fver; /* btc_ver::fcxbtafh */ -+ u8 rsvd; -+ u8 rsvd2; -+ u8 map_type; -+ u8 afh_l[4]; -+ u8 afh_m[4]; -+ u8 afh_h[4]; -+ u8 afh_le_a[4]; -+ u8 afh_le_b[4]; -+} __packed; -+ - struct rtw89_btc_fbtc_btdevinfo { - u8 fver; /* btc_ver::fcxbtdevinfo */ - u8 rsvd; -@@ -1912,6 +1931,11 @@ struct rtw89_btc_rpt_cmn_info { - u8 valid; - } __packed; - -+union rtw89_btc_fbtc_btafh_info { -+ struct rtw89_btc_fbtc_btafh v1; -+ struct rtw89_btc_fbtc_btafh_v2 v2; -+}; -+ - struct rtw89_btc_report_ctrl_state { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ - union { -@@ -1979,7 +2003,7 @@ struct rtw89_btc_rpt_fbtc_btscan { - - struct rtw89_btc_rpt_fbtc_btafh { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- struct rtw89_btc_fbtc_btafh finfo; /* info from fw */ -+ union rtw89_btc_fbtc_btafh_info finfo; - }; - - struct rtw89_btc_rpt_fbtc_btdev { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-093-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-093-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch deleted file mode 100644 index b3cc9e729..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-093-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch +++ /dev/null @@ -1,509 +0,0 @@ -From 31f12cff9d262468a11dc02af48fd1e538e1223f Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Sat, 17 Dec 2022 22:17:44 +0800 -Subject: [PATCH 093/149] wifi: rtw89: coex: refactor _chk_btc_report() to - extend more features - -Change the checking logic to switch case. Make the code more readable. -There are more feature including to common code, in order to commit the -following version of the features, switch case will make the logic more -clearly. This patch did not change logic. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 365 +++++++++------------- - 1 file changed, 143 insertions(+), 222 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1006,7 +1006,6 @@ static u32 _chk_btc_report(struct rtw89_ - struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; - struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; - struct rtw89_btc_prpt *btc_prpt = NULL; -- struct rtw89_btc_fbtc_slot *rtp_slot = NULL; - void *rpt_content = NULL, *pfinfo = NULL; - u8 rpt_type = 0; - u16 wl_slot_set = 0, wl_slot_real = 0; -@@ -1043,8 +1042,6 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); - } - pcinfo->req_fver = ver->fcxbtcrpt; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_TDMA: - pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; -@@ -1056,16 +1053,12 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); - } - pcinfo->req_fver = ver->fcxtdma; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_SLOT: - pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); - pcinfo->req_fver = ver->fcxslots; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_CYSTA: - pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; -@@ -1080,8 +1073,6 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); - } - pcinfo->req_fver = ver->fcxcysta; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_STEP: - pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; -@@ -1097,8 +1088,6 @@ static u32 _chk_btc_report(struct rtw89_ - offsetof(struct rtw89_btc_fbtc_steps_v1, step); - } - pcinfo->req_fver = ver->fcxstep; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_NULLSTA: - pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; -@@ -1110,40 +1099,30 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); - } - pcinfo->req_fver = ver->fcxnullsta; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_MREG: - pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); - pcinfo->req_fver = ver->fcxmreg; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_GPIO_DBG: - pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); - pcinfo->req_fver = ver->fcxgpiodbg; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_BT_VER: - pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btver.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); - pcinfo->req_fver = ver->fcxbtver; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_BT_SCAN: - pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); - pcinfo->req_fver = ver->fcxbtscan; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_BT_AFH: - pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; -@@ -1157,22 +1136,21 @@ static u32 _chk_btc_report(struct rtw89_ - goto err; - } - pcinfo->req_fver = ver->fcxbtafh; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - case BTC_RPT_TYPE_BT_DEVICE: - pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; - pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); - pcinfo->req_fver = ver->fcxbtdevinfo; -- pcinfo->rx_len = rpt_len; -- pcinfo->rx_cnt++; - break; - default: - pfwinfo->err[BTFRE_UNDEF_TYPE]++; - return 0; - } - -+ pcinfo->rx_len = rpt_len; -+ pcinfo->rx_cnt++; -+ - if (rpt_len != pcinfo->req_len) { - if (rpt_type < BTC_RPT_TYPE_MAX) - pfwinfo->len_mismch |= (0x1 << rpt_type); -@@ -1193,227 +1171,170 @@ static u32 _chk_btc_report(struct rtw89_ - memcpy(pfinfo, rpt_content, pcinfo->req_len); - pcinfo->valid = 1; - -- if (rpt_type == BTC_RPT_TYPE_TDMA && chip->chip_id == RTL8852A) { -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): check %d %zu\n", __func__, -- BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); -+ switch (rpt_type) { -+ case BTC_RPT_TYPE_CTRL: -+ if (chip->chip_id == RTL8852A) { -+ prpt = &pfwinfo->rpt_ctrl.finfo; -+ btc->fwinfo.rpt_en_map = prpt->rpt_enable; -+ wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; -+ wl->ver_info.fw = prpt->wl_fw_ver; -+ dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; -+ -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ pfwinfo->event[BTF_EVNT_RPT]); -+ -+ /* To avoid I/O if WL LPS or power-off */ -+ if (wl->status.map.lps != BTC_LPS_RF_OFF && -+ !wl->status.map.rf_off) { -+ rtwdev->chip->ops->btc_update_bt_cnt(rtwdev); -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -+ -+ btc->cx.cnt_bt[BTC_BCNT_POLUT] = -+ rtw89_mac_get_plt_cnt(rtwdev, -+ RTW89_MAC_0); -+ } -+ } else { -+ prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; -+ btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); -+ wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); -+ wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); -+ dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); -+ -+ for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) -+ memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], -+ sizeof(dm->gnt.band[i])); -+ -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = -+ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = -+ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = -+ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = -+ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); -+ btc->cx.cnt_bt[BTC_BCNT_POLUT] = -+ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); - -- if (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo, -- sizeof(dm->tdma_now)) != 0) { -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", -- __func__, BTC_DCNT_TDMA_NONSYNC, -- dm->tdma_now.type, dm->tdma_now.rxflctrl, -- dm->tdma_now.txpause, dm->tdma_now.wtgle_n, -- dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, -- dm->tdma_now.rxflctrl_role, -- dm->tdma_now.option_ctrl); -- -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", -- __func__, BTC_DCNT_TDMA_NONSYNC, -- pfwinfo->rpt_fbtc_tdma.finfo.type, -- pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl, -- pfwinfo->rpt_fbtc_tdma.finfo.txpause, -- pfwinfo->rpt_fbtc_tdma.finfo.wtgle_n, -- pfwinfo->rpt_fbtc_tdma.finfo.leak_n, -- pfwinfo->rpt_fbtc_tdma.finfo.ext_ctrl, -- pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl_role, -- pfwinfo->rpt_fbtc_tdma.finfo.option_ctrl); -- } -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ pfwinfo->event[BTF_EVNT_RPT]); - -- _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, -- memcmp(&dm->tdma_now, -- &pfwinfo->rpt_fbtc_tdma.finfo, -- sizeof(dm->tdma_now))); -- } else if (rpt_type == BTC_RPT_TYPE_TDMA) { -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): check %d %zu\n", __func__, -- BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); -+ if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) -+ bt->rfk_info.map.timeout = 1; -+ else -+ bt->rfk_info.map.timeout = 0; - -- if (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, -- sizeof(dm->tdma_now)) != 0) { -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", -- __func__, BTC_DCNT_TDMA_NONSYNC, -- dm->tdma_now.type, dm->tdma_now.rxflctrl, -- dm->tdma_now.txpause, dm->tdma_now.wtgle_n, -- dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, -- dm->tdma_now.rxflctrl_role, -- dm->tdma_now.option_ctrl); -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", -- __func__, BTC_DCNT_TDMA_NONSYNC, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.type, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.txpause, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.wtgle_n, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.leak_n, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.ext_ctrl, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl_role, -- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.option_ctrl); -+ dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; - } -- -- _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, -- memcmp(&dm->tdma_now, -- &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, -- sizeof(dm->tdma_now))); -- } -- -- if (rpt_type == BTC_RPT_TYPE_SLOT) { -+ break; -+ case BTC_RPT_TYPE_TDMA: -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], %s(): check %d %zu\n", __func__, -+ BTC_DCNT_TDMA_NONSYNC, -+ sizeof(dm->tdma_now)); -+ if (chip->chip_id == RTL8852A) -+ _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, -+ memcmp(&dm->tdma_now, -+ &pfwinfo->rpt_fbtc_tdma.finfo_v1, -+ sizeof(dm->tdma_now))); -+ else -+ _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, -+ memcmp(&dm->tdma_now, -+ &pfwinfo->rpt_fbtc_tdma.finfo, -+ sizeof(dm->tdma_now))); -+ break; -+ case BTC_RPT_TYPE_SLOT: - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): check %d %zu\n", - __func__, BTC_DCNT_SLOT_NONSYNC, - sizeof(dm->slot_now)); -- -- if (memcmp(dm->slot_now, pfwinfo->rpt_fbtc_slots.finfo.slot, -- sizeof(dm->slot_now)) != 0) { -- for (i = 0; i < CXST_MAX; i++) { -- rtp_slot = -- &pfwinfo->rpt_fbtc_slots.finfo.slot[i]; -- if (memcmp(&dm->slot_now[i], rtp_slot, -- sizeof(dm->slot_now[i])) != 0) { -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d slot_now[%d] dur=0x%04x tbl=%08x type=0x%04x\n", -- __func__, -- BTC_DCNT_SLOT_NONSYNC, i, -- dm->slot_now[i].dur, -- dm->slot_now[i].cxtbl, -- dm->slot_now[i].cxtype); -- -- rtw89_debug(rtwdev, RTW89_DBG_BTC, -- "[BTC], %s(): %d rpt_fbtc_slots[%d] dur=0x%04x tbl=%08x type=0x%04x\n", -- __func__, -- BTC_DCNT_SLOT_NONSYNC, i, -- rtp_slot->dur, -- rtp_slot->cxtbl, -- rtp_slot->cxtype); -- } -- } -- } - _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, - memcmp(dm->slot_now, - pfwinfo->rpt_fbtc_slots.finfo.slot, - sizeof(dm->slot_now))); -- } -- -- if (rpt_type == BTC_RPT_TYPE_CYSTA && chip->chip_id == RTL8852A && -- pcysta->cycles >= BTC_CYSTA_CHK_PERIOD) { -- /* Check Leak-AP */ -- if (pcysta->slot_cnt[CXST_LK] != 0 && -- pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { -- if (pcysta->slot_cnt[CXST_LK] < -- BTC_LEAK_AP_TH * pcysta->leakrx_cnt) -- dm->leak_ap = 1; -- } -+ break; -+ case BTC_RPT_TYPE_CYSTA: -+ if (chip->chip_id == RTL8852A) { -+ if (pcysta->cycles < BTC_CYSTA_CHK_PERIOD) -+ break; -+ /* Check Leak-AP */ -+ if (pcysta->slot_cnt[CXST_LK] != 0 && -+ pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { -+ if (pcysta->slot_cnt[CXST_LK] < -+ BTC_LEAK_AP_TH * pcysta->leakrx_cnt) -+ dm->leak_ap = 1; -+ } - -- /* Check diff time between WL slot and W1/E2G slot */ -- if (dm->tdma_now.type == CXTDMA_OFF && -- dm->tdma_now.ext_ctrl == CXECTL_EXT) -- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); -- else -- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -+ /* Check diff time between WL slot and W1/E2G slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF && -+ dm->tdma_now.ext_ctrl == CXECTL_EXT) -+ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); -+ else -+ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -+ -+ if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { -+ diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; -+ _chk_btc_err(rtwdev, -+ BTC_DCNT_WL_SLOT_DRIFT, diff_t); -+ } - -- if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { -- diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; -- _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -- } -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ pcysta->slot_cnt[CXST_W1]); -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ pcysta->slot_cnt[CXST_B1]); -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ (u32)pcysta->cycles); -+ } else { -+ if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) -+ break; - -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_W1]); -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_B1]); -- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, (u32)pcysta->cycles); -- } else if (rpt_type == BTC_RPT_TYPE_CYSTA && pcysta_v1 && -- le16_to_cpu(pcysta_v1->cycles) >= BTC_CYSTA_CHK_PERIOD) { -- cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); -- cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); -- /* Check Leak-AP */ -- if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && -- dm->tdma_now.rxflctrl) { -- if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) -- dm->leak_ap = 1; -- } -+ cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); -+ cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); - -- /* Check diff time between real WL slot and W1 slot */ -- if (dm->tdma_now.type == CXTDMA_OFF) { -- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -- wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]); -- if (wl_slot_real > wl_slot_set) { -- diff_t = wl_slot_real - wl_slot_set; -- _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -+ /* Check Leak-AP */ -+ if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && -+ dm->tdma_now.rxflctrl) { -+ if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) -+ dm->leak_ap = 1; - } -- } - -- /* Check diff time between real BT slot and EBT/E5G slot */ -- if (dm->tdma_now.type == CXTDMA_OFF && -- dm->tdma_now.ext_ctrl == CXECTL_EXT && -- btc->bt_req_len != 0) { -- bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); -- -- if (btc->bt_req_len > bt_slot_real) { -- diff_t = btc->bt_req_len - bt_slot_real; -- _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); -+ /* Check diff time between real WL slot and W1 slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF) { -+ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -+ wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]); -+ if (wl_slot_real > wl_slot_set) { -+ diff_t = wl_slot_real - wl_slot_set; -+ _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -+ } - } -- } - -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); -- _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -- le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); -- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -- (u32)le16_to_cpu(pcysta_v1->cycles)); -- } -- -- if (rpt_type == BTC_RPT_TYPE_CTRL && chip->chip_id == RTL8852A) { -- prpt = &pfwinfo->rpt_ctrl.finfo; -- btc->fwinfo.rpt_en_map = prpt->rpt_enable; -- wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; -- wl->ver_info.fw = prpt->wl_fw_ver; -- dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; -- -- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -- pfwinfo->event[BTF_EVNT_RPT]); -- -- /* To avoid I/O if WL LPS or power-off */ -- if (wl->status.map.lps != BTC_LPS_RF_OFF && !wl->status.map.rf_off) { -- rtwdev->chip->ops->btc_update_bt_cnt(rtwdev); -- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -+ /* Check diff time between real BT slot and EBT/E5G slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF && -+ dm->tdma_now.ext_ctrl == CXECTL_EXT && -+ btc->bt_req_len != 0) { -+ bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); -+ -+ if (btc->bt_req_len > bt_slot_real) { -+ diff_t = btc->bt_req_len - bt_slot_real; -+ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); -+ } -+ } - -- btc->cx.cnt_bt[BTC_BCNT_POLUT] = -- rtw89_mac_get_plt_cnt(rtwdev, RTW89_MAC_0); -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -+ le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ (u32)le16_to_cpu(pcysta_v1->cycles)); - } -- } else if (rpt_type == BTC_RPT_TYPE_CTRL) { -- prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; -- btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); -- wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); -- wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); -- dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); -- -- for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) -- memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], -- sizeof(dm->gnt.band[i])); -- -- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); -- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); -- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); -- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); -- btc->cx.cnt_bt[BTC_BCNT_POLUT] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); -- -- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -- pfwinfo->event[BTF_EVNT_RPT]); -- -- if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) -- bt->rfk_info.map.timeout = 1; -- else -- bt->rfk_info.map.timeout = 0; -- -- dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; -- } -- -- if (rpt_type >= BTC_RPT_TYPE_BT_VER && -- rpt_type <= BTC_RPT_TYPE_BT_DEVICE) -+ break; -+ case BTC_RPT_TYPE_BT_VER: -+ case BTC_RPT_TYPE_BT_SCAN: -+ case BTC_RPT_TYPE_BT_AFH: -+ case BTC_RPT_TYPE_BT_DEVICE: - _update_bt_report(rtwdev, rpt_type, pfinfo); -- -+ break; -+ } - return (rpt_len + BTC_RPT_HDR_SIZE); - - err: diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-094-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-094-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch deleted file mode 100644 index c9ead46a4..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-094-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch +++ /dev/null @@ -1,162 +0,0 @@ -From e0097ac51e84243f0d0c065cbede1138f5e3aa9f Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Sat, 17 Dec 2022 22:17:45 +0800 -Subject: [PATCH 094/149] wifi: rtw89: coex: Change TDMA related logic to - version separate - -In order to make different version of TDMA and coming update in the future -can all work well, use BTC format version to replace chip_id, because -format could change for specific chip_id. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221217141745.43291-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 47 ++++++++++++----------- - drivers/net/wireless/realtek/rtw89/core.h | 12 +++--- - 2 files changed, 32 insertions(+), 27 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1045,12 +1045,14 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_TDMA: - pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; -- if (chip->chip_id == RTL8852A) { -- pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo); -+ if (ver->fcxtdma == 1) { -+ pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); -+ } else if (ver->fcxtdma == 3) { -+ pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); - } else { -- pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo_v1; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); -+ goto err; - } - pcinfo->req_fver = ver->fcxtdma; - break; -@@ -1232,16 +1234,18 @@ static u32 _chk_btc_report(struct rtw89_ - "[BTC], %s(): check %d %zu\n", __func__, - BTC_DCNT_TDMA_NONSYNC, - sizeof(dm->tdma_now)); -- if (chip->chip_id == RTL8852A) -+ if (ver->fcxtdma == 1) - _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, - memcmp(&dm->tdma_now, -- &pfwinfo->rpt_fbtc_tdma.finfo_v1, -+ &pfwinfo->rpt_fbtc_tdma.finfo.v1, - sizeof(dm->tdma_now))); -- else -+ else if (ver->fcxtdma == 3) - _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, - memcmp(&dm->tdma_now, -- &pfwinfo->rpt_fbtc_tdma.finfo, -+ &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma, - sizeof(dm->tdma_now))); -+ else -+ goto err; - break; - case BTC_RPT_TYPE_SLOT: - rtw89_debug(rtwdev, RTW89_DBG_BTC, -@@ -1375,13 +1379,12 @@ static void _parse_btc_report(struct rtw - - static void _append_tdma(struct rtw89_dev *rtwdev) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; - const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_btf_tlv *tlv; - struct rtw89_btc_fbtc_tdma *v; -- struct rtw89_btc_fbtc_tdma_v1 *v1; -+ struct rtw89_btc_fbtc_tdma_v3 *v3; - u16 len = btc->policy_len; - - if (!btc->update_policy_force && -@@ -1394,17 +1397,17 @@ static void _append_tdma(struct rtw89_de - - tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; - tlv->type = CXPOLICY_TDMA; -- if (chip->chip_id == RTL8852A) { -+ if (ver->fcxtdma == 1) { - v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; - tlv->len = sizeof(*v); - memcpy(v, &dm->tdma, sizeof(*v)); -- btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); -+ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); - } else { -- tlv->len = sizeof(*v1); -- v1 = (struct rtw89_btc_fbtc_tdma_v1 *)&tlv->val[0]; -- v1->fver = ver->fcxtdma; -- v1->tdma = dm->tdma; -- btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v1); -+ tlv->len = sizeof(*v3); -+ v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0]; -+ v3->fver = ver->fcxtdma; -+ memcpy(&v3->tdma, &dm->tdma, sizeof(v3->tdma)); -+ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v3); - } - - rtw89_debug(rtwdev, RTW89_DBG_BTC, -@@ -6281,8 +6284,8 @@ static void _show_error(struct rtw89_dev - - static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_fbtc_tdma *t = NULL; -@@ -6294,10 +6297,10 @@ static void _show_fbtc_tdma(struct rtw89 - if (!pcinfo->valid) - return; - -- if (chip->chip_id == RTL8852A) -- t = &pfwinfo->rpt_fbtc_tdma.finfo; -+ if (ver->fcxtdma == 1) -+ t = &pfwinfo->rpt_fbtc_tdma.finfo.v1; - else -- t = &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma; -+ t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma; - - seq_printf(m, - " %-15s : ", "[tdma_policy]"); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1450,13 +1450,18 @@ struct rtw89_btc_fbtc_tdma { - u8 option_ctrl; - } __packed; - --struct rtw89_btc_fbtc_tdma_v1 { -+struct rtw89_btc_fbtc_tdma_v3 { - u8 fver; /* btc_ver::fcxtdma */ - u8 rsvd; - __le16 rsvd1; - struct rtw89_btc_fbtc_tdma tdma; - } __packed; - -+union rtw89_btc_fbtc_tdma_le32 { -+ struct rtw89_btc_fbtc_tdma v1; -+ struct rtw89_btc_fbtc_tdma_v3 v3; -+}; -+ - #define CXMREG_MAX 30 - #define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ - #define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ -@@ -1946,10 +1951,7 @@ struct rtw89_btc_report_ctrl_state { - - struct rtw89_btc_rpt_fbtc_tdma { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- union { -- struct rtw89_btc_fbtc_tdma finfo; /* info from fw */ -- struct rtw89_btc_fbtc_tdma_v1 finfo_v1; /* info from fw for 52C*/ -- }; -+ union rtw89_btc_fbtc_tdma_le32 finfo; - }; - - struct rtw89_btc_rpt_fbtc_slots { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-095-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-095-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch deleted file mode 100644 index 7b17a0337..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-095-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch +++ /dev/null @@ -1,98 +0,0 @@ -From a48f4fd05d5ea20c55afb212240972c1bd2c6ad3 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Wed, 14 Dec 2022 17:18:03 +0800 -Subject: [PATCH 095/149] wifi: rtw89: 8852b: update BSS color mapping register - -BSS color mapping register is different per IC, therefore, move this -register to chip_info and update the setting function. Without this patch, -wrong BSS color causes behavior abnormal, especially DL-OFDMA. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221214091803.41293-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/phy.c | 9 +++++---- - drivers/net/wireless/realtek/rtw89/reg.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 6 files changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2811,6 +2811,7 @@ struct rtw89_chip_info { - u8 dcfo_comp_sft; - const struct rtw89_imr_info *imr_info; - const struct rtw89_rrsr_cfgs *rrsr_cfgs; -+ u32 bss_clr_map_reg; - u32 dma_ch_mask; - const struct wiphy_wowlan_support *wowlan_stub; - }; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -4117,6 +4117,7 @@ void rtw89_phy_dm_init(struct rtw89_dev - - void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; - enum rtw89_phy_idx phy_idx = RTW89_PHY_0; - u8 bss_color; - -@@ -4125,11 +4126,11 @@ void rtw89_phy_set_bss_color(struct rtw8 - - bss_color = vif->bss_conf.he_bss_color.color; - -- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0, 0x1, -+ rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_VLD0, 0x1, - phy_idx); -- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_TGT, bss_color, -- phy_idx); -- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_STAID, -+ rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_TGT, -+ bss_color, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_STAID, - vif->cfg.aid, phy_idx); - } - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4108,6 +4108,7 @@ - #define R_SEG0CSI_EN 0x42C4 - #define B_SEG0CSI_EN BIT(23) - #define R_BSS_CLR_MAP 0x43ac -+#define R_BSS_CLR_MAP_V1 0x43B0 - #define B_BSS_CLR_MAP_VLD0 BIT(28) - #define B_BSS_CLR_MAP_TGT GENMASK(27, 22) - #define B_BSS_CLR_MAP_STAID GENMASK(21, 11) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2135,6 +2135,7 @@ const struct rtw89_chip_info rtw8852a_ch - .dcfo_comp_sft = 3, - .imr_info = &rtw8852a_imr_info, - .rrsr_cfgs = &rtw8852a_rrsr_cfgs, -+ .bss_clr_map_reg = R_BSS_CLR_MAP, - .dma_ch_mask = 0, - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852a, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2512,6 +2512,7 @@ const struct rtw89_chip_info rtw8852b_ch - .dcfo_comp_sft = 3, - .imr_info = &rtw8852b_imr_info, - .rrsr_cfgs = &rtw8852b_rrsr_cfgs, -+ .bss_clr_map_reg = R_BSS_CLR_MAP_V1, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2945,6 +2945,7 @@ const struct rtw89_chip_info rtw8852c_ch - .dcfo_comp_sft = 5, - .imr_info = &rtw8852c_imr_info, - .rrsr_cfgs = &rtw8852c_rrsr_cfgs, -+ .bss_clr_map_reg = R_BSS_CLR_MAP, - .dma_ch_mask = 0, - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852c, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-096-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-096-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch deleted file mode 100644 index a9e176ffe..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-096-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 08c93c0ca74c4223dce8fb68e4bb24f7426e55c8 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Wed, 14 Dec 2022 17:19:52 +0800 -Subject: [PATCH 096/149] wifi: rtw89: refine 6 GHz scanning dwell time - -Reduce dwell time to improve scan duration in 6 GHz. This is required -for scan requests that does not include RNR parsing and does full -channel scan. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221214091952.42792-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 5 +++-- - drivers/net/wireless/realtek/rtw89/fw.h | 1 + - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2751,7 +2751,7 @@ static void rtw89_hw_scan_add_chan(struc - if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { - ch_info->tx_pkt = false; - if (!req->duration_mandatory) -- ch_info->period -= RTW89_DWELL_TIME; -+ ch_info->period -= RTW89_DWELL_TIME_6G; - } - } - -@@ -2804,7 +2804,8 @@ static int rtw89_hw_scan_add_chan_list(s - if (req->duration_mandatory) - ch_info->period = req->duration; - else if (channel->band == NL80211_BAND_6GHZ) -- ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME; -+ ch_info->period = RTW89_CHANNEL_TIME_6G + -+ RTW89_DWELL_TIME_6G; - else - ch_info->period = RTW89_CHANNEL_TIME; - ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -205,6 +205,7 @@ struct rtw89_h2creg_sch_tx_en { - #define RTW89_DFS_CHAN_TIME 105 - #define RTW89_OFF_CHAN_TIME 100 - #define RTW89_DWELL_TIME 20 -+#define RTW89_DWELL_TIME_6G 10 - #define RTW89_SCAN_WIDTH 0 - #define RTW89_SCANOFLD_MAX_SSID 8 - #define RTW89_SCANOFLD_MAX_IE_LEN 512 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-097-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-097-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch deleted file mode 100644 index 5b5601099..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-097-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ba1a6905c71898509fd3e8d1eb790b4e1213126f Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Fri, 16 Dec 2022 13:29:39 +0800 -Subject: [PATCH 097/149] wifi: rtw89: 8852c: rfk: refine AGC tuning flow of - DPK for irregular PA - -Some hardware modules don't have good RF characteristic as regular. -It could have RF PA characteristic that current code doesn't handle -properly, and it runs into wrong DPK flow that doesn't complete DPK -resulting in bad EVM. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221216052939.9991-1-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 38 +++++++++++++++---- - 1 file changed, 30 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -26,7 +26,7 @@ static const u32 rtw8852c_backup_bb_regs - }; - - static const u32 rtw8852c_backup_rf_regs[] = { -- 0xdf, 0x8f, 0x97, 0xa3, 0x5, 0x10005 -+ 0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005 - }; - - #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs) -@@ -1757,7 +1757,7 @@ u8 _rx_dck_channel_calc(struct rtw89_dev - } - - #define RTW8852C_RF_REL_VERSION 34 --#define RTW8852C_DPK_VER 0x10 -+#define RTW8852C_DPK_VER 0xf - #define RTW8852C_DPK_TH_AVG_NUM 4 - #define RTW8852C_DPK_RF_PATH 2 - #define RTW8852C_DPK_KIP_REG_NUM 5 -@@ -1797,6 +1797,12 @@ enum dpk_agc_step { - DPK_AGC_STEP_SET_TX_GAIN, - }; - -+enum dpk_pas_result { -+ DPK_PAS_NOR, -+ DPK_PAS_GT, -+ DPK_PAS_LT, -+}; -+ - static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, - enum rtw89_rf_path path, bool is_bybb) - { -@@ -2206,9 +2212,10 @@ static u8 _dpk_gainloss(struct rtw89_dev - return _dpk_gainloss_read(rtwdev); - } - --static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) -+static enum dpk_pas_result _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) - { - u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; -+ u32 val1_sqrt_sum, val2_sqrt_sum; - u8 i; - - rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); -@@ -2239,15 +2246,25 @@ static bool _dpk_pas_read(struct rtw89_d - } - } - -- if (val1_i * val1_i + val1_q * val1_q >= (val2_i * val2_i + val2_q * val2_q) * 8 / 5) -- return true; -+ val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; -+ val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; -+ -+ if (val1_sqrt_sum < val2_sqrt_sum) -+ return DPK_PAS_LT; -+ else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) -+ return DPK_PAS_GT; - else -- return false; -+ return DPK_PAS_NOR; - } - - static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, - enum rtw89_rf_path path, u8 kidx) - { -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); -+ _dpk_kip_control_rfc(rtwdev, path, true); -+ - _dpk_one_shot(rtwdev, phy, path, D_RXAGC); - - return _dpk_sync_check(rtwdev, path, kidx); -@@ -2285,6 +2302,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtw - u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; - u8 tmp_rxbb; - u8 goout = 0, agc_cnt = 0; -+ enum dpk_pas_result pas; - u16 dgain = 0; - bool is_fail = false; - int limit = 200; -@@ -2320,9 +2338,13 @@ static u8 _dpk_agc(struct rtw89_dev *rtw - - case DPK_AGC_STEP_GAIN_LOSS_IDX: - tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); -+ pas = _dpk_pas_read(rtwdev, true); - -- if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || -- tmp_gl_idx >= 7) -+ if (pas == DPK_PAS_LT && tmp_gl_idx > 0) -+ step = DPK_AGC_STEP_GL_LT_CRITERION; -+ else if (pas == DPK_PAS_GT && tmp_gl_idx == 0) -+ step = DPK_AGC_STEP_GL_GT_CRITERION; -+ else if (tmp_gl_idx >= 7) - step = DPK_AGC_STEP_GL_GT_CRITERION; - else if (tmp_gl_idx == 0) - step = DPK_AGC_STEP_GL_LT_CRITERION; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-098-wifi-rtw89-Fix-a-typo-in-debug-message.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-098-wifi-rtw89-Fix-a-typo-in-debug-message.patch deleted file mode 100644 index 7ba9eb6b1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-098-wifi-rtw89-Fix-a-typo-in-debug-message.patch +++ /dev/null @@ -1,26 +0,0 @@ -From e20c9f656654f74c9234e6cd3231aed72f53d246 Mon Sep 17 00:00:00 2001 -From: Masanari Iida -Date: Fri, 23 Dec 2022 19:20:58 +0900 -Subject: [PATCH 098/149] wifi: rtw89: Fix a typo in debug message - -This patch fixes a spelling typo in debug message. - -Signed-off-by: Masanari Iida -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20221223102058.162179-1-standby24x7@gmail.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c -@@ -1643,7 +1643,7 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]==========IQK strat!!!!!==========\n"); -+ "[IQK]==========IQK start!!!!!==========\n"); - iqk_info->iqk_times++; - iqk_info->kcount = 0; - iqk_info->version = RTW8852A_IQK_VER; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-099-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-099-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch deleted file mode 100644 index 933bdf087..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-099-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch +++ /dev/null @@ -1,326 +0,0 @@ -From f643d08642b82eeb9b9654399dd04657050f7c6f Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:32 +0800 -Subject: [PATCH 099/149] wifi: rtw89: coex: Remove le32 to CPU translator at - firmware cycle report - -There are at least 2 version of cycle report format. If the code keep -translating the report to local variable, the numbers of variable in -check btc report function will out of maximum variable numbers. And -most of these variable are using only one time, it is not necessary -to store at memory. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 190 +++++++--------------- - 1 file changed, 60 insertions(+), 130 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -910,76 +910,6 @@ static void _update_bt_report(struct rtw - } - } - --struct rtw89_btc_fbtc_cysta_cpu { -- u8 fver; -- u8 rsvd; -- u16 cycles; -- u16 cycles_a2dp[CXT_FLCTRL_MAX]; -- u16 a2dpept; -- u16 a2dpeptto; -- u16 tavg_cycle[CXT_MAX]; -- u16 tmax_cycle[CXT_MAX]; -- u16 tmaxdiff_cycle[CXT_MAX]; -- u16 tavg_a2dp[CXT_FLCTRL_MAX]; -- u16 tmax_a2dp[CXT_FLCTRL_MAX]; -- u16 tavg_a2dpept; -- u16 tmax_a2dpept; -- u16 tavg_lk; -- u16 tmax_lk; -- u32 slot_cnt[CXST_MAX]; -- u32 bcn_cnt[CXBCN_MAX]; -- u32 leakrx_cnt; -- u32 collision_cnt; -- u32 skip_cnt; -- u32 exception; -- u32 except_cnt; -- u16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; --}; -- --static void rtw89_btc_fbtc_cysta_to_cpu(const struct rtw89_btc_fbtc_cysta *src, -- struct rtw89_btc_fbtc_cysta_cpu *dst) --{ -- static_assert(sizeof(*src) == sizeof(*dst)); -- --#define __CPY_U8(_x) ({dst->_x = src->_x; }) --#define __CPY_LE16(_x) ({dst->_x = le16_to_cpu(src->_x); }) --#define __CPY_LE16S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ -- dst->_x[_i] = le16_to_cpu(src->_x[_i]); }) --#define __CPY_LE32(_x) ({dst->_x = le32_to_cpu(src->_x); }) --#define __CPY_LE32S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ -- dst->_x[_i] = le32_to_cpu(src->_x[_i]); }) -- -- __CPY_U8(fver); -- __CPY_U8(rsvd); -- __CPY_LE16(cycles); -- __CPY_LE16S(cycles_a2dp); -- __CPY_LE16(a2dpept); -- __CPY_LE16(a2dpeptto); -- __CPY_LE16S(tavg_cycle); -- __CPY_LE16S(tmax_cycle); -- __CPY_LE16S(tmaxdiff_cycle); -- __CPY_LE16S(tavg_a2dp); -- __CPY_LE16S(tmax_a2dp); -- __CPY_LE16(tavg_a2dpept); -- __CPY_LE16(tmax_a2dpept); -- __CPY_LE16(tavg_lk); -- __CPY_LE16(tmax_lk); -- __CPY_LE32S(slot_cnt); -- __CPY_LE32S(bcn_cnt); -- __CPY_LE32(leakrx_cnt); -- __CPY_LE32(collision_cnt); -- __CPY_LE32(skip_cnt); -- __CPY_LE32(exception); -- __CPY_LE32(except_cnt); -- __CPY_LE16S(tslot_cycle); -- --#undef __CPY_U8 --#undef __CPY_LE16 --#undef __CPY_LE16S --#undef __CPY_LE32 --#undef __CPY_LE32S --} -- - #define BTC_LEAK_AP_TH 10 - #define BTC_CYSTA_CHK_PERIOD 100 - -@@ -1002,9 +932,8 @@ static u32 _chk_btc_report(struct rtw89_ - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_btc_fbtc_rpt_ctrl *prpt; - struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; -- struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; -+ struct rtw89_btc_fbtc_cysta *pcysta = NULL; - struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; -- struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; - struct rtw89_btc_prpt *btc_prpt = NULL; - void *rpt_content = NULL, *pfinfo = NULL; - u8 rpt_type = 0; -@@ -1066,8 +995,7 @@ static u32 _chk_btc_report(struct rtw89_ - pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; - if (chip->chip_id == RTL8852A) { - pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo; -- pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; -- rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); - } else { - pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1; -@@ -1259,13 +1187,13 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_CYSTA: - if (chip->chip_id == RTL8852A) { -- if (pcysta->cycles < BTC_CYSTA_CHK_PERIOD) -+ if (le16_to_cpu(pcysta->cycles) < BTC_CYSTA_CHK_PERIOD) - break; - /* Check Leak-AP */ -- if (pcysta->slot_cnt[CXST_LK] != 0 && -- pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { -- if (pcysta->slot_cnt[CXST_LK] < -- BTC_LEAK_AP_TH * pcysta->leakrx_cnt) -+ if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) != 0 && -+ le32_to_cpu(pcysta->leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { -+ if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) < -+ BTC_LEAK_AP_TH * le32_to_cpu(pcysta->leakrx_cnt)) - dm->leak_ap = 1; - } - -@@ -1276,18 +1204,18 @@ static u32 _chk_btc_report(struct rtw89_ - else - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); - -- if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { -- diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; -+ if (le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) > wl_slot_set) { -+ diff_t = le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) - wl_slot_set; - _chk_btc_err(rtwdev, - BTC_DCNT_WL_SLOT_DRIFT, diff_t); - } - - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- pcysta->slot_cnt[CXST_W1]); -+ le32_to_cpu(pcysta->slot_cnt[CXST_W1])); - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- pcysta->slot_cnt[CXST_B1]); -+ le32_to_cpu(pcysta->slot_cnt[CXST_B1])); - _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -- (u32)pcysta->cycles); -+ le16_to_cpu(pcysta->cycles)); - } else { - if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) - break; -@@ -6385,7 +6313,6 @@ static void _show_fbtc_cysta(struct rtw8 - struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; -- struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; - union rtw89_btc_fbtc_rxflct r; - u8 i, cnt = 0, slot_pair; - u16 cycle, c_begin, c_end, store_index; -@@ -6395,64 +6322,65 @@ static void _show_fbtc_cysta(struct rtw8 - return; - - pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; -- rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", -- "[cycle_cnt]", pcysta->cycles, pcysta->bcn_cnt[CXBCN_ALL], -- pcysta->bcn_cnt[CXBCN_ALL_OK], -- pcysta->bcn_cnt[CXBCN_BT_SLOT], -- pcysta->bcn_cnt[CXBCN_BT_OK]); -+ "[cycle_cnt]", -+ le16_to_cpu(pcysta_le32->cycles), -+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]), -+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]), -+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]), -+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK])); - - for (i = 0; i < CXST_MAX; i++) { -- if (!pcysta->slot_cnt[i]) -+ if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) - continue; -- seq_printf(m, -- ", %d:%d", (u32)i, pcysta->slot_cnt[i]); -+ seq_printf(m, ", %d:%d", (u32)i, -+ le32_to_cpu(pcysta_le32->slot_cnt[i])); - } - - if (dm->tdma_now.rxflctrl) { -- seq_printf(m, -- ", leak_rx:%d", pcysta->leakrx_cnt); -+ seq_printf(m, ", leak_rx:%d", -+ le32_to_cpu(pcysta_le32->leakrx_cnt)); - } - -- if (pcysta->collision_cnt) { -- seq_printf(m, -- ", collision:%d", pcysta->collision_cnt); -+ if (le32_to_cpu(pcysta_le32->collision_cnt)) { -+ seq_printf(m, ", collision:%d", -+ le32_to_cpu(pcysta_le32->collision_cnt)); - } - -- if (pcysta->skip_cnt) { -- seq_printf(m, -- ", skip:%d", pcysta->skip_cnt); -+ if (le32_to_cpu(pcysta_le32->skip_cnt)) { -+ seq_printf(m, ", skip:%d", -+ le32_to_cpu(pcysta_le32->skip_cnt)); - } - seq_puts(m, "\n"); - - seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", - "[cycle_time]", -- pcysta->tavg_cycle[CXT_WL], -- pcysta->tavg_cycle[CXT_BT], -- pcysta->tavg_lk / 1000, pcysta->tavg_lk % 1000); -- seq_printf(m, -- ", max_t[wl:%d/bt:%d/lk:%d.%03d]", -- pcysta->tmax_cycle[CXT_WL], -- pcysta->tmax_cycle[CXT_BT], -- pcysta->tmax_lk / 1000, pcysta->tmax_lk % 1000); -- seq_printf(m, -- ", maxdiff_t[wl:%d/bt:%d]\n", -- pcysta->tmaxdiff_cycle[CXT_WL], -- pcysta->tmaxdiff_cycle[CXT_BT]); -+ le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]), -+ le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]), -+ le16_to_cpu(pcysta_le32->tavg_lk) / 1000, -+ le16_to_cpu(pcysta_le32->tavg_lk) % 1000); -+ seq_printf(m, ", max_t[wl:%d/bt:%d/lk:%d.%03d]", -+ le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]), -+ le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]), -+ le16_to_cpu(pcysta_le32->tmax_lk) / 1000, -+ le16_to_cpu(pcysta_le32->tmax_lk) % 1000); -+ seq_printf(m, ", maxdiff_t[wl:%d/bt:%d]\n", -+ le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), -+ le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); - -- if (pcysta->cycles == 0) -+ if (le16_to_cpu(pcysta_le32->cycles) == 0) - return; - - /* 1 cycle record 1 wl-slot and 1 bt-slot */ - slot_pair = BTC_CYCLE_SLOT_MAX / 2; - -- if (pcysta->cycles <= slot_pair) -+ if (le16_to_cpu(pcysta_le32->cycles) <= slot_pair) - c_begin = 1; - else -- c_begin = pcysta->cycles - slot_pair + 1; -+ c_begin = le16_to_cpu(pcysta_le32->cycles) - slot_pair + 1; - -- c_end = pcysta->cycles; -+ c_end = le16_to_cpu(pcysta_le32->cycles); - - for (cycle = c_begin; cycle <= c_end; cycle++) { - cnt++; -@@ -6461,13 +6389,13 @@ static void _show_fbtc_cysta(struct rtw8 - if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) - seq_printf(m, - " %-15s : ->b%02d->w%02d", "[cycle_step]", -- pcysta->tslot_cycle[store_index], -- pcysta->tslot_cycle[store_index + 1]); -+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), -+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); - else - seq_printf(m, - "->b%02d->w%02d", -- pcysta->tslot_cycle[store_index], -- pcysta->tslot_cycle[store_index + 1]); -+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), -+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); - if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) - seq_puts(m, "\n"); - } -@@ -6476,28 +6404,30 @@ static void _show_fbtc_cysta(struct rtw8 - seq_printf(m, - " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", -- pcysta->a2dpept, pcysta->a2dpeptto); -+ le16_to_cpu(pcysta_le32->a2dpept), -+ le16_to_cpu(pcysta_le32->a2dpeptto)); - - seq_printf(m, - ", avg_t:%d, max_t:%d", -- pcysta->tavg_a2dpept, pcysta->tmax_a2dpept); -+ le16_to_cpu(pcysta_le32->tavg_a2dpept), -+ le16_to_cpu(pcysta_le32->tmax_a2dpept)); - r.val = dm->tdma_now.rxflctrl; - - if (r.type && r.tgln_n) { - seq_printf(m, - ", cycle[PSTDMA:%d/TDMA:%d], ", -- pcysta->cycles_a2dp[CXT_FLCTRL_ON], -- pcysta->cycles_a2dp[CXT_FLCTRL_OFF]); -+ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), -+ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); - - seq_printf(m, - "avg_t[PSTDMA:%d/TDMA:%d], ", -- pcysta->tavg_a2dp[CXT_FLCTRL_ON], -- pcysta->tavg_a2dp[CXT_FLCTRL_OFF]); -+ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), -+ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); - - seq_printf(m, - "max_t[PSTDMA:%d/TDMA:%d]", -- pcysta->tmax_a2dp[CXT_FLCTRL_ON], -- pcysta->tmax_a2dp[CXT_FLCTRL_OFF]); -+ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), -+ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); - } - seq_puts(m, "\n"); - } diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-100-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-100-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch deleted file mode 100644 index 80ec2f233..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-100-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch +++ /dev/null @@ -1,303 +0,0 @@ -From fab895b31982f8093afe807cb0a69805aaa97850 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:33 +0800 -Subject: [PATCH 100/149] wifi: rtw89: coex: Rename BTC firmware cycle report - by feature version - -Because there are new report format in the upcoming patches, to make the -logic more readable, rename the related structure by their version number. -And to support the several version at the same time, add union definition -to include all the versions. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 107 +++++++++++----------- - drivers/net/wireless/realtek/rtw89/core.h | 14 +-- - 2 files changed, 64 insertions(+), 57 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -932,8 +932,7 @@ static u32 _chk_btc_report(struct rtw89_ - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_btc_fbtc_rpt_ctrl *prpt; - struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; -- struct rtw89_btc_fbtc_cysta *pcysta = NULL; -- struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; -+ union rtw89_btc_fbtc_cysta_info *pcysta = NULL; - struct rtw89_btc_prpt *btc_prpt = NULL; - void *rpt_content = NULL, *pfinfo = NULL; - u8 rpt_type = 0; -@@ -993,14 +992,17 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_CYSTA: - pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; -- if (chip->chip_id == RTL8852A) { -- pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo; -- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; -+ if (ver->fcxcysta == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2; -+ pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2); -+ } else if (ver->fcxcysta == 3) { -+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3; -+ pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3); - } else { -- pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1; -- pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); -+ goto err; - } - pcinfo->req_fver = ver->fcxcysta; - break; -@@ -1186,14 +1188,14 @@ static u32 _chk_btc_report(struct rtw89_ - sizeof(dm->slot_now))); - break; - case BTC_RPT_TYPE_CYSTA: -- if (chip->chip_id == RTL8852A) { -- if (le16_to_cpu(pcysta->cycles) < BTC_CYSTA_CHK_PERIOD) -+ if (ver->fcxcysta == 2) { -+ if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD) - break; - /* Check Leak-AP */ -- if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) != 0 && -- le32_to_cpu(pcysta->leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { -- if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) < -- BTC_LEAK_AP_TH * le32_to_cpu(pcysta->leakrx_cnt)) -+ if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) != 0 && -+ le32_to_cpu(pcysta->v2.leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { -+ if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) < -+ BTC_LEAK_AP_TH * le32_to_cpu(pcysta->v2.leakrx_cnt)) - dm->leak_ap = 1; - } - -@@ -1204,24 +1206,24 @@ static u32 _chk_btc_report(struct rtw89_ - else - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); - -- if (le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) > wl_slot_set) { -- diff_t = le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) - wl_slot_set; -+ if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) { -+ diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set; - _chk_btc_err(rtwdev, - BTC_DCNT_WL_SLOT_DRIFT, diff_t); - } - - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- le32_to_cpu(pcysta->slot_cnt[CXST_W1])); -+ le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1])); - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- le32_to_cpu(pcysta->slot_cnt[CXST_B1])); -+ le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1])); - _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -- le16_to_cpu(pcysta->cycles)); -- } else { -- if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) -+ le16_to_cpu(pcysta->v2.cycles)); -+ } else if (ver->fcxcysta == 3) { -+ if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD) - break; - -- cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); -- cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); -+ cnt_leak_slot = le32_to_cpu(pcysta->v3.slot_cnt[CXST_LK]); -+ cnt_rx_imr = le32_to_cpu(pcysta->v3.leak_slot.cnt_rximr); - - /* Check Leak-AP */ - if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && -@@ -1233,7 +1235,7 @@ static u32 _chk_btc_report(struct rtw89_ - /* Check diff time between real WL slot and W1 slot */ - if (dm->tdma_now.type == CXTDMA_OFF) { - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -- wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]); -+ wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]); - if (wl_slot_real > wl_slot_set) { - diff_t = wl_slot_real - wl_slot_set; - _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -@@ -1244,8 +1246,7 @@ static u32 _chk_btc_report(struct rtw89_ - if (dm->tdma_now.type == CXTDMA_OFF && - dm->tdma_now.ext_ctrl == CXECTL_EXT && - btc->bt_req_len != 0) { -- bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); -- -+ bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]); - if (btc->bt_req_len > bt_slot_real) { - diff_t = btc->bt_req_len - bt_slot_real; - _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); -@@ -1253,11 +1254,13 @@ static u32 _chk_btc_report(struct rtw89_ - } - - _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -- le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); -+ le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1])); - _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -- le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); -+ le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); - _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -- (u32)le16_to_cpu(pcysta_v1->cycles)); -+ le16_to_cpu(pcysta->v3.cycles)); -+ } else { -+ goto err; - } - break; - case BTC_RPT_TYPE_BT_VER: -@@ -6160,21 +6163,23 @@ static void _show_dm_info(struct rtw89_d - - static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -- struct rtw89_btc_fbtc_cysta *pcysta; -- struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1; -+ union rtw89_btc_fbtc_cysta_info *pcysta; - u32 except_cnt, exception_map; - -- if (chip->chip_id == RTL8852A) { -- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; -- except_cnt = le32_to_cpu(pcysta->except_cnt); -- exception_map = le32_to_cpu(pcysta->exception); -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; -+ if (ver->fcxcysta == 2) { -+ pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2; -+ except_cnt = le32_to_cpu(pcysta->v2.except_cnt); -+ exception_map = le32_to_cpu(pcysta->v2.exception); -+ } else if (ver->fcxcysta == 3) { -+ pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; -+ except_cnt = le32_to_cpu(pcysta->v3.except_cnt); -+ exception_map = le32_to_cpu(pcysta->v3.except_map); - } else { -- pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; -- except_cnt = le32_to_cpu(pcysta_v1->except_cnt); -- exception_map = le32_to_cpu(pcysta_v1->except_map); -+ return; - } - - if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && -@@ -6305,14 +6310,14 @@ static void _show_fbtc_slots(struct rtw8 - } - } - --static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -- struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; -+ struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL; - union rtw89_btc_fbtc_rxflct r; - u8 i, cnt = 0, slot_pair; - u16 cycle, c_begin, c_end, store_index; -@@ -6321,7 +6326,7 @@ static void _show_fbtc_cysta(struct rtw8 - if (!pcinfo->valid) - return; - -- pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; -+ pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", -@@ -6433,14 +6438,14 @@ static void _show_fbtc_cysta(struct rtw8 - } - } - --static void _show_fbtc_cysta_v1(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx; -- struct rtw89_btc_fbtc_cysta_v1 *pcysta; -+ struct rtw89_btc_fbtc_cysta_v3 *pcysta; - struct rtw89_btc_rpt_cmn_info *pcinfo; - u8 i, cnt = 0, slot_pair, divide_cnt; - u16 cycle, c_begin, c_end, store_index; -@@ -6449,7 +6454,7 @@ static void _show_fbtc_cysta_v1(struct r - if (!pcinfo->valid) - return; - -- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo_v1; -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3; - seq_printf(m, - " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", - "[cycle_cnt]", -@@ -6708,8 +6713,8 @@ static void _show_fbtc_step(struct rtw89 - - static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - - if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) - return; -@@ -6718,10 +6723,10 @@ static void _show_fw_dm_msg(struct rtw89 - _show_fbtc_tdma(rtwdev, m); - _show_fbtc_slots(rtwdev, m); - -- if (chip->chip_id == RTL8852A) -- _show_fbtc_cysta(rtwdev, m); -- else -- _show_fbtc_cysta_v1(rtwdev, m); -+ if (ver->fcxcysta == 2) -+ _show_fbtc_cysta_v2(rtwdev, m); -+ else if (ver->fcxcysta == 3) -+ _show_fbtc_cysta_v3(rtwdev, m); - - _show_fbtc_nullsta(rtwdev, m); - _show_fbtc_step(rtwdev, m); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1681,7 +1681,7 @@ struct rtw89_btc_fbtc_steps_v1 { - struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; - } __packed; - --struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ -+struct rtw89_btc_fbtc_cysta_v2 { /* statistics for cycles */ - u8 fver; /* btc_ver::fcxcysta */ - u8 rsvd; - __le16 cycles; /* total cycle number */ -@@ -1743,7 +1743,7 @@ struct rtw89_btc_fbtc_cycle_leak_info { - __le16 tmax; /* max leak-slot time */ - } __packed; - --struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */ -+struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ - u8 fver; - u8 rsvd; - __le16 cycles; /* total cycle number */ -@@ -1761,6 +1761,11 @@ struct rtw89_btc_fbtc_cysta_v1 { /* stat - __le32 except_map; - } __packed; - -+union rtw89_btc_fbtc_cysta_info { -+ struct rtw89_btc_fbtc_cysta_v2 v2; -+ struct rtw89_btc_fbtc_cysta_v3 v3; -+}; -+ - struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ - u8 fver; /* btc_ver::fcxnullsta */ - u8 rsvd; -@@ -1961,10 +1966,7 @@ struct rtw89_btc_rpt_fbtc_slots { - - struct rtw89_btc_rpt_fbtc_cysta { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- union { -- struct rtw89_btc_fbtc_cysta finfo; /* info from fw for 52A*/ -- struct rtw89_btc_fbtc_cysta_v1 finfo_v1; /* info from fw for 52C*/ -- }; -+ union rtw89_btc_fbtc_cysta_info finfo; - }; - - struct rtw89_btc_rpt_fbtc_step { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-101-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-101-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch deleted file mode 100644 index c8c110189..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-101-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 202c3b5c276f3f7525d9baabea7e8896d300ceff Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:34 +0800 -Subject: [PATCH 101/149] wifi: rtw89: coex: Add v4 version firmware cycle - report - -To support v4 version firmware cycle report, apply the related -structure and functions. v4 cycle report add a group of status -to show how the free-run/TDMA training goes to. It is a firmware -mechanism that can auto adjust coexistence mode between TDMA and -free run mechanism at 3 antenna solution. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 185 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 67 ++++++++ - 2 files changed, 252 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1001,6 +1001,10 @@ static u32 _chk_btc_report(struct rtw89_ - pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3; - pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3); -+ } else if (ver->fcxcysta == 4) { -+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4; -+ pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4); - } else { - goto err; - } -@@ -1259,6 +1263,48 @@ static u32 _chk_btc_report(struct rtw89_ - le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); - _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, - le16_to_cpu(pcysta->v3.cycles)); -+ } else if (ver->fcxcysta == 4) { -+ if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD) -+ break; -+ -+ cnt_leak_slot = le16_to_cpu(pcysta->v4.slot_cnt[CXST_LK]); -+ cnt_rx_imr = le32_to_cpu(pcysta->v4.leak_slot.cnt_rximr); -+ -+ /* Check Leak-AP */ -+ if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && -+ dm->tdma_now.rxflctrl) { -+ if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) -+ dm->leak_ap = 1; -+ } -+ -+ /* Check diff time between real WL slot and W1 slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF) { -+ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -+ wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]); -+ if (wl_slot_real > wl_slot_set) { -+ diff_t = wl_slot_real - wl_slot_set; -+ _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -+ } -+ } -+ -+ /* Check diff time between real BT slot and EBT/E5G slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF && -+ dm->tdma_now.ext_ctrl == CXECTL_EXT && -+ btc->bt_req_len != 0) { -+ bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]); -+ -+ if (btc->bt_req_len > bt_slot_real) { -+ diff_t = btc->bt_req_len - bt_slot_real; -+ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); -+ } -+ } -+ -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -+ le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ le16_to_cpu(pcysta->v4.cycles)); - } else { - goto err; - } -@@ -6178,6 +6224,10 @@ static void _show_error(struct rtw89_dev - pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3; - except_cnt = le32_to_cpu(pcysta->v3.except_cnt); - exception_map = le32_to_cpu(pcysta->v3.except_map); -+ } else if (ver->fcxcysta == 4) { -+ pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; -+ except_cnt = pcysta->v4.except_cnt; -+ exception_map = le32_to_cpu(pcysta->v4.except_map); - } else { - return; - } -@@ -6569,6 +6619,139 @@ static void _show_fbtc_cysta_v3(struct r - } - } - -+static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; -+ struct rtw89_btc_fbtc_cysta_v4 *pcysta; -+ struct rtw89_btc_rpt_cmn_info *pcinfo; -+ u8 i, cnt = 0, slot_pair, divide_cnt; -+ u16 cycle, c_begin, c_end, store_index; -+ -+ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; -+ if (!pcinfo->valid) -+ return; -+ -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4; -+ seq_printf(m, -+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", -+ "[cycle_cnt]", -+ le16_to_cpu(pcysta->cycles), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); -+ -+ for (i = 0; i < CXST_MAX; i++) { -+ if (!le16_to_cpu(pcysta->slot_cnt[i])) -+ continue; -+ -+ seq_printf(m, ", %s:%d", id_to_slot(i), -+ le16_to_cpu(pcysta->slot_cnt[i])); -+ } -+ -+ if (dm->tdma_now.rxflctrl) -+ seq_printf(m, ", leak_rx:%d", -+ le32_to_cpu(pcysta->leak_slot.cnt_rximr)); -+ -+ if (pcysta->collision_cnt) -+ seq_printf(m, ", collision:%d", pcysta->collision_cnt); -+ -+ if (le16_to_cpu(pcysta->skip_cnt)) -+ seq_printf(m, ", skip:%d", -+ le16_to_cpu(pcysta->skip_cnt)); -+ -+ seq_puts(m, "\n"); -+ -+ seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", -+ "[cycle_time]", -+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), -+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), -+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000, -+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000); -+ seq_printf(m, -+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]", -+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), -+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), -+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000, -+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000); -+ seq_printf(m, -+ ", maxdiff_t[wl:%d/bt:%d]\n", -+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]), -+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); -+ -+ cycle = le16_to_cpu(pcysta->cycles); -+ if (cycle == 0) -+ return; -+ -+ /* 1 cycle record 1 wl-slot and 1 bt-slot */ -+ slot_pair = BTC_CYCLE_SLOT_MAX / 2; -+ -+ if (cycle <= slot_pair) -+ c_begin = 1; -+ else -+ c_begin = cycle - slot_pair + 1; -+ -+ c_end = cycle; -+ -+ if (a2dp->exist) -+ divide_cnt = 3; -+ else -+ divide_cnt = BTC_CYCLE_SLOT_MAX / 4; -+ -+ for (cycle = c_begin; cycle <= c_end; cycle++) { -+ cnt++; -+ store_index = ((cycle - 1) % slot_pair) * 2; -+ -+ if (cnt % divide_cnt == 1) { -+ seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); -+ } else { -+ seq_printf(m, "->b%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ seq_printf(m, "->w%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ } -+ if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) -+ seq_puts(m, "\n"); -+ } -+ -+ if (a2dp->exist) { -+ seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", -+ "[a2dp_t_sta]", -+ le16_to_cpu(pcysta->a2dp_ept.cnt), -+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); -+ -+ seq_printf(m, ", avg_t:%d, max_t:%d", -+ le16_to_cpu(pcysta->a2dp_ept.tavg), -+ le16_to_cpu(pcysta->a2dp_ept.tmax)); -+ -+ seq_puts(m, "\n"); -+ } -+} -+ - static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -@@ -6727,6 +6910,8 @@ static void _show_fw_dm_msg(struct rtw89 - _show_fbtc_cysta_v2(rtwdev, m); - else if (ver->fcxcysta == 3) - _show_fbtc_cysta_v3(rtwdev, m); -+ else if (ver->fcxcysta == 4) -+ _show_fbtc_cysta_v4(rtwdev, m); - - _show_fbtc_nullsta(rtwdev, m); - _show_fbtc_step(rtwdev, m); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1730,6 +1730,17 @@ struct rtw89_btc_fbtc_a2dp_trx_stat { - u8 rsvd2; - } __packed; - -+struct rtw89_btc_fbtc_a2dp_trx_stat_v4 { -+ u8 empty_cnt; -+ u8 retry_cnt; -+ u8 tx_rate; -+ u8 tx_cnt; -+ u8 ack_cnt; -+ u8 nack_cnt; -+ u8 no_empty_cnt; -+ u8 rsvd; -+} __packed; -+ - struct rtw89_btc_fbtc_cycle_a2dp_empty_info { - __le16 cnt; /* a2dp empty cnt */ - __le16 cnt_timeout; /* a2dp empty timeout cnt*/ -@@ -1743,6 +1754,34 @@ struct rtw89_btc_fbtc_cycle_leak_info { - __le16 tmax; /* max leak-slot time */ - } __packed; - -+#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0) -+#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10) -+ -+struct rtw89_btc_fbtc_cycle_fddt_info { -+ __le16 train_cycle; -+ __le16 tp; -+ -+ s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ -+ s8 bt_tx_power; /* decrease Tx power (dB) */ -+ s8 bt_rx_gain; /* LNA constrain level */ -+ u8 no_empty_cnt; -+ -+ u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */ -+ u8 cn; /* condition_num */ -+ u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */ -+ u8 train_result; /* refer to enum btc_fddt_check_map */ -+} __packed; -+ -+#define RTW89_BTC_FDDT_CELL_TRAIN_STATE GENMASK(3, 0) -+#define RTW89_BTC_FDDT_CELL_TRAIN_PHASE GENMASK(7, 4) -+ -+struct rtw89_btc_fbtc_fddt_cell_status { -+ s8 wl_tx_pwr; -+ s8 bt_tx_pwr; -+ s8 bt_rx_gain; -+ u8 state_phase; /* [0:3] train state, [4:7] train phase */ -+} __packed; -+ - struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ - u8 fver; - u8 rsvd; -@@ -1761,9 +1800,37 @@ struct rtw89_btc_fbtc_cysta_v3 { /* stat - __le32 except_map; - } __packed; - -+#define FDD_TRAIN_WL_DIRECTION 2 -+#define FDD_TRAIN_WL_RSSI_LEVEL 5 -+#define FDD_TRAIN_BT_RSSI_LEVEL 5 -+ -+struct rtw89_btc_fbtc_cysta_v4 { /* statistics for cycles */ -+ u8 fver; -+ u8 rsvd; -+ u8 collision_cnt; /* counter for event/timer occur at the same time */ -+ u8 except_cnt; -+ -+ __le16 skip_cnt; -+ __le16 cycles; /* total cycle number */ -+ -+ __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */ -+ __le16 slot_cnt[CXST_MAX]; /* slot count */ -+ __le16 bcn_cnt[CXBCN_MAX]; -+ struct rtw89_btc_fbtc_cycle_time_info cycle_time; -+ struct rtw89_btc_fbtc_cycle_leak_info leak_slot; -+ struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; -+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; -+ struct rtw89_btc_fbtc_cycle_fddt_info fddt_trx[BTC_CYCLE_SLOT_MAX]; -+ struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION] -+ [FDD_TRAIN_WL_RSSI_LEVEL] -+ [FDD_TRAIN_BT_RSSI_LEVEL]; -+ __le32 except_map; -+} __packed; -+ - union rtw89_btc_fbtc_cysta_info { - struct rtw89_btc_fbtc_cysta_v2 v2; - struct rtw89_btc_fbtc_cysta_v3 v3; -+ struct rtw89_btc_fbtc_cysta_v4 v4; - }; - - struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-102-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-102-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch deleted file mode 100644 index d8f5bc6a9..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-102-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch +++ /dev/null @@ -1,243 +0,0 @@ -From b02e3f5c344d62da86afbc6444638a9beb375f2e Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:35 +0800 -Subject: [PATCH 102/149] wifi: rtw89: coex: Change firmware control report to - version separate - -The rtw89 driver may support more than 1 version of Wi-Fi firmware for -certain chips. In order to support all the firmware, change to select logic -by firmware feature version code. Type control version 4 will monitor -Bluetooth PTA hardware counters at firmware and C2H to driver, but -version 1 will not do this. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 76 ++++++++++++----------- - drivers/net/wireless/realtek/rtw89/core.h | 14 +++-- - 2 files changed, 48 insertions(+), 42 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -930,8 +930,7 @@ static u32 _chk_btc_report(struct rtw89_ - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_bt_info *bt = &btc->cx.bt; -- struct rtw89_btc_fbtc_rpt_ctrl *prpt; -- struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; -+ union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL; - union rtw89_btc_fbtc_cysta_info *pcysta = NULL; - struct rtw89_btc_prpt *btc_prpt = NULL; - void *rpt_content = NULL, *pfinfo = NULL; -@@ -962,12 +961,15 @@ static u32 _chk_btc_report(struct rtw89_ - switch (rpt_type) { - case BTC_RPT_TYPE_CTRL: - pcinfo = &pfwinfo->rpt_ctrl.cinfo; -- if (chip->chip_id == RTL8852A) { -- pfinfo = &pfwinfo->rpt_ctrl.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo); -+ prpt = &pfwinfo->rpt_ctrl.finfo; -+ if (ver->fcxbtcrpt == 1) { -+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v1; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1); -+ } else if (ver->fcxbtcrpt == 4) { -+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); - } else { -- pfinfo = &pfwinfo->rpt_ctrl.finfo_v1; -- pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); -+ goto err; - } - pcinfo->req_fver = ver->fcxbtcrpt; - break; -@@ -1109,12 +1111,12 @@ static u32 _chk_btc_report(struct rtw89_ - - switch (rpt_type) { - case BTC_RPT_TYPE_CTRL: -- if (chip->chip_id == RTL8852A) { -- prpt = &pfwinfo->rpt_ctrl.finfo; -- btc->fwinfo.rpt_en_map = prpt->rpt_enable; -- wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; -- wl->ver_info.fw = prpt->wl_fw_ver; -- dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; -+ if (ver->fcxbtcrpt == 1) { -+ prpt->v1 = pfwinfo->rpt_ctrl.finfo.v1; -+ btc->fwinfo.rpt_en_map = prpt->v1.rpt_enable; -+ wl->ver_info.fw_coex = prpt->v1.wl_fw_coex_ver; -+ wl->ver_info.fw = prpt->v1.wl_fw_ver; -+ dm->wl_fw_cx_offload = !!prpt->v1.wl_fw_cx_offload; - - _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, - pfwinfo->event[BTF_EVNT_RPT]); -@@ -1129,38 +1131,40 @@ static u32 _chk_btc_report(struct rtw89_ - rtw89_mac_get_plt_cnt(rtwdev, - RTW89_MAC_0); - } -- } else { -- prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; -- btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); -- wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); -- wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); -- dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); -+ } else if (ver->fcxbtcrpt == 4) { -+ prpt->v4 = pfwinfo->rpt_ctrl.finfo.v4; -+ btc->fwinfo.rpt_en_map = le32_to_cpu(prpt->v4.rpt_info.en); -+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v4.wl_fw_info.cx_ver); -+ wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver); -+ dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload); - - for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) -- memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], -+ memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i], - sizeof(dm->gnt.band[i])); - - btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = -- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); -+ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]); - btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = -- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); -+ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]); - btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = -- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); -+ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]); - btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = -- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); -+ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]); - btc->cx.cnt_bt[BTC_BCNT_POLUT] = -- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); -+ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]); - - _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); - _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, - pfwinfo->event[BTF_EVNT_RPT]); - -- if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) -+ if (le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) - bt->rfk_info.map.timeout = 1; - else - bt->rfk_info.map.timeout = 0; - - dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; -+ } else { -+ goto err; - } - break; - case BTC_RPT_TYPE_TDMA: -@@ -7061,12 +7065,12 @@ static void _show_mreg(struct rtw89_dev - seq_puts(m, "\n"); - } - --static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -- struct rtw89_btc_fbtc_rpt_ctrl *prptctrl = NULL; -+ struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl = NULL; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_wl_info *wl = &cx->wl; -@@ -7081,7 +7085,7 @@ static void _show_summary(struct rtw89_d - - pcinfo = &pfwinfo->rpt_ctrl.cinfo; - if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { -- prptctrl = &pfwinfo->rpt_ctrl.finfo; -+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v1; - - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", -@@ -7165,11 +7169,11 @@ static void _show_summary(struct rtw89_d - cnt[BTC_NCNT_CUSTOMERIZE]); - } - --static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -- struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl; -+ struct rtw89_btc_fbtc_rpt_ctrl_v4 *prptctrl; - struct rtw89_btc_rpt_cmn_info *pcinfo; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_dm *dm = &btc->dm; -@@ -7185,7 +7189,7 @@ static void _show_summary_v1(struct rtw8 - - pcinfo = &pfwinfo->rpt_ctrl.cinfo; - if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { -- prptctrl = &pfwinfo->rpt_ctrl.finfo_v1; -+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v4; - - seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", -@@ -7279,9 +7283,9 @@ static void _show_summary_v1(struct rtw8 - - void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_bt_info *bt = &cx->bt; - -@@ -7310,10 +7314,10 @@ void rtw89_btc_dump_info(struct rtw89_de - _show_dm_info(rtwdev, m); - _show_fw_dm_msg(rtwdev, m); - _show_mreg(rtwdev, m); -- if (chip->chip_id == RTL8852A) -- _show_summary(rtwdev, m); -- else -+ if (ver->fcxbtcrpt == 1) - _show_summary_v1(rtwdev, m); -+ else if (ver->fcxbtcrpt == 4) -+ _show_summary_v4(rtwdev, m); - } - - void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1480,7 +1480,7 @@ enum rtw89_btc_bt_sta_counter { - BTC_BCNT_STA_MAX - }; - --struct rtw89_btc_fbtc_rpt_ctrl { -+struct rtw89_btc_fbtc_rpt_ctrl_v1 { - u16 fver; /* btc_ver::fcxbtcrpt */ - u16 rpt_cnt; /* tmr counters */ - u32 wl_fw_coex_ver; /* match which driver's coex version */ -@@ -1533,7 +1533,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbo - struct rtw89_btc_fbtc_rpt_ctrl_a2dp_empty a2dp; - } __packed; - --struct rtw89_btc_fbtc_rpt_ctrl_v1 { -+struct rtw89_btc_fbtc_rpt_ctrl_v4 { - u8 fver; - u8 rsvd; - __le16 rsvd1; -@@ -1544,6 +1544,11 @@ struct rtw89_btc_fbtc_rpt_ctrl_v1 { - struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX]; - } __packed; - -+union rtw89_btc_fbtc_rpt_ctrl_ver_info { -+ struct rtw89_btc_fbtc_rpt_ctrl_v1 v1; -+ struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; -+}; -+ - enum rtw89_fbtc_ext_ctrl_type { - CXECTL_OFF = 0x0, /* tdma off */ - CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ -@@ -2015,10 +2020,7 @@ union rtw89_btc_fbtc_btafh_info { - - struct rtw89_btc_report_ctrl_state { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- union { -- struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw for 52A*/ -- struct rtw89_btc_fbtc_rpt_ctrl_v1 finfo_v1; /* info from fw for 52C*/ -- }; -+ union rtw89_btc_fbtc_rpt_ctrl_ver_info finfo; - }; - - struct rtw89_btc_rpt_fbtc_tdma { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-103-wifi-rtw89-coex-Add-v5-firmware-control-report.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-103-wifi-rtw89-coex-Add-v5-firmware-control-report.patch deleted file mode 100644 index 01631a0a7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-103-wifi-rtw89-coex-Add-v5-firmware-control-report.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 0c06fd47335ab9bbcbca250267eb22227e98ffa4 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:36 +0800 -Subject: [PATCH 103/149] wifi: rtw89: coex: Add v5 firmware control report - -Comparing v5 control report to v4 version, v5 reduce some of variable's -size to reduce firmware code size. And change the grant signal report -format. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 148 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 27 ++++ - 2 files changed, 175 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -968,6 +968,9 @@ static u32 _chk_btc_report(struct rtw89_ - } else if (ver->fcxbtcrpt == 4) { - pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; - pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); -+ } else if (ver->fcxbtcrpt == 5) { -+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); - } else { - goto err; - } -@@ -1163,6 +1166,33 @@ static u32 _chk_btc_report(struct rtw89_ - bt->rfk_info.map.timeout = 0; - - dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; -+ } else if (ver->fcxbtcrpt == 5) { -+ prpt->v5 = pfwinfo->rpt_ctrl.finfo.v5; -+ pfwinfo->rpt_en_map = le32_to_cpu(prpt->v5.rpt_info.en); -+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v5.rpt_info.cx_ver); -+ wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver); -+ dm->wl_fw_cx_offload = 0; -+ -+ for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) -+ memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0], -+ sizeof(dm->gnt.band[i])); -+ -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = -+ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]); -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = -+ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = -+ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = -+ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]); -+ btc->cx.cnt_bt[BTC_BCNT_POLUT] = -+ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]); -+ -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ pfwinfo->event[BTF_EVNT_RPT]); -+ -+ dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; - } else { - goto err; - } -@@ -7281,6 +7311,122 @@ static void _show_summary_v4(struct rtw8 - cnt[BTC_NCNT_CUSTOMERIZE]); - } - -+static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_fbtc_rpt_ctrl_v5 *prptctrl; -+ struct rtw89_btc_rpt_cmn_info *pcinfo; -+ struct rtw89_btc_cx *cx = &btc->cx; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_wl_info *wl = &cx->wl; -+ u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; -+ u8 i; -+ -+ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) -+ return; -+ -+ seq_puts(m, "========== [Statistics] ==========\n"); -+ -+ pcinfo = &pfwinfo->rpt_ctrl.cinfo; -+ if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { -+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v5; -+ -+ seq_printf(m, -+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", -+ "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, -+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c), -+ pfwinfo->cnt_c2h, -+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h), -+ le16_to_cpu(prptctrl->rpt_info.len_c2h)); -+ -+ seq_printf(m, -+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", -+ pfwinfo->event[BTF_EVNT_RPT], -+ le16_to_cpu(prptctrl->rpt_info.cnt), -+ le32_to_cpu(prptctrl->rpt_info.en)); -+ -+ if (dm->error.map.wl_fw_hang) -+ seq_puts(m, " (WL FW Hang!!)"); -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", -+ "[mailbox]", -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); -+ -+ seq_printf(m, -+ "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); -+ -+ seq_printf(m, -+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", -+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], -+ cx->cnt_wl[BTC_WCNT_RFK_GO], -+ cx->cnt_wl[BTC_WCNT_RFK_REJECT], -+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); -+ -+ seq_printf(m, -+ ", bt_rfk[req:%d]", -+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); -+ -+ seq_printf(m, -+ ", AOAC[RF_on:%d/RF_off:%d]", -+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), -+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); -+ } else { -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", -+ "[summary]", pfwinfo->cnt_h2c, -+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); -+ } -+ -+ if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || -+ pfwinfo->err[BTFRE_EXCEPTION]) { -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" -+ "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", -+ "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, -+ pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], -+ wl->status.map.lps, wl->status.map.rf_off); -+ } -+ -+ for (i = 0; i < BTC_NCNT_NUM; i++) -+ cnt_sum += dm->cnt_notify[i]; -+ -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", -+ "[notify_cnt]", -+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], -+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); -+ -+ seq_printf(m, -+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", -+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], -+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], -+ cnt[BTC_NCNT_WL_STA]); -+ -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", -+ "[notify_cnt]", -+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], -+ cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); -+ -+ seq_printf(m, -+ "timer=%d, control=%d, customerize=%d", -+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], -+ cnt[BTC_NCNT_CUSTOMERIZE]); -+} -+ - void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; -@@ -7318,6 +7464,8 @@ void rtw89_btc_dump_info(struct rtw89_de - _show_summary_v1(rtwdev, m); - else if (ver->fcxbtcrpt == 4) - _show_summary_v4(rtwdev, m); -+ else if (ver->fcxbtcrpt == 5) -+ _show_summary_v5(rtwdev, m); - } - - void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1512,6 +1512,20 @@ struct rtw89_btc_fbtc_rpt_ctrl_info { - __le32 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */ - } __packed; - -+struct rtw89_btc_fbtc_rpt_ctrl_info_v5 { -+ __le32 cx_ver; /* match which driver's coex version */ -+ __le32 fw_ver; -+ __le32 en; /* report map */ -+ -+ __le16 cnt; /* fw report counter */ -+ __le16 cnt_c2h; /* fw send c2h counter */ -+ __le16 cnt_h2c; /* fw recv h2c counter */ -+ __le16 len_c2h; /* The total length of the last C2H */ -+ -+ __le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */ -+ __le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */ -+} __packed; -+ - struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info { - __le32 cx_ver; /* match which driver's coex version */ - __le32 cx_offload; -@@ -1544,9 +1558,22 @@ struct rtw89_btc_fbtc_rpt_ctrl_v4 { - struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX]; - } __packed; - -+struct rtw89_btc_fbtc_rpt_ctrl_v5 { -+ u8 fver; -+ u8 rsvd; -+ __le16 rsvd1; -+ -+ u8 gnt_val[RTW89_PHY_MAX][4]; -+ __le16 bt_cnt[BTC_BCNT_STA_MAX]; -+ -+ struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; -+ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; -+} __packed; -+ - union rtw89_btc_fbtc_rpt_ctrl_ver_info { - struct rtw89_btc_fbtc_rpt_ctrl_v1 v1; - struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; -+ struct rtw89_btc_fbtc_rpt_ctrl_v5 v5; - }; - - enum rtw89_fbtc_ext_ctrl_type { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-104-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-104-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch deleted file mode 100644 index e68271325..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-104-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 891b6a3f9407965436136319ad81f03bbf97310d Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:37 +0800 -Subject: [PATCH 104/149] wifi: rtw89: coex: only read Bluetooth counter of - report version 1 for RTL8852A - -Only when firmware control report version is 1, need to get the counter by -reading the register. The other version will monitor the counter at -firmware. And upstream branch only RTL8852A has this old version. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1878,9 +1878,13 @@ static - void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_cx *cx = &btc->cx; - u32 val; - -+ if (ver->fcxbtcrpt != 1) -+ return; -+ - val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH); - cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); - cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-105-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-105-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch deleted file mode 100644 index 2e174be57..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-105-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 3f625adc61a0f015c2ce982bc49a84e163094a0c Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 3 Jan 2023 22:02:38 +0800 -Subject: [PATCH 105/149] wifi: rtw89: coex: Update WiFi role info H2C report - -Change style to feature version separate. And because there are -different WiFi roles number in the firmware, it will make structure -length longer or shorter, so update the length calculator to cover -the difference. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230103140238.15601-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 7 +++-- - drivers/net/wireless/realtek/rtw89/fw.c | 36 +++++++++++++++-------- - 2 files changed, 27 insertions(+), 16 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1772,16 +1772,17 @@ static void _fw_set_policy(struct rtw89_ - - static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - - switch (type) { - case CXDRVINFO_INIT: - rtw89_fw_h2c_cxdrv_init(rtwdev); - break; - case CXDRVINFO_ROLE: -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - rtw89_fw_h2c_cxdrv_role(rtwdev); -- else -+ else if (ver->fwlrole == 1) - rtw89_fw_h2c_cxdrv_role_v1(rtwdev); - break; - case CXDRVINFO_CTRL: ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -1818,33 +1818,36 @@ fail: - - #define PORT_DATA_OFFSET 4 - #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 --#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR) --#define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \ -- H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \ -- H2C_LEN_CXDRVHDR) -+#define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \ -+ (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR) -+ - int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info *role_info = &wl->role_info; - struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; - struct rtw89_btc_wl_active_role *active = role_info->active_role; - struct sk_buff *skb; -+ u32 len; - u8 offset = 0; - u8 *cmd; - int ret; - int i; - -- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE); -+ len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num); -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); - return -ENOMEM; - } -- skb_put(skb, H2C_LEN_CXDRVINFO_ROLE); -+ skb_put(skb, len); - cmd = skb->data; - - RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); -- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR); -+ RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); - - RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); - RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); -@@ -1881,7 +1884,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89 - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, - H2C_CAT_OUTSRC, BTFC_SET, - SET_DRV_INFO, 0, 0, -- H2C_LEN_CXDRVINFO_ROLE); -+ len); - - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { -@@ -1896,28 +1899,35 @@ fail: - return ret; - } - -+#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \ -+ (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) -+ - int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1; - struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; - struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1; - struct sk_buff *skb; -+ u32 len; - u8 *cmd, offset; - int ret; - int i; - -- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1); -+ len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num); -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); - return -ENOMEM; - } -- skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1); -+ skb_put(skb, len); - cmd = skb->data; - - RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); -- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR); -+ RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); - - RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); - RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); -@@ -1953,7 +1963,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rt - RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset); - } - -- offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; -+ offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; - RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); - RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); - RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); -@@ -1964,7 +1974,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rt - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, - H2C_CAT_OUTSRC, BTFC_SET, - SET_DRV_INFO, 0, 0, -- H2C_LEN_CXDRVINFO_ROLE_V1); -+ len); - - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-108-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-108-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch deleted file mode 100644 index db94d014a..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-108-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 72f8b0461b4aa1b90248c36f3d2ea4a58074672e Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:38 +0800 -Subject: [PATCH 108/149] wifi: rtw89: coex: Add version code for Wi-Fi - firmware coexistence control - -The newer Wi-Fi firmware are all changed to "Not to send H2C to -mention firmware how many call flow step should firmware trace". -The structure had removed the member, and define the steps number -at newer version firmware. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -1992,8 +1992,8 @@ fail: - #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) - int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_ctrl *ctrl = &btc->ctrl; - struct sk_buff *skb; - u8 *cmd; -@@ -2013,7 +2013,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89 - RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); - RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); - RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); -- if (chip->chip_id == RTL8852A) -+ if (ver->fcxctrl == 0) - RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-109-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-109-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch deleted file mode 100644 index a0e77b170..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-109-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 3d929f075d3bb6187ad73375f6aee7bcf0b51851 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:39 +0800 -Subject: [PATCH 109/149] wifi: rtw89: coex: Change Wi-Fi Null data report to - version separate - -Coexistence need to send Null data to stop AP keeps TX packet to DUT -before DUT coexistence switch to Bluetooth time slot, or it will be an -interference to DUT BT and because DUT will not RX packet from AP -the packet retry may harmful to WL TP. Compare to v1 version, the newer -firmware report will also report Null TX data counter. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 57 +++++++++++------------ - drivers/net/wireless/realtek/rtw89/core.h | 14 +++--- - 2 files changed, 35 insertions(+), 36 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1032,12 +1032,14 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_NULLSTA: - pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; -- if (chip->chip_id == RTL8852A) { -+ if (ver->fcxnullsta == 1) { - pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo); -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); -+ } else if (ver->fcxnullsta == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2); - } else { -- pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); -+ goto err; - } - pcinfo->req_fver = ver->fcxnullsta; - break; -@@ -6789,12 +6791,11 @@ static void _show_fbtc_cysta_v4(struct r - - static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo; -- struct rtw89_btc_fbtc_cynullsta *ns; -- struct rtw89_btc_fbtc_cynullsta_v1 *ns_v1; -+ union rtw89_btc_fbtc_cynullsta_info *ns; - u8 i = 0; - - if (!btc->dm.tdma_now.rxflctrl) -@@ -6804,9 +6805,8 @@ static void _show_fbtc_nullsta(struct rt - if (!pcinfo->valid) - return; - -- if (chip->chip_id == RTL8852A) { -- ns = &pfwinfo->rpt_fbtc_nullsta.finfo; -- -+ ns = &pfwinfo->rpt_fbtc_nullsta.finfo; -+ if (ver->fcxnullsta == 1) { - seq_printf(m, " %-15s : ", "[null_sta]"); - - for (i = 0; i < 2; i++) { -@@ -6815,46 +6815,43 @@ static void _show_fbtc_nullsta(struct rt - else - seq_printf(m, "null-%d", i); - seq_printf(m, "[ok:%d/", -- le32_to_cpu(ns->result[i][1])); -+ le32_to_cpu(ns->v1.result[i][1])); - seq_printf(m, "fail:%d/", -- le32_to_cpu(ns->result[i][0])); -+ le32_to_cpu(ns->v1.result[i][0])); - seq_printf(m, "on_time:%d/", -- le32_to_cpu(ns->result[i][2])); -+ le32_to_cpu(ns->v1.result[i][2])); - seq_printf(m, "retry:%d/", -- le32_to_cpu(ns->result[i][3])); -+ le32_to_cpu(ns->v1.result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", -- le32_to_cpu(ns->avg_t[i]) / 1000, -- le32_to_cpu(ns->avg_t[i]) % 1000); -+ le32_to_cpu(ns->v1.avg_t[i]) / 1000, -+ le32_to_cpu(ns->v1.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]", -- le32_to_cpu(ns->max_t[i]) / 1000, -- le32_to_cpu(ns->max_t[i]) % 1000); -+ le32_to_cpu(ns->v1.max_t[i]) / 1000, -+ le32_to_cpu(ns->v1.max_t[i]) % 1000); - } - } else { -- ns_v1 = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; -- - seq_printf(m, " %-15s : ", "[null_sta]"); -- - for (i = 0; i < 2; i++) { - if (i != 0) - seq_printf(m, ", null-%d", i); - else - seq_printf(m, "null-%d", i); - seq_printf(m, "[Tx:%d/", -- le32_to_cpu(ns_v1->result[i][4])); -+ le32_to_cpu(ns->v2.result[i][4])); - seq_printf(m, "[ok:%d/", -- le32_to_cpu(ns_v1->result[i][1])); -+ le32_to_cpu(ns->v2.result[i][1])); - seq_printf(m, "fail:%d/", -- le32_to_cpu(ns_v1->result[i][0])); -+ le32_to_cpu(ns->v2.result[i][0])); - seq_printf(m, "on_time:%d/", -- le32_to_cpu(ns_v1->result[i][2])); -+ le32_to_cpu(ns->v2.result[i][2])); - seq_printf(m, "retry:%d/", -- le32_to_cpu(ns_v1->result[i][3])); -+ le32_to_cpu(ns->v2.result[i][3])); - seq_printf(m, "avg_t:%d.%03d/", -- le32_to_cpu(ns_v1->avg_t[i]) / 1000, -- le32_to_cpu(ns_v1->avg_t[i]) % 1000); -+ le32_to_cpu(ns->v2.avg_t[i]) / 1000, -+ le32_to_cpu(ns->v2.avg_t[i]) % 1000); - seq_printf(m, "max_t:%d.%03d]", -- le32_to_cpu(ns_v1->max_t[i]) / 1000, -- le32_to_cpu(ns_v1->max_t[i]) % 1000); -+ le32_to_cpu(ns->v2.max_t[i]) / 1000, -+ le32_to_cpu(ns->v2.max_t[i]) % 1000); - } - } - seq_puts(m, "\n"); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1865,7 +1865,7 @@ union rtw89_btc_fbtc_cysta_info { - struct rtw89_btc_fbtc_cysta_v4 v4; - }; - --struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ -+struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ - u8 fver; /* btc_ver::fcxnullsta */ - u8 rsvd; - __le16 rsvd2; -@@ -1874,7 +1874,7 @@ struct rtw89_btc_fbtc_cynullsta { /* cyc - __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ - } __packed; - --struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ -+struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */ - u8 fver; /* btc_ver::fcxnullsta */ - u8 rsvd; - __le16 rsvd2; -@@ -1883,6 +1883,11 @@ struct rtw89_btc_fbtc_cynullsta_v1 { /* - __le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */ - } __packed; - -+union rtw89_btc_fbtc_cynullsta_info { -+ struct rtw89_btc_fbtc_cynullsta_v1 v1; /* info from fw */ -+ struct rtw89_btc_fbtc_cynullsta_v2 v2; -+}; -+ - struct rtw89_btc_fbtc_btver { - u8 fver; /* btc_ver::fcxbtver */ - u8 rsvd; -@@ -2075,10 +2080,7 @@ struct rtw89_btc_rpt_fbtc_step { - - struct rtw89_btc_rpt_fbtc_nullsta { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- union { -- struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */ -- struct rtw89_btc_fbtc_cynullsta_v1 finfo_v1; /* info from fw */ -- }; -+ union rtw89_btc_fbtc_cynullsta_info finfo; - }; - - struct rtw89_btc_rpt_fbtc_mreg { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-110-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-110-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch deleted file mode 100644 index fc82df7de..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-110-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 2626ccefe615a1faa8fb6bfb07708089b103e428 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:40 +0800 -Subject: [PATCH 110/149] wifi: rtw89: coex: Change firmware steps report to - version separate - -The report records the slots/events and their time cost about the code -call flow at firmware, ver 3 assign a reserved variable to recognize -the report is enabled or not. And add corresponding function to parsing -the report. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 124 +++++++++++++++++++--- - drivers/net/wireless/realtek/rtw89/core.h | 44 ++++++-- - 2 files changed, 149 insertions(+), 19 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -923,7 +923,6 @@ static u32 _chk_btc_report(struct rtw89_ - struct rtw89_btc_btf_fwinfo *pfwinfo, - u8 *prptbuf, u32 index) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; - const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_dm *dm = &btc->dm; -@@ -1017,16 +1016,18 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_STEP: - pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; -- if (chip->chip_id == RTL8852A) { -- pfinfo = &pfwinfo->rpt_fbtc_step.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.step[0]) * -+ if (ver->fcxstep == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v2.step[0]) * - trace_step + -- offsetof(struct rtw89_btc_fbtc_steps, step); -- } else { -- pfinfo = &pfwinfo->rpt_fbtc_step.finfo_v1; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo_v1.step[0]) * -+ offsetof(struct rtw89_btc_fbtc_steps_v2, step); -+ } else if (ver->fcxstep == 3) { -+ pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v3; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.v3.step[0]) * - trace_step + -- offsetof(struct rtw89_btc_fbtc_steps_v1, step); -+ offsetof(struct rtw89_btc_fbtc_steps_v3, step); -+ } else { -+ goto err; - } - pcinfo->req_fver = ver->fcxstep; - break; -@@ -6008,6 +6009,7 @@ static void _show_bt_info(struct rtw89_d - #define CASE_BTC_POLICY_STR(e) \ - case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e - #define CASE_BTC_SLOT_STR(e) case CXST_ ## e: return #e -+#define CASE_BTC_EVT_STR(e) case CXEVNT_## e: return #e - - static const char *steps_to_str(u16 step) - { -@@ -6148,6 +6150,40 @@ static const char *id_to_slot(u32 id) - } - } - -+static const char *id_to_evt(u32 id) -+{ -+ switch (id) { -+ CASE_BTC_EVT_STR(TDMA_ENTRY); -+ CASE_BTC_EVT_STR(WL_TMR); -+ CASE_BTC_EVT_STR(B1_TMR); -+ CASE_BTC_EVT_STR(B2_TMR); -+ CASE_BTC_EVT_STR(B3_TMR); -+ CASE_BTC_EVT_STR(B4_TMR); -+ CASE_BTC_EVT_STR(W2B_TMR); -+ CASE_BTC_EVT_STR(B2W_TMR); -+ CASE_BTC_EVT_STR(BCN_EARLY); -+ CASE_BTC_EVT_STR(A2DP_EMPTY); -+ CASE_BTC_EVT_STR(LK_END); -+ CASE_BTC_EVT_STR(RX_ISR); -+ CASE_BTC_EVT_STR(RX_FC0); -+ CASE_BTC_EVT_STR(RX_FC1); -+ CASE_BTC_EVT_STR(BT_RELINK); -+ CASE_BTC_EVT_STR(BT_RETRY); -+ CASE_BTC_EVT_STR(E2G); -+ CASE_BTC_EVT_STR(E5G); -+ CASE_BTC_EVT_STR(EBT); -+ CASE_BTC_EVT_STR(ENULL); -+ CASE_BTC_EVT_STR(DRV_WLK); -+ CASE_BTC_EVT_STR(BCN_OK); -+ CASE_BTC_EVT_STR(BT_CHANGE); -+ CASE_BTC_EVT_STR(EBT_EXTEND); -+ CASE_BTC_EVT_STR(E2G_NULL1); -+ CASE_BTC_EVT_STR(B1FDD_TMR); -+ default: -+ return "unknown"; -+ } -+} -+ - static - void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, - u8 len, u8 seg_len, u8 start_idx, u8 ring_len) -@@ -6857,12 +6893,12 @@ static void _show_fbtc_nullsta(struct rt - seq_puts(m, "\n"); - } - --static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -- struct rtw89_btc_fbtc_steps *pstep = NULL; -+ struct rtw89_btc_fbtc_steps_v2 *pstep = NULL; - u8 type, val, cnt = 0, state = 0; - bool outloop = false; - u16 i, diff_t, n_start = 0, n_stop = 0; -@@ -6872,7 +6908,7 @@ static void _show_fbtc_step(struct rtw89 - if (!pcinfo->valid) - return; - -- pstep = &pfwinfo->rpt_fbtc_step.finfo; -+ pstep = &pfwinfo->rpt_fbtc_step.finfo.v2; - pos_old = le16_to_cpu(pstep->pos_old); - pos_new = le16_to_cpu(pstep->pos_new); - -@@ -6926,6 +6962,63 @@ static void _show_fbtc_step(struct rtw89 - } while (!outloop); - } - -+static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_rpt_cmn_info *pcinfo; -+ struct rtw89_btc_fbtc_steps_v3 *pstep; -+ u32 i, n_begin, n_end, array_idx, cnt = 0; -+ u8 type, val; -+ u16 diff_t; -+ -+ if ((pfwinfo->rpt_en_map & -+ rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0) -+ return; -+ -+ pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; -+ if (!pcinfo->valid) -+ return; -+ -+ pstep = &pfwinfo->rpt_fbtc_step.finfo.v3; -+ if (pcinfo->req_fver != pstep->fver) -+ return; -+ -+ if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP) -+ n_begin = 1; -+ else -+ n_begin = le32_to_cpu(pstep->cnt) - FCXDEF_STEP + 1; -+ -+ n_end = le32_to_cpu(pstep->cnt); -+ -+ if (n_begin > n_end) -+ return; -+ -+ /* restore step info by using ring instead of FIFO */ -+ for (i = n_begin; i <= n_end; i++) { -+ array_idx = (i - 1) % FCXDEF_STEP; -+ type = pstep->step[array_idx].type; -+ val = pstep->step[array_idx].val; -+ diff_t = le16_to_cpu(pstep->step[array_idx].difft); -+ -+ if (type == CXSTEP_NONE || type >= CXSTEP_MAX) -+ continue; -+ -+ if (cnt % 10 == 0) -+ seq_printf(m, " %-15s : ", "[steps]"); -+ -+ seq_printf(m, "-> %s(%02d)", -+ (type == CXSTEP_SLOT ? -+ id_to_slot((u32)val) : -+ id_to_evt((u32)val)), diff_t); -+ -+ if (cnt % 10 == 9) -+ seq_puts(m, "\n"); -+ -+ cnt++; -+ } -+} -+ - static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -6946,7 +7039,12 @@ static void _show_fw_dm_msg(struct rtw89 - _show_fbtc_cysta_v4(rtwdev, m); - - _show_fbtc_nullsta(rtwdev, m); -- _show_fbtc_step(rtwdev, m); -+ -+ if (ver->fcxstep == 2) -+ _show_fbtc_step_v2(rtwdev, m); -+ else if (ver->fcxstep == 3) -+ _show_fbtc_step_v3(rtwdev, m); -+ - } - - static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1611,6 +1611,36 @@ enum rtw89_btc_cxst_state { - CXST_MAX = 0x12, - }; - -+enum rtw89_btc_cxevnt { -+ CXEVNT_TDMA_ENTRY = 0x0, -+ CXEVNT_WL_TMR, -+ CXEVNT_B1_TMR, -+ CXEVNT_B2_TMR, -+ CXEVNT_B3_TMR, -+ CXEVNT_B4_TMR, -+ CXEVNT_W2B_TMR, -+ CXEVNT_B2W_TMR, -+ CXEVNT_BCN_EARLY, -+ CXEVNT_A2DP_EMPTY, -+ CXEVNT_LK_END, -+ CXEVNT_RX_ISR, -+ CXEVNT_RX_FC0, -+ CXEVNT_RX_FC1, -+ CXEVNT_BT_RELINK, -+ CXEVNT_BT_RETRY, -+ CXEVNT_E2G, -+ CXEVNT_E5G, -+ CXEVNT_EBT, -+ CXEVNT_ENULL, -+ CXEVNT_DRV_WLK, -+ CXEVNT_BCN_OK, -+ CXEVNT_BT_CHANGE, -+ CXEVNT_EBT_EXTEND, -+ CXEVNT_E2G_NULL1, -+ CXEVNT_B1FDD_TMR, -+ CXEVNT_MAX -+}; -+ - enum { - CXBCN_ALL = 0x0, - CXBCN_ALL_OK, -@@ -1696,7 +1726,7 @@ struct rtw89_btc_fbtc_step { - __le16 difft; - } __packed; - --struct rtw89_btc_fbtc_steps { -+struct rtw89_btc_fbtc_steps_v2 { - u8 fver; /* btc_ver::fcxstep */ - u8 rsvd; - __le16 cnt; -@@ -1705,7 +1735,7 @@ struct rtw89_btc_fbtc_steps { - struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; - } __packed; - --struct rtw89_btc_fbtc_steps_v1 { -+struct rtw89_btc_fbtc_steps_v3 { - u8 fver; - u8 en; - __le16 rsvd; -@@ -1713,6 +1743,11 @@ struct rtw89_btc_fbtc_steps_v1 { - struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; - } __packed; - -+union rtw89_btc_fbtc_steps_info { -+ struct rtw89_btc_fbtc_steps_v2 v2; -+ struct rtw89_btc_fbtc_steps_v3 v3; -+}; -+ - struct rtw89_btc_fbtc_cysta_v2 { /* statistics for cycles */ - u8 fver; /* btc_ver::fcxcysta */ - u8 rsvd; -@@ -2072,10 +2107,7 @@ struct rtw89_btc_rpt_fbtc_cysta { - - struct rtw89_btc_rpt_fbtc_step { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- union { -- struct rtw89_btc_fbtc_steps finfo; /* info from fw */ -- struct rtw89_btc_fbtc_steps_v1 finfo_v1; /* info from fw */ -- }; -+ union rtw89_btc_fbtc_steps_info finfo; /* info from fw */ - }; - - struct rtw89_btc_rpt_fbtc_nullsta { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-111-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-111-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch deleted file mode 100644 index 2fc553628..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-111-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 2ce43be348502703cf173fc31ea45bfe5ff43f90 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:41 +0800 -Subject: [PATCH 111/149] wifi: rtw89: coex: refactor debug log of slot list - -Slot list is to list the WiFi/Bluetooth PTA hardware priority setting. -Move the list parser to its function, not to append together with TDMA -parser. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 45 +++-------------------- - 1 file changed, 5 insertions(+), 40 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -6345,9 +6345,6 @@ static void _show_fbtc_tdma(struct rtw89 - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; - struct rtw89_btc_fbtc_tdma *t = NULL; -- struct rtw89_btc_fbtc_slot *s = NULL; -- struct rtw89_btc_dm *dm = &btc->dm; -- u8 i, cnt = 0; - - pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; - if (!pcinfo->valid) -@@ -6373,61 +6370,29 @@ static void _show_fbtc_tdma(struct rtw89 - "policy_type:%d", - (u32)btc->policy_type); - -- s = pfwinfo->rpt_fbtc_slots.finfo.slot; -- -- for (i = 0; i < CXST_MAX; i++) { -- if (dm->update_slot_map == BIT(CXST_MAX) - 1) -- break; -- -- if (!(dm->update_slot_map & BIT(i))) -- continue; -- -- if (cnt % 6 == 0) -- seq_printf(m, -- " %-15s : %d[%d/0x%x/%d]", -- "[slot_policy]", -- (u32)i, -- s[i].dur, s[i].cxtbl, s[i].cxtype); -- else -- seq_printf(m, -- ", %d[%d/0x%x/%d]", -- (u32)i, -- s[i].dur, s[i].cxtbl, s[i].cxtype); -- if (cnt % 6 == 5) -- seq_puts(m, "\n"); -- cnt++; -- } - seq_puts(m, "\n"); - } - - static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; -- struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -- struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -- struct rtw89_btc_fbtc_slots *pslots = NULL; -- struct rtw89_btc_fbtc_slot s; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_fbtc_slot *s; - u8 i = 0; - -- pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; -- if (!pcinfo->valid) -- return; -- -- pslots = &pfwinfo->rpt_fbtc_slots.finfo; -- - for (i = 0; i < CXST_MAX; i++) { -- s = pslots->slot[i]; -+ s = &dm->slot_now[i]; - if (i % 6 == 0) - seq_printf(m, - " %-15s : %02d[%03d/0x%x/%d]", - "[slot_list]", - (u32)i, -- s.dur, s.cxtbl, s.cxtype); -+ s->dur, s->cxtbl, s->cxtype); - else - seq_printf(m, - ", %02d[%03d/0x%x/%d]", - (u32)i, -- s.dur, s.cxtbl, s.cxtype); -+ s->dur, s->cxtbl, s->cxtype); - if (i % 6 == 5) - seq_puts(m, "\n"); - } diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-112-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-112-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch deleted file mode 100644 index 8979ff066..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-112-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ae4e1adbb1be65cadde793239a39fa947a3ff828 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:42 +0800 -Subject: [PATCH 112/149] wifi: rtw89: coex: Packet traffic arbitration - hardware owner monitor - -Because the difference of the hardware design, RTL8852C can not get the -PTA owner by the same method with RTL8852B, RTL8852A. Modify the get owner -API and related logic. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 7 ++----- - drivers/net/wireless/realtek/rtw89/mac.c | 11 +++++++++-- - 2 files changed, 11 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -4873,7 +4873,7 @@ void rtw89_btc_ntfy_init(struct rtw89_de - _write_scbd(rtwdev, - BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); - _update_bt_scbd(rtwdev, true); -- if (rtw89_mac_get_ctrl_path(rtwdev) && chip->chip_id == RTL8852A) { -+ if (rtw89_mac_get_ctrl_path(rtwdev)) { - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): PTA owner warning!!\n", - __func__); -@@ -7082,10 +7082,7 @@ static void _show_mreg(struct rtw89_dev - - /* To avoid I/O if WL LPS or power-off */ - if (!wl->status.map.lps && !wl->status.map.rf_off) { -- if (chip->chip_id == RTL8852A) -- btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); -- else if (chip->chip_id == RTL8852C) -- btc->dm.pta_owner = 0; -+ btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); - - _get_gnt(rtwdev, &gnt_cfg); - gnt = gnt_cfg.band[0]; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4865,9 +4865,16 @@ EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1 - - bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev) - { -- u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u8 val = 0; - -- return FIELD_GET(B_AX_LTE_MUX_CTRL_PATH >> 24, val); -+ if (chip->chip_id == RTL8852C) -+ return false; -+ else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) -+ val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3, -+ B_AX_LTE_MUX_CTRL_PATH >> 24); -+ -+ return !!val; - } - - u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-113-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-113-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch deleted file mode 100644 index 312be276f..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-113-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 447a3267cbed55963bcd146ddebc72429b630dbf Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:43 +0800 -Subject: [PATCH 113/149] wifi: rtw89: coex: Change RTL8852B use v1 TDMA policy - -RTL8852B support the new features like TDMA instant (Change TDMA mechanism -immediately), Co-RX feature (Wi-Fi/Bluetooth can RX in the same time) and -so on. The v1 TDMA policy will enable those newer mechanism. It will have -a better coexistence performance. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2423,7 +2423,7 @@ static const struct rtw89_chip_ops rtw88 - .btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt, - .btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby, - .btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain, -- .btc_set_policy = rtw89_btc_set_policy, -+ .btc_set_policy = rtw89_btc_set_policy_v1, - }; - - const struct rtw89_chip_info rtw8852b_chip_info = { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-114-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-114-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch deleted file mode 100644 index 16a8973ad..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-114-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch +++ /dev/null @@ -1,197 +0,0 @@ -From fbc2caf19914371973f14b6ac7ef525c49e4b1f1 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Fri, 6 Jan 2023 20:08:44 +0800 -Subject: [PATCH 114/149] wifi: rtw89: coex: Change Wi-Fi role info related - logic to version separate - -The Wi-Fi role info structure will need to H2C to firmware, firmware -need these information to do some multi-role operation. v1 add DBCC -and NOA information in the structure. And driver side also need to -put/get values at the corresponding version of structure. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106120844.17441-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 39 ++++++++++++----------- - 1 file changed, 20 insertions(+), 19 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -2075,6 +2075,7 @@ static void _set_bt_afh_info(struct rtw8 - { - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_btc_bt_link_info *b = &bt->link_info; -@@ -2088,7 +2089,7 @@ static void _set_bt_afh_info(struct rtw8 - if (btc->ctrl.manual || wl->status.map.scan) - return; - -- if (chip->chip_id == RTL8852A) { -+ if (ver->fwlrole == 0) { - mode = wl_rinfo->link_mode; - connect_cnt = wl_rinfo->connect_cnt; - } else { -@@ -2107,13 +2108,13 @@ static void _set_bt_afh_info(struct rtw8 - r = &wl_rinfo->active_role[i]; - r1 = &wl_rinfo_v1->active_role_v1[i]; - -- if (chip->chip_id == RTL8852A && -+ if (ver->fwlrole == 0 && - (r->role == RTW89_WIFI_ROLE_P2P_GO || - r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { - ch = r->ch; - bw = r->bw; - break; -- } else if (chip->chip_id != RTL8852A && -+ } else if (ver->fwlrole == 1 && - (r1->role == RTW89_WIFI_ROLE_P2P_GO || - r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { - ch = r1->ch; -@@ -2128,12 +2129,12 @@ static void _set_bt_afh_info(struct rtw8 - r = &wl_rinfo->active_role[i]; - r1 = &wl_rinfo_v1->active_role_v1[i]; - -- if (chip->chip_id == RTL8852A && -+ if (ver->fwlrole == 0 && - r->connected && r->band == RTW89_BAND_2G) { - ch = r->ch; - bw = r->bw; - break; -- } else if (chip->chip_id != RTL8852A && -+ } else if (ver->fwlrole == 1 && - r1->connected && r1->band == RTW89_BAND_2G) { - ch = r1->ch; - bw = r1->bw; -@@ -3581,8 +3582,8 @@ static void _action_wl_rfk(struct rtw89_ - - static void _set_btg_ctrl(struct rtw89_dev *rtwdev) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -@@ -3593,7 +3594,7 @@ static void _set_btg_ctrl(struct rtw89_d - if (btc->ctrl.manual) - return; - -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; - else - mode = wl_rinfo_v1->link_mode; -@@ -3686,8 +3687,8 @@ static void rtw89_tx_time_iter(void *dat - - static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_wl_info *wl = &cx->wl; -@@ -3707,7 +3708,7 @@ static void _set_wl_tx_limit(struct rtw8 - if (btc->ctrl.manual) - return; - -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; - else - mode = wl_rinfo_v1->link_mode; -@@ -3755,8 +3756,8 @@ static void _set_wl_tx_limit(struct rtw8 - - static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -@@ -3764,7 +3765,7 @@ static void _set_bt_rx_agc(struct rtw89_ - bool bt_hi_lna_rx = false; - u8 mode; - -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; - else - mode = wl_rinfo_v1->link_mode; -@@ -4628,8 +4629,8 @@ static bool _chk_wl_rfk_request(struct r - static - void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_dm *dm = &rtwdev->btc.dm; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; -@@ -4644,7 +4645,7 @@ void _run_coex(struct rtw89_dev *rtwdev, - _update_dm_step(rtwdev, reason); - _update_btc_state_map(rtwdev); - -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; - else - mode = wl_rinfo_v1->link_mode; -@@ -4766,9 +4767,9 @@ void _run_coex(struct rtw89_dev *rtwdev, - break; - case BTC_WLINK_2G_SCC: - bt->scan_rx_low_pri = true; -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - _action_wl_2g_scc(rtwdev); -- else if (chip->chip_id == RTL8852C) -+ else if (ver->fwlrole == 1) - _action_wl_2g_scc_v1(rtwdev); - break; - case BTC_WLINK_2G_MCC: -@@ -5206,10 +5207,10 @@ void rtw89_btc_ntfy_role_info(struct rtw - struct rtw89_sta *rtwsta, enum btc_role_state state) - { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); - struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_link_info r = {0}; - struct rtw89_btc_wl_link_info *wlinfo = NULL; -@@ -5273,7 +5274,7 @@ void rtw89_btc_ntfy_role_info(struct rtw - wlinfo = &wl->link_info[r.pid]; - - memcpy(wlinfo, &r, sizeof(*wlinfo)); -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - _update_wl_info(rtwdev); - else - _update_wl_info_v1(rtwdev); -@@ -5789,8 +5790,8 @@ static void _show_wl_role_info(struct rt - - static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_wl_info *wl = &cx->wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; -@@ -5802,7 +5803,7 @@ static void _show_wl_info(struct rtw89_d - - seq_puts(m, "========== [WL Status] ==========\n"); - -- if (chip->chip_id == RTL8852A) -+ if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; - else - mode = wl_rinfo_v1->link_mode; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-115-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-115-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch deleted file mode 100644 index 7b87de43b..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-115-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 95dafeabe477d9692154e85140eda5124895ea4f Mon Sep 17 00:00:00 2001 -From: Kuan-Chung Chen -Date: Fri, 6 Jan 2023 20:15:16 +0800 -Subject: [PATCH 115/149] wifi: rtw89: fix null vif pointer when get management - frame date rate - -When transmitting a packet that gets from ieee80211_nullfunc_get(), -the vif in tx_info->control was no assigned, which will cause -dereferencing a null pointer. - -Signed-off-by: Kuan-Chung Chen -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106121517.19841-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -498,7 +498,8 @@ static u16 rtw89_core_get_mgmt_rate(stru - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - u16 lowest_rate; - -- if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || vif->p2p) -+ if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || -+ (vif && vif->p2p)) - lowest_rate = RTW89_HW_RATE_OFDM6; - else if (chan->band_type == RTW89_BAND_2G) - lowest_rate = RTW89_HW_RATE_CCK1; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-116-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-116-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch deleted file mode 100644 index 867fe3032..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-116-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 877287f971b145a3699ea8466333d48aff6204e5 Mon Sep 17 00:00:00 2001 -From: Kuan-Chung Chen -Date: Fri, 6 Jan 2023 20:15:17 +0800 -Subject: [PATCH 116/149] wifi: rtw89: set the correct mac_id for management - frames - -The mac_id of management frames should follow rtwvif->mac_id or -rtwsta->mac_id. Add this patch to set the correct mac_id and -prevent unexpected behavior. - -Signed-off-by: Kuan-Chung Chen -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230106121517.19841-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 31 ++++++++++++----------- - 1 file changed, 16 insertions(+), 15 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -512,6 +512,21 @@ static u16 rtw89_core_get_mgmt_rate(stru - return __ffs(vif->bss_conf.basic_rates) + lowest_rate; - } - -+static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, -+ struct rtw89_core_tx_request *tx_req) -+{ -+ struct ieee80211_vif *vif = tx_req->vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -+ struct ieee80211_sta *sta = tx_req->sta; -+ struct rtw89_sta *rtwsta; -+ -+ if (!sta) -+ return rtwvif->mac_id; -+ -+ rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ return rtwsta->mac_id; -+} -+ - static void - rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, - struct rtw89_core_tx_request *tx_req) -@@ -528,6 +543,7 @@ rtw89_core_tx_update_mgmt_info(struct rt - desc_info->qsel = qsel; - desc_info->ch_dma = ch_dma; - desc_info->port = desc_info->hiq ? rtwvif->port : 0; -+ desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); - desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL; - desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE; - -@@ -670,21 +686,6 @@ desc_bk: - desc_info->bk = true; - } - --static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, -- struct rtw89_core_tx_request *tx_req) --{ -- struct ieee80211_vif *vif = tx_req->vif; -- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -- struct ieee80211_sta *sta = tx_req->sta; -- struct rtw89_sta *rtwsta; -- -- if (!sta) -- return rtwvif->mac_id; -- -- rtwsta = (struct rtw89_sta *)sta->drv_priv; -- return rtwsta->mac_id; --} -- - static void - rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, - struct rtw89_core_tx_request *tx_req) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-117-wifi-rtw89-correct-register-definitions-of-digital-C.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-117-wifi-rtw89-correct-register-definitions-of-digital-C.patch deleted file mode 100644 index 91082afae..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-117-wifi-rtw89-correct-register-definitions-of-digital-C.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 15423743ae840977fe269ff907e37e20fe1c14df Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Fri, 13 Jan 2023 17:06:29 +0800 -Subject: [PATCH 117/149] wifi: rtw89: correct register definitions of digital - CFO and spur elimination - -This change fixes the precision of CFO and TX EVM, and it could imporve -performance in some cases. Also, use the correctted definition for 8852A. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230113090632.60957-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 4 ++-- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 6 +++--- - 2 files changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4102,9 +4102,9 @@ - #define R_MUIC 0x40F8 - #define B_MUIC_EN BIT(0) - #define R_DCFO 0x4264 --#define B_DCFO GENMASK(1, 0) -+#define B_DCFO GENMASK(7, 0) - #define R_SEG0CSI 0x42AC --#define B_SEG0CSI_IDX GENMASK(11, 0) -+#define B_SEG0CSI_IDX GENMASK(10, 0) - #define R_SEG0CSI_EN 0x42C4 - #define B_SEG0CSI_EN BIT(23) - #define R_BSS_CLR_MAP 0x43ac ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1035,7 +1035,7 @@ static void rtw8852a_spur_elimination(st - 0x210); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, - 0x210); -- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0); -+ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x7c0); - rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, - B_P0_NBIIDX_NOTCH_EN, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, -@@ -1047,7 +1047,7 @@ static void rtw8852a_spur_elimination(st - 0x210); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, - 0x210); -- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40); -+ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x40); - rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, - B_P0_NBIIDX_NOTCH_EN, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, -@@ -1059,7 +1059,7 @@ static void rtw8852a_spur_elimination(st - 0x2d0); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, - 0x2d0); -- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740); -+ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, B_SEG0CSI_IDX, 0x740); - rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, - B_P0_NBIIDX_NOTCH_EN, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-118-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-118-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch deleted file mode 100644 index ca2f28b55..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-118-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 3aa83062c3ec64dd757554a00653cc2d42179f12 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Fri, 13 Jan 2023 17:06:30 +0800 -Subject: [PATCH 118/149] wifi: rtw89: 8852c: rfk: correct ADC clock settings - -Some hardware modules don't have good RF characteristic as regular. -It could get ADC abnormal in low temperature, and it causes bad RX -performance and affects calibration result of DPK. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230113090632.60957-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 5 ++ - .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 51 ++++++++++++++----- - 2 files changed, 44 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4738,6 +4738,7 @@ - #define R_DRCK_FH 0xC094 - #define B_DRCK_LAT BIT(9) - #define R_DRCK 0xC0C4 -+#define B_DRCK_MUL GENMASK(21, 17) - #define B_DRCK_IDLE BIT(9) - #define B_DRCK_EN BIT(6) - #define B_DRCK_VAL GENMASK(4, 0) -@@ -4755,9 +4756,13 @@ - #define B_PATH0_SAMPL_DLY_T_MSK_V1 GENMASK(27, 26) - #define R_P0_CFCH_BW0 0xC0D4 - #define B_P0_CFCH_BW0 GENMASK(27, 26) -+#define B_P0_CFCH_EN GENMASK(14, 11) -+#define B_P0_CFCH_CTL GENMASK(10, 7) - #define R_P0_CFCH_BW1 0xC0D8 - #define B_P0_CFCH_EX BIT(13) - #define B_P0_CFCH_BW1 GENMASK(8, 5) -+#define R_ADCMOD 0xC0E8 -+#define B_ADCMOD_LP GENMASK(31, 16) - #define R_ADDCK0D 0xC0F0 - #define B_ADDCK0D_VAL2 GENMASK(31, 26) - #define B_ADDCK0D_VAL GENMASK(25, 16) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -11,6 +11,15 @@ - #include "rtw8852c_rfk_table.h" - #include "rtw8852c_table.h" - -+struct rxck_def { -+ u32 ctl; -+ u32 en; -+ u32 bw0; -+ u32 bw1; -+ u32 mul; -+ u32 lp; -+}; -+ - #define _TSSI_DE_MASK GENMASK(21, 12) - static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858}; - static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860}; -@@ -62,6 +71,10 @@ static const u32 dpk_par_regs[RTW89_DPK_ - static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10}; - static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c}; - -+static const struct rxck_def _ck480M = {0x8, 0x2, 0x3, 0xf, 0x0, 0x9}; -+static const struct rxck_def _ck960M = {0x8, 0x2, 0x2, 0x8, 0x0, 0x9}; -+static const struct rxck_def _ck1920M = {0x8, 0x0, 0x2, 0x4, 0x6, 0x9}; -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", -@@ -440,6 +453,8 @@ static void rtw8852c_txck_force(struct r - static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force, - enum adc_ck ck) - { -+ const struct rxck_def *def; -+ - rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0); - - if (!force) -@@ -447,6 +462,26 @@ static void rtw8852c_rxck_force(struct r - - rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck); - rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1); -+ -+ switch (ck) { -+ case ADC_480M: -+ def = &_ck480M; -+ break; -+ case ADC_960M: -+ def = &_ck960M; -+ break; -+ case ADC_1920M: -+ default: -+ def = &_ck1920M; -+ break; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, def->ctl); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, def->en); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, def->bw0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, def->bw1); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, def->mul); -+ rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, def->lp); - } - - static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0) -@@ -630,8 +665,6 @@ static void _iqk_rxk_setting(struct rtw8 - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); - rtw8852c_rxck_force(rtwdev, path, true, ADC_480M); - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x0); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x3); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xf); - rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); - break; -@@ -639,8 +672,6 @@ static void _iqk_rxk_setting(struct rtw8 - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); - rtw8852c_rxck_force(rtwdev, path, true, ADC_960M); - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x1); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x2); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xd); - rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); - break; -@@ -648,8 +679,6 @@ static void _iqk_rxk_setting(struct rtw8 - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, 0x1); - rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, 0x2); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb); - rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); - rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x1); - break; -@@ -1413,8 +1442,6 @@ static void _iqk_macbb_setting(struct rt - rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); - rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, 0x2); - -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, 0x1); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, 0xb); - rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, 0x1); - rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); - rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); -@@ -1760,7 +1787,7 @@ u8 _rx_dck_channel_calc(struct rtw89_dev - #define RTW8852C_DPK_VER 0xf - #define RTW8852C_DPK_TH_AVG_NUM 4 - #define RTW8852C_DPK_RF_PATH 2 --#define RTW8852C_DPK_KIP_REG_NUM 5 -+#define RTW8852C_DPK_KIP_REG_NUM 7 - #define RTW8852C_DPK_RXSRAM_DBG 0 - - enum rtw8852c_dpk_id { -@@ -1919,8 +1946,6 @@ static void _dpk_bb_afe_setting(struct r - - /*4. Set ADC clk*/ - rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 + (path << 8), B_P0_CFCH_BW0, 0x1); -- rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 + (path << 8), B_P0_CFCH_BW1, 0xb); - rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), - B_P0_NRBW_DBG, 0x1); - rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f); -@@ -2671,12 +2696,14 @@ static void _dpk_cal_select(struct rtw89 - enum rtw89_phy_idx phy, u8 kpath) - { - struct rtw89_dpk_info *dpk = &rtwdev->dpk; -- static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8}; -+ static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8}; - u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR]; - u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {}; - u8 path; - bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false}; - -+ static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM); -+ - if (dpk->is_dpk_reload_en) { - for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { - if (!(kpath & BIT(path))) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-119-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-119-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch deleted file mode 100644 index 0ec8e2793..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-119-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 7f495de6ae7d31f098970fb45a038c9f69b1bf75 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 13 Jan 2023 17:06:31 +0800 -Subject: [PATCH 119/149] wifi: rtw89: fix assignation of TX BD RAM table - -TX BD's RAM table describes how HW allocates usable buffer section -for each TX channel at fetch time. The total RAM size for TX BD is -chip-dependent. For 8852BE, it has only half size (32) for TX channels -of single band. Original table arrange total size (64) for dual band. -It will overflow on 8852BE circuit and cause section conflicts between -different TX channels. - -So, we do the changes below. -* add another table for single band chip and export both kind of tables -* point to the expected one in rtw89_pci_info by chip - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230113090632.60957-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/pci.c | 15 ++++++++++++++- - drivers/net/wireless/realtek/rtw89/pci.h | 15 +++++++++------ - drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852be.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 1 + - 5 files changed, 26 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -1384,7 +1384,7 @@ static int rtw89_pci_ops_tx_write(struct - return 0; - } - --static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = { -+const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM] = { - [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, - [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, - [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, -@@ -1399,11 +1399,24 @@ static const struct rtw89_pci_bd_ram bd_ - [RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1}, - [RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1}, - }; -+EXPORT_SYMBOL(rtw89_bd_ram_table_dual); -+ -+const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM] = { -+ [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, -+ [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, -+ [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, -+ [RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2}, -+ [RTW89_TXCH_CH8] = {.start_idx = 20, .max_num = 4, .min_num = 1}, -+ [RTW89_TXCH_CH9] = {.start_idx = 24, .max_num = 4, .min_num = 1}, -+ [RTW89_TXCH_CH12] = {.start_idx = 28, .max_num = 4, .min_num = 1}, -+}; -+EXPORT_SYMBOL(rtw89_bd_ram_table_single); - - static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev) - { - struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; - const struct rtw89_pci_info *info = rtwdev->pci_info; -+ const struct rtw89_pci_bd_ram *bd_ram_table = *info->bd_ram_table; - struct rtw89_pci_tx_ring *tx_ring; - struct rtw89_pci_rx_ring *rx_ring; - struct rtw89_pci_dma_ring *bd_ring; ---- a/drivers/net/wireless/realtek/rtw89/pci.h -+++ b/drivers/net/wireless/realtek/rtw89/pci.h -@@ -750,6 +750,12 @@ struct rtw89_pci_ch_dma_addr_set { - struct rtw89_pci_ch_dma_addr rx[RTW89_RXCH_NUM]; - }; - -+struct rtw89_pci_bd_ram { -+ u8 start_idx; -+ u8 max_num; -+ u8 min_num; -+}; -+ - struct rtw89_pci_info { - enum mac_ax_bd_trunc_mode txbd_trunc_mode; - enum mac_ax_bd_trunc_mode rxbd_trunc_mode; -@@ -785,6 +791,7 @@ struct rtw89_pci_info { - u32 tx_dma_ch_mask; - const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power; - const struct rtw89_pci_ch_dma_addr_set *dma_addr_set; -+ const struct rtw89_pci_bd_ram (*bd_ram_table)[RTW89_TXCH_NUM]; - - int (*ltr_set)(struct rtw89_dev *rtwdev, bool en); - u32 (*fill_txaddr_info)(struct rtw89_dev *rtwdev, -@@ -798,12 +805,6 @@ struct rtw89_pci_info { - struct rtw89_pci_isrs *isrs); - }; - --struct rtw89_pci_bd_ram { -- u8 start_idx; -- u8 max_num; -- u8 min_num; --}; -- - struct rtw89_pci_tx_data { - dma_addr_t dma; - }; -@@ -1057,6 +1058,8 @@ static inline bool rtw89_pci_ltr_is_err_ - extern const struct dev_pm_ops rtw89_pm_ops; - extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set; - extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1; -+extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_dual[RTW89_TXCH_NUM]; -+extern const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM]; - - struct pci_device_id; - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c -@@ -44,6 +44,7 @@ static const struct rtw89_pci_info rtw88 - .tx_dma_ch_mask = 0, - .bd_idx_addr_low_power = NULL, - .dma_addr_set = &rtw89_pci_ch_dma_addr_set, -+ .bd_ram_table = &rtw89_bd_ram_table_dual, - - .ltr_set = rtw89_pci_ltr_set, - .fill_txaddr_info = rtw89_pci_fill_txaddr_info, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c -@@ -46,6 +46,7 @@ static const struct rtw89_pci_info rtw88 - BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), - .bd_idx_addr_low_power = NULL, - .dma_addr_set = &rtw89_pci_ch_dma_addr_set, -+ .bd_ram_table = &rtw89_bd_ram_table_single, - - .ltr_set = rtw89_pci_ltr_set, - .fill_txaddr_info = rtw89_pci_fill_txaddr_info, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c -@@ -53,6 +53,7 @@ static const struct rtw89_pci_info rtw88 - .tx_dma_ch_mask = 0, - .bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power, - .dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1, -+ .bd_ram_table = &rtw89_bd_ram_table_dual, - - .ltr_set = rtw89_pci_ltr_set_v1, - .fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-120-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-120-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch deleted file mode 100644 index 328f88314..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-120-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a3edb20146f000dfd5aba1f17e2dc0f363ff9446 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 13 Jan 2023 17:06:32 +0800 -Subject: [PATCH 120/149] wifi: rtw89: 8852b: fill the missing configuration - about queue empty checking - -The configurations, wde_qempty_acq_num and wde_qempty_mgq_sel, are used -when MAC checks if TX queues are empty. Fill the corresponding setting -for 8852B. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230113090632.60957-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2437,6 +2437,8 @@ const struct rtw89_chip_info rtw8852b_ch - .rsvd_ple_ofst = 0x2f800, - .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, - .dle_mem = rtw8852b_dle_mem_pcie, -+ .wde_qempty_acq_num = 4, -+ .wde_qempty_mgq_sel = 4, - .rf_base_addr = {0xe000, 0xf000}, - .pwr_on_seq = NULL, - .pwr_off_seq = NULL, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-121-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-121-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch deleted file mode 100644 index 937364ce7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-121-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 1742fbae7a49b067649b7c2958d9468711149e37 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:02 +0800 -Subject: [PATCH 121/149] wifi: rtw89: coex: Update Wi-Fi external control TDMA - parameters/tables - -This patch update the external control (Wi-Fi firmware control) type of -TDMA related parameters, almost all of these case were related to Wi-Fi -multi-role situations & AP mode. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 37 +++++++++++++++-------- - 1 file changed, 24 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -63,7 +63,7 @@ struct btc_fbtc_1slot { - static const struct rtw89_btc_fbtc_tdma t_def[] = { - [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, - [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0}, -- [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 3, 0, 0}, -+ [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0}, - [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, - [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, - [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, -@@ -80,21 +80,21 @@ static const struct rtw89_btc_fbtc_slot - [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), - [CXST_B2W] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_ISO), - [CXST_W1] = __DEF_FBTC_SLOT(70, 0xea5a5a5a, SLOT_ISO), -- [CXST_W2] = __DEF_FBTC_SLOT(70, 0xea5a5aaa, SLOT_ISO), -+ [CXST_W2] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), - [CXST_W2B] = __DEF_FBTC_SLOT(15, 0xea5a5a5a, SLOT_ISO), -- [CXST_B1] = __DEF_FBTC_SLOT(100, 0xe5555555, SLOT_MIX), -+ [CXST_B1] = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX), - [CXST_B2] = __DEF_FBTC_SLOT(7, 0xea5a5a5a, SLOT_MIX), - [CXST_B3] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX), - [CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX), - [CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO), -- [CXST_BLK] = __DEF_FBTC_SLOT(250, 0x55555555, SLOT_MIX), -- [CXST_E2G] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_MIX), -- [CXST_E5G] = __DEF_FBTC_SLOT(20, 0xffffffff, SLOT_MIX), -- [CXST_EBT] = __DEF_FBTC_SLOT(20, 0xe5555555, SLOT_MIX), -- [CXST_ENULL] = __DEF_FBTC_SLOT(7, 0xaaaaaaaa, SLOT_ISO), -+ [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), -+ [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX), -+ [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO), -+ [CXST_EBT] = __DEF_FBTC_SLOT(0, 0xe5555555, SLOT_MIX), -+ [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO), - [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), -- [CXST_W1FDD] = __DEF_FBTC_SLOT(35, 0xfafafafa, SLOT_ISO), -- [CXST_B1FDD] = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX), -+ [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), -+ [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), - }; - - static const u32 cxtbl[] = { -@@ -117,7 +117,12 @@ static const u32 cxtbl[] = { - 0xfafafafa, /* 16 */ - 0xffffddff, /* 17 */ - 0xdaffdaff, /* 18 */ -- 0xfafadafa /* 19 */ -+ 0xfafadafa, /* 19 */ -+ 0xea6a6a6a, /* 20 */ -+ 0xea55556a, /* 21 */ -+ 0xaafafafa, /* 22 */ -+ 0xfafaaafa, /* 23 */ -+ 0xfafffaff /* 24 */ - }; - - static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { -@@ -2701,15 +2706,16 @@ void rtw89_btc_set_policy_v1(struct rtw8 - break; - case BTC_CXP_OFF_EQ0: - _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); -+ _slot_set_type(btc, CXST_OFF, SLOT_ISO); - break; - case BTC_CXP_OFF_EQ1: - _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); - break; - case BTC_CXP_OFF_EQ2: -- _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); -+ _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); - break; - case BTC_CXP_OFF_EQ3: -- _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); -+ _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); - break; - case BTC_CXP_OFF_BWB0: - _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); -@@ -2765,6 +2771,7 @@ void rtw89_btc_set_policy_v1(struct rtw8 - default: - break; - } -+ s[CXST_OFF] = s_def[CXST_OFF]; - break; - case BTC_CXP_FIX: /* TDMA Fix-Slot */ - _write_scbd(rtwdev, BTC_WSCB_TDMA, true); -@@ -2791,6 +2798,10 @@ void rtw89_btc_set_policy_v1(struct rtw8 - _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_ISO); - _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); - break; -+ case BTC_CXP_FIX_TD4020: -+ _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX); -+ _slot_set(btc, CXST_B1, 20, tbl_b1, SLOT_MIX); -+ break; - case BTC_CXP_FIX_TD7010: - _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); - _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-122-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-122-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch deleted file mode 100644 index d86935985..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-122-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From aae256c0f2334691645d52e7cc965bf4241b599b Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:03 +0800 -Subject: [PATCH 122/149] wifi: rtw89: coex: Clear Bluetooth HW PTA counter - when radio state change - -Reset the counter no matter Wi-Fi is notified turning into power save or -not. With rest the counter coexistence will recognize Bluetooth is hanged -easily. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -5335,7 +5335,6 @@ void rtw89_btc_ntfy_radio_state(struct r - } - - if (rf_state == BTC_RFCTRL_WL_ON) { -- btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; - rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); - val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; - _write_scbd(rtwdev, val, true); -@@ -5347,6 +5346,8 @@ void rtw89_btc_ntfy_radio_state(struct r - _write_scbd(rtwdev, BTC_WSCB_ALL, false); - } - -+ btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; -+ - _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); - - wl->status.map.rf_off_pre = wl->status.map.rf_off; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-123-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-123-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch deleted file mode 100644 index 668da7e5f..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-123-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3f857b23dd8dae2c7301476e8e183628edc694d1 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:04 +0800 -Subject: [PATCH 123/149] wifi: rtw89: coex: Force to update TDMA parameter - when radio state change - -Force firmware to update TDMA parameter when enter/exit power saving. -The TDMA instant feature will make firmware force update TDMA parameter -immediately when the TDMA parameter H2C to firmware. Without this feature, -it will have a low fail rate trigger Bluetooth audio sound glitch when -Wi-Fi is under power saving. Or Wi-Fi fail to turn in to power save state. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -3818,6 +3818,7 @@ static void _action_common(struct rtw89_ - wl->scbd_change = false; - btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; - } -+ btc->dm.tdma_instant_excute = 0; - } - - static void _action_by_bt(struct rtw89_dev *rtwdev) -@@ -5347,6 +5348,11 @@ void rtw89_btc_ntfy_radio_state(struct r - } - - btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; -+ if (wl->status.map.lps_pre == BTC_LPS_OFF && -+ wl->status.map.lps_pre != wl->status.map.lps) -+ btc->dm.tdma_instant_excute = 1; -+ else -+ btc->dm.tdma_instant_excute = 0; - - _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-124-wifi-rtw89-coex-Refine-coexistence-log.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-124-wifi-rtw89-coex-Refine-coexistence-log.patch deleted file mode 100644 index 01b859d1b..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-124-wifi-rtw89-coex-Refine-coexistence-log.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 7cd8200555d4f01183f0b9071e0760c389a51816 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:05 +0800 -Subject: [PATCH 124/149] wifi: rtw89: coex: Refine coexistence log - -Adjust the log format and correct variable reference to make the log -more readable. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 158 +++++++++++----------- - 1 file changed, 76 insertions(+), 82 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -6401,20 +6401,21 @@ static void _show_fbtc_slots(struct rtw8 - - for (i = 0; i < CXST_MAX; i++) { - s = &dm->slot_now[i]; -- if (i % 6 == 0) -+ if (i % 5 == 0) - seq_printf(m, -- " %-15s : %02d[%03d/0x%x/%d]", -+ " %-15s : %5s[%03d/0x%x/%d]", - "[slot_list]", -- (u32)i, -+ id_to_slot((u32)i), - s->dur, s->cxtbl, s->cxtype); - else - seq_printf(m, -- ", %02d[%03d/0x%x/%d]", -- (u32)i, -+ ", %5s[%03d/0x%x/%d]", -+ id_to_slot((u32)i), - s->dur, s->cxtbl, s->cxtype); -- if (i % 6 == 5) -+ if (i % 5 == 4) - seq_puts(m, "\n"); - } -+ seq_puts(m, "\n"); - } - - static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) -@@ -6446,7 +6447,7 @@ static void _show_fbtc_cysta_v2(struct r - for (i = 0; i < CXST_MAX; i++) { - if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) - continue; -- seq_printf(m, ", %d:%d", (u32)i, -+ seq_printf(m, ", %s:%d", id_to_slot((u32)i), - le32_to_cpu(pcysta_le32->slot_cnt[i])); - } - -@@ -6481,7 +6482,7 @@ static void _show_fbtc_cysta_v2(struct r - le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]), - le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT])); - -- if (le16_to_cpu(pcysta_le32->cycles) == 0) -+ if (le16_to_cpu(pcysta_le32->cycles) <= 1) - return; - - /* 1 cycle record 1 wl-slot and 1 bt-slot */ -@@ -6608,7 +6609,7 @@ static void _show_fbtc_cysta_v3(struct r - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); - - cycle = le16_to_cpu(pcysta->cycles); -- if (cycle == 0) -+ if (cycle <= 1) - return; - - /* 1 cycle record 1 wl-slot and 1 bt-slot */ -@@ -6630,40 +6631,39 @@ static void _show_fbtc_cysta_v3(struct r - cnt++; - store_index = ((cycle - 1) % slot_pair) * 2; - -- if (cnt % divide_cnt == 1) { -- seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); -- } else { -- seq_printf(m, "->b%02d", -- le16_to_cpu(pcysta->slot_step_time[store_index])); -- if (a2dp->exist) { -- a2dp_trx = &pcysta->a2dp_trx[store_index]; -- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -- a2dp_trx->empty_cnt, -- a2dp_trx->retry_cnt, -- a2dp_trx->tx_rate ? 3 : 2, -- a2dp_trx->tx_cnt, -- a2dp_trx->ack_cnt, -- a2dp_trx->nack_cnt); -- } -- seq_printf(m, "->w%02d", -- le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -- if (a2dp->exist) { -- a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -- a2dp_trx->empty_cnt, -- a2dp_trx->retry_cnt, -- a2dp_trx->tx_rate ? 3 : 2, -- a2dp_trx->tx_cnt, -- a2dp_trx->ack_cnt, -- a2dp_trx->nack_cnt); -- } -+ if (cnt % divide_cnt == 1) -+ seq_printf(m, " %-15s : ", "[cycle_step]"); -+ -+ seq_printf(m, "->b%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); - } -- if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) -+ seq_printf(m, "->w%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ if (cnt % divide_cnt == 0 || cnt == c_end) - seq_puts(m, "\n"); - } - - if (a2dp->exist) { -- seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", -+ seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); -@@ -6741,7 +6741,7 @@ static void _show_fbtc_cysta_v4(struct r - le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); - - cycle = le16_to_cpu(pcysta->cycles); -- if (cycle == 0) -+ if (cycle <= 1) - return; - - /* 1 cycle record 1 wl-slot and 1 bt-slot */ -@@ -6763,40 +6763,39 @@ static void _show_fbtc_cysta_v4(struct r - cnt++; - store_index = ((cycle - 1) % slot_pair) * 2; - -- if (cnt % divide_cnt == 1) { -- seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); -- } else { -- seq_printf(m, "->b%02d", -- le16_to_cpu(pcysta->slot_step_time[store_index])); -- if (a2dp->exist) { -- a2dp_trx = &pcysta->a2dp_trx[store_index]; -- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -- a2dp_trx->empty_cnt, -- a2dp_trx->retry_cnt, -- a2dp_trx->tx_rate ? 3 : 2, -- a2dp_trx->tx_cnt, -- a2dp_trx->ack_cnt, -- a2dp_trx->nack_cnt); -- } -- seq_printf(m, "->w%02d", -- le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -- if (a2dp->exist) { -- a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -- a2dp_trx->empty_cnt, -- a2dp_trx->retry_cnt, -- a2dp_trx->tx_rate ? 3 : 2, -- a2dp_trx->tx_cnt, -- a2dp_trx->ack_cnt, -- a2dp_trx->nack_cnt); -- } -+ if (cnt % divide_cnt == 1) -+ seq_printf(m, " %-15s : ", "[cycle_step]"); -+ -+ seq_printf(m, "->b%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); - } -- if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) -+ seq_printf(m, "->w%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ if (cnt % divide_cnt == 0 || cnt == c_end) - seq_puts(m, "\n"); - } - - if (a2dp->exist) { -- seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", -+ seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", - "[a2dp_t_sta]", - le16_to_cpu(pcysta->a2dp_ept.cnt), - le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); -@@ -6827,13 +6826,9 @@ static void _show_fbtc_nullsta(struct rt - - ns = &pfwinfo->rpt_fbtc_nullsta.finfo; - if (ver->fcxnullsta == 1) { -- seq_printf(m, " %-15s : ", "[null_sta]"); -- - for (i = 0; i < 2; i++) { -- if (i != 0) -- seq_printf(m, ", null-%d", i); -- else -- seq_printf(m, "null-%d", i); -+ seq_printf(m, " %-15s : ", "[NULL-STA]"); -+ seq_printf(m, "null-%d", i); - seq_printf(m, "[ok:%d/", - le32_to_cpu(ns->v1.result[i][1])); - seq_printf(m, "fail:%d/", -@@ -6845,17 +6840,14 @@ static void _show_fbtc_nullsta(struct rt - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->v1.avg_t[i]) / 1000, - le32_to_cpu(ns->v1.avg_t[i]) % 1000); -- seq_printf(m, "max_t:%d.%03d]", -+ seq_printf(m, "max_t:%d.%03d]\n", - le32_to_cpu(ns->v1.max_t[i]) / 1000, - le32_to_cpu(ns->v1.max_t[i]) % 1000); - } - } else { -- seq_printf(m, " %-15s : ", "[null_sta]"); - for (i = 0; i < 2; i++) { -- if (i != 0) -- seq_printf(m, ", null-%d", i); -- else -- seq_printf(m, "null-%d", i); -+ seq_printf(m, " %-15s : ", "[NULL-STA]"); -+ seq_printf(m, "null-%d", i); - seq_printf(m, "[Tx:%d/", - le32_to_cpu(ns->v2.result[i][4])); - seq_printf(m, "[ok:%d/", -@@ -6869,12 +6861,11 @@ static void _show_fbtc_nullsta(struct rt - seq_printf(m, "avg_t:%d.%03d/", - le32_to_cpu(ns->v2.avg_t[i]) / 1000, - le32_to_cpu(ns->v2.avg_t[i]) % 1000); -- seq_printf(m, "max_t:%d.%03d]", -+ seq_printf(m, "max_t:%d.%03d]\n", - le32_to_cpu(ns->v2.max_t[i]) / 1000, - le32_to_cpu(ns->v2.max_t[i]) % 1000); - } - } -- seq_puts(m, "\n"); - } - - static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) -@@ -7147,6 +7138,9 @@ static void _show_mreg(struct rtw89_dev - if (cnt % 6 == 5) - seq_puts(m, "\n"); - cnt++; -+ -+ if (i >= pmreg->reg_num) -+ seq_puts(m, "\n"); - } - - pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-125-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-125-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch deleted file mode 100644 index fa46554c5..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-125-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6d2a479c1f9e957908d0fc9d56b9831a48f5ce80 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:06 +0800 -Subject: [PATCH 125/149] wifi: rtw89: coex: Set Bluetooth background scan PTA - request priority - -When Wi-Fi is RX, set Bluetooth background scan to low-priority and -not to break Wi-Fi packet. Bluetooth can RX depend on hardware ability -even RX request has been rejected. This way can improve Wi-Fi RX -throughput performance. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -4763,6 +4763,8 @@ void _run_coex(struct rtw89_dev *rtwdev, - _action_wl_nc(rtwdev); - break; - case BTC_WLINK_2G_STA: -+ if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) -+ bt->scan_rx_low_pri = true; - _action_wl_2g_sta(rtwdev); - break; - case BTC_WLINK_2G_AP: diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-126-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-126-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch deleted file mode 100644 index e3d4c7f74..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-126-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c7d2b22f52bd0088cd39dba57bb7c1e8f3df5489 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:07 +0800 -Subject: [PATCH 126/149] wifi: rtw89: coex: Correct A2DP exist variable source - -When Wi-Fi enter and leave LPS, coexistence driver need to know -is there A2DP exist or not. And when Wi-Fi sleep in deep power save -state will not able to receive mailbox sent from Bluetooth. So update -the A2DP exist information from reading register. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -4602,7 +4602,7 @@ static void _update_bt_scbd(struct rtw89 - - bt->whql_test = !!(val & BTC_BSCB_WHQL); - bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE; -- bt->link_info.a2dp_desc.active = !!(val & BTC_BSCB_A2DP_ACT); -+ bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT); - - /* if rfk run 1->0 */ - if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN)) diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-127-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-127-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch deleted file mode 100644 index eb8ee7cb8..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-127-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 4b3e7e813bba53402af13ecd5343ac9667ca7608 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:08 +0800 -Subject: [PATCH 127/149] wifi: rtw89: coex: Fix test fail when coexist with - raspberryPI A2DP idle - -The origin code will enable TDMA WL:BT = 50:50 to prevent Wi-Fi -throughput suddenly drop to 0 in the moment while A2DP pause. -And this protection just a short moment, and will turn to Bluetooth -idle case when A2DP turn into sniff mode. But the raspberryPI simulated -A2DP device will not turn into sniff mode. So the protection will bring -the throughput drop. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -3847,7 +3847,7 @@ static void _action_by_bt(struct rtw89_d - case BTC_BT_NOPROFILE: - if (_check_freerun(rtwdev)) - _action_freerun(rtwdev); -- else if (a2dp.active || pan.active) -+ else if (pan.active) - _action_bt_pan(rtwdev); - else - _action_bt_idle(rtwdev); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-128-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-128-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch deleted file mode 100644 index 1725db978..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-128-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch +++ /dev/null @@ -1,30 +0,0 @@ -From de06588cb95cb3bbece81e9838547c1a3c2aa023 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 17 Jan 2023 19:41:09 +0800 -Subject: [PATCH 128/149] wifi: rtw89: coex: Update Wi-Fi Bluetooth coexistence - version to 7.0.0 - -Should update the driver with the supported firmware version of the -below item. -Bluetooth firmware BT_Coex_Ver: 0x07 -Wi-Fi firmware version: RTL8852C->v0.27.56.10, RTL8852A->v0.24.36 - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230117114109.4298-9-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -9,7 +9,7 @@ - #include "ps.h" - #include "reg.h" - --#define RTW89_COEX_VERSION 0x06030013 -+#define RTW89_COEX_VERSION 0x07000013 - #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ - - enum btc_fbtc_tdma_template { diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-129-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-129-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch deleted file mode 100644 index a982960fd..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-129-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 1120e6a6c5cd1144694209d6aa6a225af064950a Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:24:51 +0800 -Subject: [PATCH 129/149] wifi: rtw89: correct unit for port offset and refine - macro - -Strictly speaking, the unit of the offset should be TU instead of ms. -So, correct it and the macro for calculation. Then, to make the macro -generic, the factor n is moved outside. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119062453.58341-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 4 +++- - drivers/net/wireless/realtek/rtw89/mac.h | 2 +- - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3930,10 +3930,12 @@ static void rtw89_mac_port_tsf_sync(stru - - /* adjust offset randomly to avoid beacon conflict */ - offset = offset - offset / 4 + get_random_u32() % (offset / 2); -- val = RTW89_PORT_OFFSET_MS_TO_32US((*n_offset)++, offset); -+ val = (*n_offset) * RTW89_PORT_OFFSET_TU_TO_32US(offset); - reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, - rtwvif->mac_idx); - -+ (*n_offset)++; -+ - rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); - rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); - rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -168,7 +168,7 @@ enum rtw89_mac_ax_l0_to_l1_event { - MAC_AX_L0_TO_L1_EVENT_MAX = 15, - }; - --#define RTW89_PORT_OFFSET_MS_TO_32US(n, shift_ms) ((n) * (shift_ms) * 1000 / 32) -+#define RTW89_PORT_OFFSET_TU_TO_32US(shift_tu) ((shift_tu) * 1024 / 32) - - enum rtw89_mac_dbg_port_sel { - /* CMAC 0 related */ diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-130-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-130-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch deleted file mode 100644 index c85b4f8ce..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-130-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 42db7edd5c0523b43a004779caf36e1ebac80b40 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:24:52 +0800 -Subject: [PATCH 130/149] wifi: rtw89: split out generic part of - rtw89_mac_port_tsf_sync() - -Originally, rtw89_mac_port_tsf_sync() contains randomization logic -internally. However, not all situation, we need the randomization. -So, split out the generic part from it. And, make the full logic of -original one contained in rtw89_mac_port_tsf_sync_rand(). It will -still be used by its original caller as before. Then, the generic -one will be used in MCC (multi-channel concurrency) management flow. -MCC will implement its logic to decide the offset for TSF sync. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119062453.58341-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 33 +++++++++++++++--------- - drivers/net/wireless/realtek/rtw89/mac.h | 4 +++ - 2 files changed, 25 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3918,27 +3918,36 @@ static void rtw89_mac_port_cfg_tbtt_shif - B_AX_TBTT_SHIFT_OFST_MASK, val); - } - --static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, -- struct rtw89_vif *rtwvif, -- struct rtw89_vif *rtwvif_src, u8 offset, -- int *n_offset) -+void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_vif *rtwvif_src, -+ u16 offset_tu) - { - u32 val, reg; - -+ val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu); -+ reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, -+ rtwvif->mac_idx); -+ -+ rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); -+ rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); -+ rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); -+} -+ -+static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_vif *rtwvif_src, -+ u8 offset, int *n_offset) -+{ - if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) - return; - - /* adjust offset randomly to avoid beacon conflict */ - offset = offset - offset / 4 + get_random_u32() % (offset / 2); -- val = (*n_offset) * RTW89_PORT_OFFSET_TU_TO_32US(offset); -- reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, -- rtwvif->mac_idx); -+ rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src, -+ (*n_offset) * offset); - - (*n_offset)++; -- -- rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port); -- rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val); -- rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW); - } - - static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) -@@ -3960,7 +3969,7 @@ static void rtw89_mac_port_tsf_resync_al - offset /= (vif_aps + 1); - - rtw89_for_each_rtwvif(rtwdev, tmp) -- rtw89_mac_port_tsf_sync(rtwdev, tmp, src, offset, &n_offset); -+ rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset); - } - - int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -906,6 +906,10 @@ int rtw89_mac_write_lte(struct rtw89_dev - int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); - int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); - int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -+void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_vif *rtwvif_src, -+ u16 offset_tu); - void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); - void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-131-wifi-rtw89-mac-add-function-to-get-TSF.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-131-wifi-rtw89-mac-add-function-to-get-TSF.patch deleted file mode 100644 index e60f7de32..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-131-wifi-rtw89-mac-add-function-to-get-TSF.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 76f478a34dafcee28165022b2f73d0ee1f0f47e5 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:24:53 +0800 -Subject: [PATCH 131/149] wifi: rtw89: mac: add function to get TSF - -Add mac function rtw89_mac_port_get_tsf() to get TSF by port. -It will be used when MCC (multi-channel concurrency) calculates -timing things. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119062453.58341-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 18 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 11 +++++++++++ - 2 files changed, 29 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4061,6 +4061,24 @@ int rtw89_mac_port_update(struct rtw89_d - return 0; - } - -+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ u64 *tsf) -+{ -+ const struct rtw89_port_reg *p = &rtw_port_base; -+ u32 tsf_low, tsf_high; -+ int ret; -+ -+ ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL); -+ if (ret) -+ return ret; -+ -+ tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l); -+ tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h); -+ *tsf = (u64)tsf_high << 32 | tsf_low; -+ -+ return 0; -+} -+ - static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, - struct cfg80211_bss *bss, - void *data) ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -828,6 +828,15 @@ static inline u32 rtw89_mac_reg_by_port( - } - - static inline u32 -+rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base) -+{ -+ u32 reg; -+ -+ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); -+ return rtw89_read32(rtwdev, reg); -+} -+ -+static inline u32 - rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, - u32 base, u32 mask) - { -@@ -910,6 +919,8 @@ void rtw89_mac_port_tsf_sync(struct rtw8 - struct rtw89_vif *rtwvif, - struct rtw89_vif *rtwvif_src, - u16 offset_tu); -+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ u64 *tsf); - void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif); - void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-133-wifi-rtw89-deal-with-RXI300-error.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-133-wifi-rtw89-deal-with-RXI300-error.patch deleted file mode 100644 index 6e4969d70..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-133-wifi-rtw89-deal-with-RXI300-error.patch +++ /dev/null @@ -1,67 +0,0 @@ -From f5d98831badb89172515ac73015d0e7475a285c1 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:35:29 +0800 -Subject: [PATCH 133/149] wifi: rtw89: deal with RXI300 error - -RXI300 is a HW design to maintain stuffs across BUS, e.g. AXI, AHB, APB. -It will feedback an error when host does an invalid BUS operation. -For example, -* BUS master request without power/clock on. -* host reads/writes/accesses an invalid address. - -They might lead to problems such as BUS timeout, platform hang, etc. So, -once if RXI300 feedback an error, it notifies that driver need a L2 SER -(system error recovery) to reset things. - -Previously, driver did not parse the error scenario for RXI300. We add -it and assign a corresponding error code which will make SER flow do L2 -reset. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119063529.61563-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 5 ++++- - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -623,7 +623,8 @@ static void rtw89_mac_dump_err_status(st - if (err != MAC_AX_ERR_L1_ERR_DMAC && - err != MAC_AX_ERR_L0_PROMOTE_TO_L1 && - err != MAC_AX_ERR_L0_ERR_CMAC0 && -- err != MAC_AX_ERR_L0_ERR_CMAC1) -+ err != MAC_AX_ERR_L0_ERR_CMAC1 && -+ err != MAC_AX_ERR_RXI300) - return; - - rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); -@@ -663,6 +664,8 @@ u32 rtw89_mac_get_err_status(struct rtw8 - err = MAC_AX_ERR_CPU_EXCEPTION; - else if (err_scnr == RTW89_WCPU_ASSERTION) - err = MAC_AX_ERR_ASSERTION; -+ else if (err_scnr == RTW89_RXI300_ERROR) -+ err = MAC_AX_ERR_RXI300; - - rtw89_fw_st_dbg_dump(rtwdev); - rtw89_mac_dump_err_status(rtwdev, err); ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -623,6 +623,7 @@ struct rtw89_mac_dle_dfi_qempty { - }; - - enum rtw89_mac_error_scenario { -+ RTW89_RXI300_ERROR = 1, - RTW89_WCPU_CPU_EXCEPTION = 2, - RTW89_WCPU_ASSERTION = 3, - }; -@@ -769,6 +770,7 @@ enum mac_ax_err_info { - MAC_AX_ERR_L2_ERR_WDT_TIMEOUT_INT = 0x2599, - MAC_AX_ERR_CPU_EXCEPTION = 0x3000, - MAC_AX_ERR_ASSERTION = 0x4000, -+ MAC_AX_ERR_RXI300 = 0x5000, - MAC_AX_GET_ERR_MAX, - MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-134-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-134-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch deleted file mode 100644 index 3520867cb..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-134-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 24d72944d79e6795ba4330c114de0387386bf3aa Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:43:41 +0800 -Subject: [PATCH 134/149] wifi: rtw89: fix parsing offset for MCC C2H - -A 8-byte offset is missed during parsing C2Hs (chip to host packets) -of MCC (multi-channel concurrent) series. -So, we fix it. - -Fixes: ef9dff4cb491 ("wifi: rtw89: mac: process MCC related C2H") -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119064342.65391-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.h | 34 ++++++++++++------------- - 1 file changed, 17 insertions(+), 17 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3219,16 +3219,16 @@ static inline struct rtw89_fw_c2h_attr * - le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(25, 24)) - - #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) - #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) - - #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) - #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 2)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) - #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) - - struct rtw89_mac_mcc_tsf_rpt { - u32 macid_x; -@@ -3242,30 +3242,30 @@ struct rtw89_mac_mcc_tsf_rpt { - static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE); - - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 0)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(17, 16)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(17, 16)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(31, 0)) - #define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 6), GENMASK(31, 0)) - - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(5, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(5, 0)) - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 6)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 6)) - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) -+ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) -+ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) - - #define RTW89_FW_HDR_SIZE 32 - #define RTW89_FW_SECTION_HDR_SIZE 16 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-135-wifi-rtw89-refine-MCC-C2H-debug-logs.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-135-wifi-rtw89-refine-MCC-C2H-debug-logs.patch deleted file mode 100644 index 0eefe932c..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-135-wifi-rtw89-refine-MCC-C2H-debug-logs.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 214a98b151b14d3dbfa60136abcf99df5d347a80 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 19 Jan 2023 14:43:42 +0800 -Subject: [PATCH 135/149] wifi: rtw89: refine MCC C2H debug logs - -To debug channel concurrency more centrally, we add a new debug flag, -RTW89_DBG_CHAN, for channel related things, especially channel concurrency. -Then, we change MCC (multi-channel concurrency) C2H (chip to host packets) -debug flag to it. - -Besides, refine debug logs to show TSF in u64 directly. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119064342.65391-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 21 +++++++++++++-------- - 2 files changed, 14 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.h -+++ b/drivers/net/wireless/realtek/rtw89/debug.h -@@ -28,6 +28,7 @@ enum rtw89_debug_mask { - RTW89_DBG_STATE = BIT(17), - RTW89_DBG_WOW = BIT(18), - RTW89_DBG_UL_TB = BIT(19), -+ RTW89_DBG_CHAN = BIT(20), - - RTW89_DBG_UNEXP = BIT(31), - }; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4295,12 +4295,12 @@ rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_d - case H2C_FUNC_MCC_SET_DURATION: - break; - default: -- rtw89_debug(rtwdev, RTW89_DBG_FW, -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, - "invalid MCC C2H RCV ACK: func %d\n", func); - return; - } - -- rtw89_debug(rtwdev, RTW89_DBG_FW, -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, - "MCC C2H RCV ACK: group %d, func %d\n", group, func); - } - -@@ -4328,12 +4328,12 @@ rtw89_mac_c2h_mcc_req_ack(struct rtw89_d - case H2C_FUNC_DEL_MCC_GROUP: - case H2C_FUNC_RESET_MCC_GROUP: - default: -- rtw89_debug(rtwdev, RTW89_DBG_FW, -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, - "invalid MCC C2H REQ ACK: func %d\n", func); - return; - } - -- rtw89_debug(rtwdev, RTW89_DBG_FW, -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, - "MCC C2H REQ ACK: group %d, func %d, return code %d\n", - group, func, retcode); - -@@ -4361,6 +4361,11 @@ rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_d - rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data); - rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data); - -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, -+ "MCC C2H TSF RPT: macid %d> %llu, macid %d> %llu\n", -+ rpt->macid_x, (u64)rpt->tsf_x_high << 32 | rpt->tsf_x_low, -+ rpt->macid_y, (u64)rpt->tsf_y_high << 32 | rpt->tsf_y_low); -+ - cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF); - rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); - } -@@ -4418,14 +4423,14 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw8 - rsp = false; - break; - default: -- rtw89_debug(rtwdev, RTW89_DBG_FW, -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, - "invalid MCC C2H STS RPT: status %d\n", status); - return; - } - -- rtw89_debug(rtwdev, RTW89_DBG_FW, -- "MCC C2H STS RPT: group %d, macid %d, status %d, tsf {%d, %d}\n", -- group, macid, status, tsf_low, tsf_high); -+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, -+ "MCC C2H STS RPT: group %d, macid %d, status %d, tsf %llu\n", -+ group, macid, status, (u64)tsf_high << 32 | tsf_low); - - if (!rsp) - return; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-136-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-136-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch deleted file mode 100644 index 8bd39cf78..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-136-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From d881d0a13c3843d213da23cde99bb73f27e53d1e Mon Sep 17 00:00:00 2001 -From: Kuan-Chung Chen -Date: Thu, 19 Jan 2023 14:46:31 +0800 -Subject: [PATCH 136/149] wifi: rtw89: disallow enter PS mode after create TDLS - link - -Buffer STA on TDLS links are not currently supported. Therefore, it -is not allowed to enter the PS mode after TDLS link is established. - -Signed-off-by: Kuan-Chung Chen -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230119064631.66971-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 10 ++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - 2 files changed, 9 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2206,8 +2206,9 @@ static bool rtw89_traffic_stats_track(st - - static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) - { -- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && -- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) -+ if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && -+ rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || -+ rtwvif->tdls_peer) - return; - - if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && -@@ -2466,9 +2467,12 @@ int rtw89_core_sta_disassoc(struct rtw89 - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) - { -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - - rtwdev->total_sta_assoc--; -+ if (sta->tdls) -+ rtwvif->tdls_peer--; - rtwsta->disassoc = true; - - return 0; -@@ -2587,6 +2591,8 @@ int rtw89_core_sta_assoc(struct rtw89_de - } - - rtwdev->total_sta_assoc++; -+ if (sta->tdls) -+ rtwvif->tdls_peer++; - rtw89_phy_ra_assoc(rtwdev, sta); - rtw89_mac_bf_assoc(rtwdev, vif, sta); - rtw89_mac_bf_monitor_calc(rtwdev, sta, false); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2452,6 +2452,7 @@ struct rtw89_vif { - bool last_a_ctrl; - bool dyn_tb_bedge_en; - u8 def_tri_idx; -+ u32 tdls_peer; - struct work_struct update_beacon_work; - struct rtw89_addr_cam_entry addr_cam; - struct rtw89_bssid_cam_entry bssid_cam; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-137-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-137-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch deleted file mode 100644 index 046eb813b..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-137-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch +++ /dev/null @@ -1,68 +0,0 @@ -From b8e8ff842b1bfe7602409fc71ee812db871ccce6 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 23 Jan 2023 14:53:56 +0800 -Subject: [PATCH 137/149] wifi: rtw89: fix potential wrong mapping for - pkt-offload - -When driver fails to send H2C to firmware for pkt-offload, we should not -update the pkt_list of driver, and need to release allocated pkt index to -avoid wrong mapping between driver and firmware. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -948,13 +948,13 @@ static int rtw89_fw_h2c_add_wow_fw_ofld( - if (!skb) - goto err; - -- list_add_tail(&info->list, &rtw_wow->pkt_list); - ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); - kfree_skb(skb); - - if (ret) -- return ret; -+ goto err; - -+ list_add_tail(&info->list, &rtw_wow->pkt_list); - *id = info->id; - return 0; - -@@ -2133,6 +2133,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_PKT_OFLD + skb_ofld->len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for h2c pkt offload\n"); -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); - return -ENOMEM; - } - skb_put(skb, H2C_LEN_PKT_OFLD); -@@ -2151,6 +2152,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); - goto fail; - } - -@@ -2684,13 +2686,14 @@ static int rtw89_append_probe_req_ie(str - goto out; - } - -- list_add_tail(&info->list, &scan_info->pkt_list[band]); - ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); - if (ret) { - kfree_skb(new); -+ kfree(info); - goto out; - } - -+ list_add_tail(&info->list, &scan_info->pkt_list[band]); - kfree_skb(new); - } - out: diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-138-wifi-rtw89-refine-packet-offload-flow.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-138-wifi-rtw89-refine-packet-offload-flow.patch deleted file mode 100644 index 040ae3e60..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-138-wifi-rtw89-refine-packet-offload-flow.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 5c12bb66b79d08b0f7aae99fc2677cab1141d4d2 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 23 Jan 2023 14:53:57 +0800 -Subject: [PATCH 138/149] wifi: rtw89: refine packet offload flow - -For upcoming firmware, driver needs to do packet offload to firmware to -ensure LPS protocol work properly, so we update current connection and -disconnect flow to maintain packet offload flow, and integrate with -current WoWLAN flow which also needs packet offload. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 17 +++--- - drivers/net/wireless/realtek/rtw89/core.h | 2 +- - drivers/net/wireless/realtek/rtw89/fw.c | 54 +++++++++++++++---- - drivers/net/wireless/realtek/rtw89/fw.h | 6 ++- - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + - drivers/net/wireless/realtek/rtw89/ser.c | 1 + - drivers/net/wireless/realtek/rtw89/wow.c | 26 ++++----- - 7 files changed, 71 insertions(+), 36 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2495,8 +2495,10 @@ int rtw89_core_sta_disconnect(struct rtw - if (sta->tdls) - rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); - -- if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) -+ if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - rtw89_vif_type_mapping(vif, false); -+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true); -+ } - - ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); - if (ret) { -@@ -2584,12 +2586,6 @@ int rtw89_core_sta_assoc(struct rtw89_de - return ret; - } - -- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id); -- if (ret) { -- rtw89_warn(rtwdev, "failed to send h2c general packet\n"); -- return ret; -- } -- - rtwdev->total_sta_assoc++; - if (sta->tdls) - rtwvif->tdls_peer++; -@@ -2608,6 +2604,12 @@ int rtw89_core_sta_assoc(struct rtw89_de - BTC_ROLE_MSTS_STA_CONN_END); - rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); - rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); -+ -+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); -+ return ret; -+ } - } - - return ret; -@@ -3132,7 +3134,6 @@ int rtw89_core_init(struct rtw89_dev *rt - continue; - INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); - } -- INIT_LIST_HEAD(&rtwdev->wow.pkt_list); - INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); - INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); - INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2461,6 +2461,7 @@ struct rtw89_vif { - struct rtw89_phy_rate_pattern rate_pattern; - struct cfg80211_scan_request *scan_req; - struct ieee80211_scan_ies *scan_ies; -+ struct list_head general_pkt_list; - }; - - enum rtw89_lv1_rcvy_step { -@@ -3724,7 +3725,6 @@ struct rtw89_wow_param { - DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); - struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; - u8 pattern_cnt; -- struct list_head pkt_list; - }; - - struct rtw89_mcc_info { ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -10,6 +10,7 @@ - #include "mac.h" - #include "phy.h" - #include "reg.h" -+#include "util.h" - - static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, - struct sk_buff *skb); -@@ -913,13 +914,12 @@ fail: - return ret; - } - --static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, -+static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - enum rtw89_fw_pkt_ofld_type type, - u8 *id) - { - struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -- struct rtw89_wow_param *rtw_wow = &rtwdev->wow; - struct rtw89_pktofld_info *info; - struct sk_buff *skb; - int ret; -@@ -954,7 +954,7 @@ static int rtw89_fw_h2c_add_wow_fw_ofld( - if (ret) - goto err; - -- list_add_tail(&info->list, &rtw_wow->pkt_list); -+ list_add_tail(&info->list, &rtwvif->general_pkt_list); - *id = info->id; - return 0; - -@@ -963,13 +963,48 @@ err: - return -ENOMEM; - } - -+void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool notify_fw) -+{ -+ struct list_head *pkt_list = &rtwvif->general_pkt_list; -+ struct rtw89_pktofld_info *info, *tmp; -+ -+ list_for_each_entry_safe(info, tmp, pkt_list, list) { -+ if (notify_fw) -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, -+ info->id); -+ list_del(&info->list); -+ kfree(info); -+ } -+} -+ -+void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw) -+{ -+ struct rtw89_vif *rtwvif; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw); -+} -+ - #define H2C_GENERAL_PKT_LEN 6 - #define H2C_GENERAL_PKT_ID_UND 0xff --int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) -+int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, u8 macid) - { -+ u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND; -+ u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND; -+ u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND; - struct sk_buff *skb; - int ret; - -+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, -+ RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); -+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, -+ RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); -+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, -+ RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null); -+ - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); -@@ -978,9 +1013,9 @@ int rtw89_fw_h2c_general_pkt(struct rtw8 - skb_put(skb, H2C_GENERAL_PKT_LEN); - SET_GENERAL_PKT_MACID(skb->data, macid); - SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); -- SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); -- SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); -- SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); -+ SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll); -+ SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null); -+ SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null); - SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -@@ -3099,8 +3134,9 @@ int rtw89_fw_h2c_keep_alive(struct rtw89 - int ret; - - if (enable) { -- ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif, -- RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id); -+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, -+ RTW89_PKT_OFLD_TYPE_NULL_DATA, -+ &pkt_id); - if (ret) - return -EPERM; - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3518,7 +3518,11 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw - int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); - void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); - void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); --int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid); -+int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ u8 macid); -+void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool notify_fw); -+void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); - int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, - bool valid, struct ieee80211_ampdu_params *params); - void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -135,6 +135,7 @@ static int rtw89_ops_add_interface(struc - rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; - rtwvif->hit_rule = 0; - ether_addr_copy(rtwvif->mac_addr, vif->addr); -+ INIT_LIST_HEAD(&rtwvif->general_pkt_list); - - ret = rtw89_mac_add_vif(rtwdev, rtwvif); - if (ret) { ---- a/drivers/net/wireless/realtek/rtw89/ser.c -+++ b/drivers/net/wireless/realtek/rtw89/ser.c -@@ -611,6 +611,7 @@ bottom: - ser_reset_mac_binding(rtwdev); - rtw89_core_stop(rtwdev); - rtw89_entity_init(rtwdev); -+ rtw89_fw_release_general_pkt_list(rtwdev, false); - INIT_LIST_HEAD(&rtwdev->rtwvifs_list); - } - ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -490,21 +490,6 @@ static int rtw89_wow_check_fw_status(str - return ret; - } - --static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev) --{ -- struct rtw89_wow_param *rtw_wow = &rtwdev->wow; -- struct list_head *pkt_list = &rtw_wow->pkt_list; -- struct rtw89_pktofld_info *info, *tmp; -- -- list_for_each_entry_safe(info, tmp, pkt_list, list) { -- rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -- rtw89_core_release_bit_map(rtwdev->pkt_offload, -- info->id); -- list_del(&info->list); -- kfree(info); -- } --} -- - static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) - { - enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; -@@ -561,6 +546,11 @@ static int rtw89_wow_swap_fw(struct rtw8 - } - - if (is_conn) { -+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); -+ return ret; -+ } - rtw89_phy_ra_assoc(rtwdev, wow_sta); - rtw89_phy_set_bss_color(rtwdev, wow_vif); - rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); -@@ -708,8 +698,6 @@ static int rtw89_wow_fw_stop(struct rtw8 - goto out; - } - -- rtw89_wow_release_pkt_list(rtwdev); -- - ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); - if (ret) { - rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); -@@ -744,6 +732,8 @@ static int rtw89_wow_enable(struct rtw89 - goto out; - } - -+ rtw89_fw_release_general_pkt_list(rtwdev, true); -+ - ret = rtw89_wow_swap_fw(rtwdev, true); - if (ret) { - rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); -@@ -789,6 +779,8 @@ static int rtw89_wow_disable(struct rtw8 - goto out; - } - -+ rtw89_fw_release_general_pkt_list(rtwdev, true); -+ - ret = rtw89_wow_swap_fw(rtwdev, false); - if (ret) { - rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-139-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-139-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch deleted file mode 100644 index 28c6221a0..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-139-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 5da5ba7e6ec4f13c2abba8de3578a3c197925243 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 23 Jan 2023 14:53:58 +0800 -Subject: [PATCH 139/149] wifi: rtw89: add use of pkt_list offload to debug - entry - -Driver can prepare pkt_list for firmware that only uses them to send out -the packets in specific situations. To understand the usage of current -status, and to check if there is leakage problem, dump bitmap and the -indices used by certain function. - -An example looks like: - - map: - ... - pkt_ofld: 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... - [SCAN 0]: 3 - [SCAN 1]: 4 - [SCAN 3]: 5 - VIF [0] xx:xx:xx:xx:xx:xx - ... - pkt_ofld[GENERAL]: 0 1 2 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 36 ++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -3354,6 +3354,31 @@ static void rtw89_dump_addr_cam(struct s - } - } - -+__printf(3, 4) -+static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list, -+ const char *fmt, ...) -+{ -+ struct rtw89_pktofld_info *info; -+ struct va_format vaf; -+ va_list args; -+ -+ if (list_empty(pkt_list)) -+ return; -+ -+ va_start(args, fmt); -+ vaf.va = &args; -+ vaf.fmt = fmt; -+ -+ seq_printf(m, "%pV", &vaf); -+ -+ va_end(args); -+ -+ list_for_each_entry(info, pkt_list, list) -+ seq_printf(m, "%d ", info->id); -+ -+ seq_puts(m, "\n"); -+} -+ - static - void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) - { -@@ -3364,6 +3389,7 @@ void rtw89_vif_ids_get_iter(void *data, - seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr); - seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); - rtw89_dump_addr_cam(m, &rtwvif->addr_cam); -+ rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: "); - } - - static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) -@@ -3402,6 +3428,7 @@ static int rtw89_debug_priv_stations_get - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - struct rtw89_cam_info *cam_info = &rtwdev->cam_info; -+ u8 idx; - - mutex_lock(&rtwdev->mutex); - -@@ -3416,6 +3443,15 @@ static int rtw89_debug_priv_stations_get - cam_info->sec_cam_map); - seq_printf(m, "\tba_cam: %*ph\n", (int)sizeof(cam_info->ba_cam_map), - cam_info->ba_cam_map); -+ seq_printf(m, "\tpkt_ofld: %*ph\n", (int)sizeof(rtwdev->pkt_offload), -+ rtwdev->pkt_offload); -+ -+ for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { -+ if (!(rtwdev->chip->support_bands & BIT(idx))) -+ continue; -+ rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx], -+ "\t\t[SCAN %u]: ", idx); -+ } - - ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, - IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-140-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-140-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch deleted file mode 100644 index d97f5367e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-140-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2e5a65f5952fe451777066e99531abc6bc684573 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 23 Jan 2023 14:53:59 +0800 -Subject: [PATCH 140/149] wifi: rtw89: 8852b: reset IDMEM mode to default value - -For different firmware type, it could use different IDMEM mode, so reset -it to default to avoid encountering error during we bisect firmware -version, like - - rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 5 - rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 3 - rtw89_8852be 0000:03:00.0: fw security fail - rtw89_8852be 0000:03:00.0: download firmware fail - rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x1E0 = 0x62 - rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x83F2 = 0x8 - rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 - rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 - rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931150 - rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 5 +++++ - drivers/net/wireless/realtek/rtw89/reg.h | 3 +++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3414,6 +3414,11 @@ int rtw89_mac_enable_cpu(struct rtw89_de - val |= B_AX_WCPU_FWDL_EN; - - rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); -+ -+ if (rtwdev->chip->chip_id == RTL8852B) -+ rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL, -+ B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2); -+ - rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK, - boot_reason); - rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -275,6 +275,9 @@ - #define B_AX_S1_LDO2PWRCUT_F BIT(23) - #define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21) - -+#define R_AX_SEC_CTRL 0x0C00 -+#define B_AX_SEC_IDMEM_SIZE_CONFIG_MASK GENMASK(17, 16) -+ - #define R_AX_FILTER_MODEL_ADDR 0x0C04 - - #define R_AX_HAXI_INIT_CFG1 0x1000 diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-141-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-141-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch deleted file mode 100644 index 57dbcd56a..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-141-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e5624482ba3e98f0c34fc72bca509c6017266253 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 23 Jan 2023 14:54:00 +0800 -Subject: [PATCH 141/149] wifi: rtw89: 8852b: don't support LPS-PG mode after - firmware 0.29.26.0 - -Due to firmware size limit of 8852b, LPS-PG mode isn't supported after -0.29.26.0, and then we have more space to support other features, such as -P2P-PS, hardware scan and so on. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 ++++-- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 3 files changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1764,7 +1764,8 @@ static enum rtw89_ps_mode rtw89_update_p - RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw)) - return RTW89_PS_MODE_NONE; - -- if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) -+ if ((chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) && -+ !RTW89_CHK_FW_FEATURE(NO_LPS_PG, &rtwdev->fw)) - return RTW89_PS_MODE_PWR_GATED; - - if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) -@@ -3160,7 +3161,6 @@ int rtw89_core_init(struct rtw89_dev *rt - rtw89_core_ppdu_sts_init(rtwdev); - rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); - -- rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); - rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; - - INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); -@@ -3316,6 +3316,8 @@ int rtw89_chip_info_setup(struct rtw89_d - if (ret) - return ret; - -+ rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); -+ - return 0; - } - EXPORT_SYMBOL(rtw89_chip_info_setup); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3023,6 +3023,7 @@ enum rtw89_fw_feature { - RTW89_FW_FEATURE_CRASH_TRIGGER, - RTW89_FW_FEATURE_PACKET_DROP, - RTW89_FW_FEATURE_NO_DEEP_PS, -+ RTW89_FW_FEATURE_NO_LPS_PG, - }; - - struct rtw89_fw_suit { ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -255,6 +255,7 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), -+ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-142-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-142-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch deleted file mode 100644 index e0a251c6e..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-142-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 7410bd727584ea9b3e1050c56fdf60d883398956 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 23 Jan 2023 14:54:01 +0800 -Subject: [PATCH 142/149] wifi: rtw89: 8852b: try to use NORMAL_CE type - firmware first - -New firmware type NORMAL_CE is introduced to support P2P-PS and hardware -scan, but no LPS-PG mode. After this patch, old firmware with NORMAL type -can still work well. - -The use of this new type is the same as before, so we add new type to -avoid taking wrong firmware. Then, driver log can also give clear -information about this change: - - rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 5 - rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 3 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230123065401.14174-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 2 ++ - drivers/net/wireless/realtek/rtw89/fw.c | 22 ++++++++++++++----- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 5 files changed, 21 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2848,6 +2848,7 @@ struct rtw89_chip_info { - enum rtw89_core_chip_id chip_id; - const struct rtw89_chip_ops *ops; - const char *fw_name; -+ bool try_ce_fw; - u32 fifo_size; - u32 dle_scc_rsvd_size; - u16 max_amsdu_limit; -@@ -3014,6 +3015,7 @@ static inline void rtw89_init_wait(struc - enum rtw89_fw_type { - RTW89_FW_NORMAL = 1, - RTW89_FW_WOWLAN = 3, -+ RTW89_FW_NORMAL_CE = 5, - }; - - enum rtw89_fw_feature { ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -152,7 +152,7 @@ static int rtw89_fw_hdr_parser(struct rt - - static - int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, -- struct rtw89_fw_suit *fw_suit) -+ struct rtw89_fw_suit *fw_suit, bool nowarn) - { - struct rtw89_fw_info *fw_info = &rtwdev->fw; - const u8 *mfw = fw_info->firmware->data; -@@ -183,7 +183,8 @@ int rtw89_mfw_recognize(struct rtw89_dev - return 0; - } - -- rtw89_err(rtwdev, "no suitable firmware found\n"); -+ if (!nowarn) -+ rtw89_err(rtwdev, "no suitable firmware found\n"); - return -ENOENT; - } - -@@ -211,12 +212,13 @@ static void rtw89_fw_update_ver(struct r - } - - static --int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) -+int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, -+ bool nowarn) - { - struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); - int ret; - -- ret = rtw89_mfw_recognize(rtwdev, type, fw_suit); -+ ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); - if (ret) - return ret; - -@@ -343,14 +345,22 @@ out: - - int rtw89_fw_recognize(struct rtw89_dev *rtwdev) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; - int ret; - -- ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL); -+ if (chip->try_ce_fw) { -+ ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); -+ if (!ret) -+ goto normal_done; -+ } -+ -+ ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); - if (ret) - return ret; - -+normal_done: - /* It still works if wowlan firmware isn't existing. */ -- __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN); -+ __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); - - rtw89_fw_recognize_features(rtwdev); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2055,6 +2055,7 @@ const struct rtw89_chip_info rtw8852a_ch - .chip_id = RTL8852A, - .ops = &rtw8852a_chip_ops, - .fw_name = "rtw89/rtw8852a_fw.bin", -+ .try_ce_fw = false, - .fifo_size = 458752, - .dle_scc_rsvd_size = 0, - .max_amsdu_limit = 3500, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2430,6 +2430,7 @@ const struct rtw89_chip_info rtw8852b_ch - .chip_id = RTL8852B, - .ops = &rtw8852b_chip_ops, - .fw_name = "rtw89/rtw8852b_fw.bin", -+ .try_ce_fw = true, - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, - .max_amsdu_limit = 3500, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2857,6 +2857,7 @@ const struct rtw89_chip_info rtw8852c_ch - .chip_id = RTL8852C, - .ops = &rtw8852c_chip_ops, - .fw_name = "rtw89/rtw8852c_fw.bin", -+ .try_ce_fw = false, - .fifo_size = 458752, - .dle_scc_rsvd_size = 0, - .max_amsdu_limit = 8000, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-143-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-143-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch deleted file mode 100644 index 9183ec850..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-143-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3712888e3dba5df2b4f3fb3ba87e20bac6afc7c0 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Thu, 26 Jan 2023 19:27:15 +0800 -Subject: [PATCH 143/149] wifi: rtw89: 8852be: enable CLKREQ of PCI capability - -Enable CLKREQ to reduce power consumption for 8852BE. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230126112715.5811-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/pci.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -3398,7 +3398,7 @@ static void rtw89_pci_clkreq_set(struct - if (ret) - rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); - -- if (chip_id == RTL8852A) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B) { - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, - RTW89_PCIE_L1_CTRL, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-144-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-144-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch deleted file mode 100644 index 528f3db18..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-144-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 764f07f4565da0c0f94f24d18f9d6f5ddb39ccd8 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 1 Feb 2023 11:20:57 +0800 -Subject: [PATCH 144/149] wifi: rtw89: use passed channel in - set_tx_shape_dfir() - -In path of setting channel and setting TX power, the rtw89_chan instance -to be used is controlled by top and passed down. The set_tx_shape_dfir() -is in path of setting TX power, so it should use the passed rtw89_chan -instead of querying it itself. Otherwise, it might encounter mismatch -between parameters if multi-channel. - -For example, -rtw89_8852ce 0000:04:00.0: set tx shape dfir by unknown ch: 155 on 2GHz - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230201032057.7349-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 4 ++-- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1618,6 +1618,7 @@ static void rtw8852b_set_txpwr_ref(struc - } - - static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, - u8 tx_shape_idx, - enum rtw89_phy_idx phy_idx) - { -@@ -1637,7 +1638,6 @@ static void rtw8852b_bb_set_tx_shape_dfi - __DECL_DFIR_PARAM(sharp_14, - 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, - 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); -- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - u8 ch = chan->channel; - const u32 *param; - u32 addr; -@@ -1678,7 +1678,7 @@ static void rtw8852b_set_tx_shape(struct - u8 tx_shape_ofdm = rtw89_8852b_tx_shape[band][RTW89_RS_OFDM][regd]; - - if (band == RTW89_BAND_2G) -- rtw8852b_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); -+ rtw8852b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); - - rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, - tx_shape_ofdm); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -1968,6 +1968,7 @@ static void rtw8852c_set_txpwr_ref(struc - } - - static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, - u8 tx_shape_idx, - enum rtw89_phy_idx phy_idx) - { -@@ -1991,7 +1992,6 @@ static void rtw8852c_bb_set_tx_shape_dfi - __DECL_DFIR_ADDR(filter, - 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0, - 0x45C4, 0x45C8); -- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - u8 ch = chan->channel; - const u32 *param; - int i; -@@ -2032,7 +2032,7 @@ static void rtw8852c_set_tx_shape(struct - u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd]; - - if (band == RTW89_BAND_2G) -- rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); -+ rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); - - rtw89_phy_tssi_ctrl_set_bandedge_cfg(rtwdev, - (enum rtw89_mac_idx)phy_idx, diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-145-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-145-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch deleted file mode 100644 index f37b033d1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-145-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5466ee9a7c63e18d3daea0bf80152944648218d2 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 3 Feb 2023 14:49:07 +0800 -Subject: [PATCH 145/149] wifi: rtw89: 8852b: correct register mask name of TX - power offset - -For a packet with 1SS rate, it can also transmit via 2 antenna, called -2T mode. For 2T TX power offset, mask should be 2T as well. Fortunately, -the mask of 2T and 1T are the same, so it can still work well without -this fix. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230203064907.8046-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1720,7 +1720,7 @@ void rtw8852b_set_txpwr_ul_tb_offset(str - - pw_ofst = max_t(s8, pw_ofst - 3, -16); - reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); -- rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); -+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); - } - - static int diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-146-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-146-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch deleted file mode 100644 index 2f06095f7..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-146-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch +++ /dev/null @@ -1,72 +0,0 @@ -From ddf9a2ead1676db46abe8acca3f689fd572a44d1 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 3 Feb 2023 14:51:57 +0800 -Subject: [PATCH 146/149] wifi: rtw89: phy: set TX power according to RF path - number by chip - -Previously, all supported chips had two RF paths. Therefore, these -codes used static number for TX power setting. Now, we are planning -to support a new chip which has only one RF path. So, we refine the -setting codes to refer to chip's RF path number at runtime. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230203065157.8227-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2042,6 +2042,7 @@ void rtw89_phy_set_txpwr_byrate(struct r - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -+ u8 max_nss_num = rtwdev->chip->rf_path_num; - static const u8 rs[] = { - RTW89_RS_CCK, - RTW89_RS_OFDM, -@@ -2064,7 +2065,7 @@ void rtw89_phy_set_txpwr_byrate(struct r - BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); - - addr = R_AX_PWR_BY_RATE; -- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { -+ for (cur.nss = 0; cur.nss < max_nss_num; cur.nss++) { - for (i = 0; i < ARRAY_SIZE(rs); i++) { - if (cur.nss >= rtw89_rs_nss_max[rs[i]]) - continue; -@@ -2127,6 +2128,7 @@ void rtw89_phy_set_txpwr_limit(struct rt - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -+ u8 max_ntx_num = rtwdev->chip->rf_path_num; - struct rtw89_txpwr_limit lmt; - u8 ch = chan->channel; - u8 bw = chan->band_width; -@@ -2141,7 +2143,7 @@ void rtw89_phy_set_txpwr_limit(struct rt - RTW89_TXPWR_LMT_PAGE_SIZE); - - addr = R_AX_PWR_LMT; -- for (i = 0; i < RTW89_NTX_NUM; i++) { -+ for (i = 0; i < max_ntx_num; i++) { - rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt, i); - - ptr = (s8 *)&lmt; -@@ -2162,6 +2164,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -+ u8 max_ntx_num = rtwdev->chip->rf_path_num; - struct rtw89_txpwr_limit_ru lmt_ru; - u8 ch = chan->channel; - u8 bw = chan->band_width; -@@ -2176,7 +2179,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct - RTW89_TXPWR_LMT_RU_PAGE_SIZE); - - addr = R_AX_PWR_RU_LMT; -- for (i = 0; i < RTW89_NTX_NUM; i++) { -+ for (i = 0; i < max_ntx_num; i++) { - rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru, i); - - ptr = (s8 *)&lmt_ru; diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-147-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-147-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch deleted file mode 100644 index c9fbe6a84..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-147-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 210871887208d1098d65b9bb597e7f9aa1c66900 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 13 Feb 2023 17:13:28 +0800 -Subject: [PATCH 147/149] wifi: rtw89: use readable return 0 in - rtw89_mac_cfg_ppdu_status() - -For normal (successful) flow, it must return 0. The original code uses -'return ret', and then we need to backward reference to initial value to -know 'ret = 0'. Changing them to 'return 0', because it will be more -readable and intuitive. This patch doesn't change logic at all. - -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Link: https://lore.kernel.org/r/202302101023.ctlih5q0-lkp@intel.com/ -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230213091328.25481-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4554,7 +4554,7 @@ EXPORT_SYMBOL(rtw89_mac_get_txpwr_cr); - int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) - { - u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx); -- int ret = 0; -+ int ret; - - ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); - if (ret) -@@ -4562,7 +4562,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw - - if (!enable) { - rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); -- return ret; -+ return 0; - } - - rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | -@@ -4572,7 +4572,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw - rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, - RTW89_PRPT_DEST_HOST); - -- return ret; -+ return 0; - } - EXPORT_SYMBOL(rtw89_mac_cfg_ppdu_status); - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-148-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-148-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch deleted file mode 100644 index 6a515c231..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-148-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ce1ba4d782d94fc8ed9116c774e2e5885626836b Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Tue, 14 Feb 2023 19:43:14 +0800 -Subject: [PATCH 148/149] wifi: rtw89: move H2C of del_pkt_offload before - polling FW status ready - -The H2C of del_pkt_offload must be called before polling FW status -ready, otherwise the following downloading normal FW will fail. - -Fixes: 5c12bb66b79d ("wifi: rtw89: refine packet offload flow") -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230214114314.5268-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/wow.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -710,6 +710,8 @@ static int rtw89_wow_fw_stop(struct rtw8 - goto out; - } - -+ rtw89_fw_release_general_pkt_list(rtwdev, true); -+ - ret = rtw89_wow_check_fw_status(rtwdev, false); - if (ret) { - rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); -@@ -779,8 +781,6 @@ static int rtw89_wow_disable(struct rtw8 - goto out; - } - -- rtw89_fw_release_general_pkt_list(rtwdev, true); -- - ret = rtw89_wow_swap_fw(rtwdev, false); - if (ret) { - rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-149-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-149-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch deleted file mode 100644 index 5836ff7a1..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-149-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0731d0b664f26f54b6293421af54da15b9eb1c8c Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Thu, 16 Feb 2023 16:28:07 +0800 -Subject: [PATCH 149/149] wifi: rtw89: fix AP mode authentication transmission - failed - -For some ICs, packets can't be sent correctly without initializing -CMAC table first. Previous flow do this initialization after -associated, results in authentication response fails to transmit. -Move the initialization up front to a proper place to solve this. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230216082807.22285-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 47 +++++++++++++---------- - 1 file changed, 26 insertions(+), 21 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2435,6 +2435,7 @@ int rtw89_core_sta_add(struct rtw89_dev - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - int i; -+ int ret; - - rtwsta->rtwdev = rtwdev; - rtwsta->rtwvif = rtwvif; -@@ -2459,6 +2460,21 @@ int rtw89_core_sta_add(struct rtw89_dev - RTW89_MAX_MAC_ID_NUM); - if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) - return -ENOSPC; -+ -+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false); -+ if (ret) { -+ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); -+ rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); -+ return ret; -+ } -+ -+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, -+ RTW89_ROLE_CREATE); -+ if (ret) { -+ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); -+ rtw89_warn(rtwdev, "failed to send h2c role info\n"); -+ return ret; -+ } - } - - return 0; -@@ -2513,14 +2529,6 @@ int rtw89_core_sta_disconnect(struct rtw - return ret; - } - -- if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { -- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_REMOVE); -- if (ret) { -- rtw89_warn(rtwdev, "failed to send h2c role info\n"); -- return ret; -- } -- } -- - /* update cam aid mac_id net_type */ - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); - if (ret) { -@@ -2541,18 +2549,6 @@ int rtw89_core_sta_assoc(struct rtw89_de - int ret; - - if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { -- ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false); -- if (ret) { -- rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); -- return ret; -- } -- -- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_CREATE); -- if (ret) { -- rtw89_warn(rtwdev, "failed to send h2c role info\n"); -- return ret; -- } -- - if (sta->tdls) { - ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, sta->addr); - if (ret) { -@@ -2622,13 +2618,22 @@ int rtw89_core_sta_remove(struct rtw89_d - { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ int ret; - - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, - BTC_ROLE_MSTS_STA_DIS_CONN); -- else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) -+ else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); - -+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, -+ RTW89_ROLE_REMOVE); -+ if (ret) { -+ rtw89_warn(rtwdev, "failed to send h2c role info\n"); -+ return ret; -+ } -+ } -+ - return 0; - } - diff --git a/package/kernel/mac80211/patches/rtl/201-v6.3-150-add-realtek-rtl8852be.patch b/package/kernel/mac80211/patches/rtl/201-v6.3-150-add-realtek-rtl8852be.patch deleted file mode 100644 index de49ee0c4..000000000 --- a/package/kernel/mac80211/patches/rtl/201-v6.3-150-add-realtek-rtl8852be.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- a/Kconfig.local -+++ b/Kconfig.local -@@ -1192,12 +1192,18 @@ config BACKPORTED_RTW89_PCI - config BACKPORTED_RTW89_8852A - tristate - default RTW89_8852A -+config BACKPORTED_RTW89_8852B -+ tristate -+ default RTW89_8852B - config BACKPORTED_RTW89_8852C - tristate - default RTW89_8852C - config BACKPORTED_RTW89_8852AE - tristate - default RTW89_8852AE -+config BACKPORTED_RTW89_8852BE -+ tristate -+ default RTW89_8852BE - config BACKPORTED_RTW89_8852CE - tristate - default RTW89_8852CE ---- a/defconfigs/wifi -+++ b/defconfigs/wifi -@@ -129,6 +129,7 @@ CPTCFG_RTW88_8822CE=m - CPTCFG_RTW88_8822CU=m - CPTCFG_RTW88=m - CPTCFG_RTW89_8852AE=m -+CPTCFG_RTW89_8852BE=m - CPTCFG_RTW89_8852CE=m - CPTCFG_RTW89=m - CPTCFG_SSB=m ---- a/local-symbols -+++ b/local-symbols -@@ -394,8 +394,10 @@ RTW89= - RTW89_CORE= - RTW89_PCI= - RTW89_8852A= -+RTW89_8852B= - RTW89_8852C= - RTW89_8852AE= -+RTW89_8852BE= - RTW89_8852CE= - RTW89_DEBUG= - RTW89_DEBUGMSG= diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-001-wifi-rtw89-add-RNR-support-for-6-GHz-scan.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-001-wifi-rtw89-add-RNR-support-for-6-GHz-scan.patch deleted file mode 100644 index 43121a4b3..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-001-wifi-rtw89-add-RNR-support-for-6-GHz-scan.patch +++ /dev/null @@ -1,305 +0,0 @@ -From c6aa9a9c47252ac7b07ed6d10459027e2f2a2de0 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Fri, 17 Feb 2023 20:00:07 +0800 -Subject: [PATCH 001/136] wifi: rtw89: add RNR support for 6 GHz scan - -Since 6 GHz band has around 60 channels and more strict rules for -active probing. Reduced neighbor report can be used to reduce the -channels we scan and get specific target BSS info to probe for. - -Declare flag WIPHY_FLAG_SPLIT_SCAN_6GHZ so the scan request could be -divided into two portions: legacy bands and 6 GHz bands. So RNR -information from legacy bands could later be used when 6 GHz scan. - -When the scan flag NL80211_SCAN_FLAG_COLOCATED_6GHZ is set, cfg80211 -will pass down a reduced channel set which contains PSCs and non-PSC -with RNR info received in the 2 GHz/5 GHz band. This reduces the -scan duration by allowing us to only scan for channels in which APs -are currently operating. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230217120007.8835-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 35 +++++- - drivers/net/wireless/realtek/rtw89/fw.c | 136 +++++++++++++++++++--- - drivers/net/wireless/realtek/rtw89/fw.h | 7 ++ - 3 files changed, 162 insertions(+), 16 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1400,6 +1400,34 @@ static void rtw89_stats_trigger_frame(st - } - } - -+static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); -+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; -+ struct list_head *pkt_list = rtwdev->scan_info.pkt_list; -+ struct rtw89_pktofld_info *info; -+ const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; -+ -+ if (rx_status->band != NL80211_BAND_6GHZ) -+ return; -+ -+ ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, ies, skb->len); -+ -+ list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { -+ if (ether_addr_equal(info->bssid, mgmt->bssid)) { -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ continue; -+ } -+ -+ if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) -+ continue; -+ -+ if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ } -+} -+ - static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) - { -@@ -1412,6 +1440,11 @@ static void rtw89_vif_rx_stats_iter(void - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - const u8 *bssid = iter_data->bssid; - -+ if (rtwdev->scanning && -+ (ieee80211_is_beacon(hdr->frame_control) || -+ ieee80211_is_probe_resp(hdr->frame_control))) -+ rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb); -+ - if (!vif->bss_conf.bssid) - return; - -@@ -3372,7 +3405,7 @@ static int rtw89_core_register_hw(struct - - hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | - WIPHY_FLAG_TDLS_EXTERNAL_SETUP | -- WIPHY_FLAG_AP_UAPSD; -+ WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_SPLIT_SCAN_6GHZ; - hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; - - hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2702,9 +2702,29 @@ static void rtw89_release_pkt_list(struc - } - } - -+static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, -+ struct rtw89_pktofld_info *info, -+ enum nl80211_band band, u8 ssid_idx) -+{ -+ struct cfg80211_scan_request *req = rtwvif->scan_req; -+ -+ if (band != NL80211_BAND_6GHZ) -+ return false; -+ -+ if (req->ssids[ssid_idx].ssid_len) { -+ memcpy(info->ssid, req->ssids[ssid_idx].ssid, -+ req->ssids[ssid_idx].ssid_len); -+ info->ssid_len = req->ssids[ssid_idx].ssid_len; -+ return false; -+ } else { -+ return true; -+ } -+} -+ - static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, -- struct sk_buff *skb) -+ struct sk_buff *skb, u8 ssid_idx) - { - struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct ieee80211_scan_ies *ies = rtwvif->scan_ies; -@@ -2732,6 +2752,13 @@ static int rtw89_append_probe_req_ie(str - goto out; - } - -+ if (rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band, -+ ssid_idx)) { -+ kfree_skb(new); -+ kfree(info); -+ goto out; -+ } -+ - ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new); - if (ret) { - kfree_skb(new); -@@ -2762,7 +2789,7 @@ static int rtw89_hw_scan_update_probe_re - if (!skb) - return -ENOMEM; - -- ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb); -+ ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i); - kfree_skb(skb); - - if (ret) -@@ -2772,6 +2799,77 @@ static int rtw89_hw_scan_update_probe_re - return 0; - } - -+static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, -+ struct cfg80211_scan_request *req, -+ struct rtw89_mac_chinfo *ch_info) -+{ -+ struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; -+ struct list_head *pkt_list = rtwdev->scan_info.pkt_list; -+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); -+ struct ieee80211_scan_ies *ies = rtwvif->scan_ies; -+ struct cfg80211_scan_6ghz_params *params; -+ struct rtw89_pktofld_info *info, *tmp; -+ struct ieee80211_hdr *hdr; -+ struct sk_buff *skb; -+ bool found; -+ int ret = 0; -+ u8 i; -+ -+ if (!req->n_6ghz_params) -+ return 0; -+ -+ for (i = 0; i < req->n_6ghz_params; i++) { -+ params = &req->scan_6ghz_params[i]; -+ -+ if (req->channels[params->channel_idx]->hw_value != -+ ch_info->pri_ch) -+ continue; -+ -+ found = false; -+ list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { -+ if (ether_addr_equal(tmp->bssid, params->bssid)) { -+ found = true; -+ break; -+ } -+ } -+ if (found) -+ continue; -+ -+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, -+ NULL, 0, req->ie_len); -+ skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); -+ skb_put_data(skb, ies->common_ies, ies->common_ie_len); -+ hdr = (struct ieee80211_hdr *)skb->data; -+ ether_addr_copy(hdr->addr3, params->bssid); -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ ret = -ENOMEM; -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); -+ if (ret) { -+ kfree_skb(skb); -+ kfree(info); -+ goto out; -+ } -+ -+ ether_addr_copy(info->bssid, params->bssid); -+ info->channel_6ghz = req->channels[params->channel_idx]->hw_value; -+ list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); -+ -+ ch_info->tx_pkt = true; -+ ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; -+ -+ kfree_skb(skb); -+ } -+ -+out: -+ return ret; -+} -+ - static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, - int ssid_num, - struct rtw89_mac_chinfo *ch_info) -@@ -2782,6 +2880,7 @@ static void rtw89_hw_scan_add_chan(struc - struct cfg80211_scan_request *req = rtwvif->scan_req; - struct rtw89_pktofld_info *info; - u8 band, probe_count = 0; -+ int ret; - - ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; - ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; -@@ -2793,25 +2892,31 @@ static void rtw89_hw_scan_add_chan(struc - ch_info->pause_data = false; - ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; - -+ if (ch_info->ch_band == RTW89_BAND_6G) { -+ if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || -+ !ch_info->is_psc) { -+ ch_info->tx_pkt = false; -+ if (!req->duration_mandatory) -+ ch_info->period -= RTW89_DWELL_TIME_6G; -+ } -+ } -+ -+ ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info); -+ if (ret) -+ rtw89_warn(rtwdev, "RNR fails: %d\n", ret); -+ - if (ssid_num) { -- ch_info->num_pkt = ssid_num; - band = rtw89_hw_to_nl80211_band(ch_info->ch_band); - - list_for_each_entry(info, &scan_info->pkt_list[band], list) { -- ch_info->pkt_id[probe_count] = info->id; -- if (++probe_count >= ssid_num) -+ if (info->channel_6ghz && -+ ch_info->pri_ch != info->channel_6ghz) -+ continue; -+ ch_info->pkt_id[probe_count++] = info->id; -+ if (probe_count >= RTW89_SCANOFLD_MAX_SSID) - break; - } -- if (probe_count != ssid_num) -- rtw89_err(rtwdev, "SSID num differs from list len\n"); -- } -- -- if (ch_info->ch_band == RTW89_BAND_6G) { -- if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { -- ch_info->tx_pkt = false; -- if (!req->duration_mandatory) -- ch_info->period -= RTW89_DWELL_TIME_6G; -- } -+ ch_info->num_pkt = probe_count; - } - - switch (chan_type) { -@@ -2872,6 +2977,7 @@ static int rtw89_hw_scan_add_chan_list(s - ch_info->central_ch = channel->hw_value; - ch_info->pri_ch = channel->hw_value; - ch_info->rand_seq_num = random_seq; -+ ch_info->is_psc = cfg80211_channel_is_psc(channel); - - if (channel->flags & - (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR)) ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -237,6 +237,7 @@ struct rtw89_mac_chinfo { - u16 tx_pwr_idx; - u8 rsvd1; - struct list_head list; -+ bool is_psc; - }; - - struct rtw89_scan_option { -@@ -247,6 +248,12 @@ struct rtw89_scan_option { - struct rtw89_pktofld_info { - struct list_head list; - u8 id; -+ -+ /* Below fields are for 6 GHz RNR use only */ -+ u8 ssid[IEEE80211_MAX_SSID_LEN]; -+ u8 ssid_len; -+ u8 bssid[ETH_ALEN]; -+ u16 channel_6ghz; - }; - - static inline void RTW89_SET_FWCMD_RA_IS_DIS(void *cmd, u32 val) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-002-wifi-rtw89-add-tx_wake-notify-for-8852B.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-002-wifi-rtw89-add-tx_wake-notify-for-8852B.patch deleted file mode 100644 index 81441d8b3..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-002-wifi-rtw89-add-tx_wake-notify-for-8852B.patch +++ /dev/null @@ -1,27 +0,0 @@ -From aa4e055945462e645224795e174c25c82f6002ac Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 20 Feb 2023 15:01:57 +0800 -Subject: [PATCH 002/136] wifi: rtw89: add tx_wake notify for 8852B - -8852B has the same issue: management frames get stuck when wifi -chip enters low ps mode, so we alse add notify wake function to -trigger wifi chip wake before forwarding management frames. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -258,6 +258,7 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), -+ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-003-wifi-rtw89-fw-configure-CRASH_TRIGGER-feature-for-88.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-003-wifi-rtw89-fw-configure-CRASH_TRIGGER-feature-for-88.patch deleted file mode 100644 index df0c258fd..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-003-wifi-rtw89-fw-configure-CRASH_TRIGGER-feature-for-88.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 31c416e69dbf416583d0d8245d91e7e82b7846b1 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 20 Feb 2023 15:01:58 +0800 -Subject: [PATCH 003/136] wifi: rtw89: fw: configure CRASH_TRIGGER feature for - 8852B - -RTL8852B firmware supports CRASH_TRIGGER feature from v0.29.29.0. -After this is configured, debugfs fw_crash can support type 1 on -RTL8852B to trigger firmware crash and verify L2 recovery through -simulation. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -259,6 +259,7 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), -+ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-004-wifi-rtw89-adjust-channel-encoding-to-common-functio.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-004-wifi-rtw89-adjust-channel-encoding-to-common-functio.patch deleted file mode 100644 index f4ecb6bb9..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-004-wifi-rtw89-adjust-channel-encoding-to-common-functio.patch +++ /dev/null @@ -1,207 +0,0 @@ -From bb9040b3ff970529ceaa20b064c113d5ffd5520f Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Mon, 20 Feb 2023 15:01:59 +0800 -Subject: [PATCH 004/136] wifi: rtw89: adjust channel encoding to common - function - -Since the range of channel table is identical among ICs. Make channel -encode/decode function common and not IC dependent. So all ICs with -matching firmware that needs this kind of coding can use it directly. -This patch doesn't change logic at all. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 72 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/phy.h | 3 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 74 +------------------ - 3 files changed, 77 insertions(+), 72 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -4294,3 +4294,75 @@ void rtw89_phy_tssi_ctrl_set_bandedge_cf - data[RTW89_TSSI_SBW20]); - } - EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg); -+ -+static -+const u8 rtw89_ch_base_table[16] = {1, 0xff, -+ 36, 100, 132, 149, 0xff, -+ 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; -+#define RTW89_CH_BASE_IDX_2G 0 -+#define RTW89_CH_BASE_IDX_5G_FIRST 2 -+#define RTW89_CH_BASE_IDX_5G_LAST 5 -+#define RTW89_CH_BASE_IDX_6G_FIRST 7 -+#define RTW89_CH_BASE_IDX_6G_LAST 14 -+ -+#define RTW89_CH_BASE_IDX_MASK GENMASK(7, 4) -+#define RTW89_CH_OFFSET_MASK GENMASK(3, 0) -+ -+u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) -+{ -+ u8 chan_idx; -+ u8 last, first; -+ u8 idx; -+ -+ switch (band) { -+ case RTW89_BAND_2G: -+ chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, RTW89_CH_BASE_IDX_2G) | -+ FIELD_PREP(RTW89_CH_OFFSET_MASK, central_ch); -+ return chan_idx; -+ case RTW89_BAND_5G: -+ first = RTW89_CH_BASE_IDX_5G_FIRST; -+ last = RTW89_CH_BASE_IDX_5G_LAST; -+ break; -+ case RTW89_BAND_6G: -+ first = RTW89_CH_BASE_IDX_6G_FIRST; -+ last = RTW89_CH_BASE_IDX_6G_LAST; -+ break; -+ default: -+ rtw89_warn(rtwdev, "Unsupported band %d\n", band); -+ return 0; -+ } -+ -+ for (idx = last; idx >= first; idx--) -+ if (central_ch >= rtw89_ch_base_table[idx]) -+ break; -+ -+ if (idx < first) { -+ rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); -+ return 0; -+ } -+ -+ chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, idx) | -+ FIELD_PREP(RTW89_CH_OFFSET_MASK, -+ (central_ch - rtw89_ch_base_table[idx]) >> 1); -+ return chan_idx; -+} -+EXPORT_SYMBOL(rtw89_encode_chan_idx); -+ -+void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, -+ u8 *ch, enum nl80211_band *band) -+{ -+ u8 idx, offset; -+ -+ idx = FIELD_GET(RTW89_CH_BASE_IDX_MASK, chan_idx); -+ offset = FIELD_GET(RTW89_CH_OFFSET_MASK, chan_idx); -+ -+ if (idx == RTW89_CH_BASE_IDX_2G) { -+ *band = NL80211_BAND_2GHZ; -+ *ch = offset; -+ return; -+ } -+ -+ *band = idx <= RTW89_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; -+ *ch = rtw89_ch_base_table[idx] + (offset << 1); -+} -+EXPORT_SYMBOL(rtw89_decode_chan_idx); ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -555,5 +555,8 @@ void rtw89_phy_tssi_ctrl_set_bandedge_cf - enum rtw89_tssi_bandedge_cfg bandedge_cfg); - void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); -+u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); -+void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, -+ u8 *ch, enum nl80211_band *band); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -852,76 +852,6 @@ static void rtw8852c_set_gain_error(stru - } - } - --static --const u8 rtw8852c_ch_base_table[16] = {1, 0xff, -- 36, 100, 132, 149, 0xff, -- 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; --#define RTW8852C_CH_BASE_IDX_2G 0 --#define RTW8852C_CH_BASE_IDX_5G_FIRST 2 --#define RTW8852C_CH_BASE_IDX_5G_LAST 5 --#define RTW8852C_CH_BASE_IDX_6G_FIRST 7 --#define RTW8852C_CH_BASE_IDX_6G_LAST 14 -- --#define RTW8852C_CH_BASE_IDX_MASK GENMASK(7, 4) --#define RTW8852C_CH_OFFSET_MASK GENMASK(3, 0) -- --static u8 rtw8852c_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) --{ -- u8 chan_idx; -- u8 last, first; -- u8 idx; -- -- switch (band) { -- case RTW89_BAND_2G: -- chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, RTW8852C_CH_BASE_IDX_2G) | -- FIELD_PREP(RTW8852C_CH_OFFSET_MASK, central_ch); -- return chan_idx; -- case RTW89_BAND_5G: -- first = RTW8852C_CH_BASE_IDX_5G_FIRST; -- last = RTW8852C_CH_BASE_IDX_5G_LAST; -- break; -- case RTW89_BAND_6G: -- first = RTW8852C_CH_BASE_IDX_6G_FIRST; -- last = RTW8852C_CH_BASE_IDX_6G_LAST; -- break; -- default: -- rtw89_warn(rtwdev, "Unsupported band %d\n", band); -- return 0; -- } -- -- for (idx = last; idx >= first; idx--) -- if (central_ch >= rtw8852c_ch_base_table[idx]) -- break; -- -- if (idx < first) { -- rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); -- return 0; -- } -- -- chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, idx) | -- FIELD_PREP(RTW8852C_CH_OFFSET_MASK, -- (central_ch - rtw8852c_ch_base_table[idx]) >> 1); -- return chan_idx; --} -- --static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, -- u8 *ch, enum nl80211_band *band) --{ -- u8 idx, offset; -- -- idx = FIELD_GET(RTW8852C_CH_BASE_IDX_MASK, chan_idx); -- offset = FIELD_GET(RTW8852C_CH_OFFSET_MASK, chan_idx); -- -- if (idx == RTW8852C_CH_BASE_IDX_2G) { -- *band = NL80211_BAND_2GHZ; -- *ch = offset; -- return; -- } -- -- *band = idx <= RTW8852C_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; -- *ch = rtw8852c_ch_base_table[idx] + (offset << 1); --} -- - static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx, -@@ -1084,7 +1014,7 @@ static void rtw8852c_ctrl_ch(struct rtw8 - } - } - -- chan_idx = rtw8852c_encode_chan_idx(rtwdev, chan->primary_channel, band); -+ chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); - rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx); - } - -@@ -2730,7 +2660,7 @@ static void rtw8852c_fill_freq_with_ppdu - if (chan_idx == 0) - return; - -- rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band); -+ rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band); - status->freq = ieee80211_channel_to_frequency(ch, band); - status->band = band; - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-005-wifi-rtw89-8852b-add-channel-encoding-for-hw_scan.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-005-wifi-rtw89-8852b-add-channel-encoding-for-hw_scan.patch deleted file mode 100644 index 039aa1234..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-005-wifi-rtw89-8852b-add-channel-encoding-for-hw_scan.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 4f24d7aa575a3c01192faa7f4fb6a91c54f4ef47 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Mon, 20 Feb 2023 15:02:00 +0800 -Subject: [PATCH 005/136] wifi: rtw89: 8852b: add channel encoding for hw_scan - -To obtain correct packet frequency for hw_scan, 52b needs to decode -the channel index obtained from hardware. Change the driver related -set channel part as well to make driver/firmware compatible. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1422,6 +1422,7 @@ static void rtw8852b_set_channel_bb(stru - { - bool cck_en = chan->channel <= 14; - u8 pri_ch_idx = chan->pri_ch_idx; -+ u8 band = chan->band_type, chan_idx; - - if (cck_en) - rtw8852b_ctrl_sco_cck(rtwdev, chan->primary_channel); -@@ -1444,8 +1445,8 @@ static void rtw8852b_set_channel_bb(stru - B_BT_DYN_DC_EST_EN_MSK, 0x0); - rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); - } -- rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, -- chan->primary_channel); -+ chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); -+ rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx); - rtw8852b_5m_mask(rtwdev, chan, phy_idx); - rtw8852b_bb_set_pop(rtwdev); - rtw8852b_bb_reset_all(rtwdev, phy_idx); -@@ -2299,13 +2300,14 @@ static void rtw8852b_fill_freq_with_ppdu - struct ieee80211_rx_status *status) - { - u16 chan = phy_ppdu->chan_idx; -- u8 band; -+ enum nl80211_band band; -+ u8 ch; - - if (chan == 0) - return; - -- band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; -- status->freq = ieee80211_channel_to_frequency(chan, band); -+ rtw89_decode_chan_idx(rtwdev, chan, &ch, &band); -+ status->freq = ieee80211_channel_to_frequency(ch, band); - status->band = band; - } - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-006-wifi-rtw89-8852b-enable-hw_scan-support.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-006-wifi-rtw89-8852b-enable-hw_scan-support.patch deleted file mode 100644 index 780a0238f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-006-wifi-rtw89-8852b-enable-hw_scan-support.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 357277e1afdae0f56d08846e818579f5a020709d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 20 Feb 2023 15:02:01 +0800 -Subject: [PATCH 006/136] wifi: rtw89: 8852b: enable hw_scan support - -This enables hw_scan for 8852b after firmware version 0.29.29.0. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -260,6 +260,7 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), -+ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-007-wifi-rtw89-refine-FW-feature-judgement-on-packet-dro.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-007-wifi-rtw89-refine-FW-feature-judgement-on-packet-dro.patch deleted file mode 100644 index ef267accd..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-007-wifi-rtw89-refine-FW-feature-judgement-on-packet-dro.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0d1f7ff19d4f8a6da5a6b60d2afd1d34b5d5ebfc Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 20 Feb 2023 15:02:02 +0800 -Subject: [PATCH 007/136] wifi: rtw89: refine FW feature judgement on packet - drop - -The newer chips use the newer firmware branches, e.g. v027, v029. -And, those firmware branches are supposed to support packet drop -when they are just branched out. - -The initial firmware branch used by each chip is as below. -* 8852A: v009 -* 8852C: v027 -* 8852B: v027 - -So, only 8852A may use firmware which doesn't support packet drop at -runtime. To save trivial positive listing in firmware feature table, -we change to reverse judgment. - -Besides, rtw89_mac_ptk_drop_by_band_and_wait() missed to check firmware -feature before calling rtw89_fw_h2c_pkt_drop(). We also fix it. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230220070202.29868-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 2 +- - drivers/net/wireless/realtek/rtw89/fw.c | 4 ++-- - drivers/net/wireless/realtek/rtw89/mac.c | 2 +- - drivers/net/wireless/realtek/rtw89/mac80211.c | 2 +- - 4 files changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3023,7 +3023,7 @@ enum rtw89_fw_feature { - RTW89_FW_FEATURE_SCAN_OFFLOAD, - RTW89_FW_FEATURE_TX_WAKE, - RTW89_FW_FEATURE_CRASH_TRIGGER, -- RTW89_FW_FEATURE_PACKET_DROP, -+ RTW89_FW_FEATURE_NO_PACKET_DROP, - RTW89_FW_FEATURE_NO_DEEP_PS, - RTW89_FW_FEATURE_NO_LPS_PG, - }; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -235,6 +235,7 @@ static bool __fw_feat_cond_ ## __cond(u3 - - __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ - __DEF_FW_FEAT_COND(le, <=); /* less or equal */ -+__DEF_FW_FEAT_COND(lt, <); /* less than */ - - struct __fw_feat_cfg { - enum rtw89_core_chip_id chip_id; -@@ -256,12 +257,11 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), -- __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), -+ __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), - __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), -- __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -5426,7 +5426,7 @@ int rtw89_mac_ptk_drop_by_band_and_wait( - for (i = 0; i < try_cnt; i++) { - ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50, - 50000, false, rtwdev); -- if (ret) -+ if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) - rtw89_fw_h2c_pkt_drop(rtwdev, ¶ms); - else - return 0; ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -676,7 +676,7 @@ static void rtw89_ops_flush(struct ieee8 - rtw89_leave_lps(rtwdev); - rtw89_hci_flush_queues(rtwdev, queues, drop); - -- if (drop && RTW89_CHK_FW_FEATURE(PACKET_DROP, &rtwdev->fw)) -+ if (drop && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) - __rtw89_drop_packets(rtwdev, vif); - else - rtw89_mac_flush_txq(rtwdev, queues, drop); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-008-wifi-rtw89-fix-SER-L1-might-stop-entering-LPS-issue.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-008-wifi-rtw89-fix-SER-L1-might-stop-entering-LPS-issue.patch deleted file mode 100644 index d8d7ca0bb..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-008-wifi-rtw89-fix-SER-L1-might-stop-entering-LPS-issue.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 5c48f9432d06bf85ca934d7c4ecb14a7ec0c7f5d Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Fri, 24 Feb 2023 16:21:17 +0800 -Subject: [PATCH 008/136] wifi: rtw89: fix SER L1 might stop entering LPS issue - -When SER L1 triggered, driver need to stop Rx and clear RTW89_FLAG_RUNNING -flag. If track_work check RTW89_FLAG_RUNNING simultaneously, it will check -failed and never queue track_work again, and LPS won't enter either. -Therefore, we cancel delayed work when enter SER L1, and queue delayed work -when leave SER L1. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230224082117.21241-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/ser.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/ser.c -+++ b/drivers/net/wireless/realtek/rtw89/ser.c -@@ -414,8 +414,11 @@ static void ser_idle_st_hdl(struct rtw89 - - static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) - { -+ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); -+ - switch (evt) { - case SER_EV_STATE_IN: -+ cancel_delayed_work_sync(&rtwdev->track_work); - drv_stop_tx(ser); - - if (hal_stop_dma(ser)) { -@@ -446,6 +449,8 @@ static void ser_reset_trx_st_hdl(struct - hal_enable_dma(ser); - drv_resume_rx(ser); - drv_resume_tx(ser); -+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, -+ RTW89_TRACK_WORK_PERIOD); - break; - - default: diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-009-wifi-rtw89-release-RX-standby-timer-of-beamformee-CS.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-009-wifi-rtw89-release-RX-standby-timer-of-beamformee-CS.patch deleted file mode 100644 index f78eed054..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-009-wifi-rtw89-release-RX-standby-timer-of-beamformee-CS.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 8a66293e73a520a42a7653d2ca32074ba323ff56 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 7 Mar 2023 22:18:48 +0800 -Subject: [PATCH 009/136] wifi: rtw89: release RX standby timer of beamformee - CSI to save power - -Originally, we keep RX standby timer to handle beamformee CSI, but this -spends power and causes system not entering power save mode. To improve -power consumption, release the timer if throughput becomes low. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230307141848.26403-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 35 +++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ - 3 files changed, 36 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3168,6 +3168,7 @@ enum rtw89_flags { - RTW89_FLAG_RUNNING, - RTW89_FLAG_BFEE_MON, - RTW89_FLAG_BFEE_EN, -+ RTW89_FLAG_BFEE_TIMER_KEEP, - RTW89_FLAG_NAPI_RUNNING, - RTW89_FLAG_LEISURE_PS, - RTW89_FLAG_LOW_POWER_MODE, ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4931,6 +4931,24 @@ u16 rtw89_mac_get_plt_cnt(struct rtw89_d - return cnt; - } - -+static void rtw89_mac_bfee_standby_timer(struct rtw89_dev *rtwdev, u8 mac_idx, -+ bool keep) -+{ -+ u32 reg; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee standby_timer to %d\n", keep); -+ reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); -+ if (keep) { -+ set_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); -+ rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, -+ BFRP_RX_STANDBY_TIMER_KEEP); -+ } else { -+ clear_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); -+ rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, -+ BFRP_RX_STANDBY_TIMER_RELEASE); -+ } -+} -+ - static void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) - { - u32 reg; -@@ -4967,9 +4985,9 @@ static int rtw89_mac_init_bfee(struct rt - rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP); - - reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); -- val32 = FIELD_PREP(B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, BFRP_RX_STANDBY_TIMER); -- val32 |= FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER); -+ val32 = FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER); - rtw89_write32(rtwdev, reg, val32); -+ rtw89_mac_bfee_standby_timer(rtwdev, mac_idx, true); - rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); - - reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); -@@ -5181,6 +5199,19 @@ void _rtw89_mac_bf_monitor_track(struct - struct rtw89_vif *rtwvif; - bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv; - bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); -+ bool keep_timer = true; -+ bool old_keep_timer; -+ -+ old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags); -+ -+ if (stats->tx_tfc_lv <= RTW89_TFC_LOW && stats->rx_tfc_lv <= RTW89_TFC_LOW) -+ keep_timer = false; -+ -+ if (keep_timer != old_keep_timer) { -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_mac_bfee_standby_timer(rtwdev, rtwvif->mac_idx, -+ keep_timer); -+ } - - if (en == old) - return; ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3056,6 +3056,8 @@ - #define R_AX_BFMEE_RESP_OPTION_C1 0xED80 - #define B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK GENMASK(31, 24) - #define B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK GENMASK(23, 20) -+#define BFRP_RX_STANDBY_TIMER_KEEP 0x0 -+#define BFRP_RX_STANDBY_TIMER_RELEASE 0x1 - #define B_AX_MU_BFRPTSEG_SEL_MASK GENMASK(18, 17) - #define B_AX_BFMEE_NDP_RXSTDBY_SEL BIT(16) - #define BFRP_RX_STANDBY_TIMER 0x0 diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-010-wifi-rtw89-coex-Add-more-error_map-and-counter-to-lo.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-010-wifi-rtw89-coex-Add-more-error_map-and-counter-to-lo.patch deleted file mode 100644 index 96bf15417..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-010-wifi-rtw89-coex-Add-more-error_map-and-counter-to-lo.patch +++ /dev/null @@ -1,347 +0,0 @@ -From e49bdd85c92dacb12151aa1b9cf48b81c81a6f98 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:19 +0800 -Subject: [PATCH 010/136] wifi: rtw89: coex: Add more error_map and counter to - log - -The error map and counter can help to analyze is coexistence mechanism -going well or not. For example, if there is E2G (External control Wi-Fi -slot for Wi-Fi 2.4 GHz) hang counter, it means Wi-Fi firmware didn't cut -a slot for Wi-Fi 2.4 GHz. Maybe something wrong with firmware timer. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 112 +++++++++++++--------- - drivers/net/wireless/realtek/rtw89/core.h | 31 ++++-- - 2 files changed, 88 insertions(+), 55 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -734,6 +734,7 @@ static void _reset_btc_var(struct rtw89_ - - #define BTC_RPT_HDR_SIZE 3 - #define BTC_CHK_WLSLOT_DRIFT_MAX 15 -+#define BTC_CHK_BTSLOT_DRIFT_MAX 15 - #define BTC_CHK_HANG_MAX 3 - - static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt) -@@ -748,62 +749,76 @@ static void _chk_btc_err(struct rtw89_de - __func__, type, cnt); - - switch (type) { -- case BTC_DCNT_RPT_FREEZE: -+ case BTC_DCNT_RPT_HANG: - if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map) -- dm->cnt_dm[BTC_DCNT_RPT_FREEZE]++; -+ dm->cnt_dm[BTC_DCNT_RPT_HANG]++; - else -- dm->cnt_dm[BTC_DCNT_RPT_FREEZE] = 0; -+ dm->cnt_dm[BTC_DCNT_RPT_HANG] = 0; - -- if (dm->cnt_dm[BTC_DCNT_RPT_FREEZE] >= BTC_CHK_HANG_MAX) -+ if (dm->cnt_dm[BTC_DCNT_RPT_HANG] >= BTC_CHK_HANG_MAX) - dm->error.map.wl_fw_hang = true; - else - dm->error.map.wl_fw_hang = false; - - dm->cnt_dm[BTC_DCNT_RPT] = cnt; - break; -- case BTC_DCNT_CYCLE_FREEZE: -+ case BTC_DCNT_CYCLE_HANG: - if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt && - (dm->tdma_now.type != CXTDMA_OFF || - dm->tdma_now.ext_ctrl == CXECTL_EXT)) -- dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE]++; -+ dm->cnt_dm[BTC_DCNT_CYCLE_HANG]++; - else -- dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] = 0; -+ dm->cnt_dm[BTC_DCNT_CYCLE_HANG] = 0; - -- if (dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] >= BTC_CHK_HANG_MAX) -+ if (dm->cnt_dm[BTC_DCNT_CYCLE_HANG] >= BTC_CHK_HANG_MAX) - dm->error.map.cycle_hang = true; - else - dm->error.map.cycle_hang = false; - - dm->cnt_dm[BTC_DCNT_CYCLE] = cnt; - break; -- case BTC_DCNT_W1_FREEZE: -+ case BTC_DCNT_W1_HANG: - if (dm->cnt_dm[BTC_DCNT_W1] == cnt && - dm->tdma_now.type != CXTDMA_OFF) -- dm->cnt_dm[BTC_DCNT_W1_FREEZE]++; -+ dm->cnt_dm[BTC_DCNT_W1_HANG]++; - else -- dm->cnt_dm[BTC_DCNT_W1_FREEZE] = 0; -+ dm->cnt_dm[BTC_DCNT_W1_HANG] = 0; - -- if (dm->cnt_dm[BTC_DCNT_W1_FREEZE] >= BTC_CHK_HANG_MAX) -+ if (dm->cnt_dm[BTC_DCNT_W1_HANG] >= BTC_CHK_HANG_MAX) - dm->error.map.w1_hang = true; - else - dm->error.map.w1_hang = false; - - dm->cnt_dm[BTC_DCNT_W1] = cnt; - break; -- case BTC_DCNT_B1_FREEZE: -+ case BTC_DCNT_B1_HANG: - if (dm->cnt_dm[BTC_DCNT_B1] == cnt && - dm->tdma_now.type != CXTDMA_OFF) -- dm->cnt_dm[BTC_DCNT_B1_FREEZE]++; -+ dm->cnt_dm[BTC_DCNT_B1_HANG]++; - else -- dm->cnt_dm[BTC_DCNT_B1_FREEZE] = 0; -+ dm->cnt_dm[BTC_DCNT_B1_HANG] = 0; - -- if (dm->cnt_dm[BTC_DCNT_B1_FREEZE] >= BTC_CHK_HANG_MAX) -+ if (dm->cnt_dm[BTC_DCNT_B1_HANG] >= BTC_CHK_HANG_MAX) - dm->error.map.b1_hang = true; - else - dm->error.map.b1_hang = false; - - dm->cnt_dm[BTC_DCNT_B1] = cnt; - break; -+ case BTC_DCNT_E2G_HANG: -+ if (dm->cnt_dm[BTC_DCNT_E2G] == cnt && -+ dm->tdma_now.ext_ctrl == CXECTL_EXT) -+ dm->cnt_dm[BTC_DCNT_E2G_HANG]++; -+ else -+ dm->cnt_dm[BTC_DCNT_E2G_HANG] = 0; -+ -+ if (dm->cnt_dm[BTC_DCNT_E2G_HANG] >= BTC_CHK_HANG_MAX) -+ dm->error.map.wl_e2g_hang = true; -+ else -+ dm->error.map.wl_e2g_hang = false; -+ -+ dm->cnt_dm[BTC_DCNT_E2G] = cnt; -+ break; - case BTC_DCNT_TDMA_NONSYNC: - if (cnt != 0) /* if tdma not sync between drv/fw */ - dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++; -@@ -822,23 +837,23 @@ static void _chk_btc_err(struct rtw89_de - dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0; - - if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX) -- dm->error.map.tdma_no_sync = true; -+ dm->error.map.slot_no_sync = true; - else -- dm->error.map.tdma_no_sync = false; -+ dm->error.map.slot_no_sync = false; - break; -- case BTC_DCNT_BTCNT_FREEZE: -+ case BTC_DCNT_BTCNT_HANG: - cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] + - cx->cnt_bt[BTC_BCNT_HIPRI_TX] + - cx->cnt_bt[BTC_BCNT_LOPRI_RX] + - cx->cnt_bt[BTC_BCNT_LOPRI_TX]; - - if (cnt == 0) -- dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE]++; -+ dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++; - else -- dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; -+ dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; - -- if ((dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] >= BTC_CHK_HANG_MAX && -- bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] && -+ if ((dm->cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX && -+ bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_HANG] && - !bt->enable.now)) - _update_bt_scbd(rtwdev, false); - break; -@@ -853,6 +868,18 @@ static void _chk_btc_err(struct rtw89_de - else - dm->error.map.wl_slot_drift = false; - break; -+ case BTC_DCNT_BT_SLOT_DRIFT: -+ if (cnt >= BTC_CHK_BTSLOT_DRIFT_MAX) -+ dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT]++; -+ else -+ dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] = 0; -+ -+ if (dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) -+ dm->error.map.bt_slot_drift = true; -+ else -+ dm->error.map.bt_slot_drift = false; -+ -+ break; - } - } - -@@ -1129,14 +1156,14 @@ static u32 _chk_btc_report(struct rtw89_ - wl->ver_info.fw = prpt->v1.wl_fw_ver; - dm->wl_fw_cx_offload = !!prpt->v1.wl_fw_cx_offload; - -- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, - pfwinfo->event[BTF_EVNT_RPT]); - - /* To avoid I/O if WL LPS or power-off */ - if (wl->status.map.lps != BTC_LPS_RF_OFF && - !wl->status.map.rf_off) { - rtwdev->chip->ops->btc_update_bt_cnt(rtwdev); -- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); - - btc->cx.cnt_bt[BTC_BCNT_POLUT] = - rtw89_mac_get_plt_cnt(rtwdev, -@@ -1164,8 +1191,8 @@ static u32 _chk_btc_report(struct rtw89_ - btc->cx.cnt_bt[BTC_BCNT_POLUT] = - le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]); - -- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, - pfwinfo->event[BTF_EVNT_RPT]); - - if (le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) -@@ -1196,8 +1223,8 @@ static u32 _chk_btc_report(struct rtw89_ - btc->cx.cnt_bt[BTC_BCNT_POLUT] = - le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]); - -- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); -- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, - pfwinfo->event[BTF_EVNT_RPT]); - - dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; -@@ -1258,11 +1285,11 @@ static u32 _chk_btc_report(struct rtw89_ - BTC_DCNT_WL_SLOT_DRIFT, diff_t); - } - -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, - le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1])); -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, - le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1])); -- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, - le16_to_cpu(pcysta->v2.cycles)); - } else if (ver->fcxcysta == 3) { - if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD) -@@ -1299,11 +1326,11 @@ static u32 _chk_btc_report(struct rtw89_ - } - } - -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, - le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1])); -- _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, - le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); -- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, - le16_to_cpu(pcysta->v3.cycles)); - } else if (ver->fcxcysta == 4) { - if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD) -@@ -1341,11 +1368,11 @@ static u32 _chk_btc_report(struct rtw89_ - } - } - -- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, - le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1])); -- _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, - le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); -- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, - le16_to_cpu(pcysta->v4.cycles)); - } else { - goto err; -@@ -4578,7 +4605,7 @@ static void _update_bt_scbd(struct rtw89 - } - - if (!(val & BTC_BSCB_ON) || -- btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] >= BTC_CHK_HANG_MAX) -+ btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX) - bt->enable.now = 0; - else - bt->enable.now = 1; -@@ -5349,7 +5376,7 @@ void rtw89_btc_ntfy_radio_state(struct r - _write_scbd(rtwdev, BTC_WSCB_ALL, false); - } - -- btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; -+ btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; - if (wl->status.map.lps_pre == BTC_LPS_OFF && - wl->status.map.lps_pre != wl->status.map.lps) - btc->dm.tdma_instant_excute = 1; -@@ -5700,11 +5727,6 @@ static void _show_cx_info(struct rtw89_d - seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ", - "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); - -- if (dm->wl_fw_cx_offload != BTC_CX_FW_OFFLOAD) -- dm->error.map.offload_mismatch = true; -- else -- dm->error.map.offload_mismatch = false; -- - ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); - ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex); - ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -883,20 +883,24 @@ enum rtw89_btc_dcnt { - BTC_DCNT_RUN = 0x0, - BTC_DCNT_CX_RUNINFO, - BTC_DCNT_RPT, -- BTC_DCNT_RPT_FREEZE, -+ BTC_DCNT_RPT_HANG, - BTC_DCNT_CYCLE, -- BTC_DCNT_CYCLE_FREEZE, -+ BTC_DCNT_CYCLE_HANG, - BTC_DCNT_W1, -- BTC_DCNT_W1_FREEZE, -+ BTC_DCNT_W1_HANG, - BTC_DCNT_B1, -- BTC_DCNT_B1_FREEZE, -+ BTC_DCNT_B1_HANG, - BTC_DCNT_TDMA_NONSYNC, - BTC_DCNT_SLOT_NONSYNC, -- BTC_DCNT_BTCNT_FREEZE, -+ BTC_DCNT_BTCNT_HANG, - BTC_DCNT_WL_SLOT_DRIFT, -- BTC_DCNT_BT_SLOT_DRIFT, - BTC_DCNT_WL_STA_LAST, -- BTC_DCNT_NUM, -+ BTC_DCNT_BT_SLOT_DRIFT, -+ BTC_DCNT_BT_SLOT_FLOOD, -+ BTC_DCNT_FDDT_TRIG, -+ BTC_DCNT_E2G, -+ BTC_DCNT_E2G_HANG, -+ BTC_DCNT_NUM - }; - - enum rtw89_btc_wl_state_cnt { -@@ -1302,15 +1306,22 @@ struct rtw89_btc_dm_emap { - u32 pta_owner: 1; - u32 wl_rfk_timeout: 1; - u32 bt_rfk_timeout: 1; -- - u32 wl_fw_hang: 1; -- u32 offload_mismatch: 1; - u32 cycle_hang: 1; - u32 w1_hang: 1; -- - u32 b1_hang: 1; - u32 tdma_no_sync: 1; -+ u32 slot_no_sync: 1; - u32 wl_slot_drift: 1; -+ u32 bt_slot_drift: 1; -+ u32 role_num_mismatch: 1; -+ u32 null1_tx_late: 1; -+ u32 bt_afh_conflict: 1; -+ u32 bt_leafh_conflict: 1; -+ u32 bt_slot_flood: 1; -+ u32 wl_e2g_hang: 1; -+ u32 wl_ver_mismatch: 1; -+ u32 bt_ver_mismatch: 1; - }; - - union rtw89_btc_dm_error_map { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-011-wifi-rtw89-coex-Add-WiFi-role-info-v2.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-011-wifi-rtw89-coex-Add-WiFi-role-info-v2.patch deleted file mode 100644 index 566c0d55f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-011-wifi-rtw89-coex-Add-WiFi-role-info-v2.patch +++ /dev/null @@ -1,671 +0,0 @@ -From 5049964c4af86865153c553fc6a138df02685ffb Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:20 +0800 -Subject: [PATCH 011/136] wifi: rtw89: coex: Add WiFi role info v2 - -Remove WiFi traffic busy level & traffic rate from active role information. -This information will move to v5 version TDMA cycle info. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 277 +++++++++++++++++++++- - drivers/net/wireless/realtek/rtw89/core.h | 32 +++ - drivers/net/wireless/realtek/rtw89/fw.c | 86 +++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 51 ++++ - 4 files changed, 439 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1819,6 +1819,8 @@ static void _fw_set_drv_info(struct rtw8 - rtw89_fw_h2c_cxdrv_role(rtwdev); - else if (ver->fwlrole == 1) - rtw89_fw_h2c_cxdrv_role_v1(rtwdev); -+ else if (ver->fwlrole == 2) -+ rtw89_fw_h2c_cxdrv_role_v2(rtwdev); - break; - case CXDRVINFO_CTRL: - rtw89_fw_h2c_cxdrv_ctrl(rtwdev); -@@ -2113,8 +2115,10 @@ static void _set_bt_afh_info(struct rtw8 - struct rtw89_btc_bt_link_info *b = &bt->link_info; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - struct rtw89_btc_wl_active_role *r; - struct rtw89_btc_wl_active_role_v1 *r1; -+ struct rtw89_btc_wl_active_role_v2 *r2; - u8 en = 0, i, ch = 0, bw = 0; - u8 mode, connect_cnt; - -@@ -2124,9 +2128,14 @@ static void _set_bt_afh_info(struct rtw8 - if (ver->fwlrole == 0) { - mode = wl_rinfo->link_mode; - connect_cnt = wl_rinfo->connect_cnt; -- } else { -+ } else if (ver->fwlrole == 1) { - mode = wl_rinfo_v1->link_mode; - connect_cnt = wl_rinfo_v1->connect_cnt; -+ } else if (ver->fwlrole == 2) { -+ mode = wl_rinfo_v2->link_mode; -+ connect_cnt = wl_rinfo_v2->connect_cnt; -+ } else { -+ return; - } - - if (wl->status.map.rf_off || bt->whql_test || -@@ -2139,6 +2148,7 @@ static void _set_bt_afh_info(struct rtw8 - for (i = 0; i < RTW89_PORT_NUM; i++) { - r = &wl_rinfo->active_role[i]; - r1 = &wl_rinfo_v1->active_role_v1[i]; -+ r2 = &wl_rinfo_v2->active_role_v2[i]; - - if (ver->fwlrole == 0 && - (r->role == RTW89_WIFI_ROLE_P2P_GO || -@@ -2152,6 +2162,12 @@ static void _set_bt_afh_info(struct rtw8 - ch = r1->ch; - bw = r1->bw; - break; -+ } else if (ver->fwlrole == 2 && -+ (r2->role == RTW89_WIFI_ROLE_P2P_GO || -+ r2->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { -+ ch = r2->ch; -+ bw = r2->bw; -+ break; - } - } - } else { -@@ -2160,6 +2176,7 @@ static void _set_bt_afh_info(struct rtw8 - for (i = 0; i < RTW89_PORT_NUM; i++) { - r = &wl_rinfo->active_role[i]; - r1 = &wl_rinfo_v1->active_role_v1[i]; -+ r2 = &wl_rinfo_v2->active_role_v2[i]; - - if (ver->fwlrole == 0 && - r->connected && r->band == RTW89_BAND_2G) { -@@ -2171,6 +2188,11 @@ static void _set_bt_afh_info(struct rtw8 - ch = r1->ch; - bw = r1->bw; - break; -+ } else if (ver->fwlrole == 2 && -+ r2->connected && r2->band == RTW89_BAND_2G) { -+ ch = r2->ch; -+ bw = r2->bw; -+ break; - } - } - } -@@ -3625,6 +3647,7 @@ static void _set_btg_ctrl(struct rtw89_d - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; - bool is_btg; - u8 mode; -@@ -3634,8 +3657,12 @@ static void _set_btg_ctrl(struct rtw89_d - - if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; -- else -+ else if (ver->fwlrole == 1) - mode = wl_rinfo_v1->link_mode; -+ else if (ver->fwlrole == 2) -+ mode = wl_rinfo_v2->link_mode; -+ else -+ return; - - /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */ - if (mode == BTC_WLINK_5G) /* always 0 if 5G */ -@@ -3736,6 +3763,7 @@ static void _set_wl_tx_limit(struct rtw8 - struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - struct rtw89_txtime_data data = {.rtwdev = rtwdev}; - u8 mode; - u8 tx_retry; -@@ -3748,8 +3776,12 @@ static void _set_wl_tx_limit(struct rtw8 - - if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; -- else -+ else if (ver->fwlrole == 1) - mode = wl_rinfo_v1->link_mode; -+ else if (ver->fwlrole == 2) -+ mode = wl_rinfo_v2->link_mode; -+ else -+ return; - - if (btc->dm.freerun || btc->ctrl.igno_bt || b->profile_cnt.now == 0 || - mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) { -@@ -3799,14 +3831,19 @@ static void _set_bt_rx_agc(struct rtw89_ - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - bool bt_hi_lna_rx = false; - u8 mode; - - if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; -- else -+ else if (ver->fwlrole == 1) - mode = wl_rinfo_v1->link_mode; -+ else if (ver->fwlrole == 2) -+ mode = wl_rinfo_v2->link_mode; -+ else -+ return; - - if (mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) - bt_hi_lna_rx = true; -@@ -4079,6 +4116,68 @@ static void _action_wl_2g_scc_v1(struct - _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); - } - -+static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_wl_info *wl = &btc->cx.wl; -+ struct rtw89_btc_bt_info *bt = &btc->cx.bt; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2; -+ u16 policy_type = BTC_CXP_OFF_BT; -+ u32 dur; -+ -+ if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED) { -+ policy_type = BTC_CXP_OFF_EQ0; -+ } else { -+ /* shared-antenna */ -+ switch (wl_rinfo->mrole_type) { -+ case BTC_WLMROLE_STA_GC: -+ dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; -+ dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT; -+ dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ -+ _action_by_bt(rtwdev); -+ return; -+ case BTC_WLMROLE_STA_STA: -+ dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; -+ dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_STATION; -+ dm->wl_scc.ebt_null = 0; /* no ext-slot-control */ -+ _action_by_bt(rtwdev); -+ return; -+ case BTC_WLMROLE_STA_GC_NOA: -+ case BTC_WLMROLE_STA_GO: -+ case BTC_WLMROLE_STA_GO_NOA: -+ dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION; -+ dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE; -+ dur = wl_rinfo->mrole_noa_duration; -+ -+ if (wl->status.map._4way) { -+ dm->wl_scc.ebt_null = 0; -+ policy_type = BTC_CXP_OFFE_WL; -+ } else if (bt->link_info.status.map.connect == 0) { -+ dm->wl_scc.ebt_null = 0; -+ policy_type = BTC_CXP_OFFE_2GISOB; -+ } else if (bt->link_info.a2dp_desc.exist && -+ dur < btc->bt_req_len) { -+ dm->wl_scc.ebt_null = 1; /* tx null at EBT */ -+ policy_type = BTC_CXP_OFFE_2GBWMIXB2; -+ } else if (bt->link_info.a2dp_desc.exist || -+ bt->link_info.pan_desc.exist) { -+ dm->wl_scc.ebt_null = 1; /* tx null at EBT */ -+ policy_type = BTC_CXP_OFFE_2GBWISOB; -+ } else { -+ dm->wl_scc.ebt_null = 0; -+ policy_type = BTC_CXP_OFFE_2GBWISOB; -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ -+ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); -+ _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); -+} -+ - static void _action_wl_2g_ap(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -4518,6 +4617,156 @@ static void _update_wl_info_v1(struct rt - _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); - } - -+static void _update_wl_info_v2(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_wl_info *wl = &btc->cx.wl; -+ struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2; -+ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; -+ u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; -+ u8 cnt_2g = 0, cnt_5g = 0, phy; -+ u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {}; -+ bool b2g = false, b5g = false, client_joined = false; -+ u8 i; -+ -+ memset(wl_rinfo, 0, sizeof(*wl_rinfo)); -+ -+ for (i = 0; i < RTW89_PORT_NUM; i++) { -+ if (!wl_linfo[i].active) -+ continue; -+ -+ cnt_active++; -+ wl_rinfo->active_role_v2[cnt_active - 1].role = wl_linfo[i].role; -+ wl_rinfo->active_role_v2[cnt_active - 1].pid = wl_linfo[i].pid; -+ wl_rinfo->active_role_v2[cnt_active - 1].phy = wl_linfo[i].phy; -+ wl_rinfo->active_role_v2[cnt_active - 1].band = wl_linfo[i].band; -+ wl_rinfo->active_role_v2[cnt_active - 1].noa = (u8)wl_linfo[i].noa; -+ wl_rinfo->active_role_v2[cnt_active - 1].connected = 0; -+ -+ wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; -+ -+ phy = wl_linfo[i].phy; -+ -+ if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { -+ wl_dinfo->role[phy] = wl_linfo[i].role; -+ wl_dinfo->op_band[phy] = wl_linfo[i].band; -+ _update_dbcc_band(rtwdev, phy); -+ _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); -+ } -+ -+ if (wl_linfo[i].connected == MLME_NO_LINK) { -+ continue; -+ } else if (wl_linfo[i].connected == MLME_LINKING) { -+ cnt_connecting++; -+ } else { -+ cnt_connect++; -+ if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || -+ wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && -+ wl_linfo[i].client_cnt > 1) -+ client_joined = true; -+ } -+ -+ wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); -+ wl_rinfo->active_role_v2[cnt_active - 1].ch = wl_linfo[i].ch; -+ wl_rinfo->active_role_v2[cnt_active - 1].bw = wl_linfo[i].bw; -+ wl_rinfo->active_role_v2[cnt_active - 1].connected = 1; -+ -+ /* only care 2 roles + BT coex */ -+ if (wl_linfo[i].band != RTW89_BAND_2G) { -+ if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) -+ wl_5g_ch[cnt_5g] = wl_linfo[i].ch; -+ cnt_5g++; -+ b5g = true; -+ } else { -+ if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) -+ wl_2g_ch[cnt_2g] = wl_linfo[i].ch; -+ cnt_2g++; -+ b2g = true; -+ } -+ } -+ -+ wl_rinfo->connect_cnt = cnt_connect; -+ -+ /* Be careful to change the following sequence!! */ -+ if (cnt_connect == 0) { -+ wl_rinfo->link_mode = BTC_WLINK_NOLINK; -+ wl_rinfo->role_map.role.none = 1; -+ } else if (!b2g && b5g) { -+ wl_rinfo->link_mode = BTC_WLINK_5G; -+ } else if (wl_rinfo->role_map.role.nan) { -+ wl_rinfo->link_mode = BTC_WLINK_2G_NAN; -+ } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { -+ wl_rinfo->link_mode = BTC_WLINK_OTHER; -+ } else if (b2g && b5g && cnt_connect == 2) { -+ if (rtwdev->dbcc_en) { -+ switch (wl_dinfo->role[RTW89_PHY_0]) { -+ case RTW89_WIFI_ROLE_STATION: -+ wl_rinfo->link_mode = BTC_WLINK_2G_STA; -+ break; -+ case RTW89_WIFI_ROLE_P2P_GO: -+ wl_rinfo->link_mode = BTC_WLINK_2G_GO; -+ break; -+ case RTW89_WIFI_ROLE_P2P_CLIENT: -+ wl_rinfo->link_mode = BTC_WLINK_2G_GC; -+ break; -+ case RTW89_WIFI_ROLE_AP: -+ wl_rinfo->link_mode = BTC_WLINK_2G_AP; -+ break; -+ default: -+ wl_rinfo->link_mode = BTC_WLINK_OTHER; -+ break; -+ } -+ } else { -+ wl_rinfo->link_mode = BTC_WLINK_25G_MCC; -+ } -+ } else if (!b5g && cnt_connect == 2) { -+ if (wl_rinfo->role_map.role.station && -+ (wl_rinfo->role_map.role.p2p_go || -+ wl_rinfo->role_map.role.p2p_gc || -+ wl_rinfo->role_map.role.ap)) { -+ if (wl_2g_ch[0] == wl_2g_ch[1]) -+ wl_rinfo->link_mode = BTC_WLINK_2G_SCC; -+ else -+ wl_rinfo->link_mode = BTC_WLINK_2G_MCC; -+ } else { -+ wl_rinfo->link_mode = BTC_WLINK_2G_MCC; -+ } -+ } else if (!b5g && cnt_connect == 1) { -+ if (wl_rinfo->role_map.role.station) -+ wl_rinfo->link_mode = BTC_WLINK_2G_STA; -+ else if (wl_rinfo->role_map.role.ap) -+ wl_rinfo->link_mode = BTC_WLINK_2G_AP; -+ else if (wl_rinfo->role_map.role.p2p_go) -+ wl_rinfo->link_mode = BTC_WLINK_2G_GO; -+ else if (wl_rinfo->role_map.role.p2p_gc) -+ wl_rinfo->link_mode = BTC_WLINK_2G_GC; -+ else -+ wl_rinfo->link_mode = BTC_WLINK_OTHER; -+ } -+ -+ /* if no client_joined, don't care P2P-GO/AP role */ -+ if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { -+ if (!client_joined) { -+ if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || -+ wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { -+ wl_rinfo->link_mode = BTC_WLINK_2G_STA; -+ wl_rinfo->connect_cnt = 1; -+ } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || -+ wl_rinfo->link_mode == BTC_WLINK_2G_AP) { -+ wl_rinfo->link_mode = BTC_WLINK_NOLINK; -+ wl_rinfo->connect_cnt = 0; -+ } -+ } -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n", -+ cnt_connect, cnt_connecting, wl_rinfo->link_mode); -+ -+ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); -+} -+ - #define BTC_CHK_HANG_MAX 3 - #define BTC_SCB_INV_VALUE GENMASK(31, 0) - -@@ -4676,6 +4925,7 @@ void _run_coex(struct rtw89_dev *rtwdev, - struct rtw89_btc_bt_info *bt = &btc->cx.bt; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - u8 mode; - - lockdep_assert_held(&rtwdev->mutex); -@@ -4686,8 +4936,12 @@ void _run_coex(struct rtw89_dev *rtwdev, - - if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; -- else -+ else if (ver->fwlrole == 1) - mode = wl_rinfo_v1->link_mode; -+ else if (ver->fwlrole == 2) -+ mode = wl_rinfo_v2->link_mode; -+ else -+ return; - - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", - __func__, reason, mode); -@@ -4812,6 +5066,8 @@ void _run_coex(struct rtw89_dev *rtwdev, - _action_wl_2g_scc(rtwdev); - else if (ver->fwlrole == 1) - _action_wl_2g_scc_v1(rtwdev); -+ else if (ver->fwlrole == 2) -+ _action_wl_2g_scc_v2(rtwdev); - break; - case BTC_WLINK_2G_MCC: - bt->scan_rx_low_pri = true; -@@ -5317,8 +5573,10 @@ void rtw89_btc_ntfy_role_info(struct rtw - memcpy(wlinfo, &r, sizeof(*wlinfo)); - if (ver->fwlrole == 0) - _update_wl_info(rtwdev); -- else -+ else if (ver->fwlrole == 1) - _update_wl_info_v1(rtwdev); -+ else if (ver->fwlrole == 2) -+ _update_wl_info_v2(rtwdev); - - if (wlinfo->role == RTW89_WIFI_ROLE_STATION && - wlinfo->connected == MLME_NO_LINK) -@@ -5838,6 +6096,7 @@ static void _show_wl_info(struct rtw89_d - struct rtw89_btc_wl_info *wl = &cx->wl; - struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; - struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; - u8 mode; - - if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) -@@ -5847,8 +6106,12 @@ static void _show_wl_info(struct rtw89_d - - if (ver->fwlrole == 0) - mode = wl_rinfo->link_mode; -- else -+ else if (ver->fwlrole == 1) - mode = wl_rinfo_v1->link_mode; -+ else if (ver->fwlrole == 2) -+ mode = wl_rinfo_v2->link_mode; -+ else -+ return; - - seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode); - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1180,6 +1180,22 @@ struct rtw89_btc_wl_active_role_v1 { - u32 noa_duration; /* ms */ - }; - -+struct rtw89_btc_wl_active_role_v2 { -+ u8 connected: 1; -+ u8 pid: 3; -+ u8 phy: 1; -+ u8 noa: 1; -+ u8 band: 2; -+ -+ u8 client_ps: 1; -+ u8 bw: 7; -+ -+ u8 role; -+ u8 ch; -+ -+ u32 noa_duration; /* ms */ -+}; -+ - struct rtw89_btc_wl_role_info_bpos { - u16 none: 1; - u16 station: 1; -@@ -1228,6 +1244,21 @@ struct rtw89_btc_wl_role_info_v1 { /* st - u32 rsvd: 27; - }; - -+struct rtw89_btc_wl_role_info_v2 { /* struct size must be n*4 bytes */ -+ u8 connect_cnt; -+ u8 link_mode; -+ union rtw89_btc_wl_role_info_map role_map; -+ struct rtw89_btc_wl_active_role_v2 active_role_v2[RTW89_PORT_NUM]; -+ u32 mrole_type; /* btc_wl_mrole_type */ -+ u32 mrole_noa_duration; /* ms */ -+ -+ u32 dbcc_en: 1; -+ u32 dbcc_chg: 1; -+ u32 dbcc_2g_phy: 2; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ -+ u32 link_mode_chg: 1; -+ u32 rsvd: 27; -+}; -+ - struct rtw89_btc_wl_ver_info { - u32 fw_coex; /* match with which coex_ver */ - u32 fw; -@@ -1343,6 +1374,7 @@ struct rtw89_btc_wl_info { - struct rtw89_btc_wl_afh_info afh_info; - struct rtw89_btc_wl_role_info role_info; - struct rtw89_btc_wl_role_info_v1 role_info_v1; -+ struct rtw89_btc_wl_role_info_v2 role_info_v2; - struct rtw89_btc_wl_scan_info scan_info; - struct rtw89_btc_wl_dbcc_info dbcc_info; - struct rtw89_btc_rf_para rf_para; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2038,6 +2038,92 @@ fail: - return ret; - } - -+#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(max_role_num) \ -+ (4 + 8 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR) -+ -+int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ const struct rtw89_btc_ver *ver = btc->ver; -+ struct rtw89_btc_wl_info *wl = &btc->cx.wl; -+ struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2; -+ struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; -+ struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2; -+ struct sk_buff *skb; -+ u32 len; -+ u8 *cmd, offset; -+ int ret; -+ int i; -+ -+ len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V2(ver->max_role_num); -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); -+ return -ENOMEM; -+ } -+ skb_put(skb, len); -+ cmd = skb->data; -+ -+ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); -+ RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); -+ -+ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); -+ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); -+ -+ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); -+ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); -+ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); -+ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); -+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); -+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); -+ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); -+ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); -+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); -+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); -+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); -+ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); -+ -+ offset = PORT_DATA_OFFSET; -+ for (i = 0; i < RTW89_PORT_NUM; i++, active++) { -+ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset); -+ RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset); -+ } -+ -+ offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; -+ RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); -+ RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); -+ RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); -+ RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset); -+ RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset); -+ RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_OUTSRC, BTFC_SET, -+ SET_DRV_INFO, 0, 0, -+ len); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ - #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) - int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) - { ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2393,6 +2393,56 @@ static inline void RTW89_SET_FWCMD_CXROL - le32p_replace_bits((__le32 *)((u8 *)cmd + (20 + (12 + offset) * n)), val, GENMASK(31, 0)); - } - -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(3, 1)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(4)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(5)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(7, 6)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, BIT(0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, GENMASK(7, 1)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (8 + (12 + offset) * n), val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(void *cmd, u8 val, int n, u8 offset) -+{ -+ u8p_replace_bits((u8 *)cmd + (9 + (12 + offset) * n), val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(void *cmd, u32 val, int n, u8 offset) -+{ -+ le32p_replace_bits((__le32 *)((u8 *)cmd + (10 + (12 + offset) * n)), val, GENMASK(31, 0)); -+} -+ - static inline void RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(void *cmd, u32 val, u8 offset) - { - le32p_replace_bits((__le32 *)((u8 *)cmd + offset), val, GENMASK(31, 0)); -@@ -3505,6 +3555,7 @@ int rtw89_fw_h2c_ra(struct rtw89_dev *rt - int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev); -+int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-012-wifi-rtw89-coex-Add-traffic-TX-RX-info-and-its-H2C.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-012-wifi-rtw89-coex-Add-traffic-TX-RX-info-and-its-H2C.patch deleted file mode 100644 index e1f727c3d..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-012-wifi-rtw89-coex-Add-traffic-TX-RX-info-and-its-H2C.patch +++ /dev/null @@ -1,403 +0,0 @@ -From a2c0ce5d01a2218af4756d311ae91845b67ac5b9 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:21 +0800 -Subject: [PATCH 012/136] wifi: rtw89: coex: Add traffic TX/RX info and its H2C - -There is a new mechanism which can do some real time performance -tuning for WiFi and BT. This TX/RX info is a condition provide to -firmware to do traffic analysis. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 59 +++++++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 43 +++++++++++ - drivers/net/wireless/realtek/rtw89/fw.c | 56 +++++++++++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 87 +++++++++++++++++++++++ - 4 files changed, 241 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1809,6 +1809,9 @@ static void _fw_set_drv_info(struct rtw8 - { - struct rtw89_btc *btc = &rtwdev->btc; - const struct rtw89_btc_ver *ver = btc->ver; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_wl_info *wl = &btc->cx.wl; -+ struct rtw89_btc_rf_trx_para rf_para = dm->rf_trx_para; - - switch (type) { - case CXDRVINFO_INIT: -@@ -1825,6 +1828,19 @@ static void _fw_set_drv_info(struct rtw8 - case CXDRVINFO_CTRL: - rtw89_fw_h2c_cxdrv_ctrl(rtwdev); - break; -+ case CXDRVINFO_TRX: -+ dm->trx_info.tx_power = u32_get_bits(rf_para.wl_tx_power, -+ RTW89_BTC_WL_DEF_TX_PWR); -+ dm->trx_info.rx_gain = u32_get_bits(rf_para.wl_rx_gain, -+ RTW89_BTC_WL_DEF_TX_PWR); -+ dm->trx_info.bt_tx_power = u32_get_bits(rf_para.bt_tx_power, -+ RTW89_BTC_WL_DEF_TX_PWR); -+ dm->trx_info.bt_rx_gain = u32_get_bits(rf_para.bt_rx_gain, -+ RTW89_BTC_WL_DEF_TX_PWR); -+ dm->trx_info.cn = wl->cn_report; -+ dm->trx_info.nhm = wl->nhm.pwr; -+ rtw89_fw_h2c_cxdrv_trx(rtwdev); -+ break; - case CXDRVINFO_RFK: - rtw89_fw_h2c_cxdrv_rfk(rtwdev); - break; -@@ -5361,6 +5377,8 @@ void rtw89_btc_ntfy_icmp_packet_work(str - mutex_unlock(&rtwdev->mutex); - } - -+#define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4) -+ - static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -@@ -5417,6 +5435,7 @@ static void _update_bt_info(struct rtw89 - a2dp->exist = btinfo.lb2.a2dp; - b->profile_cnt.now += (u8)a2dp->exist; - pan->active = btinfo.lb2.pan; -+ btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK); - - /* parse raw info low-Byte3 */ - btinfo.val = bt->raw_info[BTC_BTINFO_L3]; -@@ -5433,6 +5452,7 @@ static void _update_bt_info(struct rtw89 - btinfo.val = bt->raw_info[BTC_BTINFO_H0]; - /* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/ - b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi); -+ btc->dm.trx_info.bt_rssi = b->rssi; - - /* parse raw info high-Byte1 */ - btinfo.val = bt->raw_info[BTC_BTINFO_H1]; -@@ -5766,6 +5786,8 @@ static void rtw89_btc_ntfy_wl_sta_iter(v - (struct rtw89_btc_wl_sta_iter_data *)data; - struct rtw89_dev *rtwdev = iter_data->rtwdev; - struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ const struct rtw89_btc_ver *ver = btc->ver; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_link_info *link_info = NULL; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -@@ -5773,6 +5795,8 @@ static void rtw89_btc_ntfy_wl_sta_iter(v - struct rtw89_vif *rtwvif = rtwsta->rtwvif; - struct rtw89_traffic_stats *stats = &rtwvif->stats; - const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_btc_wl_role_info *r; -+ struct rtw89_btc_wl_role_info_v1 *r1; - u32 last_tx_rate, last_rx_rate; - u16 last_tx_lvl, last_rx_lvl; - u8 port = rtwvif->port; -@@ -5849,10 +5873,33 @@ static void rtw89_btc_ntfy_wl_sta_iter(v - link_info_t->tx_rate = rtwsta->ra_report.hw_rate; - link_info_t->rx_rate = rtwsta->rx_hw_rate; - -- wl->role_info.active_role[port].tx_lvl = (u16)stats->tx_tfc_lv; -- wl->role_info.active_role[port].rx_lvl = (u16)stats->rx_tfc_lv; -- wl->role_info.active_role[port].tx_rate = rtwsta->ra_report.hw_rate; -- wl->role_info.active_role[port].rx_rate = rtwsta->rx_hw_rate; -+ if (link_info->role == RTW89_WIFI_ROLE_STATION || -+ link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) { -+ dm->trx_info.tx_rate = link_info_t->tx_rate; -+ dm->trx_info.rx_rate = link_info_t->rx_rate; -+ } -+ -+ if (ver->fwlrole == 0) { -+ r = &wl->role_info; -+ r->active_role[port].tx_lvl = stats->tx_tfc_lv; -+ r->active_role[port].rx_lvl = stats->rx_tfc_lv; -+ r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate; -+ r->active_role[port].rx_rate = rtwsta->rx_hw_rate; -+ } else if (ver->fwlrole == 1) { -+ r1 = &wl->role_info_v1; -+ r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv; -+ r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv; -+ r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate; -+ r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate; -+ } else if (ver->fwlrole == 2) { -+ dm->trx_info.tx_lvl = stats->tx_tfc_lv; -+ dm->trx_info.rx_lvl = stats->rx_tfc_lv; -+ dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate; -+ dm->trx_info.rx_rate = rtwsta->rx_hw_rate; -+ } -+ -+ dm->trx_info.tx_tp = link_info_t->tx_throughput; -+ dm->trx_info.rx_tp = link_info_t->rx_throughput; - - if (is_sta_change) - iter_data->is_sta_change = true; -@@ -5866,6 +5913,7 @@ static void rtw89_btc_ntfy_wl_sta_iter(v - void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_dm *dm = &btc->dm; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; - struct rtw89_btc_wl_sta_iter_data data = {.rtwdev = rtwdev}; - u8 i; -@@ -5884,6 +5932,9 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_ - } - } - -+ if (dm->trx_info.wl_rssi != wl->rssi_level) -+ dm->trx_info.wl_rssi = wl->rssi_level; -+ - rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n", - __func__, !!wl->status.map.busy); - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1367,6 +1367,22 @@ struct rtw89_btc_rf_para { - u32 rx_gain_perpkt; - }; - -+struct rtw89_btc_wl_nhm { -+ u8 instant_wl_nhm_dbm; -+ u8 instant_wl_nhm_per_mhz; -+ u16 valid_record_times; -+ s8 record_pwr[16]; -+ u8 record_ratio[16]; -+ s8 pwr; /* dbm_per_MHz */ -+ u8 ratio; -+ u8 current_status; -+ u8 refresh; -+ bool start_flag; -+ u8 last_ccx_rpt_stamp; -+ s8 pwr_max; -+ s8 pwr_min; -+}; -+ - struct rtw89_btc_wl_info { - struct rtw89_btc_wl_link_info link_info[RTW89_PORT_NUM]; - struct rtw89_btc_wl_rfk_info rfk_info; -@@ -1378,10 +1394,12 @@ struct rtw89_btc_wl_info { - struct rtw89_btc_wl_scan_info scan_info; - struct rtw89_btc_wl_dbcc_info dbcc_info; - struct rtw89_btc_rf_para rf_para; -+ struct rtw89_btc_wl_nhm nhm; - union rtw89_btc_wl_state_map status; - - u8 port_id[RTW89_WIFI_ROLE_MLME_MAX]; - u8 rssi_level; -+ u8 cn_report; - - bool scbd_change; - u32 scbd; -@@ -2019,6 +2037,30 @@ struct rtw89_btc_rf_trx_para { - u8 bt_rx_gain; /* LNA constrain level */ - }; - -+struct rtw89_btc_trx_info { -+ u8 tx_lvl; -+ u8 rx_lvl; -+ u8 wl_rssi; -+ u8 bt_rssi; -+ -+ s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ -+ s8 rx_gain; /* rx gain table index (TBD.) */ -+ s8 bt_tx_power; /* decrease Tx power (dB) */ -+ s8 bt_rx_gain; /* LNA constrain level */ -+ -+ u8 cn; /* condition_num */ -+ s8 nhm; -+ u8 bt_profile; -+ u8 rsvd2; -+ -+ u16 tx_rate; -+ u16 rx_rate; -+ -+ u32 tx_tp; -+ u32 rx_tp; -+ u32 rx_err_ratio; -+}; -+ - struct rtw89_btc_dm { - struct rtw89_btc_fbtc_slot slot[CXST_MAX]; - struct rtw89_btc_fbtc_slot slot_now[CXST_MAX]; -@@ -2030,6 +2072,7 @@ struct rtw89_btc_dm { - struct rtw89_btc_wl_tx_limit_para wl_tx_limit; - struct rtw89_btc_dm_step dm_step; - struct rtw89_btc_wl_scc_ctrl wl_scc; -+ struct rtw89_btc_trx_info trx_info; - union rtw89_btc_dm_error_map error; - u32 cnt_dm[BTC_DCNT_NUM]; - u32 cnt_notify[BTC_NCNT_NUM]; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2169,6 +2169,62 @@ fail: - return ret; - } - -+#define H2C_LEN_CXDRVINFO_TRX (28 + H2C_LEN_CXDRVHDR) -+int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_trx_info *trx = &btc->dm.trx_info; -+ struct sk_buff *skb; -+ u8 *cmd; -+ int ret; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_TRX); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_trx\n"); -+ return -ENOMEM; -+ } -+ skb_put(skb, H2C_LEN_CXDRVINFO_TRX); -+ cmd = skb->data; -+ -+ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_TRX); -+ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_TRX - H2C_LEN_CXDRVHDR); -+ -+ RTW89_SET_FWCMD_CXTRX_TXLV(cmd, trx->tx_lvl); -+ RTW89_SET_FWCMD_CXTRX_RXLV(cmd, trx->rx_lvl); -+ RTW89_SET_FWCMD_CXTRX_WLRSSI(cmd, trx->wl_rssi); -+ RTW89_SET_FWCMD_CXTRX_BTRSSI(cmd, trx->bt_rssi); -+ RTW89_SET_FWCMD_CXTRX_TXPWR(cmd, trx->tx_power); -+ RTW89_SET_FWCMD_CXTRX_RXGAIN(cmd, trx->rx_gain); -+ RTW89_SET_FWCMD_CXTRX_BTTXPWR(cmd, trx->bt_tx_power); -+ RTW89_SET_FWCMD_CXTRX_BTRXGAIN(cmd, trx->bt_rx_gain); -+ RTW89_SET_FWCMD_CXTRX_CN(cmd, trx->cn); -+ RTW89_SET_FWCMD_CXTRX_NHM(cmd, trx->nhm); -+ RTW89_SET_FWCMD_CXTRX_BTPROFILE(cmd, trx->bt_profile); -+ RTW89_SET_FWCMD_CXTRX_RSVD2(cmd, trx->rsvd2); -+ RTW89_SET_FWCMD_CXTRX_TXRATE(cmd, trx->tx_rate); -+ RTW89_SET_FWCMD_CXTRX_RXRATE(cmd, trx->rx_rate); -+ RTW89_SET_FWCMD_CXTRX_TXTP(cmd, trx->tx_tp); -+ RTW89_SET_FWCMD_CXTRX_RXTP(cmd, trx->rx_tp); -+ RTW89_SET_FWCMD_CXTRX_RXERRRA(cmd, trx->rx_err_ratio); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_OUTSRC, BTFC_SET, -+ SET_DRV_INFO, 0, 0, -+ H2C_LEN_CXDRVINFO_TRX); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ - #define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) - int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) - { ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2152,6 +2152,7 @@ enum rtw89_btc_cxdrvinfo { - CXDRVINFO_RUN, - CXDRVINFO_CTRL, - CXDRVINFO_SCAN, -+ CXDRVINFO_TRX, /* WL traffic to WL fw */ - CXDRVINFO_MAX, - }; - -@@ -2493,6 +2494,91 @@ static inline void RTW89_SET_FWCMD_CXCTR - le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(18, 3)); - } - -+static inline void RTW89_SET_FWCMD_CXTRX_TXLV(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 2, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RXLV(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 3, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_WLRSSI(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 4, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_BTRSSI(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 5, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_TXPWR(void *cmd, s8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 6, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RXGAIN(void *cmd, s8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 7, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_BTTXPWR(void *cmd, s8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 8, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_BTRXGAIN(void *cmd, s8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 9, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_CN(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 10, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_NHM(void *cmd, s8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 11, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_BTPROFILE(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 12, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RSVD2(void *cmd, u8 val) -+{ -+ u8p_replace_bits((u8 *)cmd + 13, val, GENMASK(7, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_TXRATE(void *cmd, u16 val) -+{ -+ le16p_replace_bits((__le16 *)((u8 *)cmd + 14), val, GENMASK(15, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RXRATE(void *cmd, u16 val) -+{ -+ le16p_replace_bits((__le16 *)((u8 *)cmd + 16), val, GENMASK(15, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_TXTP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)((u8 *)cmd + 18), val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RXTP(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)((u8 *)cmd + 22), val, GENMASK(31, 0)); -+} -+ -+static inline void RTW89_SET_FWCMD_CXTRX_RXERRRA(void *cmd, u32 val) -+{ -+ le32p_replace_bits((__le32 *)((u8 *)cmd + 26), val, GENMASK(31, 0)); -+} -+ - static inline void RTW89_SET_FWCMD_CXRFK_STATE(void *cmd, u32 val) - { - le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(1, 0)); -@@ -3557,6 +3643,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89 - int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev); -+int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id); - int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-013-wifi-rtw89-coex-Add-register-monitor-report-v2-forma.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-013-wifi-rtw89-coex-Add-register-monitor-report-v2-forma.patch deleted file mode 100644 index 8ec2342b8..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-013-wifi-rtw89-coex-Add-register-monitor-report-v2-forma.patch +++ /dev/null @@ -1,283 +0,0 @@ -From e5e52feb5053a537180cf928428deb8bc697a42e Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:22 +0800 -Subject: [PATCH 013/136] wifi: rtw89: coex: Add register monitor report v2 - format - -The v2 firmware report reduce its maximum register numbers from 30 to 20, -it can help to save firmware code size. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 148 ++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 17 ++- - 2 files changed, 151 insertions(+), 14 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -226,7 +226,6 @@ struct rtw89_btc_btf_set_slot_table { - u8 buf[]; - } __packed; - --#define BTF_SET_MON_REG_VER 1 - struct rtw89_btc_btf_set_mon_reg { - u8 fver; - u8 reg_num; -@@ -1078,8 +1077,15 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_MREG: - pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; -- pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); -+ if (ver->fcxmreg == 1) { -+ pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v1; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v1); -+ } else if (ver->fcxmreg == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2); -+ } else { -+ goto err; -+ } - pcinfo->req_fver = ver->fcxmreg; - break; - case BTC_RPT_TYPE_GPIO_DBG: -@@ -1709,18 +1715,26 @@ static void rtw89_btc_fw_set_slots(struc - static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver; - struct rtw89_btc_btf_set_mon_reg *monreg = NULL; -- u8 n, *ptr = NULL, ulen; -+ u8 n, *ptr = NULL, ulen, cxmreg_max; - u16 sz = 0; - - n = chip->mon_reg_num; -- - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): mon_reg_num=%d\n", __func__, n); -- if (n > CXMREG_MAX) { -+ -+ if (ver->fcxmreg == 1) -+ cxmreg_max = CXMREG_MAX; -+ else if (ver->fcxmreg == 2) -+ cxmreg_max = CXMREG_MAX_V2; -+ else -+ return; -+ -+ if (n > cxmreg_max) { - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): mon reg count %d > %d\n", -- __func__, n, CXMREG_MAX); -+ __func__, n, cxmreg_max); - return; - } - -@@ -1730,7 +1744,7 @@ static void btc_fw_set_monreg(struct rtw - if (!monreg) - return; - -- monreg->fver = BTF_SET_MON_REG_VER; -+ monreg->fver = ver->fcxmreg; - monreg->reg_num = n; - ptr = &monreg->buf[0]; - memcpy(ptr, chip->mon_reg, n * ulen); -@@ -7401,13 +7415,13 @@ static void _get_gnt(struct rtw89_dev *r - } - } - --static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) -+static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m) - { - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_btc *btc = &rtwdev->btc; - struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; - struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -- struct rtw89_btc_fbtc_mreg_val *pmreg = NULL; -+ struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL; - struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; - struct rtw89_btc_cx *cx = &btc->cx; - struct rtw89_btc_wl_info *wl = &btc->cx.wl; -@@ -7457,7 +7471,7 @@ static void _show_mreg(struct rtw89_dev - return; - } - -- pmreg = &pfwinfo->rpt_fbtc_mregval.finfo; -+ pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1; - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", - __func__, pmreg->reg_num); -@@ -7486,6 +7500,111 @@ static void _show_mreg(struct rtw89_dev - rtw89_debug(rtwdev, RTW89_DBG_BTC, - "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", - __func__); -+ seq_puts(m, "\n"); -+ return; -+ } -+ -+ gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; -+ if (!gdbg->en_map) -+ return; -+ -+ seq_printf(m, " %-15s : enable_map:0x%08x", -+ "[gpio_dbg]", gdbg->en_map); -+ -+ for (i = 0; i < BTC_DBG_MAX1; i++) { -+ if (!(gdbg->en_map & BIT(i))) -+ continue; -+ seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]); -+ } -+ seq_puts(m, "\n"); -+} -+ -+static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; -+ struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL; -+ struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; -+ struct rtw89_btc_cx *cx = &btc->cx; -+ struct rtw89_btc_wl_info *wl = &btc->cx.wl; -+ struct rtw89_btc_bt_info *bt = &btc->cx.bt; -+ struct rtw89_mac_ax_coex_gnt gnt_cfg = {}; -+ struct rtw89_mac_ax_gnt gnt; -+ u8 i = 0, type = 0, cnt = 0; -+ u32 val, offset; -+ -+ if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) -+ return; -+ -+ seq_puts(m, "========== [HW Status] ==========\n"); -+ -+ seq_printf(m, -+ " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", -+ "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], -+ bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], -+ cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); -+ -+ /* To avoid I/O if WL LPS or power-off */ -+ if (!wl->status.map.lps && !wl->status.map.rf_off) { -+ btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); -+ -+ _get_gnt(rtwdev, &gnt_cfg); -+ gnt = gnt_cfg.band[0]; -+ seq_printf(m, -+ " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", -+ "[gnt_status]", -+ chip->chip_id == RTL8852C ? "HW" : -+ btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT", -+ gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl, -+ gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt); -+ -+ gnt = gnt_cfg.band[1]; -+ seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", -+ gnt.gnt_wl_sw_en ? "SW" : "HW", -+ gnt.gnt_wl, -+ gnt.gnt_bt_sw_en ? "SW" : "HW", -+ gnt.gnt_bt); -+ } -+ pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; -+ if (!pcinfo->valid) { -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", -+ __func__); -+ return; -+ } -+ -+ pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2; -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", -+ __func__, pmreg->reg_num); -+ -+ for (i = 0; i < pmreg->reg_num; i++) { -+ type = (u8)le16_to_cpu(chip->mon_reg[i].type); -+ offset = le32_to_cpu(chip->mon_reg[i].offset); -+ val = le32_to_cpu(pmreg->mreg_val[i]); -+ -+ if (cnt % 6 == 0) -+ seq_printf(m, " %-15s : %d_0x%04x=0x%08x", -+ "[reg]", (u32)type, offset, val); -+ else -+ seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, -+ offset, val); -+ if (cnt % 6 == 5) -+ seq_puts(m, "\n"); -+ cnt++; -+ -+ if (i >= pmreg->reg_num) -+ seq_puts(m, "\n"); -+ } -+ -+ pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; -+ if (!pcinfo->valid) { -+ rtw89_debug(rtwdev, RTW89_DBG_BTC, -+ "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", -+ __func__); -+ seq_puts(m, "\n"); - return; - } - -@@ -7868,7 +7987,12 @@ void rtw89_btc_dump_info(struct rtw89_de - _show_bt_info(rtwdev, m); - _show_dm_info(rtwdev, m); - _show_fw_dm_msg(rtwdev, m); -- _show_mreg(rtwdev, m); -+ -+ if (ver->fcxmreg == 1) -+ _show_mreg_v1(rtwdev, m); -+ else if (ver->fcxmreg == 2) -+ _show_mreg_v2(rtwdev, m); -+ - if (ver->fcxbtcrpt == 1) - _show_summary_v1(rtwdev, m); - else if (ver->fcxbtcrpt == 4) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1524,6 +1524,7 @@ union rtw89_btc_fbtc_tdma_le32 { - }; - - #define CXMREG_MAX 30 -+#define CXMREG_MAX_V2 20 - #define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ - #define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ - -@@ -1750,13 +1751,25 @@ struct rtw89_btc_fbtc_gpio_dbg { - u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */ - } __packed; - --struct rtw89_btc_fbtc_mreg_val { -+struct rtw89_btc_fbtc_mreg_val_v1 { - u8 fver; /* btc_ver::fcxmreg */ - u8 reg_num; - __le16 rsvd; - __le32 mreg_val[CXMREG_MAX]; - } __packed; - -+struct rtw89_btc_fbtc_mreg_val_v2 { -+ u8 fver; /* btc_ver::fcxmreg */ -+ u8 reg_num; -+ __le16 rsvd; -+ __le32 mreg_val[CXMREG_MAX_V2]; -+} __packed; -+ -+union rtw89_btc_fbtc_mreg_val { -+ struct rtw89_btc_fbtc_mreg_val_v1 v1; -+ struct rtw89_btc_fbtc_mreg_val_v2 v2; -+}; -+ - #define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \ - { .type = cpu_to_le16(__type), .bytes = cpu_to_le16(__bytes), \ - .offset = cpu_to_le32(__offset), } -@@ -2203,7 +2216,7 @@ struct rtw89_btc_rpt_fbtc_nullsta { - - struct rtw89_btc_rpt_fbtc_mreg { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- struct rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ -+ union rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ - }; - - struct rtw89_btc_rpt_fbtc_gpio_dbg { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-014-wifi-rtw89-coex-Fix-wrong-structure-assignment-at-nu.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-014-wifi-rtw89-coex-Fix-wrong-structure-assignment-at-nu.patch deleted file mode 100644 index 0ddc27bd1..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-014-wifi-rtw89-coex-Fix-wrong-structure-assignment-at-nu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9dfa09e0628d2024ce4574f645344c00fe88a535 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:23 +0800 -Subject: [PATCH 014/136] wifi: rtw89: coex: Fix wrong structure assignment at - null data report - -Correct pointer assignment of v1 null data report. It doesn't really -change logic at all, but it looks more readable. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1065,7 +1065,7 @@ static u32 _chk_btc_report(struct rtw89_ - case BTC_RPT_TYPE_NULLSTA: - pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; - if (ver->fcxnullsta == 1) { -- pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo; -+ pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v1; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); - } else if (ver->fcxnullsta == 2) { - pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-015-wifi-rtw89-coex-Add-v2-Bluetooth-scan-info.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-015-wifi-rtw89-coex-Add-v2-Bluetooth-scan-info.patch deleted file mode 100644 index d28722284..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-015-wifi-rtw89-coex-Add-v2-Bluetooth-scan-info.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 262cc19ea902d2280e2e2a56b153f37466e3349e Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:24 +0800 -Subject: [PATCH 015/136] wifi: rtw89: coex: Add v2 Bluetooth scan info - -Compare to v1 and v2 removed some not usable parameters. Save firmware -code size. The information can show how frequent and how long the -Bluetooth scan do. It will help to debug coexistence issue. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 67 +++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 63 +++++++++++++++------ - 2 files changed, 106 insertions(+), 24 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -890,13 +890,15 @@ static void _update_bt_report(struct rtw - struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; - struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; - struct rtw89_btc_fbtc_btver *pver = NULL; -- struct rtw89_btc_fbtc_btscan *pscan = NULL; -+ struct rtw89_btc_fbtc_btscan_v1 *pscan_v1; -+ struct rtw89_btc_fbtc_btscan_v2 *pscan_v2; - struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL; - struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL; - struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; -+ bool scan_update = true; -+ int i; - - pver = (struct rtw89_btc_fbtc_btver *)pfinfo; -- pscan = (struct rtw89_btc_fbtc_btscan *)pfinfo; - pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; - - rtw89_debug(rtwdev, RTW89_DBG_BTC, -@@ -910,7 +912,26 @@ static void _update_bt_report(struct rtw - bt->feature = le32_to_cpu(pver->feature); - break; - case BTC_RPT_TYPE_BT_SCAN: -- memcpy(bt->scan_info, pscan->scan, BTC_SCAN_MAX1); -+ if (ver->fcxbtscan == 1) { -+ pscan_v1 = (struct rtw89_btc_fbtc_btscan_v1 *)pfinfo; -+ for (i = 0; i < BTC_SCAN_MAX1; i++) { -+ bt->scan_info_v1[i] = pscan_v1->scan[i]; -+ if (bt->scan_info_v1[i].win == 0 && -+ bt->scan_info_v1[i].intvl == 0) -+ scan_update = false; -+ } -+ } else if (ver->fcxbtscan == 2) { -+ pscan_v2 = (struct rtw89_btc_fbtc_btscan_v2 *)pfinfo; -+ for (i = 0; i < CXSCAN_MAX; i++) { -+ bt->scan_info_v2[i] = pscan_v2->para[i]; -+ if ((pscan_v2->type & BIT(i)) && -+ pscan_v2->para[i].win == 0 && -+ pscan_v2->para[i].intvl == 0) -+ scan_update = false; -+ } -+ } -+ if (scan_update) -+ bt->scan_info_update = 1; - break; - case BTC_RPT_TYPE_BT_AFH: - if (ver->fcxbtafh == 2) { -@@ -1102,8 +1123,13 @@ static u32 _chk_btc_report(struct rtw89_ - break; - case BTC_RPT_TYPE_BT_SCAN: - pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; -- pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; -- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); -+ if (ver->fcxbtscan == 1) { -+ pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v1; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v1); -+ } else if (ver->fcxbtscan == 2) { -+ pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2); -+ } - pcinfo->req_fver = ver->fcxbtscan; - break; - case BTC_RPT_TYPE_BT_AFH: -@@ -6346,11 +6372,40 @@ static void _show_bt_info(struct rtw89_d - cx->cnt_bt[BTC_BCNT_INFOSAME]); - - seq_printf(m, -- " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)\n", -+ " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)", - "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], - cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], - cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); - -+ if (!bt->scan_info_update) { -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true); -+ seq_puts(m, "\n"); -+ } else { -+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false); -+ if (ver->fcxbtscan == 1) { -+ seq_printf(m, -+ "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)", -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win), -+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl)); -+ } else if (ver->fcxbtscan == 2) { -+ seq_printf(m, -+ "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)", -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win), -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl), -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win), -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl), -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win), -+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl)); -+ } -+ seq_puts(m, "\n"); -+ } -+ - if (bt->enable.now && bt->ver_info.fw == 0) - rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); - else ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1445,14 +1445,6 @@ struct rtw89_btc_wl_tx_limit_para { - u16 tx_retry; - }; - --struct rtw89_btc_bt_scan_info { -- u16 win; -- u16 intvl; -- u32 enable: 1; -- u32 interlace: 1; -- u32 rsvd: 30; --}; -- - enum rtw89_btc_bt_scan_type { - BTC_SCAN_INQ = 0, - BTC_SCAN_PAGE, -@@ -1463,9 +1455,50 @@ enum rtw89_btc_bt_scan_type { - BTC_SCAN_MAX1, - }; - -+enum rtw89_btc_ble_scan_type { -+ CXSCAN_BG = 0, -+ CXSCAN_INIT, -+ CXSCAN_LE, -+ CXSCAN_MAX -+}; -+ -+#define RTW89_BTC_BTC_SCAN_V1_FLAG_ENABLE BIT(0) -+#define RTW89_BTC_BTC_SCAN_V1_FLAG_INTERLACE BIT(1) -+ -+struct rtw89_btc_bt_scan_info_v1 { -+ __le16 win; -+ __le16 intvl; -+ __le32 flags; -+} __packed; -+ -+struct rtw89_btc_bt_scan_info_v2 { -+ __le16 win; -+ __le16 intvl; -+} __packed; -+ -+struct rtw89_btc_fbtc_btscan_v1 { -+ u8 fver; /* btc_ver::fcxbtscan */ -+ u8 rsvd; -+ __le16 rsvd2; -+ struct rtw89_btc_bt_scan_info_v1 scan[BTC_SCAN_MAX1]; -+} __packed; -+ -+struct rtw89_btc_fbtc_btscan_v2 { -+ u8 fver; /* btc_ver::fcxbtscan */ -+ u8 type; -+ __le16 rsvd2; -+ struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX]; -+} __packed; -+ -+union rtw89_btc_fbtc_btscan { -+ struct rtw89_btc_fbtc_btscan_v1 v1; -+ struct rtw89_btc_fbtc_btscan_v2 v2; -+}; -+ - struct rtw89_btc_bt_info { - struct rtw89_btc_bt_link_info link_info; -- struct rtw89_btc_bt_scan_info scan_info[BTC_SCAN_MAX1]; -+ struct rtw89_btc_bt_scan_info_v1 scan_info_v1[BTC_SCAN_MAX1]; -+ struct rtw89_btc_bt_scan_info_v2 scan_info_v2[CXSCAN_MAX]; - struct rtw89_btc_bt_ver_info ver_info; - struct rtw89_btc_bool_sta_chg enable; - struct rtw89_btc_bool_sta_chg inq_pag; -@@ -1488,7 +1521,8 @@ struct rtw89_btc_bt_info { - u32 run_patch_code: 1; - u32 hi_lna_rx: 1; - u32 scan_rx_low_pri: 1; -- u32 rsvd: 21; -+ u32 scan_info_update: 1; -+ u32 rsvd: 20; - }; - - struct rtw89_btc_cx { -@@ -2006,13 +2040,6 @@ struct rtw89_btc_fbtc_btver { - __le32 feature; - } __packed; - --struct rtw89_btc_fbtc_btscan { -- u8 fver; /* btc_ver::fcxbtscan */ -- u8 rsvd; -- __le16 rsvd2; -- u8 scan[6]; --} __packed; -- - struct rtw89_btc_fbtc_btafh { - u8 fver; /* btc_ver::fcxbtafh */ - u8 rsvd; -@@ -2231,7 +2258,7 @@ struct rtw89_btc_rpt_fbtc_btver { - - struct rtw89_btc_rpt_fbtc_btscan { - struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ -- struct rtw89_btc_fbtc_btscan finfo; /* info from fw */ -+ union rtw89_btc_fbtc_btscan finfo; /* info from fw */ - }; - - struct rtw89_btc_rpt_fbtc_btafh { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-016-wifi-rtw89-coex-Add-v5-firmware-cycle-status-report.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-016-wifi-rtw89-coex-Add-v5-firmware-cycle-status-report.patch deleted file mode 100644 index dbbfc81f9..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-016-wifi-rtw89-coex-Add-v5-firmware-cycle-status-report.patch +++ /dev/null @@ -1,375 +0,0 @@ -From 3ab7f9b90cc0a737e0bd8a312dc48814c4682867 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 8 Mar 2023 13:32:25 +0800 -Subject: [PATCH 016/136] wifi: rtw89: coex: Add v5 firmware cycle status - report - -To support v5 version firmware cycle report, apply the related structure -and functions. v5 cycle report add a group of status to show how the -free-run/TDMA training goes to. It is a firmware mechanism that can auto -adjust coexistence mode between TDMA and free run mechanism at 3 antenna -solution. v5 version provide more reference data to let the mechanism -make decision. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230308053225.24377-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 194 +++++++++++++++++++++- - drivers/net/wireless/realtek/rtw89/coex.h | 5 + - drivers/net/wireless/realtek/rtw89/core.h | 52 ++++++ - 3 files changed, 249 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -987,8 +987,8 @@ static u32 _chk_btc_report(struct rtw89_ - void *rpt_content = NULL, *pfinfo = NULL; - u8 rpt_type = 0; - u16 wl_slot_set = 0, wl_slot_real = 0; -- u32 trace_step = btc->ctrl.trace_step, rpt_len = 0, diff_t; -- u32 cnt_leak_slot = 0, bt_slot_real = 0, cnt_rx_imr = 0; -+ u32 trace_step = btc->ctrl.trace_step, rpt_len = 0, diff_t = 0; -+ u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr; - u8 i; - - rtw89_debug(rtwdev, RTW89_DBG_BTC, -@@ -1061,6 +1061,10 @@ static u32 _chk_btc_report(struct rtw89_ - pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4; - pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4); -+ } else if (ver->fcxcysta == 5) { -+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5; -+ pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5); - } else { - goto err; - } -@@ -1406,6 +1410,54 @@ static u32 _chk_btc_report(struct rtw89_ - le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); - _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, - le16_to_cpu(pcysta->v4.cycles)); -+ } else if (ver->fcxcysta == 5) { -+ if (dm->fddt_train == BTC_FDDT_ENABLE) -+ break; -+ cnt_leak_slot = le16_to_cpu(pcysta->v5.slot_cnt[CXST_LK]); -+ cnt_rx_imr = le32_to_cpu(pcysta->v5.leak_slot.cnt_rximr); -+ -+ /* Check Leak-AP */ -+ if (cnt_leak_slot != 0 && cnt_rx_imr != 0 && -+ dm->tdma_now.rxflctrl) { -+ if (le16_to_cpu(pcysta->v5.cycles) >= BTC_CYSTA_CHK_PERIOD && -+ cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr) -+ dm->leak_ap = 1; -+ } -+ -+ /* Check diff time between real WL slot and W1 slot */ -+ if (dm->tdma_now.type == CXTDMA_OFF) { -+ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); -+ wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]); -+ -+ if (wl_slot_real > wl_slot_set) -+ diff_t = wl_slot_real - wl_slot_set; -+ else -+ diff_t = wl_slot_set - wl_slot_real; -+ } -+ _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); -+ -+ /* Check diff time between real BT slot and EBT/E5G slot */ -+ bt_slot_set = btc->bt_req_len; -+ bt_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_BT]); -+ diff_t = 0; -+ if (dm->tdma_now.type == CXTDMA_OFF && -+ dm->tdma_now.ext_ctrl == CXECTL_EXT && -+ bt_slot_set != 0) { -+ if (bt_slot_set > bt_slot_real) -+ diff_t = bt_slot_set - bt_slot_real; -+ else -+ diff_t = bt_slot_real - bt_slot_set; -+ } -+ -+ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); -+ _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG, -+ le16_to_cpu(pcysta->v5.slot_cnt[CXST_E2G])); -+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG, -+ le16_to_cpu(pcysta->v5.slot_cnt[CXST_W1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG, -+ le16_to_cpu(pcysta->v5.slot_cnt[CXST_B1])); -+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG, -+ le16_to_cpu(pcysta->v5.cycles)); - } else { - goto err; - } -@@ -5039,6 +5091,7 @@ void _run_coex(struct rtw89_dev *rtwdev, - } - - dm->cnt_dm[BTC_DCNT_RUN]++; -+ dm->fddt_train = BTC_FDDT_DISABLE; - - if (btc->ctrl.always_freerun) { - _action_freerun(rtwdev); -@@ -6727,6 +6780,10 @@ static void _show_error(struct rtw89_dev - pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4; - except_cnt = pcysta->v4.except_cnt; - exception_map = le32_to_cpu(pcysta->v4.except_map); -+ } else if (ver->fcxcysta == 5) { -+ pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5; -+ except_cnt = pcysta->v5.except_cnt; -+ exception_map = le32_to_cpu(pcysta->v5.except_map); - } else { - return; - } -@@ -7215,6 +7272,137 @@ static void _show_fbtc_cysta_v4(struct r - } - } - -+static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 *a2dp_trx; -+ struct rtw89_btc_fbtc_cysta_v5 *pcysta; -+ struct rtw89_btc_rpt_cmn_info *pcinfo; -+ u8 i, cnt = 0, slot_pair, divide_cnt; -+ u16 cycle, c_begin, c_end, store_index; -+ -+ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; -+ if (!pcinfo->valid) -+ return; -+ -+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5; -+ seq_printf(m, -+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", -+ "[cycle_cnt]", -+ le16_to_cpu(pcysta->cycles), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]), -+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK])); -+ -+ for (i = 0; i < CXST_MAX; i++) { -+ if (!le16_to_cpu(pcysta->slot_cnt[i])) -+ continue; -+ -+ seq_printf(m, ", %s:%d", id_to_slot(i), -+ le16_to_cpu(pcysta->slot_cnt[i])); -+ } -+ -+ if (dm->tdma_now.rxflctrl) -+ seq_printf(m, ", leak_rx:%d", -+ le32_to_cpu(pcysta->leak_slot.cnt_rximr)); -+ -+ if (pcysta->collision_cnt) -+ seq_printf(m, ", collision:%d", pcysta->collision_cnt); -+ -+ if (le16_to_cpu(pcysta->skip_cnt)) -+ seq_printf(m, ", skip:%d", -+ le16_to_cpu(pcysta->skip_cnt)); -+ -+ seq_puts(m, "\n"); -+ -+ seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", -+ "[cycle_time]", -+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]), -+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]), -+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000, -+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000); -+ seq_printf(m, -+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n", -+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]), -+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]), -+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000, -+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000); -+ -+ cycle = le16_to_cpu(pcysta->cycles); -+ if (cycle <= 1) -+ return; -+ -+ /* 1 cycle record 1 wl-slot and 1 bt-slot */ -+ slot_pair = BTC_CYCLE_SLOT_MAX / 2; -+ -+ if (cycle <= slot_pair) -+ c_begin = 1; -+ else -+ c_begin = cycle - slot_pair + 1; -+ -+ c_end = cycle; -+ -+ if (a2dp->exist) -+ divide_cnt = 3; -+ else -+ divide_cnt = BTC_CYCLE_SLOT_MAX / 4; -+ -+ if (c_begin > c_end) -+ return; -+ -+ for (cycle = c_begin; cycle <= c_end; cycle++) { -+ cnt++; -+ store_index = ((cycle - 1) % slot_pair) * 2; -+ -+ if (cnt % divide_cnt == 1) -+ seq_printf(m, " %-15s : ", "[cycle_step]"); -+ -+ seq_printf(m, "->b%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ seq_printf(m, "->w%02d", -+ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); -+ if (a2dp->exist) { -+ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; -+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)", -+ a2dp_trx->empty_cnt, -+ a2dp_trx->retry_cnt, -+ a2dp_trx->tx_rate ? 3 : 2, -+ a2dp_trx->tx_cnt, -+ a2dp_trx->ack_cnt, -+ a2dp_trx->nack_cnt); -+ } -+ if (cnt % divide_cnt == 0 || cnt == c_end) -+ seq_puts(m, "\n"); -+ } -+ -+ if (a2dp->exist) { -+ seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d", -+ "[a2dp_t_sta]", -+ le16_to_cpu(pcysta->a2dp_ept.cnt), -+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout)); -+ -+ seq_printf(m, ", avg_t:%d, max_t:%d", -+ le16_to_cpu(pcysta->a2dp_ept.tavg), -+ le16_to_cpu(pcysta->a2dp_ept.tmax)); -+ -+ seq_puts(m, "\n"); -+ } -+} -+ - static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -7419,6 +7607,8 @@ static void _show_fw_dm_msg(struct rtw89 - _show_fbtc_cysta_v3(rtwdev, m); - else if (ver->fcxcysta == 4) - _show_fbtc_cysta_v4(rtwdev, m); -+ else if (ver->fcxcysta == 5) -+ _show_fbtc_cysta_v5(rtwdev, m); - - _show_fbtc_nullsta(rtwdev, m); - ---- a/drivers/net/wireless/realtek/rtw89/coex.h -+++ b/drivers/net/wireless/realtek/rtw89/coex.h -@@ -66,6 +66,11 @@ enum btc_rssi_st { - BTC_RSSI_ST_MAX - }; - -+enum btc_fddt_en { -+ BTC_FDDT_DISABLE, -+ BTC_FDDT_ENABLE, -+}; -+ - #define BTC_RSSI_HIGH(_rssi_) \ - ({typeof(_rssi_) __rssi = (_rssi_); \ - ((__rssi == BTC_RSSI_ST_HIGH || \ ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1894,6 +1894,11 @@ struct rtw89_btc_fbtc_cycle_time_info { - __le16 tmaxdiff[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ - } __packed; - -+struct rtw89_btc_fbtc_cycle_time_info_v5 { -+ __le16 tavg[CXT_MAX]; /* avg wl/bt cycle time */ -+ __le16 tmax[CXT_MAX]; /* max wl/bt cycle time */ -+} __packed; -+ - struct rtw89_btc_fbtc_a2dp_trx_stat { - u8 empty_cnt; - u8 retry_cnt; -@@ -1950,6 +1955,21 @@ struct rtw89_btc_fbtc_cycle_fddt_info { - #define RTW89_BTC_FDDT_CELL_TRAIN_STATE GENMASK(3, 0) - #define RTW89_BTC_FDDT_CELL_TRAIN_PHASE GENMASK(7, 4) - -+struct rtw89_btc_fbtc_cycle_fddt_info_v5 { -+ __le16 train_cycle; -+ __le16 tp; -+ -+ s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ -+ s8 bt_tx_power; /* decrease Tx power (dB) */ -+ s8 bt_rx_gain; /* LNA constrain level */ -+ u8 no_empty_cnt; -+ -+ u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */ -+ u8 cn; /* condition_num */ -+ u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */ -+ u8 train_result; /* refer to enum btc_fddt_check_map */ -+} __packed; -+ - struct rtw89_btc_fbtc_fddt_cell_status { - s8 wl_tx_pwr; - s8 bt_tx_pwr; -@@ -1957,6 +1977,12 @@ struct rtw89_btc_fbtc_fddt_cell_status { - u8 state_phase; /* [0:3] train state, [4:7] train phase */ - } __packed; - -+struct rtw89_btc_fbtc_fddt_cell_status_v5 { -+ s8 wl_tx_pwr; -+ s8 bt_tx_pwr; -+ s8 bt_rx_gain; -+} __packed; -+ - struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ - u8 fver; - u8 rsvd; -@@ -2002,10 +2028,35 @@ struct rtw89_btc_fbtc_cysta_v4 { /* stat - __le32 except_map; - } __packed; - -+struct rtw89_btc_fbtc_cysta_v5 { /* statistics for cycles */ -+ u8 fver; -+ u8 rsvd; -+ u8 collision_cnt; /* counter for event/timer occur at the same time */ -+ u8 except_cnt; -+ u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX]; -+ -+ __le16 skip_cnt; -+ __le16 cycles; /* total cycle number */ -+ -+ __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */ -+ __le16 slot_cnt[CXST_MAX]; /* slot count */ -+ __le16 bcn_cnt[CXBCN_MAX]; -+ struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time; -+ struct rtw89_btc_fbtc_cycle_leak_info leak_slot; -+ struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; -+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; -+ struct rtw89_btc_fbtc_cycle_fddt_info_v5 fddt_trx[BTC_CYCLE_SLOT_MAX]; -+ struct rtw89_btc_fbtc_fddt_cell_status_v5 fddt_cells[FDD_TRAIN_WL_DIRECTION] -+ [FDD_TRAIN_WL_RSSI_LEVEL] -+ [FDD_TRAIN_BT_RSSI_LEVEL]; -+ __le32 except_map; -+} __packed; -+ - union rtw89_btc_fbtc_cysta_info { - struct rtw89_btc_fbtc_cysta_v2 v2; - struct rtw89_btc_fbtc_cysta_v3 v3; - struct rtw89_btc_fbtc_cysta_v4 v4; -+ struct rtw89_btc_fbtc_cysta_v5 v5; - }; - - struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ -@@ -2123,6 +2174,7 @@ struct rtw89_btc_dm { - u32 wl_only: 1; - u32 wl_fw_cx_offload: 1; - u32 freerun: 1; -+ u32 fddt_train: 1; - u32 wl_ps_ctrl: 2; - u32 wl_mimo_ps: 1; - u32 leak_ap: 1; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-017-wifi-rtw89-coex-Add-LPS-protocol-radio-state-for-RTL.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-017-wifi-rtw89-coex-Add-LPS-protocol-radio-state-for-RTL.patch deleted file mode 100644 index bd949ff2e..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-017-wifi-rtw89-coex-Add-LPS-protocol-radio-state-for-RTL.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 70a13e5f00e9ee5497b0c25c2787347c4431b5e4 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 14 Mar 2023 10:06:13 +0800 -Subject: [PATCH 017/136] wifi: rtw89: coex: Add LPS protocol radio state for - RTL8852B - -This LPS state will not turn off RF, and it can still do some basic -traffic, only RTL8852B has the state. Coexistence need let Bluetooth -know WiFi is still alive to prevent some Bluetooth performance issue. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230314020617.28193-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 10 +++++++++- - drivers/net/wireless/realtek/rtw89/coex.h | 1 + - 2 files changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -5728,6 +5728,11 @@ void rtw89_btc_ntfy_radio_state(struct r - wl->status.map.lps = BTC_LPS_RF_OFF; - wl->status.map.busy = 0; - break; -+ case BTC_RFCTRL_LPS_WL_ON: /* LPS-Protocol (RFon) */ -+ wl->status.map.rf_off = 0; -+ wl->status.map.lps = BTC_LPS_RF_ON; -+ wl->status.map.busy = 0; -+ break; - case BTC_RFCTRL_WL_ON: - default: - wl->status.map.rf_off = 0; -@@ -5745,6 +5750,9 @@ void rtw89_btc_ntfy_radio_state(struct r - rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false); - if (rf_state == BTC_RFCTRL_WL_OFF) - _write_scbd(rtwdev, BTC_WSCB_ALL, false); -+ else if (rf_state == BTC_RFCTRL_LPS_WL_ON && -+ wl->status.map.lps_pre != BTC_LPS_OFF) -+ _update_bt_scbd(rtwdev, true); - } - - btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; -@@ -5755,7 +5763,7 @@ void rtw89_btc_ntfy_radio_state(struct r - btc->dm.tdma_instant_excute = 0; - - _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); -- -+ btc->dm.tdma_instant_excute = 0; - wl->status.map.rf_off_pre = wl->status.map.rf_off; - wl->status.map.lps_pre = wl->status.map.lps; - } ---- a/drivers/net/wireless/realtek/rtw89/coex.h -+++ b/drivers/net/wireless/realtek/rtw89/coex.h -@@ -131,6 +131,7 @@ enum btc_role_state { - enum btc_rfctrl { - BTC_RFCTRL_WL_OFF, - BTC_RFCTRL_WL_ON, -+ BTC_RFCTRL_LPS_WL_ON, - BTC_RFCTRL_FW_CTRL, - BTC_RFCTRL_MAX - }; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-018-wifi-rtw89-coex-Not-to-enable-firmware-report-when-W.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-018-wifi-rtw89-coex-Not-to-enable-firmware-report-when-W.patch deleted file mode 100644 index d43282d2f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-018-wifi-rtw89-coex-Not-to-enable-firmware-report-when-W.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 829b3a8b212a71b55598b9bd5861a41906a611ae Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 14 Mar 2023 10:06:14 +0800 -Subject: [PATCH 018/136] wifi: rtw89: coex: Not to enable firmware report when - WiFi is power saving - -If driver enable firmware report during WiFi power saving, the -firmware timer will lead to some power saving issue like, -fail to enter LPS, can not leave LPS or some unexpected issue. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230314020617.28193-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1741,10 +1741,14 @@ static void rtw89_btc_fw_en_rpt(struct r - u32 rpt_map, bool rpt_state) - { - struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map; - struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; - struct rtw89_btc_btf_set_report r = {0}; - u32 val, bit_map; - -+ if ((wl_smap->rf_off || wl_smap->lps != BTC_LPS_OFF) && rpt_state != 0) -+ return; -+ - bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map); - - rtw89_debug(rtwdev, RTW89_DBG_BTC, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-019-wifi-rtw89-coex-Update-RTL8852B-LNA2-hardware-parame.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-019-wifi-rtw89-coex-Update-RTL8852B-LNA2-hardware-parame.patch deleted file mode 100644 index 0d35fbf34..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-019-wifi-rtw89-coex-Update-RTL8852B-LNA2-hardware-parame.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 20595db3c0681cc034e50fbcba85a1e6cf3325b5 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 14 Mar 2023 10:06:15 +0800 -Subject: [PATCH 019/136] wifi: rtw89: coex: Update RTL8852B LNA2 hardware - parameter - -The LNA gain didn't set before, it will lead some WiFi RX issue. -And the setting can increase both of WiFi & BT performance while -they are both RX. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230314020617.28193-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 +- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 11 ++-- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 51 ++++++++++++++++++- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 11 ++-- - 4 files changed, 68 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2186,12 +2186,13 @@ struct rtw89_btc_dm { - u32 wl_stb_chg: 1; - u32 pta_owner: 1; - u32 tdma_instant_excute: 1; -- u32 rsvd: 1; - - u16 slot_dur[CXST_MAX]; - - u8 run_reason; - u8 run_action; -+ -+ u8 wl_lna2: 1; - }; - - struct rtw89_btc_ctrl { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1947,20 +1947,25 @@ static void rtw8852a_set_wl_lna2(struct - - static void rtw8852a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) - { -+ struct rtw89_btc *btc = &rtwdev->btc; -+ - switch (level) { - case 0: /* original */ -+ default: - rtw8852a_bb_ctrl_btc_preagc(rtwdev, false); -- rtw8852a_set_wl_lna2(rtwdev, 0); -+ btc->dm.wl_lna2 = 0; - break; - case 1: /* for FDD free-run */ - rtw8852a_bb_ctrl_btc_preagc(rtwdev, true); -- rtw8852a_set_wl_lna2(rtwdev, 0); -+ btc->dm.wl_lna2 = 0; - break; - case 2: /* for BTG Co-Rx*/ - rtw8852a_bb_ctrl_btc_preagc(rtwdev, false); -- rtw8852a_set_wl_lna2(rtwdev, 1); -+ btc->dm.wl_lna2 = 1; - break; - } -+ -+ rtw8852a_set_wl_lna2(rtwdev, btc->dm.wl_lna2); - } - - static void rtw8852a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2284,15 +2284,64 @@ static void rtw8852b_btc_wl_s1_standby(s - - /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ - if (state) -- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x579); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x179); - else - rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20); - - rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); - } - -+static void rtw8852b_btc_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) -+{ -+ switch (level) { -+ case 0: /* default */ -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); -+ break; -+ case 1: /* Fix LNA2=5 */ -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); -+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); -+ break; -+ } -+} -+ - static void rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) - { -+ struct rtw89_btc *btc = &rtwdev->btc; -+ -+ switch (level) { -+ case 0: /* original */ -+ default: -+ rtw8852b_bb_ctrl_btc_preagc(rtwdev, false); -+ btc->dm.wl_lna2 = 0; -+ break; -+ case 1: /* for FDD free-run */ -+ rtw8852b_bb_ctrl_btc_preagc(rtwdev, true); -+ btc->dm.wl_lna2 = 0; -+ break; -+ case 2: /* for BTG Co-Rx*/ -+ rtw8852b_bb_ctrl_btc_preagc(rtwdev, false); -+ btc->dm.wl_lna2 = 1; -+ break; -+ } -+ -+ rtw8852b_btc_set_wl_lna2(rtwdev, btc->dm.wl_lna2); - } - - static void rtw8852b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2633,20 +2633,25 @@ static void rtw8852c_set_wl_lna2(struct - - static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) - { -+ struct rtw89_btc *btc = &rtwdev->btc; -+ - switch (level) { - case 0: /* original */ -+ default: - rtw8852c_bb_ctrl_btc_preagc(rtwdev, false); -- rtw8852c_set_wl_lna2(rtwdev, 0); -+ btc->dm.wl_lna2 = 0; - break; - case 1: /* for FDD free-run */ - rtw8852c_bb_ctrl_btc_preagc(rtwdev, true); -- rtw8852c_set_wl_lna2(rtwdev, 0); -+ btc->dm.wl_lna2 = 0; - break; - case 2: /* for BTG Co-Rx*/ - rtw8852c_bb_ctrl_btc_preagc(rtwdev, false); -- rtw8852c_set_wl_lna2(rtwdev, 1); -+ btc->dm.wl_lna2 = 1; - break; - } -+ -+ rtw8852c_set_wl_lna2(rtwdev, btc->dm.wl_lna2); - } - - static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-020-wifi-rtw89-coex-Add-report-control-v5-variation.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-020-wifi-rtw89-coex-Add-report-control-v5-variation.patch deleted file mode 100644 index 2a7b37d62..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-020-wifi-rtw89-coex-Add-report-control-v5-variation.patch +++ /dev/null @@ -1,241 +0,0 @@ -From d7904ca8a04062e1c926498966a9fab4abfab161 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 14 Mar 2023 10:06:16 +0800 -Subject: [PATCH 020/136] wifi: rtw89: coex: Add report control v5 variation - -In order to reduce firmware code size cost, remove some counter value from -the structure. But firmware didn't update version code. To parse the -correct report, add another variation version v105 to parse it. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230314020617.28193-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 148 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 23 ++++ - 2 files changed, 171 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -1022,6 +1022,11 @@ static u32 _chk_btc_report(struct rtw89_ - } else if (ver->fcxbtcrpt == 5) { - pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; - pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); -+ } else if (ver->fcxbtcrpt == 105) { -+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v105; -+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105); -+ pcinfo->req_fver = 5; -+ break; - } else { - goto err; - } -@@ -1264,6 +1269,33 @@ static u32 _chk_btc_report(struct rtw89_ - pfwinfo->event[BTF_EVNT_RPT]); - - dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; -+ } else if (ver->fcxbtcrpt == 105) { -+ prpt->v105 = pfwinfo->rpt_ctrl.finfo.v105; -+ pfwinfo->rpt_en_map = le32_to_cpu(prpt->v105.rpt_info.en); -+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v105.rpt_info.cx_ver); -+ wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver); -+ dm->wl_fw_cx_offload = 0; -+ -+ for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) -+ memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0], -+ sizeof(dm->gnt.band[i])); -+ -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = -+ le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]); -+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = -+ le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = -+ le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]); -+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = -+ le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]); -+ btc->cx.cnt_bt[BTC_BCNT_POLUT] = -+ le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]); -+ -+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); -+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, -+ pfwinfo->event[BTF_EVNT_RPT]); -+ -+ dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; - } else { - goto err; - } -@@ -8165,8 +8197,122 @@ static void _show_summary_v5(struct rtw8 - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), - le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); - } else { -+ seq_printf(m, -+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", -+ "[summary]", pfwinfo->cnt_h2c, -+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); -+ } -+ -+ if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || -+ pfwinfo->err[BTFRE_EXCEPTION]) { -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" -+ "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", -+ "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, -+ pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], -+ wl->status.map.lps, wl->status.map.rf_off); -+ } -+ -+ for (i = 0; i < BTC_NCNT_NUM; i++) -+ cnt_sum += dm->cnt_notify[i]; -+ -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", -+ "[notify_cnt]", -+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], -+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); -+ -+ seq_printf(m, -+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", -+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], -+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], -+ cnt[BTC_NCNT_WL_STA]); -+ -+ seq_puts(m, "\n"); -+ seq_printf(m, -+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", -+ "[notify_cnt]", -+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], -+ cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); -+ -+ seq_printf(m, -+ "timer=%d, control=%d, customerize=%d", -+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], -+ cnt[BTC_NCNT_CUSTOMERIZE]); -+} -+ -+static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; -+ struct rtw89_btc_fbtc_rpt_ctrl_v105 *prptctrl; -+ struct rtw89_btc_rpt_cmn_info *pcinfo; -+ struct rtw89_btc_cx *cx = &btc->cx; -+ struct rtw89_btc_dm *dm = &btc->dm; -+ struct rtw89_btc_wl_info *wl = &cx->wl; -+ u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; -+ u8 i; -+ -+ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) -+ return; -+ -+ seq_puts(m, "========== [Statistics] ==========\n"); -+ -+ pcinfo = &pfwinfo->rpt_ctrl.cinfo; -+ if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { -+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v105; -+ -+ seq_printf(m, -+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", -+ "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, -+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c), -+ pfwinfo->cnt_c2h, -+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h), -+ le16_to_cpu(prptctrl->rpt_info.len_c2h)); -+ -+ seq_printf(m, -+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", -+ pfwinfo->event[BTF_EVNT_RPT], -+ le16_to_cpu(prptctrl->rpt_info.cnt), -+ le32_to_cpu(prptctrl->rpt_info.en)); -+ -+ if (dm->error.map.wl_fw_hang) -+ seq_puts(m, " (WL FW Hang!!)"); - seq_puts(m, "\n"); - seq_printf(m, -+ " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", -+ "[mailbox]", -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), -+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); -+ -+ seq_printf(m, -+ "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), -+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); -+ -+ seq_printf(m, -+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", -+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], -+ cx->cnt_wl[BTC_WCNT_RFK_GO], -+ cx->cnt_wl[BTC_WCNT_RFK_REJECT], -+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); -+ -+ seq_printf(m, -+ ", bt_rfk[req:%d]", -+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); -+ -+ seq_printf(m, -+ ", AOAC[RF_on:%d/RF_off:%d]", -+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), -+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); -+ } else { -+ seq_printf(m, - " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", - "[summary]", pfwinfo->cnt_h2c, - pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); -@@ -8256,6 +8402,8 @@ void rtw89_btc_dump_info(struct rtw89_de - _show_summary_v4(rtwdev, m); - else if (ver->fcxbtcrpt == 5) - _show_summary_v5(rtwdev, m); -+ else if (ver->fcxbtcrpt == 105) -+ _show_summary_v105(rtwdev, m); - } - - void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1576,6 +1576,16 @@ enum rtw89_btc_bt_sta_counter { - BTC_BCNT_STA_MAX - }; - -+enum rtw89_btc_bt_sta_counter_v105 { -+ BTC_BCNT_RFK_REQ_V105 = 0, -+ BTC_BCNT_HI_TX_V105 = 1, -+ BTC_BCNT_HI_RX_V105 = 2, -+ BTC_BCNT_LO_TX_V105 = 3, -+ BTC_BCNT_LO_RX_V105 = 4, -+ BTC_BCNT_POLLUTED_V105 = 5, -+ BTC_BCNT_STA_MAX_V105 -+}; -+ - struct rtw89_btc_fbtc_rpt_ctrl_v1 { - u16 fver; /* btc_ver::fcxbtcrpt */ - u16 rpt_cnt; /* tmr counters */ -@@ -1666,10 +1676,23 @@ struct rtw89_btc_fbtc_rpt_ctrl_v5 { - struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; - } __packed; - -+struct rtw89_btc_fbtc_rpt_ctrl_v105 { -+ u8 fver; -+ u8 rsvd; -+ __le16 rsvd1; -+ -+ u8 gnt_val[RTW89_PHY_MAX][4]; -+ __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; -+ -+ struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; -+ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; -+} __packed; -+ - union rtw89_btc_fbtc_rpt_ctrl_ver_info { - struct rtw89_btc_fbtc_rpt_ctrl_v1 v1; - struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; - struct rtw89_btc_fbtc_rpt_ctrl_v5 v5; -+ struct rtw89_btc_fbtc_rpt_ctrl_v105 v105; - }; - - enum rtw89_fbtc_ext_ctrl_type { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-021-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-021-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch deleted file mode 100644 index 85d53ca86..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-021-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7527251f77664dd19716f36f53b723845d537eec Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Tue, 14 Mar 2023 10:06:17 +0800 -Subject: [PATCH 021/136] wifi: rtw89: coex: Update Wi-Fi Bluetooth coexistence - version to 7.0.1 - -Update driver with the supported firmware version of the below item. -Bluetooth firmware BT_Coex_Ver: 0x07 -Wi-Fi firmware version: - RTL8852C->v0.27.56.10 - RTL8852A->v0.24.36 - RTL8852B->v0.29.29 - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230314020617.28193-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -9,7 +9,7 @@ - #include "ps.h" - #include "reg.h" - --#define RTW89_COEX_VERSION 0x07000013 -+#define RTW89_COEX_VERSION 0x07000113 - #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ - - enum btc_fbtc_tdma_template { -@@ -148,6 +148,13 @@ static const struct rtw89_btc_ver rtw89_ - .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, - .info_buf = 1280, .max_role_num = 5, - }, -+ {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), -+ .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, -+ .info_buf = 1800, .max_role_num = 6, -+ }, - {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), - .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, - .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-022-wifi-rtw89-add-counters-of-register-based-H2C-C2H.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-022-wifi-rtw89-add-counters-of-register-based-H2C-C2H.patch deleted file mode 100644 index a7efbef74..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-022-wifi-rtw89-add-counters-of-register-based-H2C-C2H.patch +++ /dev/null @@ -1,160 +0,0 @@ -From e749ef968f14a92155b2c3138d7720cf39e65e00 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 16 Mar 2023 14:39:56 +0800 -Subject: [PATCH 022/136] wifi: rtw89: add counters of register-based H2C/C2H - -The register-based H2C/C2H are used to exchange information between driver -and firmware, but only apply to narrow area because its data size is -smaller than regular packet-based H2C/C2H. - -This kind of H2C/C2H must be paired. To identify if any H2C/C2H is missing, -update counters to help diagnose this kind of problems. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230316063956.71687-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 4 ++++ - drivers/net/wireless/realtek/rtw89/fw.c | 11 +++++++++++ - drivers/net/wireless/realtek/rtw89/mac.c | 2 ++ - drivers/net/wireless/realtek/rtw89/reg.h | 5 +++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 ++ - 7 files changed, 28 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3140,8 +3140,10 @@ struct rtw89_chip_info { - u32 txwd_body_size; - u32 h2c_ctrl_reg; - const u32 *h2c_regs; -+ struct rtw89_reg_def h2c_counter_reg; - u32 c2h_ctrl_reg; - const u32 *c2h_regs; -+ struct rtw89_reg_def c2h_counter_reg; - const struct rtw89_page_regs *page_regs; - bool cfo_src_fd; - const struct rtw89_reg_def *dcfo_comp; -@@ -3268,6 +3270,8 @@ struct rtw89_fw_info { - struct completion completion; - u8 h2c_seq; - u8 rec_seq; -+ u8 h2c_counter; -+ u8 c2h_counter; - struct rtw89_fw_suit normal; - struct rtw89_fw_suit wowlan; - bool fw_log_enable; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -615,6 +615,8 @@ int rtw89_fw_download(struct rtw89_dev * - - fw_info->h2c_seq = 0; - fw_info->rec_seq = 0; -+ fw_info->h2c_counter = 0; -+ fw_info->c2h_counter = 0; - rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; - rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; - -@@ -2724,6 +2726,7 @@ static int rtw89_fw_write_h2c_reg(struct - struct rtw89_mac_h2c_info *info) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_fw_info *fw_info = &rtwdev->fw; - const u32 *h2c_reg = chip->h2c_regs; - u8 i, val, len; - int ret; -@@ -2743,6 +2746,9 @@ static int rtw89_fw_write_h2c_reg(struct - for (i = 0; i < RTW89_H2CREG_MAX; i++) - rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); - -+ fw_info->h2c_counter++; -+ rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, -+ chip->h2c_counter_reg.mask, fw_info->h2c_counter); - rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); - - return 0; -@@ -2752,6 +2758,7 @@ static int rtw89_fw_read_c2h_reg(struct - struct rtw89_mac_c2h_info *info) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_fw_info *fw_info = &rtwdev->fw; - const u32 *c2h_reg = chip->c2h_regs; - u32 ret; - u8 i, val; -@@ -2775,6 +2782,10 @@ static int rtw89_fw_read_c2h_reg(struct - info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - - RTW89_C2HREG_HDR_LEN; - -+ fw_info->c2h_counter++; -+ rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, -+ chip->c2h_counter_reg.mask, fw_info->c2h_counter); -+ - return 0; - } - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -3398,6 +3398,8 @@ int rtw89_mac_enable_cpu(struct rtw89_de - if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN) - return -EFAULT; - -+ rtw89_write32(rtwdev, R_AX_UDM1, 0); -+ rtw89_write32(rtwdev, R_AX_UDM2, 0); - rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); - rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); - rtw89_write32(rtwdev, R_AX_HALT_H2C, 0); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -207,6 +207,11 @@ - - #define R_AX_UDM0 0x01F0 - #define R_AX_UDM1 0x01F4 -+#define B_AX_UDM1_MASK GENMASK(31, 16) -+#define B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK GENMASK(15, 12) -+#define B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK GENMASK(11, 8) -+#define B_AX_UDM1_WCPU_C2H_ENQ_CNT_MASK GENMASK(7, 4) -+#define B_AX_UDM1_WCPU_H2C_DEQ_CNT_MASK GENMASK(3, 0) - #define R_AX_UDM2 0x01F8 - #define R_AX_UDM3 0x01FC - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2136,9 +2136,11 @@ const struct rtw89_chip_info rtw8852a_ch - .h2c_desc_size = sizeof(struct rtw89_txwd_body), - .txwd_body_size = sizeof(struct rtw89_txwd_body), - .h2c_ctrl_reg = R_AX_H2CREG_CTRL, -+ .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, - .h2c_regs = rtw8852a_h2c_regs, - .c2h_ctrl_reg = R_AX_C2HREG_CTRL, - .c2h_regs = rtw8852a_c2h_regs, -+ .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, - .page_regs = &rtw8852a_page_regs, - .cfo_src_fd = false, - .dcfo_comp = &rtw8852a_dcfo_comp, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2557,8 +2557,10 @@ const struct rtw89_chip_info rtw8852b_ch - .h2c_desc_size = sizeof(struct rtw89_txwd_body), - .txwd_body_size = sizeof(struct rtw89_txwd_body), - .h2c_ctrl_reg = R_AX_H2CREG_CTRL, -+ .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, - .h2c_regs = rtw8852b_h2c_regs, - .c2h_ctrl_reg = R_AX_C2HREG_CTRL, -+ .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, - .c2h_regs = rtw8852b_c2h_regs, - .page_regs = &rtw8852b_page_regs, - .cfo_src_fd = true, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2872,8 +2872,10 @@ const struct rtw89_chip_info rtw8852c_ch - .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), - .txwd_body_size = sizeof(struct rtw89_txwd_body_v1), - .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1, -+ .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, - .h2c_regs = rtw8852c_h2c_regs, - .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, -+ .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, - .c2h_regs = rtw8852c_c2h_regs, - .page_regs = &rtw8852c_page_regs, - .cfo_src_fd = false, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-023-wifi-rtw89-set-data-lowest-rate-according-to-AP-supp.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-023-wifi-rtw89-set-data-lowest-rate-according-to-AP-supp.patch deleted file mode 100644 index 27595a768..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-023-wifi-rtw89-set-data-lowest-rate-according-to-AP-supp.patch +++ /dev/null @@ -1,80 +0,0 @@ -From e5307c9cd7ee50accd4e5f28d6a6e09ec11849e3 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Mon, 20 Mar 2023 17:31:10 +0800 -Subject: [PATCH 023/136] wifi: rtw89: set data lowest rate according to AP - supported rate - -By default the driver uses the 1M and 6M rate (0x0) for data frames in -2 GHz and 5/6 GHz bands respectively. But the rate that might not AP -supported. Therefore, We modify the data lowest rate according to the -lowest of AP supported rate. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320093112.30466-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 38 +++++++++++++++++------ - 1 file changed, 28 insertions(+), 10 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -686,6 +686,33 @@ desc_bk: - desc_info->bk = true; - } - -+static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, -+ struct rtw89_core_tx_request *tx_req) -+{ -+ struct ieee80211_vif *vif = tx_req->vif; -+ struct ieee80211_sta *sta = tx_req->sta; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; -+ enum rtw89_sub_entity_idx idx = rtwvif->sub_entity_idx; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); -+ u16 lowest_rate; -+ -+ if (rate_pattern->enable) -+ return rate_pattern->rate; -+ -+ if (vif->p2p) -+ lowest_rate = RTW89_HW_RATE_OFDM6; -+ else if (chan->band_type == RTW89_BAND_2G) -+ lowest_rate = RTW89_HW_RATE_CCK1; -+ else -+ lowest_rate = RTW89_HW_RATE_OFDM6; -+ -+ if (!sta->deflink.supp_rates[chan->band_type]) -+ return lowest_rate; -+ -+ return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate; -+} -+ - static void - rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, - struct rtw89_core_tx_request *tx_req) -@@ -694,8 +721,6 @@ rtw89_core_tx_update_data_info(struct rt - struct ieee80211_sta *sta = tx_req->sta; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); -- struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; -- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); - struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; - struct sk_buff *skb = tx_req->skb; - u8 tid, tid_indicate; -@@ -719,14 +744,7 @@ rtw89_core_tx_update_data_info(struct rt - if (IEEE80211_SKB_CB(skb)->control.hw_key) - rtw89_core_tx_update_sec_key(rtwdev, tx_req); - -- if (vif->p2p) -- desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; -- else if (rate_pattern->enable) -- desc_info->data_retry_lowest_rate = rate_pattern->rate; -- else if (chan->band_type == RTW89_BAND_2G) -- desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1; -- else -- desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; -+ desc_info->data_retry_lowest_rate = rtw89_core_get_data_rate(rtwdev, tx_req); - } - - static enum btc_pkt_type diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-024-wifi-rtw89-remove-superfluous-H2C-of-join_info.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-024-wifi-rtw89-remove-superfluous-H2C-of-join_info.patch deleted file mode 100644 index 26fd091ee..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-024-wifi-rtw89-remove-superfluous-H2C-of-join_info.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 41209362d700f868ae7f0f30dc7634d0e0026880 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 20 Mar 2023 17:31:11 +0800 -Subject: [PATCH 024/136] wifi: rtw89: remove superfluous H2C of join_info - -We find that when starting WoWLAN, the second join_info H2C is -unnecessary and leads WoWLAN not enter power save mode if using new -firmware, so remove it. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320093112.30466-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/wow.c | 9 --------- - 1 file changed, 9 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -420,14 +420,11 @@ static int rtw89_wow_cfg_wake(struct rtw - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; - struct ieee80211_sta *wow_sta; - struct rtw89_sta *rtwsta = NULL; -- bool is_conn = true; - int ret; - - wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); - if (wow_sta) - rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; -- else -- is_conn = false; - - if (wow) { - if (rtw_wow->pattern_cnt) -@@ -454,12 +451,6 @@ static int rtw89_wow_cfg_wake(struct rtw - } - } - -- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); -- if (ret) { -- rtw89_warn(rtwdev, "failed to send h2c join info\n"); -- return ret; -- } -- - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); - if (ret) { - rtw89_warn(rtwdev, "failed to send h2c cam\n"); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-025-wifi-rtw89-fix-incorrect-channel-info-during-scan-du.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-025-wifi-rtw89-fix-incorrect-channel-info-during-scan-du.patch deleted file mode 100644 index b90298149..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-025-wifi-rtw89-fix-incorrect-channel-info-during-scan-du.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 40711486c7ba91a35ba495564e45be0f2a1b3729 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Mon, 20 Mar 2023 17:31:12 +0800 -Subject: [PATCH 025/136] wifi: rtw89: fix incorrect channel info during scan - due to ppdu_sts filtering - -We use ppdu_sts to obtain channel information from hardware, to ensure -that the scan results have correct channel information. However, some of -ppdu_sts that is filtered by the to_self check is also needed for the scan -results. Therefore, we modify the filter part in front of CFO count. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320093112.30466-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1220,6 +1220,10 @@ static void rtw89_core_parse_phy_status_ - phy_ppdu->chan_idx = RTW89_GET_PHY_STS_IE01_CH_IDX(addr); - if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) - return; -+ -+ if (!phy_ppdu->to_self) -+ return; -+ - /* sign conversion for S(12,2) */ - if (rtwdev->chip->cfo_src_fd) - cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_FD_CFO(addr), 11); -@@ -1284,9 +1288,6 @@ static int rtw89_core_rx_parse_phy_sts(s - if (phy_ppdu->ie < RTW89_CCK_PKT) - return -EINVAL; - -- if (!phy_ppdu->to_self) -- return 0; -- - pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; - end = (u8 *)phy_ppdu->buf + phy_ppdu->len; - while (pos < end) { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-026-wifi-rtw89-config-EDCCA-threshold-during-scan-to-pre.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-026-wifi-rtw89-config-EDCCA-threshold-during-scan-to-pre.patch deleted file mode 100644 index 7a4e90157..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-026-wifi-rtw89-config-EDCCA-threshold-during-scan-to-pre.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 280c444745aaf0ff7f2e54b000bd9fff9f1bbaf2 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Wed, 22 Mar 2023 14:02:38 +0800 -Subject: [PATCH 026/136] wifi: rtw89: config EDCCA threshold during scan to - prevent TX failed - -Need to configure EDCCA threshold to default value before scan, and recall -original value after scan to prevent probe request can't be sent out. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230322060238.43922-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 ++ - drivers/net/wireless/realtek/rtw89/core.h | 3 +++ - drivers/net/wireless/realtek/rtw89/phy.c | 19 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/phy.h | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 5 +++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 8 files changed, 33 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3264,6 +3264,7 @@ void rtw89_core_scan_start(struct rtw89_ - rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type); - rtw89_chip_rfk_scan(rtwdev, true); - rtw89_hci_recalc_int_mit(rtwdev); -+ rtw89_phy_config_edcca(rtwdev, true); - - rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr); - } -@@ -3281,6 +3282,7 @@ void rtw89_core_scan_complete(struct rtw - - rtw89_chip_rfk_scan(rtwdev, false); - rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); -+ rtw89_phy_config_edcca(rtwdev, false); - - rtwdev->scanning = false; - rtwdev->dig.bypass_dig = true; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3152,6 +3152,7 @@ struct rtw89_chip_info { - const struct rtw89_rrsr_cfgs *rrsr_cfgs; - u32 bss_clr_map_reg; - u32 dma_ch_mask; -+ u32 edcca_lvl_reg; - const struct wiphy_wowlan_support *wowlan_stub; - }; - -@@ -3363,6 +3364,8 @@ struct rtw89_hal { - - bool entity_active; - enum rtw89_entity_mode entity_mode; -+ -+ u32 edcca_bak; - }; - - #define RTW89_MAX_MAC_ID_NUM 128 ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -4366,3 +4366,22 @@ void rtw89_decode_chan_idx(struct rtw89_ - *ch = rtw89_ch_base_table[idx] + (offset << 1); - } - EXPORT_SYMBOL(rtw89_decode_chan_idx); -+ -+#define EDCCA_DEFAULT 249 -+void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan) -+{ -+ u32 reg = rtwdev->chip->edcca_lvl_reg; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ u32 val; -+ -+ if (scan) { -+ hal->edcca_bak = rtw89_phy_read32(rtwdev, reg); -+ val = hal->edcca_bak; -+ u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_A_MSK); -+ u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_P_MSK); -+ u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_PPDU_LVL_MSK); -+ rtw89_phy_write32(rtwdev, reg, val); -+ } else { -+ rtw89_phy_write32(rtwdev, reg, hal->edcca_bak); -+ } -+} ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -558,5 +558,6 @@ void rtw89_phy_ul_tb_ctrl_track(struct r - u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); - void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, - u8 *ch, enum nl80211_band *band); -+void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4280,6 +4280,11 @@ - #define B_PKT_POP_EN BIT(8) - #define R_SEG0R_PD 0x481C - #define R_SEG0R_PD_V1 0x4860 -+#define R_SEG0R_EDCCA_LVL 0x4840 -+#define R_SEG0R_EDCCA_LVL_V1 0x4884 -+#define B_SEG0R_PPDU_LVL_MSK GENMASK(31, 24) -+#define B_SEG0R_EDCCA_LVL_P_MSK GENMASK(15, 8) -+#define B_SEG0R_EDCCA_LVL_A_MSK GENMASK(7, 0) - #define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30) - #define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29) - #define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6) ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2149,6 +2149,7 @@ const struct rtw89_chip_info rtw8852a_ch - .rrsr_cfgs = &rtw8852a_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP, - .dma_ch_mask = 0, -+ .edcca_lvl_reg = R_SEG0R_EDCCA_LVL, - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852a, - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2572,6 +2572,7 @@ const struct rtw89_chip_info rtw8852b_ch - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), -+ .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, - }; - EXPORT_SYMBOL(rtw8852b_chip_info); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2885,6 +2885,7 @@ const struct rtw89_chip_info rtw8852c_ch - .rrsr_cfgs = &rtw8852c_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP, - .dma_ch_mask = 0, -+ .edcca_lvl_reg = R_SEG0R_EDCCA_LVL, - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852c, - #endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-027-wifi-rtw89-fix-potential-race-condition-between-napi.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-027-wifi-rtw89-fix-potential-race-condition-between-napi.patch deleted file mode 100644 index 0798c59a6..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-027-wifi-rtw89-fix-potential-race-condition-between-napi.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 47515664ecfbde11425dff121f298ae4499425c9 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 23 Mar 2023 16:28:39 +0800 -Subject: [PATCH 027/136] wifi: rtw89: fix potential race condition between - napi_init and napi_enable - -A race condition can happen if netdev is registered, but NAPI isn't -initialized yet, and meanwhile user space starts the netdev that will -enable NAPI. Then, it hits BUG_ON(): - - kernel BUG at net/core/dev.c:6423! - invalid opcode: 0000 [#1] PREEMPT SMP NOPTI - CPU: 0 PID: 417 Comm: iwd Not tainted 6.2.7-slab-dirty #3 eb0f5a8a9d91 - Hardware name: LENOVO 21DL/LNVNB161216, BIOS JPCN20WW(V1.06) 09/20/2022 - RIP: 0010:napi_enable+0x3f/0x50 - Code: 48 89 c2 48 83 e2 f6 f6 81 89 08 00 00 02 74 0d 48 83 ... - RSP: 0018:ffffada1414f3548 EFLAGS: 00010246 - RAX: 0000000000000000 RBX: ffffa01425802080 RCX: 0000000000000000 - RDX: 00000000000002ff RSI: ffffada14e50c614 RDI: ffffa01425808dc0 - RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 - R10: 0000000000000001 R11: 0000000000000100 R12: ffffa01425808f58 - R13: 0000000000000000 R14: ffffa01423498940 R15: 0000000000000001 - FS: 00007f5577c0a740(0000) GS:ffffa0169fc00000(0000) knlGS:0000000000000000 - CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 - CR2: 00007f5577a19972 CR3: 0000000125a7a000 CR4: 0000000000750ef0 - PKRU: 55555554 - Call Trace: - - rtw89_pci_ops_start+0x1c/0x70 [rtw89_pci 6cbc75429515c181cbc386478d5cfb32ffc5a0f8] - rtw89_core_start+0xbe/0x160 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] - rtw89_ops_start+0x26/0x40 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] - drv_start+0x42/0x100 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] - ieee80211_do_open+0x311/0x7d0 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] - ieee80211_open+0x6a/0x90 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] - __dev_open+0xe0/0x180 - __dev_change_flags+0x1da/0x250 - dev_change_flags+0x26/0x70 - do_setlink+0x37c/0x12c0 - ? ep_poll_callback+0x246/0x290 - ? __nla_validate_parse+0x61/0xd00 - ? __wake_up_common_lock+0x8f/0xd0 - -To fix this, follow Jonas' suggestion to switch the order of these -functions and move register netdev to be the last step of PCI probe. -Also, correct the error handling of rtw89_core_register_hw(). - -Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") -Cc: stable@vger.kernel.org -Reported-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> -Link: https://lore.kernel.org/linux-wireless/CAOiHx=n7EwK2B9CnBR07FVA=sEzFagb8TkS4XC_qBNq8OwcYUg@mail.gmail.com/T/#t -Suggested-by: Jonas Gorski -Tested-by: Larry Finger -Reviewed-by: Larry Finger -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230323082839.20474-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 10 +++++++--- - drivers/net/wireless/realtek/rtw89/pci.c | 19 ++++++++++--------- - 2 files changed, 17 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3455,18 +3455,22 @@ static int rtw89_core_register_hw(struct - ret = ieee80211_register_hw(hw); - if (ret) { - rtw89_err(rtwdev, "failed to register hw\n"); -- goto err; -+ goto err_free_supported_band; - } - - ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier); - if (ret) { - rtw89_err(rtwdev, "failed to init regd\n"); -- goto err; -+ goto err_unregister_hw; - } - - return 0; - --err: -+err_unregister_hw: -+ ieee80211_unregister_hw(hw); -+err_free_supported_band: -+ rtw89_core_clr_supported_band(rtwdev); -+ - return ret; - } - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -3874,25 +3874,26 @@ int rtw89_pci_probe(struct pci_dev *pdev - rtw89_pci_link_cfg(rtwdev); - rtw89_pci_l1ss_cfg(rtwdev); - -- ret = rtw89_core_register(rtwdev); -- if (ret) { -- rtw89_err(rtwdev, "failed to register core\n"); -- goto err_clear_resource; -- } -- - rtw89_core_napi_init(rtwdev); - - ret = rtw89_pci_request_irq(rtwdev, pdev); - if (ret) { - rtw89_err(rtwdev, "failed to request pci irq\n"); -- goto err_unregister; -+ goto err_deinit_napi; -+ } -+ -+ ret = rtw89_core_register(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to register core\n"); -+ goto err_free_irq; - } - - return 0; - --err_unregister: -+err_free_irq: -+ rtw89_pci_free_irq(rtwdev, pdev); -+err_deinit_napi: - rtw89_core_napi_deinit(rtwdev); -- rtw89_core_unregister(rtwdev); - err_clear_resource: - rtw89_pci_clear_resource(rtwdev, pdev); - err_declaim_pci: diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-028-wifi-rtw89-Remove-redundant-pci_clear_master.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-028-wifi-rtw89-Remove-redundant-pci_clear_master.patch deleted file mode 100644 index 1378888ed..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-028-wifi-rtw89-Remove-redundant-pci_clear_master.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 5995f746310108b11c7e377b0ebac4c98e53f9dc Mon Sep 17 00:00:00 2001 -From: Cai Huoqing -Date: Thu, 23 Mar 2023 19:26:13 +0800 -Subject: [PATCH 028/136] wifi: rtw89: Remove redundant pci_clear_master - -Remove pci_clear_master to simplify the code, -the bus-mastering is also cleared in do_pci_disable_device, -like this: -./drivers/pci/pci.c:2197 -static void do_pci_disable_device(struct pci_dev *dev) -{ - u16 pci_command; - - pci_read_config_word(dev, PCI_COMMAND, &pci_command); - if (pci_command & PCI_COMMAND_MASTER) { - pci_command &= ~PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, pci_command); - } - - pcibios_disable_device(dev); -}. -And dev->is_busmaster is set to 0 in pci_disable_device. - -Signed-off-by: Cai Huoqing -Reviewed-by: Simon Horman -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230323112613.7550-5-cai.huoqing@linux.dev ---- - drivers/net/wireless/realtek/rtw89/pci.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -2694,7 +2694,6 @@ static int rtw89_pci_claim_device(struct - static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, - struct pci_dev *pdev) - { -- pci_clear_master(pdev); - pci_disable_device(pdev); - } - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-029-wifi-rtw89-8852c-add-beacon-filter-and-CQM-support.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-029-wifi-rtw89-8852c-add-beacon-filter-and-CQM-support.patch deleted file mode 100644 index 647eb6559..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-029-wifi-rtw89-8852c-add-beacon-filter-and-CQM-support.patch +++ /dev/null @@ -1,411 +0,0 @@ -From d2b6da242454ee886729aad7020dfda7995bc26b Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Tue, 11 Apr 2023 20:48:28 +0800 -Subject: [PATCH 029/136] wifi: rtw89: 8852c: add beacon filter and CQM support - -Adding this supports beacon filter and connection quality monitor. -To make host CPU wake up less, let firmware perform signal -monitoring and beacon processing, then notify driver upon signal -changes or beacon loss. - -This feature needs firmware 0.27.56 or newer to support it. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230411124832.14965-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 11 +- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/fw.c | 101 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 63 +++++++++++ - drivers/net/wireless/realtek/rtw89/mac.c | 59 ++++++++++ - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/mac80211.c | 8 ++ - 7 files changed, 243 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1457,6 +1457,7 @@ static void rtw89_vif_rx_stats_iter(void - struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; - struct sk_buff *skb = iter_data->skb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu; - const u8 *bssid = iter_data->bssid; - - if (rtwdev->scanning && -@@ -1475,8 +1476,11 @@ static void rtw89_vif_rx_stats_iter(void - if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) - return; - -- if (ieee80211_is_beacon(hdr->frame_control)) -+ if (ieee80211_is_beacon(hdr->frame_control)) { -+ if (vif->type == NL80211_IFTYPE_STATION) -+ rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu); - pkt_stat->beacon_nr++; -+ } - - if (!ether_addr_equal(vif->addr, hdr->addr1)) - return; -@@ -2539,6 +2543,9 @@ int rtw89_core_sta_disassoc(struct rtw89 - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - -+ if (vif->type == NL80211_IFTYPE_STATION) -+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, false); -+ - rtwdev->total_sta_assoc--; - if (sta->tdls) - rtwvif->tdls_peer--; -@@ -3415,6 +3422,8 @@ static int rtw89_core_register_hw(struct - ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); - ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); - ieee80211_hw_set(hw, WANT_MONITOR_VIF); -+ if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) -+ ieee80211_hw_set(hw, CONNECTION_MONITOR); - - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3231,6 +3231,7 @@ enum rtw89_fw_feature { - RTW89_FW_FEATURE_NO_PACKET_DROP, - RTW89_FW_FEATURE_NO_DEEP_PS, - RTW89_FW_FEATURE_NO_LPS_PG, -+ RTW89_FW_FEATURE_BEACON_FILTER, - }; - - struct rtw89_fw_suit { ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -266,6 +266,7 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER), -+ __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), - }; - - static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) -@@ -1726,6 +1727,106 @@ int rtw89_fw_h2c_set_ofld_cfg(struct rtw - - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, -+ struct ieee80211_vif *vif, -+ bool connect) -+{ -+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); -+ struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL; -+ struct rtw89_h2c_bcnfltr *h2c; -+ u32 len = sizeof(*h2c); -+ struct sk_buff *skb; -+ int ret; -+ -+ if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) -+ return -EINVAL; -+ -+ if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA) -+ return -EINVAL; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, len); -+ h2c = (struct rtw89_h2c_bcnfltr *)skb->data; -+ -+ h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) | -+ le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) | -+ le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) | -+ le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT, -+ RTW89_H2C_BCNFLTR_W0_MODE) | -+ le32_encode_bits(RTW89_BCN_LOSS_CNT, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT) | -+ le32_encode_bits(bss_conf->cqm_rssi_hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) | -+ le32_encode_bits(bss_conf->cqm_rssi_thold + MAX_RSSI, -+ RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) | -+ le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, -+ H2C_FUNC_CFG_BCNFLTR, 0, 1, len); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ -+int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu) -+{ -+ struct rtw89_h2c_ofld_rssi *h2c; -+ u32 len = sizeof(*h2c); -+ struct sk_buff *skb; -+ s8 rssi; -+ int ret; -+ -+ if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) -+ return -EINVAL; -+ -+ if (!phy_ppdu) -+ return -EINVAL; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for h2c rssi\n"); -+ return -ENOMEM; -+ } -+ -+ rssi = phy_ppdu->rssi_avg >> RSSI_FACTOR; -+ skb_put(skb, len); -+ h2c = (struct rtw89_h2c_ofld_rssi *)skb->data; -+ -+ h2c->w0 = le32_encode_bits(phy_ppdu->mac_id, RTW89_H2C_OFLD_RSSI_W0_MACID) | -+ le32_encode_bits(1, RTW89_H2C_OFLD_RSSI_W0_NUM); -+ h2c->w1 = le32_encode_bits(rssi, RTW89_H2C_OFLD_RSSI_W1_VAL); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, -+ H2C_FUNC_OFLD_RSSI, 0, 1, len); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); - goto fail; - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -162,6 +162,27 @@ enum rtw89_p2pps_action { - RTW89_P2P_ACT_TERMINATE = 3, - }; - -+enum rtw89_bcn_fltr_offload_mode { -+ RTW89_BCN_FLTR_OFFLOAD_MODE_0 = 0, -+ RTW89_BCN_FLTR_OFFLOAD_MODE_1, -+ RTW89_BCN_FLTR_OFFLOAD_MODE_2, -+ RTW89_BCN_FLTR_OFFLOAD_MODE_3, -+ -+ RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT = RTW89_BCN_FLTR_OFFLOAD_MODE_0, -+}; -+ -+enum rtw89_bcn_fltr_type { -+ RTW89_BCN_FLTR_BEACON_LOSS, -+ RTW89_BCN_FLTR_RSSI, -+ RTW89_BCN_FLTR_NOTIFY, -+}; -+ -+enum rtw89_bcn_fltr_rssi_event { -+ RTW89_BCN_FLTR_RSSI_NOT_CHANGED, -+ RTW89_BCN_FLTR_RSSI_HIGH, -+ RTW89_BCN_FLTR_RSSI_LOW, -+}; -+ - #define FWDL_SECTION_MAX_NUM 10 - #define FWDL_SECTION_CHKSUM_LEN 8 - #define FWDL_SECTION_PER_PKT_LEN 2020 -@@ -216,6 +237,8 @@ struct rtw89_h2creg_sch_tx_en { - #define RTW89_SCAN_LIST_LIMIT \ - ((RTW89_H2C_MAX_SIZE / RTW89_MAC_CHINFO_SIZE) - RTW89_SCAN_LIST_GUARD) - -+#define RTW89_BCN_LOSS_CNT 10 -+ - struct rtw89_mac_chinfo { - u8 period; - u8 dwell_time; -@@ -3317,6 +3340,17 @@ static inline struct rtw89_fw_c2h_attr * - #define RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(23, 16)) - -+struct rtw89_c2h_mac_bcnfltr_rpt { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+} __packed; -+ -+#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID GENMASK(7, 0) -+#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE GENMASK(9, 8) -+#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT GENMASK(11, 10) -+#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA GENMASK(23, 16) -+ - #define RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 0)) - #define RTW89_GET_PHY_C2H_RA_RPT_RETRY_RATIO(c2h) \ -@@ -3410,6 +3444,28 @@ static_assert(sizeof(struct rtw89_mac_mc - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) - -+struct rtw89_h2c_bcnfltr { -+ __le32 w0; -+} __packed; -+ -+#define RTW89_H2C_BCNFLTR_W0_MON_RSSI BIT(0) -+#define RTW89_H2C_BCNFLTR_W0_MON_BCN BIT(1) -+#define RTW89_H2C_BCNFLTR_W0_MON_EN BIT(2) -+#define RTW89_H2C_BCNFLTR_W0_MODE GENMASK(4, 3) -+#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT GENMASK(11, 8) -+#define RTW89_H2C_BCNFLTR_W0_RSSI_HYST GENMASK(15, 12) -+#define RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD GENMASK(23, 16) -+#define RTW89_H2C_BCNFLTR_W0_MAC_ID GENMASK(31, 24) -+ -+struct rtw89_h2c_ofld_rssi { -+ __le32 w0; -+ __le32 w1; -+} __packed; -+ -+#define RTW89_H2C_OFLD_RSSI_W0_MACID GENMASK(7, 0) -+#define RTW89_H2C_OFLD_RSSI_W0_NUM GENMASK(15, 8) -+#define RTW89_H2C_OFLD_RSSI_W1_VAL GENMASK(7, 0) -+ - #define RTW89_FW_HDR_SIZE 32 - #define RTW89_FW_SECTION_HDR_SIZE 16 - -@@ -3537,6 +3593,8 @@ struct rtw89_fw_h2c_rf_reg_info { - #define H2C_FUNC_ADD_SCANOFLD_CH 0x16 - #define H2C_FUNC_SCANOFLD 0x17 - #define H2C_FUNC_PKT_DROP 0x1b -+#define H2C_FUNC_CFG_BCNFLTR 0x1e -+#define H2C_FUNC_OFLD_RSSI 0x1f - - /* CLASS 10 - Security CAM */ - #define H2C_CL_MAC_SEC_CAM 0xa -@@ -3637,6 +3695,11 @@ int rtw89_fw_h2c_macid_pause(struct rtw8 - int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, - u8 ac, u32 val); - int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); -+int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev, -+ struct ieee80211_vif *vif, -+ bool connect); -+int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu); - int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); - int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4238,6 +4238,64 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_ - } - - static void -+rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif); -+ enum nl80211_cqm_rssi_threshold_event nl_event; -+ const struct rtw89_c2h_mac_bcnfltr_rpt *c2h = -+ (const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data; -+ u8 type, event, mac_id; -+ s8 sig; -+ -+ type = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE); -+ sig = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA) - MAX_RSSI; -+ event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT); -+ mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID); -+ -+ if (mac_id != rtwvif->mac_id) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "C2H bcnfltr rpt macid: %d, type: %d, ma: %d, event: %d\n", -+ mac_id, type, sig, event); -+ -+ switch (type) { -+ case RTW89_BCN_FLTR_BEACON_LOSS: -+ if (!rtwdev->scanning) -+ ieee80211_connection_loss(vif); -+ else -+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); -+ return; -+ case RTW89_BCN_FLTR_NOTIFY: -+ nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; -+ break; -+ case RTW89_BCN_FLTR_RSSI: -+ if (event == RTW89_BCN_FLTR_RSSI_LOW) -+ nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; -+ else if (event == RTW89_BCN_FLTR_RSSI_HIGH) -+ nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; -+ else -+ return; -+ break; -+ default: -+ return; -+ } -+ -+ ieee80211_cqm_rssi_notify(vif, nl_event, sig, GFP_KERNEL); -+} -+ -+static void -+rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, -+ u32 len) -+{ -+ struct rtw89_vif *rtwvif; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif, c2h); -+} -+ -+static void - rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) - { - rtw89_debug(rtwdev, RTW89_DBG_FW, -@@ -4457,6 +4515,7 @@ void (* const rtw89_mac_c2h_ofld_handler - [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, - [RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp, - [RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt, -+ [RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt, - }; - - static ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -359,6 +359,7 @@ enum rtw89_mac_c2h_ofld_func { - RTW89_MAC_C2H_FUNC_MACID_PAUSE, - RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6, - RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9, -+ RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd, - RTW89_MAC_C2H_FUNC_OFLD_MAX, - }; - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -114,6 +114,11 @@ static int rtw89_ops_add_interface(struc - vif->addr, vif->type, vif->p2p); - - mutex_lock(&rtwdev->mutex); -+ -+ if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) -+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | -+ IEEE80211_VIF_SUPPORTS_CQM_RSSI; -+ - rtwvif->rtwdev = rtwdev; - list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); - INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work); -@@ -425,6 +430,9 @@ static void rtw89_ops_bss_info_changed(s - if (changed & BSS_CHANGED_P2P_PS) - rtw89_process_p2p_ps(rtwdev, vif); - -+ if (changed & BSS_CHANGED_CQM) -+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); -+ - mutex_unlock(&rtwdev->mutex); - } - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-030-wifi-rtw89-add-function-to-wait-for-completion-of-TX.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-030-wifi-rtw89-add-function-to-wait-for-completion-of-TX.patch deleted file mode 100644 index 85946f883..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-030-wifi-rtw89-add-function-to-wait-for-completion-of-TX.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 1ae5ca615285d5d4f72d1de464716d85dffef19f Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Tue, 11 Apr 2023 20:48:29 +0800 -Subject: [PATCH 030/136] wifi: rtw89: add function to wait for completion of - TX skbs - -Allocate a per-skb completion to track those skbs we are interested in -and wait for them to complete transmission with TX status. - -Normally, the completion object is freed by wait side, but it could be -timeout result that complete side should free the object instead. Add a -owner field with RCU to determine which side should free the object. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230411124832.14965-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 31 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 40 +++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/pci.c | 5 +++ - drivers/net/wireless/realtek/rtw89/pci.h | 4 +-- - 4 files changed, 78 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -867,6 +867,37 @@ void rtw89_core_tx_kick_off(struct rtw89 - rtw89_hci_tx_kick_off(rtwdev, ch_dma); - } - -+int rtw89_core_tx_kick_off_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, -+ int qsel, unsigned int timeout) -+{ -+ struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); -+ struct rtw89_tx_wait_info *wait; -+ unsigned long time_left; -+ int ret = 0; -+ -+ wait = kzalloc(sizeof(*wait), GFP_KERNEL); -+ if (!wait) { -+ rtw89_core_tx_kick_off(rtwdev, qsel); -+ return 0; -+ } -+ -+ init_completion(&wait->completion); -+ rcu_assign_pointer(skb_data->wait, wait); -+ -+ rtw89_core_tx_kick_off(rtwdev, qsel); -+ time_left = wait_for_completion_timeout(&wait->completion, -+ msecs_to_jiffies(timeout)); -+ if (time_left == 0) -+ ret = -ETIMEDOUT; -+ else if (!wait->tx_done) -+ ret = -EAGAIN; -+ -+ rcu_assign_pointer(skb_data->wait, NULL); -+ kfree_rcu(wait, rcu_head); -+ -+ return ret; -+} -+ - int rtw89_h2c_tx(struct rtw89_dev *rtwdev, - struct sk_buff *skb, bool fwdl) - { ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2623,6 +2623,17 @@ struct rtw89_phy_rate_pattern { - bool enable; - }; - -+struct rtw89_tx_wait_info { -+ struct rcu_head rcu_head; -+ struct completion completion; -+ bool tx_done; -+}; -+ -+struct rtw89_tx_skb_data { -+ struct rtw89_tx_wait_info __rcu *wait; -+ u8 hci_priv[]; -+}; -+ - #define RTW89_P2P_MAX_NOA_NUM 2 - - struct rtw89_vif { -@@ -4179,6 +4190,14 @@ static inline void rtw89_hci_clear(struc - rtwdev->hci.ops->clear(rtwdev, pdev); - } - -+static inline -+struct rtw89_tx_skb_data *RTW89_TX_SKB_CB(struct sk_buff *skb) -+{ -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ -+ return (struct rtw89_tx_skb_data *)info->status.status_driver_data; -+} -+ - static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) - { - return rtwdev->hci.ops->read8(rtwdev, addr); -@@ -4822,11 +4841,32 @@ static inline struct sk_buff *rtw89_allo - return dev_alloc_skb(length); - } - -+static inline void rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev, -+ struct rtw89_tx_skb_data *skb_data, -+ bool tx_done) -+{ -+ struct rtw89_tx_wait_info *wait; -+ -+ rcu_read_lock(); -+ -+ wait = rcu_dereference(skb_data->wait); -+ if (!wait) -+ goto out; -+ -+ wait->tx_done = tx_done; -+ complete(&wait->completion); -+ -+out: -+ rcu_read_unlock(); -+} -+ - int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); - int rtw89_h2c_tx(struct rtw89_dev *rtwdev, - struct sk_buff *skb, bool fwdl); - void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); -+int rtw89_core_tx_kick_off_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, -+ int qsel, unsigned int timeout); - void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, - struct rtw89_tx_desc_info *desc_info, - void *txdesc); ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -364,8 +364,11 @@ static void rtw89_pci_tx_status(struct r - struct rtw89_pci_tx_ring *tx_ring, - struct sk_buff *skb, u8 tx_status) - { -+ struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); - struct ieee80211_tx_info *info; - -+ rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status == RTW89_TX_DONE); -+ - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); - -@@ -1203,6 +1206,7 @@ static int rtw89_pci_txwd_submit(struct - struct pci_dev *pdev = rtwpci->pdev; - struct sk_buff *skb = tx_req->skb; - struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); -+ struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); - bool en_wd_info = desc_info->en_wd_info; - u32 txwd_len; - u32 txwp_len; -@@ -1218,6 +1222,7 @@ static int rtw89_pci_txwd_submit(struct - } - - tx_data->dma = dma; -+ rcu_assign_pointer(skb_data->wait, NULL); - - txwp_len = sizeof(*txwp_info); - txwd_len = chip->txwd_body_size; ---- a/drivers/net/wireless/realtek/rtw89/pci.h -+++ b/drivers/net/wireless/realtek/rtw89/pci.h -@@ -1004,9 +1004,9 @@ rtw89_pci_rxbd_increase(struct rtw89_pci - - static inline struct rtw89_pci_tx_data *RTW89_PCI_TX_SKB_CB(struct sk_buff *skb) - { -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct rtw89_tx_skb_data *data = RTW89_TX_SKB_CB(skb); - -- return (struct rtw89_pci_tx_data *)info->status.status_driver_data; -+ return (struct rtw89_pci_tx_data *)data->hci_priv; - } - - static inline struct rtw89_pci_tx_bd_32 * diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-031-wifi-rtw89-add-ieee80211-remain_on_channel-ops.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-031-wifi-rtw89-add-ieee80211-remain_on_channel-ops.patch deleted file mode 100644 index 097b98ab4..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-031-wifi-rtw89-add-ieee80211-remain_on_channel-ops.patch +++ /dev/null @@ -1,666 +0,0 @@ -From a0e97ae3f3320a246a79db7372fc23a38556014e Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Tue, 11 Apr 2023 20:48:30 +0800 -Subject: [PATCH 031/136] wifi: rtw89: add ieee80211::remain_on_channel ops - -Add support of remain on channel ops. Since channel context is -required to enable multi-channel concurrent(MCC) and the current -ROC in mac80211 don't support more than 1 channel context, add this -to let P2P and other protocols relying on this work as expected. -The off-channel duration and cancel timing is purely controlled by -upper layers. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230411124832.14965-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/chan.c | 35 +++ - drivers/net/wireless/realtek/rtw89/chan.h | 3 + - drivers/net/wireless/realtek/rtw89/core.c | 212 +++++++++++++++++- - drivers/net/wireless/realtek/rtw89/core.h | 30 +++ - drivers/net/wireless/realtek/rtw89/mac.c | 5 +- - drivers/net/wireless/realtek/rtw89/mac80211.c | 80 ++++++- - drivers/net/wireless/realtek/rtw89/ps.h | 16 ++ - 7 files changed, 378 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/chan.c -+++ b/drivers/net/wireless/realtek/rtw89/chan.c -@@ -141,6 +141,38 @@ void rtw89_config_entity_chandef(struct - __rtw89_config_entity_chandef(rtwdev, idx, chandef, true); - } - -+void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, -+ enum rtw89_sub_entity_idx idx, -+ const struct cfg80211_chan_def *chandef) -+{ -+ struct rtw89_hal *hal = &rtwdev->hal; -+ enum rtw89_sub_entity_idx cur; -+ -+ if (chandef) { -+ cur = atomic_cmpxchg(&hal->roc_entity_idx, -+ RTW89_SUB_ENTITY_IDLE, idx); -+ if (cur != RTW89_SUB_ENTITY_IDLE) { -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, -+ "ROC still processing on entity %d\n", idx); -+ return; -+ } -+ -+ hal->roc_chandef = *chandef; -+ } else { -+ cur = atomic_cmpxchg(&hal->roc_entity_idx, idx, -+ RTW89_SUB_ENTITY_IDLE); -+ if (cur == idx) -+ return; -+ -+ if (cur == RTW89_SUB_ENTITY_IDLE) -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, -+ "ROC already finished on entity %d\n", idx); -+ else -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, -+ "ROC is processing on entity %d\n", cur); -+ } -+} -+ - static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev) - { - struct cfg80211_chan_def chandef = {0}; -@@ -154,6 +186,7 @@ void rtw89_entity_init(struct rtw89_dev - struct rtw89_hal *hal = &rtwdev->hal; - - bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY); -+ atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE); - rtw89_config_default_chandef(rtwdev); - } - -@@ -229,6 +262,8 @@ void rtw89_chanctx_ops_remove(struct rtw - rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; - } - -+ atomic_cmpxchg(&hal->roc_entity_idx, roll, RTW89_SUB_ENTITY_0); -+ - drop = roll; - - out: ---- a/drivers/net/wireless/realtek/rtw89/chan.h -+++ b/drivers/net/wireless/realtek/rtw89/chan.h -@@ -45,6 +45,9 @@ bool rtw89_assign_entity_chan(struct rtw - void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, - enum rtw89_sub_entity_idx idx, - const struct cfg80211_chan_def *chandef); -+void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, -+ enum rtw89_sub_entity_idx idx, -+ const struct cfg80211_chan_def *chandef); - void rtw89_entity_init(struct rtw89_dev *rtwdev); - enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev); - int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2014,6 +2014,18 @@ static void rtw89_core_free_sta_pending_ - spin_unlock_bh(&rtwdev->ba_lock); - } - -+static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, -+ struct ieee80211_sta *sta) -+{ -+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ struct sk_buff *skb, *tmp; -+ -+ skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { -+ skb_unlink(skb, &rtwsta->roc_queue); -+ dev_kfree_skb_any(skb); -+ } -+} -+ - static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, - struct rtw89_txq *rtwtxq) - { -@@ -2153,6 +2165,7 @@ static void rtw89_core_txq_schedule(stru - { - struct ieee80211_hw *hw = rtwdev->hw; - struct ieee80211_txq *txq; -+ struct rtw89_vif *rtwvif; - struct rtw89_txq *rtwtxq; - unsigned long frame_cnt; - unsigned long byte_cnt; -@@ -2162,6 +2175,12 @@ static void rtw89_core_txq_schedule(stru - ieee80211_txq_schedule_start(hw, ac); - while ((txq = ieee80211_next_txq(hw, ac))) { - rtwtxq = (struct rtw89_txq *)txq->drv_priv; -+ rtwvif = (struct rtw89_vif *)txq->vif->drv_priv; -+ -+ if (rtwvif->offchan) { -+ ieee80211_return_txq(hw, txq, true); -+ continue; -+ } - tx_resource = rtw89_check_and_reclaim_tx_resource(rtwdev, txq->tid); - sched_txq = false; - -@@ -2230,6 +2249,187 @@ static void rtw89_forbid_ba_work(struct - spin_unlock_bh(&rtwdev->ba_lock); - } - -+static void rtw89_core_sta_pending_tx_iter(void *data, -+ struct ieee80211_sta *sta) -+{ -+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ struct rtw89_vif *rtwvif_target = data, *rtwvif = rtwsta->rtwvif; -+ struct rtw89_dev *rtwdev = rtwvif->rtwdev; -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ struct sk_buff *skb, *tmp; -+ int qsel, ret; -+ -+ if (rtwvif->sub_entity_idx != rtwvif_target->sub_entity_idx) -+ return; -+ -+ if (skb_queue_len(&rtwsta->roc_queue) == 0) -+ return; -+ -+ skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { -+ skb_unlink(skb, &rtwsta->roc_queue); -+ -+ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); -+ if (ret) { -+ rtw89_warn(rtwdev, "pending tx failed with %d\n", ret); -+ dev_kfree_skb_any(skb); -+ } else { -+ rtw89_core_tx_kick_off(rtwdev, qsel); -+ } -+ } -+} -+ -+static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif) -+{ -+ ieee80211_iterate_stations_atomic(rtwdev->hw, -+ rtw89_core_sta_pending_tx_iter, -+ rtwvif); -+} -+ -+static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool qos, bool ps) -+{ -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ struct ieee80211_sta *sta; -+ struct ieee80211_hdr *hdr; -+ struct sk_buff *skb; -+ int ret, qsel; -+ -+ if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) -+ return 0; -+ -+ rcu_read_lock(); -+ sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); -+ if (!sta) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, qos); -+ if (!skb) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ hdr = (struct ieee80211_hdr *)skb->data; -+ if (ps) -+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); -+ -+ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); -+ if (ret) { -+ rtw89_warn(rtwdev, "nullfunc transmit failed: %d\n", ret); -+ dev_kfree_skb_any(skb); -+ goto out; -+ } -+ -+ rcu_read_unlock(); -+ -+ return rtw89_core_tx_kick_off_and_wait(rtwdev, skb, qsel, -+ RTW89_ROC_TX_TIMEOUT); -+out: -+ rcu_read_unlock(); -+ -+ return ret; -+} -+ -+void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ struct ieee80211_hw *hw = rtwdev->hw; -+ struct rtw89_roc *roc = &rtwvif->roc; -+ struct cfg80211_chan_def roc_chan; -+ struct rtw89_vif *tmp; -+ int ret; -+ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work, -+ msecs_to_jiffies(rtwvif->roc.duration)); -+ -+ rtw89_leave_ips_by_hwflags(rtwdev); -+ rtw89_leave_lps(rtwdev); -+ -+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, true); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, -+ "roc send null-1 failed: %d\n", ret); -+ -+ rtw89_for_each_rtwvif(rtwdev, tmp) -+ if (tmp->sub_entity_idx == rtwvif->sub_entity_idx) -+ tmp->offchan = true; -+ -+ cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT); -+ rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, &roc_chan); -+ rtw89_set_channel(rtwdev); -+ rtw89_write32_clr(rtwdev, -+ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), -+ B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); -+ -+ ieee80211_ready_on_channel(hw); -+} -+ -+void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ struct ieee80211_hw *hw = rtwdev->hw; -+ struct rtw89_roc *roc = &rtwvif->roc; -+ struct rtw89_vif *tmp; -+ int ret; -+ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ ieee80211_remain_on_channel_expired(hw); -+ -+ rtw89_leave_ips_by_hwflags(rtwdev); -+ rtw89_leave_lps(rtwdev); -+ -+ rtw89_write32_mask(rtwdev, -+ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), -+ B_AX_RX_FLTR_CFG_MASK, -+ rtwdev->hal.rx_fltr); -+ -+ roc->state = RTW89_ROC_IDLE; -+ rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, NULL); -+ rtw89_set_channel(rtwdev); -+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, false); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, -+ "roc send null-0 failed: %d\n", ret); -+ -+ rtw89_for_each_rtwvif(rtwdev, tmp) -+ if (tmp->sub_entity_idx == rtwvif->sub_entity_idx) -+ tmp->offchan = false; -+ -+ rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif); -+ queue_work(rtwdev->txq_wq, &rtwdev->txq_work); -+ -+ if (hw->conf.flags & IEEE80211_CONF_IDLE) -+ ieee80211_queue_delayed_work(hw, &roc->roc_work, -+ RTW89_ROC_IDLE_TIMEOUT); -+} -+ -+void rtw89_roc_work(struct work_struct *work) -+{ -+ struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, -+ roc.roc_work.work); -+ struct rtw89_dev *rtwdev = rtwvif->rtwdev; -+ struct rtw89_roc *roc = &rtwvif->roc; -+ -+ mutex_lock(&rtwdev->mutex); -+ -+ switch (roc->state) { -+ case RTW89_ROC_IDLE: -+ rtw89_enter_ips_by_hwflags(rtwdev); -+ break; -+ case RTW89_ROC_MGMT: -+ case RTW89_ROC_NORMAL: -+ rtw89_roc_end(rtwdev, rtwvif); -+ break; -+ default: -+ break; -+ } -+ -+ mutex_unlock(&rtwdev->mutex); -+} -+ - static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, - u32 throughput, u64 cnt) - { -@@ -2299,6 +2499,9 @@ static void rtw89_vif_enter_lps(struct r - rtwvif->tdls_peer) - return; - -+ if (rtwvif->offchan) -+ return; -+ - if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && - rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) - rtw89_enter_lps(rtwdev, rtwvif); -@@ -2528,6 +2731,7 @@ int rtw89_core_sta_add(struct rtw89_dev - rtwsta->rtwvif = rtwvif; - rtwsta->prev_rssi = 0; - INIT_LIST_HEAD(&rtwsta->ba_cam_list); -+ skb_queue_head_init(&rtwsta->roc_queue); - - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - rtw89_core_txq_init(rtwdev, sta->txq[i]); -@@ -2597,6 +2801,8 @@ int rtw89_core_sta_disconnect(struct rtw - rtw89_mac_bf_disassoc(rtwdev, vif, sta); - rtw89_core_free_sta_pending_ba(rtwdev, sta); - rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); -+ rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); -+ - if (vif->type == NL80211_IFTYPE_AP || sta->tdls) - rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); - if (sta->tdls) -@@ -3480,6 +3686,7 @@ static int rtw89_core_register_hw(struct - hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); - hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); - hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); -+ hw->wiphy->max_remain_on_channel_duration = 1000; - - wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); - -@@ -3563,7 +3770,8 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - goto err; - - no_chanctx = chip->support_chanctx_num == 0 || -- !(early_feat_map & BIT(RTW89_FW_FEATURE_SCAN_OFFLOAD)); -+ !(early_feat_map & BIT(RTW89_FW_FEATURE_SCAN_OFFLOAD)) || -+ !(early_feat_map & BIT(RTW89_FW_FEATURE_BEACON_FILTER)); - - if (no_chanctx) { - ops->add_chanctx = NULL; -@@ -3571,6 +3779,8 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - ops->change_chanctx = NULL; - ops->assign_vif_chanctx = NULL; - ops->unassign_vif_chanctx = NULL; -+ ops->remain_on_channel = NULL; -+ ops->cancel_remain_on_channel = NULL; - } - - driver_data_size = sizeof(struct rtw89_dev) + bus_data_size; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -569,6 +569,7 @@ enum rtw89_sub_entity_idx { - RTW89_SUB_ENTITY_0 = 0, - - NUM_OF_RTW89_SUB_ENTITY, -+ RTW89_SUB_ENTITY_IDLE = NUM_OF_RTW89_SUB_ENTITY, - }; - - enum rtw89_rf_path { -@@ -2597,6 +2598,7 @@ struct rtw89_sta { - struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */ - struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */ - struct list_head ba_cam_list; -+ struct sk_buff_head roc_queue; - - bool use_cfg_mask; - struct cfg80211_bitrate_mask mask; -@@ -2634,11 +2636,28 @@ struct rtw89_tx_skb_data { - u8 hci_priv[]; - }; - -+#define RTW89_ROC_IDLE_TIMEOUT 500 -+#define RTW89_ROC_TX_TIMEOUT 30 -+enum rtw89_roc_state { -+ RTW89_ROC_IDLE, -+ RTW89_ROC_NORMAL, -+ RTW89_ROC_MGMT, -+}; -+ -+struct rtw89_roc { -+ struct ieee80211_channel chan; -+ struct delayed_work roc_work; -+ enum ieee80211_roc_type type; -+ enum rtw89_roc_state state; -+ int duration; -+}; -+ - #define RTW89_P2P_MAX_NOA_NUM 2 - - struct rtw89_vif { - struct list_head list; - struct rtw89_dev *rtwdev; -+ struct rtw89_roc roc; - enum rtw89_sub_entity_idx sub_entity_idx; - - u8 mac_id; -@@ -2654,6 +2673,7 @@ struct rtw89_vif { - u8 bcn_hit_cond; - u8 hit_rule; - u8 last_noa_nr; -+ bool offchan; - bool trigger; - bool lsig_txop; - u8 tgt_ind; -@@ -3370,9 +3390,11 @@ struct rtw89_hal { - bool tx_path_diversity; - bool support_cckpd; - bool support_igi; -+ atomic_t roc_entity_idx; - - DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY); - struct rtw89_sub_entity sub[NUM_OF_RTW89_SUB_ENTITY]; -+ struct cfg80211_chan_def roc_chandef; - - bool entity_active; - enum rtw89_entity_mode entity_mode; -@@ -4035,6 +4057,7 @@ struct rtw89_dev { - struct delayed_work coex_rfk_chk_work; - struct delayed_work cfo_track_work; - struct delayed_work forbid_ba_work; -+ struct delayed_work roc_work; - struct rtw89_ppdu_sts_info ppdu_sts; - u8 total_sta_assoc; - bool scanning; -@@ -4550,6 +4573,10 @@ const struct cfg80211_chan_def *rtw89_ch - enum rtw89_sub_entity_idx idx) - { - struct rtw89_hal *hal = &rtwdev->hal; -+ enum rtw89_sub_entity_idx roc_idx = atomic_read(&hal->roc_entity_idx); -+ -+ if (roc_idx == idx) -+ return &hal->roc_chandef; - - return &hal->sub[idx].chandef; - } -@@ -4936,6 +4963,9 @@ void rtw89_complete_cond(struct rtw89_wa - int rtw89_core_start(struct rtw89_dev *rtwdev); - void rtw89_core_stop(struct rtw89_dev *rtwdev); - void rtw89_core_update_beacon_work(struct work_struct *work); -+void rtw89_roc_work(struct work_struct *work); -+void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -+void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, - const u8 *mac_addr, bool hw_scan); - void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4193,6 +4193,9 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_ - u16 chan; - int ret; - -+ if (!rtwvif) -+ return; -+ - tx_fail = RTW89_GET_MAC_C2H_SCANOFLD_TX_FAIL(c2h->data); - status = RTW89_GET_MAC_C2H_SCANOFLD_STATUS(c2h->data); - chan = RTW89_GET_MAC_C2H_SCANOFLD_PRI_CH(c2h->data); -@@ -4262,7 +4265,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev - - switch (type) { - case RTW89_BCN_FLTR_BEACON_LOSS: -- if (!rtwdev->scanning) -+ if (!rtwdev->scanning && !rtwvif->offchan) - ieee80211_connection_loss(vif); - else - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -23,9 +23,19 @@ static void rtw89_ops_tx(struct ieee8021 - struct rtw89_dev *rtwdev = hw->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; -+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct ieee80211_sta *sta = control->sta; -+ u32 flags = IEEE80211_SKB_CB(skb)->flags; - int ret, qsel; - -+ if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) { -+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n"); -+ skb_queue_tail(&rtwsta->roc_queue, skb); -+ return; -+ } -+ - ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); - if (ret) { - rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret); -@@ -115,13 +125,18 @@ static int rtw89_ops_add_interface(struc - - mutex_lock(&rtwdev->mutex); - -+ rtw89_leave_ips_by_hwflags(rtwdev); -+ - if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | - IEEE80211_VIF_SUPPORTS_CQM_RSSI; - - rtwvif->rtwdev = rtwdev; -+ rtwvif->roc.state = RTW89_ROC_IDLE; -+ rtwvif->offchan = false; - list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); - INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work); -+ INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work); - rtw89_leave_ps_mode(rtwdev); - - rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); -@@ -168,6 +183,7 @@ static void rtw89_ops_remove_interface(s - vif->addr, vif->type, vif->p2p); - - cancel_work_sync(&rtwvif->update_beacon_work); -+ cancel_delayed_work_sync(&rtwvif->roc.roc_work); - - mutex_lock(&rtwdev->mutex); - rtw89_leave_ps_mode(rtwdev); -@@ -175,6 +191,8 @@ static void rtw89_ops_remove_interface(s - rtw89_mac_remove_vif(rtwdev, rtwvif); - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - list_del_init(&rtwvif->list); -+ rtw89_enter_ips_by_hwflags(rtwdev); -+ - mutex_unlock(&rtwdev->mutex); - } - -@@ -803,12 +821,13 @@ static int rtw89_ops_hw_scan(struct ieee - struct ieee80211_scan_request *req) - { - struct rtw89_dev *rtwdev = hw->priv; -+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); - int ret = 0; - - if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) - return 1; - -- if (rtwdev->scanning) -+ if (rtwdev->scanning || rtwvif->offchan) - return -EBUSY; - - mutex_lock(&rtwdev->mutex); -@@ -911,6 +930,63 @@ static void rtw89_ops_unassign_vif_chanc - mutex_unlock(&rtwdev->mutex); - } - -+static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_channel *chan, -+ int duration, -+ enum ieee80211_roc_type type) -+{ -+ struct rtw89_dev *rtwdev = hw->priv; -+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); -+ struct rtw89_roc *roc = &rtwvif->roc; -+ -+ if (!vif) -+ return -EINVAL; -+ -+ mutex_lock(&rtwdev->mutex); -+ -+ if (roc->state != RTW89_ROC_IDLE) { -+ mutex_unlock(&rtwdev->mutex); -+ return -EBUSY; -+ } -+ -+ if (rtwdev->scanning) -+ rtw89_hw_scan_abort(rtwdev, vif); -+ -+ if (type == IEEE80211_ROC_TYPE_MGMT_TX) -+ roc->state = RTW89_ROC_MGMT; -+ else -+ roc->state = RTW89_ROC_NORMAL; -+ -+ roc->duration = duration; -+ roc->chan = *chan; -+ roc->type = type; -+ -+ rtw89_roc_start(rtwdev, rtwvif); -+ -+ mutex_unlock(&rtwdev->mutex); -+ -+ return 0; -+} -+ -+static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+{ -+ struct rtw89_dev *rtwdev = hw->priv; -+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); -+ -+ if (!rtwvif) -+ return -EINVAL; -+ -+ cancel_delayed_work_sync(&rtwvif->roc.roc_work); -+ -+ mutex_lock(&rtwdev->mutex); -+ rtw89_roc_end(rtwdev, rtwvif); -+ mutex_unlock(&rtwdev->mutex); -+ -+ return 0; -+} -+ - static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta) - { - struct cfg80211_tid_config *tid_config = data; -@@ -1022,6 +1098,8 @@ const struct ieee80211_ops rtw89_ops = { - .change_chanctx = rtw89_ops_change_chanctx, - .assign_vif_chanctx = rtw89_ops_assign_vif_chanctx, - .unassign_vif_chanctx = rtw89_ops_unassign_vif_chanctx, -+ .remain_on_channel = rtw89_ops_remain_on_channel, -+ .cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel, - .set_sar_specs = rtw89_ops_set_sar_specs, - .sta_rc_update = rtw89_ops_sta_rc_update, - .set_tid_config = rtw89_ops_set_tid_config, ---- a/drivers/net/wireless/realtek/rtw89/ps.h -+++ b/drivers/net/wireless/realtek/rtw89/ps.h -@@ -15,4 +15,20 @@ void rtw89_leave_ips(struct rtw89_dev *r - void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); - void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); - -+static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev) -+{ -+ struct ieee80211_hw *hw = rtwdev->hw; -+ -+ if (hw->conf.flags & IEEE80211_CONF_IDLE) -+ rtw89_leave_ips(rtwdev); -+} -+ -+static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev) -+{ -+ struct ieee80211_hw *hw = rtwdev->hw; -+ -+ if (hw->conf.flags & IEEE80211_CONF_IDLE) -+ rtw89_enter_ips(rtwdev); -+} -+ - #endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-032-wifi-rtw89-add-flag-check-for-power-state.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-032-wifi-rtw89-add-flag-check-for-power-state.patch deleted file mode 100644 index 11a568664..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-032-wifi-rtw89-add-flag-check-for-power-state.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 6cfb6cc20a61aa17bdb5440459a3503a885ee913 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Tue, 11 Apr 2023 20:48:31 +0800 -Subject: [PATCH 032/136] wifi: rtw89: add flag check for power state - -Use POWER_ON flag to make sure power on/off is symmetric. Since both -remain_on_channel and hw_scan both alter the power state, this makes -sure that we don't enter/leave IPS mode twice. -Also, replace IPS related functions with inline function that does -similar logic so we can track it more easily. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230411124832.14965-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 7 +++---- - drivers/net/wireless/realtek/rtw89/ps.c | 6 ++++++ - 2 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2207,8 +2207,7 @@ static void rtw89_ips_work(struct work_s - struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, - ips_work); - mutex_lock(&rtwdev->mutex); -- if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE) -- rtw89_enter_ips(rtwdev); -+ rtw89_enter_ips_by_hwflags(rtwdev); - mutex_unlock(&rtwdev->mutex); - } - -@@ -3501,8 +3500,8 @@ void rtw89_core_scan_start(struct rtw89_ - - rtwdev->scanning = true; - rtw89_leave_lps(rtwdev); -- if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) -- rtw89_leave_ips(rtwdev); -+ if (hw_scan) -+ rtw89_leave_ips_by_hwflags(rtwdev); - - ether_addr_copy(rtwvif->mac_addr, mac_addr); - rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type); ---- a/drivers/net/wireless/realtek/rtw89/ps.c -+++ b/drivers/net/wireless/realtek/rtw89/ps.c -@@ -155,6 +155,9 @@ void rtw89_enter_ips(struct rtw89_dev *r - - set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); - -+ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) -+ return; -+ - rtw89_for_each_rtwvif(rtwdev, rtwvif) - rtw89_mac_vif_deinit(rtwdev, rtwvif); - -@@ -166,6 +169,9 @@ void rtw89_leave_ips(struct rtw89_dev *r - struct rtw89_vif *rtwvif; - int ret; - -+ if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) -+ return; -+ - ret = rtw89_core_start(rtwdev); - if (ret) - rtw89_err(rtwdev, "failed to leave idle state\n"); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-033-wifi-rtw89-fix-authentication-fail-during-scan.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-033-wifi-rtw89-fix-authentication-fail-during-scan.patch deleted file mode 100644 index 6c3f6a306..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-033-wifi-rtw89-fix-authentication-fail-during-scan.patch +++ /dev/null @@ -1,79 +0,0 @@ -From c5280e5f6763c216e16feec10c63b6b32106ddb7 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Tue, 11 Apr 2023 20:48:32 +0800 -Subject: [PATCH 033/136] wifi: rtw89: fix authentication fail during scan - -We used to store operating channel info after associated. However, scan -might happen before that. Without switching back to operating channel, -authentication or association might fail. Therefore, we switch back to -operating channel when the scanning vif's BSSID is non-zero, which -implies connected or during attempt to connect. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230411124832.14965-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -3199,7 +3199,7 @@ static void rtw89_hw_scan_add_chan(struc - } - - static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev, -- struct rtw89_vif *rtwvif) -+ struct rtw89_vif *rtwvif, bool connected) - { - struct cfg80211_scan_request *req = rtwvif->scan_req; - struct rtw89_mac_chinfo *ch_info, *tmp; -@@ -3243,7 +3243,7 @@ static int rtw89_hw_scan_add_chan_list(s - type = RTW89_CHAN_ACTIVE; - rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info); - -- if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK && -+ if (connected && - off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) { - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) { -@@ -3276,7 +3276,7 @@ out: - } - - static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev, -- struct rtw89_vif *rtwvif) -+ struct rtw89_vif *rtwvif, bool connected) - { - int ret; - -@@ -3285,7 +3285,7 @@ static int rtw89_hw_scan_prehandle(struc - rtw89_err(rtwdev, "Update probe request failed\n"); - goto out; - } -- ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif); -+ ret = rtw89_hw_scan_add_chan_list(rtwdev, rtwvif, connected); - out: - return ret; - } -@@ -3363,16 +3363,19 @@ int rtw89_hw_scan_offload(struct rtw89_d - { - struct rtw89_scan_option opt = {0}; - struct rtw89_vif *rtwvif; -+ bool connected; - int ret = 0; - - rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; - if (!rtwvif) - return -EINVAL; - -+ /* This variable implies connected or during attempt to connect */ -+ connected = !is_zero_ether_addr(rtwvif->bssid); - opt.enable = enable; -- opt.target_ch_mode = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK; -+ opt.target_ch_mode = connected; - if (enable) { -- ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif); -+ ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected); - if (ret) - goto out; - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-034-wifi-rtw89-fw-use-generic-flow-to-set-check-features.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-034-wifi-rtw89-fw-use-generic-flow-to-set-check-features.patch deleted file mode 100644 index 0e54bb7de..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-034-wifi-rtw89-fw-use-generic-flow-to-set-check-features.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 639ec6d63588b7e7c2dfae1df447daf243fb8342 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 20 Mar 2023 21:06:04 +0800 -Subject: [PATCH 034/136] wifi: rtw89: fw: use generic flow to set/check - features - -In early feature bitmap obtained from rtw89_early_fw_feature_recognize(), -the bits needed to check get increased. It's more friendly to work with -RTW89_CHK_FW_FEATURE(). So, we concentrate the flow of iterating FW feature -configures and calling RTW89_SET_FW_FEATURE() for various uses. And then, -we adjust rtw89_early_fw_feature_recognize() for RTW89_CHK_FW_FEATURE(). - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320130606.20777-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 8 ++--- - drivers/net/wireless/realtek/rtw89/fw.c | 41 +++++++++++------------ - drivers/net/wireless/realtek/rtw89/fw.h | 2 +- - 3 files changed, 25 insertions(+), 26 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3754,23 +3754,23 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - u32 bus_data_size, - const struct rtw89_chip_info *chip) - { -+ struct rtw89_fw_info early_fw = {}; - const struct firmware *firmware; - struct ieee80211_hw *hw; - struct rtw89_dev *rtwdev; - struct ieee80211_ops *ops; - u32 driver_data_size; -- u32 early_feat_map = 0; - bool no_chanctx; - -- firmware = rtw89_early_fw_feature_recognize(device, chip, &early_feat_map); -+ firmware = rtw89_early_fw_feature_recognize(device, chip, &early_fw); - - ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); - if (!ops) - goto err; - - no_chanctx = chip->support_chanctx_num == 0 || -- !(early_feat_map & BIT(RTW89_FW_FEATURE_SCAN_OFFLOAD)) || -- !(early_feat_map & BIT(RTW89_FW_FEATURE_BEACON_FILTER)); -+ !RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &early_fw) || -+ !RTW89_CHK_FW_FEATURE(BEACON_FILTER, &early_fw); - - if (no_chanctx) { - ops->add_chanctx = NULL; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -269,38 +269,45 @@ static const struct __fw_feat_cfg fw_fea - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER), - }; - -+static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, -+ const struct rtw89_chip_info *chip, -+ u32 ver_code) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { -+ const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; -+ -+ if (chip->chip_id != ent->chip_id) -+ continue; -+ -+ if (ent->cond(ver_code, ent->ver_code)) -+ RTW89_SET_FW_FEATURE(ent->feature, fw); -+ } -+} -+ - static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -- const struct __fw_feat_cfg *ent; - const struct rtw89_fw_suit *fw_suit; - u32 suit_ver_code; -- int i; - - fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); - suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit); - -- for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { -- ent = &fw_feat_tbl[i]; -- if (chip->chip_id != ent->chip_id) -- continue; -- -- if (ent->cond(suit_ver_code, ent->ver_code)) -- RTW89_SET_FW_FEATURE(ent->feature, &rtwdev->fw); -- } -+ rtw89_fw_iterate_feature_cfg(&rtwdev->fw, chip, suit_ver_code); - } - - const struct firmware * - rtw89_early_fw_feature_recognize(struct device *device, - const struct rtw89_chip_info *chip, -- u32 *early_feat_map) -+ struct rtw89_fw_info *early_fw) - { - union rtw89_compat_fw_hdr buf = {}; - const struct firmware *firmware; - bool full_req = false; - u32 ver_code; - int ret; -- int i; - - /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will - * be denied (-EPERM). Then, we don't get right firmware things as -@@ -329,15 +336,7 @@ rtw89_early_fw_feature_recognize(struct - if (!ver_code) - goto out; - -- for (i = 0; i < ARRAY_SIZE(fw_feat_tbl); i++) { -- const struct __fw_feat_cfg *ent = &fw_feat_tbl[i]; -- -- if (chip->chip_id != ent->chip_id) -- continue; -- -- if (ent->cond(ver_code, ent->ver_code)) -- *early_feat_map |= BIT(ent->feature); -- } -+ rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code); - - out: - if (full_req) ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3658,7 +3658,7 @@ int rtw89_fw_recognize(struct rtw89_dev - const struct firmware * - rtw89_early_fw_feature_recognize(struct device *device, - const struct rtw89_chip_info *chip, -- u32 *early_feat_map); -+ struct rtw89_fw_info *early_fw); - int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); - int rtw89_load_firmware(struct rtw89_dev *rtwdev); - void rtw89_unload_firmware(struct rtw89_dev *rtwdev); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-035-wifi-rtw89-use-schedule_work-to-request-firmware.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-035-wifi-rtw89-use-schedule_work-to-request-firmware.patch deleted file mode 100644 index ba93049a8..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-035-wifi-rtw89-use-schedule_work-to-request-firmware.patch +++ /dev/null @@ -1,225 +0,0 @@ -From b80ad23a8f2e0b63384cadc0aa2c1135b1dc03eb Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 20 Mar 2023 21:06:05 +0800 -Subject: [PATCH 035/136] wifi: rtw89: use schedule_work to request firmware - -Since we are going to load more than one firmware and some are not -presented or optional, using asynchronous API request_firmware_nowait() -will become complicated. Also, we want to use firmware_request_nowarn() -to avoid warning messages when loading optional files. So, use -schedule_work to be simpler. - -To abstract loading a firmware or file, define a struct rtw89_fw_req_info -containing a struct firmware and a completion to ensure this firmware is -loaded completely. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320130606.20777-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 17 +++--- - drivers/net/wireless/realtek/rtw89/core.h | 8 ++- - drivers/net/wireless/realtek/rtw89/fw.c | 68 ++++++++++------------- - drivers/net/wireless/realtek/rtw89/fw.h | 2 +- - 4 files changed, 45 insertions(+), 50 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3423,7 +3423,6 @@ void rtw89_core_stop(struct rtw89_dev *r - int rtw89_core_init(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -- int ret; - u8 band; - - INIT_LIST_HEAD(&rtwdev->ba_list); -@@ -3457,6 +3456,8 @@ int rtw89_core_init(struct rtw89_dev *rt - - INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); - INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); -+ INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); -+ - skb_queue_head_init(&rtwdev->c2h_queue); - rtw89_core_ppdu_sts_init(rtwdev); - rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); -@@ -3468,12 +3469,10 @@ int rtw89_core_init(struct rtw89_dev *rt - INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); - INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); - -- ret = rtw89_load_firmware(rtwdev); -- if (ret) { -- rtw89_warn(rtwdev, "no firmware loaded\n"); -- destroy_workqueue(rtwdev->txq_wq); -- return ret; -- } -+ init_completion(&rtwdev->fw.req.completion); -+ -+ schedule_work(&rtwdev->load_firmware_work); -+ - rtw89_ser_init(rtwdev); - rtw89_entity_init(rtwdev); - -@@ -3792,7 +3791,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - rtwdev->dev = device; - rtwdev->ops = ops; - rtwdev->chip = chip; -- rtwdev->fw.firmware = firmware; -+ rtwdev->fw.req.firmware = firmware; - - rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n", - no_chanctx ? "without" : "with"); -@@ -3809,7 +3808,7 @@ EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); - void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev) - { - kfree(rtwdev->ops); -- release_firmware(rtwdev->fw.firmware); -+ release_firmware(rtwdev->fw.req.firmware); - ieee80211_free_hw(rtwdev->hw); - } - EXPORT_SYMBOL(rtw89_free_ieee80211_hw); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3297,10 +3297,13 @@ struct rtw89_fw_suit { - GET_FW_HDR_SUBVERSION(fw_hdr), \ - GET_FW_HDR_SUBINDEX(fw_hdr)) - --struct rtw89_fw_info { -+struct rtw89_fw_req_info { - const struct firmware *firmware; -- struct rtw89_dev *rtwdev; - struct completion completion; -+}; -+ -+struct rtw89_fw_info { -+ struct rtw89_fw_req_info req; - u8 h2c_seq; - u8 rec_seq; - u8 h2c_counter; -@@ -4018,6 +4021,7 @@ struct rtw89_dev { - struct sk_buff_head c2h_queue; - struct work_struct c2h_work; - struct work_struct ips_work; -+ struct work_struct load_firmware_work; - - struct list_head early_h2c_list; - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -155,8 +155,9 @@ int rtw89_mfw_recognize(struct rtw89_dev - struct rtw89_fw_suit *fw_suit, bool nowarn) - { - struct rtw89_fw_info *fw_info = &rtwdev->fw; -- const u8 *mfw = fw_info->firmware->data; -- u32 mfw_len = fw_info->firmware->size; -+ const struct firmware *firmware = fw_info->req.firmware; -+ const u8 *mfw = firmware->data; -+ u32 mfw_len = firmware->size; - const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; - const struct rtw89_mfw_info *mfw_info; - int i; -@@ -631,67 +632,58 @@ int rtw89_wait_firmware_completion(struc - { - struct rtw89_fw_info *fw = &rtwdev->fw; - -- wait_for_completion(&fw->completion); -- if (!fw->firmware) -+ wait_for_completion(&fw->req.completion); -+ if (!fw->req.firmware) - return -EINVAL; - - return 0; - } - --static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context) -+static int rtw89_load_firmware_req(struct rtw89_dev *rtwdev, -+ struct rtw89_fw_req_info *req, -+ const char *fw_name, bool nowarn) - { -- struct rtw89_fw_info *fw = context; -- struct rtw89_dev *rtwdev = fw->rtwdev; -- -- if (!firmware || !firmware->data) { -- rtw89_err(rtwdev, "failed to request firmware\n"); -- complete_all(&fw->completion); -- return; -- } -- -- fw->firmware = firmware; -- complete_all(&fw->completion); --} -- --int rtw89_load_firmware(struct rtw89_dev *rtwdev) --{ -- struct rtw89_fw_info *fw = &rtwdev->fw; -- const char *fw_name = rtwdev->chip->fw_name; - int ret; - -- fw->rtwdev = rtwdev; -- init_completion(&fw->completion); -- -- if (fw->firmware) { -+ if (req->firmware) { - rtw89_debug(rtwdev, RTW89_DBG_FW, - "full firmware has been early requested\n"); -- complete_all(&fw->completion); -+ complete_all(&req->completion); - return 0; - } - -- ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, -- GFP_KERNEL, fw, rtw89_load_firmware_cb); -- if (ret) { -- rtw89_err(rtwdev, "failed to async firmware request\n"); -- return ret; -- } -+ if (nowarn) -+ ret = firmware_request_nowarn(&req->firmware, fw_name, rtwdev->dev); -+ else -+ ret = request_firmware(&req->firmware, fw_name, rtwdev->dev); - -- return 0; -+ complete_all(&req->completion); -+ -+ return ret; -+} -+ -+void rtw89_load_firmware_work(struct work_struct *work) -+{ -+ struct rtw89_dev *rtwdev = -+ container_of(work, struct rtw89_dev, load_firmware_work); -+ const char *fw_name = rtwdev->chip->fw_name; -+ -+ rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); - } - - void rtw89_unload_firmware(struct rtw89_dev *rtwdev) - { - struct rtw89_fw_info *fw = &rtwdev->fw; - -- rtw89_wait_firmware_completion(rtwdev); -+ cancel_work_sync(&rtwdev->load_firmware_work); - -- if (fw->firmware) { -- release_firmware(fw->firmware); -+ if (fw->req.firmware) { -+ release_firmware(fw->req.firmware); - - /* assign NULL back in case rtw89_free_ieee80211_hw() - * try to release the same one again. - */ -- fw->firmware = NULL; -+ fw->req.firmware = NULL; - } - } - ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3660,7 +3660,7 @@ rtw89_early_fw_feature_recognize(struct - const struct rtw89_chip_info *chip, - struct rtw89_fw_info *early_fw); - int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); --int rtw89_load_firmware(struct rtw89_dev *rtwdev); -+void rtw89_load_firmware_work(struct work_struct *work); - void rtw89_unload_firmware(struct rtw89_dev *rtwdev); - int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev); - void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-036-wifi-rtw89-add-firmware-format-version-to-backward-c.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-036-wifi-rtw89-add-firmware-format-version-to-backward-c.patch deleted file mode 100644 index ffa3f83a4..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-036-wifi-rtw89-add-firmware-format-version-to-backward-c.patch +++ /dev/null @@ -1,273 +0,0 @@ -From ffde7f3476a6dfd5856dc2af207dd0f950b10122 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 20 Mar 2023 21:06:06 +0800 -Subject: [PATCH 036/136] wifi: rtw89: add firmware format version to backward - compatible with older drivers - -In the discuss threads [1] [2], new firmware format break user space -because older drivers can't recognize new firmware format. To avoid this, -the new format will be named rtw89/rtw8852b_fw-1.bin and only new driver -try to load it. Old drivers only load original and understandable firmware -rtw89/rtw8852b_fw.bin. - -More, new driver will be still backward compatible with old firmware, so -original firmware can be used by new driver. - -If there is newer firmware format is introduced, rtw89/rtw8852b_fw-2.bin -will be given. The same rules will be applied like above. So, we will have -firmware like below in linux-firmware in the future. - - rtw89/rtw8852b_fw-2.bin - rtw89/rtw8852b_fw-1.bin - rtw89/rtw8852b_fw.bin - -After this patch, MODULE_FIRMWARE() of 8852A/B/C become - rtw89/rtw8852a_fw.bin - rtw89/rtw8852b_fw-1.bin - rtw89/rtw8852c_fw.bin - -[1] https://lore.kernel.org/linux-wireless/df1ce994-3368-a57e-7078-8bdcccf4a1fd@gmail.com/T/#m24cb43be31a762d0ea70bf07f27ae96c59f6931b -[2] https://bugzilla.kernel.org/show_bug.cgi?id=217207 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230320130606.20777-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 4 ++- - drivers/net/wireless/realtek/rtw89/core.h | 4 ++- - drivers/net/wireless/realtek/rtw89/fw.c | 33 ++++++++++++++----- - drivers/net/wireless/realtek/rtw89/fw.h | 12 ++++++- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 10 ++++-- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 10 ++++-- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 10 ++++-- - 7 files changed, 66 insertions(+), 17 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3759,9 +3759,10 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - struct rtw89_dev *rtwdev; - struct ieee80211_ops *ops; - u32 driver_data_size; -+ int fw_format = -1; - bool no_chanctx; - -- firmware = rtw89_early_fw_feature_recognize(device, chip, &early_fw); -+ firmware = rtw89_early_fw_feature_recognize(device, chip, &early_fw, &fw_format); - - ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); - if (!ops) -@@ -3792,6 +3793,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - rtwdev->ops = ops; - rtwdev->chip = chip; - rtwdev->fw.req.firmware = firmware; -+ rtwdev->fw.fw_format = fw_format; - - rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n", - no_chanctx ? "without" : "with"); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3080,7 +3080,8 @@ struct rtw89_phy_ul_tb_info { - struct rtw89_chip_info { - enum rtw89_core_chip_id chip_id; - const struct rtw89_chip_ops *ops; -- const char *fw_name; -+ const char *fw_basename; -+ u8 fw_format_max; - bool try_ce_fw; - u32 fifo_size; - u32 dle_scc_rsvd_size; -@@ -3304,6 +3305,7 @@ struct rtw89_fw_req_info { - - struct rtw89_fw_info { - struct rtw89_fw_req_info req; -+ int fw_format; - u8 h2c_seq; - u8 rec_seq; - u8 h2c_counter; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -302,11 +302,14 @@ static void rtw89_fw_recognize_features( - const struct firmware * - rtw89_early_fw_feature_recognize(struct device *device, - const struct rtw89_chip_info *chip, -- struct rtw89_fw_info *early_fw) -+ struct rtw89_fw_info *early_fw, -+ int *used_fw_format) - { - union rtw89_compat_fw_hdr buf = {}; - const struct firmware *firmware; - bool full_req = false; -+ char fw_name[64]; -+ int fw_format; - u32 ver_code; - int ret; - -@@ -317,12 +320,22 @@ rtw89_early_fw_feature_recognize(struct - if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE)) - full_req = true; - -- if (full_req) -- ret = request_firmware(&firmware, chip->fw_name, device); -- else -- ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, -- device, &buf, sizeof(buf), -- 0); -+ for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) { -+ rtw89_fw_get_filename(fw_name, sizeof(fw_name), -+ chip->fw_basename, fw_format); -+ -+ if (full_req) -+ ret = request_firmware(&firmware, fw_name, device); -+ else -+ ret = request_partial_firmware_into_buf(&firmware, fw_name, -+ device, &buf, sizeof(buf), -+ 0); -+ if (!ret) { -+ dev_info(device, "loaded firmware %s\n", fw_name); -+ *used_fw_format = fw_format; -+ break; -+ } -+ } - - if (ret) { - dev_err(device, "failed to early request firmware: %d\n", ret); -@@ -666,7 +679,11 @@ void rtw89_load_firmware_work(struct wor - { - struct rtw89_dev *rtwdev = - container_of(work, struct rtw89_dev, load_firmware_work); -- const char *fw_name = rtwdev->chip->fw_name; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ char fw_name[64]; -+ -+ rtw89_fw_get_filename(fw_name, sizeof(fw_name), -+ chip->fw_basename, rtwdev->fw.fw_format); - - rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3515,6 +3515,15 @@ static inline u32 rtw89_compat_fw_hdr_ve - return RTW89_FW_HDR_VER_CODE(&compat->fw_hdr); - } - -+static inline void rtw89_fw_get_filename(char *buf, size_t size, -+ const char *fw_basename, int fw_format) -+{ -+ if (fw_format <= 0) -+ snprintf(buf, size, "%s.bin", fw_basename); -+ else -+ snprintf(buf, size, "%s-%d.bin", fw_basename, fw_format); -+} -+ - #define RTW89_H2C_RF_PAGE_SIZE 500 - #define RTW89_H2C_RF_PAGE_NUM 3 - struct rtw89_fw_h2c_rf_reg_info { -@@ -3658,7 +3667,8 @@ int rtw89_fw_recognize(struct rtw89_dev - const struct firmware * - rtw89_early_fw_feature_recognize(struct device *device, - const struct rtw89_chip_info *chip, -- struct rtw89_fw_info *early_fw); -+ struct rtw89_fw_info *early_fw, -+ int *used_fw_format); - int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); - void rtw89_load_firmware_work(struct work_struct *work); - void rtw89_unload_firmware(struct rtw89_dev *rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -12,6 +12,11 @@ - #include "rtw8852a_table.h" - #include "txrx.h" - -+#define RTW8852A_FW_FORMAT_MAX 0 -+#define RTW8852A_FW_BASENAME "rtw89/rtw8852a_fw" -+#define RTW8852A_MODULE_FIRMWARE \ -+ RTW8852A_FW_BASENAME ".bin" -+ - static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = { - {128, 1896, grp_0}, /* ACH 0 */ - {128, 1896, grp_0}, /* ACH 1 */ -@@ -2059,7 +2064,8 @@ static const struct rtw89_chip_ops rtw88 - const struct rtw89_chip_info rtw8852a_chip_info = { - .chip_id = RTL8852A, - .ops = &rtw8852a_chip_ops, -- .fw_name = "rtw89/rtw8852a_fw.bin", -+ .fw_basename = RTW8852A_FW_BASENAME, -+ .fw_format_max = RTW8852A_FW_FORMAT_MAX, - .try_ce_fw = false, - .fifo_size = 458752, - .dle_scc_rsvd_size = 0, -@@ -2156,7 +2162,7 @@ const struct rtw89_chip_info rtw8852a_ch - }; - EXPORT_SYMBOL(rtw8852a_chip_info); - --MODULE_FIRMWARE("rtw89/rtw8852a_fw.bin"); -+MODULE_FIRMWARE(RTW8852A_MODULE_FIRMWARE); - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852A driver"); - MODULE_LICENSE("Dual BSD/GPL"); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -12,6 +12,11 @@ - #include "rtw8852b_table.h" - #include "txrx.h" - -+#define RTW8852B_FW_FORMAT_MAX 1 -+#define RTW8852B_FW_BASENAME "rtw89/rtw8852b_fw" -+#define RTW8852B_MODULE_FIRMWARE \ -+ RTW8852B_FW_BASENAME "-" __stringify(RTW8852B_FW_FORMAT_MAX) ".bin" -+ - static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = { - {5, 343, grp_0}, /* ACH 0 */ - {5, 343, grp_0}, /* ACH 1 */ -@@ -2480,7 +2485,8 @@ static const struct rtw89_chip_ops rtw88 - const struct rtw89_chip_info rtw8852b_chip_info = { - .chip_id = RTL8852B, - .ops = &rtw8852b_chip_ops, -- .fw_name = "rtw89/rtw8852b_fw.bin", -+ .fw_basename = RTW8852B_FW_BASENAME, -+ .fw_format_max = RTW8852B_FW_FORMAT_MAX, - .try_ce_fw = true, - .fifo_size = 196608, - .dle_scc_rsvd_size = 98304, -@@ -2576,7 +2582,7 @@ const struct rtw89_chip_info rtw8852b_ch - }; - EXPORT_SYMBOL(rtw8852b_chip_info); - --MODULE_FIRMWARE("rtw89/rtw8852b_fw.bin"); -+MODULE_FIRMWARE(RTW8852B_MODULE_FIRMWARE); - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852B driver"); - MODULE_LICENSE("Dual BSD/GPL"); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -13,6 +13,11 @@ - #include "rtw8852c_table.h" - #include "util.h" - -+#define RTW8852C_FW_FORMAT_MAX 0 -+#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw" -+#define RTW8852C_MODULE_FIRMWARE \ -+ RTW8852C_FW_BASENAME ".bin" -+ - static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = { - {13, 1614, grp_0}, /* ACH 0 */ - {13, 1614, grp_0}, /* ACH 1 */ -@@ -2791,7 +2796,8 @@ static const struct rtw89_chip_ops rtw88 - const struct rtw89_chip_info rtw8852c_chip_info = { - .chip_id = RTL8852C, - .ops = &rtw8852c_chip_ops, -- .fw_name = "rtw89/rtw8852c_fw.bin", -+ .fw_basename = RTW8852C_FW_BASENAME, -+ .fw_format_max = RTW8852C_FW_FORMAT_MAX, - .try_ce_fw = false, - .fifo_size = 458752, - .dle_scc_rsvd_size = 0, -@@ -2892,7 +2898,7 @@ const struct rtw89_chip_info rtw8852c_ch - }; - EXPORT_SYMBOL(rtw8852c_chip_info); - --MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin"); -+MODULE_FIRMWARE(RTW8852C_MODULE_FIRMWARE); - MODULE_AUTHOR("Realtek Corporation"); - MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver"); - MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-037-wifi-rtw89-support-parameter-tables-by-RFE-type.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-037-wifi-rtw89-support-parameter-tables-by-RFE-type.patch deleted file mode 100644 index 3706f174f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-037-wifi-rtw89-support-parameter-tables-by-RFE-type.patch +++ /dev/null @@ -1,532 +0,0 @@ -From 5395482afabb61cc980c9e78f013dd31cf212568 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 30 Mar 2023 16:03:31 +0800 -Subject: [PATCH 037/136] wifi: rtw89: support parameter tables by RFE type - -One chip can have different RFE (RF front end) types which we will judge -at runtime. And, different RFE types may use different RF parameter tables. -Though we didn't really meet this case previously, we are going to meet it -on upcoming chip RTL8851B. So, this commit handles parameter tables for -runtime RFE type. - -We now encapsulate rtw89_txpwr_rule_<2/5/6>ghz tables into rtw89_rfe_parms. -Then, each chip defines its default parameter tables, and if needed, it can -configure extra parameter tables by RFE type. Finally we determine runtime -parameter tables by RFE type if one is configured. Otherwise, we use the -default parameter tables. - -For now, we just move all settings under default parameter tables. We will -configure parameter tables by RFE types in separate commits afterwards. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330080331.37155-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 23 +++++++ - drivers/net/wireless/realtek/rtw89/core.h | 55 +++++++++++----- - drivers/net/wireless/realtek/rtw89/phy.c | 64 +++++++++++-------- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 6 +- - .../wireless/realtek/rtw89/rtw8852a_table.c | 15 +++++ - .../wireless/realtek/rtw89/rtw8852a_table.h | 11 +--- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 6 +- - .../wireless/realtek/rtw89/rtw8852b_table.c | 15 +++++ - .../wireless/realtek/rtw89/rtw8852b_table.h | 11 +--- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 8 +-- - .../wireless/realtek/rtw89/rtw8852c_table.c | 21 ++++++ - .../wireless/realtek/rtw89/rtw8852c_table.h | 16 +---- - 12 files changed, 161 insertions(+), 90 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3557,6 +3557,28 @@ static void rtw89_core_setup_phycap(stru - rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV; - } - -+static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_rfe_parms_conf *conf = chip->rfe_parms_conf; -+ struct rtw89_efuse *efuse = &rtwdev->efuse; -+ u8 rfe_type = efuse->rfe_type; -+ -+ if (!conf) -+ goto out; -+ -+ while (conf->rfe_parms) { -+ if (rfe_type == conf->rfe_type) { -+ rtwdev->rfe_parms = conf->rfe_parms; -+ return; -+ } -+ conf++; -+ } -+ -+out: -+ rtwdev->rfe_parms = chip->dflt_parms; -+} -+ - static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) - { - int ret; -@@ -3578,6 +3600,7 @@ static int rtw89_chip_efuse_info_setup(s - return ret; - - rtw89_core_setup_phycap(rtwdev); -+ rtw89_core_setup_rfe_parms(rtwdev); - - rtw89_mac_pwr_off(rtwdev); - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2990,6 +2990,41 @@ struct rtw89_txpwr_table { - const struct rtw89_txpwr_table *tbl); - }; - -+struct rtw89_txpwr_rule_2ghz { -+ const s8 (*lmt)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -+ const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -+}; -+ -+struct rtw89_txpwr_rule_5ghz { -+ const s8 (*lmt)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+ const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+}; -+ -+struct rtw89_txpwr_rule_6ghz { -+ const s8 (*lmt)[RTW89_6G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+ const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+}; -+ -+struct rtw89_rfe_parms { -+ struct rtw89_txpwr_rule_2ghz rule_2ghz; -+ struct rtw89_txpwr_rule_5ghz rule_5ghz; -+ struct rtw89_txpwr_rule_6ghz rule_6ghz; -+}; -+ -+struct rtw89_rfe_parms_conf { -+ const struct rtw89_rfe_parms *rfe_parms; -+ u8 rfe_type; -+}; -+ - struct rtw89_page_regs { - u32 hci_fc_ctrl; - u32 ch_page_ctrl; -@@ -3127,21 +3162,10 @@ struct rtw89_chip_info { - const struct rtw89_phy_dig_gain_table *dig_table; - const struct rtw89_dig_regs *dig_regs; - const struct rtw89_phy_tssi_dbw_table *tssi_dbw_table; -- const s8 (*txpwr_lmt_2g)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -- const s8 (*txpwr_lmt_5g)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -- const s8 (*txpwr_lmt_6g)[RTW89_6G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -- const s8 (*txpwr_lmt_ru_2g)[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; -- const s8 (*txpwr_lmt_ru_5g)[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -- const s8 (*txpwr_lmt_ru_6g)[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+ -+ /* NULL if no rfe-specific, or a null-terminated array by rfe_parms */ -+ const struct rtw89_rfe_parms_conf *rfe_parms_conf; -+ const struct rtw89_rfe_parms *dflt_parms; - - u8 txpwr_factor_rf; - u8 txpwr_factor_mac; -@@ -3992,6 +4016,7 @@ struct rtw89_dev { - struct rtw89_hw_scan_info scan_info; - const struct rtw89_chip_info *chip; - const struct rtw89_pci_info *pci_info; -+ const struct rtw89_rfe_parms *rfe_parms; - struct rtw89_hal hal; - struct rtw89_mcc_info mcc; - struct rtw89_mac_info mac; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1617,29 +1617,35 @@ static u8 rtw89_channel_to_idx(struct rt - s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, - u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; -+ const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; -+ const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; -+ const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; - u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); - u8 regd = rtw89_regd_get(rtwdev, band); - s8 lmt = 0, sar; - - switch (band) { - case RTW89_BAND_2G: -- lmt = (*chip->txpwr_lmt_2g)[bw][ntx][rs][bf][regd][ch_idx]; -- if (!lmt) -- lmt = (*chip->txpwr_lmt_2g)[bw][ntx][rs][bf] -- [RTW89_WW][ch_idx]; -+ lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; -+ if (lmt) -+ break; -+ -+ lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_5G: -- lmt = (*chip->txpwr_lmt_5g)[bw][ntx][rs][bf][regd][ch_idx]; -- if (!lmt) -- lmt = (*chip->txpwr_lmt_5g)[bw][ntx][rs][bf] -- [RTW89_WW][ch_idx]; -+ lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; -+ if (lmt) -+ break; -+ -+ lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_6G: -- lmt = (*chip->txpwr_lmt_6g)[bw][ntx][rs][bf][regd][ch_idx]; -- if (!lmt) -- lmt = (*chip->txpwr_lmt_6g)[bw][ntx][rs][bf] -- [RTW89_WW][ch_idx]; -+ lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; -+ if (lmt) -+ break; -+ -+ lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; - break; - default: - rtw89_warn(rtwdev, "unknown band type: %d\n", band); -@@ -1862,29 +1868,35 @@ void rtw89_phy_fill_txpwr_limit(struct r - static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, - u8 ru, u8 ntx, u8 ch) - { -- const struct rtw89_chip_info *chip = rtwdev->chip; -+ const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms; -+ const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; -+ const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; -+ const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; - u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); - u8 regd = rtw89_regd_get(rtwdev, band); - s8 lmt_ru = 0, sar; - - switch (band) { - case RTW89_BAND_2G: -- lmt_ru = (*chip->txpwr_lmt_ru_2g)[ru][ntx][regd][ch_idx]; -- if (!lmt_ru) -- lmt_ru = (*chip->txpwr_lmt_ru_2g)[ru][ntx] -- [RTW89_WW][ch_idx]; -+ lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][regd][ch_idx]; -+ if (lmt_ru) -+ break; -+ -+ lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_5G: -- lmt_ru = (*chip->txpwr_lmt_ru_5g)[ru][ntx][regd][ch_idx]; -- if (!lmt_ru) -- lmt_ru = (*chip->txpwr_lmt_ru_5g)[ru][ntx] -- [RTW89_WW][ch_idx]; -+ lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][regd][ch_idx]; -+ if (lmt_ru) -+ break; -+ -+ lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_6G: -- lmt_ru = (*chip->txpwr_lmt_ru_6g)[ru][ntx][regd][ch_idx]; -- if (!lmt_ru) -- lmt_ru = (*chip->txpwr_lmt_ru_6g)[ru][ntx] -- [RTW89_WW][ch_idx]; -+ lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][ch_idx]; -+ if (lmt_ru) -+ break; -+ -+ lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; - break; - default: - rtw89_warn(rtwdev, "unknown band type: %d\n", band); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2085,10 +2085,8 @@ const struct rtw89_chip_info rtw8852a_ch - &rtw89_8852a_phy_radiob_table,}, - .nctl_table = &rtw89_8852a_phy_nctl_table, - .byr_table = &rtw89_8852a_byr_table, -- .txpwr_lmt_2g = &rtw89_8852a_txpwr_lmt_2g, -- .txpwr_lmt_5g = &rtw89_8852a_txpwr_lmt_5g, -- .txpwr_lmt_ru_2g = &rtw89_8852a_txpwr_lmt_ru_2g, -- .txpwr_lmt_ru_5g = &rtw89_8852a_txpwr_lmt_ru_5g, -+ .dflt_parms = &rtw89_8852a_dflt_parms, -+ .rfe_parms_conf = NULL, - .txpwr_factor_rf = 2, - .txpwr_factor_mac = 1, - .dig_table = &rtw89_8852a_phy_dig_table, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c -@@ -43377,6 +43377,7 @@ static const s8 _txpwr_track_delta_swing - 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, - 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; - -+static - const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -@@ -45566,6 +45567,7 @@ const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -@@ -47898,6 +47900,7 @@ const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_UK][41] = 40, - }; - -+static - const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { - [0][0][RTW89_WW][0] = 32, -@@ -48994,6 +48997,7 @@ const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW - [2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { - [0][0][RTW89_WW][0] = 22, -@@ -51043,3 +51047,14 @@ const struct rtw89_phy_dig_gain_table rt - .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, - .cfg_tia_a = &rtw89_8852a_tia_gain_a_table - }; -+ -+const struct rtw89_rfe_parms rtw89_8852a_dflt_parms = { -+ .rule_2ghz = { -+ .lmt = &rtw89_8852a_txpwr_lmt_2g, -+ .lmt_ru = &rtw89_8852a_txpwr_lmt_ru_2g, -+ }, -+ .rule_5ghz = { -+ .lmt = &rtw89_8852a_txpwr_lmt_5g, -+ .lmt_ru = &rtw89_8852a_txpwr_lmt_ru_5g, -+ }, -+}; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h -@@ -14,15 +14,6 @@ extern const struct rtw89_phy_table rtw8 - extern const struct rtw89_txpwr_table rtw89_8852a_byr_table; - extern const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table; - extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg; --extern const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; --extern const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+extern const struct rtw89_rfe_parms rtw89_8852a_dflt_parms; - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2506,10 +2506,8 @@ const struct rtw89_chip_info rtw8852b_ch - &rtw89_8852b_phy_radiob_table,}, - .nctl_table = &rtw89_8852b_phy_nctl_table, - .byr_table = &rtw89_8852b_byr_table, -- .txpwr_lmt_2g = &rtw89_8852b_txpwr_lmt_2g, -- .txpwr_lmt_5g = &rtw89_8852b_txpwr_lmt_5g, -- .txpwr_lmt_ru_2g = &rtw89_8852b_txpwr_lmt_ru_2g, -- .txpwr_lmt_ru_5g = &rtw89_8852b_txpwr_lmt_ru_5g, -+ .dflt_parms = &rtw89_8852b_dflt_parms, -+ .rfe_parms_conf = NULL, - .txpwr_factor_rf = 2, - .txpwr_factor_mac = 1, - .dig_table = NULL, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -@@ -14706,6 +14706,7 @@ const u8 rtw89_8852b_tx_shape[RTW89_BAND - [1][1][RTW89_UKRAINE] = 0, - }; - -+static - const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -@@ -16895,6 +16896,7 @@ const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -@@ -19539,6 +19541,7 @@ const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_UK][49] = 127, - }; - -+static - const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { - [0][0][RTW89_WW][0] = 32, -@@ -20635,6 +20638,7 @@ const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW - [2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { - [0][0][RTW89_WW][0] = 24, -@@ -22875,3 +22879,14 @@ const struct rtw89_txpwr_track_cfg rtw89 - .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, - .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, - }; -+ -+const struct rtw89_rfe_parms rtw89_8852b_dflt_parms = { -+ .rule_2ghz = { -+ .lmt = &rtw89_8852b_txpwr_lmt_2g, -+ .lmt_ru = &rtw89_8852b_txpwr_lmt_ru_2g, -+ }, -+ .rule_5ghz = { -+ .lmt = &rtw89_8852b_txpwr_lmt_5g, -+ .lmt_ru = &rtw89_8852b_txpwr_lmt_ru_5g, -+ }, -+}; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h -@@ -16,15 +16,6 @@ extern const struct rtw89_txpwr_table rt - extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg; - extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM]; --extern const s8 rtw89_8852b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; --extern const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; -+extern const struct rtw89_rfe_parms rtw89_8852b_dflt_parms; - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2817,12 +2817,8 @@ const struct rtw89_chip_info rtw8852c_ch - &rtw89_8852c_phy_radioa_table,}, - .nctl_table = &rtw89_8852c_phy_nctl_table, - .byr_table = &rtw89_8852c_byr_table, -- .txpwr_lmt_2g = &rtw89_8852c_txpwr_lmt_2g, -- .txpwr_lmt_5g = &rtw89_8852c_txpwr_lmt_5g, -- .txpwr_lmt_6g = &rtw89_8852c_txpwr_lmt_6g, -- .txpwr_lmt_ru_2g = &rtw89_8852c_txpwr_lmt_ru_2g, -- .txpwr_lmt_ru_5g = &rtw89_8852c_txpwr_lmt_ru_5g, -- .txpwr_lmt_ru_6g = &rtw89_8852c_txpwr_lmt_ru_6g, -+ .dflt_parms = &rtw89_8852c_dflt_parms, -+ .rfe_parms_conf = NULL, - .txpwr_factor_rf = 2, - .txpwr_factor_mac = 1, - .dig_table = NULL, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -28590,6 +28590,7 @@ const u8 rtw89_8852c_tx_shape[RTW89_BAND - [2][1][RTW89_KCC] = 0, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -@@ -30107,6 +30108,7 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -@@ -32020,6 +32022,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_UK][45] = 127, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] - [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { -@@ -33977,6 +33980,7 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_ - [3][1][2][1][RTW89_KCC][112] = 127, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { - [0][0][RTW89_WW][0] = 32, -@@ -34737,6 +34741,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [2][1][RTW89_UK][13] = 127, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { - [0][0][RTW89_WW][0] = 16, -@@ -36253,6 +36258,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][1][RTW89_UK][52] = 127, - }; - -+static - const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { - [0][0][RTW89_WW][0] = -16, -@@ -37472,3 +37478,18 @@ const struct rtw89_phy_tssi_dbw_table rt - .data[RTW89_TSSI_BANDEDGE_MID] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - .data[RTW89_TSSI_BANDEDGE_HIGH] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - }; -+ -+const struct rtw89_rfe_parms rtw89_8852c_dflt_parms = { -+ .rule_2ghz = { -+ .lmt = &rtw89_8852c_txpwr_lmt_2g, -+ .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_2g, -+ }, -+ .rule_5ghz = { -+ .lmt = &rtw89_8852c_txpwr_lmt_5g, -+ .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_5g, -+ }, -+ .rule_6ghz = { -+ .lmt = &rtw89_8852c_txpwr_lmt_6g, -+ .lmt_ru = &rtw89_8852c_txpwr_lmt_ru_6g, -+ }, -+}; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h -@@ -17,20 +17,6 @@ extern const struct rtw89_phy_tssi_dbw_t - extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg; - extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] -- [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; --extern const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+extern const struct rtw89_rfe_parms rtw89_8852c_dflt_parms; - - #endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-038-wifi-rtw89-use-hardware-CFO-to-improve-performance.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-038-wifi-rtw89-use-hardware-CFO-to-improve-performance.patch deleted file mode 100644 index 1616f5b48..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-038-wifi-rtw89-use-hardware-CFO-to-improve-performance.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 9f9882dbe2eecdb27f5f3832f215679747f94d8f Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Thu, 30 Mar 2023 21:23:52 +0800 -Subject: [PATCH 038/136] wifi: rtw89: use hardware CFO to improve performance - -Turn on hardware CFO (central frequency offset) compensation based on IC -capability, and improve digital CFO compensation accuracy by using -more fixed points number. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330132352.13647-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 ++ - drivers/net/wireless/realtek/rtw89/phy.c | 28 +++++++++++++------ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 3 +- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 3 +- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 +- - 5 files changed, 29 insertions(+), 11 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3202,6 +3202,7 @@ struct rtw89_chip_info { - struct rtw89_reg_def c2h_counter_reg; - const struct rtw89_page_regs *page_regs; - bool cfo_src_fd; -+ bool cfo_hw_comp; - const struct rtw89_reg_def *dcfo_comp; - u8 dcfo_comp_sft; - const struct rtw89_imr_info *imr_info; -@@ -3684,6 +3685,8 @@ struct rtw89_cfo_tracking_info { - s32 cfo_avg_pre; - s32 cfo_avg[CFO_TRACK_MAX_USER]; - s32 pre_cfo_avg[CFO_TRACK_MAX_USER]; -+ s32 dcfo_avg; -+ s32 dcfo_avg_pre; - u32 packet_count; - u32 packet_count_pre; - s32 residual_cfo_acc; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2417,7 +2417,6 @@ static void rtw89_dcfo_comp(struct rtw89 - bool is_linked = rtwdev->total_sta_assoc > 0; - s32 cfo_avg_312; - s32 dcfo_comp_val; -- u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft; - int sign; - - if (!is_linked) { -@@ -2430,8 +2429,8 @@ static void rtw89_dcfo_comp(struct rtw89 - return; - dcfo_comp_val = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO); - sign = curr_cfo > 0 ? 1 : -1; -- cfo_avg_312 = (curr_cfo << dcfo_comp_sft) / 5 + sign * dcfo_comp_val; -- rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: avg_cfo=%d\n", cfo_avg_312); -+ cfo_avg_312 = curr_cfo / 625 + sign * dcfo_comp_val; -+ rtw89_debug(rtwdev, RTW89_DBG_CFO, "avg_cfo_312=%d step\n", cfo_avg_312); - if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) - cfo_avg_312 = -cfo_avg_312; - rtw89_phy_set_phy_regs(rtwdev, dcfo_comp->addr, dcfo_comp->mask, -@@ -2440,9 +2439,16 @@ static void rtw89_dcfo_comp(struct rtw89 - - static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ - rtw89_phy_set_phy_regs(rtwdev, R_DCFO_OPT, B_DCFO_OPT_EN, 1); - rtw89_phy_set_phy_regs(rtwdev, R_DCFO_WEIGHT, B_DCFO_WEIGHT_MSK, 8); -- rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK); -+ -+ if (chip->cfo_hw_comp) -+ rtw89_write32_mask(rtwdev, R_AX_PWR_UL_CTRL2, -+ B_AX_PWR_UL_CFO_MASK, 0x6); -+ else -+ rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK); - } - - static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev) -@@ -2512,6 +2518,7 @@ static void rtw89_phy_cfo_crystal_cap_ad - - static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; - s32 cfo_khz_all = 0; - s32 cfo_cnt_all = 0; -@@ -2528,6 +2535,8 @@ static s32 rtw89_phy_average_cfo_calc(st - cfo_cnt_all += cfo->cfo_cnt[i]; - cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all); - cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; -+ cfo->dcfo_avg = phy_div(cfo_khz_all << chip->dcfo_comp_sft, -+ cfo_cnt_all); - } - rtw89_debug(rtwdev, RTW89_DBG_CFO, - "CFO track for macid = %d\n", i); -@@ -2654,7 +2663,9 @@ static void rtw89_phy_cfo_dm(struct rtw8 - s32 new_cfo = 0; - bool x_cap_update = false; - u8 pre_x_cap = cfo->crystal_cap; -+ u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft; - -+ cfo->dcfo_avg = 0; - rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n", - rtwdev->total_sta_assoc); - if (rtwdev->total_sta_assoc == 0) { -@@ -2696,18 +2707,19 @@ static void rtw89_phy_cfo_dm(struct rtw8 - - rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo); - cfo->cfo_avg_pre = new_cfo; -+ cfo->dcfo_avg_pre = cfo->dcfo_avg; - x_cap_update = cfo->crystal_cap != pre_x_cap; - rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update); - rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n", - cfo->def_x_cap, pre_x_cap, cfo->crystal_cap, - cfo->x_cap_ofst); - if (x_cap_update) { -- if (new_cfo > 0) -- new_cfo -= CFO_SW_COMP_FINE_TUNE; -+ if (cfo->dcfo_avg > 0) -+ cfo->dcfo_avg -= CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft; - else -- new_cfo += CFO_SW_COMP_FINE_TUNE; -+ cfo->dcfo_avg += CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft; - } -- rtw89_dcfo_comp(rtwdev, new_cfo); -+ rtw89_dcfo_comp(rtwdev, cfo->dcfo_avg); - rtw89_phy_cfo_statistics_reset(rtwdev); - } - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2147,8 +2147,9 @@ const struct rtw89_chip_info rtw8852a_ch - .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, - .page_regs = &rtw8852a_page_regs, - .cfo_src_fd = false, -+ .cfo_hw_comp = false, - .dcfo_comp = &rtw8852a_dcfo_comp, -- .dcfo_comp_sft = 3, -+ .dcfo_comp_sft = 10, - .imr_info = &rtw8852a_imr_info, - .rrsr_cfgs = &rtw8852a_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2568,8 +2568,9 @@ const struct rtw89_chip_info rtw8852b_ch - .c2h_regs = rtw8852b_c2h_regs, - .page_regs = &rtw8852b_page_regs, - .cfo_src_fd = true, -+ .cfo_hw_comp = true, - .dcfo_comp = &rtw8852b_dcfo_comp, -- .dcfo_comp_sft = 3, -+ .dcfo_comp_sft = 10, - .imr_info = &rtw8852b_imr_info, - .rrsr_cfgs = &rtw8852b_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP_V1, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2881,8 +2881,9 @@ const struct rtw89_chip_info rtw8852c_ch - .c2h_regs = rtw8852c_c2h_regs, - .page_regs = &rtw8852c_page_regs, - .cfo_src_fd = false, -+ .cfo_hw_comp = false, - .dcfo_comp = &rtw8852c_dcfo_comp, -- .dcfo_comp_sft = 5, -+ .dcfo_comp_sft = 12, - .imr_info = &rtw8852c_imr_info, - .rrsr_cfgs = &rtw8852c_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-039-wifi-rtw89-read-version-of-analog-hardware.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-039-wifi-rtw89-read-version-of-analog-hardware.patch deleted file mode 100644 index d151f45f7..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-039-wifi-rtw89-read-version-of-analog-hardware.patch +++ /dev/null @@ -1,72 +0,0 @@ -From a6fb2bb84654dde55fab94251c9119b6917d098d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 30 Mar 2023 21:33:21 +0800 -Subject: [PATCH 039/136] wifi: rtw89: read version of analog hardware - -The chip contains digital and analog parts, and each of them has its own -version number. This is used by BT coexistence mechanism to make strategy -decision for different analog version. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330133324.19538-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 10 ++++++++++ - drivers/net/wireless/realtek/rtw89/core.h | 2 ++ - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - 3 files changed, 13 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3535,6 +3535,8 @@ void rtw89_core_scan_complete(struct rtw - static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; -+ int ret; -+ u8 val; - u8 cv; - - cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK); -@@ -3546,6 +3548,14 @@ static void rtw89_read_chip_ver(struct r - } - - rtwdev->hal.cv = cv; -+ -+ if (chip->chip_id == RTL8852B || chip->chip_id == RTL8851B) { -+ ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CV, &val); -+ if (!ret) -+ return; -+ -+ rtwdev->hal.acv = u8_get_bits(val, XTAL_SI_ACV_MASK); -+ } - } - - static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -108,6 +108,7 @@ enum rtw89_core_chip_id { - RTL8852A, - RTL8852B, - RTL8852C, -+ RTL8851B, - }; - - enum rtw89_cv { -@@ -3412,6 +3413,7 @@ struct rtw89_sub_entity { - struct rtw89_hal { - u32 rx_fltr; - u8 cv; -+ u8 acv; - u32 sw_amsdu_max_size; - u32 antenna_tx; - u32 antenna_rx; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -1117,6 +1117,7 @@ enum rtw89_mac_xtal_si_offset { - XTAL_SI_XTAL_XMD_4 = 0x26, - #define XTAL_SI_LPS_CAP GENMASK(3, 0) - XTAL_SI_CV = 0x41, -+#define XTAL_SI_ACV_MASK GENMASK(3, 0) - XTAL_SI_LOW_ADDR = 0x62, - #define XTAL_SI_LOW_ADDR_MASK GENMASK(7, 0) - XTAL_SI_CTRL = 0x63, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-040-wifi-rtw89-8851b-fix-TX-path-to-path-A-for-one-RF-pa.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-040-wifi-rtw89-8851b-fix-TX-path-to-path-A-for-one-RF-pa.patch deleted file mode 100644 index 965d0f8b7..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-040-wifi-rtw89-8851b-fix-TX-path-to-path-A-for-one-RF-pa.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d5289b2d69a777d24686d7ee8264a55761dc9f93 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 30 Mar 2023 21:33:22 +0800 -Subject: [PATCH 040/136] wifi: rtw89: 8851b: fix TX path to path A for one RF - path chip - -For two RF paths chips, we normally set path B as main path by default. -8851B has single one RF path, so set TX path to A and set mapping of -path B to 0. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330133324.19538-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -1161,9 +1161,18 @@ fail: - static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev, - struct sk_buff *skb) - { -+ const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_hal *hal = &rtwdev->hal; -- u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; -- u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0; -+ u8 ntx_path; -+ u8 map_b; -+ -+ if (chip->rf_path_num == 1) { -+ ntx_path = RF_A; -+ map_b = 0; -+ } else { -+ ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; -+ map_b = hal->antenna_tx == RF_AB ? 1 : 0; -+ } - - SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); - SET_CMC_TBL_PATH_MAP_A(skb->data, 0); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-041-wifi-rtw89-mac-update-MAC-settings-to-support-8851b.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-041-wifi-rtw89-mac-update-MAC-settings-to-support-8851b.patch deleted file mode 100644 index ce67cdbc3..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-041-wifi-rtw89-mac-update-MAC-settings-to-support-8851b.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 5c3afcba545cc820ba7911cecdf3abb05ea5e0df Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 30 Mar 2023 21:33:23 +0800 -Subject: [PATCH 041/136] wifi: rtw89: mac: update MAC settings to support - 8851b - -Many settings of 8851B are the same as 8852B or 8852A, like DLE (Data link -engine), security engine and so on. Update them according to hardware -design. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330133324.19538-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 44 +++++++++++++++++------- - drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ - 2 files changed, 33 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1584,12 +1584,15 @@ static void dle_func_en(struct rtw89_dev - - static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable) - { -- if (enable) -- rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, -- B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); -- else -- rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, -- B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); -+ u32 val = B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN; -+ -+ if (enable) { -+ if (rtwdev->chip->chip_id == RTL8851B) -+ val |= B_AX_AXIDMA_CLK_EN; -+ rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, val); -+ } else { -+ rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, val); -+ } - } - - static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg) -@@ -1854,7 +1857,8 @@ static int preload_init(struct rtw89_dev - { - const struct rtw89_chip_info *chip = rtwdev->chip; - -- if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || !is_qta_poh(rtwdev)) -+ if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || -+ chip->chip_id == RTL8851B || !is_qta_poh(rtwdev)) - return 0; - - return preload_init_set(rtwdev, mac_idx, mode); -@@ -1890,7 +1894,8 @@ static void _patch_ss2f_path(struct rtw8 - { - const struct rtw89_chip_info *chip = rtwdev->chip; - -- if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) -+ if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || -+ chip->chip_id == RTL8851B) - return; - - rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK, -@@ -1959,7 +1964,8 @@ static int sec_eng_init(struct rtw89_dev - /* init TX encryption */ - val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC); - val |= (B_AX_MC_DEC | B_AX_BC_DEC); -- if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) -+ if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || -+ chip->chip_id == RTL8851B) - val &= ~B_AX_TX_PARTIAL_MODE; - rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); - -@@ -2065,7 +2071,7 @@ static int scheduler_init(struct rtw89_d - rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK, - SIFS_MACTXEN_T1); - -- if (rtwdev->chip->chip_id == RTL8852B) { -+ if (rtwdev->chip->chip_id == RTL8852B || rtwdev->chip->chip_id == RTL8851B) { - reg = rtw89_mac_reg_by_idx(R_AX_SCH_EXT_CTRL, mac_idx); - rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV); - } -@@ -3364,8 +3370,15 @@ static int rtw89_mac_trx_init(struct rtw - - static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev) - { -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; - u32 val32; - -+ if (chip_id == RTL8852B || chip_id == RTL8851B) { -+ rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN); -+ rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN); -+ return; -+ } -+ - rtw89_mac_mem_write(rtwdev, R_AX_WDT_CTRL, - WDT_CTRL_ALL_DIS, RTW89_MAC_MEM_CPU_LOCAL); - -@@ -3450,7 +3463,10 @@ static int rtw89_mac_dmac_pre_init(struc - B_AX_PKT_BUF_EN; - rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val); - -- val = B_AX_DISPATCHER_CLK_EN; -+ if (chip_id == RTL8851B) -+ val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN; -+ else -+ val = B_AX_DISPATCHER_CLK_EN; - rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val); - - if (chip_id != RTL8852C) -@@ -4691,11 +4707,13 @@ int rtw89_mac_coex_init(struct rtw89_dev - int ret; - - rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT); -- rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN); -+ if (rtwdev->chip->chip_id != RTL8851B) -+ rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN); - rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8); - rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK); - rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16); -- rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24); -+ if (rtwdev->chip->chip_id != RTL8851B) -+ rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24); - - val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0); - val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN; ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -129,6 +129,7 @@ - - #define R_AX_PLATFORM_ENABLE 0x0088 - #define B_AX_AXIDMA_EN BIT(3) -+#define B_AX_APB_WRAP_EN BIT(2) - #define B_AX_WCPU_EN BIT(1) - #define B_AX_PLATFORM_EN BIT(0) - -@@ -488,6 +489,7 @@ - #define B_AX_DISPATCHER_CLK_EN BIT(18) - #define B_AX_BBRPT_CLK_EN BIT(17) - #define B_AX_MAC_SEC_CLK_EN BIT(16) -+#define B_AX_AXIDMA_CLK_EN BIT(9) - - #define PCI_LTR_IDLE_TIMER_1US 0 - #define PCI_LTR_IDLE_TIMER_10US 1 diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-042-wifi-rtw89-pci-update-PCI-related-settings-to-suppor.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-042-wifi-rtw89-pci-update-PCI-related-settings-to-suppor.patch deleted file mode 100644 index 2aa603d3e..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-042-wifi-rtw89-pci-update-PCI-related-settings-to-suppor.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 2a6d518dedcbc8dc6e666c1a68700945bca174b8 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 30 Mar 2023 21:33:24 +0800 -Subject: [PATCH 042/136] wifi: rtw89: pci: update PCI related settings to - support 8851B - -Many settings of 8851B are like 8852A or 8852B. Change them to proper -settings as hardware design. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230330133324.19538-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/pci.c | 33 +++++++++++++++--------- - 1 file changed, 21 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -1917,9 +1917,10 @@ __get_target(struct rtw89_dev *rtwdev, u - - static int rtw89_pci_autok_x(struct rtw89_dev *rtwdev) - { -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; - int ret; - -- if (rtwdev->chip->chip_id != RTL8852B) -+ if (chip_id != RTL8852B && chip_id != RTL8851B) - return 0; - - ret = rtw89_write16_mdio_mask(rtwdev, RAC_REG_FLD_0, BAC_AUTOK_N_MASK, -@@ -1929,13 +1930,14 @@ static int rtw89_pci_autok_x(struct rtw8 - - static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) - { -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; - enum rtw89_pcie_phy phy_rate; - u16 val16, mgn_set, div_set, tar; - u8 val8, bdr_ori; - bool l1_flag = false; - int ret = 0; - -- if (rtwdev->chip->chip_id != RTL8852B) -+ if (chip_id != RTL8852B && chip_id != RTL8851B) - return 0; - - ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_PHY_RATE, &val8); -@@ -2112,7 +2114,9 @@ static void rtw89_pci_rxdma_prefth(struc - - static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev) - { -- if (rtwdev->chip->chip_id != RTL8852A && rtwdev->chip->chip_id != RTL8852B) -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; -+ -+ if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B) - return; - - rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN); -@@ -2140,7 +2144,9 @@ static u32 rtw89_pci_l2_rxen_lat(struct - - static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev) - { -- if (rtwdev->chip->chip_id != RTL8852A && rtwdev->chip->chip_id != RTL8852B) -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; -+ -+ if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B) - return; - - rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN); -@@ -2148,8 +2154,9 @@ static void rtw89_pci_aphy_pwrcut(struct - - static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) - { -- if (rtwdev->chip->chip_id == RTL8852A || -- rtwdev->chip->chip_id == RTL8852B) { -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; -+ -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); - rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, -@@ -2162,7 +2169,9 @@ static void rtw89_pci_hci_ldo(struct rtw - - static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev) - { -- if (rtwdev->chip->chip_id != RTL8852B) -+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; -+ -+ if (chip_id != RTL8852B && chip_id != RTL8851B) - return 0; - - return rtw89_write16_mdio_mask(rtwdev, RAC_REG_REV2, BAC_CMU_EN_DLY_MASK, -@@ -3402,7 +3411,7 @@ static void rtw89_pci_clkreq_set(struct - if (ret) - rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); - -- if (chip_id == RTL8852A || chip_id == RTL8852B) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, - RTW89_PCIE_L1_CTRL, -@@ -3447,7 +3456,7 @@ static void rtw89_pci_aspm_set(struct rt - if (ret) - rtw89_err(rtwdev, "failed to read ASPM Delay\n"); - -- if (chip_id == RTL8852A || chip_id == RTL8852B) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, - RTW89_PCIE_L1_CTRL, -@@ -3527,7 +3536,7 @@ static void rtw89_pci_l1ss_set(struct rt - enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; - int ret; - -- if (chip_id == RTL8852A || chip_id == RTL8852B) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, - RTW89_PCIE_TIMER_CTRL, -@@ -3726,7 +3735,7 @@ static int __maybe_unused rtw89_pci_susp - rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); - rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); - rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); -- if (chip_id == RTL8852A || chip_id == RTL8852B) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); - rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, -@@ -3760,7 +3769,7 @@ static int __maybe_unused rtw89_pci_resu - rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); - rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); - rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); -- if (chip_id == RTL8852A || chip_id == RTL8852B) { -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) { - rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, - B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); - rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-043-wifi-rtw89-8851b-add-BB-and-RF-tables-1-of-2.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-043-wifi-rtw89-8851b-add-BB-and-RF-tables-1-of-2.patch deleted file mode 100644 index 944a083a6..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-043-wifi-rtw89-8851b-add-BB-and-RF-tables-1-of-2.patch +++ /dev/null @@ -1,6819 +0,0 @@ -From 108bdaaa8bc7eafa2cf4aa3b883fdadca0d2ce45 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 1 Apr 2023 22:25:46 +0800 -Subject: [PATCH 043/136] wifi: rtw89: 8851b: add BB and RF tables (1 of 2) - -These tables contain BB and RF parameters that driver will load them into -registers. It also contains TX power according to country, band, rate and -so on. Increasing thermal can cause TX power degraded, so power tracking -tables are defined to compensate TX power. - -Internal version of these tables: - - HALBB_029_106_15 (V17) - - HALRF_029_00_089 - * Radio A 0x22 - * NCTL 0x5 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230401142548.55466-2-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8851b_table.c | 6766 +++++++++++++++++ - .../wireless/realtek/rtw89/rtw8851b_table.h | 21 + - 2 files changed, 6787 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_table.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_table.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -0,0 +1,6766 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#include "phy.h" -+#include "reg.h" -+#include "rtw8851b_table.h" -+ -+static const struct rtw89_reg2_def rtw89_8851b_phy_bb_regs[] = { -+ {0x704, 0x601E0500}, -+ {0x4000, 0x00000000}, -+ {0x4004, 0xCA014000}, -+ {0x4008, 0xC751D4F0}, -+ {0x400C, 0x44511475}, -+ {0x4010, 0x00000000}, -+ {0x4014, 0x00000000}, -+ {0x47BC, 0x00000380}, -+ {0x4018, 0x4F4C084B}, -+ {0x401C, 0x084A4E52}, -+ {0x4020, 0x4D504E4B}, -+ {0x4024, 0x4F4C0849}, -+ {0x4028, 0x08484C50}, -+ {0x402C, 0x4C50504C}, -+ {0x4030, 0x5454084A}, -+ {0x4034, 0x084B5654}, -+ {0x4038, 0x6A6C605A}, -+ {0x403C, 0x4C4C084C}, -+ {0x4040, 0x084B4E4D}, -+ {0x4044, 0x4E4C4B4B}, -+ {0x4048, 0x4B4B084A}, -+ {0x404C, 0x084A4E4C}, -+ {0x4050, 0x514F4C4A}, -+ {0x4054, 0x524E084A}, -+ {0x4058, 0x084A5154}, -+ {0x405C, 0x53555554}, -+ {0x4060, 0x45450845}, -+ {0x4064, 0x08454144}, -+ {0x4068, 0x40434445}, -+ {0x406C, 0x44450845}, -+ {0x4070, 0x08444043}, -+ {0x4074, 0x42434444}, -+ {0x4078, 0x46450844}, -+ {0x407C, 0x08444843}, -+ {0x4080, 0x4B4E4A47}, -+ {0x4084, 0x4F4C084B}, -+ {0x4088, 0x084A4E52}, -+ {0x408C, 0x4D504E4B}, -+ {0x4090, 0x4F4C0849}, -+ {0x4094, 0x08484C50}, -+ {0x4098, 0x4C50504C}, -+ {0x409C, 0x5454084A}, -+ {0x40A0, 0x084B5654}, -+ {0x40A4, 0x6A6C605A}, -+ {0x40A8, 0x4C4C084C}, -+ {0x40AC, 0x084B4E4D}, -+ {0x40B0, 0x4E4C4B4B}, -+ {0x40B4, 0x4B4B084A}, -+ {0x40B8, 0x084A4E4C}, -+ {0x40BC, 0x514F4C4A}, -+ {0x40C0, 0x524E084A}, -+ {0x40C4, 0x084A5154}, -+ {0x40C8, 0x53555554}, -+ {0x40CC, 0x45450845}, -+ {0x40D0, 0x08454144}, -+ {0x40D4, 0x40434445}, -+ {0x40D8, 0x44450845}, -+ {0x40DC, 0x08444043}, -+ {0x40E0, 0x42434444}, -+ {0x40E4, 0x46450844}, -+ {0x40E8, 0x08444843}, -+ {0x40EC, 0x4B4E4A47}, -+ {0x40F0, 0x00000000}, -+ {0x4A38, 0x00000000}, -+ {0x40F4, 0x00000006}, -+ {0x40F8, 0x00000000}, -+ {0x40FC, 0x8C30C30C}, -+ {0x4100, 0x4C30C30C}, -+ {0x4104, 0x0C30C30C}, -+ {0x4108, 0x0C30C30C}, -+ {0x410C, 0x0C30C30C}, -+ {0x4110, 0x0C30C30C}, -+ {0x4114, 0x28A28A28}, -+ {0x4118, 0x28A28A28}, -+ {0x411C, 0x28A28A28}, -+ {0x4120, 0x28A28A28}, -+ {0x4124, 0x28A28A28}, -+ {0x4128, 0x28A28A28}, -+ {0x412C, 0x06666666}, -+ {0x4130, 0x33333333}, -+ {0x4134, 0x33333333}, -+ {0x4138, 0x33333333}, -+ {0x413C, 0x00000031}, -+ {0x4140, 0x5100600A}, -+ {0x4144, 0x18363113}, -+ {0x4148, 0x1D976DDC}, -+ {0x414C, 0x1C072DD7}, -+ {0x4150, 0x1127CDF4}, -+ {0x4154, 0x1E37BDF1}, -+ {0x4158, 0x1FB7F1D6}, -+ {0x415C, 0x1EA7DDF9}, -+ {0x4160, 0x1FE445DD}, -+ {0x4164, 0x1F97F1FE}, -+ {0x4168, 0x1FF781ED}, -+ {0x416C, 0x1FA7F5FE}, -+ {0x4170, 0x1E07B913}, -+ {0x4174, 0x1FD7FDFF}, -+ {0x4178, 0x1E17B9FA}, -+ {0x417C, 0x19A66914}, -+ {0x4180, 0x10F65598}, -+ {0x4184, 0x14A5A111}, -+ {0x4188, 0x1D3765DB}, -+ {0x418C, 0x17C685CA}, -+ {0x4190, 0x1107C5F3}, -+ {0x4194, 0x1B5785EB}, -+ {0x4198, 0x1F97ED8F}, -+ {0x419C, 0x1BC7A5F3}, -+ {0x41A0, 0x1FE43595}, -+ {0x41A4, 0x1EB7D9FC}, -+ {0x41A8, 0x1FE65DBE}, -+ {0x41AC, 0x1EC7D9FC}, -+ {0x41B0, 0x1976FCFF}, -+ {0x41B4, 0x1F77F5FF}, -+ {0x41B8, 0x1976FDEC}, -+ {0x41BC, 0x198664EF}, -+ {0x41C0, 0x11062D93}, -+ {0x41C4, 0x10C4E910}, -+ {0x41C8, 0x1CA759DB}, -+ {0x41CC, 0x1335A9B5}, -+ {0x41D0, 0x1097B9F3}, -+ {0x41D4, 0x17B72DE1}, -+ {0x41D8, 0x1F67ED42}, -+ {0x41DC, 0x18074DE9}, -+ {0x41E0, 0x1FD40547}, -+ {0x41E4, 0x1D57ADF9}, -+ {0x41E8, 0x1FE52182}, -+ {0x41EC, 0x1D67B1F9}, -+ {0x41F0, 0x14860CE1}, -+ {0x41F4, 0x1EC7E9FE}, -+ {0x41F8, 0x14860DD6}, -+ {0x41FC, 0x195664C7}, -+ {0x4200, 0x0005E58A}, -+ {0x4204, 0x00000000}, -+ {0x4208, 0x00000000}, -+ {0x420C, 0x7A000000}, -+ {0x4210, 0x0F9F3D7A}, -+ {0x4214, 0x0040817C}, -+ {0x4218, 0x00E10204}, -+ {0x421C, 0x227D94CD}, -+ {0x4220, 0x08028A28}, -+ {0x4224, 0x00000200}, -+ {0x4228, 0x04688000}, -+ {0x47C0, 0x00000001}, -+ {0x4A48, 0x00000002}, -+ {0x4B04, 0x00000000}, -+ {0x4B08, 0x00000000}, -+ {0x422C, 0x0060B002}, -+ {0x4230, 0x9A8249A8}, -+ {0x4234, 0x26A1469E}, -+ {0x4238, 0x2099A824}, -+ {0x423C, 0x2359461C}, -+ {0x4240, 0x1631A675}, -+ {0x4244, 0x2C6B1D63}, -+ {0x4248, 0x0000000E}, -+ {0x424C, 0x00000001}, -+ {0x4250, 0x00000001}, -+ {0x4254, 0x00000000}, -+ {0x4258, 0x00000000}, -+ {0x425C, 0x00000000}, -+ {0x4260, 0x0020000C}, -+ {0x4A30, 0x00000000}, -+ {0x4264, 0x00000000}, -+ {0x4268, 0x00000000}, -+ {0x426C, 0x0418317C}, -+ {0x4270, 0x2B33135C}, -+ {0x4274, 0x00000002}, -+ {0x4278, 0x00000000}, -+ {0x427C, 0x00000000}, -+ {0x4280, 0x00000000}, -+ {0x4284, 0x00000000}, -+ {0x4288, 0x00000000}, -+ {0x428C, 0x00000000}, -+ {0x4290, 0x00000000}, -+ {0x4294, 0x00000000}, -+ {0x4298, 0x00000000}, -+ {0x429C, 0x84026000}, -+ {0x42A0, 0x0051AC20}, -+ {0x4A24, 0x0010C040}, -+ {0x42A4, 0x02024008}, -+ {0x42A8, 0x00000000}, -+ {0x42AC, 0x00000000}, -+ {0x42B0, 0x22CE803C}, -+ {0x42B4, 0xD8000000}, -+ {0x42B8, 0x596FD67E}, -+ {0x42BC, 0x7D67D67D}, -+ {0x42C0, 0x7D67D65B}, -+ {0x42C4, 0x28029F59}, -+ {0x42C8, 0x00280280}, -+ {0x4AF4, 0x00000000}, -+ {0x42CC, 0x00000000}, -+ {0x42D0, 0x00000000}, -+ {0x42D4, 0x00000003}, -+ {0x4AF8, 0x00280000}, -+ {0x42D8, 0x00000001}, -+ {0x42DC, 0x69AEC800}, -+ {0x42E0, 0x8B4CD3D1}, -+ {0x42E4, 0xC514534F}, -+ {0x42E8, 0x85145145}, -+ {0x42EC, 0x45145145}, -+ {0x42F0, 0x05145145}, -+ {0x42F4, 0x05145145}, -+ {0x42F8, 0x05145145}, -+ {0x42FC, 0x17659145}, -+ {0x4300, 0x176DD5D9}, -+ {0x4304, 0x0F65765B}, -+ {0x4308, 0x0F3CF3CF}, -+ {0x430C, 0x0F3CF3CF}, -+ {0x4310, 0x0F3CF3CF}, -+ {0x4314, 0x0F3CF3CF}, -+ {0x4318, 0x0F3CF3CF}, -+ {0x431C, 0x0F3CF3CF}, -+ {0x4320, 0x0F3CF3CF}, -+ {0x4324, 0x0F44F351}, -+ {0x4328, 0x192D7547}, -+ {0x432C, 0x0F5CF5CF}, -+ {0x4330, 0x051593D9}, -+ {0x4334, 0x05145145}, -+ {0x4338, 0x05145145}, -+ {0x433C, 0x05145145}, -+ {0x4340, 0x05145145}, -+ {0x4344, 0x05145145}, -+ {0x4348, 0x19545145}, -+ {0x434C, 0x1B65B5DB}, -+ {0x4350, 0x1965965B}, -+ {0x4354, 0x0F3CF3CF}, -+ {0x4358, 0x0F3CF3CF}, -+ {0x435C, 0x0F3CF1CF}, -+ {0x4360, 0x0F3CF3CF}, -+ {0x4364, 0x0F3CF3CF}, -+ {0x4368, 0x0F3CF3CF}, -+ {0x436C, 0x0F3CF3CF}, -+ {0x4370, 0x0934D2CF}, -+ {0x4374, 0x112CB3CF}, -+ {0x4378, 0x9777A777}, -+ {0x437C, 0xBB7BAC95}, -+ {0x4380, 0xB667B889}, -+ {0x4384, 0x7B9B8899}, -+ {0x4388, 0x7A5567C8}, -+ {0x438C, 0x2278CCCC}, -+ {0x4390, 0x7C222222}, -+ {0x4394, 0x0000029B}, -+ {0x4398, 0x001CCCCC}, -+ {0x4AAC, 0xCCCCC88C}, -+ {0x4AB0, 0x0000AACC}, -+ {0x439C, 0x00000000}, -+ {0x43A0, 0x00000008}, -+ {0x43A4, 0x00000000}, -+ {0x43A8, 0x00000000}, -+ {0x43AC, 0x00000000}, -+ {0x43B0, 0x10000000}, -+ {0x43B4, 0x00401001}, -+ {0x43B8, 0x00061003}, -+ {0x43BC, 0x000024D8}, -+ {0x43C0, 0x00000000}, -+ {0x43C4, 0x10000020}, -+ {0x43C8, 0x20000200}, -+ {0x43CC, 0x00000000}, -+ {0x43D0, 0x04000000}, -+ {0x43D4, 0x44000100}, -+ {0x43D8, 0x60804060}, -+ {0x43DC, 0x44204210}, -+ {0x43E0, 0x82108082}, -+ {0x43E4, 0x82108402}, -+ {0x43E8, 0xC8082108}, -+ {0x43EC, 0xC8202084}, -+ {0x43F0, 0x44208208}, -+ {0x43F4, 0x84108204}, -+ {0x43F8, 0xD0108104}, -+ {0x43FC, 0xF8210108}, -+ {0x4400, 0x6431E930}, -+ {0x4404, 0x02309468}, -+ {0x4408, 0x10C61C22}, -+ {0x440C, 0x02109469}, -+ {0x4410, 0x10C61C22}, -+ {0x4414, 0x00041049}, -+ {0x4A4C, 0x00060581}, -+ {0x4418, 0x00000000}, -+ {0x441C, 0x00000000}, -+ {0x4420, 0xEC000000}, -+ {0x4424, 0xB0200020}, -+ {0x4428, 0x00001FF0}, -+ {0x4AC8, 0x00000001}, -+ {0x4B0C, 0x00000000}, -+ {0x4CDC, 0x00000000}, -+ {0x442C, 0x00000000}, -+ {0x4430, 0x00000000}, -+ {0x4434, 0x00000000}, -+ {0x4438, 0x00000000}, -+ {0x443C, 0x190642D0}, -+ {0x4440, 0xA80668A0}, -+ {0x4444, 0x60900820}, -+ {0x4448, 0x9F28518C}, -+ {0x444C, 0x32488A62}, -+ {0x4450, 0x9C6E36DC}, -+ {0x4454, 0x0000F52B}, -+ {0x4A34, 0x00000007}, -+ {0x4CE0, 0x68120000}, -+ {0x4CE4, 0x1A0681E0}, -+ {0x4CE8, 0x94060180}, -+ {0x4CEC, 0x000603FF}, -+ {0x4CF0, 0xA0502000}, -+ {0x4CF4, 0x00001000}, -+ {0x4D00, 0x00000044}, -+ {0x4B14, 0x00000000}, -+ {0x4458, 0x00000000}, -+ {0x445C, 0x4801442E}, -+ {0x4460, 0x0051A0FA}, -+ {0x4B18, 0x0000011F}, -+ {0x4B1C, 0x0000011F}, -+ {0x4464, 0x00000000}, -+ {0x4468, 0x00000000}, -+ {0x446C, 0x00000000}, -+ {0x4470, 0x00000000}, -+ {0x4474, 0x00000000}, -+ {0x4478, 0x00000000}, -+ {0x447C, 0x00000000}, -+ {0x4480, 0x2A0A6040}, -+ {0x4484, 0x0A0A6829}, -+ {0x4488, 0x00000004}, -+ {0x448C, 0x00000000}, -+ {0x4490, 0x80000000}, -+ {0x4494, 0x10000000}, -+ {0x4498, 0xE0000000}, -+ {0x4A28, 0x000ED877}, -+ {0x4AB4, 0x00000000}, -+ {0x4B20, 0x00000000}, -+ {0x4B24, 0x00000000}, -+ {0x4B28, 0x00000000}, -+ {0x4B2C, 0x00000000}, -+ {0x449C, 0x0000001E}, -+ {0x44A0, 0x02B2C394}, -+ {0x44A4, 0x00000400}, -+ {0x4A2C, 0x0050240E}, -+ {0x4B30, 0x7FFFFD20}, -+ {0x4B34, 0x920823FF}, -+ {0x4B38, 0x7FFFFFFF}, -+ {0x4B3C, 0x01773773}, -+ {0x44A8, 0x00000001}, -+ {0x44AC, 0x000190C0}, -+ {0x44B0, 0x00000000}, -+ {0x44B4, 0x00000000}, -+ {0x44B8, 0x00000000}, -+ {0x44BC, 0x00000000}, -+ {0x44C0, 0x00000000}, -+ {0x44C4, 0x00000000}, -+ {0x44C8, 0x00000000}, -+ {0x44CC, 0x00000000}, -+ {0x44D0, 0x00000000}, -+ {0x44D4, 0x00000000}, -+ {0x44D8, 0x00000000}, -+ {0x44DC, 0x00000000}, -+ {0x44E0, 0x00000000}, -+ {0x44E4, 0x00000000}, -+ {0x44E8, 0x00000000}, -+ {0x44EC, 0x00000000}, -+ {0x44F0, 0x00000000}, -+ {0x44F4, 0x00000000}, -+ {0x44F8, 0x00000000}, -+ {0x44FC, 0x00000000}, -+ {0x4500, 0x00000000}, -+ {0x4504, 0x00000000}, -+ {0x4508, 0x00000000}, -+ {0x450C, 0x00000000}, -+ {0x4510, 0x00000000}, -+ {0x4514, 0x00000000}, -+ {0x4518, 0x00000000}, -+ {0x451C, 0x00000000}, -+ {0x4520, 0x00000000}, -+ {0x4524, 0x00000000}, -+ {0x4528, 0x00000000}, -+ {0x452C, 0x00000000}, -+ {0x4530, 0x4E830171}, -+ {0x4534, 0x00000870}, -+ {0x4538, 0x000000FF}, -+ {0x453C, 0x00000000}, -+ {0x4540, 0x00000000}, -+ {0x4544, 0x00000000}, -+ {0x4548, 0x00000000}, -+ {0x454C, 0x00000000}, -+ {0x4550, 0x00000000}, -+ {0x4554, 0x00000000}, -+ {0x4558, 0x00000000}, -+ {0x455C, 0x00000000}, -+ {0x4560, 0x40000000}, -+ {0x4564, 0x40000000}, -+ {0x4568, 0x00000000}, -+ {0x456C, 0x20000000}, -+ {0x4570, 0x04F040BB}, -+ {0x4574, 0x000E53FF}, -+ {0x4578, 0x000205CB}, -+ {0x457C, 0x00200000}, -+ {0x4580, 0x00000040}, -+ {0x4584, 0x00000000}, -+ {0x4588, 0x00000017}, -+ {0x458C, 0x30000000}, -+ {0x4590, 0x00000000}, -+ {0x4594, 0x00000000}, -+ {0x4598, 0x00000001}, -+ {0x459C, 0x0003FE00}, -+ {0x45A0, 0x00000086}, -+ {0x45A4, 0x00000000}, -+ {0x45A8, 0xC00001C0}, -+ {0x45AC, 0x78038000}, -+ {0x45B0, 0x8000004A}, -+ {0x45B4, 0x04094800}, -+ {0x45B8, 0x00280002}, -+ {0x45BC, 0x06748790}, -+ {0x45C0, 0x80000000}, -+ {0x45C4, 0x00000000}, -+ {0x45C8, 0x00000000}, -+ {0x45CC, 0x00558670}, -+ {0x45D0, 0x002883F0}, -+ {0x45D4, 0x00090120}, -+ {0x45D8, 0x00000000}, -+ {0x45E0, 0xA3A6D3C4}, -+ {0x45E4, 0xAB27B126}, -+ {0x45E8, 0x00006778}, -+ {0x45F4, 0x000001B5}, -+ {0x45EC, 0x11110F0A}, -+ {0x45F0, 0x00000003}, -+ {0x4A0C, 0x0000000A}, -+ {0x45F8, 0x0058BC3F}, -+ {0x45FC, 0x00000003}, -+ {0x462C, 0x00000020}, -+ {0x4600, 0x000003D9}, -+ {0x45F0, 0x00000004}, -+ {0x4604, 0x002B1CB0}, -+ {0x4A50, 0xC0000000}, -+ {0x4A54, 0x00001000}, -+ {0x4A58, 0x00000000}, -+ {0x4A18, 0x00000024}, -+ {0x4608, 0x00000001}, -+ {0x460C, 0x00000000}, -+ {0x4A10, 0x00000001}, -+ {0x4610, 0x00000001}, -+ {0x4614, 0x16E5298F}, -+ {0x4618, 0x18C6294A}, -+ {0x461C, 0x0E06318A}, -+ {0x4620, 0x0E539CE5}, -+ {0x4624, 0x00019287}, -+ {0x4A14, 0x000000BF}, -+ {0x4628, 0x00000001}, -+ {0x4630, 0x000001AA}, -+ {0x4A18, 0x00001900}, -+ {0x4A1C, 0x000002A6}, -+ {0x4634, 0x000000A3}, -+ {0x4A20, 0x00000086}, -+ {0x4638, 0x00045656}, -+ {0x49F8, 0x00000000}, -+ {0x463C, 0x00000000}, -+ {0x4640, 0x00000000}, -+ {0x4644, 0x00C8CC00}, -+ {0x4648, 0xC400B6B6}, -+ {0x464C, 0xDC400FC0}, -+ {0x4A44, 0x00000000}, -+ {0x4A8C, 0x00000110}, -+ {0x4BC4, 0x00000001}, -+ {0x4650, 0x08882550}, -+ {0x4654, 0x08CC2660}, -+ {0x4658, 0x09102660}, -+ {0x465C, 0x00000154}, -+ {0x45DC, 0xC39E38E8}, -+ {0x4660, 0x452607E6}, -+ {0x4664, 0x6750DC65}, -+ {0x4668, 0xF3F0F1ED}, -+ {0x466C, 0x30141506}, -+ {0x4670, 0x2C2B2B2B}, -+ {0x4674, 0x2C2C2C2C}, -+ {0x4678, 0xDDB738E8}, -+ {0x467C, 0x543618FB}, -+ {0x4680, 0x4F31DC6F}, -+ {0x4684, 0xFBEBDA00}, -+ {0x4688, 0x1A10FF04}, -+ {0x468C, 0x282A3000}, -+ {0x4690, 0x2A29292A}, -+ {0x4694, 0x04FA2A2A}, -+ {0x4698, 0xEE0F04D1}, -+ {0x469C, 0x99E91436}, -+ {0x46A0, 0x0701E79E}, -+ {0x46A4, 0x08D77CFF}, -+ {0x46A8, 0x321AFF14}, -+ {0x46AC, 0x60313447}, -+ {0x46B0, 0x63666666}, -+ {0x46B4, 0x35374425}, -+ {0x46B8, 0x35883042}, -+ {0x46BC, 0x5177C252}, -+ {0x4720, 0x7FFFFD63}, -+ {0x4724, 0xB58D11FF}, -+ {0x4728, 0x47FFFFFF}, -+ {0x472C, 0x0E7893B6}, -+ {0x4730, 0xE0391201}, -+ {0x4734, 0x00000020}, -+ {0x4738, 0x8325C500}, -+ {0x473C, 0x00000B7F}, -+ {0x46C0, 0x00000000}, -+ {0x46C4, 0x00000000}, -+ {0x46C8, 0x00000219}, -+ {0x4BDC, 0x00002020}, -+ {0x46CC, 0x00000000}, -+ {0x46D0, 0x00000000}, -+ {0x4A3C, 0x00000002}, -+ {0x46D4, 0x00000001}, -+ {0x46D8, 0x00000001}, -+ {0x46DC, 0x00000000}, -+ {0x46E0, 0x00000000}, -+ {0x46E4, 0x00000151}, -+ {0x46E8, 0x00000498}, -+ {0x46EC, 0x00000498}, -+ {0x46F0, 0x00000000}, -+ {0x46F4, 0x00000000}, -+ {0x46F8, 0x00001146}, -+ {0x46FC, 0x00000000}, -+ {0x4700, 0x00000000}, -+ {0x4704, 0x00C8CC00}, -+ {0x4708, 0xC400B6B6}, -+ {0x470C, 0xDC400FC0}, -+ {0x4A90, 0x00000110}, -+ {0x4B10, 0x00000000}, -+ {0x4BE0, 0x00000001}, -+ {0x4710, 0x08882550}, -+ {0x4714, 0x08CC2660}, -+ {0x4718, 0x09102660}, -+ {0x471C, 0x00000154}, -+ {0x4740, 0xC69F38E8}, -+ {0x4744, 0x462709E9}, -+ {0x4748, 0x6750DC67}, -+ {0x474C, 0xF3F0F1ED}, -+ {0x4750, 0x30141506}, -+ {0x4754, 0x2C2B2B2B}, -+ {0x4758, 0x2C2C2C2C}, -+ {0x475C, 0xE0B738E8}, -+ {0x4760, 0x52381BFE}, -+ {0x4764, 0x5031DC6C}, -+ {0x4768, 0xFBEBDA00}, -+ {0x476C, 0x1A10FF04}, -+ {0x4770, 0x282A3000}, -+ {0x4774, 0x2A29292A}, -+ {0x4778, 0x04FA2A2A}, -+ {0x477C, 0xEE0F04D1}, -+ {0x47C4, 0x00000000}, -+ {0x47C8, 0xA32103FE}, -+ {0x47CC, 0xB20A5328}, -+ {0x47D0, 0xC686314F}, -+ {0x47D4, 0x000004D7}, -+ {0x4BFC, 0x00000000}, -+ {0x4C00, 0x0C442416}, -+ {0x4C04, 0x00000000}, -+ {0x47D8, 0x009B902A}, -+ {0x47DC, 0x009B902A}, -+ {0x47E0, 0x98682C18}, -+ {0x47E4, 0x6318C4C1}, -+ {0x47E8, 0x6248C631}, -+ {0x47EC, 0x922A8253}, -+ {0x47F0, 0x00000005}, -+ {0x47F4, 0x00001759}, -+ {0x47F8, 0x4BB01800}, -+ {0x47FC, 0x831408BE}, -+ {0x4A84, 0x000000E9}, -+ {0x4C08, 0x0F801404}, -+ {0x4C0C, 0x00A2B404}, -+ {0x4800, 0x9ABBCACB}, -+ {0x4804, 0x56867578}, -+ {0x4808, 0xBCCBBB13}, -+ {0x480C, 0x7889989B}, -+ {0x4810, 0xBBB0F455}, -+ {0x4814, 0x777BBBBB}, -+ {0x4818, 0x15277777}, -+ {0x481C, 0x27039CE9}, -+ {0x4820, 0x42424432}, -+ {0x4824, 0x36058342}, -+ {0x4828, 0x00000006}, -+ {0x482C, 0x00000005}, -+ {0x4830, 0x00000005}, -+ {0x4834, 0xC7013016}, -+ {0x4838, 0x84413016}, -+ {0x483C, 0x84413016}, -+ {0x4840, 0x8C413016}, -+ {0x4844, 0x8C40B028}, -+ {0x4848, 0x3140B028}, -+ {0x484C, 0x2940B028}, -+ {0x4850, 0x8440B028}, -+ {0x4854, 0x2318C610}, -+ {0x4858, 0x45344753}, -+ {0x485C, 0x236A6A88}, -+ {0x4860, 0xAC8DF814}, -+ {0x4864, 0x08877ACB}, -+ {0x4868, 0x000107AA}, -+ {0x4A94, 0x00000000}, -+ {0x486C, 0xBCEB4A14}, -+ {0x4870, 0x000A3A4A}, -+ {0x4874, 0xBCEB4A14}, -+ {0x4878, 0x000A3A4A}, -+ {0x487C, 0xBCBDBD85}, -+ {0x4880, 0x0CABB99A}, -+ {0x4884, 0x38384242}, -+ {0x4888, 0x0086102E}, -+ {0x488C, 0xCA24C82A}, -+ {0x4AFC, 0x00000000}, -+ {0x4C14, 0x0000349D}, -+ {0x4CF8, 0x00000007}, -+ {0x4890, 0x00008A62}, -+ {0x4894, 0x00000008}, -+ {0x4958, 0x80040000}, -+ {0x495C, 0x80040000}, -+ {0x4960, 0xFE800000}, -+ {0x4964, 0x834C0000}, -+ {0x4968, 0x00000000}, -+ {0x496C, 0x00000000}, -+ {0x4970, 0x00000000}, -+ {0x4974, 0x00000000}, -+ {0x4978, 0x00000000}, -+ {0x497C, 0x00000000}, -+ {0x4980, 0x40000000}, -+ {0x4984, 0x00000000}, -+ {0x4988, 0x00000000}, -+ {0x498C, 0x00000000}, -+ {0x4990, 0x00000000}, -+ {0x4994, 0x04065800}, -+ {0x4998, 0x02004080}, -+ {0x499C, 0x0E1E3E05}, -+ {0x49A0, 0x0A163068}, -+ {0x49A4, 0x00206040}, -+ {0x49A8, 0x02020202}, -+ {0x49AC, 0x00002020}, -+ {0x49B0, 0xF8F8F418}, -+ {0x49B4, 0xF8E8F8F8}, -+ {0x49B8, 0xF80808E8}, -+ {0x4A00, 0xF8F8FA00}, -+ {0x4A04, 0xFAFAFAF8}, -+ {0x4A08, 0xFAFAFAFA}, -+ {0x49BC, 0x00000000}, -+ {0x49C0, 0x800C562D}, -+ {0x49C4, 0x00000101}, -+ {0x49C8, 0x00000000}, -+ {0x49CC, 0x00000000}, -+ {0x49D0, 0x00000000}, -+ {0x49D4, 0x00000000}, -+ {0x49D8, 0x00000000}, -+ {0x49DC, 0x00000000}, -+ {0x49E0, 0x00000000}, -+ {0x49E4, 0x00000000}, -+ {0x49E8, 0x00000000}, -+ {0x49EC, 0x00000000}, -+ {0x4C28, 0x00000000}, -+ {0x4C2C, 0x00000000}, -+ {0x4C30, 0x00000000}, -+ {0x4C34, 0x00000000}, -+ {0x4C38, 0x00000000}, -+ {0x4C3C, 0x00000000}, -+ {0x4C40, 0x00000000}, -+ {0x4C44, 0x01C0C832}, -+ {0x4C48, 0x03207032}, -+ {0x4C4C, 0x0320701C}, -+ {0x4C50, 0x03207032}, -+ {0x4C54, 0x01C0C81C}, -+ {0x4C58, 0x00A0281C}, -+ {0x4C5C, 0x0320C80A}, -+ {0x4C60, 0x00A0C832}, -+ {0x4C64, 0x01C0C832}, -+ {0x4C68, 0x03207032}, -+ {0x4C6C, 0x0320701C}, -+ {0x4C70, 0x03207032}, -+ {0x4C74, 0x01C0C81C}, -+ {0x4C78, 0x00A0281C}, -+ {0x4C7C, 0x0321A80A}, -+ {0x4C80, 0x0320C86A}, -+ {0x4C84, 0x12B02832}, -+ {0x4C88, 0x12B3292B}, -+ {0x4C8C, 0x0CA4ACCA}, -+ {0x4C90, 0x12B4AC6A}, -+ {0x4C94, 0x0CA4ACCA}, -+ {0x4C98, 0x06A3292B}, -+ {0x4C9C, 0x06A0280A}, -+ {0x4CA0, 0x0CA0286A}, -+ {0x4CA4, 0x0CA1A8CA}, -+ {0x4CA8, 0x06A3286A}, -+ {0x4CAC, 0x0000000A}, -+ {0x4CB0, 0x01209C27}, -+ {0x4CB4, 0x02704800}, -+ {0x4CB8, 0x02704812}, -+ {0x4CBC, 0x00004827}, -+ {0x4CC0, 0x01209C12}, -+ {0x4CC4, 0x00000012}, -+ {0x4CC8, 0x02718000}, -+ {0x4CCC, 0x02709C60}, -+ {0x4CD0, 0x00000027}, -+ {0x4CD4, 0x00000000}, -+ {0x4CD8, 0x0000014A}, -+ {0x994, 0x00000010}, -+ {0x904, 0x00000005}, -+ {0x708, 0x00000000}, -+ {0x884, 0x0043F01D}, -+ {0x710, 0xEF810000}, -+ {0x718, 0x1333233F}, -+ {0x604, 0x041E1E1E}, -+ {0x714, 0x00010000}, -+ {0x586C, 0x000000F0}, -+ {0x586C, 0x000000E0}, -+ {0x586C, 0x000000D0}, -+ {0x586C, 0x000000C0}, -+ {0x586C, 0x000000B0}, -+ {0x586C, 0x000000A0}, -+ {0x586C, 0x00000090}, -+ {0x586C, 0x00000080}, -+ {0x586C, 0x00000070}, -+ {0x586C, 0x00000060}, -+ {0x586C, 0x00000050}, -+ {0x586C, 0x00000040}, -+ {0x586C, 0x00000030}, -+ {0x586C, 0x00000020}, -+ {0x586C, 0x00000010}, -+ {0x586C, 0x00000000}, -+ {0xC0D4, 0xABA41460}, -+ {0xC0D8, 0xC43A7E87}, -+ {0xC0DC, 0x30C194B8}, -+ {0xC0E0, 0x75008138}, -+ {0xC0E4, 0x0000272B}, -+ {0xC0E8, 0x000A0C81}, -+ {0xC0EC, 0x00030003}, -+ {0xC0F0, 0x00000024}, -+ {0xC0C4, 0x005E3A00}, -+ {0xC004, 0x45800000}, -+ {0xC024, 0x45800000}, -+ {0x334, 0xFFFFFFFF}, -+ {0x33C, 0x55000000}, -+ {0x340, 0x00005555}, -+ {0x724, 0x00111200}, -+ {0x5868, 0xA9550000}, -+ {0x5870, 0x33221100}, -+ {0x5874, 0x77665544}, -+ {0x5878, 0xBBAA9988}, -+ {0x587C, 0xFFEEDDCC}, -+ {0x5880, 0x76543210}, -+ {0x5884, 0xFEDCBA98}, -+ {0x5888, 0x00000000}, -+ {0x588C, 0x00000000}, -+ {0x5894, 0x00000008}, -+ {0x650, 0x00200888}, -+ {0x710, 0xF3810000}, -+ {0x020, 0x0000F381}, -+ {0x024, 0x0000F381}, -+ {0x000, 0xC580801E}, -+ {0x980, 0x10002250}, -+ {0x988, 0x3C3C4107}, -+ {0x994, 0x00000010}, -+ {0x000, 0x0580801F}, -+ {0x240C, 0x00000000}, -+ {0x640, 0x210A141E}, -+ {0x640, 0x2114141E}, -+ {0x640, 0x2114141E}, -+ {0x644, 0x3414283C}, -+ {0x644, 0x3425283C}, -+ {0x644, 0x3426283C}, -+ {0x2640, 0x140A141E}, -+ {0x2640, 0x1414141E}, -+ {0x2640, 0x1414141E}, -+ {0x2644, 0x3414283C}, -+ {0x2644, 0x3425283C}, -+ {0x2644, 0x3425183C}, -+ {0x2300, 0x02748790}, -+ {0x2304, 0x00558670}, -+ {0x2308, 0x002883F0}, -+ {0x230C, 0x00090120}, -+ {0x2310, 0x00000000}, -+ {0x2314, 0x06000000}, -+ {0x2318, 0x00000000}, -+ {0x231C, 0x00000000}, -+ {0x2320, 0x03020100}, -+ {0x2324, 0x07060504}, -+ {0x2328, 0x0B0A0908}, -+ {0x232C, 0x0F0E0D0C}, -+ {0x2330, 0x13121110}, -+ {0x2334, 0x17161514}, -+ {0x2338, 0x0C700022}, -+ {0x233C, 0x0A0529D0}, -+ {0x2340, 0x000529D0}, -+ {0x2344, 0x0006318A}, -+ {0x2348, 0xB7E6318A}, -+ {0x234C, 0x80039C00}, -+ {0x2350, 0x80039C00}, -+ {0x2354, 0x0005298F}, -+ {0x2358, 0x0015296E}, -+ {0x235C, 0x0C07FC31}, -+ {0x2360, 0x0219AAAE}, -+ {0x2364, 0xE4F624C3}, -+ {0x2368, 0x53626F15}, -+ {0x236C, 0x48000000}, -+ {0x2370, 0x48000000}, -+ {0x2374, 0x07540000}, -+ {0x2378, 0x202401B9}, -+ {0x237C, 0x00F7000E}, -+ {0x2380, 0x0F0A1111}, -+ {0x2384, 0x30D9000F}, -+ {0x2388, 0x0200EA02}, -+ {0x238C, 0x003CB061}, -+ {0x2390, 0x69C00000}, -+ {0x2394, 0x00000000}, -+ {0x2398, 0x000000F0}, -+ {0x239C, 0x0001FFFF}, -+ {0x23A0, 0x00C80064}, -+ {0x23A4, 0x0190012C}, -+ {0x23A8, 0x001917BE}, -+ {0x23AC, 0x0B30880C}, -+ {0x23B0, 0x9281CE00}, -+ {0x23B4, 0x7F027C00}, -+ {0x704, 0x601E0502}, -+ {0x5600, 0x00000000}, -+ {0x5604, 0x802D2721}, -+ {0x5610, 0x00201020}, -+ {0x5618, 0x00801008}, -+ {0x5624, 0x0808081E}, -+ {0x562C, 0x0000081D}, -+ {0x5634, 0x3D2EE000}, -+ {0x5638, 0x0001AC42}, -+ {0x5640, 0x3D6EF000}, -+ {0x5644, 0x0001AC3E}, -+ {0x566C, 0x00210005}, -+ {0x5680, 0x20500010}, -+ {0x5684, 0x00020001}, -+ {0x56A0, 0x0034C000}, -+ {0x56BC, 0x04000000}, -+ {0x56C0, 0x00000688}, -+ {0x56C4, 0x00000010}, -+ {0x56C8, 0x0E800400}, -+ {0x56CC, 0x01E400FF}, -+ {0x5800, 0x003F807F}, -+ {0x5810, 0x59008400}, -+ {0x5814, 0x201AF000}, -+ {0x5818, 0x182C18E8}, -+ {0x581C, 0x3DD80280}, -+ {0x5820, 0x80000080}, -+ {0x5828, 0x023F8121}, -+ {0x5830, 0x023F8121}, -+ {0x5838, 0x003F8121}, -+ {0x5840, 0x023F8121}, -+ {0x5848, 0x023F8121}, -+ {0x5850, 0x023F8121}, -+ {0x5858, 0x003F7121}, -+ {0x5860, 0x023F7121}, -+ {0x5864, 0x1A1801FF}, -+ {0x5868, 0xA9A90002}, -+ {0x5880, 0x77777777}, -+ {0x5884, 0x77777777}, -+ {0x5894, 0x01080604}, -+ {0x5898, 0x00000000}, -+ {0x589C, 0x00000000}, -+ {0x58A0, 0x000000FE}, -+ {0x58B0, 0x00000800}, -+ {0x58BC, 0x07A7807F}, -+ {0x58C0, 0x007E0000}, -+ {0x58C4, 0x0003FFFF}, -+ {0x58D4, 0x7401FE00}, -+ {0x58D8, 0x8008016C}, -+ {0x58DC, 0xC000807F}, -+ {0x58E4, 0x3000881F}, -+ {0x58E8, 0x00000003}, -+ {0x58F0, 0x400401FF}, -+ {0x58F4, 0x80000000}, -+ {0x58F8, 0xC0000000}, -+ {0x58FC, 0x00000000}, -+ {0x700, 0x40000030}, -+ {0x704, 0x601E0502}, -+ {0x704, 0x601E0500}, -+ {0x704, 0x601E0502}, -+ {0x20FC, 0x00000000}, -+ {0x20F8, 0x00000000}, -+ {0x20F0, 0x00000000}, -+ {0x9C0, 0x00000001}, -+ {0x9C0, 0x00000000}, -+ {0x9C0, 0x00000001}, -+ {0x9C0, 0x00000000}, -+ {0x4AE8, 0x00000744}, -+ {0x4AD4, 0x00000040}, -+ {0x4AE4, 0x0079E99E}, -+ {0x4BC8, 0xFBD5B89F}, -+ {0x4BCC, 0x99563918}, -+ {0x4BD0, 0x12EED5B8}, -+ {0x4BD4, 0x6F7D542F}, -+ {0x4BD8, 0x0000001D}, -+ {0x300, 0xF30CE31C}, -+ {0x304, 0x13EF1F19}, -+ {0x308, 0x0C0CF3F3}, -+ {0x30C, 0x0CE30C0C}, -+ {0x310, 0x80496000}, -+ {0x314, 0x0041E000}, -+ {0x318, 0x20022042}, -+ {0x31C, 0x20448009}, -+ {0x320, 0x00010031}, -+ {0x324, 0xE000E000}, -+ {0x328, 0xE000E000}, -+ {0x32C, 0xE0008049}, -+ {0x12BC, 0x10104041}, -+ {0x12C0, 0x13311111}, -+ {0x12E4, 0x30D52A68}, -+ {0x010, 0x0005FFFF}, -+ {0x028, 0x0000F381}, -+ {0x02C, 0x0000F381}, -+ {0x620, 0x00141230}, -+ {0x70C, 0x00000020}, -+ {0x720, 0x20000000}, -+ {0x730, 0x00000002}, -+ {0x738, 0x004100C0}, -+ {0x73C, 0x00000002}, -+ {0x748, 0x01000002}, -+ {0x74C, 0x00000001}, -+ {0xA08, 0x00007800}, -+ {0xC14, 0x25010000}, -+ {0xC3C, 0x2840E1BF}, -+ {0xC40, 0x00000000}, -+ {0xC44, 0x00000007}, -+ {0xC48, 0x410E4000}, -+ {0xC54, 0x1EE14368}, -+ {0xC58, 0x41000000}, -+ {0xC5C, 0x80558000}, -+ {0xC60, 0x017FFFF2}, -+ {0xC64, 0x0010A130}, -+ {0xC68, 0x90000050}, -+ {0xC6C, 0x10201021}, -+ {0xC70, 0x071B0660}, -+ {0xC74, 0x00000000}, -+ {0xC78, 0x80000000}, -+ {0xC7C, 0x0020BFE0}, -+ {0xC88, 0xC2AC8000}, -+ {0xC8C, 0x02F2FC08}, -+ {0xD00, 0x77777777}, -+ {0xD04, 0xBBBBBBBB}, -+ {0xD08, 0xBBBBBBBB}, -+ {0xD0C, 0x000B2070}, -+ {0xD10, 0x20110FFF}, -+ {0xD18, 0x50009800}, -+ {0xD20, 0x01900000}, -+ {0xD30, 0x03FF8000}, -+ {0xD40, 0xF64FA0F7}, -+ {0xD44, 0x0401463F}, -+ {0xD48, 0x0003FF7F}, -+ {0xD4C, 0x00000000}, -+ {0xD50, 0xF64FA0F7}, -+ {0xD54, 0x04100437}, -+ {0xD58, 0x0000FF7F}, -+ {0xD5C, 0x00000000}, -+ {0xD60, 0x00000000}, -+ {0xD64, 0x00000000}, -+ {0xD70, 0x00000015}, -+ {0xD78, 0x00000001}, -+ {0xD7C, 0x001D050E}, -+ {0xD80, 0x00000100}, -+ {0xD84, 0x00006607}, -+ {0xD90, 0x000003FF}, -+ {0xD94, 0x00000000}, -+ {0xD98, 0x0000003F}, -+ {0xD9C, 0x00000000}, -+ {0xDA0, 0x000003FE}, -+ {0xDA4, 0x00000000}, -+ {0xDA8, 0x0000003F}, -+ {0xDAC, 0x00000000}, -+ {0xDD4, 0x00000000}, -+ {0x1010, 0x00000000}, -+ {0x2000, 0x50BBBF04}, -+ {0x2008, 0x000FFFFF}, -+ {0x5800, 0x03FF807F}, -+ {0x5804, 0x04237040}, -+ {0x5808, 0x04237040}, -+ {0x5818, 0x082C1800}, -+ {0x624, 0x0101030A}, -+ {0x241C, 0x00000001}, -+ {0xC0F8, 0x00000001}, -+ {0x35C, 0x000004C4}, -+ {0x1200, 0x00010142}, -+ {0x120C, 0x00012233}, -+ {0x1210, 0x8049E304}, -+ {0x12A0, 0x49107056}, -+ {0x12A8, 0x33337025}, -+ {0x12AC, 0x12333121}, -+ {0x12B8, 0x30020000}, -+ {0x0F0, 0x00000001}, -+ {0x0F4, 0x00000011}, -+ {0x0F8, 0x20230307}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8851b_phy_bb_reg_gain[] = { -+ {0xF00100FF, 0x00000000}, -+ {0xF00200FF, 0x00000001}, -+ {0xF00300FF, 0x00000002}, -+ {0xF00400FF, 0x00000003}, -+ {0xF00500FF, 0x00000004}, -+ {0xF00600FF, 0x00000005}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x13F6D7B6}, -+ {0x001, 0x00725132}, -+ {0x002, 0x00005A38}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x13F6D7B6}, -+ {0x001, 0x00725132}, -+ {0x002, 0x00005A38}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x13F6D7B6}, -+ {0x001, 0x00725132}, -+ {0x002, 0x00005A38}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x19FADCBC}, -+ {0x001, 0x007A5A3A}, -+ {0x002, 0x00005838}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x19FADCBC}, -+ {0x001, 0x007A5A3A}, -+ {0x002, 0x00005838}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x000, 0x19FADCBC}, -+ {0x001, 0x007A5A3A}, -+ {0x002, 0x00005838}, -+ {0xA0000000, 0x00000000}, -+ {0x000, 0x13F6D7B6}, -+ {0x001, 0x00725132}, -+ {0x002, 0x00005A38}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0xA0000000, 0x00000000}, -+ {0x100, 0x1BFEE0B7}, -+ {0x101, 0x006C5238}, -+ {0x102, 0x00005031}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x19F8D8C1}, -+ {0x10001, 0x006F4F31}, -+ {0x10002, 0x00006F58}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x19F8D8C1}, -+ {0x10001, 0x006F4F31}, -+ {0x10002, 0x00006F58}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x19F8D8C1}, -+ {0x10001, 0x006F4F31}, -+ {0x10002, 0x00006F58}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x1DF8DAC1}, -+ {0x10001, 0x00755437}, -+ {0x10002, 0x00007058}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x1DF8DAC1}, -+ {0x10001, 0x00755437}, -+ {0x10002, 0x00007058}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10000, 0x1DF8DAC1}, -+ {0x10001, 0x00755437}, -+ {0x10002, 0x00007058}, -+ {0xA0000000, 0x00000000}, -+ {0x10000, 0x19F8D8C1}, -+ {0x10001, 0x006F4F31}, -+ {0x10002, 0x00006F58}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0xA0000000, 0x00000000}, -+ {0x10100, 0x09E9C69F}, -+ {0x10101, 0x00674627}, -+ {0x10102, 0x00006750}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1AF0D2B8}, -+ {0x20001, 0x00755334}, -+ {0x20002, 0x00006F58}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1AF0D2B8}, -+ {0x20001, 0x00755334}, -+ {0x20002, 0x00006F58}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1AF0D2B8}, -+ {0x20001, 0x00755334}, -+ {0x20002, 0x00006F58}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1D00E2C8}, -+ {0x20001, 0x00775336}, -+ {0x20002, 0x00006D58}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1D00E2C8}, -+ {0x20001, 0x00775336}, -+ {0x20002, 0x00006D58}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20000, 0x1D00E2C8}, -+ {0x20001, 0x00775336}, -+ {0x20002, 0x00006D58}, -+ {0xA0000000, 0x00000000}, -+ {0x20000, 0x1AF0D2B8}, -+ {0x20001, 0x00755334}, -+ {0x20002, 0x00006F58}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0xA0000000, 0x00000000}, -+ {0x20100, 0x07E9C6A0}, -+ {0x20101, 0x00674728}, -+ {0x20102, 0x00006850}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x15EED2B6}, -+ {0x30001, 0x006F4D2F}, -+ {0x30002, 0x00006F58}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x15EED2B6}, -+ {0x30001, 0x006F4D2F}, -+ {0x30002, 0x00006F58}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x15EED2B6}, -+ {0x30001, 0x006F4D2F}, -+ {0x30002, 0x00006F58}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x1F00E2C6}, -+ {0x30001, 0x00795739}, -+ {0x30002, 0x00006F58}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x1F00E2C6}, -+ {0x30001, 0x00795739}, -+ {0x30002, 0x00006F58}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30000, 0x1F00E2C6}, -+ {0x30001, 0x00795739}, -+ {0x30002, 0x00006F58}, -+ {0xA0000000, 0x00000000}, -+ {0x30000, 0x15EED2B6}, -+ {0x30001, 0x006F4D2F}, -+ {0x30002, 0x00006F58}, -+ {0xB0000000, 0x00000000}, -+ {0x800100ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x900200ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x900300ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x900400ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x900500ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0x900600ff, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0xA0000000, 0x00000000}, -+ {0x30100, 0x06E9C69F}, -+ {0x30101, 0x00654527}, -+ {0x30102, 0x00006750}, -+ {0xB0000000, 0x00000000}, -+ {0x1000000, 0x000000F4}, -+ {0x1000010, 0x000000F8}, -+ {0x1000011, 0x0000F8F8}, -+ {0x1000100, 0x000000F8}, -+ {0x1000110, 0x00000000}, -+ {0x1000111, 0x00000000}, -+ {0x1010000, 0x000000F4}, -+ {0x1010010, 0x000000F8}, -+ {0x1010011, 0x0000F8F8}, -+ {0x1010020, 0x000000F8}, -+ {0x1010021, 0x0808E8E8}, -+ {0x1010029, 0x0000F8F8}, -+ {0x1010100, 0x000000F4}, -+ {0x1010110, 0x000000F8}, -+ {0x1010111, 0x0000F8F8}, -+ {0x1010120, 0x000000F8}, -+ {0x1010121, 0x0808E8E8}, -+ {0x1010129, 0x0000F8F8}, -+ {0x1020000, 0x000000F4}, -+ {0x1020010, 0x000000F8}, -+ {0x1020011, 0x0000F8F8}, -+ {0x1020020, 0x000000F8}, -+ {0x1020021, 0x0808E8E8}, -+ {0x1020029, 0x0000F8F8}, -+ {0x1020100, 0x000000F4}, -+ {0x1020110, 0x000000F8}, -+ {0x1020111, 0x0000F8F8}, -+ {0x1020120, 0x000000F8}, -+ {0x1020121, 0x0808E8E8}, -+ {0x1020129, 0x0000F8F8}, -+ {0x1030000, 0x000000F4}, -+ {0x1030010, 0x000000F8}, -+ {0x1030011, 0x0000F8F8}, -+ {0x1030020, 0x000000F8}, -+ {0x1030021, 0x0808E8E8}, -+ {0x1030029, 0x0000F8F8}, -+ {0x1030100, 0x000000F4}, -+ {0x1030110, 0x000000F8}, -+ {0x1030111, 0x0000F8F8}, -+ {0x1030120, 0x000000F8}, -+ {0x1030121, 0x0808E8E8}, -+ {0x1030129, 0x0000F8F8}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8851b_phy_radioa_regs[] = { -+ {0xF0010000, 0x00000000}, -+ {0xF0020000, 0x00000001}, -+ {0xF0030000, 0x00000002}, -+ {0x000, 0x00030000}, -+ {0x018, 0x00013124}, -+ {0x0EF, 0x00080000}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x00000110}, -+ {0x03F, 0x0000D39C}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x00000110}, -+ {0x03F, 0x0000F79E}, -+ {0x0EF, 0x00000000}, -+ {0x01B, 0x00003A40}, -+ {0x08F, 0x000C170E}, -+ {0x08E, 0x00005160}, -+ {0x002, 0x00000600}, -+ {0x0EE, 0x00000002}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x0000003F}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x0000003F}, -+ {0x0EE, 0x00000000}, -+ {0x0EF, 0x00004000}, -+ {0x033, 0x00000007}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000707}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000704}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00020500}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00010404}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00099B04}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00092B04}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x000B3204}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000017}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000787}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00000784}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00020580}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00010484}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00099B84}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00092B84}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x000B3284}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x00000000}, -+ {0x03F, 0x00003080}, -+ {0x0EF, 0x00000000}, -+ {0x0EE, 0x00000010}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000003}, -+ {0x0EE, 0x00000000}, -+ {0x0EF, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000034}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000037}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000034}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000024}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000037}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000027}, -+ {0x0EF, 0x00000000}, -+ {0x0EC, 0x00000400}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000022}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000022}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00000022}, -+ {0x0EC, 0x00000000}, -+ {0x0EC, 0x00000004}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x000000AE}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0000008C}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000006A}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000048}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000026}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000004}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000002}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000000}, -+ {0x0EC, 0x00000000}, -+ {0x0EF, 0x00008000}, -+ {0x033, 0x00000007}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001BB0}, -+ {0x033, 0x00000002}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001AB0}, -+ {0x033, 0x00000001}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D9BC}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D4BC}, -+ {0x033, 0x00000017}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001BB0}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001AB0}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D9BC}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D4BC}, -+ {0x033, 0x00000027}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001BB0}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001AB0}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D9BC}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D4BC}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00091BB0}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x000A9AB0}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x000BD9BC}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0009D4BC}, -+ {0x033, 0x0000001E}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x0000001D}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x0000001C}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x0000001B}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00091BB0}, -+ {0x033, 0x0000001A}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00099AB0}, -+ {0x033, 0x00000019}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x000AD9BC}, -+ {0x033, 0x00000018}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0009D4BC}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001FB0}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001DB0}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001CB0}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00001BB0}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x00009AB0}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0009D9BC}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x00000003}, -+ {0x03F, 0x0000D4BC}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00002000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000004}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000004}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000000C}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000003}, -+ {0x0EF, 0x00000000}, -+ {0x06C, 0x00038085}, -+ {0x06D, 0x00000D6B}, -+ {0x06E, 0x0001FB89}, -+ {0x06F, 0x00097B99}, -+ {0x069, 0x00008040}, -+ {0x0EF, 0x00000200}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000008FF}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000004F2}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000217}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000131}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000400}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000004F7}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000004F7}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000004F2}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000117}, -+ {0x0EF, 0x00000000}, -+ {0x043, 0x00005000}, -+ {0x036, 0x000147D0}, -+ {0x0B0, 0x0008677C}, -+ {0x0B1, 0x00012920}, -+ {0x0BB, 0x000EF000}, -+ {0x0CB, 0x000A9594}, -+ {0x0CC, 0x000C36D2}, -+ {0x0CD, 0x00024923}, -+ {0x0CE, 0x00020180}, -+ {0x0CF, 0x00000000}, -+ {0x0D5, 0x0006E27A}, -+ {0x0D8, 0x00000044}, -+ {0x0D9, 0x00000007}, -+ {0x0DD, 0x00000020}, -+ {0x0E3, 0x0000002C}, -+ {0x0B7, 0x0000000C}, -+ {0x0E1, 0x000080C0}, -+ {0x0E4, 0x00000380}, -+ {0x0ED, 0x00002000}, -+ {0x033, 0x00000001}, -+ {0x03D, 0x000A6094}, -+ {0x03E, 0x00003449}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000003}, -+ {0x03D, 0x000AA094}, -+ {0x03E, 0x00003449}, -+ {0x03F, 0x00000001}, -+ {0x0ED, 0x00000000}, -+ {0x0ED, 0x00000100}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x0000007F}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x0000007F}, -+ {0x0ED, 0x00000000}, -+ {0x0ED, 0x00000080}, -+ {0x033, 0x00000000}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x033, 0x00000040}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x033, 0x00000050}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x033, 0x00000070}, -+ {0x03E, 0x000007E1}, -+ {0x03F, 0x0001F87F}, -+ {0x0ED, 0x00000000}, -+ {0x0ED, 0x00000004}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00008420}, -+ {0x0ED, 0x00000000}, -+ {0x018, 0x00011108}, -+ {0x0B9, 0x00000000}, -+ {0x0B9, 0x00000000}, -+ {0x0B9, 0x00000200}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0FF, 0x00000000}, -+ {0x0B9, 0x00000000}, -+ {0x018, 0x00013124}, -+ {0x05A, 0x0006808F}, -+ {0x0ED, 0x00000008}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0000000F}, -+ {0x0ED, 0x00000000}, -+ {0x000, 0x00020000}, -+ {0x018, 0x00010124}, -+ {0x0EE, 0x00000800}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000002}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000006}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00001000}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x00000000}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x00000103}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x00000107}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00000207}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x00000307}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x00000307}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00000200}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000000}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000002}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x00000003}, -+ {0x0EE, 0x00000000}, -+ {0x011, 0x00014062}, -+ {0x0EF, 0x00000010}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000DF3}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000DF3}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000A83}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000A83}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x00000643}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x00000643}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000100}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x0001B5A9}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0001B589}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x0001B5A9}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x0001B5A9}, -+ {0x033, 0x0000000E}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000010}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000011}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000012}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000013}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000014}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000015}, -+ {0x03F, 0x0001B589}, -+ {0x033, 0x00000016}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000017}, -+ {0x03F, 0x0001B5A9}, -+ {0x033, 0x00000018}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000019}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001A}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001B}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001C}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001D}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001E}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x0000001F}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000020}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000021}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000022}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000023}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000024}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000025}, -+ {0x03F, 0x0001B5A8}, -+ {0x033, 0x00000022}, -+ {0x03F, 0x0001B5A8}, -+ {0x0EF, 0x00000000}, -+ {0x0EF, 0x00000040}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000008}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x00000009}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x0000000A}, -+ {0x03F, 0x000002C5}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x000002C5}, -+ {0x0EF, 0x00000000}, -+ {0x059, 0x00050033}, -+ {0x061, 0x0005F48A}, -+ {0x062, 0x00077435}, -+ {0x063, 0x000F80A2}, -+ {0x065, 0x00018F22}, -+ {0x067, 0x00008060}, -+ {0x07E, 0x0009780B}, -+ {0x0EE, 0x00000004}, -+ {0x033, 0x0000000B}, -+ {0x03F, 0x0000000B}, -+ {0x033, 0x0000000C}, -+ {0x03F, 0x00000012}, -+ {0x033, 0x0000000D}, -+ {0x03F, 0x00000019}, -+ {0x033, 0x0000000F}, -+ {0x03F, 0x0000000B}, -+ {0x033, 0x00000010}, -+ {0x03F, 0x00000012}, -+ {0x033, 0x00000011}, -+ {0x03F, 0x00000019}, -+ {0x03F, 0x00000000}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00000800}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000002}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00001000}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00003000}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000000}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000001}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000003}, -+ {0x033, 0x00000004}, -+ {0x03F, 0x00000007}, -+ {0x033, 0x00000005}, -+ {0x03F, 0x0000000F}, -+ {0x033, 0x00000006}, -+ {0x03F, 0x0000010F}, -+ {0x033, 0x00000007}, -+ {0x03F, 0x0000030F}, -+ {0x0EE, 0x00000000}, -+ {0x0EE, 0x00000200}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000004}, -+ {0x033, 0x00000001}, -+ {0x03F, 0x00000005}, -+ {0x033, 0x00000002}, -+ {0x03F, 0x00000006}, -+ {0x033, 0x00000003}, -+ {0x03F, 0x00000007}, -+ {0x0EE, 0x00000000}, -+ {0x0EF, 0x00000080}, -+ {0x033, 0x00000004}, -+ {0x03E, 0x0000001D}, -+ {0x03F, 0x0001A241}, -+ {0x033, 0x00000005}, -+ {0x03E, 0x0000001D}, -+ {0x03F, 0x0001A241}, -+ {0x033, 0x00000006}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000007}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000008}, -+ {0x03E, 0x0000001D}, -+ {0x03F, 0x0001A241}, -+ {0x033, 0x00000009}, -+ {0x03E, 0x0001A241}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000000A}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000000B}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000000C}, -+ {0x03E, 0x0000001D}, -+ {0x03F, 0x0001A241}, -+ {0x033, 0x0000000D}, -+ {0x03E, 0x0000001D}, -+ {0x03F, 0x0001A241}, -+ {0x033, 0x0000000E}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000000F}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000010}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000011}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000012}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000013}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000014}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000015}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000016}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000017}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000018}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000019}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x0000001A}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000001B}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000001C}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x0000001D}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x0000001E}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000001F}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000020}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000021}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x000199C1}, -+ {0x033, 0x00000022}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000023}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000024}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000025}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000026}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000027}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000028}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000029}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x0000002A}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000002B}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000002C}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x0000002D}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x0000002E}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000002F}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000030}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000031}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000032}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000033}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000034}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000035}, -+ {0x03E, 0x0000001C}, -+ {0x03F, 0x0001E141}, -+ {0x033, 0x00000036}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000037}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000038}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x00000039}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C1}, -+ {0x033, 0x0000003A}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x033, 0x0000003B}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x033, 0x0000003C}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x033, 0x0000003D}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x033, 0x0000003E}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x033, 0x0000003F}, -+ {0x03E, 0x0000001B}, -+ {0x03F, 0x0001C3C3}, -+ {0x0EF, 0x00000000}, -+ {0x051, 0x0003D368}, -+ {0x052, 0x000A3338}, -+ {0x053, 0x000688AF}, -+ {0x054, 0x00012C04}, -+ {0x058, 0x00084221}, -+ {0x05B, 0x000EB000}, -+ {0x100EE, 0x00002000}, -+ {0x10030, 0x000000F9}, -+ {0x10030, 0x000004F6}, -+ {0x10030, 0x000008F3}, -+ {0x10030, 0x00000CF0}, -+ {0x10030, 0x000010ED}, -+ {0x10030, 0x000014EA}, -+ {0x10030, 0x000018E7}, -+ {0x10030, 0x00001CE4}, -+ {0x10030, 0x000020E1}, -+ {0x10030, 0x000024A4}, -+ {0x10030, 0x000028A1}, -+ {0x10030, 0x00002C9E}, -+ {0x10030, 0x0000309B}, -+ {0x10030, 0x0000341E}, -+ {0x10030, 0x0000381B}, -+ {0x10030, 0x00003C18}, -+ {0x10030, 0x00004015}, -+ {0x10030, 0x000200BC}, -+ {0x10030, 0x000204B9}, -+ {0x10030, 0x000208B6}, -+ {0x10030, 0x00020CB3}, -+ {0x10030, 0x000210B0}, -+ {0x10030, 0x000214AD}, -+ {0x10030, 0x0002186C}, -+ {0x10030, 0x00021C69}, -+ {0x10030, 0x00022066}, -+ {0x10030, 0x00022426}, -+ {0x10030, 0x00022823}, -+ {0x10030, 0x00022C20}, -+ {0x10030, 0x0002301D}, -+ {0x10030, 0x0002341A}, -+ {0x10030, 0x00023817}, -+ {0x10030, 0x00023C14}, -+ {0x10030, 0x00024011}, -+ {0x10030, 0x000280BC}, -+ {0x10030, 0x000284B9}, -+ {0x10030, 0x000288B6}, -+ {0x10030, 0x00028CB3}, -+ {0x10030, 0x000290B0}, -+ {0x10030, 0x000294AD}, -+ {0x10030, 0x0002986C}, -+ {0x10030, 0x00029C69}, -+ {0x10030, 0x0002A066}, -+ {0x10030, 0x0002A426}, -+ {0x10030, 0x0002A823}, -+ {0x10030, 0x0002AC20}, -+ {0x10030, 0x0002B01D}, -+ {0x10030, 0x0002B41A}, -+ {0x10030, 0x0002B817}, -+ {0x10030, 0x0002BC14}, -+ {0x10030, 0x0002C011}, -+ {0x10030, 0x000300BC}, -+ {0x10030, 0x000304B9}, -+ {0x10030, 0x000308B6}, -+ {0x10030, 0x00030CB3}, -+ {0x10030, 0x000310B0}, -+ {0x10030, 0x000314AD}, -+ {0x10030, 0x0003186C}, -+ {0x10030, 0x00031C69}, -+ {0x10030, 0x00032066}, -+ {0x10030, 0x00032426}, -+ {0x10030, 0x00032823}, -+ {0x10030, 0x00032C20}, -+ {0x10030, 0x0003301D}, -+ {0x10030, 0x0003341A}, -+ {0x10030, 0x00033817}, -+ {0x10030, 0x00033C14}, -+ {0x10030, 0x00034011}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10030, 0x000201EF}, -+ {0x10030, 0x000205E9}, -+ {0x10030, 0x000209E3}, -+ {0x10030, 0x00020DDD}, -+ {0x10030, 0x000211D7}, -+ {0x10030, 0x000215D1}, -+ {0x10030, 0x00021919}, -+ {0x10030, 0x00021D13}, -+ {0x10030, 0x000220D9}, -+ {0x10030, 0x000224D3}, -+ {0x10030, 0x00022899}, -+ {0x10030, 0x00022C93}, -+ {0x10030, 0x00023059}, -+ {0x10030, 0x00023453}, -+ {0x10030, 0x00023819}, -+ {0x10030, 0x00023C13}, -+ {0x10030, 0x0002400D}, -+ {0x10030, 0x00024407}, -+ {0x10030, 0x000281EF}, -+ {0x10030, 0x000285E9}, -+ {0x10030, 0x000289E3}, -+ {0x10030, 0x00028DDD}, -+ {0x10030, 0x000291D7}, -+ {0x10030, 0x000295D1}, -+ {0x10030, 0x00029919}, -+ {0x10030, 0x00029D13}, -+ {0x10030, 0x0002A0D9}, -+ {0x10030, 0x0002A4D3}, -+ {0x10030, 0x0002A899}, -+ {0x10030, 0x0002AC93}, -+ {0x10030, 0x0002B059}, -+ {0x10030, 0x0002B453}, -+ {0x10030, 0x0002B819}, -+ {0x10030, 0x0002BC13}, -+ {0x10030, 0x0002C00D}, -+ {0x10030, 0x0002C407}, -+ {0x10030, 0x000301EF}, -+ {0x10030, 0x000305E9}, -+ {0x10030, 0x000309E3}, -+ {0x10030, 0x00030DDD}, -+ {0x10030, 0x000311D7}, -+ {0x10030, 0x000315D1}, -+ {0x10030, 0x00031919}, -+ {0x10030, 0x00031D13}, -+ {0x10030, 0x000320D9}, -+ {0x10030, 0x000324D3}, -+ {0x10030, 0x00032899}, -+ {0x10030, 0x00032C93}, -+ {0x10030, 0x00033059}, -+ {0x10030, 0x00033453}, -+ {0x10030, 0x00033819}, -+ {0x10030, 0x00033C13}, -+ {0x10030, 0x0003400D}, -+ {0x10030, 0x00034407}, -+ {0x100EE, 0x00000000}, -+ {0x100EE, 0x00004000}, -+ {0x10030, 0x000001EF}, -+ {0x10030, 0x000005E9}, -+ {0x10030, 0x000009E3}, -+ {0x10030, 0x00000DDD}, -+ {0x10030, 0x000011A5}, -+ {0x10030, 0x0000159F}, -+ {0x10030, 0x00001965}, -+ {0x10030, 0x00001D5F}, -+ {0x10030, 0x00002125}, -+ {0x10030, 0x0000251F}, -+ {0x10030, 0x000028E5}, -+ {0x10030, 0x00002CDF}, -+ {0x10030, 0x000030A5}, -+ {0x10030, 0x0000349F}, -+ {0x10030, 0x00003865}, -+ {0x10030, 0x00003C5F}, -+ {0x10030, 0x00004025}, -+ {0x10030, 0x0000441F}, -+ {0x100EE, 0x00000000}, -+ {0x0EF, 0x00000008}, -+ {0x033, 0x00000000}, -+ {0x03F, 0x00000004}, -+ {0x0EF, 0x00000000}, -+ {0x005, 0x00000001}, -+ {0x10005, 0x00000001}, -+ {0x0FE, 0x00000022}, -+}; -+ -+static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = { -+ {0x8000, 0x00000008}, -+ {0x8008, 0x00000000}, -+ {0x8004, 0xe8862b66}, -+ {0x800c, 0x78000000}, -+ {0x8010, 0x88015000}, -+ {0x8014, 0x80010100}, -+ {0x8018, 0x10010100}, -+ {0x801c, 0xa210bc00}, -+ {0x8020, 0x000403e0}, -+ {0x8024, 0x00072160}, -+ {0x8028, 0x00180e00}, -+ {0x8030, 0x400000c0}, -+ {0x8034, 0x11000830}, -+ {0x8038, 0x40000000}, -+ {0x803c, 0x00000008}, -+ {0x8040, 0x00000046}, -+ {0x8044, 0x0010001f}, -+ {0x8048, 0x00000003}, -+ {0x804c, 0x420840e0}, -+ {0x8050, 0xce08cce0}, -+ {0x8054, 0x420840e0}, -+ {0x8058, 0xce08cce0}, -+ {0x805c, 0x150c0b02}, -+ {0x8060, 0x150c0b02}, -+ {0x8064, 0x2aa00047}, -+ {0x8074, 0x80000000}, -+ {0x807c, 0x000000ee}, -+ {0x8088, 0x80000000}, -+ {0x808c, 0x00000000}, -+ {0x80b0, 0x00000000}, -+ {0x80cc, 0x00000000}, -+ {0x80d0, 0x00000000}, -+ {0x80ec, 0x00000002}, -+ {0x8098, 0x0000ff00}, -+ {0x8070, 0x00e80000}, -+ {0x80b0, 0xffe00fff}, -+ {0x809c, 0x0000001f}, -+ {0x80b8, 0x00002000}, -+ {0x80bc, 0x00050033}, -+ {0xa400, 0x00000000}, -+ {0xa404, 0x00000180}, -+ {0xa408, 0x000001af}, -+ {0xa40c, 0x000001e3}, -+ {0xa410, 0x00000220}, -+ {0xa414, 0x00000262}, -+ {0xa418, 0x000002ac}, -+ {0xa41c, 0x0000035e}, -+ {0xa420, 0x000003c7}, -+ {0xa424, 0x0000043d}, -+ {0xa428, 0x000004c1}, -+ {0xa42c, 0x00000556}, -+ {0xa430, 0x000005fc}, -+ {0xa434, 0x000006b7}, -+ {0xa438, 0x00000789}, -+ {0xa43c, 0x00000875}, -+ {0xa440, 0x0000011f}, -+ {0x8104, 0x00000000}, -+ {0x810c, 0x00000000}, -+ {0x8110, 0x00000000}, -+ {0x8114, 0x00000000}, -+ {0x8120, 0x10010000}, -+ {0x8124, 0x00000000}, -+ {0x8128, 0x00000200}, -+ {0x812c, 0x0000c000}, -+ {0x8130, 0x40000000}, -+ {0x8138, 0x40000000}, -+ {0x813c, 0x40000000}, -+ {0x8140, 0x00000000}, -+ {0x8144, 0x0b040b03}, -+ {0x8148, 0x07020b04}, -+ {0x814c, 0x07020b04}, -+ {0x8150, 0xe4e40000}, -+ {0x8158, 0xffffffff}, -+ {0x815c, 0xffffffff}, -+ {0x8160, 0xffffffff}, -+ {0x8164, 0xffffffff}, -+ {0x8168, 0xffffffff}, -+ {0x816c, 0x1fffffff}, -+ {0x81cc, 0x00000000}, -+ {0x81dc, 0x00000002}, -+ {0x81e0, 0x00000000}, -+ {0x81e4, 0x00000001}, -+ {0x81a0, 0x00000000}, -+ {0x81ac, 0x3fc20400}, -+ {0x81b0, 0x3f914100}, -+ {0x81bc, 0x0000005b}, -+ {0x81c0, 0x0000005b}, -+ {0x81b4, 0x01e0f078}, -+ {0x81b8, 0x01e0f078}, -+ {0x81f0, 0x0000f078}, -+ {0x81d8, 0x00000001}, -+ {0x9500, 0x00000000}, -+ {0x9504, 0x00000000}, -+ {0x9508, 0x00000000}, -+ {0x950c, 0x00000000}, -+ {0x9510, 0x00000000}, -+ {0x9514, 0x00000000}, -+ {0x9518, 0x00000000}, -+ {0x951c, 0x00000000}, -+ {0x9520, 0x00000000}, -+ {0x9524, 0x00000000}, -+ {0x9528, 0x00000000}, -+ {0x952c, 0x00000000}, -+ {0x9530, 0x00000000}, -+ {0x9534, 0x00000000}, -+ {0x9538, 0x00000000}, -+ {0x953c, 0x00000000}, -+ {0x9540, 0x04000000}, -+ {0x9544, 0x00000000}, -+ {0x9548, 0x00000000}, -+ {0x954c, 0x00000000}, -+ {0x9550, 0x00000000}, -+ {0x9554, 0x00000000}, -+ {0x9558, 0x00000000}, -+ {0x955c, 0x00000000}, -+ {0x9560, 0x00000000}, -+ {0x9564, 0x00000000}, -+ {0x9568, 0x00000000}, -+ {0x956c, 0x00000000}, -+ {0x9570, 0x00000000}, -+ {0x9574, 0x00000000}, -+ {0x9578, 0x00000000}, -+ {0x957c, 0x00000000}, -+ {0x9580, 0x00000000}, -+ {0x9584, 0x04000000}, -+ {0x9588, 0x00000000}, -+ {0x958c, 0x00000000}, -+ {0x9590, 0x00000000}, -+ {0x9594, 0x00000000}, -+ {0x9598, 0x00000000}, -+ {0x959c, 0x00000000}, -+ {0x95a0, 0x00000000}, -+ {0x95a4, 0x00000000}, -+ {0x95a8, 0x00000000}, -+ {0x95ac, 0x00000000}, -+ {0x95b0, 0x00000000}, -+ {0x95b4, 0x00000000}, -+ {0x95b8, 0x00000000}, -+ {0x95bc, 0x00000000}, -+ {0x95c0, 0x00000000}, -+ {0x95c4, 0x00000000}, -+ {0x95c8, 0x04000000}, -+ {0x95cc, 0x00000000}, -+ {0x95d0, 0x00000000}, -+ {0x95d4, 0x00000000}, -+ {0x95d8, 0x00000000}, -+ {0x95dc, 0x00000000}, -+ {0x95e0, 0x00000000}, -+ {0x95e4, 0x00000000}, -+ {0x95e8, 0x00000000}, -+ {0x95ec, 0x00000000}, -+ {0x95f0, 0x00000000}, -+ {0x95f4, 0x00000000}, -+ {0x95f8, 0x00000000}, -+ {0x95fc, 0x00000000}, -+ {0x9600, 0x00000000}, -+ {0x9604, 0x00000000}, -+ {0x9608, 0x00000000}, -+ {0x960c, 0x04000000}, -+ {0x9610, 0x00000000}, -+ {0x9614, 0x00000000}, -+ {0x9618, 0x00000000}, -+ {0x961c, 0x00000000}, -+ {0x9620, 0x00000000}, -+ {0x9624, 0x00000000}, -+ {0x9628, 0x00000000}, -+ {0x962c, 0x00000000}, -+ {0x9630, 0x00000000}, -+ {0x9634, 0x00000000}, -+ {0x9638, 0x00000000}, -+ {0x963c, 0x00000000}, -+ {0x9640, 0x00000000}, -+ {0x9644, 0x00000000}, -+ {0x9648, 0x00000000}, -+ {0x964c, 0x00000000}, -+ {0x9650, 0x04000000}, -+ {0x9654, 0x00000000}, -+ {0x9658, 0x00000000}, -+ {0x965c, 0x00000000}, -+ {0x9660, 0x00000000}, -+ {0x9664, 0x00000000}, -+ {0x9668, 0x00000000}, -+ {0x966c, 0x00000000}, -+ {0x9670, 0x00000000}, -+ {0x9674, 0x00000000}, -+ {0x9678, 0x00000000}, -+ {0x967c, 0x00000000}, -+ {0x9680, 0x00000000}, -+ {0x9684, 0x00000000}, -+ {0x9688, 0x00000000}, -+ {0x968c, 0x00000000}, -+ {0x9690, 0x00000000}, -+ {0x9694, 0x04000000}, -+ {0x9698, 0x00000000}, -+ {0x969c, 0x00000000}, -+ {0x96a0, 0x00000000}, -+ {0x96a4, 0x00000000}, -+ {0x96a8, 0x00000000}, -+ {0x96ac, 0x00000000}, -+ {0x96b0, 0x00000000}, -+ {0x96b4, 0x00000000}, -+ {0x96b8, 0x00000000}, -+ {0x96bc, 0x00000000}, -+ {0x96c0, 0x00000000}, -+ {0x96c4, 0x00000000}, -+ {0x96c8, 0x00000000}, -+ {0x96cc, 0x00000000}, -+ {0x96d0, 0x00000000}, -+ {0x96d4, 0x00000000}, -+ {0x96d8, 0x04000000}, -+ {0x96dc, 0x00000000}, -+ {0x96e0, 0x00000000}, -+ {0x96e4, 0x00000000}, -+ {0x96e8, 0x00000000}, -+ {0x96ec, 0x00000000}, -+ {0x96f0, 0x00000000}, -+ {0x96f4, 0x00000000}, -+ {0x96f8, 0x00000000}, -+ {0x96fc, 0x00000000}, -+ {0x9700, 0x00000000}, -+ {0x9704, 0x00000000}, -+ {0x9708, 0x00000000}, -+ {0x970c, 0x00000000}, -+ {0x9710, 0x00000000}, -+ {0x9714, 0x00000000}, -+ {0x9718, 0x00000000}, -+ {0x971c, 0x04000000}, -+ {0x9720, 0x00000000}, -+ {0x9724, 0x00000000}, -+ {0x9728, 0x00000000}, -+ {0x972c, 0x00000000}, -+ {0x9730, 0x00000000}, -+ {0x9734, 0x00000000}, -+ {0x9738, 0x00000000}, -+ {0x973c, 0x00000000}, -+ {0x9740, 0x00000000}, -+ {0x9744, 0x00000000}, -+ {0x9748, 0x00000000}, -+ {0x974c, 0x00000000}, -+ {0x9750, 0x00000000}, -+ {0x9754, 0x00000000}, -+ {0x9758, 0x00000000}, -+ {0x975c, 0x00000000}, -+ {0x9760, 0x04000000}, -+ {0x9764, 0x00000000}, -+ {0x9768, 0x00000000}, -+ {0x976c, 0x00000000}, -+ {0x9770, 0x00000000}, -+ {0x9774, 0x00000000}, -+ {0x9778, 0x00000000}, -+ {0x977c, 0x00000000}, -+ {0x9780, 0x00000000}, -+ {0x9784, 0x00000000}, -+ {0x9788, 0x00000000}, -+ {0x978c, 0x00000000}, -+ {0x9790, 0x00000000}, -+ {0x9794, 0x00000000}, -+ {0x9798, 0x00000000}, -+ {0x979c, 0x00000000}, -+ {0x97a0, 0x00000000}, -+ {0x97a4, 0x04000000}, -+ {0x97a8, 0x00000000}, -+ {0x97ac, 0x00000000}, -+ {0x97b0, 0x00000000}, -+ {0x97b4, 0x00000000}, -+ {0x97b8, 0x00000000}, -+ {0x97bc, 0x00000000}, -+ {0x97c0, 0x00000000}, -+ {0x97c4, 0x00000000}, -+ {0x97c8, 0x00000000}, -+ {0x97cc, 0x00000000}, -+ {0x97d0, 0x00000000}, -+ {0x97d4, 0x00000000}, -+ {0x97d8, 0x00000000}, -+ {0x97dc, 0x00000000}, -+ {0x97e0, 0x00000000}, -+ {0x97e4, 0x00000000}, -+ {0x97e8, 0x04000000}, -+ {0x97ec, 0x00000000}, -+ {0x97f0, 0x00000000}, -+ {0x97f4, 0x00000000}, -+ {0x97f8, 0x00000000}, -+ {0x97fc, 0x00000000}, -+ {0x9800, 0x00000000}, -+ {0x9804, 0x00000000}, -+ {0x9808, 0x00000000}, -+ {0x980c, 0x00000000}, -+ {0x9810, 0x00000000}, -+ {0x9814, 0x00000000}, -+ {0x9818, 0x00000000}, -+ {0x981c, 0x00000000}, -+ {0x9820, 0x00000000}, -+ {0x9824, 0x00000000}, -+ {0x9828, 0x00000000}, -+ {0x982c, 0x04000000}, -+ {0x81d8, 0x00000000}, -+ {0xb104, 0x2b251f19}, -+ {0xb108, 0x433d3731}, -+ {0xb10c, 0x5b554f49}, -+ {0xb110, 0x736d6761}, -+ {0xb114, 0x7f7f7f79}, -+ {0xb118, 0x120f7f7f}, -+ {0xb11c, 0x1e1b1815}, -+ {0xb120, 0x2a272421}, -+ {0xb124, 0x3633302d}, -+ {0xb128, 0x3f3f3c39}, -+ {0xb12c, 0x3f3f3f3f}, -+ {0x8088, 0x00000110}, -+ {0x8000, 0x00000008}, -+ {0x8080, 0x00000005}, -+ {0x8500, 0x80000008}, -+ {0x8504, 0x43000004}, -+ {0x8508, 0x4b044a00}, -+ {0x850c, 0x40098604}, -+ {0x8510, 0x0004e01f}, -+ {0x8514, 0x74104b00}, -+ {0x8518, 0x000021e0}, -+ {0x851c, 0x74301658}, -+ {0x8520, 0x43800004}, -+ {0x8524, 0x4c000007}, -+ {0x8528, 0x43000004}, -+ {0x852c, 0x56030007}, -+ {0x8530, 0x57000004}, -+ {0x8534, 0x400042fe}, -+ {0x8538, 0x50554200}, -+ {0x853c, 0xb4183000}, -+ {0x8540, 0xe537a50f}, -+ {0x8544, 0xf12bf02b}, -+ {0x8548, 0xf32bf22b}, -+ {0x854c, 0xf62bf42b}, -+ {0x8550, 0xf82bf72b}, -+ {0x8554, 0xfa2bf92b}, -+ {0x8558, 0xfd2bfc2b}, -+ {0x855c, 0xe537fe2b}, -+ {0x8560, 0xf12af02a}, -+ {0x8564, 0xf32af22a}, -+ {0x8568, 0xf52af42a}, -+ {0x856c, 0x000bf62a}, -+ {0x8570, 0xf028a511}, -+ {0x8574, 0xf228f128}, -+ {0x8578, 0xf428f328}, -+ {0x857c, 0xf628f528}, -+ {0x8580, 0xf828f728}, -+ {0x8584, 0xfa28f928}, -+ {0x8588, 0xfc28fb28}, -+ {0x858c, 0xfe28fd28}, -+ {0x8590, 0xf028ff28}, -+ {0x8594, 0xf228f128}, -+ {0x8598, 0x30750001}, -+ {0x859c, 0x30753075}, -+ {0x85a0, 0x30b63097}, -+ {0x85a4, 0x30be30bb}, -+ {0x85a8, 0x30d930cc}, -+ {0x85ac, 0x316d30e6}, -+ {0x85b0, 0x3189317f}, -+ {0x85b4, 0x31d23193}, -+ {0x85b8, 0x31e43210}, -+ {0x85bc, 0x31e831dd}, -+ {0x85c0, 0x322831e1}, -+ {0x85c4, 0x323c3232}, -+ {0x85c8, 0x32503246}, -+ {0x85cc, 0x3264325a}, -+ {0x85d0, 0x3278326e}, -+ {0x85d4, 0x32983285}, -+ {0x85d8, 0x32aa32a6}, -+ {0x85dc, 0x330b32f3}, -+ {0x85e0, 0x333f330c}, -+ {0x85e4, 0x334c3341}, -+ {0x85e8, 0xe35e0001}, -+ {0x85ec, 0x20887410}, -+ {0x85f0, 0x140f0200}, -+ {0x85f4, 0x02002098}, -+ {0x85f8, 0x7430140f}, -+ {0x85fc, 0x5b10e39c}, -+ {0x8600, 0x20807410}, -+ {0x8604, 0x140f0000}, -+ {0x8608, 0x56015507}, -+ {0x860c, 0x7410e382}, -+ {0x8610, 0x02002088}, -+ {0x8614, 0x5517140f}, -+ {0x8618, 0xe34ee382}, -+ {0x861c, 0x468e7508}, -+ {0x8620, 0xe0ace38c}, -+ {0x8624, 0x5500f0e2}, -+ {0x8628, 0x5501e37e}, -+ {0x862c, 0x5b10f1de}, -+ {0x8630, 0x20907410}, -+ {0x8634, 0x140f0000}, -+ {0x8638, 0xe3825507}, -+ {0x863c, 0x20987410}, -+ {0x8640, 0x140f0200}, -+ {0x8644, 0xe3825517}, -+ {0x8648, 0x46967509}, -+ {0x864c, 0xe0ace38c}, -+ {0x8650, 0xe37e5500}, -+ {0x8654, 0x00015501}, -+ {0x8658, 0x4d000007}, -+ {0x865c, 0x74200004}, -+ {0x8660, 0x57005710}, -+ {0x8664, 0x9700140f}, -+ {0x8668, 0x00017430}, -+ {0x866c, 0xe39ce35e}, -+ {0x8670, 0xe52a0bbd}, -+ {0x8674, 0xe36a0001}, -+ {0x8678, 0x0001e3c4}, -+ {0x867c, 0x55005b30}, -+ {0x8680, 0x46500005}, -+ {0x8684, 0x74000004}, -+ {0x8688, 0x1658e37e}, -+ {0x868c, 0x74305501}, -+ {0x8690, 0x46100005}, -+ {0x8694, 0x00010004}, -+ {0x8698, 0x30f8e35e}, -+ {0x869c, 0xe52a0023}, -+ {0x86a0, 0x54ed0002}, -+ {0x86a4, 0x00230baa}, -+ {0x86a8, 0x0002e52a}, -+ {0x86ac, 0xe356e3e4}, -+ {0x86b0, 0xe35e0001}, -+ {0x86b4, 0x002230f3}, -+ {0x86b8, 0x0002e52a}, -+ {0x86bc, 0x0baa54ec}, -+ {0x86c0, 0xe52a0022}, -+ {0x86c4, 0xe3e40002}, -+ {0x86c8, 0x0001e356}, -+ {0x86cc, 0x0baae35e}, -+ {0x86d0, 0xe3e430ec}, -+ {0x86d4, 0x0001e356}, -+ {0x86d8, 0x6d0f6c67}, -+ {0x86dc, 0xe52ae39c}, -+ {0x86e0, 0xe39c6c8b}, -+ {0x86e4, 0x0bace52a}, -+ {0x86e8, 0x6d0f6cb3}, -+ {0x86ec, 0xe52ae39c}, -+ {0x86f0, 0x6cdb0bad}, -+ {0x86f4, 0xe39c6d0f}, -+ {0x86f8, 0x6cf5e52a}, -+ {0x86fc, 0xe39c6d0f}, -+ {0x8700, 0x6c0be52a}, -+ {0x8704, 0xe39c6d00}, -+ {0x8708, 0x6c25e52a}, -+ {0x870c, 0xe52ae39c}, -+ {0x8710, 0x6c4df8c6}, -+ {0x8714, 0xe52ae39c}, -+ {0x8718, 0x6c75f9cf}, -+ {0x871c, 0xe52ae39c}, -+ {0x8720, 0xe39c6c99}, -+ {0x8724, 0xfad6e52a}, -+ {0x8728, 0x21e87410}, -+ {0x872c, 0x6e670009}, -+ {0x8730, 0xe3c46f0f}, -+ {0x8734, 0x7410e52f}, -+ {0x8738, 0x000b21e8}, -+ {0x873c, 0xe3c46e8b}, -+ {0x8740, 0x7410e52f}, -+ {0x8744, 0x000d21e8}, -+ {0x8748, 0x6f0f6eb3}, -+ {0x874c, 0xe52fe3c4}, -+ {0x8750, 0xfe07ff08}, -+ {0x8754, 0x21e87410}, -+ {0x8758, 0x6ec7000e}, -+ {0x875c, 0xe52fe3c4}, -+ {0x8760, 0x21e87410}, -+ {0x8764, 0x6edb000f}, -+ {0x8768, 0xe3c46f0f}, -+ {0x876c, 0x7410e52f}, -+ {0x8770, 0x001021e8}, -+ {0x8774, 0xe3c46eef}, -+ {0x8778, 0xff03e52f}, -+ {0x877c, 0xe52ffe02}, -+ {0x8780, 0x21e87410}, -+ {0x8784, 0x6e110013}, -+ {0x8788, 0xe3c46f00}, -+ {0x878c, 0xff03e52f}, -+ {0x8790, 0xe52ffe02}, -+ {0x8794, 0x21e87410}, -+ {0x8798, 0x6e250014}, -+ {0x879c, 0xe52fe3c4}, -+ {0x87a0, 0xff08fc24}, -+ {0x87a4, 0x7410fe07}, -+ {0x87a8, 0x001521e8}, -+ {0x87ac, 0xe3c46e39}, -+ {0x87b0, 0x7410e52f}, -+ {0x87b4, 0x001621e8}, -+ {0x87b8, 0xe3c46e4d}, -+ {0x87bc, 0xfd27e52f}, -+ {0x87c0, 0x21e87410}, -+ {0x87c4, 0x6e750018}, -+ {0x87c8, 0xe52fe3c4}, -+ {0x87cc, 0x21e87410}, -+ {0x87d0, 0x6e99001a}, -+ {0x87d4, 0xe52fe3c4}, -+ {0x87d8, 0xe36afe24}, -+ {0x87dc, 0x63404380}, -+ {0x87e0, 0x43006880}, -+ {0x87e4, 0x31300bac}, -+ {0x87e8, 0xe52f0022}, -+ {0x87ec, 0x54ec0002}, -+ {0x87f0, 0x00220baa}, -+ {0x87f4, 0x0002e52f}, -+ {0x87f8, 0xe362e3e4}, -+ {0x87fc, 0xe36a0001}, -+ {0x8800, 0x63404380}, -+ {0x8804, 0x43006881}, -+ {0x8808, 0x31210baa}, -+ {0x880c, 0xe362e3e4}, -+ {0x8810, 0xe36a0001}, -+ {0x8814, 0x63414380}, -+ {0x8818, 0x43006882}, -+ {0x881c, 0x31140baa}, -+ {0x8820, 0xe362e3e4}, -+ {0x8824, 0x00040001}, -+ {0x8828, 0x000742fc}, -+ {0x882c, 0x00046001}, -+ {0x8830, 0x00074200}, -+ {0x8834, 0x62006220}, -+ {0x8838, 0x55010004}, -+ {0x883c, 0x66055b40}, -+ {0x8840, 0x62000007}, -+ {0x8844, 0xe40e6300}, -+ {0x8848, 0x09000004}, -+ {0x884c, 0x0b400a01}, -+ {0x8850, 0x0e010d00}, -+ {0x8854, 0x00040032}, -+ {0x8858, 0x42fb950b}, -+ {0x885c, 0x4d040007}, -+ {0x8860, 0x42000004}, -+ {0x8864, 0x00074380}, -+ {0x8868, 0x00044d01}, -+ {0x886c, 0x00074300}, -+ {0x8870, 0x05a30562}, -+ {0x8874, 0xe40e961f}, -+ {0x8878, 0xe37e0004}, -+ {0x887c, 0x06a20007}, -+ {0x8880, 0xe40e07a3}, -+ {0x8884, 0xe37e0004}, -+ {0x8888, 0x0002e3fe}, -+ {0x888c, 0x4380e406}, -+ {0x8890, 0x4d000007}, -+ {0x8894, 0x43000004}, -+ {0x8898, 0x000742fe}, -+ {0x889c, 0x00044d00}, -+ {0x88a0, 0x00014200}, -+ {0x88a4, 0x42fc0004}, -+ {0x88a8, 0x60030007}, -+ {0x88ac, 0x42000004}, -+ {0x88b0, 0x00073199}, -+ {0x88b4, 0x07a306a2}, -+ {0x88b8, 0xe1eb31c5}, -+ {0x88bc, 0xe1fee1f9}, -+ {0x88c0, 0xe1eb0001}, -+ {0x88c4, 0x0001e1fe}, -+ {0x88c8, 0xe1f9e1f2}, -+ {0x88cc, 0x0001e1fe}, -+ {0x88d0, 0xe1fee1f2}, -+ {0x88d4, 0x00040001}, -+ {0x88d8, 0x000742fc}, -+ {0x88dc, 0x00046003}, -+ {0x88e0, 0x00014200}, -+ {0x88e4, 0x42fc0004}, -+ {0x88e8, 0x60010007}, -+ {0x88ec, 0x42000004}, -+ {0x88f0, 0x00070001}, -+ {0x88f4, 0x62006220}, -+ {0x88f8, 0x0001e406}, -+ {0x88fc, 0x63000007}, -+ {0x8900, 0x09000004}, -+ {0x8904, 0x0e010a00}, -+ {0x8908, 0x00070032}, -+ {0x890c, 0xe40e06a2}, -+ {0x8910, 0x0002e41a}, -+ {0x8914, 0x000742fe}, -+ {0x8918, 0x00044d00}, -+ {0x891c, 0x00014200}, -+ {0x8920, 0x77000005}, -+ {0x8924, 0x52000007}, -+ {0x8928, 0x42fe0004}, -+ {0x892c, 0x60000007}, -+ {0x8930, 0x42000004}, -+ {0x8934, 0x60004380}, -+ {0x8938, 0x62016100}, -+ {0x893c, 0x68046310}, -+ {0x8940, 0x41000005}, -+ {0x8944, 0x00075500}, -+ {0x8948, 0x00045c02}, -+ {0x894c, 0x00014300}, -+ {0x8950, 0x6c060005}, -+ {0x8954, 0xe2aae298}, -+ {0x8958, 0xe42ae285}, -+ {0x895c, 0xe432e2f3}, -+ {0x8960, 0x0001e30c}, -+ {0x8964, 0x0005e285}, -+ {0x8968, 0xe2986c06}, -+ {0x896c, 0xe42ae4a9}, -+ {0x8970, 0xe432e2f3}, -+ {0x8974, 0x0001e30c}, -+ {0x8978, 0x6c000005}, -+ {0x897c, 0xe2aae298}, -+ {0x8980, 0xe445e285}, -+ {0x8984, 0xe44de2f3}, -+ {0x8988, 0x0001e30c}, -+ {0x898c, 0x0005e285}, -+ {0x8990, 0xe2986c00}, -+ {0x8994, 0xe445e4a9}, -+ {0x8998, 0xe44de2f3}, -+ {0x899c, 0x0001e30c}, -+ {0x89a0, 0x6c040005}, -+ {0x89a4, 0xe2aae298}, -+ {0x89a8, 0xe460e285}, -+ {0x89ac, 0xe468e2f3}, -+ {0x89b0, 0x0001e30c}, -+ {0x89b4, 0x0005e285}, -+ {0x89b8, 0xe2986c04}, -+ {0x89bc, 0xe460e4a9}, -+ {0x89c0, 0xe468e2f3}, -+ {0x89c4, 0x0001e30c}, -+ {0x89c8, 0x6c020005}, -+ {0x89cc, 0xe2aae298}, -+ {0x89d0, 0xe47be285}, -+ {0x89d4, 0xe483e2f3}, -+ {0x89d8, 0x0001e30c}, -+ {0x89dc, 0x0005e285}, -+ {0x89e0, 0xe2986c02}, -+ {0x89e4, 0xe47be4a9}, -+ {0x89e8, 0xe483e2f3}, -+ {0x89ec, 0x0001e30c}, -+ {0x89f0, 0x43800004}, -+ {0x89f4, 0x610a6008}, -+ {0x89f8, 0x63ce6200}, -+ {0x89fc, 0x60800006}, -+ {0x8a00, 0x00047f00}, -+ {0x8a04, 0xe4e04300}, -+ {0x8a08, 0x00070001}, -+ {0x8a0c, 0x4d015500}, -+ {0x8a10, 0x74200004}, -+ {0x8a14, 0x57107711}, -+ {0x8a18, 0x140f5700}, -+ {0x8a1c, 0x00077430}, -+ {0x8a20, 0x00044d00}, -+ {0x8a24, 0x00074380}, -+ {0x8a28, 0x00047200}, -+ {0x8a2c, 0x00014300}, -+ {0x8a30, 0x74200004}, -+ {0x8a34, 0x77000005}, -+ {0x8a38, 0x73887e07}, -+ {0x8a3c, 0x8f007380}, -+ {0x8a40, 0x0004140f}, -+ {0x8a44, 0x00057430}, -+ {0x8a48, 0x00017300}, -+ {0x8a4c, 0x0005e496}, -+ {0x8a50, 0x00017300}, -+ {0x8a54, 0x43800004}, -+ {0x8a58, 0x0006b103}, -+ {0x8a5c, 0x91037cdb}, -+ {0x8a60, 0x40db0007}, -+ {0x8a64, 0x43000004}, -+ {0x8a68, 0x0005e496}, -+ {0x8a6c, 0x00067380}, -+ {0x8a70, 0x60025d01}, -+ {0x8a74, 0xe4ba6200}, -+ {0x8a78, 0x73000005}, -+ {0x8a7c, 0x76080007}, -+ {0x8a80, 0x00047578}, -+ {0x8a84, 0x00074380}, -+ {0x8a88, 0x5e005e01}, -+ {0x8a8c, 0x0006140a}, -+ {0x8a90, 0x7f006380}, -+ {0x8a94, 0x00076080}, -+ {0x8a98, 0x4e204c3f}, -+ {0x8a9c, 0x73047280}, -+ {0x8aa0, 0x140a7300}, -+ {0x8aa4, 0x00044d20}, -+ {0x8aa8, 0x00064300}, -+ {0x8aac, 0x00077402}, -+ {0x8ab0, 0x40004001}, -+ {0x8ab4, 0x0006ab00}, -+ {0x8ab8, 0x00077404}, -+ {0x8abc, 0x40004001}, -+ {0x8ac0, 0x140aab00}, -+ {0x8ac4, 0x43800004}, -+ {0x8ac8, 0x52800007}, -+ {0x8acc, 0x140a5200}, -+ {0x8ad0, 0x4d004c00}, -+ {0x8ad4, 0x00064e00}, -+ {0x8ad8, 0x63006080}, -+ {0x8adc, 0x43000004}, -+ {0x8ae0, 0x76000007}, -+ {0x8ae4, 0x00040001}, -+ {0x8ae8, 0xb1034380}, -+ {0x8aec, 0x7cdb0006}, -+ {0x8af0, 0x00079103}, -+ {0x8af4, 0x000440db}, -+ {0x8af8, 0xe4964300}, -+ {0x8afc, 0xe4ba7e03}, -+ {0x8b00, 0x43800004}, -+ {0x8b04, 0x0006b103}, -+ {0x8b08, 0x91037c5b}, -+ {0x8b0c, 0x405b0007}, -+ {0x8b10, 0x43000004}, -+ {0x8b14, 0x00010001}, -+ {0x8b18, 0x43800004}, -+ {0x8b1c, 0x4e200007}, -+ {0x8b20, 0x63800006}, -+ {0x8b24, 0x5f807cdb}, -+ {0x8b28, 0x43000004}, -+ {0x8b2c, 0x76080007}, -+ {0x8b30, 0x00057560}, -+ {0x8b34, 0x00047380}, -+ {0x8b38, 0x0005420e}, -+ {0x8b3c, 0x14c86c01}, -+ {0x8b40, 0x6c001432}, -+ {0x8b44, 0x42000004}, -+ {0x8b48, 0x43800004}, -+ {0x8b4c, 0x5f000006}, -+ {0x8b50, 0x73010007}, -+ {0x8b54, 0x00047300}, -+ {0x8b58, 0x0007420f}, -+ {0x8b5c, 0x52005280}, -+ {0x8b60, 0x0004140a}, -+ {0x8b64, 0x00064200}, -+ {0x8b68, 0x7c5b6300}, -+ {0x8b6c, 0x4e000007}, -+ {0x8b70, 0x43000004}, -+ {0x8b74, 0x73000005}, -+ {0x8b78, 0x76000007}, -+ {0x8b7c, 0xe4c30001}, -+ {0x8b80, 0x00040001}, -+ {0x8b84, 0x60004380}, -+ {0x8b88, 0x62016100}, -+ {0x8b8c, 0x00066310}, -+ {0x8b90, 0x00046000}, -+ {0x8b94, 0x00014300}, -+ {0x8b98, 0x0001e4e0}, -+ {0x8b9c, 0x4e004f02}, -+ {0x8ba0, 0x52015302}, -+ {0x8ba4, 0x140f0001}, -+ {0x8ba8, 0x00019700}, -+ {0x8bac, 0x65014380}, -+ {0x8bb0, 0x79007800}, -+ {0x8bb4, 0x7b407a00}, -+ {0x8bb8, 0x00014300}, -+ {0x8bbc, 0x65004380}, -+ {0x8bc0, 0x00014300}, -+ {0x8bc4, 0x64014380}, -+ {0x8bc8, 0x7d007c00}, -+ {0x8bcc, 0x7f407e00}, -+ {0x8bd0, 0x00014300}, -+ {0x8bd4, 0x64004380}, -+ {0x8bd8, 0x00014300}, -+ {0x8bdc, 0x7b004380}, -+ {0x8be0, 0x79007a04}, -+ {0x8be4, 0x43007802}, -+ {0x8be8, 0x33825509}, -+ {0x8bec, 0x43800001}, -+ {0x8bf0, 0x7a007b40}, -+ {0x8bf4, 0x55194300}, -+ {0x8bf8, 0x00013382}, -+ {0x8bfc, 0x74007401}, -+ {0x8c00, 0x00018e00}, -+ {0x8c04, 0x52300007}, -+ {0x8c08, 0x74310004}, -+ {0x8c0c, 0x8e007430}, -+ {0x8c10, 0x52200007}, -+ {0x8c14, 0x00010004}, -+ {0x8c18, 0x57005702}, -+ {0x8c1c, 0x00018e00}, -+ {0x8c20, 0x57425740}, -+ {0x8c24, 0x8e005740}, -+ {0x8c28, 0x00015700}, -+ {0x8c2c, 0x561042ef}, -+ {0x8c30, 0x42005600}, -+ {0x8c34, 0x00018c00}, -+ {0x8c38, 0xe3a75b20}, -+ {0x8c3c, 0x54005480}, -+ {0x8c40, 0x54005481}, -+ {0x8c44, 0x54005482}, -+ {0x8c48, 0xbf1ae3ac}, -+ {0x8c4c, 0xe36e300b}, -+ {0x8c50, 0xe390e377}, -+ {0x8c54, 0x0001e523}, -+ {0x8c58, 0x54c054bf}, -+ {0x8c5c, 0x54c154a3}, -+ {0x8c60, 0x4c1854a4}, -+ {0x8c64, 0xbf091402}, -+ {0x8c68, 0x54a454c2}, -+ {0x8c6c, 0xbf051402}, -+ {0x8c70, 0x54a354c1}, -+ {0x8c74, 0xbf011402}, -+ {0x8c78, 0x54dfe534}, -+ {0x8c7c, 0x54bf0001}, -+ {0x8c80, 0x050a54e5}, -+ {0x8c84, 0x000154df}, -+ {0x8c88, 0x00071657}, -+ {0x8c8c, 0x00044c80}, -+ {0x8c90, 0x43807430}, -+ {0x8c94, 0x7e007f40}, -+ {0x8c98, 0x7c027d00}, -+ {0x8c9c, 0x5b404300}, -+ {0x8ca0, 0x5c015501}, -+ {0x8ca4, 0x5480e396}, -+ {0x8ca8, 0x54815400}, -+ {0x8cac, 0x54825400}, -+ {0x8cb0, 0x00075400}, -+ {0x8cb4, 0x00044c00}, -+ {0x8cb8, 0xe3ac7410}, -+ {0x8cbc, 0x300bbfe1}, -+ {0x8cc0, 0x56005610}, -+ {0x8cc4, 0x00018c00}, -+ {0x8cc8, 0x57005704}, -+ {0x8ccc, 0xa7038e00}, -+ {0x8cd0, 0x33f0aff7}, -+ {0x8cd4, 0xaf034019}, -+ {0x8cd8, 0x33f0402b}, -+ {0x8cdc, 0x33df402b}, -+ {0x8ce0, 0x57005708}, -+ {0x8ce4, 0x57818e00}, -+ {0x8ce8, 0x8e005780}, -+ {0x8cec, 0x00074380}, -+ {0x8cf0, 0x5c005c01}, -+ {0x8cf4, 0x00041403}, -+ {0x8cf8, 0x00014300}, -+ {0x8cfc, 0x0007427f}, -+ {0x8d00, 0x62006280}, -+ {0x8d04, 0x00049200}, -+ {0x8d08, 0x00014200}, -+ {0x8d0c, 0x0007427f}, -+ {0x8d10, 0x63146394}, -+ {0x8d14, 0x00049200}, -+ {0x8d18, 0x00014200}, -+ {0x8d1c, 0x42fe0004}, -+ {0x8d20, 0x4d010007}, -+ {0x8d24, 0x42000004}, -+ {0x8d28, 0x140f7420}, -+ {0x8d2c, 0x57005710}, -+ {0x8d30, 0x0001141f}, -+ {0x8d34, 0x42fe0004}, -+ {0x8d38, 0x4d010007}, -+ {0x8d3c, 0x42000004}, -+ {0x8d40, 0x140f7420}, -+ {0x8d44, 0x000742bf}, -+ {0x8d48, 0x62006240}, -+ {0x8d4c, 0x0004141f}, -+ {0x8d50, 0x00014200}, -+ {0x8d54, 0x5d060006}, -+ {0x8d58, 0x61046003}, -+ {0x8d5c, 0x00056201}, -+ {0x8d60, 0x00017310}, -+ {0x8d64, 0x43800004}, -+ {0x8d68, 0x5e010007}, -+ {0x8d6c, 0x140a5e00}, -+ {0x8d70, 0x0006b103}, -+ {0x8d74, 0x91037f07}, -+ {0x8d78, 0x43070007}, -+ {0x8d7c, 0x5c000006}, -+ {0x8d80, 0x5e035d02}, -+ {0x8d84, 0x43000004}, -+ {0x8d88, 0x00060001}, -+ {0x8d8c, 0x60005d04}, -+ {0x8d90, 0x62016104}, -+ {0x8d94, 0x73100005}, -+ {0x8d98, 0x00040001}, -+ {0x8d9c, 0x00074380}, -+ {0x8da0, 0x5e005e01}, -+ {0x8da4, 0xb103140a}, -+ {0x8da8, 0x7fc60006}, -+ {0x8dac, 0x00079103}, -+ {0x8db0, 0x000643c6}, -+ {0x8db4, 0x5d025c00}, -+ {0x8db8, 0x00045e03}, -+ {0x8dbc, 0x00014300}, -+ {0x8dc0, 0x5d040006}, -+ {0x8dc4, 0x61046000}, -+ {0x8dc8, 0x00056201}, -+ {0x8dcc, 0x00017310}, -+ {0x8dd0, 0x43800004}, -+ {0x8dd4, 0x5e010007}, -+ {0x8dd8, 0x140a5e00}, -+ {0x8ddc, 0x0006b103}, -+ {0x8de0, 0x91037fc6}, -+ {0x8de4, 0x43c60007}, -+ {0x8de8, 0x5c000006}, -+ {0x8dec, 0x5e035d02}, -+ {0x8df0, 0x43000004}, -+ {0x8df4, 0x00060001}, -+ {0x8df8, 0x60025d00}, -+ {0x8dfc, 0x62016100}, -+ {0x8e00, 0x73000005}, -+ {0x8e04, 0x00040001}, -+ {0x8e08, 0x00074380}, -+ {0x8e0c, 0x5e005e01}, -+ {0x8e10, 0xb103140a}, -+ {0x8e14, 0x7fc00006}, -+ {0x8e18, 0x00079103}, -+ {0x8e1c, 0x000643c0}, -+ {0x8e20, 0x5d025c00}, -+ {0x8e24, 0x00045e03}, -+ {0x8e28, 0x00014300}, -+ {0x8e2c, 0x7e020005}, -+ {0x8e30, 0x42f70004}, -+ {0x8e34, 0x6c080005}, -+ {0x8e38, 0x42700004}, -+ {0x8e3c, 0x73810005}, -+ {0x8e40, 0x93007380}, -+ {0x8e44, 0x42f70004}, -+ {0x8e48, 0x6c000005}, -+ {0x8e4c, 0x42000004}, -+ {0x8e50, 0x00040001}, -+ {0x8e54, 0x00074380}, -+ {0x8e58, 0x73007304}, -+ {0x8e5c, 0x72401405}, -+ {0x8e60, 0x43000004}, -+ {0x8e64, 0x74040006}, -+ {0x8e68, 0x40010007}, -+ {0x8e6c, 0xab004000}, -+ {0x8e70, 0x0001140f}, -+ {0x8e74, 0x140ae517}, -+ {0x8e78, 0x140ae4c3}, -+ {0x8e7c, 0x0001e51e}, -+ {0x8e80, 0xe4c3e517}, -+ {0x8e84, 0x00040001}, -+ {0x8e88, 0x00047410}, -+ {0x8e8c, 0x42f04380}, -+ {0x8e90, 0x62080007}, -+ {0x8e94, 0x24206301}, -+ {0x8e98, 0x14c80000}, -+ {0x8e9c, 0x00002428}, -+ {0x8ea0, 0x1a4215f4}, -+ {0x8ea4, 0x6300000b}, -+ {0x8ea8, 0x42000004}, -+ {0x8eac, 0x74304300}, -+ {0x8eb0, 0x4380140f}, -+ {0x8eb4, 0x73080007}, -+ {0x8eb8, 0x00047300}, -+ {0x8ebc, 0x00014300}, -+ {0x8ec0, 0x4bf00007}, -+ {0x8ec4, 0x490b4a8f}, -+ {0x8ec8, 0x4a8e48f1}, -+ {0x8ecc, 0x48a5490a}, -+ {0x8ed0, 0x49094a8d}, -+ {0x8ed4, 0x4a8c487d}, -+ {0x8ed8, 0x48754908}, -+ {0x8edc, 0x49074a8b}, -+ {0x8ee0, 0x4a8a4889}, -+ {0x8ee4, 0x48b74906}, -+ {0x8ee8, 0x49054a89}, -+ {0x8eec, 0x4a8848fc}, -+ {0x8ef0, 0x48564905}, -+ {0x8ef4, 0x49044a87}, -+ {0x8ef8, 0x4a8648c1}, -+ {0x8efc, 0x483d4904}, -+ {0x8f00, 0x49034a85}, -+ {0x8f04, 0x4a8448c7}, -+ {0x8f08, 0x485e4903}, -+ {0x8f0c, 0x49024a83}, -+ {0x8f10, 0x4a8248ac}, -+ {0x8f14, 0x48624902}, -+ {0x8f18, 0x49024a81}, -+ {0x8f1c, 0x4a804820}, -+ {0x8f20, 0x48004900}, -+ {0x8f24, 0x49014a90}, -+ {0x8f28, 0x4a10481f}, -+ {0x8f2c, 0x00060001}, -+ {0x8f30, 0x5f005f80}, -+ {0x8f34, 0x00059900}, -+ {0x8f38, 0x00017300}, -+ {0x8f3c, 0x63800006}, -+ {0x8f40, 0x98006300}, -+ {0x8f44, 0x549f0001}, -+ {0x8f48, 0x5c015400}, -+ {0x8f4c, 0x540054df}, -+ {0x8f50, 0x00015c02}, -+ {0x8f54, 0x07145c01}, -+ {0x8f58, 0x5c025400}, -+ {0x8f5c, 0x5c020001}, -+ {0x8f60, 0x54000714}, -+ {0x8f64, 0x00015c01}, -+ {0x8f68, 0x4c184c98}, -+ {0x8f6c, 0x00080001}, -+ {0x8f70, 0x5c020004}, -+ {0x8f74, 0x09017430}, -+ {0x8f78, 0x0ba60c01}, -+ {0x8f7c, 0x77800005}, -+ {0x8f80, 0x52200007}, -+ {0x8f84, 0x43800004}, -+ {0x8f88, 0x610a6008}, -+ {0x8f8c, 0x63c26200}, -+ {0x8f90, 0x5c000007}, -+ {0x8f94, 0x43000004}, -+ {0x8f98, 0x00000001}, -+ {0x8080, 0x00000004}, -+ {0x8080, 0x00000000}, -+ {0x8088, 0x00000000}, -+}; -+ -+static const struct rtw89_txpwr_byrate_cfg rtw89_8851b_txpwr_byrate[] = { -+ { 0, 0, 0, 0, 4, 0x50505050, }, -+ { 0, 0, 1, 0, 4, 0x54585858, }, -+ { 0, 0, 1, 4, 4, 0x44484c50, }, -+ { 0, 0, 2, 0, 4, 0x50545858, }, -+ { 0, 0, 2, 4, 4, 0x4044484c, }, -+ { 0, 0, 2, 8, 4, 0x3034383c, }, -+ { 0, 0, 3, 0, 4, 0x50505050, }, -+ { 0, 1, 2, 0, 4, 0x50545858, }, -+ { 0, 1, 2, 4, 4, 0x4044484c, }, -+ { 0, 1, 2, 8, 4, 0x3034383c, }, -+ { 0, 1, 3, 0, 4, 0x50505050, }, -+ { 0, 0, 4, 1, 4, 0x00000000, }, -+ { 0, 0, 4, 0, 1, 0x00000000, }, -+ { 1, 0, 1, 0, 4, 0x58585858, }, -+ { 1, 0, 1, 4, 4, 0x484c5054, }, -+ { 1, 0, 2, 0, 4, 0x54585858, }, -+ { 1, 0, 2, 4, 4, 0x44484c50, }, -+ { 1, 0, 2, 8, 4, 0x34383c40, }, -+ { 1, 0, 3, 0, 4, 0x40404040, }, -+ { 1, 1, 2, 0, 4, 0x54585858, }, -+ { 1, 1, 2, 4, 4, 0x44484c50, }, -+ { 1, 1, 2, 8, 4, 0x34383c40, }, -+ { 1, 1, 3, 0, 4, 0x48484848, }, -+ { 1, 0, 4, 0, 4, 0x00000000, }, -+ { 2, 0, 1, 0, 4, 0x40404040, }, -+ { 2, 0, 1, 4, 4, 0x383c4040, }, -+ { 2, 0, 2, 0, 4, 0x40404040, }, -+ { 2, 0, 2, 4, 4, 0x34383c40, }, -+ { 2, 0, 2, 8, 4, 0x24282c30, }, -+ { 2, 0, 3, 0, 4, 0x40404040, }, -+ { 2, 1, 2, 0, 4, 0x40404040, }, -+ { 2, 1, 2, 4, 4, 0x34383c40, }, -+ { 2, 1, 2, 8, 4, 0x24282c30, }, -+ { 2, 1, 3, 0, 4, 0x40404040, }, -+ { 2, 0, 4, 0, 4, 0x00000000, }, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { -+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}, -+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, -+ 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { -+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -+ {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_2ga_n[] = { -+ 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, -3, -3, -+ -4, -4, -4, -4, -4, -5, -5, -5, -5, -5, -5, -6, -6, -6 -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_2ga_p[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4 -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { -+ 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -3, -3, -3, -3, -3, -+ -4, -4, -4, -4, -4, -5, -5, -5, -5, -5, -5, -6, -6, -6 -+}; -+ -+static const s8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4 -+}; -+ -+const u8 rtw89_8851b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+ [RTW89_REGD_NUM] = { -+ [0][0][RTW89_ACMA] = 0, -+ [0][0][RTW89_CN] = 0, -+ [0][0][RTW89_ETSI] = 0, -+ [0][0][RTW89_FCC] = 1, -+ [0][0][RTW89_IC] = 1, -+ [0][0][RTW89_KCC] = 0, -+ [0][0][RTW89_MKK] = 0, -+ [0][0][RTW89_UK] = 0, -+ [0][1][RTW89_ACMA] = 0, -+ [0][1][RTW89_CN] = 0, -+ [0][1][RTW89_ETSI] = 0, -+ [0][1][RTW89_FCC] = 3, -+ [0][1][RTW89_IC] = 3, -+ [0][1][RTW89_KCC] = 0, -+ [0][1][RTW89_MKK] = 0, -+ [0][1][RTW89_UK] = 0, -+ [1][1][RTW89_ACMA] = 0, -+ [1][1][RTW89_CN] = 0, -+ [1][1][RTW89_ETSI] = 0, -+ [1][1][RTW89_FCC] = 3, -+ [1][1][RTW89_IC] = 3, -+ [1][1][RTW89_KCC] = 0, -+ [1][1][RTW89_MKK] = 0, -+ [1][1][RTW89_UK] = 0, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][0][0][RTW89_WW][0] = 58, -+ [0][0][0][0][RTW89_WW][1] = 58, -+ [0][0][0][0][RTW89_WW][2] = 58, -+ [0][0][0][0][RTW89_WW][3] = 58, -+ [0][0][0][0][RTW89_WW][4] = 58, -+ [0][0][0][0][RTW89_WW][5] = 58, -+ [0][0][0][0][RTW89_WW][6] = 58, -+ [0][0][0][0][RTW89_WW][7] = 58, -+ [0][0][0][0][RTW89_WW][8] = 58, -+ [0][0][0][0][RTW89_WW][9] = 58, -+ [0][0][0][0][RTW89_WW][10] = 58, -+ [0][0][0][0][RTW89_WW][11] = 58, -+ [0][0][0][0][RTW89_WW][12] = 52, -+ [0][0][0][0][RTW89_WW][13] = 76, -+ [0][1][0][0][RTW89_WW][0] = 0, -+ [0][1][0][0][RTW89_WW][1] = 0, -+ [0][1][0][0][RTW89_WW][2] = 0, -+ [0][1][0][0][RTW89_WW][3] = 0, -+ [0][1][0][0][RTW89_WW][4] = 0, -+ [0][1][0][0][RTW89_WW][5] = 0, -+ [0][1][0][0][RTW89_WW][6] = 0, -+ [0][1][0][0][RTW89_WW][7] = 0, -+ [0][1][0][0][RTW89_WW][8] = 0, -+ [0][1][0][0][RTW89_WW][9] = 0, -+ [0][1][0][0][RTW89_WW][10] = 0, -+ [0][1][0][0][RTW89_WW][11] = 0, -+ [0][1][0][0][RTW89_WW][12] = 0, -+ [0][1][0][0][RTW89_WW][13] = 0, -+ [1][0][0][0][RTW89_WW][0] = 0, -+ [1][0][0][0][RTW89_WW][1] = 0, -+ [1][0][0][0][RTW89_WW][2] = 58, -+ [1][0][0][0][RTW89_WW][3] = 58, -+ [1][0][0][0][RTW89_WW][4] = 58, -+ [1][0][0][0][RTW89_WW][5] = 58, -+ [1][0][0][0][RTW89_WW][6] = 58, -+ [1][0][0][0][RTW89_WW][7] = 58, -+ [1][0][0][0][RTW89_WW][8] = 58, -+ [1][0][0][0][RTW89_WW][9] = 58, -+ [1][0][0][0][RTW89_WW][10] = 58, -+ [1][0][0][0][RTW89_WW][11] = 0, -+ [1][0][0][0][RTW89_WW][12] = 0, -+ [1][0][0][0][RTW89_WW][13] = 0, -+ [1][1][0][0][RTW89_WW][0] = 0, -+ [1][1][0][0][RTW89_WW][1] = 0, -+ [1][1][0][0][RTW89_WW][2] = 0, -+ [1][1][0][0][RTW89_WW][3] = 0, -+ [1][1][0][0][RTW89_WW][4] = 0, -+ [1][1][0][0][RTW89_WW][5] = 0, -+ [1][1][0][0][RTW89_WW][6] = 0, -+ [1][1][0][0][RTW89_WW][7] = 0, -+ [1][1][0][0][RTW89_WW][8] = 0, -+ [1][1][0][0][RTW89_WW][9] = 0, -+ [1][1][0][0][RTW89_WW][10] = 0, -+ [1][1][0][0][RTW89_WW][11] = 0, -+ [1][1][0][0][RTW89_WW][12] = 0, -+ [1][1][0][0][RTW89_WW][13] = 0, -+ [0][0][1][0][RTW89_WW][0] = 58, -+ [0][0][1][0][RTW89_WW][1] = 60, -+ [0][0][1][0][RTW89_WW][2] = 60, -+ [0][0][1][0][RTW89_WW][3] = 60, -+ [0][0][1][0][RTW89_WW][4] = 60, -+ [0][0][1][0][RTW89_WW][5] = 60, -+ [0][0][1][0][RTW89_WW][6] = 60, -+ [0][0][1][0][RTW89_WW][7] = 60, -+ [0][0][1][0][RTW89_WW][8] = 60, -+ [0][0][1][0][RTW89_WW][9] = 60, -+ [0][0][1][0][RTW89_WW][10] = 60, -+ [0][0][1][0][RTW89_WW][11] = 60, -+ [0][0][1][0][RTW89_WW][12] = 58, -+ [0][0][1][0][RTW89_WW][13] = 0, -+ [0][1][1][0][RTW89_WW][0] = 0, -+ [0][1][1][0][RTW89_WW][1] = 0, -+ [0][1][1][0][RTW89_WW][2] = 0, -+ [0][1][1][0][RTW89_WW][3] = 0, -+ [0][1][1][0][RTW89_WW][4] = 0, -+ [0][1][1][0][RTW89_WW][5] = 0, -+ [0][1][1][0][RTW89_WW][6] = 0, -+ [0][1][1][0][RTW89_WW][7] = 0, -+ [0][1][1][0][RTW89_WW][8] = 0, -+ [0][1][1][0][RTW89_WW][9] = 0, -+ [0][1][1][0][RTW89_WW][10] = 0, -+ [0][1][1][0][RTW89_WW][11] = 0, -+ [0][1][1][0][RTW89_WW][12] = 0, -+ [0][1][1][0][RTW89_WW][13] = 0, -+ [0][0][2][0][RTW89_WW][0] = 60, -+ [0][0][2][0][RTW89_WW][1] = 60, -+ [0][0][2][0][RTW89_WW][2] = 60, -+ [0][0][2][0][RTW89_WW][3] = 60, -+ [0][0][2][0][RTW89_WW][4] = 60, -+ [0][0][2][0][RTW89_WW][5] = 60, -+ [0][0][2][0][RTW89_WW][6] = 60, -+ [0][0][2][0][RTW89_WW][7] = 60, -+ [0][0][2][0][RTW89_WW][8] = 60, -+ [0][0][2][0][RTW89_WW][9] = 60, -+ [0][0][2][0][RTW89_WW][10] = 60, -+ [0][0][2][0][RTW89_WW][11] = 60, -+ [0][0][2][0][RTW89_WW][12] = 60, -+ [0][0][2][0][RTW89_WW][13] = 0, -+ [0][1][2][0][RTW89_WW][0] = 0, -+ [0][1][2][0][RTW89_WW][1] = 0, -+ [0][1][2][0][RTW89_WW][2] = 0, -+ [0][1][2][0][RTW89_WW][3] = 0, -+ [0][1][2][0][RTW89_WW][4] = 0, -+ [0][1][2][0][RTW89_WW][5] = 0, -+ [0][1][2][0][RTW89_WW][6] = 0, -+ [0][1][2][0][RTW89_WW][7] = 0, -+ [0][1][2][0][RTW89_WW][8] = 0, -+ [0][1][2][0][RTW89_WW][9] = 0, -+ [0][1][2][0][RTW89_WW][10] = 0, -+ [0][1][2][0][RTW89_WW][11] = 0, -+ [0][1][2][0][RTW89_WW][12] = 0, -+ [0][1][2][0][RTW89_WW][13] = 0, -+ [0][1][2][1][RTW89_WW][0] = 0, -+ [0][1][2][1][RTW89_WW][1] = 0, -+ [0][1][2][1][RTW89_WW][2] = 0, -+ [0][1][2][1][RTW89_WW][3] = 0, -+ [0][1][2][1][RTW89_WW][4] = 0, -+ [0][1][2][1][RTW89_WW][5] = 0, -+ [0][1][2][1][RTW89_WW][6] = 0, -+ [0][1][2][1][RTW89_WW][7] = 0, -+ [0][1][2][1][RTW89_WW][8] = 0, -+ [0][1][2][1][RTW89_WW][9] = 0, -+ [0][1][2][1][RTW89_WW][10] = 0, -+ [0][1][2][1][RTW89_WW][11] = 0, -+ [0][1][2][1][RTW89_WW][12] = 0, -+ [0][1][2][1][RTW89_WW][13] = 0, -+ [1][0][2][0][RTW89_WW][0] = 0, -+ [1][0][2][0][RTW89_WW][1] = 0, -+ [1][0][2][0][RTW89_WW][2] = 58, -+ [1][0][2][0][RTW89_WW][3] = 58, -+ [1][0][2][0][RTW89_WW][4] = 58, -+ [1][0][2][0][RTW89_WW][5] = 58, -+ [1][0][2][0][RTW89_WW][6] = 58, -+ [1][0][2][0][RTW89_WW][7] = 58, -+ [1][0][2][0][RTW89_WW][8] = 58, -+ [1][0][2][0][RTW89_WW][9] = 58, -+ [1][0][2][0][RTW89_WW][10] = 58, -+ [1][0][2][0][RTW89_WW][11] = 0, -+ [1][0][2][0][RTW89_WW][12] = 0, -+ [1][0][2][0][RTW89_WW][13] = 0, -+ [1][1][2][0][RTW89_WW][0] = 0, -+ [1][1][2][0][RTW89_WW][1] = 0, -+ [1][1][2][0][RTW89_WW][2] = 0, -+ [1][1][2][0][RTW89_WW][3] = 0, -+ [1][1][2][0][RTW89_WW][4] = 0, -+ [1][1][2][0][RTW89_WW][5] = 0, -+ [1][1][2][0][RTW89_WW][6] = 0, -+ [1][1][2][0][RTW89_WW][7] = 0, -+ [1][1][2][0][RTW89_WW][8] = 0, -+ [1][1][2][0][RTW89_WW][9] = 0, -+ [1][1][2][0][RTW89_WW][10] = 0, -+ [1][1][2][0][RTW89_WW][11] = 0, -+ [1][1][2][0][RTW89_WW][12] = 0, -+ [1][1][2][0][RTW89_WW][13] = 0, -+ [1][1][2][1][RTW89_WW][0] = 0, -+ [1][1][2][1][RTW89_WW][1] = 0, -+ [1][1][2][1][RTW89_WW][2] = 0, -+ [1][1][2][1][RTW89_WW][3] = 0, -+ [1][1][2][1][RTW89_WW][4] = 0, -+ [1][1][2][1][RTW89_WW][5] = 0, -+ [1][1][2][1][RTW89_WW][6] = 0, -+ [1][1][2][1][RTW89_WW][7] = 0, -+ [1][1][2][1][RTW89_WW][8] = 0, -+ [1][1][2][1][RTW89_WW][9] = 0, -+ [1][1][2][1][RTW89_WW][10] = 0, -+ [1][1][2][1][RTW89_WW][11] = 0, -+ [1][1][2][1][RTW89_WW][12] = 0, -+ [1][1][2][1][RTW89_WW][13] = 0, -+ [0][0][0][0][RTW89_FCC][0] = 84, -+ [0][0][0][0][RTW89_ETSI][0] = 58, -+ [0][0][0][0][RTW89_MKK][0] = 68, -+ [0][0][0][0][RTW89_IC][0] = 84, -+ [0][0][0][0][RTW89_KCC][0] = 68, -+ [0][0][0][0][RTW89_ACMA][0] = 58, -+ [0][0][0][0][RTW89_CN][0] = 60, -+ [0][0][0][0][RTW89_UK][0] = 58, -+ [0][0][0][0][RTW89_FCC][1] = 84, -+ [0][0][0][0][RTW89_ETSI][1] = 58, -+ [0][0][0][0][RTW89_MKK][1] = 68, -+ [0][0][0][0][RTW89_IC][1] = 84, -+ [0][0][0][0][RTW89_KCC][1] = 68, -+ [0][0][0][0][RTW89_ACMA][1] = 58, -+ [0][0][0][0][RTW89_CN][1] = 60, -+ [0][0][0][0][RTW89_UK][1] = 58, -+ [0][0][0][0][RTW89_FCC][2] = 84, -+ [0][0][0][0][RTW89_ETSI][2] = 58, -+ [0][0][0][0][RTW89_MKK][2] = 68, -+ [0][0][0][0][RTW89_IC][2] = 84, -+ [0][0][0][0][RTW89_KCC][2] = 68, -+ [0][0][0][0][RTW89_ACMA][2] = 58, -+ [0][0][0][0][RTW89_CN][2] = 60, -+ [0][0][0][0][RTW89_UK][2] = 58, -+ [0][0][0][0][RTW89_FCC][3] = 84, -+ [0][0][0][0][RTW89_ETSI][3] = 58, -+ [0][0][0][0][RTW89_MKK][3] = 68, -+ [0][0][0][0][RTW89_IC][3] = 84, -+ [0][0][0][0][RTW89_KCC][3] = 68, -+ [0][0][0][0][RTW89_ACMA][3] = 58, -+ [0][0][0][0][RTW89_CN][3] = 60, -+ [0][0][0][0][RTW89_UK][3] = 58, -+ [0][0][0][0][RTW89_FCC][4] = 84, -+ [0][0][0][0][RTW89_ETSI][4] = 58, -+ [0][0][0][0][RTW89_MKK][4] = 68, -+ [0][0][0][0][RTW89_IC][4] = 84, -+ [0][0][0][0][RTW89_KCC][4] = 68, -+ [0][0][0][0][RTW89_ACMA][4] = 58, -+ [0][0][0][0][RTW89_CN][4] = 60, -+ [0][0][0][0][RTW89_UK][4] = 58, -+ [0][0][0][0][RTW89_FCC][5] = 84, -+ [0][0][0][0][RTW89_ETSI][5] = 58, -+ [0][0][0][0][RTW89_MKK][5] = 68, -+ [0][0][0][0][RTW89_IC][5] = 84, -+ [0][0][0][0][RTW89_KCC][5] = 68, -+ [0][0][0][0][RTW89_ACMA][5] = 58, -+ [0][0][0][0][RTW89_CN][5] = 60, -+ [0][0][0][0][RTW89_UK][5] = 58, -+ [0][0][0][0][RTW89_FCC][6] = 84, -+ [0][0][0][0][RTW89_ETSI][6] = 58, -+ [0][0][0][0][RTW89_MKK][6] = 68, -+ [0][0][0][0][RTW89_IC][6] = 84, -+ [0][0][0][0][RTW89_KCC][6] = 68, -+ [0][0][0][0][RTW89_ACMA][6] = 58, -+ [0][0][0][0][RTW89_CN][6] = 60, -+ [0][0][0][0][RTW89_UK][6] = 58, -+ [0][0][0][0][RTW89_FCC][7] = 84, -+ [0][0][0][0][RTW89_ETSI][7] = 58, -+ [0][0][0][0][RTW89_MKK][7] = 68, -+ [0][0][0][0][RTW89_IC][7] = 84, -+ [0][0][0][0][RTW89_KCC][7] = 68, -+ [0][0][0][0][RTW89_ACMA][7] = 58, -+ [0][0][0][0][RTW89_CN][7] = 60, -+ [0][0][0][0][RTW89_UK][7] = 58, -+ [0][0][0][0][RTW89_FCC][8] = 84, -+ [0][0][0][0][RTW89_ETSI][8] = 58, -+ [0][0][0][0][RTW89_MKK][8] = 68, -+ [0][0][0][0][RTW89_IC][8] = 84, -+ [0][0][0][0][RTW89_KCC][8] = 68, -+ [0][0][0][0][RTW89_ACMA][8] = 58, -+ [0][0][0][0][RTW89_CN][8] = 60, -+ [0][0][0][0][RTW89_UK][8] = 58, -+ [0][0][0][0][RTW89_FCC][9] = 84, -+ [0][0][0][0][RTW89_ETSI][9] = 58, -+ [0][0][0][0][RTW89_MKK][9] = 68, -+ [0][0][0][0][RTW89_IC][9] = 84, -+ [0][0][0][0][RTW89_KCC][9] = 68, -+ [0][0][0][0][RTW89_ACMA][9] = 58, -+ [0][0][0][0][RTW89_CN][9] = 60, -+ [0][0][0][0][RTW89_UK][9] = 58, -+ [0][0][0][0][RTW89_FCC][10] = 82, -+ [0][0][0][0][RTW89_ETSI][10] = 58, -+ [0][0][0][0][RTW89_MKK][10] = 68, -+ [0][0][0][0][RTW89_IC][10] = 82, -+ [0][0][0][0][RTW89_KCC][10] = 68, -+ [0][0][0][0][RTW89_ACMA][10] = 58, -+ [0][0][0][0][RTW89_CN][10] = 60, -+ [0][0][0][0][RTW89_UK][10] = 58, -+ [0][0][0][0][RTW89_FCC][11] = 62, -+ [0][0][0][0][RTW89_ETSI][11] = 58, -+ [0][0][0][0][RTW89_MKK][11] = 68, -+ [0][0][0][0][RTW89_IC][11] = 62, -+ [0][0][0][0][RTW89_KCC][11] = 68, -+ [0][0][0][0][RTW89_ACMA][11] = 58, -+ [0][0][0][0][RTW89_CN][11] = 60, -+ [0][0][0][0][RTW89_UK][11] = 58, -+ [0][0][0][0][RTW89_FCC][12] = 52, -+ [0][0][0][0][RTW89_ETSI][12] = 58, -+ [0][0][0][0][RTW89_MKK][12] = 68, -+ [0][0][0][0][RTW89_IC][12] = 52, -+ [0][0][0][0][RTW89_KCC][12] = 68, -+ [0][0][0][0][RTW89_ACMA][12] = 58, -+ [0][0][0][0][RTW89_CN][12] = 60, -+ [0][0][0][0][RTW89_UK][12] = 58, -+ [0][0][0][0][RTW89_FCC][13] = 127, -+ [0][0][0][0][RTW89_ETSI][13] = 127, -+ [0][0][0][0][RTW89_MKK][13] = 76, -+ [0][0][0][0][RTW89_IC][13] = 127, -+ [0][0][0][0][RTW89_KCC][13] = 127, -+ [0][0][0][0][RTW89_ACMA][13] = 127, -+ [0][0][0][0][RTW89_CN][13] = 127, -+ [0][0][0][0][RTW89_UK][13] = 127, -+ [0][1][0][0][RTW89_FCC][0] = 127, -+ [0][1][0][0][RTW89_ETSI][0] = 127, -+ [0][1][0][0][RTW89_MKK][0] = 127, -+ [0][1][0][0][RTW89_IC][0] = 127, -+ [0][1][0][0][RTW89_KCC][0] = 127, -+ [0][1][0][0][RTW89_ACMA][0] = 127, -+ [0][1][0][0][RTW89_CN][0] = 127, -+ [0][1][0][0][RTW89_UK][0] = 127, -+ [0][1][0][0][RTW89_FCC][1] = 127, -+ [0][1][0][0][RTW89_ETSI][1] = 127, -+ [0][1][0][0][RTW89_MKK][1] = 127, -+ [0][1][0][0][RTW89_IC][1] = 127, -+ [0][1][0][0][RTW89_KCC][1] = 127, -+ [0][1][0][0][RTW89_ACMA][1] = 127, -+ [0][1][0][0][RTW89_CN][1] = 127, -+ [0][1][0][0][RTW89_UK][1] = 127, -+ [0][1][0][0][RTW89_FCC][2] = 127, -+ [0][1][0][0][RTW89_ETSI][2] = 127, -+ [0][1][0][0][RTW89_MKK][2] = 127, -+ [0][1][0][0][RTW89_IC][2] = 127, -+ [0][1][0][0][RTW89_KCC][2] = 127, -+ [0][1][0][0][RTW89_ACMA][2] = 127, -+ [0][1][0][0][RTW89_CN][2] = 127, -+ [0][1][0][0][RTW89_UK][2] = 127, -+ [0][1][0][0][RTW89_FCC][3] = 127, -+ [0][1][0][0][RTW89_ETSI][3] = 127, -+ [0][1][0][0][RTW89_MKK][3] = 127, -+ [0][1][0][0][RTW89_IC][3] = 127, -+ [0][1][0][0][RTW89_KCC][3] = 127, -+ [0][1][0][0][RTW89_ACMA][3] = 127, -+ [0][1][0][0][RTW89_CN][3] = 127, -+ [0][1][0][0][RTW89_UK][3] = 127, -+ [0][1][0][0][RTW89_FCC][4] = 127, -+ [0][1][0][0][RTW89_ETSI][4] = 127, -+ [0][1][0][0][RTW89_MKK][4] = 127, -+ [0][1][0][0][RTW89_IC][4] = 127, -+ [0][1][0][0][RTW89_KCC][4] = 127, -+ [0][1][0][0][RTW89_ACMA][4] = 127, -+ [0][1][0][0][RTW89_CN][4] = 127, -+ [0][1][0][0][RTW89_UK][4] = 127, -+ [0][1][0][0][RTW89_FCC][5] = 127, -+ [0][1][0][0][RTW89_ETSI][5] = 127, -+ [0][1][0][0][RTW89_MKK][5] = 127, -+ [0][1][0][0][RTW89_IC][5] = 127, -+ [0][1][0][0][RTW89_KCC][5] = 127, -+ [0][1][0][0][RTW89_ACMA][5] = 127, -+ [0][1][0][0][RTW89_CN][5] = 127, -+ [0][1][0][0][RTW89_UK][5] = 127, -+ [0][1][0][0][RTW89_FCC][6] = 127, -+ [0][1][0][0][RTW89_ETSI][6] = 127, -+ [0][1][0][0][RTW89_MKK][6] = 127, -+ [0][1][0][0][RTW89_IC][6] = 127, -+ [0][1][0][0][RTW89_KCC][6] = 127, -+ [0][1][0][0][RTW89_ACMA][6] = 127, -+ [0][1][0][0][RTW89_CN][6] = 127, -+ [0][1][0][0][RTW89_UK][6] = 127, -+ [0][1][0][0][RTW89_FCC][7] = 127, -+ [0][1][0][0][RTW89_ETSI][7] = 127, -+ [0][1][0][0][RTW89_MKK][7] = 127, -+ [0][1][0][0][RTW89_IC][7] = 127, -+ [0][1][0][0][RTW89_KCC][7] = 127, -+ [0][1][0][0][RTW89_ACMA][7] = 127, -+ [0][1][0][0][RTW89_CN][7] = 127, -+ [0][1][0][0][RTW89_UK][7] = 127, -+ [0][1][0][0][RTW89_FCC][8] = 127, -+ [0][1][0][0][RTW89_ETSI][8] = 127, -+ [0][1][0][0][RTW89_MKK][8] = 127, -+ [0][1][0][0][RTW89_IC][8] = 127, -+ [0][1][0][0][RTW89_KCC][8] = 127, -+ [0][1][0][0][RTW89_ACMA][8] = 127, -+ [0][1][0][0][RTW89_CN][8] = 127, -+ [0][1][0][0][RTW89_UK][8] = 127, -+ [0][1][0][0][RTW89_FCC][9] = 127, -+ [0][1][0][0][RTW89_ETSI][9] = 127, -+ [0][1][0][0][RTW89_MKK][9] = 127, -+ [0][1][0][0][RTW89_IC][9] = 127, -+ [0][1][0][0][RTW89_KCC][9] = 127, -+ [0][1][0][0][RTW89_ACMA][9] = 127, -+ [0][1][0][0][RTW89_CN][9] = 127, -+ [0][1][0][0][RTW89_UK][9] = 127, -+ [0][1][0][0][RTW89_FCC][10] = 127, -+ [0][1][0][0][RTW89_ETSI][10] = 127, -+ [0][1][0][0][RTW89_MKK][10] = 127, -+ [0][1][0][0][RTW89_IC][10] = 127, -+ [0][1][0][0][RTW89_KCC][10] = 127, -+ [0][1][0][0][RTW89_ACMA][10] = 127, -+ [0][1][0][0][RTW89_CN][10] = 127, -+ [0][1][0][0][RTW89_UK][10] = 127, -+ [0][1][0][0][RTW89_FCC][11] = 127, -+ [0][1][0][0][RTW89_ETSI][11] = 127, -+ [0][1][0][0][RTW89_MKK][11] = 127, -+ [0][1][0][0][RTW89_IC][11] = 127, -+ [0][1][0][0][RTW89_KCC][11] = 127, -+ [0][1][0][0][RTW89_ACMA][11] = 127, -+ [0][1][0][0][RTW89_CN][11] = 127, -+ [0][1][0][0][RTW89_UK][11] = 127, -+ [0][1][0][0][RTW89_FCC][12] = 127, -+ [0][1][0][0][RTW89_ETSI][12] = 127, -+ [0][1][0][0][RTW89_MKK][12] = 127, -+ [0][1][0][0][RTW89_IC][12] = 127, -+ [0][1][0][0][RTW89_KCC][12] = 127, -+ [0][1][0][0][RTW89_ACMA][12] = 127, -+ [0][1][0][0][RTW89_CN][12] = 127, -+ [0][1][0][0][RTW89_UK][12] = 127, -+ [0][1][0][0][RTW89_FCC][13] = 127, -+ [0][1][0][0][RTW89_ETSI][13] = 127, -+ [0][1][0][0][RTW89_MKK][13] = 127, -+ [0][1][0][0][RTW89_IC][13] = 127, -+ [0][1][0][0][RTW89_KCC][13] = 127, -+ [0][1][0][0][RTW89_ACMA][13] = 127, -+ [0][1][0][0][RTW89_CN][13] = 127, -+ [0][1][0][0][RTW89_UK][13] = 127, -+ [1][0][0][0][RTW89_FCC][0] = 127, -+ [1][0][0][0][RTW89_ETSI][0] = 127, -+ [1][0][0][0][RTW89_MKK][0] = 127, -+ [1][0][0][0][RTW89_IC][0] = 127, -+ [1][0][0][0][RTW89_KCC][0] = 127, -+ [1][0][0][0][RTW89_ACMA][0] = 127, -+ [1][0][0][0][RTW89_CN][0] = 127, -+ [1][0][0][0][RTW89_UK][0] = 127, -+ [1][0][0][0][RTW89_FCC][1] = 127, -+ [1][0][0][0][RTW89_ETSI][1] = 127, -+ [1][0][0][0][RTW89_MKK][1] = 127, -+ [1][0][0][0][RTW89_IC][1] = 127, -+ [1][0][0][0][RTW89_KCC][1] = 127, -+ [1][0][0][0][RTW89_ACMA][1] = 127, -+ [1][0][0][0][RTW89_CN][1] = 127, -+ [1][0][0][0][RTW89_UK][1] = 127, -+ [1][0][0][0][RTW89_FCC][2] = 127, -+ [1][0][0][0][RTW89_ETSI][2] = 58, -+ [1][0][0][0][RTW89_MKK][2] = 70, -+ [1][0][0][0][RTW89_IC][2] = 127, -+ [1][0][0][0][RTW89_KCC][2] = 68, -+ [1][0][0][0][RTW89_ACMA][2] = 58, -+ [1][0][0][0][RTW89_CN][2] = 60, -+ [1][0][0][0][RTW89_UK][2] = 58, -+ [1][0][0][0][RTW89_FCC][3] = 127, -+ [1][0][0][0][RTW89_ETSI][3] = 58, -+ [1][0][0][0][RTW89_MKK][3] = 76, -+ [1][0][0][0][RTW89_IC][3] = 127, -+ [1][0][0][0][RTW89_KCC][3] = 68, -+ [1][0][0][0][RTW89_ACMA][3] = 58, -+ [1][0][0][0][RTW89_CN][3] = 60, -+ [1][0][0][0][RTW89_UK][3] = 58, -+ [1][0][0][0][RTW89_FCC][4] = 127, -+ [1][0][0][0][RTW89_ETSI][4] = 58, -+ [1][0][0][0][RTW89_MKK][4] = 76, -+ [1][0][0][0][RTW89_IC][4] = 127, -+ [1][0][0][0][RTW89_KCC][4] = 68, -+ [1][0][0][0][RTW89_ACMA][4] = 58, -+ [1][0][0][0][RTW89_CN][4] = 60, -+ [1][0][0][0][RTW89_UK][4] = 58, -+ [1][0][0][0][RTW89_FCC][5] = 127, -+ [1][0][0][0][RTW89_ETSI][5] = 58, -+ [1][0][0][0][RTW89_MKK][5] = 76, -+ [1][0][0][0][RTW89_IC][5] = 127, -+ [1][0][0][0][RTW89_KCC][5] = 68, -+ [1][0][0][0][RTW89_ACMA][5] = 58, -+ [1][0][0][0][RTW89_CN][5] = 60, -+ [1][0][0][0][RTW89_UK][5] = 58, -+ [1][0][0][0][RTW89_FCC][6] = 127, -+ [1][0][0][0][RTW89_ETSI][6] = 58, -+ [1][0][0][0][RTW89_MKK][6] = 76, -+ [1][0][0][0][RTW89_IC][6] = 127, -+ [1][0][0][0][RTW89_KCC][6] = 68, -+ [1][0][0][0][RTW89_ACMA][6] = 58, -+ [1][0][0][0][RTW89_CN][6] = 60, -+ [1][0][0][0][RTW89_UK][6] = 58, -+ [1][0][0][0][RTW89_FCC][7] = 127, -+ [1][0][0][0][RTW89_ETSI][7] = 58, -+ [1][0][0][0][RTW89_MKK][7] = 76, -+ [1][0][0][0][RTW89_IC][7] = 127, -+ [1][0][0][0][RTW89_KCC][7] = 68, -+ [1][0][0][0][RTW89_ACMA][7] = 58, -+ [1][0][0][0][RTW89_CN][7] = 60, -+ [1][0][0][0][RTW89_UK][7] = 58, -+ [1][0][0][0][RTW89_FCC][8] = 127, -+ [1][0][0][0][RTW89_ETSI][8] = 58, -+ [1][0][0][0][RTW89_MKK][8] = 76, -+ [1][0][0][0][RTW89_IC][8] = 127, -+ [1][0][0][0][RTW89_KCC][8] = 68, -+ [1][0][0][0][RTW89_ACMA][8] = 58, -+ [1][0][0][0][RTW89_CN][8] = 60, -+ [1][0][0][0][RTW89_UK][8] = 58, -+ [1][0][0][0][RTW89_FCC][9] = 127, -+ [1][0][0][0][RTW89_ETSI][9] = 58, -+ [1][0][0][0][RTW89_MKK][9] = 76, -+ [1][0][0][0][RTW89_IC][9] = 127, -+ [1][0][0][0][RTW89_KCC][9] = 68, -+ [1][0][0][0][RTW89_ACMA][9] = 58, -+ [1][0][0][0][RTW89_CN][9] = 60, -+ [1][0][0][0][RTW89_UK][9] = 58, -+ [1][0][0][0][RTW89_FCC][10] = 127, -+ [1][0][0][0][RTW89_ETSI][10] = 58, -+ [1][0][0][0][RTW89_MKK][10] = 66, -+ [1][0][0][0][RTW89_IC][10] = 127, -+ [1][0][0][0][RTW89_KCC][10] = 68, -+ [1][0][0][0][RTW89_ACMA][10] = 58, -+ [1][0][0][0][RTW89_CN][10] = 60, -+ [1][0][0][0][RTW89_UK][10] = 58, -+ [1][0][0][0][RTW89_FCC][11] = 127, -+ [1][0][0][0][RTW89_ETSI][11] = 127, -+ [1][0][0][0][RTW89_MKK][11] = 127, -+ [1][0][0][0][RTW89_IC][11] = 127, -+ [1][0][0][0][RTW89_KCC][11] = 127, -+ [1][0][0][0][RTW89_ACMA][11] = 127, -+ [1][0][0][0][RTW89_CN][11] = 127, -+ [1][0][0][0][RTW89_UK][11] = 127, -+ [1][0][0][0][RTW89_FCC][12] = 127, -+ [1][0][0][0][RTW89_ETSI][12] = 127, -+ [1][0][0][0][RTW89_MKK][12] = 127, -+ [1][0][0][0][RTW89_IC][12] = 127, -+ [1][0][0][0][RTW89_KCC][12] = 127, -+ [1][0][0][0][RTW89_ACMA][12] = 127, -+ [1][0][0][0][RTW89_CN][12] = 127, -+ [1][0][0][0][RTW89_UK][12] = 127, -+ [1][0][0][0][RTW89_FCC][13] = 127, -+ [1][0][0][0][RTW89_ETSI][13] = 127, -+ [1][0][0][0][RTW89_MKK][13] = 127, -+ [1][0][0][0][RTW89_IC][13] = 127, -+ [1][0][0][0][RTW89_KCC][13] = 127, -+ [1][0][0][0][RTW89_ACMA][13] = 127, -+ [1][0][0][0][RTW89_CN][13] = 127, -+ [1][0][0][0][RTW89_UK][13] = 127, -+ [1][1][0][0][RTW89_FCC][0] = 127, -+ [1][1][0][0][RTW89_ETSI][0] = 127, -+ [1][1][0][0][RTW89_MKK][0] = 127, -+ [1][1][0][0][RTW89_IC][0] = 127, -+ [1][1][0][0][RTW89_KCC][0] = 127, -+ [1][1][0][0][RTW89_ACMA][0] = 127, -+ [1][1][0][0][RTW89_CN][0] = 127, -+ [1][1][0][0][RTW89_UK][0] = 127, -+ [1][1][0][0][RTW89_FCC][1] = 127, -+ [1][1][0][0][RTW89_ETSI][1] = 127, -+ [1][1][0][0][RTW89_MKK][1] = 127, -+ [1][1][0][0][RTW89_IC][1] = 127, -+ [1][1][0][0][RTW89_KCC][1] = 127, -+ [1][1][0][0][RTW89_ACMA][1] = 127, -+ [1][1][0][0][RTW89_CN][1] = 127, -+ [1][1][0][0][RTW89_UK][1] = 127, -+ [1][1][0][0][RTW89_FCC][2] = 127, -+ [1][1][0][0][RTW89_ETSI][2] = 127, -+ [1][1][0][0][RTW89_MKK][2] = 127, -+ [1][1][0][0][RTW89_IC][2] = 127, -+ [1][1][0][0][RTW89_KCC][2] = 127, -+ [1][1][0][0][RTW89_ACMA][2] = 127, -+ [1][1][0][0][RTW89_CN][2] = 127, -+ [1][1][0][0][RTW89_UK][2] = 127, -+ [1][1][0][0][RTW89_FCC][3] = 127, -+ [1][1][0][0][RTW89_ETSI][3] = 127, -+ [1][1][0][0][RTW89_MKK][3] = 127, -+ [1][1][0][0][RTW89_IC][3] = 127, -+ [1][1][0][0][RTW89_KCC][3] = 127, -+ [1][1][0][0][RTW89_ACMA][3] = 127, -+ [1][1][0][0][RTW89_CN][3] = 127, -+ [1][1][0][0][RTW89_UK][3] = 127, -+ [1][1][0][0][RTW89_FCC][4] = 127, -+ [1][1][0][0][RTW89_ETSI][4] = 127, -+ [1][1][0][0][RTW89_MKK][4] = 127, -+ [1][1][0][0][RTW89_IC][4] = 127, -+ [1][1][0][0][RTW89_KCC][4] = 127, -+ [1][1][0][0][RTW89_ACMA][4] = 127, -+ [1][1][0][0][RTW89_CN][4] = 127, -+ [1][1][0][0][RTW89_UK][4] = 127, -+ [1][1][0][0][RTW89_FCC][5] = 127, -+ [1][1][0][0][RTW89_ETSI][5] = 127, -+ [1][1][0][0][RTW89_MKK][5] = 127, -+ [1][1][0][0][RTW89_IC][5] = 127, -+ [1][1][0][0][RTW89_KCC][5] = 127, -+ [1][1][0][0][RTW89_ACMA][5] = 127, -+ [1][1][0][0][RTW89_CN][5] = 127, -+ [1][1][0][0][RTW89_UK][5] = 127, -+ [1][1][0][0][RTW89_FCC][6] = 127, -+ [1][1][0][0][RTW89_ETSI][6] = 127, -+ [1][1][0][0][RTW89_MKK][6] = 127, -+ [1][1][0][0][RTW89_IC][6] = 127, -+ [1][1][0][0][RTW89_KCC][6] = 127, -+ [1][1][0][0][RTW89_ACMA][6] = 127, -+ [1][1][0][0][RTW89_CN][6] = 127, -+ [1][1][0][0][RTW89_UK][6] = 127, -+ [1][1][0][0][RTW89_FCC][7] = 127, -+ [1][1][0][0][RTW89_ETSI][7] = 127, -+ [1][1][0][0][RTW89_MKK][7] = 127, -+ [1][1][0][0][RTW89_IC][7] = 127, -+ [1][1][0][0][RTW89_KCC][7] = 127, -+ [1][1][0][0][RTW89_ACMA][7] = 127, -+ [1][1][0][0][RTW89_CN][7] = 127, -+ [1][1][0][0][RTW89_UK][7] = 127, -+ [1][1][0][0][RTW89_FCC][8] = 127, -+ [1][1][0][0][RTW89_ETSI][8] = 127, -+ [1][1][0][0][RTW89_MKK][8] = 127, -+ [1][1][0][0][RTW89_IC][8] = 127, -+ [1][1][0][0][RTW89_KCC][8] = 127, -+ [1][1][0][0][RTW89_ACMA][8] = 127, -+ [1][1][0][0][RTW89_CN][8] = 127, -+ [1][1][0][0][RTW89_UK][8] = 127, -+ [1][1][0][0][RTW89_FCC][9] = 127, -+ [1][1][0][0][RTW89_ETSI][9] = 127, -+ [1][1][0][0][RTW89_MKK][9] = 127, -+ [1][1][0][0][RTW89_IC][9] = 127, -+ [1][1][0][0][RTW89_KCC][9] = 127, -+ [1][1][0][0][RTW89_ACMA][9] = 127, -+ [1][1][0][0][RTW89_CN][9] = 127, -+ [1][1][0][0][RTW89_UK][9] = 127, -+ [1][1][0][0][RTW89_FCC][10] = 127, -+ [1][1][0][0][RTW89_ETSI][10] = 127, -+ [1][1][0][0][RTW89_MKK][10] = 127, -+ [1][1][0][0][RTW89_IC][10] = 127, -+ [1][1][0][0][RTW89_KCC][10] = 127, -+ [1][1][0][0][RTW89_ACMA][10] = 127, -+ [1][1][0][0][RTW89_CN][10] = 127, -+ [1][1][0][0][RTW89_UK][10] = 127, -+ [1][1][0][0][RTW89_FCC][11] = 127, -+ [1][1][0][0][RTW89_ETSI][11] = 127, -+ [1][1][0][0][RTW89_MKK][11] = 127, -+ [1][1][0][0][RTW89_IC][11] = 127, -+ [1][1][0][0][RTW89_KCC][11] = 127, -+ [1][1][0][0][RTW89_ACMA][11] = 127, -+ [1][1][0][0][RTW89_CN][11] = 127, -+ [1][1][0][0][RTW89_UK][11] = 127, -+ [1][1][0][0][RTW89_FCC][12] = 127, -+ [1][1][0][0][RTW89_ETSI][12] = 127, -+ [1][1][0][0][RTW89_MKK][12] = 127, -+ [1][1][0][0][RTW89_IC][12] = 127, -+ [1][1][0][0][RTW89_KCC][12] = 127, -+ [1][1][0][0][RTW89_ACMA][12] = 127, -+ [1][1][0][0][RTW89_CN][12] = 127, -+ [1][1][0][0][RTW89_UK][12] = 127, -+ [1][1][0][0][RTW89_FCC][13] = 127, -+ [1][1][0][0][RTW89_ETSI][13] = 127, -+ [1][1][0][0][RTW89_MKK][13] = 127, -+ [1][1][0][0][RTW89_IC][13] = 127, -+ [1][1][0][0][RTW89_KCC][13] = 127, -+ [1][1][0][0][RTW89_ACMA][13] = 127, -+ [1][1][0][0][RTW89_CN][13] = 127, -+ [1][1][0][0][RTW89_UK][13] = 127, -+ [0][0][1][0][RTW89_FCC][0] = 80, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 72, -+ [0][0][1][0][RTW89_IC][0] = 80, -+ [0][0][1][0][RTW89_KCC][0] = 78, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CN][0] = 60, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][1] = 80, -+ [0][0][1][0][RTW89_ETSI][1] = 60, -+ [0][0][1][0][RTW89_MKK][1] = 74, -+ [0][0][1][0][RTW89_IC][1] = 80, -+ [0][0][1][0][RTW89_KCC][1] = 78, -+ [0][0][1][0][RTW89_ACMA][1] = 60, -+ [0][0][1][0][RTW89_CN][1] = 60, -+ [0][0][1][0][RTW89_UK][1] = 60, -+ [0][0][1][0][RTW89_FCC][2] = 84, -+ [0][0][1][0][RTW89_ETSI][2] = 60, -+ [0][0][1][0][RTW89_MKK][2] = 74, -+ [0][0][1][0][RTW89_IC][2] = 84, -+ [0][0][1][0][RTW89_KCC][2] = 78, -+ [0][0][1][0][RTW89_ACMA][2] = 60, -+ [0][0][1][0][RTW89_CN][2] = 60, -+ [0][0][1][0][RTW89_UK][2] = 60, -+ [0][0][1][0][RTW89_FCC][3] = 84, -+ [0][0][1][0][RTW89_ETSI][3] = 60, -+ [0][0][1][0][RTW89_MKK][3] = 74, -+ [0][0][1][0][RTW89_IC][3] = 84, -+ [0][0][1][0][RTW89_KCC][3] = 78, -+ [0][0][1][0][RTW89_ACMA][3] = 60, -+ [0][0][1][0][RTW89_CN][3] = 60, -+ [0][0][1][0][RTW89_UK][3] = 60, -+ [0][0][1][0][RTW89_FCC][4] = 84, -+ [0][0][1][0][RTW89_ETSI][4] = 60, -+ [0][0][1][0][RTW89_MKK][4] = 74, -+ [0][0][1][0][RTW89_IC][4] = 84, -+ [0][0][1][0][RTW89_KCC][4] = 76, -+ [0][0][1][0][RTW89_ACMA][4] = 60, -+ [0][0][1][0][RTW89_CN][4] = 60, -+ [0][0][1][0][RTW89_UK][4] = 60, -+ [0][0][1][0][RTW89_FCC][5] = 84, -+ [0][0][1][0][RTW89_ETSI][5] = 60, -+ [0][0][1][0][RTW89_MKK][5] = 74, -+ [0][0][1][0][RTW89_IC][5] = 84, -+ [0][0][1][0][RTW89_KCC][5] = 76, -+ [0][0][1][0][RTW89_ACMA][5] = 60, -+ [0][0][1][0][RTW89_CN][5] = 60, -+ [0][0][1][0][RTW89_UK][5] = 60, -+ [0][0][1][0][RTW89_FCC][6] = 84, -+ [0][0][1][0][RTW89_ETSI][6] = 60, -+ [0][0][1][0][RTW89_MKK][6] = 74, -+ [0][0][1][0][RTW89_IC][6] = 84, -+ [0][0][1][0][RTW89_KCC][6] = 76, -+ [0][0][1][0][RTW89_ACMA][6] = 60, -+ [0][0][1][0][RTW89_CN][6] = 60, -+ [0][0][1][0][RTW89_UK][6] = 60, -+ [0][0][1][0][RTW89_FCC][7] = 84, -+ [0][0][1][0][RTW89_ETSI][7] = 60, -+ [0][0][1][0][RTW89_MKK][7] = 74, -+ [0][0][1][0][RTW89_IC][7] = 84, -+ [0][0][1][0][RTW89_KCC][7] = 76, -+ [0][0][1][0][RTW89_ACMA][7] = 60, -+ [0][0][1][0][RTW89_CN][7] = 60, -+ [0][0][1][0][RTW89_UK][7] = 60, -+ [0][0][1][0][RTW89_FCC][8] = 80, -+ [0][0][1][0][RTW89_ETSI][8] = 60, -+ [0][0][1][0][RTW89_MKK][8] = 74, -+ [0][0][1][0][RTW89_IC][8] = 80, -+ [0][0][1][0][RTW89_KCC][8] = 76, -+ [0][0][1][0][RTW89_ACMA][8] = 60, -+ [0][0][1][0][RTW89_CN][8] = 60, -+ [0][0][1][0][RTW89_UK][8] = 60, -+ [0][0][1][0][RTW89_FCC][9] = 76, -+ [0][0][1][0][RTW89_ETSI][9] = 60, -+ [0][0][1][0][RTW89_MKK][9] = 74, -+ [0][0][1][0][RTW89_IC][9] = 76, -+ [0][0][1][0][RTW89_KCC][9] = 74, -+ [0][0][1][0][RTW89_ACMA][9] = 60, -+ [0][0][1][0][RTW89_CN][9] = 60, -+ [0][0][1][0][RTW89_UK][9] = 60, -+ [0][0][1][0][RTW89_FCC][10] = 76, -+ [0][0][1][0][RTW89_ETSI][10] = 60, -+ [0][0][1][0][RTW89_MKK][10] = 74, -+ [0][0][1][0][RTW89_IC][10] = 76, -+ [0][0][1][0][RTW89_KCC][10] = 74, -+ [0][0][1][0][RTW89_ACMA][10] = 60, -+ [0][0][1][0][RTW89_CN][10] = 60, -+ [0][0][1][0][RTW89_UK][10] = 60, -+ [0][0][1][0][RTW89_FCC][11] = 68, -+ [0][0][1][0][RTW89_ETSI][11] = 60, -+ [0][0][1][0][RTW89_MKK][11] = 74, -+ [0][0][1][0][RTW89_IC][11] = 68, -+ [0][0][1][0][RTW89_KCC][11] = 74, -+ [0][0][1][0][RTW89_ACMA][11] = 60, -+ [0][0][1][0][RTW89_CN][11] = 60, -+ [0][0][1][0][RTW89_UK][11] = 60, -+ [0][0][1][0][RTW89_FCC][12] = 64, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 70, -+ [0][0][1][0][RTW89_IC][12] = 64, -+ [0][0][1][0][RTW89_KCC][12] = 74, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CN][12] = 60, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][13] = 127, -+ [0][0][1][0][RTW89_ETSI][13] = 127, -+ [0][0][1][0][RTW89_MKK][13] = 127, -+ [0][0][1][0][RTW89_IC][13] = 127, -+ [0][0][1][0][RTW89_KCC][13] = 127, -+ [0][0][1][0][RTW89_ACMA][13] = 127, -+ [0][0][1][0][RTW89_CN][13] = 127, -+ [0][0][1][0][RTW89_UK][13] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 127, -+ [0][1][1][0][RTW89_ETSI][0] = 127, -+ [0][1][1][0][RTW89_MKK][0] = 127, -+ [0][1][1][0][RTW89_IC][0] = 127, -+ [0][1][1][0][RTW89_KCC][0] = 127, -+ [0][1][1][0][RTW89_ACMA][0] = 127, -+ [0][1][1][0][RTW89_CN][0] = 127, -+ [0][1][1][0][RTW89_UK][0] = 127, -+ [0][1][1][0][RTW89_FCC][1] = 127, -+ [0][1][1][0][RTW89_ETSI][1] = 127, -+ [0][1][1][0][RTW89_MKK][1] = 127, -+ [0][1][1][0][RTW89_IC][1] = 127, -+ [0][1][1][0][RTW89_KCC][1] = 127, -+ [0][1][1][0][RTW89_ACMA][1] = 127, -+ [0][1][1][0][RTW89_CN][1] = 127, -+ [0][1][1][0][RTW89_UK][1] = 127, -+ [0][1][1][0][RTW89_FCC][2] = 127, -+ [0][1][1][0][RTW89_ETSI][2] = 127, -+ [0][1][1][0][RTW89_MKK][2] = 127, -+ [0][1][1][0][RTW89_IC][2] = 127, -+ [0][1][1][0][RTW89_KCC][2] = 127, -+ [0][1][1][0][RTW89_ACMA][2] = 127, -+ [0][1][1][0][RTW89_CN][2] = 127, -+ [0][1][1][0][RTW89_UK][2] = 127, -+ [0][1][1][0][RTW89_FCC][3] = 127, -+ [0][1][1][0][RTW89_ETSI][3] = 127, -+ [0][1][1][0][RTW89_MKK][3] = 127, -+ [0][1][1][0][RTW89_IC][3] = 127, -+ [0][1][1][0][RTW89_KCC][3] = 127, -+ [0][1][1][0][RTW89_ACMA][3] = 127, -+ [0][1][1][0][RTW89_CN][3] = 127, -+ [0][1][1][0][RTW89_UK][3] = 127, -+ [0][1][1][0][RTW89_FCC][4] = 127, -+ [0][1][1][0][RTW89_ETSI][4] = 127, -+ [0][1][1][0][RTW89_MKK][4] = 127, -+ [0][1][1][0][RTW89_IC][4] = 127, -+ [0][1][1][0][RTW89_KCC][4] = 127, -+ [0][1][1][0][RTW89_ACMA][4] = 127, -+ [0][1][1][0][RTW89_CN][4] = 127, -+ [0][1][1][0][RTW89_UK][4] = 127, -+ [0][1][1][0][RTW89_FCC][5] = 127, -+ [0][1][1][0][RTW89_ETSI][5] = 127, -+ [0][1][1][0][RTW89_MKK][5] = 127, -+ [0][1][1][0][RTW89_IC][5] = 127, -+ [0][1][1][0][RTW89_KCC][5] = 127, -+ [0][1][1][0][RTW89_ACMA][5] = 127, -+ [0][1][1][0][RTW89_CN][5] = 127, -+ [0][1][1][0][RTW89_UK][5] = 127, -+ [0][1][1][0][RTW89_FCC][6] = 127, -+ [0][1][1][0][RTW89_ETSI][6] = 127, -+ [0][1][1][0][RTW89_MKK][6] = 127, -+ [0][1][1][0][RTW89_IC][6] = 127, -+ [0][1][1][0][RTW89_KCC][6] = 127, -+ [0][1][1][0][RTW89_ACMA][6] = 127, -+ [0][1][1][0][RTW89_CN][6] = 127, -+ [0][1][1][0][RTW89_UK][6] = 127, -+ [0][1][1][0][RTW89_FCC][7] = 127, -+ [0][1][1][0][RTW89_ETSI][7] = 127, -+ [0][1][1][0][RTW89_MKK][7] = 127, -+ [0][1][1][0][RTW89_IC][7] = 127, -+ [0][1][1][0][RTW89_KCC][7] = 127, -+ [0][1][1][0][RTW89_ACMA][7] = 127, -+ [0][1][1][0][RTW89_CN][7] = 127, -+ [0][1][1][0][RTW89_UK][7] = 127, -+ [0][1][1][0][RTW89_FCC][8] = 127, -+ [0][1][1][0][RTW89_ETSI][8] = 127, -+ [0][1][1][0][RTW89_MKK][8] = 127, -+ [0][1][1][0][RTW89_IC][8] = 127, -+ [0][1][1][0][RTW89_KCC][8] = 127, -+ [0][1][1][0][RTW89_ACMA][8] = 127, -+ [0][1][1][0][RTW89_CN][8] = 127, -+ [0][1][1][0][RTW89_UK][8] = 127, -+ [0][1][1][0][RTW89_FCC][9] = 127, -+ [0][1][1][0][RTW89_ETSI][9] = 127, -+ [0][1][1][0][RTW89_MKK][9] = 127, -+ [0][1][1][0][RTW89_IC][9] = 127, -+ [0][1][1][0][RTW89_KCC][9] = 127, -+ [0][1][1][0][RTW89_ACMA][9] = 127, -+ [0][1][1][0][RTW89_CN][9] = 127, -+ [0][1][1][0][RTW89_UK][9] = 127, -+ [0][1][1][0][RTW89_FCC][10] = 127, -+ [0][1][1][0][RTW89_ETSI][10] = 127, -+ [0][1][1][0][RTW89_MKK][10] = 127, -+ [0][1][1][0][RTW89_IC][10] = 127, -+ [0][1][1][0][RTW89_KCC][10] = 127, -+ [0][1][1][0][RTW89_ACMA][10] = 127, -+ [0][1][1][0][RTW89_CN][10] = 127, -+ [0][1][1][0][RTW89_UK][10] = 127, -+ [0][1][1][0][RTW89_FCC][11] = 127, -+ [0][1][1][0][RTW89_ETSI][11] = 127, -+ [0][1][1][0][RTW89_MKK][11] = 127, -+ [0][1][1][0][RTW89_IC][11] = 127, -+ [0][1][1][0][RTW89_KCC][11] = 127, -+ [0][1][1][0][RTW89_ACMA][11] = 127, -+ [0][1][1][0][RTW89_CN][11] = 127, -+ [0][1][1][0][RTW89_UK][11] = 127, -+ [0][1][1][0][RTW89_FCC][12] = 127, -+ [0][1][1][0][RTW89_ETSI][12] = 127, -+ [0][1][1][0][RTW89_MKK][12] = 127, -+ [0][1][1][0][RTW89_IC][12] = 127, -+ [0][1][1][0][RTW89_KCC][12] = 127, -+ [0][1][1][0][RTW89_ACMA][12] = 127, -+ [0][1][1][0][RTW89_CN][12] = 127, -+ [0][1][1][0][RTW89_UK][12] = 127, -+ [0][1][1][0][RTW89_FCC][13] = 127, -+ [0][1][1][0][RTW89_ETSI][13] = 127, -+ [0][1][1][0][RTW89_MKK][13] = 127, -+ [0][1][1][0][RTW89_IC][13] = 127, -+ [0][1][1][0][RTW89_KCC][13] = 127, -+ [0][1][1][0][RTW89_ACMA][13] = 127, -+ [0][1][1][0][RTW89_CN][13] = 127, -+ [0][1][1][0][RTW89_UK][13] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 78, -+ [0][0][2][0][RTW89_ETSI][0] = 60, -+ [0][0][2][0][RTW89_MKK][0] = 72, -+ [0][0][2][0][RTW89_IC][0] = 78, -+ [0][0][2][0][RTW89_KCC][0] = 78, -+ [0][0][2][0][RTW89_ACMA][0] = 60, -+ [0][0][2][0][RTW89_CN][0] = 60, -+ [0][0][2][0][RTW89_UK][0] = 60, -+ [0][0][2][0][RTW89_FCC][1] = 78, -+ [0][0][2][0][RTW89_ETSI][1] = 60, -+ [0][0][2][0][RTW89_MKK][1] = 78, -+ [0][0][2][0][RTW89_IC][1] = 78, -+ [0][0][2][0][RTW89_KCC][1] = 78, -+ [0][0][2][0][RTW89_ACMA][1] = 60, -+ [0][0][2][0][RTW89_CN][1] = 60, -+ [0][0][2][0][RTW89_UK][1] = 60, -+ [0][0][2][0][RTW89_FCC][2] = 82, -+ [0][0][2][0][RTW89_ETSI][2] = 60, -+ [0][0][2][0][RTW89_MKK][2] = 78, -+ [0][0][2][0][RTW89_IC][2] = 82, -+ [0][0][2][0][RTW89_KCC][2] = 78, -+ [0][0][2][0][RTW89_ACMA][2] = 60, -+ [0][0][2][0][RTW89_CN][2] = 60, -+ [0][0][2][0][RTW89_UK][2] = 60, -+ [0][0][2][0][RTW89_FCC][3] = 82, -+ [0][0][2][0][RTW89_ETSI][3] = 60, -+ [0][0][2][0][RTW89_MKK][3] = 78, -+ [0][0][2][0][RTW89_IC][3] = 82, -+ [0][0][2][0][RTW89_KCC][3] = 78, -+ [0][0][2][0][RTW89_ACMA][3] = 60, -+ [0][0][2][0][RTW89_CN][3] = 60, -+ [0][0][2][0][RTW89_UK][3] = 60, -+ [0][0][2][0][RTW89_FCC][4] = 82, -+ [0][0][2][0][RTW89_ETSI][4] = 60, -+ [0][0][2][0][RTW89_MKK][4] = 78, -+ [0][0][2][0][RTW89_IC][4] = 82, -+ [0][0][2][0][RTW89_KCC][4] = 78, -+ [0][0][2][0][RTW89_ACMA][4] = 60, -+ [0][0][2][0][RTW89_CN][4] = 60, -+ [0][0][2][0][RTW89_UK][4] = 60, -+ [0][0][2][0][RTW89_FCC][5] = 82, -+ [0][0][2][0][RTW89_ETSI][5] = 60, -+ [0][0][2][0][RTW89_MKK][5] = 78, -+ [0][0][2][0][RTW89_IC][5] = 82, -+ [0][0][2][0][RTW89_KCC][5] = 78, -+ [0][0][2][0][RTW89_ACMA][5] = 60, -+ [0][0][2][0][RTW89_CN][5] = 60, -+ [0][0][2][0][RTW89_UK][5] = 60, -+ [0][0][2][0][RTW89_FCC][6] = 82, -+ [0][0][2][0][RTW89_ETSI][6] = 60, -+ [0][0][2][0][RTW89_MKK][6] = 78, -+ [0][0][2][0][RTW89_IC][6] = 82, -+ [0][0][2][0][RTW89_KCC][6] = 78, -+ [0][0][2][0][RTW89_ACMA][6] = 60, -+ [0][0][2][0][RTW89_CN][6] = 60, -+ [0][0][2][0][RTW89_UK][6] = 60, -+ [0][0][2][0][RTW89_FCC][7] = 82, -+ [0][0][2][0][RTW89_ETSI][7] = 60, -+ [0][0][2][0][RTW89_MKK][7] = 78, -+ [0][0][2][0][RTW89_IC][7] = 82, -+ [0][0][2][0][RTW89_KCC][7] = 78, -+ [0][0][2][0][RTW89_ACMA][7] = 60, -+ [0][0][2][0][RTW89_CN][7] = 60, -+ [0][0][2][0][RTW89_UK][7] = 60, -+ [0][0][2][0][RTW89_FCC][8] = 80, -+ [0][0][2][0][RTW89_ETSI][8] = 60, -+ [0][0][2][0][RTW89_MKK][8] = 78, -+ [0][0][2][0][RTW89_IC][8] = 80, -+ [0][0][2][0][RTW89_KCC][8] = 78, -+ [0][0][2][0][RTW89_ACMA][8] = 60, -+ [0][0][2][0][RTW89_CN][8] = 60, -+ [0][0][2][0][RTW89_UK][8] = 60, -+ [0][0][2][0][RTW89_FCC][9] = 76, -+ [0][0][2][0][RTW89_ETSI][9] = 60, -+ [0][0][2][0][RTW89_MKK][9] = 78, -+ [0][0][2][0][RTW89_IC][9] = 76, -+ [0][0][2][0][RTW89_KCC][9] = 78, -+ [0][0][2][0][RTW89_ACMA][9] = 60, -+ [0][0][2][0][RTW89_CN][9] = 60, -+ [0][0][2][0][RTW89_UK][9] = 60, -+ [0][0][2][0][RTW89_FCC][10] = 76, -+ [0][0][2][0][RTW89_ETSI][10] = 60, -+ [0][0][2][0][RTW89_MKK][10] = 78, -+ [0][0][2][0][RTW89_IC][10] = 76, -+ [0][0][2][0][RTW89_KCC][10] = 78, -+ [0][0][2][0][RTW89_ACMA][10] = 60, -+ [0][0][2][0][RTW89_CN][10] = 60, -+ [0][0][2][0][RTW89_UK][10] = 60, -+ [0][0][2][0][RTW89_FCC][11] = 70, -+ [0][0][2][0][RTW89_ETSI][11] = 60, -+ [0][0][2][0][RTW89_MKK][11] = 78, -+ [0][0][2][0][RTW89_IC][11] = 70, -+ [0][0][2][0][RTW89_KCC][11] = 78, -+ [0][0][2][0][RTW89_ACMA][11] = 60, -+ [0][0][2][0][RTW89_CN][11] = 60, -+ [0][0][2][0][RTW89_UK][11] = 60, -+ [0][0][2][0][RTW89_FCC][12] = 70, -+ [0][0][2][0][RTW89_ETSI][12] = 60, -+ [0][0][2][0][RTW89_MKK][12] = 70, -+ [0][0][2][0][RTW89_IC][12] = 70, -+ [0][0][2][0][RTW89_KCC][12] = 78, -+ [0][0][2][0][RTW89_ACMA][12] = 60, -+ [0][0][2][0][RTW89_CN][12] = 60, -+ [0][0][2][0][RTW89_UK][12] = 60, -+ [0][0][2][0][RTW89_FCC][13] = 127, -+ [0][0][2][0][RTW89_ETSI][13] = 127, -+ [0][0][2][0][RTW89_MKK][13] = 127, -+ [0][0][2][0][RTW89_IC][13] = 127, -+ [0][0][2][0][RTW89_KCC][13] = 127, -+ [0][0][2][0][RTW89_ACMA][13] = 127, -+ [0][0][2][0][RTW89_CN][13] = 127, -+ [0][0][2][0][RTW89_UK][13] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 127, -+ [0][1][2][0][RTW89_ETSI][0] = 127, -+ [0][1][2][0][RTW89_MKK][0] = 127, -+ [0][1][2][0][RTW89_IC][0] = 127, -+ [0][1][2][0][RTW89_KCC][0] = 127, -+ [0][1][2][0][RTW89_ACMA][0] = 127, -+ [0][1][2][0][RTW89_CN][0] = 127, -+ [0][1][2][0][RTW89_UK][0] = 127, -+ [0][1][2][0][RTW89_FCC][1] = 127, -+ [0][1][2][0][RTW89_ETSI][1] = 127, -+ [0][1][2][0][RTW89_MKK][1] = 127, -+ [0][1][2][0][RTW89_IC][1] = 127, -+ [0][1][2][0][RTW89_KCC][1] = 127, -+ [0][1][2][0][RTW89_ACMA][1] = 127, -+ [0][1][2][0][RTW89_CN][1] = 127, -+ [0][1][2][0][RTW89_UK][1] = 127, -+ [0][1][2][0][RTW89_FCC][2] = 127, -+ [0][1][2][0][RTW89_ETSI][2] = 127, -+ [0][1][2][0][RTW89_MKK][2] = 127, -+ [0][1][2][0][RTW89_IC][2] = 127, -+ [0][1][2][0][RTW89_KCC][2] = 127, -+ [0][1][2][0][RTW89_ACMA][2] = 127, -+ [0][1][2][0][RTW89_CN][2] = 127, -+ [0][1][2][0][RTW89_UK][2] = 127, -+ [0][1][2][0][RTW89_FCC][3] = 127, -+ [0][1][2][0][RTW89_ETSI][3] = 127, -+ [0][1][2][0][RTW89_MKK][3] = 127, -+ [0][1][2][0][RTW89_IC][3] = 127, -+ [0][1][2][0][RTW89_KCC][3] = 127, -+ [0][1][2][0][RTW89_ACMA][3] = 127, -+ [0][1][2][0][RTW89_CN][3] = 127, -+ [0][1][2][0][RTW89_UK][3] = 127, -+ [0][1][2][0][RTW89_FCC][4] = 127, -+ [0][1][2][0][RTW89_ETSI][4] = 127, -+ [0][1][2][0][RTW89_MKK][4] = 127, -+ [0][1][2][0][RTW89_IC][4] = 127, -+ [0][1][2][0][RTW89_KCC][4] = 127, -+ [0][1][2][0][RTW89_ACMA][4] = 127, -+ [0][1][2][0][RTW89_CN][4] = 127, -+ [0][1][2][0][RTW89_UK][4] = 127, -+ [0][1][2][0][RTW89_FCC][5] = 127, -+ [0][1][2][0][RTW89_ETSI][5] = 127, -+ [0][1][2][0][RTW89_MKK][5] = 127, -+ [0][1][2][0][RTW89_IC][5] = 127, -+ [0][1][2][0][RTW89_KCC][5] = 127, -+ [0][1][2][0][RTW89_ACMA][5] = 127, -+ [0][1][2][0][RTW89_CN][5] = 127, -+ [0][1][2][0][RTW89_UK][5] = 127, -+ [0][1][2][0][RTW89_FCC][6] = 127, -+ [0][1][2][0][RTW89_ETSI][6] = 127, -+ [0][1][2][0][RTW89_MKK][6] = 127, -+ [0][1][2][0][RTW89_IC][6] = 127, -+ [0][1][2][0][RTW89_KCC][6] = 127, -+ [0][1][2][0][RTW89_ACMA][6] = 127, -+ [0][1][2][0][RTW89_CN][6] = 127, -+ [0][1][2][0][RTW89_UK][6] = 127, -+ [0][1][2][0][RTW89_FCC][7] = 127, -+ [0][1][2][0][RTW89_ETSI][7] = 127, -+ [0][1][2][0][RTW89_MKK][7] = 127, -+ [0][1][2][0][RTW89_IC][7] = 127, -+ [0][1][2][0][RTW89_KCC][7] = 127, -+ [0][1][2][0][RTW89_ACMA][7] = 127, -+ [0][1][2][0][RTW89_CN][7] = 127, -+ [0][1][2][0][RTW89_UK][7] = 127, -+ [0][1][2][0][RTW89_FCC][8] = 127, -+ [0][1][2][0][RTW89_ETSI][8] = 127, -+ [0][1][2][0][RTW89_MKK][8] = 127, -+ [0][1][2][0][RTW89_IC][8] = 127, -+ [0][1][2][0][RTW89_KCC][8] = 127, -+ [0][1][2][0][RTW89_ACMA][8] = 127, -+ [0][1][2][0][RTW89_CN][8] = 127, -+ [0][1][2][0][RTW89_UK][8] = 127, -+ [0][1][2][0][RTW89_FCC][9] = 127, -+ [0][1][2][0][RTW89_ETSI][9] = 127, -+ [0][1][2][0][RTW89_MKK][9] = 127, -+ [0][1][2][0][RTW89_IC][9] = 127, -+ [0][1][2][0][RTW89_KCC][9] = 127, -+ [0][1][2][0][RTW89_ACMA][9] = 127, -+ [0][1][2][0][RTW89_CN][9] = 127, -+ [0][1][2][0][RTW89_UK][9] = 127, -+ [0][1][2][0][RTW89_FCC][10] = 127, -+ [0][1][2][0][RTW89_ETSI][10] = 127, -+ [0][1][2][0][RTW89_MKK][10] = 127, -+ [0][1][2][0][RTW89_IC][10] = 127, -+ [0][1][2][0][RTW89_KCC][10] = 127, -+ [0][1][2][0][RTW89_ACMA][10] = 127, -+ [0][1][2][0][RTW89_CN][10] = 127, -+ [0][1][2][0][RTW89_UK][10] = 127, -+ [0][1][2][0][RTW89_FCC][11] = 127, -+ [0][1][2][0][RTW89_ETSI][11] = 127, -+ [0][1][2][0][RTW89_MKK][11] = 127, -+ [0][1][2][0][RTW89_IC][11] = 127, -+ [0][1][2][0][RTW89_KCC][11] = 127, -+ [0][1][2][0][RTW89_ACMA][11] = 127, -+ [0][1][2][0][RTW89_CN][11] = 127, -+ [0][1][2][0][RTW89_UK][11] = 127, -+ [0][1][2][0][RTW89_FCC][12] = 127, -+ [0][1][2][0][RTW89_ETSI][12] = 127, -+ [0][1][2][0][RTW89_MKK][12] = 127, -+ [0][1][2][0][RTW89_IC][12] = 127, -+ [0][1][2][0][RTW89_KCC][12] = 127, -+ [0][1][2][0][RTW89_ACMA][12] = 127, -+ [0][1][2][0][RTW89_CN][12] = 127, -+ [0][1][2][0][RTW89_UK][12] = 127, -+ [0][1][2][0][RTW89_FCC][13] = 127, -+ [0][1][2][0][RTW89_ETSI][13] = 127, -+ [0][1][2][0][RTW89_MKK][13] = 127, -+ [0][1][2][0][RTW89_IC][13] = 127, -+ [0][1][2][0][RTW89_KCC][13] = 127, -+ [0][1][2][0][RTW89_ACMA][13] = 127, -+ [0][1][2][0][RTW89_CN][13] = 127, -+ [0][1][2][0][RTW89_UK][13] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 127, -+ [0][1][2][1][RTW89_ETSI][0] = 127, -+ [0][1][2][1][RTW89_MKK][0] = 127, -+ [0][1][2][1][RTW89_IC][0] = 127, -+ [0][1][2][1][RTW89_KCC][0] = 127, -+ [0][1][2][1][RTW89_ACMA][0] = 127, -+ [0][1][2][1][RTW89_CN][0] = 127, -+ [0][1][2][1][RTW89_UK][0] = 127, -+ [0][1][2][1][RTW89_FCC][1] = 127, -+ [0][1][2][1][RTW89_ETSI][1] = 127, -+ [0][1][2][1][RTW89_MKK][1] = 127, -+ [0][1][2][1][RTW89_IC][1] = 127, -+ [0][1][2][1][RTW89_KCC][1] = 127, -+ [0][1][2][1][RTW89_ACMA][1] = 127, -+ [0][1][2][1][RTW89_CN][1] = 127, -+ [0][1][2][1][RTW89_UK][1] = 127, -+ [0][1][2][1][RTW89_FCC][2] = 127, -+ [0][1][2][1][RTW89_ETSI][2] = 127, -+ [0][1][2][1][RTW89_MKK][2] = 127, -+ [0][1][2][1][RTW89_IC][2] = 127, -+ [0][1][2][1][RTW89_KCC][2] = 127, -+ [0][1][2][1][RTW89_ACMA][2] = 127, -+ [0][1][2][1][RTW89_CN][2] = 127, -+ [0][1][2][1][RTW89_UK][2] = 127, -+ [0][1][2][1][RTW89_FCC][3] = 127, -+ [0][1][2][1][RTW89_ETSI][3] = 127, -+ [0][1][2][1][RTW89_MKK][3] = 127, -+ [0][1][2][1][RTW89_IC][3] = 127, -+ [0][1][2][1][RTW89_KCC][3] = 127, -+ [0][1][2][1][RTW89_ACMA][3] = 127, -+ [0][1][2][1][RTW89_CN][3] = 127, -+ [0][1][2][1][RTW89_UK][3] = 127, -+ [0][1][2][1][RTW89_FCC][4] = 127, -+ [0][1][2][1][RTW89_ETSI][4] = 127, -+ [0][1][2][1][RTW89_MKK][4] = 127, -+ [0][1][2][1][RTW89_IC][4] = 127, -+ [0][1][2][1][RTW89_KCC][4] = 127, -+ [0][1][2][1][RTW89_ACMA][4] = 127, -+ [0][1][2][1][RTW89_CN][4] = 127, -+ [0][1][2][1][RTW89_UK][4] = 127, -+ [0][1][2][1][RTW89_FCC][5] = 127, -+ [0][1][2][1][RTW89_ETSI][5] = 127, -+ [0][1][2][1][RTW89_MKK][5] = 127, -+ [0][1][2][1][RTW89_IC][5] = 127, -+ [0][1][2][1][RTW89_KCC][5] = 127, -+ [0][1][2][1][RTW89_ACMA][5] = 127, -+ [0][1][2][1][RTW89_CN][5] = 127, -+ [0][1][2][1][RTW89_UK][5] = 127, -+ [0][1][2][1][RTW89_FCC][6] = 127, -+ [0][1][2][1][RTW89_ETSI][6] = 127, -+ [0][1][2][1][RTW89_MKK][6] = 127, -+ [0][1][2][1][RTW89_IC][6] = 127, -+ [0][1][2][1][RTW89_KCC][6] = 127, -+ [0][1][2][1][RTW89_ACMA][6] = 127, -+ [0][1][2][1][RTW89_CN][6] = 127, -+ [0][1][2][1][RTW89_UK][6] = 127, -+ [0][1][2][1][RTW89_FCC][7] = 127, -+ [0][1][2][1][RTW89_ETSI][7] = 127, -+ [0][1][2][1][RTW89_MKK][7] = 127, -+ [0][1][2][1][RTW89_IC][7] = 127, -+ [0][1][2][1][RTW89_KCC][7] = 127, -+ [0][1][2][1][RTW89_ACMA][7] = 127, -+ [0][1][2][1][RTW89_CN][7] = 127, -+ [0][1][2][1][RTW89_UK][7] = 127, -+ [0][1][2][1][RTW89_FCC][8] = 127, -+ [0][1][2][1][RTW89_ETSI][8] = 127, -+ [0][1][2][1][RTW89_MKK][8] = 127, -+ [0][1][2][1][RTW89_IC][8] = 127, -+ [0][1][2][1][RTW89_KCC][8] = 127, -+ [0][1][2][1][RTW89_ACMA][8] = 127, -+ [0][1][2][1][RTW89_CN][8] = 127, -+ [0][1][2][1][RTW89_UK][8] = 127, -+ [0][1][2][1][RTW89_FCC][9] = 127, -+ [0][1][2][1][RTW89_ETSI][9] = 127, -+ [0][1][2][1][RTW89_MKK][9] = 127, -+ [0][1][2][1][RTW89_IC][9] = 127, -+ [0][1][2][1][RTW89_KCC][9] = 127, -+ [0][1][2][1][RTW89_ACMA][9] = 127, -+ [0][1][2][1][RTW89_CN][9] = 127, -+ [0][1][2][1][RTW89_UK][9] = 127, -+ [0][1][2][1][RTW89_FCC][10] = 127, -+ [0][1][2][1][RTW89_ETSI][10] = 127, -+ [0][1][2][1][RTW89_MKK][10] = 127, -+ [0][1][2][1][RTW89_IC][10] = 127, -+ [0][1][2][1][RTW89_KCC][10] = 127, -+ [0][1][2][1][RTW89_ACMA][10] = 127, -+ [0][1][2][1][RTW89_CN][10] = 127, -+ [0][1][2][1][RTW89_UK][10] = 127, -+ [0][1][2][1][RTW89_FCC][11] = 127, -+ [0][1][2][1][RTW89_ETSI][11] = 127, -+ [0][1][2][1][RTW89_MKK][11] = 127, -+ [0][1][2][1][RTW89_IC][11] = 127, -+ [0][1][2][1][RTW89_KCC][11] = 127, -+ [0][1][2][1][RTW89_ACMA][11] = 127, -+ [0][1][2][1][RTW89_CN][11] = 127, -+ [0][1][2][1][RTW89_UK][11] = 127, -+ [0][1][2][1][RTW89_FCC][12] = 127, -+ [0][1][2][1][RTW89_ETSI][12] = 127, -+ [0][1][2][1][RTW89_MKK][12] = 127, -+ [0][1][2][1][RTW89_IC][12] = 127, -+ [0][1][2][1][RTW89_KCC][12] = 127, -+ [0][1][2][1][RTW89_ACMA][12] = 127, -+ [0][1][2][1][RTW89_CN][12] = 127, -+ [0][1][2][1][RTW89_UK][12] = 127, -+ [0][1][2][1][RTW89_FCC][13] = 127, -+ [0][1][2][1][RTW89_ETSI][13] = 127, -+ [0][1][2][1][RTW89_MKK][13] = 127, -+ [0][1][2][1][RTW89_IC][13] = 127, -+ [0][1][2][1][RTW89_KCC][13] = 127, -+ [0][1][2][1][RTW89_ACMA][13] = 127, -+ [0][1][2][1][RTW89_CN][13] = 127, -+ [0][1][2][1][RTW89_UK][13] = 127, -+ [1][0][2][0][RTW89_FCC][0] = 127, -+ [1][0][2][0][RTW89_ETSI][0] = 127, -+ [1][0][2][0][RTW89_MKK][0] = 127, -+ [1][0][2][0][RTW89_IC][0] = 127, -+ [1][0][2][0][RTW89_KCC][0] = 127, -+ [1][0][2][0][RTW89_ACMA][0] = 127, -+ [1][0][2][0][RTW89_CN][0] = 127, -+ [1][0][2][0][RTW89_UK][0] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 127, -+ [1][0][2][0][RTW89_ETSI][1] = 127, -+ [1][0][2][0][RTW89_MKK][1] = 127, -+ [1][0][2][0][RTW89_IC][1] = 127, -+ [1][0][2][0][RTW89_KCC][1] = 127, -+ [1][0][2][0][RTW89_ACMA][1] = 127, -+ [1][0][2][0][RTW89_CN][1] = 127, -+ [1][0][2][0][RTW89_UK][1] = 127, -+ [1][0][2][0][RTW89_FCC][2] = 72, -+ [1][0][2][0][RTW89_ETSI][2] = 58, -+ [1][0][2][0][RTW89_MKK][2] = 80, -+ [1][0][2][0][RTW89_IC][2] = 72, -+ [1][0][2][0][RTW89_KCC][2] = 80, -+ [1][0][2][0][RTW89_ACMA][2] = 58, -+ [1][0][2][0][RTW89_CN][2] = 60, -+ [1][0][2][0][RTW89_UK][2] = 58, -+ [1][0][2][0][RTW89_FCC][3] = 72, -+ [1][0][2][0][RTW89_ETSI][3] = 58, -+ [1][0][2][0][RTW89_MKK][3] = 80, -+ [1][0][2][0][RTW89_IC][3] = 72, -+ [1][0][2][0][RTW89_KCC][3] = 80, -+ [1][0][2][0][RTW89_ACMA][3] = 58, -+ [1][0][2][0][RTW89_CN][3] = 60, -+ [1][0][2][0][RTW89_UK][3] = 58, -+ [1][0][2][0][RTW89_FCC][4] = 76, -+ [1][0][2][0][RTW89_ETSI][4] = 58, -+ [1][0][2][0][RTW89_MKK][4] = 80, -+ [1][0][2][0][RTW89_IC][4] = 76, -+ [1][0][2][0][RTW89_KCC][4] = 80, -+ [1][0][2][0][RTW89_ACMA][4] = 58, -+ [1][0][2][0][RTW89_CN][4] = 60, -+ [1][0][2][0][RTW89_UK][4] = 58, -+ [1][0][2][0][RTW89_FCC][5] = 78, -+ [1][0][2][0][RTW89_ETSI][5] = 58, -+ [1][0][2][0][RTW89_MKK][5] = 80, -+ [1][0][2][0][RTW89_IC][5] = 78, -+ [1][0][2][0][RTW89_KCC][5] = 80, -+ [1][0][2][0][RTW89_ACMA][5] = 58, -+ [1][0][2][0][RTW89_CN][5] = 60, -+ [1][0][2][0][RTW89_UK][5] = 58, -+ [1][0][2][0][RTW89_FCC][6] = 78, -+ [1][0][2][0][RTW89_ETSI][6] = 58, -+ [1][0][2][0][RTW89_MKK][6] = 78, -+ [1][0][2][0][RTW89_IC][6] = 78, -+ [1][0][2][0][RTW89_KCC][6] = 80, -+ [1][0][2][0][RTW89_ACMA][6] = 58, -+ [1][0][2][0][RTW89_CN][6] = 60, -+ [1][0][2][0][RTW89_UK][6] = 58, -+ [1][0][2][0][RTW89_FCC][7] = 78, -+ [1][0][2][0][RTW89_ETSI][7] = 58, -+ [1][0][2][0][RTW89_MKK][7] = 80, -+ [1][0][2][0][RTW89_IC][7] = 78, -+ [1][0][2][0][RTW89_KCC][7] = 80, -+ [1][0][2][0][RTW89_ACMA][7] = 58, -+ [1][0][2][0][RTW89_CN][7] = 60, -+ [1][0][2][0][RTW89_UK][7] = 58, -+ [1][0][2][0][RTW89_FCC][8] = 78, -+ [1][0][2][0][RTW89_ETSI][8] = 58, -+ [1][0][2][0][RTW89_MKK][8] = 80, -+ [1][0][2][0][RTW89_IC][8] = 78, -+ [1][0][2][0][RTW89_KCC][8] = 78, -+ [1][0][2][0][RTW89_ACMA][8] = 58, -+ [1][0][2][0][RTW89_CN][8] = 60, -+ [1][0][2][0][RTW89_UK][8] = 58, -+ [1][0][2][0][RTW89_FCC][9] = 76, -+ [1][0][2][0][RTW89_ETSI][9] = 58, -+ [1][0][2][0][RTW89_MKK][9] = 80, -+ [1][0][2][0][RTW89_IC][9] = 76, -+ [1][0][2][0][RTW89_KCC][9] = 78, -+ [1][0][2][0][RTW89_ACMA][9] = 58, -+ [1][0][2][0][RTW89_CN][9] = 60, -+ [1][0][2][0][RTW89_UK][9] = 58, -+ [1][0][2][0][RTW89_FCC][10] = 70, -+ [1][0][2][0][RTW89_ETSI][10] = 58, -+ [1][0][2][0][RTW89_MKK][10] = 78, -+ [1][0][2][0][RTW89_IC][10] = 70, -+ [1][0][2][0][RTW89_KCC][10] = 78, -+ [1][0][2][0][RTW89_ACMA][10] = 58, -+ [1][0][2][0][RTW89_CN][10] = 60, -+ [1][0][2][0][RTW89_UK][10] = 58, -+ [1][0][2][0][RTW89_FCC][11] = 127, -+ [1][0][2][0][RTW89_ETSI][11] = 127, -+ [1][0][2][0][RTW89_MKK][11] = 127, -+ [1][0][2][0][RTW89_IC][11] = 127, -+ [1][0][2][0][RTW89_KCC][11] = 127, -+ [1][0][2][0][RTW89_ACMA][11] = 127, -+ [1][0][2][0][RTW89_CN][11] = 127, -+ [1][0][2][0][RTW89_UK][11] = 127, -+ [1][0][2][0][RTW89_FCC][12] = 127, -+ [1][0][2][0][RTW89_ETSI][12] = 127, -+ [1][0][2][0][RTW89_MKK][12] = 127, -+ [1][0][2][0][RTW89_IC][12] = 127, -+ [1][0][2][0][RTW89_KCC][12] = 127, -+ [1][0][2][0][RTW89_ACMA][12] = 127, -+ [1][0][2][0][RTW89_CN][12] = 127, -+ [1][0][2][0][RTW89_UK][12] = 127, -+ [1][0][2][0][RTW89_FCC][13] = 127, -+ [1][0][2][0][RTW89_ETSI][13] = 127, -+ [1][0][2][0][RTW89_MKK][13] = 127, -+ [1][0][2][0][RTW89_IC][13] = 127, -+ [1][0][2][0][RTW89_KCC][13] = 127, -+ [1][0][2][0][RTW89_ACMA][13] = 127, -+ [1][0][2][0][RTW89_CN][13] = 127, -+ [1][0][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_FCC][0] = 127, -+ [1][1][2][0][RTW89_ETSI][0] = 127, -+ [1][1][2][0][RTW89_MKK][0] = 127, -+ [1][1][2][0][RTW89_IC][0] = 127, -+ [1][1][2][0][RTW89_KCC][0] = 127, -+ [1][1][2][0][RTW89_ACMA][0] = 127, -+ [1][1][2][0][RTW89_CN][0] = 127, -+ [1][1][2][0][RTW89_UK][0] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 127, -+ [1][1][2][0][RTW89_ETSI][1] = 127, -+ [1][1][2][0][RTW89_MKK][1] = 127, -+ [1][1][2][0][RTW89_IC][1] = 127, -+ [1][1][2][0][RTW89_KCC][1] = 127, -+ [1][1][2][0][RTW89_ACMA][1] = 127, -+ [1][1][2][0][RTW89_CN][1] = 127, -+ [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_FCC][2] = 127, -+ [1][1][2][0][RTW89_ETSI][2] = 127, -+ [1][1][2][0][RTW89_MKK][2] = 127, -+ [1][1][2][0][RTW89_IC][2] = 127, -+ [1][1][2][0][RTW89_KCC][2] = 127, -+ [1][1][2][0][RTW89_ACMA][2] = 127, -+ [1][1][2][0][RTW89_CN][2] = 127, -+ [1][1][2][0][RTW89_UK][2] = 127, -+ [1][1][2][0][RTW89_FCC][3] = 127, -+ [1][1][2][0][RTW89_ETSI][3] = 127, -+ [1][1][2][0][RTW89_MKK][3] = 127, -+ [1][1][2][0][RTW89_IC][3] = 127, -+ [1][1][2][0][RTW89_KCC][3] = 127, -+ [1][1][2][0][RTW89_ACMA][3] = 127, -+ [1][1][2][0][RTW89_CN][3] = 127, -+ [1][1][2][0][RTW89_UK][3] = 127, -+ [1][1][2][0][RTW89_FCC][4] = 127, -+ [1][1][2][0][RTW89_ETSI][4] = 127, -+ [1][1][2][0][RTW89_MKK][4] = 127, -+ [1][1][2][0][RTW89_IC][4] = 127, -+ [1][1][2][0][RTW89_KCC][4] = 127, -+ [1][1][2][0][RTW89_ACMA][4] = 127, -+ [1][1][2][0][RTW89_CN][4] = 127, -+ [1][1][2][0][RTW89_UK][4] = 127, -+ [1][1][2][0][RTW89_FCC][5] = 127, -+ [1][1][2][0][RTW89_ETSI][5] = 127, -+ [1][1][2][0][RTW89_MKK][5] = 127, -+ [1][1][2][0][RTW89_IC][5] = 127, -+ [1][1][2][0][RTW89_KCC][5] = 127, -+ [1][1][2][0][RTW89_ACMA][5] = 127, -+ [1][1][2][0][RTW89_CN][5] = 127, -+ [1][1][2][0][RTW89_UK][5] = 127, -+ [1][1][2][0][RTW89_FCC][6] = 127, -+ [1][1][2][0][RTW89_ETSI][6] = 127, -+ [1][1][2][0][RTW89_MKK][6] = 127, -+ [1][1][2][0][RTW89_IC][6] = 127, -+ [1][1][2][0][RTW89_KCC][6] = 127, -+ [1][1][2][0][RTW89_ACMA][6] = 127, -+ [1][1][2][0][RTW89_CN][6] = 127, -+ [1][1][2][0][RTW89_UK][6] = 127, -+ [1][1][2][0][RTW89_FCC][7] = 127, -+ [1][1][2][0][RTW89_ETSI][7] = 127, -+ [1][1][2][0][RTW89_MKK][7] = 127, -+ [1][1][2][0][RTW89_IC][7] = 127, -+ [1][1][2][0][RTW89_KCC][7] = 127, -+ [1][1][2][0][RTW89_ACMA][7] = 127, -+ [1][1][2][0][RTW89_CN][7] = 127, -+ [1][1][2][0][RTW89_UK][7] = 127, -+ [1][1][2][0][RTW89_FCC][8] = 127, -+ [1][1][2][0][RTW89_ETSI][8] = 127, -+ [1][1][2][0][RTW89_MKK][8] = 127, -+ [1][1][2][0][RTW89_IC][8] = 127, -+ [1][1][2][0][RTW89_KCC][8] = 127, -+ [1][1][2][0][RTW89_ACMA][8] = 127, -+ [1][1][2][0][RTW89_CN][8] = 127, -+ [1][1][2][0][RTW89_UK][8] = 127, -+ [1][1][2][0][RTW89_FCC][9] = 127, -+ [1][1][2][0][RTW89_ETSI][9] = 127, -+ [1][1][2][0][RTW89_MKK][9] = 127, -+ [1][1][2][0][RTW89_IC][9] = 127, -+ [1][1][2][0][RTW89_KCC][9] = 127, -+ [1][1][2][0][RTW89_ACMA][9] = 127, -+ [1][1][2][0][RTW89_CN][9] = 127, -+ [1][1][2][0][RTW89_UK][9] = 127, -+ [1][1][2][0][RTW89_FCC][10] = 127, -+ [1][1][2][0][RTW89_ETSI][10] = 127, -+ [1][1][2][0][RTW89_MKK][10] = 127, -+ [1][1][2][0][RTW89_IC][10] = 127, -+ [1][1][2][0][RTW89_KCC][10] = 127, -+ [1][1][2][0][RTW89_ACMA][10] = 127, -+ [1][1][2][0][RTW89_CN][10] = 127, -+ [1][1][2][0][RTW89_UK][10] = 127, -+ [1][1][2][0][RTW89_FCC][11] = 127, -+ [1][1][2][0][RTW89_ETSI][11] = 127, -+ [1][1][2][0][RTW89_MKK][11] = 127, -+ [1][1][2][0][RTW89_IC][11] = 127, -+ [1][1][2][0][RTW89_KCC][11] = 127, -+ [1][1][2][0][RTW89_ACMA][11] = 127, -+ [1][1][2][0][RTW89_CN][11] = 127, -+ [1][1][2][0][RTW89_UK][11] = 127, -+ [1][1][2][0][RTW89_FCC][12] = 127, -+ [1][1][2][0][RTW89_ETSI][12] = 127, -+ [1][1][2][0][RTW89_MKK][12] = 127, -+ [1][1][2][0][RTW89_IC][12] = 127, -+ [1][1][2][0][RTW89_KCC][12] = 127, -+ [1][1][2][0][RTW89_ACMA][12] = 127, -+ [1][1][2][0][RTW89_CN][12] = 127, -+ [1][1][2][0][RTW89_UK][12] = 127, -+ [1][1][2][0][RTW89_FCC][13] = 127, -+ [1][1][2][0][RTW89_ETSI][13] = 127, -+ [1][1][2][0][RTW89_MKK][13] = 127, -+ [1][1][2][0][RTW89_IC][13] = 127, -+ [1][1][2][0][RTW89_KCC][13] = 127, -+ [1][1][2][0][RTW89_ACMA][13] = 127, -+ [1][1][2][0][RTW89_CN][13] = 127, -+ [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_FCC][0] = 127, -+ [1][1][2][1][RTW89_ETSI][0] = 127, -+ [1][1][2][1][RTW89_MKK][0] = 127, -+ [1][1][2][1][RTW89_IC][0] = 127, -+ [1][1][2][1][RTW89_KCC][0] = 127, -+ [1][1][2][1][RTW89_ACMA][0] = 127, -+ [1][1][2][1][RTW89_CN][0] = 127, -+ [1][1][2][1][RTW89_UK][0] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 127, -+ [1][1][2][1][RTW89_ETSI][1] = 127, -+ [1][1][2][1][RTW89_MKK][1] = 127, -+ [1][1][2][1][RTW89_IC][1] = 127, -+ [1][1][2][1][RTW89_KCC][1] = 127, -+ [1][1][2][1][RTW89_ACMA][1] = 127, -+ [1][1][2][1][RTW89_CN][1] = 127, -+ [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_FCC][2] = 127, -+ [1][1][2][1][RTW89_ETSI][2] = 127, -+ [1][1][2][1][RTW89_MKK][2] = 127, -+ [1][1][2][1][RTW89_IC][2] = 127, -+ [1][1][2][1][RTW89_KCC][2] = 127, -+ [1][1][2][1][RTW89_ACMA][2] = 127, -+ [1][1][2][1][RTW89_CN][2] = 127, -+ [1][1][2][1][RTW89_UK][2] = 127, -+ [1][1][2][1][RTW89_FCC][3] = 127, -+ [1][1][2][1][RTW89_ETSI][3] = 127, -+ [1][1][2][1][RTW89_MKK][3] = 127, -+ [1][1][2][1][RTW89_IC][3] = 127, -+ [1][1][2][1][RTW89_KCC][3] = 127, -+ [1][1][2][1][RTW89_ACMA][3] = 127, -+ [1][1][2][1][RTW89_CN][3] = 127, -+ [1][1][2][1][RTW89_UK][3] = 127, -+ [1][1][2][1][RTW89_FCC][4] = 127, -+ [1][1][2][1][RTW89_ETSI][4] = 127, -+ [1][1][2][1][RTW89_MKK][4] = 127, -+ [1][1][2][1][RTW89_IC][4] = 127, -+ [1][1][2][1][RTW89_KCC][4] = 127, -+ [1][1][2][1][RTW89_ACMA][4] = 127, -+ [1][1][2][1][RTW89_CN][4] = 127, -+ [1][1][2][1][RTW89_UK][4] = 127, -+ [1][1][2][1][RTW89_FCC][5] = 127, -+ [1][1][2][1][RTW89_ETSI][5] = 127, -+ [1][1][2][1][RTW89_MKK][5] = 127, -+ [1][1][2][1][RTW89_IC][5] = 127, -+ [1][1][2][1][RTW89_KCC][5] = 127, -+ [1][1][2][1][RTW89_ACMA][5] = 127, -+ [1][1][2][1][RTW89_CN][5] = 127, -+ [1][1][2][1][RTW89_UK][5] = 127, -+ [1][1][2][1][RTW89_FCC][6] = 127, -+ [1][1][2][1][RTW89_ETSI][6] = 127, -+ [1][1][2][1][RTW89_MKK][6] = 127, -+ [1][1][2][1][RTW89_IC][6] = 127, -+ [1][1][2][1][RTW89_KCC][6] = 127, -+ [1][1][2][1][RTW89_ACMA][6] = 127, -+ [1][1][2][1][RTW89_CN][6] = 127, -+ [1][1][2][1][RTW89_UK][6] = 127, -+ [1][1][2][1][RTW89_FCC][7] = 127, -+ [1][1][2][1][RTW89_ETSI][7] = 127, -+ [1][1][2][1][RTW89_MKK][7] = 127, -+ [1][1][2][1][RTW89_IC][7] = 127, -+ [1][1][2][1][RTW89_KCC][7] = 127, -+ [1][1][2][1][RTW89_ACMA][7] = 127, -+ [1][1][2][1][RTW89_CN][7] = 127, -+ [1][1][2][1][RTW89_UK][7] = 127, -+ [1][1][2][1][RTW89_FCC][8] = 127, -+ [1][1][2][1][RTW89_ETSI][8] = 127, -+ [1][1][2][1][RTW89_MKK][8] = 127, -+ [1][1][2][1][RTW89_IC][8] = 127, -+ [1][1][2][1][RTW89_KCC][8] = 127, -+ [1][1][2][1][RTW89_ACMA][8] = 127, -+ [1][1][2][1][RTW89_CN][8] = 127, -+ [1][1][2][1][RTW89_UK][8] = 127, -+ [1][1][2][1][RTW89_FCC][9] = 127, -+ [1][1][2][1][RTW89_ETSI][9] = 127, -+ [1][1][2][1][RTW89_MKK][9] = 127, -+ [1][1][2][1][RTW89_IC][9] = 127, -+ [1][1][2][1][RTW89_KCC][9] = 127, -+ [1][1][2][1][RTW89_ACMA][9] = 127, -+ [1][1][2][1][RTW89_CN][9] = 127, -+ [1][1][2][1][RTW89_UK][9] = 127, -+ [1][1][2][1][RTW89_FCC][10] = 127, -+ [1][1][2][1][RTW89_ETSI][10] = 127, -+ [1][1][2][1][RTW89_MKK][10] = 127, -+ [1][1][2][1][RTW89_IC][10] = 127, -+ [1][1][2][1][RTW89_KCC][10] = 127, -+ [1][1][2][1][RTW89_ACMA][10] = 127, -+ [1][1][2][1][RTW89_CN][10] = 127, -+ [1][1][2][1][RTW89_UK][10] = 127, -+ [1][1][2][1][RTW89_FCC][11] = 127, -+ [1][1][2][1][RTW89_ETSI][11] = 127, -+ [1][1][2][1][RTW89_MKK][11] = 127, -+ [1][1][2][1][RTW89_IC][11] = 127, -+ [1][1][2][1][RTW89_KCC][11] = 127, -+ [1][1][2][1][RTW89_ACMA][11] = 127, -+ [1][1][2][1][RTW89_CN][11] = 127, -+ [1][1][2][1][RTW89_UK][11] = 127, -+ [1][1][2][1][RTW89_FCC][12] = 127, -+ [1][1][2][1][RTW89_ETSI][12] = 127, -+ [1][1][2][1][RTW89_MKK][12] = 127, -+ [1][1][2][1][RTW89_IC][12] = 127, -+ [1][1][2][1][RTW89_KCC][12] = 127, -+ [1][1][2][1][RTW89_ACMA][12] = 127, -+ [1][1][2][1][RTW89_CN][12] = 127, -+ [1][1][2][1][RTW89_UK][12] = 127, -+ [1][1][2][1][RTW89_FCC][13] = 127, -+ [1][1][2][1][RTW89_ETSI][13] = 127, -+ [1][1][2][1][RTW89_MKK][13] = 127, -+ [1][1][2][1][RTW89_IC][13] = 127, -+ [1][1][2][1][RTW89_KCC][13] = 127, -+ [1][1][2][1][RTW89_ACMA][13] = 127, -+ [1][1][2][1][RTW89_CN][13] = 127, -+ [1][1][2][1][RTW89_UK][13] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][1][0][RTW89_WW][0] = 58, -+ [0][0][1][0][RTW89_WW][2] = 58, -+ [0][0][1][0][RTW89_WW][4] = 58, -+ [0][0][1][0][RTW89_WW][6] = 50, -+ [0][0][1][0][RTW89_WW][8] = 58, -+ [0][0][1][0][RTW89_WW][10] = 58, -+ [0][0][1][0][RTW89_WW][12] = 58, -+ [0][0][1][0][RTW89_WW][14] = 58, -+ [0][0][1][0][RTW89_WW][15] = 58, -+ [0][0][1][0][RTW89_WW][17] = 60, -+ [0][0][1][0][RTW89_WW][19] = 60, -+ [0][0][1][0][RTW89_WW][21] = 60, -+ [0][0][1][0][RTW89_WW][23] = 60, -+ [0][0][1][0][RTW89_WW][25] = 60, -+ [0][0][1][0][RTW89_WW][27] = 60, -+ [0][0][1][0][RTW89_WW][29] = 60, -+ [0][0][1][0][RTW89_WW][31] = 60, -+ [0][0][1][0][RTW89_WW][33] = 60, -+ [0][0][1][0][RTW89_WW][35] = 60, -+ [0][0][1][0][RTW89_WW][37] = 74, -+ [0][0][1][0][RTW89_WW][38] = 30, -+ [0][0][1][0][RTW89_WW][40] = 30, -+ [0][0][1][0][RTW89_WW][42] = 30, -+ [0][0][1][0][RTW89_WW][44] = 30, -+ [0][0][1][0][RTW89_WW][46] = 30, -+ [0][0][1][0][RTW89_WW][48] = 72, -+ [0][0][1][0][RTW89_WW][50] = 72, -+ [0][0][1][0][RTW89_WW][52] = 72, -+ [0][1][1][0][RTW89_WW][0] = 0, -+ [0][1][1][0][RTW89_WW][2] = 0, -+ [0][1][1][0][RTW89_WW][4] = 0, -+ [0][1][1][0][RTW89_WW][6] = 0, -+ [0][1][1][0][RTW89_WW][8] = 0, -+ [0][1][1][0][RTW89_WW][10] = 0, -+ [0][1][1][0][RTW89_WW][12] = 0, -+ [0][1][1][0][RTW89_WW][14] = 0, -+ [0][1][1][0][RTW89_WW][15] = 0, -+ [0][1][1][0][RTW89_WW][17] = 0, -+ [0][1][1][0][RTW89_WW][19] = 0, -+ [0][1][1][0][RTW89_WW][21] = 0, -+ [0][1][1][0][RTW89_WW][23] = 0, -+ [0][1][1][0][RTW89_WW][25] = 0, -+ [0][1][1][0][RTW89_WW][27] = 0, -+ [0][1][1][0][RTW89_WW][29] = 0, -+ [0][1][1][0][RTW89_WW][31] = 0, -+ [0][1][1][0][RTW89_WW][33] = 0, -+ [0][1][1][0][RTW89_WW][35] = 0, -+ [0][1][1][0][RTW89_WW][37] = 0, -+ [0][1][1][0][RTW89_WW][38] = 0, -+ [0][1][1][0][RTW89_WW][40] = 0, -+ [0][1][1][0][RTW89_WW][42] = 0, -+ [0][1][1][0][RTW89_WW][44] = 0, -+ [0][1][1][0][RTW89_WW][46] = 0, -+ [0][1][1][0][RTW89_WW][48] = 0, -+ [0][1][1][0][RTW89_WW][50] = 0, -+ [0][1][1][0][RTW89_WW][52] = 0, -+ [0][0][2][0][RTW89_WW][0] = 62, -+ [0][0][2][0][RTW89_WW][2] = 62, -+ [0][0][2][0][RTW89_WW][4] = 62, -+ [0][0][2][0][RTW89_WW][6] = 54, -+ [0][0][2][0][RTW89_WW][8] = 62, -+ [0][0][2][0][RTW89_WW][10] = 62, -+ [0][0][2][0][RTW89_WW][12] = 62, -+ [0][0][2][0][RTW89_WW][14] = 62, -+ [0][0][2][0][RTW89_WW][15] = 60, -+ [0][0][2][0][RTW89_WW][17] = 62, -+ [0][0][2][0][RTW89_WW][19] = 62, -+ [0][0][2][0][RTW89_WW][21] = 62, -+ [0][0][2][0][RTW89_WW][23] = 62, -+ [0][0][2][0][RTW89_WW][25] = 62, -+ [0][0][2][0][RTW89_WW][27] = 62, -+ [0][0][2][0][RTW89_WW][29] = 62, -+ [0][0][2][0][RTW89_WW][31] = 62, -+ [0][0][2][0][RTW89_WW][33] = 62, -+ [0][0][2][0][RTW89_WW][35] = 62, -+ [0][0][2][0][RTW89_WW][37] = 76, -+ [0][0][2][0][RTW89_WW][38] = 30, -+ [0][0][2][0][RTW89_WW][40] = 30, -+ [0][0][2][0][RTW89_WW][42] = 30, -+ [0][0][2][0][RTW89_WW][44] = 30, -+ [0][0][2][0][RTW89_WW][46] = 30, -+ [0][0][2][0][RTW89_WW][48] = 74, -+ [0][0][2][0][RTW89_WW][50] = 76, -+ [0][0][2][0][RTW89_WW][52] = 76, -+ [0][1][2][0][RTW89_WW][0] = 0, -+ [0][1][2][0][RTW89_WW][2] = 0, -+ [0][1][2][0][RTW89_WW][4] = 0, -+ [0][1][2][0][RTW89_WW][6] = 0, -+ [0][1][2][0][RTW89_WW][8] = 0, -+ [0][1][2][0][RTW89_WW][10] = 0, -+ [0][1][2][0][RTW89_WW][12] = 0, -+ [0][1][2][0][RTW89_WW][14] = 0, -+ [0][1][2][0][RTW89_WW][15] = 0, -+ [0][1][2][0][RTW89_WW][17] = 0, -+ [0][1][2][0][RTW89_WW][19] = 0, -+ [0][1][2][0][RTW89_WW][21] = 0, -+ [0][1][2][0][RTW89_WW][23] = 0, -+ [0][1][2][0][RTW89_WW][25] = 0, -+ [0][1][2][0][RTW89_WW][27] = 0, -+ [0][1][2][0][RTW89_WW][29] = 0, -+ [0][1][2][0][RTW89_WW][31] = 0, -+ [0][1][2][0][RTW89_WW][33] = 0, -+ [0][1][2][0][RTW89_WW][35] = 0, -+ [0][1][2][0][RTW89_WW][37] = 0, -+ [0][1][2][0][RTW89_WW][38] = 0, -+ [0][1][2][0][RTW89_WW][40] = 0, -+ [0][1][2][0][RTW89_WW][42] = 0, -+ [0][1][2][0][RTW89_WW][44] = 0, -+ [0][1][2][0][RTW89_WW][46] = 0, -+ [0][1][2][0][RTW89_WW][48] = 0, -+ [0][1][2][0][RTW89_WW][50] = 0, -+ [0][1][2][0][RTW89_WW][52] = 0, -+ [0][1][2][1][RTW89_WW][0] = 0, -+ [0][1][2][1][RTW89_WW][2] = 0, -+ [0][1][2][1][RTW89_WW][4] = 0, -+ [0][1][2][1][RTW89_WW][6] = 0, -+ [0][1][2][1][RTW89_WW][8] = 0, -+ [0][1][2][1][RTW89_WW][10] = 0, -+ [0][1][2][1][RTW89_WW][12] = 0, -+ [0][1][2][1][RTW89_WW][14] = 0, -+ [0][1][2][1][RTW89_WW][15] = 0, -+ [0][1][2][1][RTW89_WW][17] = 0, -+ [0][1][2][1][RTW89_WW][19] = 0, -+ [0][1][2][1][RTW89_WW][21] = 0, -+ [0][1][2][1][RTW89_WW][23] = 0, -+ [0][1][2][1][RTW89_WW][25] = 0, -+ [0][1][2][1][RTW89_WW][27] = 0, -+ [0][1][2][1][RTW89_WW][29] = 0, -+ [0][1][2][1][RTW89_WW][31] = 0, -+ [0][1][2][1][RTW89_WW][33] = 0, -+ [0][1][2][1][RTW89_WW][35] = 0, -+ [0][1][2][1][RTW89_WW][37] = 0, -+ [0][1][2][1][RTW89_WW][38] = 0, -+ [0][1][2][1][RTW89_WW][40] = 0, -+ [0][1][2][1][RTW89_WW][42] = 0, -+ [0][1][2][1][RTW89_WW][44] = 0, -+ [0][1][2][1][RTW89_WW][46] = 0, -+ [0][1][2][1][RTW89_WW][48] = 0, -+ [0][1][2][1][RTW89_WW][50] = 0, -+ [0][1][2][1][RTW89_WW][52] = 0, -+ [1][0][2][0][RTW89_WW][1] = 64, -+ [1][0][2][0][RTW89_WW][5] = 62, -+ [1][0][2][0][RTW89_WW][9] = 64, -+ [1][0][2][0][RTW89_WW][13] = 64, -+ [1][0][2][0][RTW89_WW][16] = 66, -+ [1][0][2][0][RTW89_WW][20] = 66, -+ [1][0][2][0][RTW89_WW][24] = 66, -+ [1][0][2][0][RTW89_WW][28] = 66, -+ [1][0][2][0][RTW89_WW][32] = 66, -+ [1][0][2][0][RTW89_WW][36] = 76, -+ [1][0][2][0][RTW89_WW][39] = 30, -+ [1][0][2][0][RTW89_WW][43] = 30, -+ [1][0][2][0][RTW89_WW][47] = 84, -+ [1][0][2][0][RTW89_WW][51] = 84, -+ [1][1][2][0][RTW89_WW][1] = 0, -+ [1][1][2][0][RTW89_WW][5] = 0, -+ [1][1][2][0][RTW89_WW][9] = 0, -+ [1][1][2][0][RTW89_WW][13] = 0, -+ [1][1][2][0][RTW89_WW][16] = 0, -+ [1][1][2][0][RTW89_WW][20] = 0, -+ [1][1][2][0][RTW89_WW][24] = 0, -+ [1][1][2][0][RTW89_WW][28] = 0, -+ [1][1][2][0][RTW89_WW][32] = 0, -+ [1][1][2][0][RTW89_WW][36] = 0, -+ [1][1][2][0][RTW89_WW][39] = 0, -+ [1][1][2][0][RTW89_WW][43] = 0, -+ [1][1][2][0][RTW89_WW][47] = 0, -+ [1][1][2][0][RTW89_WW][51] = 0, -+ [1][1][2][1][RTW89_WW][1] = 0, -+ [1][1][2][1][RTW89_WW][5] = 0, -+ [1][1][2][1][RTW89_WW][9] = 0, -+ [1][1][2][1][RTW89_WW][13] = 0, -+ [1][1][2][1][RTW89_WW][16] = 0, -+ [1][1][2][1][RTW89_WW][20] = 0, -+ [1][1][2][1][RTW89_WW][24] = 0, -+ [1][1][2][1][RTW89_WW][28] = 0, -+ [1][1][2][1][RTW89_WW][32] = 0, -+ [1][1][2][1][RTW89_WW][36] = 0, -+ [1][1][2][1][RTW89_WW][39] = 0, -+ [1][1][2][1][RTW89_WW][43] = 0, -+ [1][1][2][1][RTW89_WW][47] = 0, -+ [1][1][2][1][RTW89_WW][51] = 0, -+ [2][0][2][0][RTW89_WW][3] = 62, -+ [2][0][2][0][RTW89_WW][11] = 62, -+ [2][0][2][0][RTW89_WW][18] = 64, -+ [2][0][2][0][RTW89_WW][26] = 64, -+ [2][0][2][0][RTW89_WW][34] = 72, -+ [2][0][2][0][RTW89_WW][41] = 30, -+ [2][0][2][0][RTW89_WW][49] = 74, -+ [2][1][2][0][RTW89_WW][3] = 0, -+ [2][1][2][0][RTW89_WW][11] = 0, -+ [2][1][2][0][RTW89_WW][18] = 0, -+ [2][1][2][0][RTW89_WW][26] = 0, -+ [2][1][2][0][RTW89_WW][34] = 0, -+ [2][1][2][0][RTW89_WW][41] = 0, -+ [2][1][2][0][RTW89_WW][49] = 0, -+ [2][1][2][1][RTW89_WW][3] = 0, -+ [2][1][2][1][RTW89_WW][11] = 0, -+ [2][1][2][1][RTW89_WW][18] = 0, -+ [2][1][2][1][RTW89_WW][26] = 0, -+ [2][1][2][1][RTW89_WW][34] = 0, -+ [2][1][2][1][RTW89_WW][41] = 0, -+ [2][1][2][1][RTW89_WW][49] = 0, -+ [3][0][2][0][RTW89_WW][7] = 58, -+ [3][0][2][0][RTW89_WW][22] = 58, -+ [3][0][2][0][RTW89_WW][45] = 0, -+ [3][1][2][0][RTW89_WW][7] = 0, -+ [3][1][2][0][RTW89_WW][22] = 0, -+ [3][1][2][0][RTW89_WW][45] = 0, -+ [3][1][2][1][RTW89_WW][7] = 0, -+ [3][1][2][1][RTW89_WW][22] = 0, -+ [3][1][2][1][RTW89_WW][45] = 0, -+ [0][0][1][0][RTW89_FCC][0] = 80, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 60, -+ [0][0][1][0][RTW89_IC][0] = 62, -+ [0][0][1][0][RTW89_KCC][0] = 74, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CN][0] = 60, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][2] = 82, -+ [0][0][1][0][RTW89_ETSI][2] = 58, -+ [0][0][1][0][RTW89_MKK][2] = 60, -+ [0][0][1][0][RTW89_IC][2] = 62, -+ [0][0][1][0][RTW89_KCC][2] = 74, -+ [0][0][1][0][RTW89_ACMA][2] = 58, -+ [0][0][1][0][RTW89_CN][2] = 60, -+ [0][0][1][0][RTW89_UK][2] = 58, -+ [0][0][1][0][RTW89_FCC][4] = 82, -+ [0][0][1][0][RTW89_ETSI][4] = 58, -+ [0][0][1][0][RTW89_MKK][4] = 60, -+ [0][0][1][0][RTW89_IC][4] = 62, -+ [0][0][1][0][RTW89_KCC][4] = 74, -+ [0][0][1][0][RTW89_ACMA][4] = 58, -+ [0][0][1][0][RTW89_CN][4] = 60, -+ [0][0][1][0][RTW89_UK][4] = 58, -+ [0][0][1][0][RTW89_FCC][6] = 82, -+ [0][0][1][0][RTW89_ETSI][6] = 58, -+ [0][0][1][0][RTW89_MKK][6] = 60, -+ [0][0][1][0][RTW89_IC][6] = 62, -+ [0][0][1][0][RTW89_KCC][6] = 50, -+ [0][0][1][0][RTW89_ACMA][6] = 58, -+ [0][0][1][0][RTW89_CN][6] = 60, -+ [0][0][1][0][RTW89_UK][6] = 58, -+ [0][0][1][0][RTW89_FCC][8] = 82, -+ [0][0][1][0][RTW89_ETSI][8] = 58, -+ [0][0][1][0][RTW89_MKK][8] = 60, -+ [0][0][1][0][RTW89_IC][8] = 64, -+ [0][0][1][0][RTW89_KCC][8] = 74, -+ [0][0][1][0][RTW89_ACMA][8] = 58, -+ [0][0][1][0][RTW89_CN][8] = 60, -+ [0][0][1][0][RTW89_UK][8] = 58, -+ [0][0][1][0][RTW89_FCC][10] = 82, -+ [0][0][1][0][RTW89_ETSI][10] = 58, -+ [0][0][1][0][RTW89_MKK][10] = 60, -+ [0][0][1][0][RTW89_IC][10] = 64, -+ [0][0][1][0][RTW89_KCC][10] = 74, -+ [0][0][1][0][RTW89_ACMA][10] = 58, -+ [0][0][1][0][RTW89_CN][10] = 60, -+ [0][0][1][0][RTW89_UK][10] = 58, -+ [0][0][1][0][RTW89_FCC][12] = 82, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 60, -+ [0][0][1][0][RTW89_IC][12] = 64, -+ [0][0][1][0][RTW89_KCC][12] = 76, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CN][12] = 60, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][14] = 78, -+ [0][0][1][0][RTW89_ETSI][14] = 58, -+ [0][0][1][0][RTW89_MKK][14] = 60, -+ [0][0][1][0][RTW89_IC][14] = 64, -+ [0][0][1][0][RTW89_KCC][14] = 76, -+ [0][0][1][0][RTW89_ACMA][14] = 58, -+ [0][0][1][0][RTW89_CN][14] = 60, -+ [0][0][1][0][RTW89_UK][14] = 58, -+ [0][0][1][0][RTW89_FCC][15] = 78, -+ [0][0][1][0][RTW89_ETSI][15] = 58, -+ [0][0][1][0][RTW89_MKK][15] = 78, -+ [0][0][1][0][RTW89_IC][15] = 78, -+ [0][0][1][0][RTW89_KCC][15] = 78, -+ [0][0][1][0][RTW89_ACMA][15] = 58, -+ [0][0][1][0][RTW89_CN][15] = 127, -+ [0][0][1][0][RTW89_UK][15] = 58, -+ [0][0][1][0][RTW89_FCC][17] = 82, -+ [0][0][1][0][RTW89_ETSI][17] = 60, -+ [0][0][1][0][RTW89_MKK][17] = 78, -+ [0][0][1][0][RTW89_IC][17] = 82, -+ [0][0][1][0][RTW89_KCC][17] = 78, -+ [0][0][1][0][RTW89_ACMA][17] = 60, -+ [0][0][1][0][RTW89_CN][17] = 127, -+ [0][0][1][0][RTW89_UK][17] = 60, -+ [0][0][1][0][RTW89_FCC][19] = 82, -+ [0][0][1][0][RTW89_ETSI][19] = 60, -+ [0][0][1][0][RTW89_MKK][19] = 78, -+ [0][0][1][0][RTW89_IC][19] = 82, -+ [0][0][1][0][RTW89_KCC][19] = 78, -+ [0][0][1][0][RTW89_ACMA][19] = 60, -+ [0][0][1][0][RTW89_CN][19] = 127, -+ [0][0][1][0][RTW89_UK][19] = 60, -+ [0][0][1][0][RTW89_FCC][21] = 82, -+ [0][0][1][0][RTW89_ETSI][21] = 60, -+ [0][0][1][0][RTW89_MKK][21] = 78, -+ [0][0][1][0][RTW89_IC][21] = 82, -+ [0][0][1][0][RTW89_KCC][21] = 78, -+ [0][0][1][0][RTW89_ACMA][21] = 60, -+ [0][0][1][0][RTW89_CN][21] = 127, -+ [0][0][1][0][RTW89_UK][21] = 60, -+ [0][0][1][0][RTW89_FCC][23] = 82, -+ [0][0][1][0][RTW89_ETSI][23] = 60, -+ [0][0][1][0][RTW89_MKK][23] = 78, -+ [0][0][1][0][RTW89_IC][23] = 82, -+ [0][0][1][0][RTW89_KCC][23] = 78, -+ [0][0][1][0][RTW89_ACMA][23] = 60, -+ [0][0][1][0][RTW89_CN][23] = 127, -+ [0][0][1][0][RTW89_UK][23] = 60, -+ [0][0][1][0][RTW89_FCC][25] = 82, -+ [0][0][1][0][RTW89_ETSI][25] = 60, -+ [0][0][1][0][RTW89_MKK][25] = 78, -+ [0][0][1][0][RTW89_IC][25] = 127, -+ [0][0][1][0][RTW89_KCC][25] = 78, -+ [0][0][1][0][RTW89_ACMA][25] = 127, -+ [0][0][1][0][RTW89_CN][25] = 127, -+ [0][0][1][0][RTW89_UK][25] = 60, -+ [0][0][1][0][RTW89_FCC][27] = 82, -+ [0][0][1][0][RTW89_ETSI][27] = 60, -+ [0][0][1][0][RTW89_MKK][27] = 78, -+ [0][0][1][0][RTW89_IC][27] = 127, -+ [0][0][1][0][RTW89_KCC][27] = 78, -+ [0][0][1][0][RTW89_ACMA][27] = 127, -+ [0][0][1][0][RTW89_CN][27] = 127, -+ [0][0][1][0][RTW89_UK][27] = 60, -+ [0][0][1][0][RTW89_FCC][29] = 82, -+ [0][0][1][0][RTW89_ETSI][29] = 60, -+ [0][0][1][0][RTW89_MKK][29] = 78, -+ [0][0][1][0][RTW89_IC][29] = 127, -+ [0][0][1][0][RTW89_KCC][29] = 78, -+ [0][0][1][0][RTW89_ACMA][29] = 127, -+ [0][0][1][0][RTW89_CN][29] = 127, -+ [0][0][1][0][RTW89_UK][29] = 60, -+ [0][0][1][0][RTW89_FCC][31] = 82, -+ [0][0][1][0][RTW89_ETSI][31] = 60, -+ [0][0][1][0][RTW89_MKK][31] = 78, -+ [0][0][1][0][RTW89_IC][31] = 82, -+ [0][0][1][0][RTW89_KCC][31] = 74, -+ [0][0][1][0][RTW89_ACMA][31] = 60, -+ [0][0][1][0][RTW89_CN][31] = 127, -+ [0][0][1][0][RTW89_UK][31] = 60, -+ [0][0][1][0][RTW89_FCC][33] = 82, -+ [0][0][1][0][RTW89_ETSI][33] = 60, -+ [0][0][1][0][RTW89_MKK][33] = 78, -+ [0][0][1][0][RTW89_IC][33] = 82, -+ [0][0][1][0][RTW89_KCC][33] = 74, -+ [0][0][1][0][RTW89_ACMA][33] = 60, -+ [0][0][1][0][RTW89_CN][33] = 127, -+ [0][0][1][0][RTW89_UK][33] = 60, -+ [0][0][1][0][RTW89_FCC][35] = 72, -+ [0][0][1][0][RTW89_ETSI][35] = 60, -+ [0][0][1][0][RTW89_MKK][35] = 78, -+ [0][0][1][0][RTW89_IC][35] = 72, -+ [0][0][1][0][RTW89_KCC][35] = 74, -+ [0][0][1][0][RTW89_ACMA][35] = 60, -+ [0][0][1][0][RTW89_CN][35] = 127, -+ [0][0][1][0][RTW89_UK][35] = 60, -+ [0][0][1][0][RTW89_FCC][37] = 82, -+ [0][0][1][0][RTW89_ETSI][37] = 127, -+ [0][0][1][0][RTW89_MKK][37] = 78, -+ [0][0][1][0][RTW89_IC][37] = 82, -+ [0][0][1][0][RTW89_KCC][37] = 74, -+ [0][0][1][0][RTW89_ACMA][37] = 78, -+ [0][0][1][0][RTW89_CN][37] = 127, -+ [0][0][1][0][RTW89_UK][37] = 78, -+ [0][0][1][0][RTW89_FCC][38] = 82, -+ [0][0][1][0][RTW89_ETSI][38] = 30, -+ [0][0][1][0][RTW89_MKK][38] = 127, -+ [0][0][1][0][RTW89_IC][38] = 82, -+ [0][0][1][0][RTW89_KCC][38] = 70, -+ [0][0][1][0][RTW89_ACMA][38] = 78, -+ [0][0][1][0][RTW89_CN][38] = 78, -+ [0][0][1][0][RTW89_UK][38] = 58, -+ [0][0][1][0][RTW89_FCC][40] = 82, -+ [0][0][1][0][RTW89_ETSI][40] = 30, -+ [0][0][1][0][RTW89_MKK][40] = 127, -+ [0][0][1][0][RTW89_IC][40] = 82, -+ [0][0][1][0][RTW89_KCC][40] = 76, -+ [0][0][1][0][RTW89_ACMA][40] = 78, -+ [0][0][1][0][RTW89_CN][40] = 78, -+ [0][0][1][0][RTW89_UK][40] = 58, -+ [0][0][1][0][RTW89_FCC][42] = 82, -+ [0][0][1][0][RTW89_ETSI][42] = 30, -+ [0][0][1][0][RTW89_MKK][42] = 127, -+ [0][0][1][0][RTW89_IC][42] = 82, -+ [0][0][1][0][RTW89_KCC][42] = 76, -+ [0][0][1][0][RTW89_ACMA][42] = 78, -+ [0][0][1][0][RTW89_CN][42] = 78, -+ [0][0][1][0][RTW89_UK][42] = 58, -+ [0][0][1][0][RTW89_FCC][44] = 82, -+ [0][0][1][0][RTW89_ETSI][44] = 30, -+ [0][0][1][0][RTW89_MKK][44] = 127, -+ [0][0][1][0][RTW89_IC][44] = 82, -+ [0][0][1][0][RTW89_KCC][44] = 76, -+ [0][0][1][0][RTW89_ACMA][44] = 78, -+ [0][0][1][0][RTW89_CN][44] = 78, -+ [0][0][1][0][RTW89_UK][44] = 58, -+ [0][0][1][0][RTW89_FCC][46] = 82, -+ [0][0][1][0][RTW89_ETSI][46] = 30, -+ [0][0][1][0][RTW89_MKK][46] = 127, -+ [0][0][1][0][RTW89_IC][46] = 82, -+ [0][0][1][0][RTW89_KCC][46] = 76, -+ [0][0][1][0][RTW89_ACMA][46] = 78, -+ [0][0][1][0][RTW89_CN][46] = 78, -+ [0][0][1][0][RTW89_UK][46] = 58, -+ [0][0][1][0][RTW89_FCC][48] = 72, -+ [0][0][1][0][RTW89_ETSI][48] = 127, -+ [0][0][1][0][RTW89_MKK][48] = 127, -+ [0][0][1][0][RTW89_IC][48] = 127, -+ [0][0][1][0][RTW89_KCC][48] = 127, -+ [0][0][1][0][RTW89_ACMA][48] = 127, -+ [0][0][1][0][RTW89_CN][48] = 127, -+ [0][0][1][0][RTW89_UK][48] = 127, -+ [0][0][1][0][RTW89_FCC][50] = 72, -+ [0][0][1][0][RTW89_ETSI][50] = 127, -+ [0][0][1][0][RTW89_MKK][50] = 127, -+ [0][0][1][0][RTW89_IC][50] = 127, -+ [0][0][1][0][RTW89_KCC][50] = 127, -+ [0][0][1][0][RTW89_ACMA][50] = 127, -+ [0][0][1][0][RTW89_CN][50] = 127, -+ [0][0][1][0][RTW89_UK][50] = 127, -+ [0][0][1][0][RTW89_FCC][52] = 72, -+ [0][0][1][0][RTW89_ETSI][52] = 127, -+ [0][0][1][0][RTW89_MKK][52] = 127, -+ [0][0][1][0][RTW89_IC][52] = 127, -+ [0][0][1][0][RTW89_KCC][52] = 127, -+ [0][0][1][0][RTW89_ACMA][52] = 127, -+ [0][0][1][0][RTW89_CN][52] = 127, -+ [0][0][1][0][RTW89_UK][52] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 127, -+ [0][1][1][0][RTW89_ETSI][0] = 127, -+ [0][1][1][0][RTW89_MKK][0] = 127, -+ [0][1][1][0][RTW89_IC][0] = 127, -+ [0][1][1][0][RTW89_KCC][0] = 127, -+ [0][1][1][0][RTW89_ACMA][0] = 127, -+ [0][1][1][0][RTW89_CN][0] = 127, -+ [0][1][1][0][RTW89_UK][0] = 127, -+ [0][1][1][0][RTW89_FCC][2] = 127, -+ [0][1][1][0][RTW89_ETSI][2] = 127, -+ [0][1][1][0][RTW89_MKK][2] = 127, -+ [0][1][1][0][RTW89_IC][2] = 127, -+ [0][1][1][0][RTW89_KCC][2] = 127, -+ [0][1][1][0][RTW89_ACMA][2] = 127, -+ [0][1][1][0][RTW89_CN][2] = 127, -+ [0][1][1][0][RTW89_UK][2] = 127, -+ [0][1][1][0][RTW89_FCC][4] = 127, -+ [0][1][1][0][RTW89_ETSI][4] = 127, -+ [0][1][1][0][RTW89_MKK][4] = 127, -+ [0][1][1][0][RTW89_IC][4] = 127, -+ [0][1][1][0][RTW89_KCC][4] = 127, -+ [0][1][1][0][RTW89_ACMA][4] = 127, -+ [0][1][1][0][RTW89_CN][4] = 127, -+ [0][1][1][0][RTW89_UK][4] = 127, -+ [0][1][1][0][RTW89_FCC][6] = 127, -+ [0][1][1][0][RTW89_ETSI][6] = 127, -+ [0][1][1][0][RTW89_MKK][6] = 127, -+ [0][1][1][0][RTW89_IC][6] = 127, -+ [0][1][1][0][RTW89_KCC][6] = 127, -+ [0][1][1][0][RTW89_ACMA][6] = 127, -+ [0][1][1][0][RTW89_CN][6] = 127, -+ [0][1][1][0][RTW89_UK][6] = 127, -+ [0][1][1][0][RTW89_FCC][8] = 127, -+ [0][1][1][0][RTW89_ETSI][8] = 127, -+ [0][1][1][0][RTW89_MKK][8] = 127, -+ [0][1][1][0][RTW89_IC][8] = 127, -+ [0][1][1][0][RTW89_KCC][8] = 127, -+ [0][1][1][0][RTW89_ACMA][8] = 127, -+ [0][1][1][0][RTW89_CN][8] = 127, -+ [0][1][1][0][RTW89_UK][8] = 127, -+ [0][1][1][0][RTW89_FCC][10] = 127, -+ [0][1][1][0][RTW89_ETSI][10] = 127, -+ [0][1][1][0][RTW89_MKK][10] = 127, -+ [0][1][1][0][RTW89_IC][10] = 127, -+ [0][1][1][0][RTW89_KCC][10] = 127, -+ [0][1][1][0][RTW89_ACMA][10] = 127, -+ [0][1][1][0][RTW89_CN][10] = 127, -+ [0][1][1][0][RTW89_UK][10] = 127, -+ [0][1][1][0][RTW89_FCC][12] = 127, -+ [0][1][1][0][RTW89_ETSI][12] = 127, -+ [0][1][1][0][RTW89_MKK][12] = 127, -+ [0][1][1][0][RTW89_IC][12] = 127, -+ [0][1][1][0][RTW89_KCC][12] = 127, -+ [0][1][1][0][RTW89_ACMA][12] = 127, -+ [0][1][1][0][RTW89_CN][12] = 127, -+ [0][1][1][0][RTW89_UK][12] = 127, -+ [0][1][1][0][RTW89_FCC][14] = 127, -+ [0][1][1][0][RTW89_ETSI][14] = 127, -+ [0][1][1][0][RTW89_MKK][14] = 127, -+ [0][1][1][0][RTW89_IC][14] = 127, -+ [0][1][1][0][RTW89_KCC][14] = 127, -+ [0][1][1][0][RTW89_ACMA][14] = 127, -+ [0][1][1][0][RTW89_CN][14] = 127, -+ [0][1][1][0][RTW89_UK][14] = 127, -+ [0][1][1][0][RTW89_FCC][15] = 127, -+ [0][1][1][0][RTW89_ETSI][15] = 127, -+ [0][1][1][0][RTW89_MKK][15] = 127, -+ [0][1][1][0][RTW89_IC][15] = 127, -+ [0][1][1][0][RTW89_KCC][15] = 127, -+ [0][1][1][0][RTW89_ACMA][15] = 127, -+ [0][1][1][0][RTW89_CN][15] = 127, -+ [0][1][1][0][RTW89_UK][15] = 127, -+ [0][1][1][0][RTW89_FCC][17] = 127, -+ [0][1][1][0][RTW89_ETSI][17] = 127, -+ [0][1][1][0][RTW89_MKK][17] = 127, -+ [0][1][1][0][RTW89_IC][17] = 127, -+ [0][1][1][0][RTW89_KCC][17] = 127, -+ [0][1][1][0][RTW89_ACMA][17] = 127, -+ [0][1][1][0][RTW89_CN][17] = 127, -+ [0][1][1][0][RTW89_UK][17] = 127, -+ [0][1][1][0][RTW89_FCC][19] = 127, -+ [0][1][1][0][RTW89_ETSI][19] = 127, -+ [0][1][1][0][RTW89_MKK][19] = 127, -+ [0][1][1][0][RTW89_IC][19] = 127, -+ [0][1][1][0][RTW89_KCC][19] = 127, -+ [0][1][1][0][RTW89_ACMA][19] = 127, -+ [0][1][1][0][RTW89_CN][19] = 127, -+ [0][1][1][0][RTW89_UK][19] = 127, -+ [0][1][1][0][RTW89_FCC][21] = 127, -+ [0][1][1][0][RTW89_ETSI][21] = 127, -+ [0][1][1][0][RTW89_MKK][21] = 127, -+ [0][1][1][0][RTW89_IC][21] = 127, -+ [0][1][1][0][RTW89_KCC][21] = 127, -+ [0][1][1][0][RTW89_ACMA][21] = 127, -+ [0][1][1][0][RTW89_CN][21] = 127, -+ [0][1][1][0][RTW89_UK][21] = 127, -+ [0][1][1][0][RTW89_FCC][23] = 127, -+ [0][1][1][0][RTW89_ETSI][23] = 127, -+ [0][1][1][0][RTW89_MKK][23] = 127, -+ [0][1][1][0][RTW89_IC][23] = 127, -+ [0][1][1][0][RTW89_KCC][23] = 127, -+ [0][1][1][0][RTW89_ACMA][23] = 127, -+ [0][1][1][0][RTW89_CN][23] = 127, -+ [0][1][1][0][RTW89_UK][23] = 127, -+ [0][1][1][0][RTW89_FCC][25] = 127, -+ [0][1][1][0][RTW89_ETSI][25] = 127, -+ [0][1][1][0][RTW89_MKK][25] = 127, -+ [0][1][1][0][RTW89_IC][25] = 127, -+ [0][1][1][0][RTW89_KCC][25] = 127, -+ [0][1][1][0][RTW89_ACMA][25] = 127, -+ [0][1][1][0][RTW89_CN][25] = 127, -+ [0][1][1][0][RTW89_UK][25] = 127, -+ [0][1][1][0][RTW89_FCC][27] = 127, -+ [0][1][1][0][RTW89_ETSI][27] = 127, -+ [0][1][1][0][RTW89_MKK][27] = 127, -+ [0][1][1][0][RTW89_IC][27] = 127, -+ [0][1][1][0][RTW89_KCC][27] = 127, -+ [0][1][1][0][RTW89_ACMA][27] = 127, -+ [0][1][1][0][RTW89_CN][27] = 127, -+ [0][1][1][0][RTW89_UK][27] = 127, -+ [0][1][1][0][RTW89_FCC][29] = 127, -+ [0][1][1][0][RTW89_ETSI][29] = 127, -+ [0][1][1][0][RTW89_MKK][29] = 127, -+ [0][1][1][0][RTW89_IC][29] = 127, -+ [0][1][1][0][RTW89_KCC][29] = 127, -+ [0][1][1][0][RTW89_ACMA][29] = 127, -+ [0][1][1][0][RTW89_CN][29] = 127, -+ [0][1][1][0][RTW89_UK][29] = 127, -+ [0][1][1][0][RTW89_FCC][31] = 127, -+ [0][1][1][0][RTW89_ETSI][31] = 127, -+ [0][1][1][0][RTW89_MKK][31] = 127, -+ [0][1][1][0][RTW89_IC][31] = 127, -+ [0][1][1][0][RTW89_KCC][31] = 127, -+ [0][1][1][0][RTW89_ACMA][31] = 127, -+ [0][1][1][0][RTW89_CN][31] = 127, -+ [0][1][1][0][RTW89_UK][31] = 127, -+ [0][1][1][0][RTW89_FCC][33] = 127, -+ [0][1][1][0][RTW89_ETSI][33] = 127, -+ [0][1][1][0][RTW89_MKK][33] = 127, -+ [0][1][1][0][RTW89_IC][33] = 127, -+ [0][1][1][0][RTW89_KCC][33] = 127, -+ [0][1][1][0][RTW89_ACMA][33] = 127, -+ [0][1][1][0][RTW89_CN][33] = 127, -+ [0][1][1][0][RTW89_UK][33] = 127, -+ [0][1][1][0][RTW89_FCC][35] = 127, -+ [0][1][1][0][RTW89_ETSI][35] = 127, -+ [0][1][1][0][RTW89_MKK][35] = 127, -+ [0][1][1][0][RTW89_IC][35] = 127, -+ [0][1][1][0][RTW89_KCC][35] = 127, -+ [0][1][1][0][RTW89_ACMA][35] = 127, -+ [0][1][1][0][RTW89_CN][35] = 127, -+ [0][1][1][0][RTW89_UK][35] = 127, -+ [0][1][1][0][RTW89_FCC][37] = 127, -+ [0][1][1][0][RTW89_ETSI][37] = 127, -+ [0][1][1][0][RTW89_MKK][37] = 127, -+ [0][1][1][0][RTW89_IC][37] = 127, -+ [0][1][1][0][RTW89_KCC][37] = 127, -+ [0][1][1][0][RTW89_ACMA][37] = 127, -+ [0][1][1][0][RTW89_CN][37] = 127, -+ [0][1][1][0][RTW89_UK][37] = 127, -+ [0][1][1][0][RTW89_FCC][38] = 127, -+ [0][1][1][0][RTW89_ETSI][38] = 127, -+ [0][1][1][0][RTW89_MKK][38] = 127, -+ [0][1][1][0][RTW89_IC][38] = 127, -+ [0][1][1][0][RTW89_KCC][38] = 127, -+ [0][1][1][0][RTW89_ACMA][38] = 127, -+ [0][1][1][0][RTW89_CN][38] = 127, -+ [0][1][1][0][RTW89_UK][38] = 127, -+ [0][1][1][0][RTW89_FCC][40] = 127, -+ [0][1][1][0][RTW89_ETSI][40] = 127, -+ [0][1][1][0][RTW89_MKK][40] = 127, -+ [0][1][1][0][RTW89_IC][40] = 127, -+ [0][1][1][0][RTW89_KCC][40] = 127, -+ [0][1][1][0][RTW89_ACMA][40] = 127, -+ [0][1][1][0][RTW89_CN][40] = 127, -+ [0][1][1][0][RTW89_UK][40] = 127, -+ [0][1][1][0][RTW89_FCC][42] = 127, -+ [0][1][1][0][RTW89_ETSI][42] = 127, -+ [0][1][1][0][RTW89_MKK][42] = 127, -+ [0][1][1][0][RTW89_IC][42] = 127, -+ [0][1][1][0][RTW89_KCC][42] = 127, -+ [0][1][1][0][RTW89_ACMA][42] = 127, -+ [0][1][1][0][RTW89_CN][42] = 127, -+ [0][1][1][0][RTW89_UK][42] = 127, -+ [0][1][1][0][RTW89_FCC][44] = 127, -+ [0][1][1][0][RTW89_ETSI][44] = 127, -+ [0][1][1][0][RTW89_MKK][44] = 127, -+ [0][1][1][0][RTW89_IC][44] = 127, -+ [0][1][1][0][RTW89_KCC][44] = 127, -+ [0][1][1][0][RTW89_ACMA][44] = 127, -+ [0][1][1][0][RTW89_CN][44] = 127, -+ [0][1][1][0][RTW89_UK][44] = 127, -+ [0][1][1][0][RTW89_FCC][46] = 127, -+ [0][1][1][0][RTW89_ETSI][46] = 127, -+ [0][1][1][0][RTW89_MKK][46] = 127, -+ [0][1][1][0][RTW89_IC][46] = 127, -+ [0][1][1][0][RTW89_KCC][46] = 127, -+ [0][1][1][0][RTW89_ACMA][46] = 127, -+ [0][1][1][0][RTW89_CN][46] = 127, -+ [0][1][1][0][RTW89_UK][46] = 127, -+ [0][1][1][0][RTW89_FCC][48] = 127, -+ [0][1][1][0][RTW89_ETSI][48] = 127, -+ [0][1][1][0][RTW89_MKK][48] = 127, -+ [0][1][1][0][RTW89_IC][48] = 127, -+ [0][1][1][0][RTW89_KCC][48] = 127, -+ [0][1][1][0][RTW89_ACMA][48] = 127, -+ [0][1][1][0][RTW89_CN][48] = 127, -+ [0][1][1][0][RTW89_UK][48] = 127, -+ [0][1][1][0][RTW89_FCC][50] = 127, -+ [0][1][1][0][RTW89_ETSI][50] = 127, -+ [0][1][1][0][RTW89_MKK][50] = 127, -+ [0][1][1][0][RTW89_IC][50] = 127, -+ [0][1][1][0][RTW89_KCC][50] = 127, -+ [0][1][1][0][RTW89_ACMA][50] = 127, -+ [0][1][1][0][RTW89_CN][50] = 127, -+ [0][1][1][0][RTW89_UK][50] = 127, -+ [0][1][1][0][RTW89_FCC][52] = 127, -+ [0][1][1][0][RTW89_ETSI][52] = 127, -+ [0][1][1][0][RTW89_MKK][52] = 127, -+ [0][1][1][0][RTW89_IC][52] = 127, -+ [0][1][1][0][RTW89_KCC][52] = 127, -+ [0][1][1][0][RTW89_ACMA][52] = 127, -+ [0][1][1][0][RTW89_CN][52] = 127, -+ [0][1][1][0][RTW89_UK][52] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 78, -+ [0][0][2][0][RTW89_ETSI][0] = 62, -+ [0][0][2][0][RTW89_MKK][0] = 62, -+ [0][0][2][0][RTW89_IC][0] = 64, -+ [0][0][2][0][RTW89_KCC][0] = 76, -+ [0][0][2][0][RTW89_ACMA][0] = 62, -+ [0][0][2][0][RTW89_CN][0] = 62, -+ [0][0][2][0][RTW89_UK][0] = 62, -+ [0][0][2][0][RTW89_FCC][2] = 82, -+ [0][0][2][0][RTW89_ETSI][2] = 62, -+ [0][0][2][0][RTW89_MKK][2] = 62, -+ [0][0][2][0][RTW89_IC][2] = 64, -+ [0][0][2][0][RTW89_KCC][2] = 76, -+ [0][0][2][0][RTW89_ACMA][2] = 62, -+ [0][0][2][0][RTW89_CN][2] = 62, -+ [0][0][2][0][RTW89_UK][2] = 62, -+ [0][0][2][0][RTW89_FCC][4] = 82, -+ [0][0][2][0][RTW89_ETSI][4] = 62, -+ [0][0][2][0][RTW89_MKK][4] = 62, -+ [0][0][2][0][RTW89_IC][4] = 64, -+ [0][0][2][0][RTW89_KCC][4] = 76, -+ [0][0][2][0][RTW89_ACMA][4] = 62, -+ [0][0][2][0][RTW89_CN][4] = 62, -+ [0][0][2][0][RTW89_UK][4] = 62, -+ [0][0][2][0][RTW89_FCC][6] = 82, -+ [0][0][2][0][RTW89_ETSI][6] = 62, -+ [0][0][2][0][RTW89_MKK][6] = 62, -+ [0][0][2][0][RTW89_IC][6] = 64, -+ [0][0][2][0][RTW89_KCC][6] = 54, -+ [0][0][2][0][RTW89_ACMA][6] = 62, -+ [0][0][2][0][RTW89_CN][6] = 62, -+ [0][0][2][0][RTW89_UK][6] = 62, -+ [0][0][2][0][RTW89_FCC][8] = 82, -+ [0][0][2][0][RTW89_ETSI][8] = 62, -+ [0][0][2][0][RTW89_MKK][8] = 62, -+ [0][0][2][0][RTW89_IC][8] = 64, -+ [0][0][2][0][RTW89_KCC][8] = 76, -+ [0][0][2][0][RTW89_ACMA][8] = 62, -+ [0][0][2][0][RTW89_CN][8] = 62, -+ [0][0][2][0][RTW89_UK][8] = 62, -+ [0][0][2][0][RTW89_FCC][10] = 82, -+ [0][0][2][0][RTW89_ETSI][10] = 62, -+ [0][0][2][0][RTW89_MKK][10] = 62, -+ [0][0][2][0][RTW89_IC][10] = 64, -+ [0][0][2][0][RTW89_KCC][10] = 76, -+ [0][0][2][0][RTW89_ACMA][10] = 62, -+ [0][0][2][0][RTW89_CN][10] = 62, -+ [0][0][2][0][RTW89_UK][10] = 62, -+ [0][0][2][0][RTW89_FCC][12] = 82, -+ [0][0][2][0][RTW89_ETSI][12] = 62, -+ [0][0][2][0][RTW89_MKK][12] = 62, -+ [0][0][2][0][RTW89_IC][12] = 64, -+ [0][0][2][0][RTW89_KCC][12] = 78, -+ [0][0][2][0][RTW89_ACMA][12] = 62, -+ [0][0][2][0][RTW89_CN][12] = 62, -+ [0][0][2][0][RTW89_UK][12] = 62, -+ [0][0][2][0][RTW89_FCC][14] = 76, -+ [0][0][2][0][RTW89_ETSI][14] = 62, -+ [0][0][2][0][RTW89_MKK][14] = 62, -+ [0][0][2][0][RTW89_IC][14] = 64, -+ [0][0][2][0][RTW89_KCC][14] = 78, -+ [0][0][2][0][RTW89_ACMA][14] = 62, -+ [0][0][2][0][RTW89_CN][14] = 62, -+ [0][0][2][0][RTW89_UK][14] = 62, -+ [0][0][2][0][RTW89_FCC][15] = 76, -+ [0][0][2][0][RTW89_ETSI][15] = 60, -+ [0][0][2][0][RTW89_MKK][15] = 78, -+ [0][0][2][0][RTW89_IC][15] = 76, -+ [0][0][2][0][RTW89_KCC][15] = 78, -+ [0][0][2][0][RTW89_ACMA][15] = 60, -+ [0][0][2][0][RTW89_CN][15] = 127, -+ [0][0][2][0][RTW89_UK][15] = 60, -+ [0][0][2][0][RTW89_FCC][17] = 82, -+ [0][0][2][0][RTW89_ETSI][17] = 62, -+ [0][0][2][0][RTW89_MKK][17] = 78, -+ [0][0][2][0][RTW89_IC][17] = 82, -+ [0][0][2][0][RTW89_KCC][17] = 78, -+ [0][0][2][0][RTW89_ACMA][17] = 62, -+ [0][0][2][0][RTW89_CN][17] = 127, -+ [0][0][2][0][RTW89_UK][17] = 62, -+ [0][0][2][0][RTW89_FCC][19] = 82, -+ [0][0][2][0][RTW89_ETSI][19] = 62, -+ [0][0][2][0][RTW89_MKK][19] = 78, -+ [0][0][2][0][RTW89_IC][19] = 82, -+ [0][0][2][0][RTW89_KCC][19] = 78, -+ [0][0][2][0][RTW89_ACMA][19] = 62, -+ [0][0][2][0][RTW89_CN][19] = 127, -+ [0][0][2][0][RTW89_UK][19] = 62, -+ [0][0][2][0][RTW89_FCC][21] = 82, -+ [0][0][2][0][RTW89_ETSI][21] = 62, -+ [0][0][2][0][RTW89_MKK][21] = 78, -+ [0][0][2][0][RTW89_IC][21] = 82, -+ [0][0][2][0][RTW89_KCC][21] = 78, -+ [0][0][2][0][RTW89_ACMA][21] = 62, -+ [0][0][2][0][RTW89_CN][21] = 127, -+ [0][0][2][0][RTW89_UK][21] = 62, -+ [0][0][2][0][RTW89_FCC][23] = 82, -+ [0][0][2][0][RTW89_ETSI][23] = 62, -+ [0][0][2][0][RTW89_MKK][23] = 78, -+ [0][0][2][0][RTW89_IC][23] = 82, -+ [0][0][2][0][RTW89_KCC][23] = 78, -+ [0][0][2][0][RTW89_ACMA][23] = 62, -+ [0][0][2][0][RTW89_CN][23] = 127, -+ [0][0][2][0][RTW89_UK][23] = 62, -+ [0][0][2][0][RTW89_FCC][25] = 82, -+ [0][0][2][0][RTW89_ETSI][25] = 62, -+ [0][0][2][0][RTW89_MKK][25] = 78, -+ [0][0][2][0][RTW89_IC][25] = 127, -+ [0][0][2][0][RTW89_KCC][25] = 78, -+ [0][0][2][0][RTW89_ACMA][25] = 127, -+ [0][0][2][0][RTW89_CN][25] = 127, -+ [0][0][2][0][RTW89_UK][25] = 62, -+ [0][0][2][0][RTW89_FCC][27] = 82, -+ [0][0][2][0][RTW89_ETSI][27] = 62, -+ [0][0][2][0][RTW89_MKK][27] = 78, -+ [0][0][2][0][RTW89_IC][27] = 127, -+ [0][0][2][0][RTW89_KCC][27] = 78, -+ [0][0][2][0][RTW89_ACMA][27] = 127, -+ [0][0][2][0][RTW89_CN][27] = 127, -+ [0][0][2][0][RTW89_UK][27] = 62, -+ [0][0][2][0][RTW89_FCC][29] = 82, -+ [0][0][2][0][RTW89_ETSI][29] = 62, -+ [0][0][2][0][RTW89_MKK][29] = 78, -+ [0][0][2][0][RTW89_IC][29] = 127, -+ [0][0][2][0][RTW89_KCC][29] = 78, -+ [0][0][2][0][RTW89_ACMA][29] = 127, -+ [0][0][2][0][RTW89_CN][29] = 127, -+ [0][0][2][0][RTW89_UK][29] = 62, -+ [0][0][2][0][RTW89_FCC][31] = 82, -+ [0][0][2][0][RTW89_ETSI][31] = 62, -+ [0][0][2][0][RTW89_MKK][31] = 78, -+ [0][0][2][0][RTW89_IC][31] = 82, -+ [0][0][2][0][RTW89_KCC][31] = 74, -+ [0][0][2][0][RTW89_ACMA][31] = 62, -+ [0][0][2][0][RTW89_CN][31] = 127, -+ [0][0][2][0][RTW89_UK][31] = 62, -+ [0][0][2][0][RTW89_FCC][33] = 82, -+ [0][0][2][0][RTW89_ETSI][33] = 62, -+ [0][0][2][0][RTW89_MKK][33] = 78, -+ [0][0][2][0][RTW89_IC][33] = 82, -+ [0][0][2][0][RTW89_KCC][33] = 74, -+ [0][0][2][0][RTW89_ACMA][33] = 62, -+ [0][0][2][0][RTW89_CN][33] = 127, -+ [0][0][2][0][RTW89_UK][33] = 62, -+ [0][0][2][0][RTW89_FCC][35] = 72, -+ [0][0][2][0][RTW89_ETSI][35] = 62, -+ [0][0][2][0][RTW89_MKK][35] = 78, -+ [0][0][2][0][RTW89_IC][35] = 72, -+ [0][0][2][0][RTW89_KCC][35] = 74, -+ [0][0][2][0][RTW89_ACMA][35] = 62, -+ [0][0][2][0][RTW89_CN][35] = 127, -+ [0][0][2][0][RTW89_UK][35] = 62, -+ [0][0][2][0][RTW89_FCC][37] = 82, -+ [0][0][2][0][RTW89_ETSI][37] = 127, -+ [0][0][2][0][RTW89_MKK][37] = 78, -+ [0][0][2][0][RTW89_IC][37] = 82, -+ [0][0][2][0][RTW89_KCC][37] = 76, -+ [0][0][2][0][RTW89_ACMA][37] = 78, -+ [0][0][2][0][RTW89_CN][37] = 127, -+ [0][0][2][0][RTW89_UK][37] = 78, -+ [0][0][2][0][RTW89_FCC][38] = 82, -+ [0][0][2][0][RTW89_ETSI][38] = 30, -+ [0][0][2][0][RTW89_MKK][38] = 127, -+ [0][0][2][0][RTW89_IC][38] = 82, -+ [0][0][2][0][RTW89_KCC][38] = 66, -+ [0][0][2][0][RTW89_ACMA][38] = 78, -+ [0][0][2][0][RTW89_CN][38] = 78, -+ [0][0][2][0][RTW89_UK][38] = 60, -+ [0][0][2][0][RTW89_FCC][40] = 82, -+ [0][0][2][0][RTW89_ETSI][40] = 30, -+ [0][0][2][0][RTW89_MKK][40] = 127, -+ [0][0][2][0][RTW89_IC][40] = 82, -+ [0][0][2][0][RTW89_KCC][40] = 74, -+ [0][0][2][0][RTW89_ACMA][40] = 78, -+ [0][0][2][0][RTW89_CN][40] = 78, -+ [0][0][2][0][RTW89_UK][40] = 60, -+ [0][0][2][0][RTW89_FCC][42] = 82, -+ [0][0][2][0][RTW89_ETSI][42] = 30, -+ [0][0][2][0][RTW89_MKK][42] = 127, -+ [0][0][2][0][RTW89_IC][42] = 82, -+ [0][0][2][0][RTW89_KCC][42] = 74, -+ [0][0][2][0][RTW89_ACMA][42] = 78, -+ [0][0][2][0][RTW89_CN][42] = 78, -+ [0][0][2][0][RTW89_UK][42] = 60, -+ [0][0][2][0][RTW89_FCC][44] = 82, -+ [0][0][2][0][RTW89_ETSI][44] = 30, -+ [0][0][2][0][RTW89_MKK][44] = 127, -+ [0][0][2][0][RTW89_IC][44] = 82, -+ [0][0][2][0][RTW89_KCC][44] = 74, -+ [0][0][2][0][RTW89_ACMA][44] = 78, -+ [0][0][2][0][RTW89_CN][44] = 78, -+ [0][0][2][0][RTW89_UK][44] = 60, -+ [0][0][2][0][RTW89_FCC][46] = 82, -+ [0][0][2][0][RTW89_ETSI][46] = 30, -+ [0][0][2][0][RTW89_MKK][46] = 127, -+ [0][0][2][0][RTW89_IC][46] = 82, -+ [0][0][2][0][RTW89_KCC][46] = 74, -+ [0][0][2][0][RTW89_ACMA][46] = 78, -+ [0][0][2][0][RTW89_CN][46] = 78, -+ [0][0][2][0][RTW89_UK][46] = 60, -+ [0][0][2][0][RTW89_FCC][48] = 74, -+ [0][0][2][0][RTW89_ETSI][48] = 127, -+ [0][0][2][0][RTW89_MKK][48] = 127, -+ [0][0][2][0][RTW89_IC][48] = 127, -+ [0][0][2][0][RTW89_KCC][48] = 127, -+ [0][0][2][0][RTW89_ACMA][48] = 127, -+ [0][0][2][0][RTW89_CN][48] = 127, -+ [0][0][2][0][RTW89_UK][48] = 127, -+ [0][0][2][0][RTW89_FCC][50] = 76, -+ [0][0][2][0][RTW89_ETSI][50] = 127, -+ [0][0][2][0][RTW89_MKK][50] = 127, -+ [0][0][2][0][RTW89_IC][50] = 127, -+ [0][0][2][0][RTW89_KCC][50] = 127, -+ [0][0][2][0][RTW89_ACMA][50] = 127, -+ [0][0][2][0][RTW89_CN][50] = 127, -+ [0][0][2][0][RTW89_UK][50] = 127, -+ [0][0][2][0][RTW89_FCC][52] = 76, -+ [0][0][2][0][RTW89_ETSI][52] = 127, -+ [0][0][2][0][RTW89_MKK][52] = 127, -+ [0][0][2][0][RTW89_IC][52] = 127, -+ [0][0][2][0][RTW89_KCC][52] = 127, -+ [0][0][2][0][RTW89_ACMA][52] = 127, -+ [0][0][2][0][RTW89_CN][52] = 127, -+ [0][0][2][0][RTW89_UK][52] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 127, -+ [0][1][2][0][RTW89_ETSI][0] = 127, -+ [0][1][2][0][RTW89_MKK][0] = 127, -+ [0][1][2][0][RTW89_IC][0] = 127, -+ [0][1][2][0][RTW89_KCC][0] = 127, -+ [0][1][2][0][RTW89_ACMA][0] = 127, -+ [0][1][2][0][RTW89_CN][0] = 127, -+ [0][1][2][0][RTW89_UK][0] = 127, -+ [0][1][2][0][RTW89_FCC][2] = 127, -+ [0][1][2][0][RTW89_ETSI][2] = 127, -+ [0][1][2][0][RTW89_MKK][2] = 127, -+ [0][1][2][0][RTW89_IC][2] = 127, -+ [0][1][2][0][RTW89_KCC][2] = 127, -+ [0][1][2][0][RTW89_ACMA][2] = 127, -+ [0][1][2][0][RTW89_CN][2] = 127, -+ [0][1][2][0][RTW89_UK][2] = 127, -+ [0][1][2][0][RTW89_FCC][4] = 127, -+ [0][1][2][0][RTW89_ETSI][4] = 127, -+ [0][1][2][0][RTW89_MKK][4] = 127, -+ [0][1][2][0][RTW89_IC][4] = 127, -+ [0][1][2][0][RTW89_KCC][4] = 127, -+ [0][1][2][0][RTW89_ACMA][4] = 127, -+ [0][1][2][0][RTW89_CN][4] = 127, -+ [0][1][2][0][RTW89_UK][4] = 127, -+ [0][1][2][0][RTW89_FCC][6] = 127, -+ [0][1][2][0][RTW89_ETSI][6] = 127, -+ [0][1][2][0][RTW89_MKK][6] = 127, -+ [0][1][2][0][RTW89_IC][6] = 127, -+ [0][1][2][0][RTW89_KCC][6] = 127, -+ [0][1][2][0][RTW89_ACMA][6] = 127, -+ [0][1][2][0][RTW89_CN][6] = 127, -+ [0][1][2][0][RTW89_UK][6] = 127, -+ [0][1][2][0][RTW89_FCC][8] = 127, -+ [0][1][2][0][RTW89_ETSI][8] = 127, -+ [0][1][2][0][RTW89_MKK][8] = 127, -+ [0][1][2][0][RTW89_IC][8] = 127, -+ [0][1][2][0][RTW89_KCC][8] = 127, -+ [0][1][2][0][RTW89_ACMA][8] = 127, -+ [0][1][2][0][RTW89_CN][8] = 127, -+ [0][1][2][0][RTW89_UK][8] = 127, -+ [0][1][2][0][RTW89_FCC][10] = 127, -+ [0][1][2][0][RTW89_ETSI][10] = 127, -+ [0][1][2][0][RTW89_MKK][10] = 127, -+ [0][1][2][0][RTW89_IC][10] = 127, -+ [0][1][2][0][RTW89_KCC][10] = 127, -+ [0][1][2][0][RTW89_ACMA][10] = 127, -+ [0][1][2][0][RTW89_CN][10] = 127, -+ [0][1][2][0][RTW89_UK][10] = 127, -+ [0][1][2][0][RTW89_FCC][12] = 127, -+ [0][1][2][0][RTW89_ETSI][12] = 127, -+ [0][1][2][0][RTW89_MKK][12] = 127, -+ [0][1][2][0][RTW89_IC][12] = 127, -+ [0][1][2][0][RTW89_KCC][12] = 127, -+ [0][1][2][0][RTW89_ACMA][12] = 127, -+ [0][1][2][0][RTW89_CN][12] = 127, -+ [0][1][2][0][RTW89_UK][12] = 127, -+ [0][1][2][0][RTW89_FCC][14] = 127, -+ [0][1][2][0][RTW89_ETSI][14] = 127, -+ [0][1][2][0][RTW89_MKK][14] = 127, -+ [0][1][2][0][RTW89_IC][14] = 127, -+ [0][1][2][0][RTW89_KCC][14] = 127, -+ [0][1][2][0][RTW89_ACMA][14] = 127, -+ [0][1][2][0][RTW89_CN][14] = 127, -+ [0][1][2][0][RTW89_UK][14] = 127, -+ [0][1][2][0][RTW89_FCC][15] = 127, -+ [0][1][2][0][RTW89_ETSI][15] = 127, -+ [0][1][2][0][RTW89_MKK][15] = 127, -+ [0][1][2][0][RTW89_IC][15] = 127, -+ [0][1][2][0][RTW89_KCC][15] = 127, -+ [0][1][2][0][RTW89_ACMA][15] = 127, -+ [0][1][2][0][RTW89_CN][15] = 127, -+ [0][1][2][0][RTW89_UK][15] = 127, -+ [0][1][2][0][RTW89_FCC][17] = 127, -+ [0][1][2][0][RTW89_ETSI][17] = 127, -+ [0][1][2][0][RTW89_MKK][17] = 127, -+ [0][1][2][0][RTW89_IC][17] = 127, -+ [0][1][2][0][RTW89_KCC][17] = 127, -+ [0][1][2][0][RTW89_ACMA][17] = 127, -+ [0][1][2][0][RTW89_CN][17] = 127, -+ [0][1][2][0][RTW89_UK][17] = 127, -+ [0][1][2][0][RTW89_FCC][19] = 127, -+ [0][1][2][0][RTW89_ETSI][19] = 127, -+ [0][1][2][0][RTW89_MKK][19] = 127, -+ [0][1][2][0][RTW89_IC][19] = 127, -+ [0][1][2][0][RTW89_KCC][19] = 127, -+ [0][1][2][0][RTW89_ACMA][19] = 127, -+ [0][1][2][0][RTW89_CN][19] = 127, -+ [0][1][2][0][RTW89_UK][19] = 127, -+ [0][1][2][0][RTW89_FCC][21] = 127, -+ [0][1][2][0][RTW89_ETSI][21] = 127, -+ [0][1][2][0][RTW89_MKK][21] = 127, -+ [0][1][2][0][RTW89_IC][21] = 127, -+ [0][1][2][0][RTW89_KCC][21] = 127, -+ [0][1][2][0][RTW89_ACMA][21] = 127, -+ [0][1][2][0][RTW89_CN][21] = 127, -+ [0][1][2][0][RTW89_UK][21] = 127, -+ [0][1][2][0][RTW89_FCC][23] = 127, -+ [0][1][2][0][RTW89_ETSI][23] = 127, -+ [0][1][2][0][RTW89_MKK][23] = 127, -+ [0][1][2][0][RTW89_IC][23] = 127, -+ [0][1][2][0][RTW89_KCC][23] = 127, -+ [0][1][2][0][RTW89_ACMA][23] = 127, -+ [0][1][2][0][RTW89_CN][23] = 127, -+ [0][1][2][0][RTW89_UK][23] = 127, -+ [0][1][2][0][RTW89_FCC][25] = 127, -+ [0][1][2][0][RTW89_ETSI][25] = 127, -+ [0][1][2][0][RTW89_MKK][25] = 127, -+ [0][1][2][0][RTW89_IC][25] = 127, -+ [0][1][2][0][RTW89_KCC][25] = 127, -+ [0][1][2][0][RTW89_ACMA][25] = 127, -+ [0][1][2][0][RTW89_CN][25] = 127, -+ [0][1][2][0][RTW89_UK][25] = 127, -+ [0][1][2][0][RTW89_FCC][27] = 127, -+ [0][1][2][0][RTW89_ETSI][27] = 127, -+ [0][1][2][0][RTW89_MKK][27] = 127, -+ [0][1][2][0][RTW89_IC][27] = 127, -+ [0][1][2][0][RTW89_KCC][27] = 127, -+ [0][1][2][0][RTW89_ACMA][27] = 127, -+ [0][1][2][0][RTW89_CN][27] = 127, -+ [0][1][2][0][RTW89_UK][27] = 127, -+ [0][1][2][0][RTW89_FCC][29] = 127, -+ [0][1][2][0][RTW89_ETSI][29] = 127, -+ [0][1][2][0][RTW89_MKK][29] = 127, -+ [0][1][2][0][RTW89_IC][29] = 127, -+ [0][1][2][0][RTW89_KCC][29] = 127, -+ [0][1][2][0][RTW89_ACMA][29] = 127, -+ [0][1][2][0][RTW89_CN][29] = 127, -+ [0][1][2][0][RTW89_UK][29] = 127, -+ [0][1][2][0][RTW89_FCC][31] = 127, -+ [0][1][2][0][RTW89_ETSI][31] = 127, -+ [0][1][2][0][RTW89_MKK][31] = 127, -+ [0][1][2][0][RTW89_IC][31] = 127, -+ [0][1][2][0][RTW89_KCC][31] = 127, -+ [0][1][2][0][RTW89_ACMA][31] = 127, -+ [0][1][2][0][RTW89_CN][31] = 127, -+ [0][1][2][0][RTW89_UK][31] = 127, -+ [0][1][2][0][RTW89_FCC][33] = 127, -+ [0][1][2][0][RTW89_ETSI][33] = 127, -+ [0][1][2][0][RTW89_MKK][33] = 127, -+ [0][1][2][0][RTW89_IC][33] = 127, -+ [0][1][2][0][RTW89_KCC][33] = 127, -+ [0][1][2][0][RTW89_ACMA][33] = 127, -+ [0][1][2][0][RTW89_CN][33] = 127, -+ [0][1][2][0][RTW89_UK][33] = 127, -+ [0][1][2][0][RTW89_FCC][35] = 127, -+ [0][1][2][0][RTW89_ETSI][35] = 127, -+ [0][1][2][0][RTW89_MKK][35] = 127, -+ [0][1][2][0][RTW89_IC][35] = 127, -+ [0][1][2][0][RTW89_KCC][35] = 127, -+ [0][1][2][0][RTW89_ACMA][35] = 127, -+ [0][1][2][0][RTW89_CN][35] = 127, -+ [0][1][2][0][RTW89_UK][35] = 127, -+ [0][1][2][0][RTW89_FCC][37] = 127, -+ [0][1][2][0][RTW89_ETSI][37] = 127, -+ [0][1][2][0][RTW89_MKK][37] = 127, -+ [0][1][2][0][RTW89_IC][37] = 127, -+ [0][1][2][0][RTW89_KCC][37] = 127, -+ [0][1][2][0][RTW89_ACMA][37] = 127, -+ [0][1][2][0][RTW89_CN][37] = 127, -+ [0][1][2][0][RTW89_UK][37] = 127, -+ [0][1][2][0][RTW89_FCC][38] = 127, -+ [0][1][2][0][RTW89_ETSI][38] = 127, -+ [0][1][2][0][RTW89_MKK][38] = 127, -+ [0][1][2][0][RTW89_IC][38] = 127, -+ [0][1][2][0][RTW89_KCC][38] = 127, -+ [0][1][2][0][RTW89_ACMA][38] = 127, -+ [0][1][2][0][RTW89_CN][38] = 127, -+ [0][1][2][0][RTW89_UK][38] = 127, -+ [0][1][2][0][RTW89_FCC][40] = 127, -+ [0][1][2][0][RTW89_ETSI][40] = 127, -+ [0][1][2][0][RTW89_MKK][40] = 127, -+ [0][1][2][0][RTW89_IC][40] = 127, -+ [0][1][2][0][RTW89_KCC][40] = 127, -+ [0][1][2][0][RTW89_ACMA][40] = 127, -+ [0][1][2][0][RTW89_CN][40] = 127, -+ [0][1][2][0][RTW89_UK][40] = 127, -+ [0][1][2][0][RTW89_FCC][42] = 127, -+ [0][1][2][0][RTW89_ETSI][42] = 127, -+ [0][1][2][0][RTW89_MKK][42] = 127, -+ [0][1][2][0][RTW89_IC][42] = 127, -+ [0][1][2][0][RTW89_KCC][42] = 127, -+ [0][1][2][0][RTW89_ACMA][42] = 127, -+ [0][1][2][0][RTW89_CN][42] = 127, -+ [0][1][2][0][RTW89_UK][42] = 127, -+ [0][1][2][0][RTW89_FCC][44] = 127, -+ [0][1][2][0][RTW89_ETSI][44] = 127, -+ [0][1][2][0][RTW89_MKK][44] = 127, -+ [0][1][2][0][RTW89_IC][44] = 127, -+ [0][1][2][0][RTW89_KCC][44] = 127, -+ [0][1][2][0][RTW89_ACMA][44] = 127, -+ [0][1][2][0][RTW89_CN][44] = 127, -+ [0][1][2][0][RTW89_UK][44] = 127, -+ [0][1][2][0][RTW89_FCC][46] = 127, -+ [0][1][2][0][RTW89_ETSI][46] = 127, -+ [0][1][2][0][RTW89_MKK][46] = 127, -+ [0][1][2][0][RTW89_IC][46] = 127, -+ [0][1][2][0][RTW89_KCC][46] = 127, -+ [0][1][2][0][RTW89_ACMA][46] = 127, -+ [0][1][2][0][RTW89_CN][46] = 127, -+ [0][1][2][0][RTW89_UK][46] = 127, -+ [0][1][2][0][RTW89_FCC][48] = 127, -+ [0][1][2][0][RTW89_ETSI][48] = 127, -+ [0][1][2][0][RTW89_MKK][48] = 127, -+ [0][1][2][0][RTW89_IC][48] = 127, -+ [0][1][2][0][RTW89_KCC][48] = 127, -+ [0][1][2][0][RTW89_ACMA][48] = 127, -+ [0][1][2][0][RTW89_CN][48] = 127, -+ [0][1][2][0][RTW89_UK][48] = 127, -+ [0][1][2][0][RTW89_FCC][50] = 127, -+ [0][1][2][0][RTW89_ETSI][50] = 127, -+ [0][1][2][0][RTW89_MKK][50] = 127, -+ [0][1][2][0][RTW89_IC][50] = 127, -+ [0][1][2][0][RTW89_KCC][50] = 127, -+ [0][1][2][0][RTW89_ACMA][50] = 127, -+ [0][1][2][0][RTW89_CN][50] = 127, -+ [0][1][2][0][RTW89_UK][50] = 127, -+ [0][1][2][0][RTW89_FCC][52] = 127, -+ [0][1][2][0][RTW89_ETSI][52] = 127, -+ [0][1][2][0][RTW89_MKK][52] = 127, -+ [0][1][2][0][RTW89_IC][52] = 127, -+ [0][1][2][0][RTW89_KCC][52] = 127, -+ [0][1][2][0][RTW89_ACMA][52] = 127, -+ [0][1][2][0][RTW89_CN][52] = 127, -+ [0][1][2][0][RTW89_UK][52] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 127, -+ [0][1][2][1][RTW89_ETSI][0] = 127, -+ [0][1][2][1][RTW89_MKK][0] = 127, -+ [0][1][2][1][RTW89_IC][0] = 127, -+ [0][1][2][1][RTW89_KCC][0] = 127, -+ [0][1][2][1][RTW89_ACMA][0] = 127, -+ [0][1][2][1][RTW89_CN][0] = 127, -+ [0][1][2][1][RTW89_UK][0] = 127, -+ [0][1][2][1][RTW89_FCC][2] = 127, -+ [0][1][2][1][RTW89_ETSI][2] = 127, -+ [0][1][2][1][RTW89_MKK][2] = 127, -+ [0][1][2][1][RTW89_IC][2] = 127, -+ [0][1][2][1][RTW89_KCC][2] = 127, -+ [0][1][2][1][RTW89_ACMA][2] = 127, -+ [0][1][2][1][RTW89_CN][2] = 127, -+ [0][1][2][1][RTW89_UK][2] = 127, -+ [0][1][2][1][RTW89_FCC][4] = 127, -+ [0][1][2][1][RTW89_ETSI][4] = 127, -+ [0][1][2][1][RTW89_MKK][4] = 127, -+ [0][1][2][1][RTW89_IC][4] = 127, -+ [0][1][2][1][RTW89_KCC][4] = 127, -+ [0][1][2][1][RTW89_ACMA][4] = 127, -+ [0][1][2][1][RTW89_CN][4] = 127, -+ [0][1][2][1][RTW89_UK][4] = 127, -+ [0][1][2][1][RTW89_FCC][6] = 127, -+ [0][1][2][1][RTW89_ETSI][6] = 127, -+ [0][1][2][1][RTW89_MKK][6] = 127, -+ [0][1][2][1][RTW89_IC][6] = 127, -+ [0][1][2][1][RTW89_KCC][6] = 127, -+ [0][1][2][1][RTW89_ACMA][6] = 127, -+ [0][1][2][1][RTW89_CN][6] = 127, -+ [0][1][2][1][RTW89_UK][6] = 127, -+ [0][1][2][1][RTW89_FCC][8] = 127, -+ [0][1][2][1][RTW89_ETSI][8] = 127, -+ [0][1][2][1][RTW89_MKK][8] = 127, -+ [0][1][2][1][RTW89_IC][8] = 127, -+ [0][1][2][1][RTW89_KCC][8] = 127, -+ [0][1][2][1][RTW89_ACMA][8] = 127, -+ [0][1][2][1][RTW89_CN][8] = 127, -+ [0][1][2][1][RTW89_UK][8] = 127, -+ [0][1][2][1][RTW89_FCC][10] = 127, -+ [0][1][2][1][RTW89_ETSI][10] = 127, -+ [0][1][2][1][RTW89_MKK][10] = 127, -+ [0][1][2][1][RTW89_IC][10] = 127, -+ [0][1][2][1][RTW89_KCC][10] = 127, -+ [0][1][2][1][RTW89_ACMA][10] = 127, -+ [0][1][2][1][RTW89_CN][10] = 127, -+ [0][1][2][1][RTW89_UK][10] = 127, -+ [0][1][2][1][RTW89_FCC][12] = 127, -+ [0][1][2][1][RTW89_ETSI][12] = 127, -+ [0][1][2][1][RTW89_MKK][12] = 127, -+ [0][1][2][1][RTW89_IC][12] = 127, -+ [0][1][2][1][RTW89_KCC][12] = 127, -+ [0][1][2][1][RTW89_ACMA][12] = 127, -+ [0][1][2][1][RTW89_CN][12] = 127, -+ [0][1][2][1][RTW89_UK][12] = 127, -+ [0][1][2][1][RTW89_FCC][14] = 127, -+ [0][1][2][1][RTW89_ETSI][14] = 127, -+ [0][1][2][1][RTW89_MKK][14] = 127, -+ [0][1][2][1][RTW89_IC][14] = 127, -+ [0][1][2][1][RTW89_KCC][14] = 127, -+ [0][1][2][1][RTW89_ACMA][14] = 127, -+ [0][1][2][1][RTW89_CN][14] = 127, -+ [0][1][2][1][RTW89_UK][14] = 127, -+ [0][1][2][1][RTW89_FCC][15] = 127, -+ [0][1][2][1][RTW89_ETSI][15] = 127, -+ [0][1][2][1][RTW89_MKK][15] = 127, -+ [0][1][2][1][RTW89_IC][15] = 127, -+ [0][1][2][1][RTW89_KCC][15] = 127, -+ [0][1][2][1][RTW89_ACMA][15] = 127, -+ [0][1][2][1][RTW89_CN][15] = 127, -+ [0][1][2][1][RTW89_UK][15] = 127, -+ [0][1][2][1][RTW89_FCC][17] = 127, -+ [0][1][2][1][RTW89_ETSI][17] = 127, -+ [0][1][2][1][RTW89_MKK][17] = 127, -+ [0][1][2][1][RTW89_IC][17] = 127, -+ [0][1][2][1][RTW89_KCC][17] = 127, -+ [0][1][2][1][RTW89_ACMA][17] = 127, -+ [0][1][2][1][RTW89_CN][17] = 127, -+ [0][1][2][1][RTW89_UK][17] = 127, -+ [0][1][2][1][RTW89_FCC][19] = 127, -+ [0][1][2][1][RTW89_ETSI][19] = 127, -+ [0][1][2][1][RTW89_MKK][19] = 127, -+ [0][1][2][1][RTW89_IC][19] = 127, -+ [0][1][2][1][RTW89_KCC][19] = 127, -+ [0][1][2][1][RTW89_ACMA][19] = 127, -+ [0][1][2][1][RTW89_CN][19] = 127, -+ [0][1][2][1][RTW89_UK][19] = 127, -+ [0][1][2][1][RTW89_FCC][21] = 127, -+ [0][1][2][1][RTW89_ETSI][21] = 127, -+ [0][1][2][1][RTW89_MKK][21] = 127, -+ [0][1][2][1][RTW89_IC][21] = 127, -+ [0][1][2][1][RTW89_KCC][21] = 127, -+ [0][1][2][1][RTW89_ACMA][21] = 127, -+ [0][1][2][1][RTW89_CN][21] = 127, -+ [0][1][2][1][RTW89_UK][21] = 127, -+ [0][1][2][1][RTW89_FCC][23] = 127, -+ [0][1][2][1][RTW89_ETSI][23] = 127, -+ [0][1][2][1][RTW89_MKK][23] = 127, -+ [0][1][2][1][RTW89_IC][23] = 127, -+ [0][1][2][1][RTW89_KCC][23] = 127, -+ [0][1][2][1][RTW89_ACMA][23] = 127, -+ [0][1][2][1][RTW89_CN][23] = 127, -+ [0][1][2][1][RTW89_UK][23] = 127, -+ [0][1][2][1][RTW89_FCC][25] = 127, -+ [0][1][2][1][RTW89_ETSI][25] = 127, -+ [0][1][2][1][RTW89_MKK][25] = 127, -+ [0][1][2][1][RTW89_IC][25] = 127, -+ [0][1][2][1][RTW89_KCC][25] = 127, -+ [0][1][2][1][RTW89_ACMA][25] = 127, -+ [0][1][2][1][RTW89_CN][25] = 127, -+ [0][1][2][1][RTW89_UK][25] = 127, -+ [0][1][2][1][RTW89_FCC][27] = 127, -+ [0][1][2][1][RTW89_ETSI][27] = 127, -+ [0][1][2][1][RTW89_MKK][27] = 127, -+ [0][1][2][1][RTW89_IC][27] = 127, -+ [0][1][2][1][RTW89_KCC][27] = 127, -+ [0][1][2][1][RTW89_ACMA][27] = 127, -+ [0][1][2][1][RTW89_CN][27] = 127, -+ [0][1][2][1][RTW89_UK][27] = 127, -+ [0][1][2][1][RTW89_FCC][29] = 127, -+ [0][1][2][1][RTW89_ETSI][29] = 127, -+ [0][1][2][1][RTW89_MKK][29] = 127, -+ [0][1][2][1][RTW89_IC][29] = 127, -+ [0][1][2][1][RTW89_KCC][29] = 127, -+ [0][1][2][1][RTW89_ACMA][29] = 127, -+ [0][1][2][1][RTW89_CN][29] = 127, -+ [0][1][2][1][RTW89_UK][29] = 127, -+ [0][1][2][1][RTW89_FCC][31] = 127, -+ [0][1][2][1][RTW89_ETSI][31] = 127, -+ [0][1][2][1][RTW89_MKK][31] = 127, -+ [0][1][2][1][RTW89_IC][31] = 127, -+ [0][1][2][1][RTW89_KCC][31] = 127, -+ [0][1][2][1][RTW89_ACMA][31] = 127, -+ [0][1][2][1][RTW89_CN][31] = 127, -+ [0][1][2][1][RTW89_UK][31] = 127, -+ [0][1][2][1][RTW89_FCC][33] = 127, -+ [0][1][2][1][RTW89_ETSI][33] = 127, -+ [0][1][2][1][RTW89_MKK][33] = 127, -+ [0][1][2][1][RTW89_IC][33] = 127, -+ [0][1][2][1][RTW89_KCC][33] = 127, -+ [0][1][2][1][RTW89_ACMA][33] = 127, -+ [0][1][2][1][RTW89_CN][33] = 127, -+ [0][1][2][1][RTW89_UK][33] = 127, -+ [0][1][2][1][RTW89_FCC][35] = 127, -+ [0][1][2][1][RTW89_ETSI][35] = 127, -+ [0][1][2][1][RTW89_MKK][35] = 127, -+ [0][1][2][1][RTW89_IC][35] = 127, -+ [0][1][2][1][RTW89_KCC][35] = 127, -+ [0][1][2][1][RTW89_ACMA][35] = 127, -+ [0][1][2][1][RTW89_CN][35] = 127, -+ [0][1][2][1][RTW89_UK][35] = 127, -+ [0][1][2][1][RTW89_FCC][37] = 127, -+ [0][1][2][1][RTW89_ETSI][37] = 127, -+ [0][1][2][1][RTW89_MKK][37] = 127, -+ [0][1][2][1][RTW89_IC][37] = 127, -+ [0][1][2][1][RTW89_KCC][37] = 127, -+ [0][1][2][1][RTW89_ACMA][37] = 127, -+ [0][1][2][1][RTW89_CN][37] = 127, -+ [0][1][2][1][RTW89_UK][37] = 127, -+ [0][1][2][1][RTW89_FCC][38] = 127, -+ [0][1][2][1][RTW89_ETSI][38] = 127, -+ [0][1][2][1][RTW89_MKK][38] = 127, -+ [0][1][2][1][RTW89_IC][38] = 127, -+ [0][1][2][1][RTW89_KCC][38] = 127, -+ [0][1][2][1][RTW89_ACMA][38] = 127, -+ [0][1][2][1][RTW89_CN][38] = 127, -+ [0][1][2][1][RTW89_UK][38] = 127, -+ [0][1][2][1][RTW89_FCC][40] = 127, -+ [0][1][2][1][RTW89_ETSI][40] = 127, -+ [0][1][2][1][RTW89_MKK][40] = 127, -+ [0][1][2][1][RTW89_IC][40] = 127, -+ [0][1][2][1][RTW89_KCC][40] = 127, -+ [0][1][2][1][RTW89_ACMA][40] = 127, -+ [0][1][2][1][RTW89_CN][40] = 127, -+ [0][1][2][1][RTW89_UK][40] = 127, -+ [0][1][2][1][RTW89_FCC][42] = 127, -+ [0][1][2][1][RTW89_ETSI][42] = 127, -+ [0][1][2][1][RTW89_MKK][42] = 127, -+ [0][1][2][1][RTW89_IC][42] = 127, -+ [0][1][2][1][RTW89_KCC][42] = 127, -+ [0][1][2][1][RTW89_ACMA][42] = 127, -+ [0][1][2][1][RTW89_CN][42] = 127, -+ [0][1][2][1][RTW89_UK][42] = 127, -+ [0][1][2][1][RTW89_FCC][44] = 127, -+ [0][1][2][1][RTW89_ETSI][44] = 127, -+ [0][1][2][1][RTW89_MKK][44] = 127, -+ [0][1][2][1][RTW89_IC][44] = 127, -+ [0][1][2][1][RTW89_KCC][44] = 127, -+ [0][1][2][1][RTW89_ACMA][44] = 127, -+ [0][1][2][1][RTW89_CN][44] = 127, -+ [0][1][2][1][RTW89_UK][44] = 127, -+ [0][1][2][1][RTW89_FCC][46] = 127, -+ [0][1][2][1][RTW89_ETSI][46] = 127, -+ [0][1][2][1][RTW89_MKK][46] = 127, -+ [0][1][2][1][RTW89_IC][46] = 127, -+ [0][1][2][1][RTW89_KCC][46] = 127, -+ [0][1][2][1][RTW89_ACMA][46] = 127, -+ [0][1][2][1][RTW89_CN][46] = 127, -+ [0][1][2][1][RTW89_UK][46] = 127, -+ [0][1][2][1][RTW89_FCC][48] = 127, -+ [0][1][2][1][RTW89_ETSI][48] = 127, -+ [0][1][2][1][RTW89_MKK][48] = 127, -+ [0][1][2][1][RTW89_IC][48] = 127, -+ [0][1][2][1][RTW89_KCC][48] = 127, -+ [0][1][2][1][RTW89_ACMA][48] = 127, -+ [0][1][2][1][RTW89_CN][48] = 127, -+ [0][1][2][1][RTW89_UK][48] = 127, -+ [0][1][2][1][RTW89_FCC][50] = 127, -+ [0][1][2][1][RTW89_ETSI][50] = 127, -+ [0][1][2][1][RTW89_MKK][50] = 127, -+ [0][1][2][1][RTW89_IC][50] = 127, -+ [0][1][2][1][RTW89_KCC][50] = 127, -+ [0][1][2][1][RTW89_ACMA][50] = 127, -+ [0][1][2][1][RTW89_CN][50] = 127, -+ [0][1][2][1][RTW89_UK][50] = 127, -+ [0][1][2][1][RTW89_FCC][52] = 127, -+ [0][1][2][1][RTW89_ETSI][52] = 127, -+ [0][1][2][1][RTW89_MKK][52] = 127, -+ [0][1][2][1][RTW89_IC][52] = 127, -+ [0][1][2][1][RTW89_KCC][52] = 127, -+ [0][1][2][1][RTW89_ACMA][52] = 127, -+ [0][1][2][1][RTW89_CN][52] = 127, -+ [0][1][2][1][RTW89_UK][52] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 68, -+ [1][0][2][0][RTW89_ETSI][1] = 64, -+ [1][0][2][0][RTW89_MKK][1] = 64, -+ [1][0][2][0][RTW89_IC][1] = 64, -+ [1][0][2][0][RTW89_KCC][1] = 74, -+ [1][0][2][0][RTW89_ACMA][1] = 64, -+ [1][0][2][0][RTW89_CN][1] = 64, -+ [1][0][2][0][RTW89_UK][1] = 64, -+ [1][0][2][0][RTW89_FCC][5] = 82, -+ [1][0][2][0][RTW89_ETSI][5] = 64, -+ [1][0][2][0][RTW89_MKK][5] = 62, -+ [1][0][2][0][RTW89_IC][5] = 64, -+ [1][0][2][0][RTW89_KCC][5] = 66, -+ [1][0][2][0][RTW89_ACMA][5] = 64, -+ [1][0][2][0][RTW89_CN][5] = 64, -+ [1][0][2][0][RTW89_UK][5] = 64, -+ [1][0][2][0][RTW89_FCC][9] = 82, -+ [1][0][2][0][RTW89_ETSI][9] = 64, -+ [1][0][2][0][RTW89_MKK][9] = 64, -+ [1][0][2][0][RTW89_IC][9] = 64, -+ [1][0][2][0][RTW89_KCC][9] = 78, -+ [1][0][2][0][RTW89_ACMA][9] = 64, -+ [1][0][2][0][RTW89_CN][9] = 64, -+ [1][0][2][0][RTW89_UK][9] = 64, -+ [1][0][2][0][RTW89_FCC][13] = 66, -+ [1][0][2][0][RTW89_ETSI][13] = 64, -+ [1][0][2][0][RTW89_MKK][13] = 64, -+ [1][0][2][0][RTW89_IC][13] = 64, -+ [1][0][2][0][RTW89_KCC][13] = 72, -+ [1][0][2][0][RTW89_ACMA][13] = 64, -+ [1][0][2][0][RTW89_CN][13] = 64, -+ [1][0][2][0][RTW89_UK][13] = 64, -+ [1][0][2][0][RTW89_FCC][16] = 66, -+ [1][0][2][0][RTW89_ETSI][16] = 66, -+ [1][0][2][0][RTW89_MKK][16] = 80, -+ [1][0][2][0][RTW89_IC][16] = 66, -+ [1][0][2][0][RTW89_KCC][16] = 74, -+ [1][0][2][0][RTW89_ACMA][16] = 66, -+ [1][0][2][0][RTW89_CN][16] = 127, -+ [1][0][2][0][RTW89_UK][16] = 66, -+ [1][0][2][0][RTW89_FCC][20] = 80, -+ [1][0][2][0][RTW89_ETSI][20] = 66, -+ [1][0][2][0][RTW89_MKK][20] = 80, -+ [1][0][2][0][RTW89_IC][20] = 80, -+ [1][0][2][0][RTW89_KCC][20] = 74, -+ [1][0][2][0][RTW89_ACMA][20] = 66, -+ [1][0][2][0][RTW89_CN][20] = 127, -+ [1][0][2][0][RTW89_UK][20] = 66, -+ [1][0][2][0][RTW89_FCC][24] = 80, -+ [1][0][2][0][RTW89_ETSI][24] = 66, -+ [1][0][2][0][RTW89_MKK][24] = 80, -+ [1][0][2][0][RTW89_IC][24] = 127, -+ [1][0][2][0][RTW89_KCC][24] = 74, -+ [1][0][2][0][RTW89_ACMA][24] = 127, -+ [1][0][2][0][RTW89_CN][24] = 127, -+ [1][0][2][0][RTW89_UK][24] = 66, -+ [1][0][2][0][RTW89_FCC][28] = 80, -+ [1][0][2][0][RTW89_ETSI][28] = 66, -+ [1][0][2][0][RTW89_MKK][28] = 80, -+ [1][0][2][0][RTW89_IC][28] = 127, -+ [1][0][2][0][RTW89_KCC][28] = 74, -+ [1][0][2][0][RTW89_ACMA][28] = 127, -+ [1][0][2][0][RTW89_CN][28] = 127, -+ [1][0][2][0][RTW89_UK][28] = 66, -+ [1][0][2][0][RTW89_FCC][32] = 76, -+ [1][0][2][0][RTW89_ETSI][32] = 66, -+ [1][0][2][0][RTW89_MKK][32] = 80, -+ [1][0][2][0][RTW89_IC][32] = 76, -+ [1][0][2][0][RTW89_KCC][32] = 78, -+ [1][0][2][0][RTW89_ACMA][32] = 66, -+ [1][0][2][0][RTW89_CN][32] = 127, -+ [1][0][2][0][RTW89_UK][32] = 66, -+ [1][0][2][0][RTW89_FCC][36] = 80, -+ [1][0][2][0][RTW89_ETSI][36] = 127, -+ [1][0][2][0][RTW89_MKK][36] = 80, -+ [1][0][2][0][RTW89_IC][36] = 80, -+ [1][0][2][0][RTW89_KCC][36] = 76, -+ [1][0][2][0][RTW89_ACMA][36] = 78, -+ [1][0][2][0][RTW89_CN][36] = 127, -+ [1][0][2][0][RTW89_UK][36] = 80, -+ [1][0][2][0][RTW89_FCC][39] = 84, -+ [1][0][2][0][RTW89_ETSI][39] = 30, -+ [1][0][2][0][RTW89_MKK][39] = 127, -+ [1][0][2][0][RTW89_IC][39] = 84, -+ [1][0][2][0][RTW89_KCC][39] = 68, -+ [1][0][2][0][RTW89_ACMA][39] = 80, -+ [1][0][2][0][RTW89_CN][39] = 70, -+ [1][0][2][0][RTW89_UK][39] = 64, -+ [1][0][2][0][RTW89_FCC][43] = 84, -+ [1][0][2][0][RTW89_ETSI][43] = 30, -+ [1][0][2][0][RTW89_MKK][43] = 127, -+ [1][0][2][0][RTW89_IC][43] = 84, -+ [1][0][2][0][RTW89_KCC][43] = 78, -+ [1][0][2][0][RTW89_ACMA][43] = 80, -+ [1][0][2][0][RTW89_CN][43] = 80, -+ [1][0][2][0][RTW89_UK][43] = 64, -+ [1][0][2][0][RTW89_FCC][47] = 84, -+ [1][0][2][0][RTW89_ETSI][47] = 127, -+ [1][0][2][0][RTW89_MKK][47] = 127, -+ [1][0][2][0][RTW89_IC][47] = 127, -+ [1][0][2][0][RTW89_KCC][47] = 127, -+ [1][0][2][0][RTW89_ACMA][47] = 127, -+ [1][0][2][0][RTW89_CN][47] = 127, -+ [1][0][2][0][RTW89_UK][47] = 127, -+ [1][0][2][0][RTW89_FCC][51] = 84, -+ [1][0][2][0][RTW89_ETSI][51] = 127, -+ [1][0][2][0][RTW89_MKK][51] = 127, -+ [1][0][2][0][RTW89_IC][51] = 127, -+ [1][0][2][0][RTW89_KCC][51] = 127, -+ [1][0][2][0][RTW89_ACMA][51] = 127, -+ [1][0][2][0][RTW89_CN][51] = 127, -+ [1][0][2][0][RTW89_UK][51] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 127, -+ [1][1][2][0][RTW89_ETSI][1] = 127, -+ [1][1][2][0][RTW89_MKK][1] = 127, -+ [1][1][2][0][RTW89_IC][1] = 127, -+ [1][1][2][0][RTW89_KCC][1] = 127, -+ [1][1][2][0][RTW89_ACMA][1] = 127, -+ [1][1][2][0][RTW89_CN][1] = 127, -+ [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_FCC][5] = 127, -+ [1][1][2][0][RTW89_ETSI][5] = 127, -+ [1][1][2][0][RTW89_MKK][5] = 127, -+ [1][1][2][0][RTW89_IC][5] = 127, -+ [1][1][2][0][RTW89_KCC][5] = 127, -+ [1][1][2][0][RTW89_ACMA][5] = 127, -+ [1][1][2][0][RTW89_CN][5] = 127, -+ [1][1][2][0][RTW89_UK][5] = 127, -+ [1][1][2][0][RTW89_FCC][9] = 127, -+ [1][1][2][0][RTW89_ETSI][9] = 127, -+ [1][1][2][0][RTW89_MKK][9] = 127, -+ [1][1][2][0][RTW89_IC][9] = 127, -+ [1][1][2][0][RTW89_KCC][9] = 127, -+ [1][1][2][0][RTW89_ACMA][9] = 127, -+ [1][1][2][0][RTW89_CN][9] = 127, -+ [1][1][2][0][RTW89_UK][9] = 127, -+ [1][1][2][0][RTW89_FCC][13] = 127, -+ [1][1][2][0][RTW89_ETSI][13] = 127, -+ [1][1][2][0][RTW89_MKK][13] = 127, -+ [1][1][2][0][RTW89_IC][13] = 127, -+ [1][1][2][0][RTW89_KCC][13] = 127, -+ [1][1][2][0][RTW89_ACMA][13] = 127, -+ [1][1][2][0][RTW89_CN][13] = 127, -+ [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_FCC][16] = 127, -+ [1][1][2][0][RTW89_ETSI][16] = 127, -+ [1][1][2][0][RTW89_MKK][16] = 127, -+ [1][1][2][0][RTW89_IC][16] = 127, -+ [1][1][2][0][RTW89_KCC][16] = 127, -+ [1][1][2][0][RTW89_ACMA][16] = 127, -+ [1][1][2][0][RTW89_CN][16] = 127, -+ [1][1][2][0][RTW89_UK][16] = 127, -+ [1][1][2][0][RTW89_FCC][20] = 127, -+ [1][1][2][0][RTW89_ETSI][20] = 127, -+ [1][1][2][0][RTW89_MKK][20] = 127, -+ [1][1][2][0][RTW89_IC][20] = 127, -+ [1][1][2][0][RTW89_KCC][20] = 127, -+ [1][1][2][0][RTW89_ACMA][20] = 127, -+ [1][1][2][0][RTW89_CN][20] = 127, -+ [1][1][2][0][RTW89_UK][20] = 127, -+ [1][1][2][0][RTW89_FCC][24] = 127, -+ [1][1][2][0][RTW89_ETSI][24] = 127, -+ [1][1][2][0][RTW89_MKK][24] = 127, -+ [1][1][2][0][RTW89_IC][24] = 127, -+ [1][1][2][0][RTW89_KCC][24] = 127, -+ [1][1][2][0][RTW89_ACMA][24] = 127, -+ [1][1][2][0][RTW89_CN][24] = 127, -+ [1][1][2][0][RTW89_UK][24] = 127, -+ [1][1][2][0][RTW89_FCC][28] = 127, -+ [1][1][2][0][RTW89_ETSI][28] = 127, -+ [1][1][2][0][RTW89_MKK][28] = 127, -+ [1][1][2][0][RTW89_IC][28] = 127, -+ [1][1][2][0][RTW89_KCC][28] = 127, -+ [1][1][2][0][RTW89_ACMA][28] = 127, -+ [1][1][2][0][RTW89_CN][28] = 127, -+ [1][1][2][0][RTW89_UK][28] = 127, -+ [1][1][2][0][RTW89_FCC][32] = 127, -+ [1][1][2][0][RTW89_ETSI][32] = 127, -+ [1][1][2][0][RTW89_MKK][32] = 127, -+ [1][1][2][0][RTW89_IC][32] = 127, -+ [1][1][2][0][RTW89_KCC][32] = 127, -+ [1][1][2][0][RTW89_ACMA][32] = 127, -+ [1][1][2][0][RTW89_CN][32] = 127, -+ [1][1][2][0][RTW89_UK][32] = 127, -+ [1][1][2][0][RTW89_FCC][36] = 127, -+ [1][1][2][0][RTW89_ETSI][36] = 127, -+ [1][1][2][0][RTW89_MKK][36] = 127, -+ [1][1][2][0][RTW89_IC][36] = 127, -+ [1][1][2][0][RTW89_KCC][36] = 127, -+ [1][1][2][0][RTW89_ACMA][36] = 127, -+ [1][1][2][0][RTW89_CN][36] = 127, -+ [1][1][2][0][RTW89_UK][36] = 127, -+ [1][1][2][0][RTW89_FCC][39] = 127, -+ [1][1][2][0][RTW89_ETSI][39] = 127, -+ [1][1][2][0][RTW89_MKK][39] = 127, -+ [1][1][2][0][RTW89_IC][39] = 127, -+ [1][1][2][0][RTW89_KCC][39] = 127, -+ [1][1][2][0][RTW89_ACMA][39] = 127, -+ [1][1][2][0][RTW89_CN][39] = 127, -+ [1][1][2][0][RTW89_UK][39] = 127, -+ [1][1][2][0][RTW89_FCC][43] = 127, -+ [1][1][2][0][RTW89_ETSI][43] = 127, -+ [1][1][2][0][RTW89_MKK][43] = 127, -+ [1][1][2][0][RTW89_IC][43] = 127, -+ [1][1][2][0][RTW89_KCC][43] = 127, -+ [1][1][2][0][RTW89_ACMA][43] = 127, -+ [1][1][2][0][RTW89_CN][43] = 127, -+ [1][1][2][0][RTW89_UK][43] = 127, -+ [1][1][2][0][RTW89_FCC][47] = 127, -+ [1][1][2][0][RTW89_ETSI][47] = 127, -+ [1][1][2][0][RTW89_MKK][47] = 127, -+ [1][1][2][0][RTW89_IC][47] = 127, -+ [1][1][2][0][RTW89_KCC][47] = 127, -+ [1][1][2][0][RTW89_ACMA][47] = 127, -+ [1][1][2][0][RTW89_CN][47] = 127, -+ [1][1][2][0][RTW89_UK][47] = 127, -+ [1][1][2][0][RTW89_FCC][51] = 127, -+ [1][1][2][0][RTW89_ETSI][51] = 127, -+ [1][1][2][0][RTW89_MKK][51] = 127, -+ [1][1][2][0][RTW89_IC][51] = 127, -+ [1][1][2][0][RTW89_KCC][51] = 127, -+ [1][1][2][0][RTW89_ACMA][51] = 127, -+ [1][1][2][0][RTW89_CN][51] = 127, -+ [1][1][2][0][RTW89_UK][51] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 127, -+ [1][1][2][1][RTW89_ETSI][1] = 127, -+ [1][1][2][1][RTW89_MKK][1] = 127, -+ [1][1][2][1][RTW89_IC][1] = 127, -+ [1][1][2][1][RTW89_KCC][1] = 127, -+ [1][1][2][1][RTW89_ACMA][1] = 127, -+ [1][1][2][1][RTW89_CN][1] = 127, -+ [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_FCC][5] = 127, -+ [1][1][2][1][RTW89_ETSI][5] = 127, -+ [1][1][2][1][RTW89_MKK][5] = 127, -+ [1][1][2][1][RTW89_IC][5] = 127, -+ [1][1][2][1][RTW89_KCC][5] = 127, -+ [1][1][2][1][RTW89_ACMA][5] = 127, -+ [1][1][2][1][RTW89_CN][5] = 127, -+ [1][1][2][1][RTW89_UK][5] = 127, -+ [1][1][2][1][RTW89_FCC][9] = 127, -+ [1][1][2][1][RTW89_ETSI][9] = 127, -+ [1][1][2][1][RTW89_MKK][9] = 127, -+ [1][1][2][1][RTW89_IC][9] = 127, -+ [1][1][2][1][RTW89_KCC][9] = 127, -+ [1][1][2][1][RTW89_ACMA][9] = 127, -+ [1][1][2][1][RTW89_CN][9] = 127, -+ [1][1][2][1][RTW89_UK][9] = 127, -+ [1][1][2][1][RTW89_FCC][13] = 127, -+ [1][1][2][1][RTW89_ETSI][13] = 127, -+ [1][1][2][1][RTW89_MKK][13] = 127, -+ [1][1][2][1][RTW89_IC][13] = 127, -+ [1][1][2][1][RTW89_KCC][13] = 127, -+ [1][1][2][1][RTW89_ACMA][13] = 127, -+ [1][1][2][1][RTW89_CN][13] = 127, -+ [1][1][2][1][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_FCC][16] = 127, -+ [1][1][2][1][RTW89_ETSI][16] = 127, -+ [1][1][2][1][RTW89_MKK][16] = 127, -+ [1][1][2][1][RTW89_IC][16] = 127, -+ [1][1][2][1][RTW89_KCC][16] = 127, -+ [1][1][2][1][RTW89_ACMA][16] = 127, -+ [1][1][2][1][RTW89_CN][16] = 127, -+ [1][1][2][1][RTW89_UK][16] = 127, -+ [1][1][2][1][RTW89_FCC][20] = 127, -+ [1][1][2][1][RTW89_ETSI][20] = 127, -+ [1][1][2][1][RTW89_MKK][20] = 127, -+ [1][1][2][1][RTW89_IC][20] = 127, -+ [1][1][2][1][RTW89_KCC][20] = 127, -+ [1][1][2][1][RTW89_ACMA][20] = 127, -+ [1][1][2][1][RTW89_CN][20] = 127, -+ [1][1][2][1][RTW89_UK][20] = 127, -+ [1][1][2][1][RTW89_FCC][24] = 127, -+ [1][1][2][1][RTW89_ETSI][24] = 127, -+ [1][1][2][1][RTW89_MKK][24] = 127, -+ [1][1][2][1][RTW89_IC][24] = 127, -+ [1][1][2][1][RTW89_KCC][24] = 127, -+ [1][1][2][1][RTW89_ACMA][24] = 127, -+ [1][1][2][1][RTW89_CN][24] = 127, -+ [1][1][2][1][RTW89_UK][24] = 127, -+ [1][1][2][1][RTW89_FCC][28] = 127, -+ [1][1][2][1][RTW89_ETSI][28] = 127, -+ [1][1][2][1][RTW89_MKK][28] = 127, -+ [1][1][2][1][RTW89_IC][28] = 127, -+ [1][1][2][1][RTW89_KCC][28] = 127, -+ [1][1][2][1][RTW89_ACMA][28] = 127, -+ [1][1][2][1][RTW89_CN][28] = 127, -+ [1][1][2][1][RTW89_UK][28] = 127, -+ [1][1][2][1][RTW89_FCC][32] = 127, -+ [1][1][2][1][RTW89_ETSI][32] = 127, -+ [1][1][2][1][RTW89_MKK][32] = 127, -+ [1][1][2][1][RTW89_IC][32] = 127, -+ [1][1][2][1][RTW89_KCC][32] = 127, -+ [1][1][2][1][RTW89_ACMA][32] = 127, -+ [1][1][2][1][RTW89_CN][32] = 127, -+ [1][1][2][1][RTW89_UK][32] = 127, -+ [1][1][2][1][RTW89_FCC][36] = 127, -+ [1][1][2][1][RTW89_ETSI][36] = 127, -+ [1][1][2][1][RTW89_MKK][36] = 127, -+ [1][1][2][1][RTW89_IC][36] = 127, -+ [1][1][2][1][RTW89_KCC][36] = 127, -+ [1][1][2][1][RTW89_ACMA][36] = 127, -+ [1][1][2][1][RTW89_CN][36] = 127, -+ [1][1][2][1][RTW89_UK][36] = 127, -+ [1][1][2][1][RTW89_FCC][39] = 127, -+ [1][1][2][1][RTW89_ETSI][39] = 127, -+ [1][1][2][1][RTW89_MKK][39] = 127, -+ [1][1][2][1][RTW89_IC][39] = 127, -+ [1][1][2][1][RTW89_KCC][39] = 127, -+ [1][1][2][1][RTW89_ACMA][39] = 127, -+ [1][1][2][1][RTW89_CN][39] = 127, -+ [1][1][2][1][RTW89_UK][39] = 127, -+ [1][1][2][1][RTW89_FCC][43] = 127, -+ [1][1][2][1][RTW89_ETSI][43] = 127, -+ [1][1][2][1][RTW89_MKK][43] = 127, -+ [1][1][2][1][RTW89_IC][43] = 127, -+ [1][1][2][1][RTW89_KCC][43] = 127, -+ [1][1][2][1][RTW89_ACMA][43] = 127, -+ [1][1][2][1][RTW89_CN][43] = 127, -+ [1][1][2][1][RTW89_UK][43] = 127, -+ [1][1][2][1][RTW89_FCC][47] = 127, -+ [1][1][2][1][RTW89_ETSI][47] = 127, -+ [1][1][2][1][RTW89_MKK][47] = 127, -+ [1][1][2][1][RTW89_IC][47] = 127, -+ [1][1][2][1][RTW89_KCC][47] = 127, -+ [1][1][2][1][RTW89_ACMA][47] = 127, -+ [1][1][2][1][RTW89_CN][47] = 127, -+ [1][1][2][1][RTW89_UK][47] = 127, -+ [1][1][2][1][RTW89_FCC][51] = 127, -+ [1][1][2][1][RTW89_ETSI][51] = 127, -+ [1][1][2][1][RTW89_MKK][51] = 127, -+ [1][1][2][1][RTW89_IC][51] = 127, -+ [1][1][2][1][RTW89_KCC][51] = 127, -+ [1][1][2][1][RTW89_ACMA][51] = 127, -+ [1][1][2][1][RTW89_CN][51] = 127, -+ [1][1][2][1][RTW89_UK][51] = 127, -+ [2][0][2][0][RTW89_FCC][3] = 76, -+ [2][0][2][0][RTW89_ETSI][3] = 64, -+ [2][0][2][0][RTW89_MKK][3] = 62, -+ [2][0][2][0][RTW89_IC][3] = 64, -+ [2][0][2][0][RTW89_KCC][3] = 72, -+ [2][0][2][0][RTW89_ACMA][3] = 64, -+ [2][0][2][0][RTW89_CN][3] = 64, -+ [2][0][2][0][RTW89_UK][3] = 64, -+ [2][0][2][0][RTW89_FCC][11] = 64, -+ [2][0][2][0][RTW89_ETSI][11] = 64, -+ [2][0][2][0][RTW89_MKK][11] = 64, -+ [2][0][2][0][RTW89_IC][11] = 62, -+ [2][0][2][0][RTW89_KCC][11] = 72, -+ [2][0][2][0][RTW89_ACMA][11] = 64, -+ [2][0][2][0][RTW89_CN][11] = 64, -+ [2][0][2][0][RTW89_UK][11] = 64, -+ [2][0][2][0][RTW89_FCC][18] = 66, -+ [2][0][2][0][RTW89_ETSI][18] = 64, -+ [2][0][2][0][RTW89_MKK][18] = 72, -+ [2][0][2][0][RTW89_IC][18] = 66, -+ [2][0][2][0][RTW89_KCC][18] = 72, -+ [2][0][2][0][RTW89_ACMA][18] = 64, -+ [2][0][2][0][RTW89_CN][18] = 127, -+ [2][0][2][0][RTW89_UK][18] = 64, -+ [2][0][2][0][RTW89_FCC][26] = 76, -+ [2][0][2][0][RTW89_ETSI][26] = 64, -+ [2][0][2][0][RTW89_MKK][26] = 72, -+ [2][0][2][0][RTW89_IC][26] = 127, -+ [2][0][2][0][RTW89_KCC][26] = 72, -+ [2][0][2][0][RTW89_ACMA][26] = 127, -+ [2][0][2][0][RTW89_CN][26] = 127, -+ [2][0][2][0][RTW89_UK][26] = 64, -+ [2][0][2][0][RTW89_FCC][34] = 76, -+ [2][0][2][0][RTW89_ETSI][34] = 127, -+ [2][0][2][0][RTW89_MKK][34] = 72, -+ [2][0][2][0][RTW89_IC][34] = 76, -+ [2][0][2][0][RTW89_KCC][34] = 72, -+ [2][0][2][0][RTW89_ACMA][34] = 72, -+ [2][0][2][0][RTW89_CN][34] = 127, -+ [2][0][2][0][RTW89_UK][34] = 72, -+ [2][0][2][0][RTW89_FCC][41] = 76, -+ [2][0][2][0][RTW89_ETSI][41] = 30, -+ [2][0][2][0][RTW89_MKK][41] = 127, -+ [2][0][2][0][RTW89_IC][41] = 76, -+ [2][0][2][0][RTW89_KCC][41] = 64, -+ [2][0][2][0][RTW89_ACMA][41] = 72, -+ [2][0][2][0][RTW89_CN][41] = 72, -+ [2][0][2][0][RTW89_UK][41] = 64, -+ [2][0][2][0][RTW89_FCC][49] = 74, -+ [2][0][2][0][RTW89_ETSI][49] = 127, -+ [2][0][2][0][RTW89_MKK][49] = 127, -+ [2][0][2][0][RTW89_IC][49] = 127, -+ [2][0][2][0][RTW89_KCC][49] = 127, -+ [2][0][2][0][RTW89_ACMA][49] = 127, -+ [2][0][2][0][RTW89_CN][49] = 127, -+ [2][0][2][0][RTW89_UK][49] = 127, -+ [2][1][2][0][RTW89_FCC][3] = 127, -+ [2][1][2][0][RTW89_ETSI][3] = 127, -+ [2][1][2][0][RTW89_MKK][3] = 127, -+ [2][1][2][0][RTW89_IC][3] = 127, -+ [2][1][2][0][RTW89_KCC][3] = 127, -+ [2][1][2][0][RTW89_ACMA][3] = 127, -+ [2][1][2][0][RTW89_CN][3] = 127, -+ [2][1][2][0][RTW89_UK][3] = 127, -+ [2][1][2][0][RTW89_FCC][11] = 127, -+ [2][1][2][0][RTW89_ETSI][11] = 127, -+ [2][1][2][0][RTW89_MKK][11] = 127, -+ [2][1][2][0][RTW89_IC][11] = 127, -+ [2][1][2][0][RTW89_KCC][11] = 127, -+ [2][1][2][0][RTW89_ACMA][11] = 127, -+ [2][1][2][0][RTW89_CN][11] = 127, -+ [2][1][2][0][RTW89_UK][11] = 127, -+ [2][1][2][0][RTW89_FCC][18] = 127, -+ [2][1][2][0][RTW89_ETSI][18] = 127, -+ [2][1][2][0][RTW89_MKK][18] = 127, -+ [2][1][2][0][RTW89_IC][18] = 127, -+ [2][1][2][0][RTW89_KCC][18] = 127, -+ [2][1][2][0][RTW89_ACMA][18] = 127, -+ [2][1][2][0][RTW89_CN][18] = 127, -+ [2][1][2][0][RTW89_UK][18] = 127, -+ [2][1][2][0][RTW89_FCC][26] = 127, -+ [2][1][2][0][RTW89_ETSI][26] = 127, -+ [2][1][2][0][RTW89_MKK][26] = 127, -+ [2][1][2][0][RTW89_IC][26] = 127, -+ [2][1][2][0][RTW89_KCC][26] = 127, -+ [2][1][2][0][RTW89_ACMA][26] = 127, -+ [2][1][2][0][RTW89_CN][26] = 127, -+ [2][1][2][0][RTW89_UK][26] = 127, -+ [2][1][2][0][RTW89_FCC][34] = 127, -+ [2][1][2][0][RTW89_ETSI][34] = 127, -+ [2][1][2][0][RTW89_MKK][34] = 127, -+ [2][1][2][0][RTW89_IC][34] = 127, -+ [2][1][2][0][RTW89_KCC][34] = 127, -+ [2][1][2][0][RTW89_ACMA][34] = 127, -+ [2][1][2][0][RTW89_CN][34] = 127, -+ [2][1][2][0][RTW89_UK][34] = 127, -+ [2][1][2][0][RTW89_FCC][41] = 127, -+ [2][1][2][0][RTW89_ETSI][41] = 127, -+ [2][1][2][0][RTW89_MKK][41] = 127, -+ [2][1][2][0][RTW89_IC][41] = 127, -+ [2][1][2][0][RTW89_KCC][41] = 127, -+ [2][1][2][0][RTW89_ACMA][41] = 127, -+ [2][1][2][0][RTW89_CN][41] = 127, -+ [2][1][2][0][RTW89_UK][41] = 127, -+ [2][1][2][0][RTW89_FCC][49] = 127, -+ [2][1][2][0][RTW89_ETSI][49] = 127, -+ [2][1][2][0][RTW89_MKK][49] = 127, -+ [2][1][2][0][RTW89_IC][49] = 127, -+ [2][1][2][0][RTW89_KCC][49] = 127, -+ [2][1][2][0][RTW89_ACMA][49] = 127, -+ [2][1][2][0][RTW89_CN][49] = 127, -+ [2][1][2][0][RTW89_UK][49] = 127, -+ [2][1][2][1][RTW89_FCC][3] = 127, -+ [2][1][2][1][RTW89_ETSI][3] = 127, -+ [2][1][2][1][RTW89_MKK][3] = 127, -+ [2][1][2][1][RTW89_IC][3] = 127, -+ [2][1][2][1][RTW89_KCC][3] = 127, -+ [2][1][2][1][RTW89_ACMA][3] = 127, -+ [2][1][2][1][RTW89_CN][3] = 127, -+ [2][1][2][1][RTW89_UK][3] = 127, -+ [2][1][2][1][RTW89_FCC][11] = 127, -+ [2][1][2][1][RTW89_ETSI][11] = 127, -+ [2][1][2][1][RTW89_MKK][11] = 127, -+ [2][1][2][1][RTW89_IC][11] = 127, -+ [2][1][2][1][RTW89_KCC][11] = 127, -+ [2][1][2][1][RTW89_ACMA][11] = 127, -+ [2][1][2][1][RTW89_CN][11] = 127, -+ [2][1][2][1][RTW89_UK][11] = 127, -+ [2][1][2][1][RTW89_FCC][18] = 127, -+ [2][1][2][1][RTW89_ETSI][18] = 127, -+ [2][1][2][1][RTW89_MKK][18] = 127, -+ [2][1][2][1][RTW89_IC][18] = 127, -+ [2][1][2][1][RTW89_KCC][18] = 127, -+ [2][1][2][1][RTW89_ACMA][18] = 127, -+ [2][1][2][1][RTW89_CN][18] = 127, -+ [2][1][2][1][RTW89_UK][18] = 127, -+ [2][1][2][1][RTW89_FCC][26] = 127, -+ [2][1][2][1][RTW89_ETSI][26] = 127, -+ [2][1][2][1][RTW89_MKK][26] = 127, -+ [2][1][2][1][RTW89_IC][26] = 127, -+ [2][1][2][1][RTW89_KCC][26] = 127, -+ [2][1][2][1][RTW89_ACMA][26] = 127, -+ [2][1][2][1][RTW89_CN][26] = 127, -+ [2][1][2][1][RTW89_UK][26] = 127, -+ [2][1][2][1][RTW89_FCC][34] = 127, -+ [2][1][2][1][RTW89_ETSI][34] = 127, -+ [2][1][2][1][RTW89_MKK][34] = 127, -+ [2][1][2][1][RTW89_IC][34] = 127, -+ [2][1][2][1][RTW89_KCC][34] = 127, -+ [2][1][2][1][RTW89_ACMA][34] = 127, -+ [2][1][2][1][RTW89_CN][34] = 127, -+ [2][1][2][1][RTW89_UK][34] = 127, -+ [2][1][2][1][RTW89_FCC][41] = 127, -+ [2][1][2][1][RTW89_ETSI][41] = 127, -+ [2][1][2][1][RTW89_MKK][41] = 127, -+ [2][1][2][1][RTW89_IC][41] = 127, -+ [2][1][2][1][RTW89_KCC][41] = 127, -+ [2][1][2][1][RTW89_ACMA][41] = 127, -+ [2][1][2][1][RTW89_CN][41] = 127, -+ [2][1][2][1][RTW89_UK][41] = 127, -+ [2][1][2][1][RTW89_FCC][49] = 127, -+ [2][1][2][1][RTW89_ETSI][49] = 127, -+ [2][1][2][1][RTW89_MKK][49] = 127, -+ [2][1][2][1][RTW89_IC][49] = 127, -+ [2][1][2][1][RTW89_KCC][49] = 127, -+ [2][1][2][1][RTW89_ACMA][49] = 127, -+ [2][1][2][1][RTW89_CN][49] = 127, -+ [2][1][2][1][RTW89_UK][49] = 127, -+ [3][0][2][0][RTW89_FCC][7] = 127, -+ [3][0][2][0][RTW89_ETSI][7] = 127, -+ [3][0][2][0][RTW89_MKK][7] = 127, -+ [3][0][2][0][RTW89_IC][7] = 127, -+ [3][0][2][0][RTW89_KCC][7] = 127, -+ [3][0][2][0][RTW89_ACMA][7] = 127, -+ [3][0][2][0][RTW89_CN][7] = 58, -+ [3][0][2][0][RTW89_UK][7] = 127, -+ [3][0][2][0][RTW89_FCC][22] = 127, -+ [3][0][2][0][RTW89_ETSI][22] = 127, -+ [3][0][2][0][RTW89_MKK][22] = 127, -+ [3][0][2][0][RTW89_IC][22] = 127, -+ [3][0][2][0][RTW89_KCC][22] = 127, -+ [3][0][2][0][RTW89_ACMA][22] = 127, -+ [3][0][2][0][RTW89_CN][22] = 58, -+ [3][0][2][0][RTW89_UK][22] = 127, -+ [3][0][2][0][RTW89_FCC][45] = 127, -+ [3][0][2][0][RTW89_ETSI][45] = 127, -+ [3][0][2][0][RTW89_MKK][45] = 127, -+ [3][0][2][0][RTW89_IC][45] = 127, -+ [3][0][2][0][RTW89_KCC][45] = 127, -+ [3][0][2][0][RTW89_ACMA][45] = 127, -+ [3][0][2][0][RTW89_CN][45] = 127, -+ [3][0][2][0][RTW89_UK][45] = 127, -+ [3][1][2][0][RTW89_FCC][7] = 127, -+ [3][1][2][0][RTW89_ETSI][7] = 127, -+ [3][1][2][0][RTW89_MKK][7] = 127, -+ [3][1][2][0][RTW89_IC][7] = 127, -+ [3][1][2][0][RTW89_KCC][7] = 127, -+ [3][1][2][0][RTW89_ACMA][7] = 127, -+ [3][1][2][0][RTW89_CN][7] = 127, -+ [3][1][2][0][RTW89_UK][7] = 127, -+ [3][1][2][0][RTW89_FCC][22] = 127, -+ [3][1][2][0][RTW89_ETSI][22] = 127, -+ [3][1][2][0][RTW89_MKK][22] = 127, -+ [3][1][2][0][RTW89_IC][22] = 127, -+ [3][1][2][0][RTW89_KCC][22] = 127, -+ [3][1][2][0][RTW89_ACMA][22] = 127, -+ [3][1][2][0][RTW89_CN][22] = 127, -+ [3][1][2][0][RTW89_UK][22] = 127, -+ [3][1][2][0][RTW89_FCC][45] = 127, -+ [3][1][2][0][RTW89_ETSI][45] = 127, -+ [3][1][2][0][RTW89_MKK][45] = 127, -+ [3][1][2][0][RTW89_IC][45] = 127, -+ [3][1][2][0][RTW89_KCC][45] = 127, -+ [3][1][2][0][RTW89_ACMA][45] = 127, -+ [3][1][2][0][RTW89_CN][45] = 127, -+ [3][1][2][0][RTW89_UK][45] = 127, -+ [3][1][2][1][RTW89_FCC][7] = 127, -+ [3][1][2][1][RTW89_ETSI][7] = 127, -+ [3][1][2][1][RTW89_MKK][7] = 127, -+ [3][1][2][1][RTW89_IC][7] = 127, -+ [3][1][2][1][RTW89_KCC][7] = 127, -+ [3][1][2][1][RTW89_ACMA][7] = 127, -+ [3][1][2][1][RTW89_CN][7] = 127, -+ [3][1][2][1][RTW89_UK][7] = 127, -+ [3][1][2][1][RTW89_FCC][22] = 127, -+ [3][1][2][1][RTW89_ETSI][22] = 127, -+ [3][1][2][1][RTW89_MKK][22] = 127, -+ [3][1][2][1][RTW89_IC][22] = 127, -+ [3][1][2][1][RTW89_KCC][22] = 127, -+ [3][1][2][1][RTW89_ACMA][22] = 127, -+ [3][1][2][1][RTW89_CN][22] = 127, -+ [3][1][2][1][RTW89_UK][22] = 127, -+ [3][1][2][1][RTW89_FCC][45] = 127, -+ [3][1][2][1][RTW89_ETSI][45] = 127, -+ [3][1][2][1][RTW89_MKK][45] = 127, -+ [3][1][2][1][RTW89_IC][45] = 127, -+ [3][1][2][1][RTW89_KCC][45] = 127, -+ [3][1][2][1][RTW89_ACMA][45] = 127, -+ [3][1][2][1][RTW89_CN][45] = 127, -+ [3][1][2][1][RTW89_UK][45] = 127, -+}; ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8851B_TABLE_H__ -+#define __RTW89_8851B_TABLE_H__ -+ -+#include "core.h" -+ -+extern const struct rtw89_phy_table rtw89_8851b_phy_bb_table; -+extern const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table; -+extern const struct rtw89_phy_table rtw89_8851b_phy_radioa_table; -+extern const struct rtw89_phy_table rtw89_8851b_phy_nctl_table; -+extern const struct rtw89_txpwr_table rtw89_8851b_byr_table; -+extern const struct rtw89_txpwr_track_cfg rtw89_8851b_trk_cfg; -+extern const u8 rtw89_8851b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+ [RTW89_REGD_NUM]; -+extern const struct rtw89_rfe_parms rtw89_8851b_dflt_parms; -+extern const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[]; -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-044-wifi-rtw89-8851b-add-BB-and-RF-tables-2-of-2.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-044-wifi-rtw89-8851b-add-BB-and-RF-tables-2-of-2.patch deleted file mode 100644 index ad5d52d0d..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-044-wifi-rtw89-8851b-add-BB-and-RF-tables-2-of-2.patch +++ /dev/null @@ -1,8087 +0,0 @@ -From cf4917cf0ab828a4b520daa1708e8572b810417a Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 1 Apr 2023 22:25:47 +0800 -Subject: [PATCH 044/136] wifi: rtw89: 8851b: add BB and RF tables (2 of 2) - -These tables contain BB and RF parameters that driver will load them into -registers. It also contains TX power according to country, band, rate and -so on. Increasing thermal can cause TX power degraded, so power tracking -tables are defined to compensate TX power. - -Internal version of these tables: - - HALBB_029_106_15 (V17) - - HALRF_029_00_089 - * Radio A 0x22 - * NCTL 0x5 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230401142548.55466-3-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8851b_table.c | 8058 +++++++++++++++++ - 1 file changed, 8058 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -6764,3 +6764,8061 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_CN][45] = 127, - [3][1][2][1][RTW89_UK][45] = 127, - }; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 30, -+ [0][0][RTW89_WW][1] = 30, -+ [0][0][RTW89_WW][2] = 30, -+ [0][0][RTW89_WW][3] = 30, -+ [0][0][RTW89_WW][4] = 30, -+ [0][0][RTW89_WW][5] = 30, -+ [0][0][RTW89_WW][6] = 30, -+ [0][0][RTW89_WW][7] = 30, -+ [0][0][RTW89_WW][8] = 30, -+ [0][0][RTW89_WW][9] = 30, -+ [0][0][RTW89_WW][10] = 30, -+ [0][0][RTW89_WW][11] = 30, -+ [0][0][RTW89_WW][12] = 30, -+ [0][0][RTW89_WW][13] = 0, -+ [0][1][RTW89_WW][0] = 20, -+ [0][1][RTW89_WW][1] = 22, -+ [0][1][RTW89_WW][2] = 22, -+ [0][1][RTW89_WW][3] = 22, -+ [0][1][RTW89_WW][4] = 22, -+ [0][1][RTW89_WW][5] = 22, -+ [0][1][RTW89_WW][6] = 22, -+ [0][1][RTW89_WW][7] = 22, -+ [0][1][RTW89_WW][8] = 22, -+ [0][1][RTW89_WW][9] = 22, -+ [0][1][RTW89_WW][10] = 22, -+ [0][1][RTW89_WW][11] = 22, -+ [0][1][RTW89_WW][12] = 20, -+ [0][1][RTW89_WW][13] = 0, -+ [1][0][RTW89_WW][0] = 42, -+ [1][0][RTW89_WW][1] = 42, -+ [1][0][RTW89_WW][2] = 42, -+ [1][0][RTW89_WW][3] = 42, -+ [1][0][RTW89_WW][4] = 42, -+ [1][0][RTW89_WW][5] = 42, -+ [1][0][RTW89_WW][6] = 42, -+ [1][0][RTW89_WW][7] = 42, -+ [1][0][RTW89_WW][8] = 42, -+ [1][0][RTW89_WW][9] = 42, -+ [1][0][RTW89_WW][10] = 42, -+ [1][0][RTW89_WW][11] = 42, -+ [1][0][RTW89_WW][12] = 34, -+ [1][0][RTW89_WW][13] = 0, -+ [1][1][RTW89_WW][0] = 32, -+ [1][1][RTW89_WW][1] = 32, -+ [1][1][RTW89_WW][2] = 32, -+ [1][1][RTW89_WW][3] = 32, -+ [1][1][RTW89_WW][4] = 32, -+ [1][1][RTW89_WW][5] = 32, -+ [1][1][RTW89_WW][6] = 32, -+ [1][1][RTW89_WW][7] = 32, -+ [1][1][RTW89_WW][8] = 32, -+ [1][1][RTW89_WW][9] = 32, -+ [1][1][RTW89_WW][10] = 32, -+ [1][1][RTW89_WW][11] = 32, -+ [1][1][RTW89_WW][12] = 32, -+ [1][1][RTW89_WW][13] = 0, -+ [2][0][RTW89_WW][0] = 54, -+ [2][0][RTW89_WW][1] = 54, -+ [2][0][RTW89_WW][2] = 54, -+ [2][0][RTW89_WW][3] = 54, -+ [2][0][RTW89_WW][4] = 54, -+ [2][0][RTW89_WW][5] = 54, -+ [2][0][RTW89_WW][6] = 54, -+ [2][0][RTW89_WW][7] = 54, -+ [2][0][RTW89_WW][8] = 54, -+ [2][0][RTW89_WW][9] = 54, -+ [2][0][RTW89_WW][10] = 54, -+ [2][0][RTW89_WW][11] = 54, -+ [2][0][RTW89_WW][12] = 34, -+ [2][0][RTW89_WW][13] = 0, -+ [2][1][RTW89_WW][0] = 44, -+ [2][1][RTW89_WW][1] = 44, -+ [2][1][RTW89_WW][2] = 44, -+ [2][1][RTW89_WW][3] = 44, -+ [2][1][RTW89_WW][4] = 44, -+ [2][1][RTW89_WW][5] = 44, -+ [2][1][RTW89_WW][6] = 44, -+ [2][1][RTW89_WW][7] = 44, -+ [2][1][RTW89_WW][8] = 44, -+ [2][1][RTW89_WW][9] = 44, -+ [2][1][RTW89_WW][10] = 44, -+ [2][1][RTW89_WW][11] = 44, -+ [2][1][RTW89_WW][12] = 42, -+ [2][1][RTW89_WW][13] = 0, -+ [0][0][RTW89_FCC][0] = 62, -+ [0][0][RTW89_ETSI][0] = 30, -+ [0][0][RTW89_MKK][0] = 40, -+ [0][0][RTW89_IC][0] = 62, -+ [0][0][RTW89_KCC][0] = 46, -+ [0][0][RTW89_ACMA][0] = 30, -+ [0][0][RTW89_CN][0] = 32, -+ [0][0][RTW89_UK][0] = 30, -+ [0][0][RTW89_FCC][1] = 62, -+ [0][0][RTW89_ETSI][1] = 30, -+ [0][0][RTW89_MKK][1] = 44, -+ [0][0][RTW89_IC][1] = 62, -+ [0][0][RTW89_KCC][1] = 46, -+ [0][0][RTW89_ACMA][1] = 30, -+ [0][0][RTW89_CN][1] = 32, -+ [0][0][RTW89_UK][1] = 30, -+ [0][0][RTW89_FCC][2] = 66, -+ [0][0][RTW89_ETSI][2] = 30, -+ [0][0][RTW89_MKK][2] = 44, -+ [0][0][RTW89_IC][2] = 66, -+ [0][0][RTW89_KCC][2] = 46, -+ [0][0][RTW89_ACMA][2] = 30, -+ [0][0][RTW89_CN][2] = 32, -+ [0][0][RTW89_UK][2] = 30, -+ [0][0][RTW89_FCC][3] = 70, -+ [0][0][RTW89_ETSI][3] = 30, -+ [0][0][RTW89_MKK][3] = 44, -+ [0][0][RTW89_IC][3] = 70, -+ [0][0][RTW89_KCC][3] = 46, -+ [0][0][RTW89_ACMA][3] = 30, -+ [0][0][RTW89_CN][3] = 32, -+ [0][0][RTW89_UK][3] = 30, -+ [0][0][RTW89_FCC][4] = 70, -+ [0][0][RTW89_ETSI][4] = 30, -+ [0][0][RTW89_MKK][4] = 44, -+ [0][0][RTW89_IC][4] = 70, -+ [0][0][RTW89_KCC][4] = 48, -+ [0][0][RTW89_ACMA][4] = 30, -+ [0][0][RTW89_CN][4] = 32, -+ [0][0][RTW89_UK][4] = 30, -+ [0][0][RTW89_FCC][5] = 84, -+ [0][0][RTW89_ETSI][5] = 30, -+ [0][0][RTW89_MKK][5] = 44, -+ [0][0][RTW89_IC][5] = 84, -+ [0][0][RTW89_KCC][5] = 48, -+ [0][0][RTW89_ACMA][5] = 30, -+ [0][0][RTW89_CN][5] = 32, -+ [0][0][RTW89_UK][5] = 30, -+ [0][0][RTW89_FCC][6] = 66, -+ [0][0][RTW89_ETSI][6] = 30, -+ [0][0][RTW89_MKK][6] = 44, -+ [0][0][RTW89_IC][6] = 66, -+ [0][0][RTW89_KCC][6] = 48, -+ [0][0][RTW89_ACMA][6] = 30, -+ [0][0][RTW89_CN][6] = 32, -+ [0][0][RTW89_UK][6] = 30, -+ [0][0][RTW89_FCC][7] = 66, -+ [0][0][RTW89_ETSI][7] = 30, -+ [0][0][RTW89_MKK][7] = 44, -+ [0][0][RTW89_IC][7] = 66, -+ [0][0][RTW89_KCC][7] = 48, -+ [0][0][RTW89_ACMA][7] = 30, -+ [0][0][RTW89_CN][7] = 32, -+ [0][0][RTW89_UK][7] = 30, -+ [0][0][RTW89_FCC][8] = 62, -+ [0][0][RTW89_ETSI][8] = 30, -+ [0][0][RTW89_MKK][8] = 44, -+ [0][0][RTW89_IC][8] = 62, -+ [0][0][RTW89_KCC][8] = 48, -+ [0][0][RTW89_ACMA][8] = 30, -+ [0][0][RTW89_CN][8] = 32, -+ [0][0][RTW89_UK][8] = 30, -+ [0][0][RTW89_FCC][9] = 58, -+ [0][0][RTW89_ETSI][9] = 30, -+ [0][0][RTW89_MKK][9] = 44, -+ [0][0][RTW89_IC][9] = 58, -+ [0][0][RTW89_KCC][9] = 44, -+ [0][0][RTW89_ACMA][9] = 30, -+ [0][0][RTW89_CN][9] = 32, -+ [0][0][RTW89_UK][9] = 30, -+ [0][0][RTW89_FCC][10] = 58, -+ [0][0][RTW89_ETSI][10] = 30, -+ [0][0][RTW89_MKK][10] = 44, -+ [0][0][RTW89_IC][10] = 58, -+ [0][0][RTW89_KCC][10] = 44, -+ [0][0][RTW89_ACMA][10] = 30, -+ [0][0][RTW89_CN][10] = 32, -+ [0][0][RTW89_UK][10] = 30, -+ [0][0][RTW89_FCC][11] = 54, -+ [0][0][RTW89_ETSI][11] = 30, -+ [0][0][RTW89_MKK][11] = 44, -+ [0][0][RTW89_IC][11] = 54, -+ [0][0][RTW89_KCC][11] = 44, -+ [0][0][RTW89_ACMA][11] = 30, -+ [0][0][RTW89_CN][11] = 32, -+ [0][0][RTW89_UK][11] = 30, -+ [0][0][RTW89_FCC][12] = 36, -+ [0][0][RTW89_ETSI][12] = 30, -+ [0][0][RTW89_MKK][12] = 40, -+ [0][0][RTW89_IC][12] = 36, -+ [0][0][RTW89_KCC][12] = 44, -+ [0][0][RTW89_ACMA][12] = 30, -+ [0][0][RTW89_CN][12] = 32, -+ [0][0][RTW89_UK][12] = 30, -+ [0][0][RTW89_FCC][13] = 127, -+ [0][0][RTW89_ETSI][13] = 127, -+ [0][0][RTW89_MKK][13] = 127, -+ [0][0][RTW89_IC][13] = 127, -+ [0][0][RTW89_KCC][13] = 127, -+ [0][0][RTW89_ACMA][13] = 127, -+ [0][0][RTW89_CN][13] = 127, -+ [0][0][RTW89_UK][13] = 127, -+ [0][1][RTW89_FCC][0] = 127, -+ [0][1][RTW89_ETSI][0] = 127, -+ [0][1][RTW89_MKK][0] = 127, -+ [0][1][RTW89_IC][0] = 127, -+ [0][1][RTW89_KCC][0] = 127, -+ [0][1][RTW89_ACMA][0] = 127, -+ [0][1][RTW89_CN][0] = 20, -+ [0][1][RTW89_UK][0] = 127, -+ [0][1][RTW89_FCC][1] = 127, -+ [0][1][RTW89_ETSI][1] = 127, -+ [0][1][RTW89_MKK][1] = 127, -+ [0][1][RTW89_IC][1] = 127, -+ [0][1][RTW89_KCC][1] = 127, -+ [0][1][RTW89_ACMA][1] = 127, -+ [0][1][RTW89_CN][1] = 22, -+ [0][1][RTW89_UK][1] = 127, -+ [0][1][RTW89_FCC][2] = 127, -+ [0][1][RTW89_ETSI][2] = 127, -+ [0][1][RTW89_MKK][2] = 127, -+ [0][1][RTW89_IC][2] = 127, -+ [0][1][RTW89_KCC][2] = 127, -+ [0][1][RTW89_ACMA][2] = 127, -+ [0][1][RTW89_CN][2] = 22, -+ [0][1][RTW89_UK][2] = 127, -+ [0][1][RTW89_FCC][3] = 127, -+ [0][1][RTW89_ETSI][3] = 127, -+ [0][1][RTW89_MKK][3] = 127, -+ [0][1][RTW89_IC][3] = 127, -+ [0][1][RTW89_KCC][3] = 127, -+ [0][1][RTW89_ACMA][3] = 127, -+ [0][1][RTW89_CN][3] = 22, -+ [0][1][RTW89_UK][3] = 127, -+ [0][1][RTW89_FCC][4] = 127, -+ [0][1][RTW89_ETSI][4] = 127, -+ [0][1][RTW89_MKK][4] = 127, -+ [0][1][RTW89_IC][4] = 127, -+ [0][1][RTW89_KCC][4] = 127, -+ [0][1][RTW89_ACMA][4] = 127, -+ [0][1][RTW89_CN][4] = 22, -+ [0][1][RTW89_UK][4] = 127, -+ [0][1][RTW89_FCC][5] = 127, -+ [0][1][RTW89_ETSI][5] = 127, -+ [0][1][RTW89_MKK][5] = 127, -+ [0][1][RTW89_IC][5] = 127, -+ [0][1][RTW89_KCC][5] = 127, -+ [0][1][RTW89_ACMA][5] = 127, -+ [0][1][RTW89_CN][5] = 22, -+ [0][1][RTW89_UK][5] = 127, -+ [0][1][RTW89_FCC][6] = 127, -+ [0][1][RTW89_ETSI][6] = 127, -+ [0][1][RTW89_MKK][6] = 127, -+ [0][1][RTW89_IC][6] = 127, -+ [0][1][RTW89_KCC][6] = 127, -+ [0][1][RTW89_ACMA][6] = 127, -+ [0][1][RTW89_CN][6] = 22, -+ [0][1][RTW89_UK][6] = 127, -+ [0][1][RTW89_FCC][7] = 127, -+ [0][1][RTW89_ETSI][7] = 127, -+ [0][1][RTW89_MKK][7] = 127, -+ [0][1][RTW89_IC][7] = 127, -+ [0][1][RTW89_KCC][7] = 127, -+ [0][1][RTW89_ACMA][7] = 127, -+ [0][1][RTW89_CN][7] = 22, -+ [0][1][RTW89_UK][7] = 127, -+ [0][1][RTW89_FCC][8] = 127, -+ [0][1][RTW89_ETSI][8] = 127, -+ [0][1][RTW89_MKK][8] = 127, -+ [0][1][RTW89_IC][8] = 127, -+ [0][1][RTW89_KCC][8] = 127, -+ [0][1][RTW89_ACMA][8] = 127, -+ [0][1][RTW89_CN][8] = 22, -+ [0][1][RTW89_UK][8] = 127, -+ [0][1][RTW89_FCC][9] = 127, -+ [0][1][RTW89_ETSI][9] = 127, -+ [0][1][RTW89_MKK][9] = 127, -+ [0][1][RTW89_IC][9] = 127, -+ [0][1][RTW89_KCC][9] = 127, -+ [0][1][RTW89_ACMA][9] = 127, -+ [0][1][RTW89_CN][9] = 22, -+ [0][1][RTW89_UK][9] = 127, -+ [0][1][RTW89_FCC][10] = 127, -+ [0][1][RTW89_ETSI][10] = 127, -+ [0][1][RTW89_MKK][10] = 127, -+ [0][1][RTW89_IC][10] = 127, -+ [0][1][RTW89_KCC][10] = 127, -+ [0][1][RTW89_ACMA][10] = 127, -+ [0][1][RTW89_CN][10] = 22, -+ [0][1][RTW89_UK][10] = 127, -+ [0][1][RTW89_FCC][11] = 127, -+ [0][1][RTW89_ETSI][11] = 127, -+ [0][1][RTW89_MKK][11] = 127, -+ [0][1][RTW89_IC][11] = 127, -+ [0][1][RTW89_KCC][11] = 127, -+ [0][1][RTW89_ACMA][11] = 127, -+ [0][1][RTW89_CN][11] = 22, -+ [0][1][RTW89_UK][11] = 127, -+ [0][1][RTW89_FCC][12] = 127, -+ [0][1][RTW89_ETSI][12] = 127, -+ [0][1][RTW89_MKK][12] = 127, -+ [0][1][RTW89_IC][12] = 127, -+ [0][1][RTW89_KCC][12] = 127, -+ [0][1][RTW89_ACMA][12] = 127, -+ [0][1][RTW89_CN][12] = 20, -+ [0][1][RTW89_UK][12] = 127, -+ [0][1][RTW89_FCC][13] = 127, -+ [0][1][RTW89_ETSI][13] = 127, -+ [0][1][RTW89_MKK][13] = 127, -+ [0][1][RTW89_IC][13] = 127, -+ [0][1][RTW89_KCC][13] = 127, -+ [0][1][RTW89_ACMA][13] = 127, -+ [0][1][RTW89_CN][13] = 127, -+ [0][1][RTW89_UK][13] = 127, -+ [1][0][RTW89_FCC][0] = 70, -+ [1][0][RTW89_ETSI][0] = 42, -+ [1][0][RTW89_MKK][0] = 52, -+ [1][0][RTW89_IC][0] = 70, -+ [1][0][RTW89_KCC][0] = 56, -+ [1][0][RTW89_ACMA][0] = 42, -+ [1][0][RTW89_CN][0] = 42, -+ [1][0][RTW89_UK][0] = 42, -+ [1][0][RTW89_FCC][1] = 70, -+ [1][0][RTW89_ETSI][1] = 42, -+ [1][0][RTW89_MKK][1] = 52, -+ [1][0][RTW89_IC][1] = 70, -+ [1][0][RTW89_KCC][1] = 56, -+ [1][0][RTW89_ACMA][1] = 42, -+ [1][0][RTW89_CN][1] = 44, -+ [1][0][RTW89_UK][1] = 42, -+ [1][0][RTW89_FCC][2] = 74, -+ [1][0][RTW89_ETSI][2] = 42, -+ [1][0][RTW89_MKK][2] = 52, -+ [1][0][RTW89_IC][2] = 74, -+ [1][0][RTW89_KCC][2] = 56, -+ [1][0][RTW89_ACMA][2] = 42, -+ [1][0][RTW89_CN][2] = 44, -+ [1][0][RTW89_UK][2] = 42, -+ [1][0][RTW89_FCC][3] = 76, -+ [1][0][RTW89_ETSI][3] = 42, -+ [1][0][RTW89_MKK][3] = 52, -+ [1][0][RTW89_IC][3] = 76, -+ [1][0][RTW89_KCC][3] = 56, -+ [1][0][RTW89_ACMA][3] = 42, -+ [1][0][RTW89_CN][3] = 44, -+ [1][0][RTW89_UK][3] = 42, -+ [1][0][RTW89_FCC][4] = 76, -+ [1][0][RTW89_ETSI][4] = 42, -+ [1][0][RTW89_MKK][4] = 52, -+ [1][0][RTW89_IC][4] = 76, -+ [1][0][RTW89_KCC][4] = 56, -+ [1][0][RTW89_ACMA][4] = 42, -+ [1][0][RTW89_CN][4] = 44, -+ [1][0][RTW89_UK][4] = 42, -+ [1][0][RTW89_FCC][5] = 82, -+ [1][0][RTW89_ETSI][5] = 42, -+ [1][0][RTW89_MKK][5] = 52, -+ [1][0][RTW89_IC][5] = 82, -+ [1][0][RTW89_KCC][5] = 56, -+ [1][0][RTW89_ACMA][5] = 42, -+ [1][0][RTW89_CN][5] = 44, -+ [1][0][RTW89_UK][5] = 42, -+ [1][0][RTW89_FCC][6] = 74, -+ [1][0][RTW89_ETSI][6] = 42, -+ [1][0][RTW89_MKK][6] = 52, -+ [1][0][RTW89_IC][6] = 74, -+ [1][0][RTW89_KCC][6] = 56, -+ [1][0][RTW89_ACMA][6] = 42, -+ [1][0][RTW89_CN][6] = 44, -+ [1][0][RTW89_UK][6] = 42, -+ [1][0][RTW89_FCC][7] = 74, -+ [1][0][RTW89_ETSI][7] = 42, -+ [1][0][RTW89_MKK][7] = 52, -+ [1][0][RTW89_IC][7] = 74, -+ [1][0][RTW89_KCC][7] = 56, -+ [1][0][RTW89_ACMA][7] = 42, -+ [1][0][RTW89_CN][7] = 44, -+ [1][0][RTW89_UK][7] = 42, -+ [1][0][RTW89_FCC][8] = 74, -+ [1][0][RTW89_ETSI][8] = 42, -+ [1][0][RTW89_MKK][8] = 52, -+ [1][0][RTW89_IC][8] = 74, -+ [1][0][RTW89_KCC][8] = 56, -+ [1][0][RTW89_ACMA][8] = 42, -+ [1][0][RTW89_CN][8] = 44, -+ [1][0][RTW89_UK][8] = 42, -+ [1][0][RTW89_FCC][9] = 70, -+ [1][0][RTW89_ETSI][9] = 42, -+ [1][0][RTW89_MKK][9] = 52, -+ [1][0][RTW89_IC][9] = 70, -+ [1][0][RTW89_KCC][9] = 58, -+ [1][0][RTW89_ACMA][9] = 42, -+ [1][0][RTW89_CN][9] = 44, -+ [1][0][RTW89_UK][9] = 42, -+ [1][0][RTW89_FCC][10] = 70, -+ [1][0][RTW89_ETSI][10] = 42, -+ [1][0][RTW89_MKK][10] = 52, -+ [1][0][RTW89_IC][10] = 70, -+ [1][0][RTW89_KCC][10] = 58, -+ [1][0][RTW89_ACMA][10] = 42, -+ [1][0][RTW89_CN][10] = 44, -+ [1][0][RTW89_UK][10] = 42, -+ [1][0][RTW89_FCC][11] = 66, -+ [1][0][RTW89_ETSI][11] = 42, -+ [1][0][RTW89_MKK][11] = 52, -+ [1][0][RTW89_IC][11] = 66, -+ [1][0][RTW89_KCC][11] = 58, -+ [1][0][RTW89_ACMA][11] = 42, -+ [1][0][RTW89_CN][11] = 44, -+ [1][0][RTW89_UK][11] = 42, -+ [1][0][RTW89_FCC][12] = 34, -+ [1][0][RTW89_ETSI][12] = 42, -+ [1][0][RTW89_MKK][12] = 52, -+ [1][0][RTW89_IC][12] = 34, -+ [1][0][RTW89_KCC][12] = 58, -+ [1][0][RTW89_ACMA][12] = 42, -+ [1][0][RTW89_CN][12] = 42, -+ [1][0][RTW89_UK][12] = 42, -+ [1][0][RTW89_FCC][13] = 127, -+ [1][0][RTW89_ETSI][13] = 127, -+ [1][0][RTW89_MKK][13] = 127, -+ [1][0][RTW89_IC][13] = 127, -+ [1][0][RTW89_KCC][13] = 127, -+ [1][0][RTW89_ACMA][13] = 127, -+ [1][0][RTW89_CN][13] = 127, -+ [1][0][RTW89_UK][13] = 127, -+ [1][1][RTW89_FCC][0] = 127, -+ [1][1][RTW89_ETSI][0] = 127, -+ [1][1][RTW89_MKK][0] = 127, -+ [1][1][RTW89_IC][0] = 127, -+ [1][1][RTW89_KCC][0] = 127, -+ [1][1][RTW89_ACMA][0] = 127, -+ [1][1][RTW89_CN][0] = 32, -+ [1][1][RTW89_UK][0] = 127, -+ [1][1][RTW89_FCC][1] = 127, -+ [1][1][RTW89_ETSI][1] = 127, -+ [1][1][RTW89_MKK][1] = 127, -+ [1][1][RTW89_IC][1] = 127, -+ [1][1][RTW89_KCC][1] = 127, -+ [1][1][RTW89_ACMA][1] = 127, -+ [1][1][RTW89_CN][1] = 32, -+ [1][1][RTW89_UK][1] = 127, -+ [1][1][RTW89_FCC][2] = 127, -+ [1][1][RTW89_ETSI][2] = 127, -+ [1][1][RTW89_MKK][2] = 127, -+ [1][1][RTW89_IC][2] = 127, -+ [1][1][RTW89_KCC][2] = 127, -+ [1][1][RTW89_ACMA][2] = 127, -+ [1][1][RTW89_CN][2] = 32, -+ [1][1][RTW89_UK][2] = 127, -+ [1][1][RTW89_FCC][3] = 127, -+ [1][1][RTW89_ETSI][3] = 127, -+ [1][1][RTW89_MKK][3] = 127, -+ [1][1][RTW89_IC][3] = 127, -+ [1][1][RTW89_KCC][3] = 127, -+ [1][1][RTW89_ACMA][3] = 127, -+ [1][1][RTW89_CN][3] = 32, -+ [1][1][RTW89_UK][3] = 127, -+ [1][1][RTW89_FCC][4] = 127, -+ [1][1][RTW89_ETSI][4] = 127, -+ [1][1][RTW89_MKK][4] = 127, -+ [1][1][RTW89_IC][4] = 127, -+ [1][1][RTW89_KCC][4] = 127, -+ [1][1][RTW89_ACMA][4] = 127, -+ [1][1][RTW89_CN][4] = 32, -+ [1][1][RTW89_UK][4] = 127, -+ [1][1][RTW89_FCC][5] = 127, -+ [1][1][RTW89_ETSI][5] = 127, -+ [1][1][RTW89_MKK][5] = 127, -+ [1][1][RTW89_IC][5] = 127, -+ [1][1][RTW89_KCC][5] = 127, -+ [1][1][RTW89_ACMA][5] = 127, -+ [1][1][RTW89_CN][5] = 32, -+ [1][1][RTW89_UK][5] = 127, -+ [1][1][RTW89_FCC][6] = 127, -+ [1][1][RTW89_ETSI][6] = 127, -+ [1][1][RTW89_MKK][6] = 127, -+ [1][1][RTW89_IC][6] = 127, -+ [1][1][RTW89_KCC][6] = 127, -+ [1][1][RTW89_ACMA][6] = 127, -+ [1][1][RTW89_CN][6] = 32, -+ [1][1][RTW89_UK][6] = 127, -+ [1][1][RTW89_FCC][7] = 127, -+ [1][1][RTW89_ETSI][7] = 127, -+ [1][1][RTW89_MKK][7] = 127, -+ [1][1][RTW89_IC][7] = 127, -+ [1][1][RTW89_KCC][7] = 127, -+ [1][1][RTW89_ACMA][7] = 127, -+ [1][1][RTW89_CN][7] = 32, -+ [1][1][RTW89_UK][7] = 127, -+ [1][1][RTW89_FCC][8] = 127, -+ [1][1][RTW89_ETSI][8] = 127, -+ [1][1][RTW89_MKK][8] = 127, -+ [1][1][RTW89_IC][8] = 127, -+ [1][1][RTW89_KCC][8] = 127, -+ [1][1][RTW89_ACMA][8] = 127, -+ [1][1][RTW89_CN][8] = 32, -+ [1][1][RTW89_UK][8] = 127, -+ [1][1][RTW89_FCC][9] = 127, -+ [1][1][RTW89_ETSI][9] = 127, -+ [1][1][RTW89_MKK][9] = 127, -+ [1][1][RTW89_IC][9] = 127, -+ [1][1][RTW89_KCC][9] = 127, -+ [1][1][RTW89_ACMA][9] = 127, -+ [1][1][RTW89_CN][9] = 32, -+ [1][1][RTW89_UK][9] = 127, -+ [1][1][RTW89_FCC][10] = 127, -+ [1][1][RTW89_ETSI][10] = 127, -+ [1][1][RTW89_MKK][10] = 127, -+ [1][1][RTW89_IC][10] = 127, -+ [1][1][RTW89_KCC][10] = 127, -+ [1][1][RTW89_ACMA][10] = 127, -+ [1][1][RTW89_CN][10] = 32, -+ [1][1][RTW89_UK][10] = 127, -+ [1][1][RTW89_FCC][11] = 127, -+ [1][1][RTW89_ETSI][11] = 127, -+ [1][1][RTW89_MKK][11] = 127, -+ [1][1][RTW89_IC][11] = 127, -+ [1][1][RTW89_KCC][11] = 127, -+ [1][1][RTW89_ACMA][11] = 127, -+ [1][1][RTW89_CN][11] = 32, -+ [1][1][RTW89_UK][11] = 127, -+ [1][1][RTW89_FCC][12] = 127, -+ [1][1][RTW89_ETSI][12] = 127, -+ [1][1][RTW89_MKK][12] = 127, -+ [1][1][RTW89_IC][12] = 127, -+ [1][1][RTW89_KCC][12] = 127, -+ [1][1][RTW89_ACMA][12] = 127, -+ [1][1][RTW89_CN][12] = 32, -+ [1][1][RTW89_UK][12] = 127, -+ [1][1][RTW89_FCC][13] = 127, -+ [1][1][RTW89_ETSI][13] = 127, -+ [1][1][RTW89_MKK][13] = 127, -+ [1][1][RTW89_IC][13] = 127, -+ [1][1][RTW89_KCC][13] = 127, -+ [1][1][RTW89_ACMA][13] = 127, -+ [1][1][RTW89_CN][13] = 127, -+ [1][1][RTW89_UK][13] = 127, -+ [2][0][RTW89_FCC][0] = 76, -+ [2][0][RTW89_ETSI][0] = 54, -+ [2][0][RTW89_MKK][0] = 64, -+ [2][0][RTW89_IC][0] = 76, -+ [2][0][RTW89_KCC][0] = 68, -+ [2][0][RTW89_ACMA][0] = 54, -+ [2][0][RTW89_CN][0] = 56, -+ [2][0][RTW89_UK][0] = 54, -+ [2][0][RTW89_FCC][1] = 76, -+ [2][0][RTW89_ETSI][1] = 54, -+ [2][0][RTW89_MKK][1] = 64, -+ [2][0][RTW89_IC][1] = 76, -+ [2][0][RTW89_KCC][1] = 68, -+ [2][0][RTW89_ACMA][1] = 54, -+ [2][0][RTW89_CN][1] = 56, -+ [2][0][RTW89_UK][1] = 54, -+ [2][0][RTW89_FCC][2] = 78, -+ [2][0][RTW89_ETSI][2] = 54, -+ [2][0][RTW89_MKK][2] = 64, -+ [2][0][RTW89_IC][2] = 78, -+ [2][0][RTW89_KCC][2] = 68, -+ [2][0][RTW89_ACMA][2] = 54, -+ [2][0][RTW89_CN][2] = 56, -+ [2][0][RTW89_UK][2] = 54, -+ [2][0][RTW89_FCC][3] = 78, -+ [2][0][RTW89_ETSI][3] = 54, -+ [2][0][RTW89_MKK][3] = 64, -+ [2][0][RTW89_IC][3] = 78, -+ [2][0][RTW89_KCC][3] = 68, -+ [2][0][RTW89_ACMA][3] = 54, -+ [2][0][RTW89_CN][3] = 56, -+ [2][0][RTW89_UK][3] = 54, -+ [2][0][RTW89_FCC][4] = 78, -+ [2][0][RTW89_ETSI][4] = 54, -+ [2][0][RTW89_MKK][4] = 64, -+ [2][0][RTW89_IC][4] = 78, -+ [2][0][RTW89_KCC][4] = 68, -+ [2][0][RTW89_ACMA][4] = 54, -+ [2][0][RTW89_CN][4] = 56, -+ [2][0][RTW89_UK][4] = 54, -+ [2][0][RTW89_FCC][5] = 82, -+ [2][0][RTW89_ETSI][5] = 54, -+ [2][0][RTW89_MKK][5] = 64, -+ [2][0][RTW89_IC][5] = 82, -+ [2][0][RTW89_KCC][5] = 68, -+ [2][0][RTW89_ACMA][5] = 54, -+ [2][0][RTW89_CN][5] = 56, -+ [2][0][RTW89_UK][5] = 54, -+ [2][0][RTW89_FCC][6] = 74, -+ [2][0][RTW89_ETSI][6] = 54, -+ [2][0][RTW89_MKK][6] = 64, -+ [2][0][RTW89_IC][6] = 74, -+ [2][0][RTW89_KCC][6] = 68, -+ [2][0][RTW89_ACMA][6] = 54, -+ [2][0][RTW89_CN][6] = 56, -+ [2][0][RTW89_UK][6] = 54, -+ [2][0][RTW89_FCC][7] = 74, -+ [2][0][RTW89_ETSI][7] = 54, -+ [2][0][RTW89_MKK][7] = 64, -+ [2][0][RTW89_IC][7] = 74, -+ [2][0][RTW89_KCC][7] = 68, -+ [2][0][RTW89_ACMA][7] = 54, -+ [2][0][RTW89_CN][7] = 56, -+ [2][0][RTW89_UK][7] = 54, -+ [2][0][RTW89_FCC][8] = 74, -+ [2][0][RTW89_ETSI][8] = 54, -+ [2][0][RTW89_MKK][8] = 64, -+ [2][0][RTW89_IC][8] = 74, -+ [2][0][RTW89_KCC][8] = 68, -+ [2][0][RTW89_ACMA][8] = 54, -+ [2][0][RTW89_CN][8] = 56, -+ [2][0][RTW89_UK][8] = 54, -+ [2][0][RTW89_FCC][9] = 72, -+ [2][0][RTW89_ETSI][9] = 54, -+ [2][0][RTW89_MKK][9] = 64, -+ [2][0][RTW89_IC][9] = 72, -+ [2][0][RTW89_KCC][9] = 68, -+ [2][0][RTW89_ACMA][9] = 54, -+ [2][0][RTW89_CN][9] = 56, -+ [2][0][RTW89_UK][9] = 54, -+ [2][0][RTW89_FCC][10] = 72, -+ [2][0][RTW89_ETSI][10] = 54, -+ [2][0][RTW89_MKK][10] = 64, -+ [2][0][RTW89_IC][10] = 72, -+ [2][0][RTW89_KCC][10] = 68, -+ [2][0][RTW89_ACMA][10] = 54, -+ [2][0][RTW89_CN][10] = 56, -+ [2][0][RTW89_UK][10] = 54, -+ [2][0][RTW89_FCC][11] = 64, -+ [2][0][RTW89_ETSI][11] = 54, -+ [2][0][RTW89_MKK][11] = 64, -+ [2][0][RTW89_IC][11] = 64, -+ [2][0][RTW89_KCC][11] = 68, -+ [2][0][RTW89_ACMA][11] = 54, -+ [2][0][RTW89_CN][11] = 56, -+ [2][0][RTW89_UK][11] = 54, -+ [2][0][RTW89_FCC][12] = 34, -+ [2][0][RTW89_ETSI][12] = 54, -+ [2][0][RTW89_MKK][12] = 64, -+ [2][0][RTW89_IC][12] = 34, -+ [2][0][RTW89_KCC][12] = 68, -+ [2][0][RTW89_ACMA][12] = 54, -+ [2][0][RTW89_CN][12] = 56, -+ [2][0][RTW89_UK][12] = 54, -+ [2][0][RTW89_FCC][13] = 127, -+ [2][0][RTW89_ETSI][13] = 127, -+ [2][0][RTW89_MKK][13] = 127, -+ [2][0][RTW89_IC][13] = 127, -+ [2][0][RTW89_KCC][13] = 127, -+ [2][0][RTW89_ACMA][13] = 127, -+ [2][0][RTW89_CN][13] = 127, -+ [2][0][RTW89_UK][13] = 127, -+ [2][1][RTW89_FCC][0] = 127, -+ [2][1][RTW89_ETSI][0] = 127, -+ [2][1][RTW89_MKK][0] = 127, -+ [2][1][RTW89_IC][0] = 127, -+ [2][1][RTW89_KCC][0] = 127, -+ [2][1][RTW89_ACMA][0] = 127, -+ [2][1][RTW89_CN][0] = 44, -+ [2][1][RTW89_UK][0] = 127, -+ [2][1][RTW89_FCC][1] = 127, -+ [2][1][RTW89_ETSI][1] = 127, -+ [2][1][RTW89_MKK][1] = 127, -+ [2][1][RTW89_IC][1] = 127, -+ [2][1][RTW89_KCC][1] = 127, -+ [2][1][RTW89_ACMA][1] = 127, -+ [2][1][RTW89_CN][1] = 44, -+ [2][1][RTW89_UK][1] = 127, -+ [2][1][RTW89_FCC][2] = 127, -+ [2][1][RTW89_ETSI][2] = 127, -+ [2][1][RTW89_MKK][2] = 127, -+ [2][1][RTW89_IC][2] = 127, -+ [2][1][RTW89_KCC][2] = 127, -+ [2][1][RTW89_ACMA][2] = 127, -+ [2][1][RTW89_CN][2] = 44, -+ [2][1][RTW89_UK][2] = 127, -+ [2][1][RTW89_FCC][3] = 127, -+ [2][1][RTW89_ETSI][3] = 127, -+ [2][1][RTW89_MKK][3] = 127, -+ [2][1][RTW89_IC][3] = 127, -+ [2][1][RTW89_KCC][3] = 127, -+ [2][1][RTW89_ACMA][3] = 127, -+ [2][1][RTW89_CN][3] = 44, -+ [2][1][RTW89_UK][3] = 127, -+ [2][1][RTW89_FCC][4] = 127, -+ [2][1][RTW89_ETSI][4] = 127, -+ [2][1][RTW89_MKK][4] = 127, -+ [2][1][RTW89_IC][4] = 127, -+ [2][1][RTW89_KCC][4] = 127, -+ [2][1][RTW89_ACMA][4] = 127, -+ [2][1][RTW89_CN][4] = 44, -+ [2][1][RTW89_UK][4] = 127, -+ [2][1][RTW89_FCC][5] = 127, -+ [2][1][RTW89_ETSI][5] = 127, -+ [2][1][RTW89_MKK][5] = 127, -+ [2][1][RTW89_IC][5] = 127, -+ [2][1][RTW89_KCC][5] = 127, -+ [2][1][RTW89_ACMA][5] = 127, -+ [2][1][RTW89_CN][5] = 44, -+ [2][1][RTW89_UK][5] = 127, -+ [2][1][RTW89_FCC][6] = 127, -+ [2][1][RTW89_ETSI][6] = 127, -+ [2][1][RTW89_MKK][6] = 127, -+ [2][1][RTW89_IC][6] = 127, -+ [2][1][RTW89_KCC][6] = 127, -+ [2][1][RTW89_ACMA][6] = 127, -+ [2][1][RTW89_CN][6] = 44, -+ [2][1][RTW89_UK][6] = 127, -+ [2][1][RTW89_FCC][7] = 127, -+ [2][1][RTW89_ETSI][7] = 127, -+ [2][1][RTW89_MKK][7] = 127, -+ [2][1][RTW89_IC][7] = 127, -+ [2][1][RTW89_KCC][7] = 127, -+ [2][1][RTW89_ACMA][7] = 127, -+ [2][1][RTW89_CN][7] = 44, -+ [2][1][RTW89_UK][7] = 127, -+ [2][1][RTW89_FCC][8] = 127, -+ [2][1][RTW89_ETSI][8] = 127, -+ [2][1][RTW89_MKK][8] = 127, -+ [2][1][RTW89_IC][8] = 127, -+ [2][1][RTW89_KCC][8] = 127, -+ [2][1][RTW89_ACMA][8] = 127, -+ [2][1][RTW89_CN][8] = 44, -+ [2][1][RTW89_UK][8] = 127, -+ [2][1][RTW89_FCC][9] = 127, -+ [2][1][RTW89_ETSI][9] = 127, -+ [2][1][RTW89_MKK][9] = 127, -+ [2][1][RTW89_IC][9] = 127, -+ [2][1][RTW89_KCC][9] = 127, -+ [2][1][RTW89_ACMA][9] = 127, -+ [2][1][RTW89_CN][9] = 44, -+ [2][1][RTW89_UK][9] = 127, -+ [2][1][RTW89_FCC][10] = 127, -+ [2][1][RTW89_ETSI][10] = 127, -+ [2][1][RTW89_MKK][10] = 127, -+ [2][1][RTW89_IC][10] = 127, -+ [2][1][RTW89_KCC][10] = 127, -+ [2][1][RTW89_ACMA][10] = 127, -+ [2][1][RTW89_CN][10] = 44, -+ [2][1][RTW89_UK][10] = 127, -+ [2][1][RTW89_FCC][11] = 127, -+ [2][1][RTW89_ETSI][11] = 127, -+ [2][1][RTW89_MKK][11] = 127, -+ [2][1][RTW89_IC][11] = 127, -+ [2][1][RTW89_KCC][11] = 127, -+ [2][1][RTW89_ACMA][11] = 127, -+ [2][1][RTW89_CN][11] = 44, -+ [2][1][RTW89_UK][11] = 127, -+ [2][1][RTW89_FCC][12] = 127, -+ [2][1][RTW89_ETSI][12] = 127, -+ [2][1][RTW89_MKK][12] = 127, -+ [2][1][RTW89_IC][12] = 127, -+ [2][1][RTW89_KCC][12] = 127, -+ [2][1][RTW89_ACMA][12] = 127, -+ [2][1][RTW89_CN][12] = 42, -+ [2][1][RTW89_UK][12] = 127, -+ [2][1][RTW89_FCC][13] = 127, -+ [2][1][RTW89_ETSI][13] = 127, -+ [2][1][RTW89_MKK][13] = 127, -+ [2][1][RTW89_IC][13] = 127, -+ [2][1][RTW89_KCC][13] = 127, -+ [2][1][RTW89_ACMA][13] = 127, -+ [2][1][RTW89_CN][13] = 127, -+ [2][1][RTW89_UK][13] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 16, -+ [0][0][RTW89_WW][2] = 16, -+ [0][0][RTW89_WW][4] = 16, -+ [0][0][RTW89_WW][6] = 16, -+ [0][0][RTW89_WW][8] = 16, -+ [0][0][RTW89_WW][10] = 16, -+ [0][0][RTW89_WW][12] = 16, -+ [0][0][RTW89_WW][14] = 16, -+ [0][0][RTW89_WW][15] = 24, -+ [0][0][RTW89_WW][17] = 24, -+ [0][0][RTW89_WW][19] = 24, -+ [0][0][RTW89_WW][21] = 24, -+ [0][0][RTW89_WW][23] = 24, -+ [0][0][RTW89_WW][25] = 24, -+ [0][0][RTW89_WW][27] = 24, -+ [0][0][RTW89_WW][29] = 24, -+ [0][0][RTW89_WW][31] = 24, -+ [0][0][RTW89_WW][33] = 24, -+ [0][0][RTW89_WW][35] = 24, -+ [0][0][RTW89_WW][37] = 44, -+ [0][0][RTW89_WW][38] = 24, -+ [0][0][RTW89_WW][40] = 24, -+ [0][0][RTW89_WW][42] = 24, -+ [0][0][RTW89_WW][44] = 24, -+ [0][0][RTW89_WW][46] = 24, -+ [0][0][RTW89_WW][48] = 42, -+ [0][0][RTW89_WW][50] = 42, -+ [0][0][RTW89_WW][52] = 40, -+ [0][1][RTW89_WW][0] = 4, -+ [0][1][RTW89_WW][2] = 4, -+ [0][1][RTW89_WW][4] = 4, -+ [0][1][RTW89_WW][6] = 4, -+ [0][1][RTW89_WW][8] = 4, -+ [0][1][RTW89_WW][10] = 4, -+ [0][1][RTW89_WW][12] = 4, -+ [0][1][RTW89_WW][14] = 4, -+ [0][1][RTW89_WW][15] = 0, -+ [0][1][RTW89_WW][17] = 0, -+ [0][1][RTW89_WW][19] = 0, -+ [0][1][RTW89_WW][21] = 0, -+ [0][1][RTW89_WW][23] = 0, -+ [0][1][RTW89_WW][25] = 0, -+ [0][1][RTW89_WW][27] = 0, -+ [0][1][RTW89_WW][29] = 0, -+ [0][1][RTW89_WW][31] = 0, -+ [0][1][RTW89_WW][33] = 0, -+ [0][1][RTW89_WW][35] = 0, -+ [0][1][RTW89_WW][37] = 0, -+ [0][1][RTW89_WW][38] = 42, -+ [0][1][RTW89_WW][40] = 42, -+ [0][1][RTW89_WW][42] = 42, -+ [0][1][RTW89_WW][44] = 42, -+ [0][1][RTW89_WW][46] = 42, -+ [0][1][RTW89_WW][48] = 0, -+ [0][1][RTW89_WW][50] = 0, -+ [0][1][RTW89_WW][52] = 0, -+ [1][0][RTW89_WW][0] = 26, -+ [1][0][RTW89_WW][2] = 26, -+ [1][0][RTW89_WW][4] = 26, -+ [1][0][RTW89_WW][6] = 26, -+ [1][0][RTW89_WW][8] = 26, -+ [1][0][RTW89_WW][10] = 26, -+ [1][0][RTW89_WW][12] = 26, -+ [1][0][RTW89_WW][14] = 26, -+ [1][0][RTW89_WW][15] = 34, -+ [1][0][RTW89_WW][17] = 34, -+ [1][0][RTW89_WW][19] = 34, -+ [1][0][RTW89_WW][21] = 34, -+ [1][0][RTW89_WW][23] = 34, -+ [1][0][RTW89_WW][25] = 34, -+ [1][0][RTW89_WW][27] = 34, -+ [1][0][RTW89_WW][29] = 34, -+ [1][0][RTW89_WW][31] = 34, -+ [1][0][RTW89_WW][33] = 34, -+ [1][0][RTW89_WW][35] = 34, -+ [1][0][RTW89_WW][37] = 54, -+ [1][0][RTW89_WW][38] = 28, -+ [1][0][RTW89_WW][40] = 28, -+ [1][0][RTW89_WW][42] = 28, -+ [1][0][RTW89_WW][44] = 28, -+ [1][0][RTW89_WW][46] = 28, -+ [1][0][RTW89_WW][48] = 52, -+ [1][0][RTW89_WW][50] = 52, -+ [1][0][RTW89_WW][52] = 52, -+ [1][1][RTW89_WW][0] = 14, -+ [1][1][RTW89_WW][2] = 14, -+ [1][1][RTW89_WW][4] = 14, -+ [1][1][RTW89_WW][6] = 14, -+ [1][1][RTW89_WW][8] = 14, -+ [1][1][RTW89_WW][10] = 14, -+ [1][1][RTW89_WW][12] = 14, -+ [1][1][RTW89_WW][14] = 14, -+ [1][1][RTW89_WW][15] = 0, -+ [1][1][RTW89_WW][17] = 0, -+ [1][1][RTW89_WW][19] = 0, -+ [1][1][RTW89_WW][21] = 0, -+ [1][1][RTW89_WW][23] = 0, -+ [1][1][RTW89_WW][25] = 0, -+ [1][1][RTW89_WW][27] = 0, -+ [1][1][RTW89_WW][29] = 0, -+ [1][1][RTW89_WW][31] = 0, -+ [1][1][RTW89_WW][33] = 0, -+ [1][1][RTW89_WW][35] = 0, -+ [1][1][RTW89_WW][37] = 0, -+ [1][1][RTW89_WW][38] = 54, -+ [1][1][RTW89_WW][40] = 54, -+ [1][1][RTW89_WW][42] = 54, -+ [1][1][RTW89_WW][44] = 54, -+ [1][1][RTW89_WW][46] = 54, -+ [1][1][RTW89_WW][48] = 0, -+ [1][1][RTW89_WW][50] = 0, -+ [1][1][RTW89_WW][52] = 0, -+ [2][0][RTW89_WW][0] = 40, -+ [2][0][RTW89_WW][2] = 40, -+ [2][0][RTW89_WW][4] = 40, -+ [2][0][RTW89_WW][6] = 40, -+ [2][0][RTW89_WW][8] = 40, -+ [2][0][RTW89_WW][10] = 40, -+ [2][0][RTW89_WW][12] = 40, -+ [2][0][RTW89_WW][14] = 40, -+ [2][0][RTW89_WW][15] = 46, -+ [2][0][RTW89_WW][17] = 46, -+ [2][0][RTW89_WW][19] = 46, -+ [2][0][RTW89_WW][21] = 46, -+ [2][0][RTW89_WW][23] = 46, -+ [2][0][RTW89_WW][25] = 46, -+ [2][0][RTW89_WW][27] = 46, -+ [2][0][RTW89_WW][29] = 46, -+ [2][0][RTW89_WW][31] = 46, -+ [2][0][RTW89_WW][33] = 46, -+ [2][0][RTW89_WW][35] = 46, -+ [2][0][RTW89_WW][37] = 66, -+ [2][0][RTW89_WW][38] = 28, -+ [2][0][RTW89_WW][40] = 28, -+ [2][0][RTW89_WW][42] = 28, -+ [2][0][RTW89_WW][44] = 28, -+ [2][0][RTW89_WW][46] = 28, -+ [2][0][RTW89_WW][48] = 64, -+ [2][0][RTW89_WW][50] = 64, -+ [2][0][RTW89_WW][52] = 60, -+ [2][1][RTW89_WW][0] = 28, -+ [2][1][RTW89_WW][2] = 28, -+ [2][1][RTW89_WW][4] = 28, -+ [2][1][RTW89_WW][6] = 28, -+ [2][1][RTW89_WW][8] = 28, -+ [2][1][RTW89_WW][10] = 28, -+ [2][1][RTW89_WW][12] = 28, -+ [2][1][RTW89_WW][14] = 28, -+ [2][1][RTW89_WW][15] = 0, -+ [2][1][RTW89_WW][17] = 0, -+ [2][1][RTW89_WW][19] = 0, -+ [2][1][RTW89_WW][21] = 0, -+ [2][1][RTW89_WW][23] = 0, -+ [2][1][RTW89_WW][25] = 0, -+ [2][1][RTW89_WW][27] = 0, -+ [2][1][RTW89_WW][29] = 0, -+ [2][1][RTW89_WW][31] = 0, -+ [2][1][RTW89_WW][33] = 0, -+ [2][1][RTW89_WW][35] = 0, -+ [2][1][RTW89_WW][37] = 0, -+ [2][1][RTW89_WW][38] = 56, -+ [2][1][RTW89_WW][40] = 56, -+ [2][1][RTW89_WW][42] = 56, -+ [2][1][RTW89_WW][44] = 56, -+ [2][1][RTW89_WW][46] = 56, -+ [2][1][RTW89_WW][48] = 0, -+ [2][1][RTW89_WW][50] = 0, -+ [2][1][RTW89_WW][52] = 0, -+ [0][0][RTW89_FCC][0] = 52, -+ [0][0][RTW89_ETSI][0] = 24, -+ [0][0][RTW89_MKK][0] = 26, -+ [0][0][RTW89_IC][0] = 28, -+ [0][0][RTW89_KCC][0] = 42, -+ [0][0][RTW89_ACMA][0] = 24, -+ [0][0][RTW89_CN][0] = 16, -+ [0][0][RTW89_UK][0] = 24, -+ [0][0][RTW89_FCC][2] = 54, -+ [0][0][RTW89_ETSI][2] = 24, -+ [0][0][RTW89_MKK][2] = 26, -+ [0][0][RTW89_IC][2] = 28, -+ [0][0][RTW89_KCC][2] = 42, -+ [0][0][RTW89_ACMA][2] = 24, -+ [0][0][RTW89_CN][2] = 16, -+ [0][0][RTW89_UK][2] = 24, -+ [0][0][RTW89_FCC][4] = 52, -+ [0][0][RTW89_ETSI][4] = 24, -+ [0][0][RTW89_MKK][4] = 26, -+ [0][0][RTW89_IC][4] = 28, -+ [0][0][RTW89_KCC][4] = 42, -+ [0][0][RTW89_ACMA][4] = 24, -+ [0][0][RTW89_CN][4] = 16, -+ [0][0][RTW89_UK][4] = 24, -+ [0][0][RTW89_FCC][6] = 52, -+ [0][0][RTW89_ETSI][6] = 24, -+ [0][0][RTW89_MKK][6] = 26, -+ [0][0][RTW89_IC][6] = 28, -+ [0][0][RTW89_KCC][6] = 18, -+ [0][0][RTW89_ACMA][6] = 24, -+ [0][0][RTW89_CN][6] = 16, -+ [0][0][RTW89_UK][6] = 24, -+ [0][0][RTW89_FCC][8] = 52, -+ [0][0][RTW89_ETSI][8] = 24, -+ [0][0][RTW89_MKK][8] = 26, -+ [0][0][RTW89_IC][8] = 52, -+ [0][0][RTW89_KCC][8] = 42, -+ [0][0][RTW89_ACMA][8] = 24, -+ [0][0][RTW89_CN][8] = 16, -+ [0][0][RTW89_UK][8] = 24, -+ [0][0][RTW89_FCC][10] = 52, -+ [0][0][RTW89_ETSI][10] = 24, -+ [0][0][RTW89_MKK][10] = 26, -+ [0][0][RTW89_IC][10] = 52, -+ [0][0][RTW89_KCC][10] = 42, -+ [0][0][RTW89_ACMA][10] = 24, -+ [0][0][RTW89_CN][10] = 16, -+ [0][0][RTW89_UK][10] = 24, -+ [0][0][RTW89_FCC][12] = 56, -+ [0][0][RTW89_ETSI][12] = 24, -+ [0][0][RTW89_MKK][12] = 26, -+ [0][0][RTW89_IC][12] = 56, -+ [0][0][RTW89_KCC][12] = 44, -+ [0][0][RTW89_ACMA][12] = 24, -+ [0][0][RTW89_CN][12] = 16, -+ [0][0][RTW89_UK][12] = 24, -+ [0][0][RTW89_FCC][14] = 56, -+ [0][0][RTW89_ETSI][14] = 24, -+ [0][0][RTW89_MKK][14] = 26, -+ [0][0][RTW89_IC][14] = 56, -+ [0][0][RTW89_KCC][14] = 44, -+ [0][0][RTW89_ACMA][14] = 24, -+ [0][0][RTW89_CN][14] = 16, -+ [0][0][RTW89_UK][14] = 24, -+ [0][0][RTW89_FCC][15] = 54, -+ [0][0][RTW89_ETSI][15] = 24, -+ [0][0][RTW89_MKK][15] = 46, -+ [0][0][RTW89_IC][15] = 54, -+ [0][0][RTW89_KCC][15] = 44, -+ [0][0][RTW89_ACMA][15] = 24, -+ [0][0][RTW89_CN][15] = 127, -+ [0][0][RTW89_UK][15] = 24, -+ [0][0][RTW89_FCC][17] = 54, -+ [0][0][RTW89_ETSI][17] = 24, -+ [0][0][RTW89_MKK][17] = 50, -+ [0][0][RTW89_IC][17] = 54, -+ [0][0][RTW89_KCC][17] = 44, -+ [0][0][RTW89_ACMA][17] = 24, -+ [0][0][RTW89_CN][17] = 127, -+ [0][0][RTW89_UK][17] = 24, -+ [0][0][RTW89_FCC][19] = 54, -+ [0][0][RTW89_ETSI][19] = 24, -+ [0][0][RTW89_MKK][19] = 50, -+ [0][0][RTW89_IC][19] = 54, -+ [0][0][RTW89_KCC][19] = 44, -+ [0][0][RTW89_ACMA][19] = 24, -+ [0][0][RTW89_CN][19] = 127, -+ [0][0][RTW89_UK][19] = 24, -+ [0][0][RTW89_FCC][21] = 54, -+ [0][0][RTW89_ETSI][21] = 24, -+ [0][0][RTW89_MKK][21] = 50, -+ [0][0][RTW89_IC][21] = 54, -+ [0][0][RTW89_KCC][21] = 44, -+ [0][0][RTW89_ACMA][21] = 24, -+ [0][0][RTW89_CN][21] = 127, -+ [0][0][RTW89_UK][21] = 24, -+ [0][0][RTW89_FCC][23] = 54, -+ [0][0][RTW89_ETSI][23] = 24, -+ [0][0][RTW89_MKK][23] = 50, -+ [0][0][RTW89_IC][23] = 54, -+ [0][0][RTW89_KCC][23] = 44, -+ [0][0][RTW89_ACMA][23] = 24, -+ [0][0][RTW89_CN][23] = 127, -+ [0][0][RTW89_UK][23] = 24, -+ [0][0][RTW89_FCC][25] = 54, -+ [0][0][RTW89_ETSI][25] = 24, -+ [0][0][RTW89_MKK][25] = 50, -+ [0][0][RTW89_IC][25] = 127, -+ [0][0][RTW89_KCC][25] = 44, -+ [0][0][RTW89_ACMA][25] = 127, -+ [0][0][RTW89_CN][25] = 127, -+ [0][0][RTW89_UK][25] = 24, -+ [0][0][RTW89_FCC][27] = 54, -+ [0][0][RTW89_ETSI][27] = 24, -+ [0][0][RTW89_MKK][27] = 50, -+ [0][0][RTW89_IC][27] = 127, -+ [0][0][RTW89_KCC][27] = 42, -+ [0][0][RTW89_ACMA][27] = 127, -+ [0][0][RTW89_CN][27] = 127, -+ [0][0][RTW89_UK][27] = 24, -+ [0][0][RTW89_FCC][29] = 54, -+ [0][0][RTW89_ETSI][29] = 24, -+ [0][0][RTW89_MKK][29] = 50, -+ [0][0][RTW89_IC][29] = 127, -+ [0][0][RTW89_KCC][29] = 42, -+ [0][0][RTW89_ACMA][29] = 127, -+ [0][0][RTW89_CN][29] = 127, -+ [0][0][RTW89_UK][29] = 24, -+ [0][0][RTW89_FCC][31] = 54, -+ [0][0][RTW89_ETSI][31] = 24, -+ [0][0][RTW89_MKK][31] = 50, -+ [0][0][RTW89_IC][31] = 56, -+ [0][0][RTW89_KCC][31] = 42, -+ [0][0][RTW89_ACMA][31] = 24, -+ [0][0][RTW89_CN][31] = 127, -+ [0][0][RTW89_UK][31] = 24, -+ [0][0][RTW89_FCC][33] = 56, -+ [0][0][RTW89_ETSI][33] = 24, -+ [0][0][RTW89_MKK][33] = 50, -+ [0][0][RTW89_IC][33] = 56, -+ [0][0][RTW89_KCC][33] = 42, -+ [0][0][RTW89_ACMA][33] = 24, -+ [0][0][RTW89_CN][33] = 127, -+ [0][0][RTW89_UK][33] = 24, -+ [0][0][RTW89_FCC][35] = 56, -+ [0][0][RTW89_ETSI][35] = 24, -+ [0][0][RTW89_MKK][35] = 50, -+ [0][0][RTW89_IC][35] = 56, -+ [0][0][RTW89_KCC][35] = 42, -+ [0][0][RTW89_ACMA][35] = 24, -+ [0][0][RTW89_CN][35] = 127, -+ [0][0][RTW89_UK][35] = 24, -+ [0][0][RTW89_FCC][37] = 86, -+ [0][0][RTW89_ETSI][37] = 127, -+ [0][0][RTW89_MKK][37] = 46, -+ [0][0][RTW89_IC][37] = 86, -+ [0][0][RTW89_KCC][37] = 44, -+ [0][0][RTW89_ACMA][37] = 50, -+ [0][0][RTW89_CN][37] = 127, -+ [0][0][RTW89_UK][37] = 52, -+ [0][0][RTW89_FCC][38] = 68, -+ [0][0][RTW89_ETSI][38] = 28, -+ [0][0][RTW89_MKK][38] = 127, -+ [0][0][RTW89_IC][38] = 68, -+ [0][0][RTW89_KCC][38] = 44, -+ [0][0][RTW89_ACMA][38] = 84, -+ [0][0][RTW89_CN][38] = 54, -+ [0][0][RTW89_UK][38] = 24, -+ [0][0][RTW89_FCC][40] = 68, -+ [0][0][RTW89_ETSI][40] = 28, -+ [0][0][RTW89_MKK][40] = 127, -+ [0][0][RTW89_IC][40] = 68, -+ [0][0][RTW89_KCC][40] = 44, -+ [0][0][RTW89_ACMA][40] = 84, -+ [0][0][RTW89_CN][40] = 54, -+ [0][0][RTW89_UK][40] = 24, -+ [0][0][RTW89_FCC][42] = 70, -+ [0][0][RTW89_ETSI][42] = 28, -+ [0][0][RTW89_MKK][42] = 127, -+ [0][0][RTW89_IC][42] = 70, -+ [0][0][RTW89_KCC][42] = 44, -+ [0][0][RTW89_ACMA][42] = 84, -+ [0][0][RTW89_CN][42] = 54, -+ [0][0][RTW89_UK][42] = 24, -+ [0][0][RTW89_FCC][44] = 62, -+ [0][0][RTW89_ETSI][44] = 28, -+ [0][0][RTW89_MKK][44] = 127, -+ [0][0][RTW89_IC][44] = 62, -+ [0][0][RTW89_KCC][44] = 44, -+ [0][0][RTW89_ACMA][44] = 84, -+ [0][0][RTW89_CN][44] = 54, -+ [0][0][RTW89_UK][44] = 24, -+ [0][0][RTW89_FCC][46] = 62, -+ [0][0][RTW89_ETSI][46] = 28, -+ [0][0][RTW89_MKK][46] = 127, -+ [0][0][RTW89_IC][46] = 62, -+ [0][0][RTW89_KCC][46] = 44, -+ [0][0][RTW89_ACMA][46] = 84, -+ [0][0][RTW89_CN][46] = 54, -+ [0][0][RTW89_UK][46] = 24, -+ [0][0][RTW89_FCC][48] = 42, -+ [0][0][RTW89_ETSI][48] = 127, -+ [0][0][RTW89_MKK][48] = 127, -+ [0][0][RTW89_IC][48] = 127, -+ [0][0][RTW89_KCC][48] = 127, -+ [0][0][RTW89_ACMA][48] = 127, -+ [0][0][RTW89_CN][48] = 127, -+ [0][0][RTW89_UK][48] = 127, -+ [0][0][RTW89_FCC][50] = 42, -+ [0][0][RTW89_ETSI][50] = 127, -+ [0][0][RTW89_MKK][50] = 127, -+ [0][0][RTW89_IC][50] = 127, -+ [0][0][RTW89_KCC][50] = 127, -+ [0][0][RTW89_ACMA][50] = 127, -+ [0][0][RTW89_CN][50] = 127, -+ [0][0][RTW89_UK][50] = 127, -+ [0][0][RTW89_FCC][52] = 40, -+ [0][0][RTW89_ETSI][52] = 127, -+ [0][0][RTW89_MKK][52] = 127, -+ [0][0][RTW89_IC][52] = 127, -+ [0][0][RTW89_KCC][52] = 127, -+ [0][0][RTW89_ACMA][52] = 127, -+ [0][0][RTW89_CN][52] = 127, -+ [0][0][RTW89_UK][52] = 127, -+ [0][1][RTW89_FCC][0] = 127, -+ [0][1][RTW89_ETSI][0] = 127, -+ [0][1][RTW89_MKK][0] = 127, -+ [0][1][RTW89_IC][0] = 127, -+ [0][1][RTW89_KCC][0] = 127, -+ [0][1][RTW89_ACMA][0] = 127, -+ [0][1][RTW89_CN][0] = 4, -+ [0][1][RTW89_UK][0] = 127, -+ [0][1][RTW89_FCC][2] = 127, -+ [0][1][RTW89_ETSI][2] = 127, -+ [0][1][RTW89_MKK][2] = 127, -+ [0][1][RTW89_IC][2] = 127, -+ [0][1][RTW89_KCC][2] = 127, -+ [0][1][RTW89_ACMA][2] = 127, -+ [0][1][RTW89_CN][2] = 4, -+ [0][1][RTW89_UK][2] = 127, -+ [0][1][RTW89_FCC][4] = 127, -+ [0][1][RTW89_ETSI][4] = 127, -+ [0][1][RTW89_MKK][4] = 127, -+ [0][1][RTW89_IC][4] = 127, -+ [0][1][RTW89_KCC][4] = 127, -+ [0][1][RTW89_ACMA][4] = 127, -+ [0][1][RTW89_CN][4] = 4, -+ [0][1][RTW89_UK][4] = 127, -+ [0][1][RTW89_FCC][6] = 127, -+ [0][1][RTW89_ETSI][6] = 127, -+ [0][1][RTW89_MKK][6] = 127, -+ [0][1][RTW89_IC][6] = 127, -+ [0][1][RTW89_KCC][6] = 127, -+ [0][1][RTW89_ACMA][6] = 127, -+ [0][1][RTW89_CN][6] = 4, -+ [0][1][RTW89_UK][6] = 127, -+ [0][1][RTW89_FCC][8] = 127, -+ [0][1][RTW89_ETSI][8] = 127, -+ [0][1][RTW89_MKK][8] = 127, -+ [0][1][RTW89_IC][8] = 127, -+ [0][1][RTW89_KCC][8] = 127, -+ [0][1][RTW89_ACMA][8] = 127, -+ [0][1][RTW89_CN][8] = 4, -+ [0][1][RTW89_UK][8] = 127, -+ [0][1][RTW89_FCC][10] = 127, -+ [0][1][RTW89_ETSI][10] = 127, -+ [0][1][RTW89_MKK][10] = 127, -+ [0][1][RTW89_IC][10] = 127, -+ [0][1][RTW89_KCC][10] = 127, -+ [0][1][RTW89_ACMA][10] = 127, -+ [0][1][RTW89_CN][10] = 4, -+ [0][1][RTW89_UK][10] = 127, -+ [0][1][RTW89_FCC][12] = 127, -+ [0][1][RTW89_ETSI][12] = 127, -+ [0][1][RTW89_MKK][12] = 127, -+ [0][1][RTW89_IC][12] = 127, -+ [0][1][RTW89_KCC][12] = 127, -+ [0][1][RTW89_ACMA][12] = 127, -+ [0][1][RTW89_CN][12] = 4, -+ [0][1][RTW89_UK][12] = 127, -+ [0][1][RTW89_FCC][14] = 127, -+ [0][1][RTW89_ETSI][14] = 127, -+ [0][1][RTW89_MKK][14] = 127, -+ [0][1][RTW89_IC][14] = 127, -+ [0][1][RTW89_KCC][14] = 127, -+ [0][1][RTW89_ACMA][14] = 127, -+ [0][1][RTW89_CN][14] = 4, -+ [0][1][RTW89_UK][14] = 127, -+ [0][1][RTW89_FCC][15] = 127, -+ [0][1][RTW89_ETSI][15] = 127, -+ [0][1][RTW89_MKK][15] = 127, -+ [0][1][RTW89_IC][15] = 127, -+ [0][1][RTW89_KCC][15] = 127, -+ [0][1][RTW89_ACMA][15] = 127, -+ [0][1][RTW89_CN][15] = 127, -+ [0][1][RTW89_UK][15] = 127, -+ [0][1][RTW89_FCC][17] = 127, -+ [0][1][RTW89_ETSI][17] = 127, -+ [0][1][RTW89_MKK][17] = 127, -+ [0][1][RTW89_IC][17] = 127, -+ [0][1][RTW89_KCC][17] = 127, -+ [0][1][RTW89_ACMA][17] = 127, -+ [0][1][RTW89_CN][17] = 127, -+ [0][1][RTW89_UK][17] = 127, -+ [0][1][RTW89_FCC][19] = 127, -+ [0][1][RTW89_ETSI][19] = 127, -+ [0][1][RTW89_MKK][19] = 127, -+ [0][1][RTW89_IC][19] = 127, -+ [0][1][RTW89_KCC][19] = 127, -+ [0][1][RTW89_ACMA][19] = 127, -+ [0][1][RTW89_CN][19] = 127, -+ [0][1][RTW89_UK][19] = 127, -+ [0][1][RTW89_FCC][21] = 127, -+ [0][1][RTW89_ETSI][21] = 127, -+ [0][1][RTW89_MKK][21] = 127, -+ [0][1][RTW89_IC][21] = 127, -+ [0][1][RTW89_KCC][21] = 127, -+ [0][1][RTW89_ACMA][21] = 127, -+ [0][1][RTW89_CN][21] = 127, -+ [0][1][RTW89_UK][21] = 127, -+ [0][1][RTW89_FCC][23] = 127, -+ [0][1][RTW89_ETSI][23] = 127, -+ [0][1][RTW89_MKK][23] = 127, -+ [0][1][RTW89_IC][23] = 127, -+ [0][1][RTW89_KCC][23] = 127, -+ [0][1][RTW89_ACMA][23] = 127, -+ [0][1][RTW89_CN][23] = 127, -+ [0][1][RTW89_UK][23] = 127, -+ [0][1][RTW89_FCC][25] = 127, -+ [0][1][RTW89_ETSI][25] = 127, -+ [0][1][RTW89_MKK][25] = 127, -+ [0][1][RTW89_IC][25] = 127, -+ [0][1][RTW89_KCC][25] = 127, -+ [0][1][RTW89_ACMA][25] = 127, -+ [0][1][RTW89_CN][25] = 127, -+ [0][1][RTW89_UK][25] = 127, -+ [0][1][RTW89_FCC][27] = 127, -+ [0][1][RTW89_ETSI][27] = 127, -+ [0][1][RTW89_MKK][27] = 127, -+ [0][1][RTW89_IC][27] = 127, -+ [0][1][RTW89_KCC][27] = 127, -+ [0][1][RTW89_ACMA][27] = 127, -+ [0][1][RTW89_CN][27] = 127, -+ [0][1][RTW89_UK][27] = 127, -+ [0][1][RTW89_FCC][29] = 127, -+ [0][1][RTW89_ETSI][29] = 127, -+ [0][1][RTW89_MKK][29] = 127, -+ [0][1][RTW89_IC][29] = 127, -+ [0][1][RTW89_KCC][29] = 127, -+ [0][1][RTW89_ACMA][29] = 127, -+ [0][1][RTW89_CN][29] = 127, -+ [0][1][RTW89_UK][29] = 127, -+ [0][1][RTW89_FCC][31] = 127, -+ [0][1][RTW89_ETSI][31] = 127, -+ [0][1][RTW89_MKK][31] = 127, -+ [0][1][RTW89_IC][31] = 127, -+ [0][1][RTW89_KCC][31] = 127, -+ [0][1][RTW89_ACMA][31] = 127, -+ [0][1][RTW89_CN][31] = 127, -+ [0][1][RTW89_UK][31] = 127, -+ [0][1][RTW89_FCC][33] = 127, -+ [0][1][RTW89_ETSI][33] = 127, -+ [0][1][RTW89_MKK][33] = 127, -+ [0][1][RTW89_IC][33] = 127, -+ [0][1][RTW89_KCC][33] = 127, -+ [0][1][RTW89_ACMA][33] = 127, -+ [0][1][RTW89_CN][33] = 127, -+ [0][1][RTW89_UK][33] = 127, -+ [0][1][RTW89_FCC][35] = 127, -+ [0][1][RTW89_ETSI][35] = 127, -+ [0][1][RTW89_MKK][35] = 127, -+ [0][1][RTW89_IC][35] = 127, -+ [0][1][RTW89_KCC][35] = 127, -+ [0][1][RTW89_ACMA][35] = 127, -+ [0][1][RTW89_CN][35] = 127, -+ [0][1][RTW89_UK][35] = 127, -+ [0][1][RTW89_FCC][37] = 127, -+ [0][1][RTW89_ETSI][37] = 127, -+ [0][1][RTW89_MKK][37] = 127, -+ [0][1][RTW89_IC][37] = 127, -+ [0][1][RTW89_KCC][37] = 127, -+ [0][1][RTW89_ACMA][37] = 127, -+ [0][1][RTW89_CN][37] = 127, -+ [0][1][RTW89_UK][37] = 127, -+ [0][1][RTW89_FCC][38] = 127, -+ [0][1][RTW89_ETSI][38] = 127, -+ [0][1][RTW89_MKK][38] = 127, -+ [0][1][RTW89_IC][38] = 127, -+ [0][1][RTW89_KCC][38] = 127, -+ [0][1][RTW89_ACMA][38] = 127, -+ [0][1][RTW89_CN][38] = 42, -+ [0][1][RTW89_UK][38] = 127, -+ [0][1][RTW89_FCC][40] = 127, -+ [0][1][RTW89_ETSI][40] = 127, -+ [0][1][RTW89_MKK][40] = 127, -+ [0][1][RTW89_IC][40] = 127, -+ [0][1][RTW89_KCC][40] = 127, -+ [0][1][RTW89_ACMA][40] = 127, -+ [0][1][RTW89_CN][40] = 42, -+ [0][1][RTW89_UK][40] = 127, -+ [0][1][RTW89_FCC][42] = 127, -+ [0][1][RTW89_ETSI][42] = 127, -+ [0][1][RTW89_MKK][42] = 127, -+ [0][1][RTW89_IC][42] = 127, -+ [0][1][RTW89_KCC][42] = 127, -+ [0][1][RTW89_ACMA][42] = 127, -+ [0][1][RTW89_CN][42] = 42, -+ [0][1][RTW89_UK][42] = 127, -+ [0][1][RTW89_FCC][44] = 127, -+ [0][1][RTW89_ETSI][44] = 127, -+ [0][1][RTW89_MKK][44] = 127, -+ [0][1][RTW89_IC][44] = 127, -+ [0][1][RTW89_KCC][44] = 127, -+ [0][1][RTW89_ACMA][44] = 127, -+ [0][1][RTW89_CN][44] = 42, -+ [0][1][RTW89_UK][44] = 127, -+ [0][1][RTW89_FCC][46] = 127, -+ [0][1][RTW89_ETSI][46] = 127, -+ [0][1][RTW89_MKK][46] = 127, -+ [0][1][RTW89_IC][46] = 127, -+ [0][1][RTW89_KCC][46] = 127, -+ [0][1][RTW89_ACMA][46] = 127, -+ [0][1][RTW89_CN][46] = 42, -+ [0][1][RTW89_UK][46] = 127, -+ [0][1][RTW89_FCC][48] = 127, -+ [0][1][RTW89_ETSI][48] = 127, -+ [0][1][RTW89_MKK][48] = 127, -+ [0][1][RTW89_IC][48] = 127, -+ [0][1][RTW89_KCC][48] = 127, -+ [0][1][RTW89_ACMA][48] = 127, -+ [0][1][RTW89_CN][48] = 127, -+ [0][1][RTW89_UK][48] = 127, -+ [0][1][RTW89_FCC][50] = 127, -+ [0][1][RTW89_ETSI][50] = 127, -+ [0][1][RTW89_MKK][50] = 127, -+ [0][1][RTW89_IC][50] = 127, -+ [0][1][RTW89_KCC][50] = 127, -+ [0][1][RTW89_ACMA][50] = 127, -+ [0][1][RTW89_CN][50] = 127, -+ [0][1][RTW89_UK][50] = 127, -+ [0][1][RTW89_FCC][52] = 127, -+ [0][1][RTW89_ETSI][52] = 127, -+ [0][1][RTW89_MKK][52] = 127, -+ [0][1][RTW89_IC][52] = 127, -+ [0][1][RTW89_KCC][52] = 127, -+ [0][1][RTW89_ACMA][52] = 127, -+ [0][1][RTW89_CN][52] = 127, -+ [0][1][RTW89_UK][52] = 127, -+ [1][0][RTW89_FCC][0] = 64, -+ [1][0][RTW89_ETSI][0] = 34, -+ [1][0][RTW89_MKK][0] = 38, -+ [1][0][RTW89_IC][0] = 38, -+ [1][0][RTW89_KCC][0] = 52, -+ [1][0][RTW89_ACMA][0] = 34, -+ [1][0][RTW89_CN][0] = 26, -+ [1][0][RTW89_UK][0] = 34, -+ [1][0][RTW89_FCC][2] = 66, -+ [1][0][RTW89_ETSI][2] = 34, -+ [1][0][RTW89_MKK][2] = 38, -+ [1][0][RTW89_IC][2] = 38, -+ [1][0][RTW89_KCC][2] = 52, -+ [1][0][RTW89_ACMA][2] = 34, -+ [1][0][RTW89_CN][2] = 26, -+ [1][0][RTW89_UK][2] = 34, -+ [1][0][RTW89_FCC][4] = 62, -+ [1][0][RTW89_ETSI][4] = 34, -+ [1][0][RTW89_MKK][4] = 36, -+ [1][0][RTW89_IC][4] = 38, -+ [1][0][RTW89_KCC][4] = 52, -+ [1][0][RTW89_ACMA][4] = 34, -+ [1][0][RTW89_CN][4] = 26, -+ [1][0][RTW89_UK][4] = 34, -+ [1][0][RTW89_FCC][6] = 62, -+ [1][0][RTW89_ETSI][6] = 34, -+ [1][0][RTW89_MKK][6] = 36, -+ [1][0][RTW89_IC][6] = 38, -+ [1][0][RTW89_KCC][6] = 32, -+ [1][0][RTW89_ACMA][6] = 34, -+ [1][0][RTW89_CN][6] = 26, -+ [1][0][RTW89_UK][6] = 34, -+ [1][0][RTW89_FCC][8] = 62, -+ [1][0][RTW89_ETSI][8] = 34, -+ [1][0][RTW89_MKK][8] = 38, -+ [1][0][RTW89_IC][8] = 62, -+ [1][0][RTW89_KCC][8] = 52, -+ [1][0][RTW89_ACMA][8] = 34, -+ [1][0][RTW89_CN][8] = 26, -+ [1][0][RTW89_UK][8] = 34, -+ [1][0][RTW89_FCC][10] = 62, -+ [1][0][RTW89_ETSI][10] = 34, -+ [1][0][RTW89_MKK][10] = 38, -+ [1][0][RTW89_IC][10] = 62, -+ [1][0][RTW89_KCC][10] = 52, -+ [1][0][RTW89_ACMA][10] = 34, -+ [1][0][RTW89_CN][10] = 26, -+ [1][0][RTW89_UK][10] = 34, -+ [1][0][RTW89_FCC][12] = 62, -+ [1][0][RTW89_ETSI][12] = 34, -+ [1][0][RTW89_MKK][12] = 38, -+ [1][0][RTW89_IC][12] = 62, -+ [1][0][RTW89_KCC][12] = 54, -+ [1][0][RTW89_ACMA][12] = 34, -+ [1][0][RTW89_CN][12] = 26, -+ [1][0][RTW89_UK][12] = 34, -+ [1][0][RTW89_FCC][14] = 64, -+ [1][0][RTW89_ETSI][14] = 34, -+ [1][0][RTW89_MKK][14] = 38, -+ [1][0][RTW89_IC][14] = 64, -+ [1][0][RTW89_KCC][14] = 54, -+ [1][0][RTW89_ACMA][14] = 34, -+ [1][0][RTW89_CN][14] = 26, -+ [1][0][RTW89_UK][14] = 34, -+ [1][0][RTW89_FCC][15] = 62, -+ [1][0][RTW89_ETSI][15] = 34, -+ [1][0][RTW89_MKK][15] = 58, -+ [1][0][RTW89_IC][15] = 62, -+ [1][0][RTW89_KCC][15] = 54, -+ [1][0][RTW89_ACMA][15] = 34, -+ [1][0][RTW89_CN][15] = 127, -+ [1][0][RTW89_UK][15] = 34, -+ [1][0][RTW89_FCC][17] = 62, -+ [1][0][RTW89_ETSI][17] = 34, -+ [1][0][RTW89_MKK][17] = 58, -+ [1][0][RTW89_IC][17] = 62, -+ [1][0][RTW89_KCC][17] = 54, -+ [1][0][RTW89_ACMA][17] = 34, -+ [1][0][RTW89_CN][17] = 127, -+ [1][0][RTW89_UK][17] = 34, -+ [1][0][RTW89_FCC][19] = 64, -+ [1][0][RTW89_ETSI][19] = 34, -+ [1][0][RTW89_MKK][19] = 58, -+ [1][0][RTW89_IC][19] = 64, -+ [1][0][RTW89_KCC][19] = 54, -+ [1][0][RTW89_ACMA][19] = 34, -+ [1][0][RTW89_CN][19] = 127, -+ [1][0][RTW89_UK][19] = 34, -+ [1][0][RTW89_FCC][21] = 64, -+ [1][0][RTW89_ETSI][21] = 34, -+ [1][0][RTW89_MKK][21] = 58, -+ [1][0][RTW89_IC][21] = 64, -+ [1][0][RTW89_KCC][21] = 54, -+ [1][0][RTW89_ACMA][21] = 34, -+ [1][0][RTW89_CN][21] = 127, -+ [1][0][RTW89_UK][21] = 34, -+ [1][0][RTW89_FCC][23] = 64, -+ [1][0][RTW89_ETSI][23] = 34, -+ [1][0][RTW89_MKK][23] = 58, -+ [1][0][RTW89_IC][23] = 64, -+ [1][0][RTW89_KCC][23] = 54, -+ [1][0][RTW89_ACMA][23] = 34, -+ [1][0][RTW89_CN][23] = 127, -+ [1][0][RTW89_UK][23] = 34, -+ [1][0][RTW89_FCC][25] = 64, -+ [1][0][RTW89_ETSI][25] = 34, -+ [1][0][RTW89_MKK][25] = 58, -+ [1][0][RTW89_IC][25] = 127, -+ [1][0][RTW89_KCC][25] = 54, -+ [1][0][RTW89_ACMA][25] = 127, -+ [1][0][RTW89_CN][25] = 127, -+ [1][0][RTW89_UK][25] = 34, -+ [1][0][RTW89_FCC][27] = 64, -+ [1][0][RTW89_ETSI][27] = 34, -+ [1][0][RTW89_MKK][27] = 58, -+ [1][0][RTW89_IC][27] = 127, -+ [1][0][RTW89_KCC][27] = 54, -+ [1][0][RTW89_ACMA][27] = 127, -+ [1][0][RTW89_CN][27] = 127, -+ [1][0][RTW89_UK][27] = 34, -+ [1][0][RTW89_FCC][29] = 64, -+ [1][0][RTW89_ETSI][29] = 34, -+ [1][0][RTW89_MKK][29] = 58, -+ [1][0][RTW89_IC][29] = 127, -+ [1][0][RTW89_KCC][29] = 54, -+ [1][0][RTW89_ACMA][29] = 127, -+ [1][0][RTW89_CN][29] = 127, -+ [1][0][RTW89_UK][29] = 34, -+ [1][0][RTW89_FCC][31] = 64, -+ [1][0][RTW89_ETSI][31] = 34, -+ [1][0][RTW89_MKK][31] = 58, -+ [1][0][RTW89_IC][31] = 64, -+ [1][0][RTW89_KCC][31] = 54, -+ [1][0][RTW89_ACMA][31] = 34, -+ [1][0][RTW89_CN][31] = 127, -+ [1][0][RTW89_UK][31] = 34, -+ [1][0][RTW89_FCC][33] = 64, -+ [1][0][RTW89_ETSI][33] = 34, -+ [1][0][RTW89_MKK][33] = 58, -+ [1][0][RTW89_IC][33] = 64, -+ [1][0][RTW89_KCC][33] = 54, -+ [1][0][RTW89_ACMA][33] = 34, -+ [1][0][RTW89_CN][33] = 127, -+ [1][0][RTW89_UK][33] = 34, -+ [1][0][RTW89_FCC][35] = 64, -+ [1][0][RTW89_ETSI][35] = 34, -+ [1][0][RTW89_MKK][35] = 58, -+ [1][0][RTW89_IC][35] = 64, -+ [1][0][RTW89_KCC][35] = 54, -+ [1][0][RTW89_ACMA][35] = 34, -+ [1][0][RTW89_CN][35] = 127, -+ [1][0][RTW89_UK][35] = 34, -+ [1][0][RTW89_FCC][37] = 78, -+ [1][0][RTW89_ETSI][37] = 127, -+ [1][0][RTW89_MKK][37] = 56, -+ [1][0][RTW89_IC][37] = 78, -+ [1][0][RTW89_KCC][37] = 54, -+ [1][0][RTW89_ACMA][37] = 62, -+ [1][0][RTW89_CN][37] = 127, -+ [1][0][RTW89_UK][37] = 62, -+ [1][0][RTW89_FCC][38] = 82, -+ [1][0][RTW89_ETSI][38] = 28, -+ [1][0][RTW89_MKK][38] = 127, -+ [1][0][RTW89_IC][38] = 82, -+ [1][0][RTW89_KCC][38] = 54, -+ [1][0][RTW89_ACMA][38] = 84, -+ [1][0][RTW89_CN][38] = 66, -+ [1][0][RTW89_UK][38] = 34, -+ [1][0][RTW89_FCC][40] = 82, -+ [1][0][RTW89_ETSI][40] = 28, -+ [1][0][RTW89_MKK][40] = 127, -+ [1][0][RTW89_IC][40] = 82, -+ [1][0][RTW89_KCC][40] = 54, -+ [1][0][RTW89_ACMA][40] = 84, -+ [1][0][RTW89_CN][40] = 66, -+ [1][0][RTW89_UK][40] = 34, -+ [1][0][RTW89_FCC][42] = 78, -+ [1][0][RTW89_ETSI][42] = 28, -+ [1][0][RTW89_MKK][42] = 127, -+ [1][0][RTW89_IC][42] = 78, -+ [1][0][RTW89_KCC][42] = 54, -+ [1][0][RTW89_ACMA][42] = 84, -+ [1][0][RTW89_CN][42] = 66, -+ [1][0][RTW89_UK][42] = 34, -+ [1][0][RTW89_FCC][44] = 82, -+ [1][0][RTW89_ETSI][44] = 28, -+ [1][0][RTW89_MKK][44] = 127, -+ [1][0][RTW89_IC][44] = 82, -+ [1][0][RTW89_KCC][44] = 54, -+ [1][0][RTW89_ACMA][44] = 84, -+ [1][0][RTW89_CN][44] = 66, -+ [1][0][RTW89_UK][44] = 34, -+ [1][0][RTW89_FCC][46] = 82, -+ [1][0][RTW89_ETSI][46] = 28, -+ [1][0][RTW89_MKK][46] = 127, -+ [1][0][RTW89_IC][46] = 82, -+ [1][0][RTW89_KCC][46] = 54, -+ [1][0][RTW89_ACMA][46] = 84, -+ [1][0][RTW89_CN][46] = 66, -+ [1][0][RTW89_UK][46] = 34, -+ [1][0][RTW89_FCC][48] = 52, -+ [1][0][RTW89_ETSI][48] = 127, -+ [1][0][RTW89_MKK][48] = 127, -+ [1][0][RTW89_IC][48] = 127, -+ [1][0][RTW89_KCC][48] = 127, -+ [1][0][RTW89_ACMA][48] = 127, -+ [1][0][RTW89_CN][48] = 127, -+ [1][0][RTW89_UK][48] = 127, -+ [1][0][RTW89_FCC][50] = 52, -+ [1][0][RTW89_ETSI][50] = 127, -+ [1][0][RTW89_MKK][50] = 127, -+ [1][0][RTW89_IC][50] = 127, -+ [1][0][RTW89_KCC][50] = 127, -+ [1][0][RTW89_ACMA][50] = 127, -+ [1][0][RTW89_CN][50] = 127, -+ [1][0][RTW89_UK][50] = 127, -+ [1][0][RTW89_FCC][52] = 52, -+ [1][0][RTW89_ETSI][52] = 127, -+ [1][0][RTW89_MKK][52] = 127, -+ [1][0][RTW89_IC][52] = 127, -+ [1][0][RTW89_KCC][52] = 127, -+ [1][0][RTW89_ACMA][52] = 127, -+ [1][0][RTW89_CN][52] = 127, -+ [1][0][RTW89_UK][52] = 127, -+ [1][1][RTW89_FCC][0] = 127, -+ [1][1][RTW89_ETSI][0] = 127, -+ [1][1][RTW89_MKK][0] = 127, -+ [1][1][RTW89_IC][0] = 127, -+ [1][1][RTW89_KCC][0] = 127, -+ [1][1][RTW89_ACMA][0] = 127, -+ [1][1][RTW89_CN][0] = 14, -+ [1][1][RTW89_UK][0] = 127, -+ [1][1][RTW89_FCC][2] = 127, -+ [1][1][RTW89_ETSI][2] = 127, -+ [1][1][RTW89_MKK][2] = 127, -+ [1][1][RTW89_IC][2] = 127, -+ [1][1][RTW89_KCC][2] = 127, -+ [1][1][RTW89_ACMA][2] = 127, -+ [1][1][RTW89_CN][2] = 14, -+ [1][1][RTW89_UK][2] = 127, -+ [1][1][RTW89_FCC][4] = 127, -+ [1][1][RTW89_ETSI][4] = 127, -+ [1][1][RTW89_MKK][4] = 127, -+ [1][1][RTW89_IC][4] = 127, -+ [1][1][RTW89_KCC][4] = 127, -+ [1][1][RTW89_ACMA][4] = 127, -+ [1][1][RTW89_CN][4] = 14, -+ [1][1][RTW89_UK][4] = 127, -+ [1][1][RTW89_FCC][6] = 127, -+ [1][1][RTW89_ETSI][6] = 127, -+ [1][1][RTW89_MKK][6] = 127, -+ [1][1][RTW89_IC][6] = 127, -+ [1][1][RTW89_KCC][6] = 127, -+ [1][1][RTW89_ACMA][6] = 127, -+ [1][1][RTW89_CN][6] = 14, -+ [1][1][RTW89_UK][6] = 127, -+ [1][1][RTW89_FCC][8] = 127, -+ [1][1][RTW89_ETSI][8] = 127, -+ [1][1][RTW89_MKK][8] = 127, -+ [1][1][RTW89_IC][8] = 127, -+ [1][1][RTW89_KCC][8] = 127, -+ [1][1][RTW89_ACMA][8] = 127, -+ [1][1][RTW89_CN][8] = 14, -+ [1][1][RTW89_UK][8] = 127, -+ [1][1][RTW89_FCC][10] = 127, -+ [1][1][RTW89_ETSI][10] = 127, -+ [1][1][RTW89_MKK][10] = 127, -+ [1][1][RTW89_IC][10] = 127, -+ [1][1][RTW89_KCC][10] = 127, -+ [1][1][RTW89_ACMA][10] = 127, -+ [1][1][RTW89_CN][10] = 14, -+ [1][1][RTW89_UK][10] = 127, -+ [1][1][RTW89_FCC][12] = 127, -+ [1][1][RTW89_ETSI][12] = 127, -+ [1][1][RTW89_MKK][12] = 127, -+ [1][1][RTW89_IC][12] = 127, -+ [1][1][RTW89_KCC][12] = 127, -+ [1][1][RTW89_ACMA][12] = 127, -+ [1][1][RTW89_CN][12] = 14, -+ [1][1][RTW89_UK][12] = 127, -+ [1][1][RTW89_FCC][14] = 127, -+ [1][1][RTW89_ETSI][14] = 127, -+ [1][1][RTW89_MKK][14] = 127, -+ [1][1][RTW89_IC][14] = 127, -+ [1][1][RTW89_KCC][14] = 127, -+ [1][1][RTW89_ACMA][14] = 127, -+ [1][1][RTW89_CN][14] = 14, -+ [1][1][RTW89_UK][14] = 127, -+ [1][1][RTW89_FCC][15] = 127, -+ [1][1][RTW89_ETSI][15] = 127, -+ [1][1][RTW89_MKK][15] = 127, -+ [1][1][RTW89_IC][15] = 127, -+ [1][1][RTW89_KCC][15] = 127, -+ [1][1][RTW89_ACMA][15] = 127, -+ [1][1][RTW89_CN][15] = 127, -+ [1][1][RTW89_UK][15] = 127, -+ [1][1][RTW89_FCC][17] = 127, -+ [1][1][RTW89_ETSI][17] = 127, -+ [1][1][RTW89_MKK][17] = 127, -+ [1][1][RTW89_IC][17] = 127, -+ [1][1][RTW89_KCC][17] = 127, -+ [1][1][RTW89_ACMA][17] = 127, -+ [1][1][RTW89_CN][17] = 127, -+ [1][1][RTW89_UK][17] = 127, -+ [1][1][RTW89_FCC][19] = 127, -+ [1][1][RTW89_ETSI][19] = 127, -+ [1][1][RTW89_MKK][19] = 127, -+ [1][1][RTW89_IC][19] = 127, -+ [1][1][RTW89_KCC][19] = 127, -+ [1][1][RTW89_ACMA][19] = 127, -+ [1][1][RTW89_CN][19] = 127, -+ [1][1][RTW89_UK][19] = 127, -+ [1][1][RTW89_FCC][21] = 127, -+ [1][1][RTW89_ETSI][21] = 127, -+ [1][1][RTW89_MKK][21] = 127, -+ [1][1][RTW89_IC][21] = 127, -+ [1][1][RTW89_KCC][21] = 127, -+ [1][1][RTW89_ACMA][21] = 127, -+ [1][1][RTW89_CN][21] = 127, -+ [1][1][RTW89_UK][21] = 127, -+ [1][1][RTW89_FCC][23] = 127, -+ [1][1][RTW89_ETSI][23] = 127, -+ [1][1][RTW89_MKK][23] = 127, -+ [1][1][RTW89_IC][23] = 127, -+ [1][1][RTW89_KCC][23] = 127, -+ [1][1][RTW89_ACMA][23] = 127, -+ [1][1][RTW89_CN][23] = 127, -+ [1][1][RTW89_UK][23] = 127, -+ [1][1][RTW89_FCC][25] = 127, -+ [1][1][RTW89_ETSI][25] = 127, -+ [1][1][RTW89_MKK][25] = 127, -+ [1][1][RTW89_IC][25] = 127, -+ [1][1][RTW89_KCC][25] = 127, -+ [1][1][RTW89_ACMA][25] = 127, -+ [1][1][RTW89_CN][25] = 127, -+ [1][1][RTW89_UK][25] = 127, -+ [1][1][RTW89_FCC][27] = 127, -+ [1][1][RTW89_ETSI][27] = 127, -+ [1][1][RTW89_MKK][27] = 127, -+ [1][1][RTW89_IC][27] = 127, -+ [1][1][RTW89_KCC][27] = 127, -+ [1][1][RTW89_ACMA][27] = 127, -+ [1][1][RTW89_CN][27] = 127, -+ [1][1][RTW89_UK][27] = 127, -+ [1][1][RTW89_FCC][29] = 127, -+ [1][1][RTW89_ETSI][29] = 127, -+ [1][1][RTW89_MKK][29] = 127, -+ [1][1][RTW89_IC][29] = 127, -+ [1][1][RTW89_KCC][29] = 127, -+ [1][1][RTW89_ACMA][29] = 127, -+ [1][1][RTW89_CN][29] = 127, -+ [1][1][RTW89_UK][29] = 127, -+ [1][1][RTW89_FCC][31] = 127, -+ [1][1][RTW89_ETSI][31] = 127, -+ [1][1][RTW89_MKK][31] = 127, -+ [1][1][RTW89_IC][31] = 127, -+ [1][1][RTW89_KCC][31] = 127, -+ [1][1][RTW89_ACMA][31] = 127, -+ [1][1][RTW89_CN][31] = 127, -+ [1][1][RTW89_UK][31] = 127, -+ [1][1][RTW89_FCC][33] = 127, -+ [1][1][RTW89_ETSI][33] = 127, -+ [1][1][RTW89_MKK][33] = 127, -+ [1][1][RTW89_IC][33] = 127, -+ [1][1][RTW89_KCC][33] = 127, -+ [1][1][RTW89_ACMA][33] = 127, -+ [1][1][RTW89_CN][33] = 127, -+ [1][1][RTW89_UK][33] = 127, -+ [1][1][RTW89_FCC][35] = 127, -+ [1][1][RTW89_ETSI][35] = 127, -+ [1][1][RTW89_MKK][35] = 127, -+ [1][1][RTW89_IC][35] = 127, -+ [1][1][RTW89_KCC][35] = 127, -+ [1][1][RTW89_ACMA][35] = 127, -+ [1][1][RTW89_CN][35] = 127, -+ [1][1][RTW89_UK][35] = 127, -+ [1][1][RTW89_FCC][37] = 127, -+ [1][1][RTW89_ETSI][37] = 127, -+ [1][1][RTW89_MKK][37] = 127, -+ [1][1][RTW89_IC][37] = 127, -+ [1][1][RTW89_KCC][37] = 127, -+ [1][1][RTW89_ACMA][37] = 127, -+ [1][1][RTW89_CN][37] = 127, -+ [1][1][RTW89_UK][37] = 127, -+ [1][1][RTW89_FCC][38] = 127, -+ [1][1][RTW89_ETSI][38] = 127, -+ [1][1][RTW89_MKK][38] = 127, -+ [1][1][RTW89_IC][38] = 127, -+ [1][1][RTW89_KCC][38] = 127, -+ [1][1][RTW89_ACMA][38] = 127, -+ [1][1][RTW89_CN][38] = 54, -+ [1][1][RTW89_UK][38] = 127, -+ [1][1][RTW89_FCC][40] = 127, -+ [1][1][RTW89_ETSI][40] = 127, -+ [1][1][RTW89_MKK][40] = 127, -+ [1][1][RTW89_IC][40] = 127, -+ [1][1][RTW89_KCC][40] = 127, -+ [1][1][RTW89_ACMA][40] = 127, -+ [1][1][RTW89_CN][40] = 54, -+ [1][1][RTW89_UK][40] = 127, -+ [1][1][RTW89_FCC][42] = 127, -+ [1][1][RTW89_ETSI][42] = 127, -+ [1][1][RTW89_MKK][42] = 127, -+ [1][1][RTW89_IC][42] = 127, -+ [1][1][RTW89_KCC][42] = 127, -+ [1][1][RTW89_ACMA][42] = 127, -+ [1][1][RTW89_CN][42] = 54, -+ [1][1][RTW89_UK][42] = 127, -+ [1][1][RTW89_FCC][44] = 127, -+ [1][1][RTW89_ETSI][44] = 127, -+ [1][1][RTW89_MKK][44] = 127, -+ [1][1][RTW89_IC][44] = 127, -+ [1][1][RTW89_KCC][44] = 127, -+ [1][1][RTW89_ACMA][44] = 127, -+ [1][1][RTW89_CN][44] = 54, -+ [1][1][RTW89_UK][44] = 127, -+ [1][1][RTW89_FCC][46] = 127, -+ [1][1][RTW89_ETSI][46] = 127, -+ [1][1][RTW89_MKK][46] = 127, -+ [1][1][RTW89_IC][46] = 127, -+ [1][1][RTW89_KCC][46] = 127, -+ [1][1][RTW89_ACMA][46] = 127, -+ [1][1][RTW89_CN][46] = 54, -+ [1][1][RTW89_UK][46] = 127, -+ [1][1][RTW89_FCC][48] = 127, -+ [1][1][RTW89_ETSI][48] = 127, -+ [1][1][RTW89_MKK][48] = 127, -+ [1][1][RTW89_IC][48] = 127, -+ [1][1][RTW89_KCC][48] = 127, -+ [1][1][RTW89_ACMA][48] = 127, -+ [1][1][RTW89_CN][48] = 127, -+ [1][1][RTW89_UK][48] = 127, -+ [1][1][RTW89_FCC][50] = 127, -+ [1][1][RTW89_ETSI][50] = 127, -+ [1][1][RTW89_MKK][50] = 127, -+ [1][1][RTW89_IC][50] = 127, -+ [1][1][RTW89_KCC][50] = 127, -+ [1][1][RTW89_ACMA][50] = 127, -+ [1][1][RTW89_CN][50] = 127, -+ [1][1][RTW89_UK][50] = 127, -+ [1][1][RTW89_FCC][52] = 127, -+ [1][1][RTW89_ETSI][52] = 127, -+ [1][1][RTW89_MKK][52] = 127, -+ [1][1][RTW89_IC][52] = 127, -+ [1][1][RTW89_KCC][52] = 127, -+ [1][1][RTW89_ACMA][52] = 127, -+ [1][1][RTW89_CN][52] = 127, -+ [1][1][RTW89_UK][52] = 127, -+ [2][0][RTW89_FCC][0] = 78, -+ [2][0][RTW89_ETSI][0] = 46, -+ [2][0][RTW89_MKK][0] = 48, -+ [2][0][RTW89_IC][0] = 50, -+ [2][0][RTW89_KCC][0] = 64, -+ [2][0][RTW89_ACMA][0] = 46, -+ [2][0][RTW89_CN][0] = 40, -+ [2][0][RTW89_UK][0] = 46, -+ [2][0][RTW89_FCC][2] = 74, -+ [2][0][RTW89_ETSI][2] = 46, -+ [2][0][RTW89_MKK][2] = 48, -+ [2][0][RTW89_IC][2] = 48, -+ [2][0][RTW89_KCC][2] = 64, -+ [2][0][RTW89_ACMA][2] = 46, -+ [2][0][RTW89_CN][2] = 40, -+ [2][0][RTW89_UK][2] = 46, -+ [2][0][RTW89_FCC][4] = 74, -+ [2][0][RTW89_ETSI][4] = 46, -+ [2][0][RTW89_MKK][4] = 48, -+ [2][0][RTW89_IC][4] = 48, -+ [2][0][RTW89_KCC][4] = 64, -+ [2][0][RTW89_ACMA][4] = 46, -+ [2][0][RTW89_CN][4] = 40, -+ [2][0][RTW89_UK][4] = 46, -+ [2][0][RTW89_FCC][6] = 74, -+ [2][0][RTW89_ETSI][6] = 46, -+ [2][0][RTW89_MKK][6] = 48, -+ [2][0][RTW89_IC][6] = 48, -+ [2][0][RTW89_KCC][6] = 40, -+ [2][0][RTW89_ACMA][6] = 46, -+ [2][0][RTW89_CN][6] = 40, -+ [2][0][RTW89_UK][6] = 46, -+ [2][0][RTW89_FCC][8] = 74, -+ [2][0][RTW89_ETSI][8] = 46, -+ [2][0][RTW89_MKK][8] = 48, -+ [2][0][RTW89_IC][8] = 64, -+ [2][0][RTW89_KCC][8] = 66, -+ [2][0][RTW89_ACMA][8] = 46, -+ [2][0][RTW89_CN][8] = 40, -+ [2][0][RTW89_UK][8] = 46, -+ [2][0][RTW89_FCC][10] = 74, -+ [2][0][RTW89_ETSI][10] = 46, -+ [2][0][RTW89_MKK][10] = 48, -+ [2][0][RTW89_IC][10] = 64, -+ [2][0][RTW89_KCC][10] = 66, -+ [2][0][RTW89_ACMA][10] = 46, -+ [2][0][RTW89_CN][10] = 40, -+ [2][0][RTW89_UK][10] = 46, -+ [2][0][RTW89_FCC][12] = 74, -+ [2][0][RTW89_ETSI][12] = 46, -+ [2][0][RTW89_MKK][12] = 48, -+ [2][0][RTW89_IC][12] = 64, -+ [2][0][RTW89_KCC][12] = 64, -+ [2][0][RTW89_ACMA][12] = 46, -+ [2][0][RTW89_CN][12] = 40, -+ [2][0][RTW89_UK][12] = 46, -+ [2][0][RTW89_FCC][14] = 80, -+ [2][0][RTW89_ETSI][14] = 46, -+ [2][0][RTW89_MKK][14] = 48, -+ [2][0][RTW89_IC][14] = 64, -+ [2][0][RTW89_KCC][14] = 64, -+ [2][0][RTW89_ACMA][14] = 46, -+ [2][0][RTW89_CN][14] = 40, -+ [2][0][RTW89_UK][14] = 46, -+ [2][0][RTW89_FCC][15] = 72, -+ [2][0][RTW89_ETSI][15] = 46, -+ [2][0][RTW89_MKK][15] = 70, -+ [2][0][RTW89_IC][15] = 72, -+ [2][0][RTW89_KCC][15] = 66, -+ [2][0][RTW89_ACMA][15] = 46, -+ [2][0][RTW89_CN][15] = 127, -+ [2][0][RTW89_UK][15] = 46, -+ [2][0][RTW89_FCC][17] = 72, -+ [2][0][RTW89_ETSI][17] = 46, -+ [2][0][RTW89_MKK][17] = 70, -+ [2][0][RTW89_IC][17] = 72, -+ [2][0][RTW89_KCC][17] = 66, -+ [2][0][RTW89_ACMA][17] = 46, -+ [2][0][RTW89_CN][17] = 127, -+ [2][0][RTW89_UK][17] = 46, -+ [2][0][RTW89_FCC][19] = 70, -+ [2][0][RTW89_ETSI][19] = 46, -+ [2][0][RTW89_MKK][19] = 70, -+ [2][0][RTW89_IC][19] = 70, -+ [2][0][RTW89_KCC][19] = 66, -+ [2][0][RTW89_ACMA][19] = 46, -+ [2][0][RTW89_CN][19] = 127, -+ [2][0][RTW89_UK][19] = 46, -+ [2][0][RTW89_FCC][21] = 70, -+ [2][0][RTW89_ETSI][21] = 46, -+ [2][0][RTW89_MKK][21] = 70, -+ [2][0][RTW89_IC][21] = 70, -+ [2][0][RTW89_KCC][21] = 66, -+ [2][0][RTW89_ACMA][21] = 46, -+ [2][0][RTW89_CN][21] = 127, -+ [2][0][RTW89_UK][21] = 46, -+ [2][0][RTW89_FCC][23] = 70, -+ [2][0][RTW89_ETSI][23] = 46, -+ [2][0][RTW89_MKK][23] = 70, -+ [2][0][RTW89_IC][23] = 70, -+ [2][0][RTW89_KCC][23] = 66, -+ [2][0][RTW89_ACMA][23] = 46, -+ [2][0][RTW89_CN][23] = 127, -+ [2][0][RTW89_UK][23] = 46, -+ [2][0][RTW89_FCC][25] = 70, -+ [2][0][RTW89_ETSI][25] = 46, -+ [2][0][RTW89_MKK][25] = 70, -+ [2][0][RTW89_IC][25] = 127, -+ [2][0][RTW89_KCC][25] = 66, -+ [2][0][RTW89_ACMA][25] = 127, -+ [2][0][RTW89_CN][25] = 127, -+ [2][0][RTW89_UK][25] = 46, -+ [2][0][RTW89_FCC][27] = 70, -+ [2][0][RTW89_ETSI][27] = 46, -+ [2][0][RTW89_MKK][27] = 70, -+ [2][0][RTW89_IC][27] = 127, -+ [2][0][RTW89_KCC][27] = 64, -+ [2][0][RTW89_ACMA][27] = 127, -+ [2][0][RTW89_CN][27] = 127, -+ [2][0][RTW89_UK][27] = 46, -+ [2][0][RTW89_FCC][29] = 70, -+ [2][0][RTW89_ETSI][29] = 46, -+ [2][0][RTW89_MKK][29] = 70, -+ [2][0][RTW89_IC][29] = 127, -+ [2][0][RTW89_KCC][29] = 64, -+ [2][0][RTW89_ACMA][29] = 127, -+ [2][0][RTW89_CN][29] = 127, -+ [2][0][RTW89_UK][29] = 46, -+ [2][0][RTW89_FCC][31] = 70, -+ [2][0][RTW89_ETSI][31] = 46, -+ [2][0][RTW89_MKK][31] = 70, -+ [2][0][RTW89_IC][31] = 70, -+ [2][0][RTW89_KCC][31] = 64, -+ [2][0][RTW89_ACMA][31] = 46, -+ [2][0][RTW89_CN][31] = 127, -+ [2][0][RTW89_UK][31] = 46, -+ [2][0][RTW89_FCC][33] = 70, -+ [2][0][RTW89_ETSI][33] = 46, -+ [2][0][RTW89_MKK][33] = 70, -+ [2][0][RTW89_IC][33] = 70, -+ [2][0][RTW89_KCC][33] = 64, -+ [2][0][RTW89_ACMA][33] = 46, -+ [2][0][RTW89_CN][33] = 127, -+ [2][0][RTW89_UK][33] = 46, -+ [2][0][RTW89_FCC][35] = 70, -+ [2][0][RTW89_ETSI][35] = 46, -+ [2][0][RTW89_MKK][35] = 70, -+ [2][0][RTW89_IC][35] = 70, -+ [2][0][RTW89_KCC][35] = 64, -+ [2][0][RTW89_ACMA][35] = 46, -+ [2][0][RTW89_CN][35] = 127, -+ [2][0][RTW89_UK][35] = 46, -+ [2][0][RTW89_FCC][37] = 84, -+ [2][0][RTW89_ETSI][37] = 127, -+ [2][0][RTW89_MKK][37] = 68, -+ [2][0][RTW89_IC][37] = 84, -+ [2][0][RTW89_KCC][37] = 66, -+ [2][0][RTW89_ACMA][37] = 74, -+ [2][0][RTW89_CN][37] = 127, -+ [2][0][RTW89_UK][37] = 74, -+ [2][0][RTW89_FCC][38] = 84, -+ [2][0][RTW89_ETSI][38] = 28, -+ [2][0][RTW89_MKK][38] = 127, -+ [2][0][RTW89_IC][38] = 84, -+ [2][0][RTW89_KCC][38] = 64, -+ [2][0][RTW89_ACMA][38] = 84, -+ [2][0][RTW89_CN][38] = 68, -+ [2][0][RTW89_UK][38] = 46, -+ [2][0][RTW89_FCC][40] = 84, -+ [2][0][RTW89_ETSI][40] = 28, -+ [2][0][RTW89_MKK][40] = 127, -+ [2][0][RTW89_IC][40] = 84, -+ [2][0][RTW89_KCC][40] = 64, -+ [2][0][RTW89_ACMA][40] = 84, -+ [2][0][RTW89_CN][40] = 68, -+ [2][0][RTW89_UK][40] = 46, -+ [2][0][RTW89_FCC][42] = 80, -+ [2][0][RTW89_ETSI][42] = 28, -+ [2][0][RTW89_MKK][42] = 127, -+ [2][0][RTW89_IC][42] = 80, -+ [2][0][RTW89_KCC][42] = 66, -+ [2][0][RTW89_ACMA][42] = 84, -+ [2][0][RTW89_CN][42] = 68, -+ [2][0][RTW89_UK][42] = 46, -+ [2][0][RTW89_FCC][44] = 82, -+ [2][0][RTW89_ETSI][44] = 28, -+ [2][0][RTW89_MKK][44] = 127, -+ [2][0][RTW89_IC][44] = 82, -+ [2][0][RTW89_KCC][44] = 66, -+ [2][0][RTW89_ACMA][44] = 84, -+ [2][0][RTW89_CN][44] = 68, -+ [2][0][RTW89_UK][44] = 46, -+ [2][0][RTW89_FCC][46] = 82, -+ [2][0][RTW89_ETSI][46] = 28, -+ [2][0][RTW89_MKK][46] = 127, -+ [2][0][RTW89_IC][46] = 82, -+ [2][0][RTW89_KCC][46] = 66, -+ [2][0][RTW89_ACMA][46] = 84, -+ [2][0][RTW89_CN][46] = 68, -+ [2][0][RTW89_UK][46] = 46, -+ [2][0][RTW89_FCC][48] = 64, -+ [2][0][RTW89_ETSI][48] = 127, -+ [2][0][RTW89_MKK][48] = 127, -+ [2][0][RTW89_IC][48] = 127, -+ [2][0][RTW89_KCC][48] = 127, -+ [2][0][RTW89_ACMA][48] = 127, -+ [2][0][RTW89_CN][48] = 127, -+ [2][0][RTW89_UK][48] = 127, -+ [2][0][RTW89_FCC][50] = 64, -+ [2][0][RTW89_ETSI][50] = 127, -+ [2][0][RTW89_MKK][50] = 127, -+ [2][0][RTW89_IC][50] = 127, -+ [2][0][RTW89_KCC][50] = 127, -+ [2][0][RTW89_ACMA][50] = 127, -+ [2][0][RTW89_CN][50] = 127, -+ [2][0][RTW89_UK][50] = 127, -+ [2][0][RTW89_FCC][52] = 60, -+ [2][0][RTW89_ETSI][52] = 127, -+ [2][0][RTW89_MKK][52] = 127, -+ [2][0][RTW89_IC][52] = 127, -+ [2][0][RTW89_KCC][52] = 127, -+ [2][0][RTW89_ACMA][52] = 127, -+ [2][0][RTW89_CN][52] = 127, -+ [2][0][RTW89_UK][52] = 127, -+ [2][1][RTW89_FCC][0] = 127, -+ [2][1][RTW89_ETSI][0] = 127, -+ [2][1][RTW89_MKK][0] = 127, -+ [2][1][RTW89_IC][0] = 127, -+ [2][1][RTW89_KCC][0] = 127, -+ [2][1][RTW89_ACMA][0] = 127, -+ [2][1][RTW89_CN][0] = 28, -+ [2][1][RTW89_UK][0] = 127, -+ [2][1][RTW89_FCC][2] = 127, -+ [2][1][RTW89_ETSI][2] = 127, -+ [2][1][RTW89_MKK][2] = 127, -+ [2][1][RTW89_IC][2] = 127, -+ [2][1][RTW89_KCC][2] = 127, -+ [2][1][RTW89_ACMA][2] = 127, -+ [2][1][RTW89_CN][2] = 28, -+ [2][1][RTW89_UK][2] = 127, -+ [2][1][RTW89_FCC][4] = 127, -+ [2][1][RTW89_ETSI][4] = 127, -+ [2][1][RTW89_MKK][4] = 127, -+ [2][1][RTW89_IC][4] = 127, -+ [2][1][RTW89_KCC][4] = 127, -+ [2][1][RTW89_ACMA][4] = 127, -+ [2][1][RTW89_CN][4] = 28, -+ [2][1][RTW89_UK][4] = 127, -+ [2][1][RTW89_FCC][6] = 127, -+ [2][1][RTW89_ETSI][6] = 127, -+ [2][1][RTW89_MKK][6] = 127, -+ [2][1][RTW89_IC][6] = 127, -+ [2][1][RTW89_KCC][6] = 127, -+ [2][1][RTW89_ACMA][6] = 127, -+ [2][1][RTW89_CN][6] = 28, -+ [2][1][RTW89_UK][6] = 127, -+ [2][1][RTW89_FCC][8] = 127, -+ [2][1][RTW89_ETSI][8] = 127, -+ [2][1][RTW89_MKK][8] = 127, -+ [2][1][RTW89_IC][8] = 127, -+ [2][1][RTW89_KCC][8] = 127, -+ [2][1][RTW89_ACMA][8] = 127, -+ [2][1][RTW89_CN][8] = 28, -+ [2][1][RTW89_UK][8] = 127, -+ [2][1][RTW89_FCC][10] = 127, -+ [2][1][RTW89_ETSI][10] = 127, -+ [2][1][RTW89_MKK][10] = 127, -+ [2][1][RTW89_IC][10] = 127, -+ [2][1][RTW89_KCC][10] = 127, -+ [2][1][RTW89_ACMA][10] = 127, -+ [2][1][RTW89_CN][10] = 28, -+ [2][1][RTW89_UK][10] = 127, -+ [2][1][RTW89_FCC][12] = 127, -+ [2][1][RTW89_ETSI][12] = 127, -+ [2][1][RTW89_MKK][12] = 127, -+ [2][1][RTW89_IC][12] = 127, -+ [2][1][RTW89_KCC][12] = 127, -+ [2][1][RTW89_ACMA][12] = 127, -+ [2][1][RTW89_CN][12] = 28, -+ [2][1][RTW89_UK][12] = 127, -+ [2][1][RTW89_FCC][14] = 127, -+ [2][1][RTW89_ETSI][14] = 127, -+ [2][1][RTW89_MKK][14] = 127, -+ [2][1][RTW89_IC][14] = 127, -+ [2][1][RTW89_KCC][14] = 127, -+ [2][1][RTW89_ACMA][14] = 127, -+ [2][1][RTW89_CN][14] = 28, -+ [2][1][RTW89_UK][14] = 127, -+ [2][1][RTW89_FCC][15] = 127, -+ [2][1][RTW89_ETSI][15] = 127, -+ [2][1][RTW89_MKK][15] = 127, -+ [2][1][RTW89_IC][15] = 127, -+ [2][1][RTW89_KCC][15] = 127, -+ [2][1][RTW89_ACMA][15] = 127, -+ [2][1][RTW89_CN][15] = 127, -+ [2][1][RTW89_UK][15] = 127, -+ [2][1][RTW89_FCC][17] = 127, -+ [2][1][RTW89_ETSI][17] = 127, -+ [2][1][RTW89_MKK][17] = 127, -+ [2][1][RTW89_IC][17] = 127, -+ [2][1][RTW89_KCC][17] = 127, -+ [2][1][RTW89_ACMA][17] = 127, -+ [2][1][RTW89_CN][17] = 127, -+ [2][1][RTW89_UK][17] = 127, -+ [2][1][RTW89_FCC][19] = 127, -+ [2][1][RTW89_ETSI][19] = 127, -+ [2][1][RTW89_MKK][19] = 127, -+ [2][1][RTW89_IC][19] = 127, -+ [2][1][RTW89_KCC][19] = 127, -+ [2][1][RTW89_ACMA][19] = 127, -+ [2][1][RTW89_CN][19] = 127, -+ [2][1][RTW89_UK][19] = 127, -+ [2][1][RTW89_FCC][21] = 127, -+ [2][1][RTW89_ETSI][21] = 127, -+ [2][1][RTW89_MKK][21] = 127, -+ [2][1][RTW89_IC][21] = 127, -+ [2][1][RTW89_KCC][21] = 127, -+ [2][1][RTW89_ACMA][21] = 127, -+ [2][1][RTW89_CN][21] = 127, -+ [2][1][RTW89_UK][21] = 127, -+ [2][1][RTW89_FCC][23] = 127, -+ [2][1][RTW89_ETSI][23] = 127, -+ [2][1][RTW89_MKK][23] = 127, -+ [2][1][RTW89_IC][23] = 127, -+ [2][1][RTW89_KCC][23] = 127, -+ [2][1][RTW89_ACMA][23] = 127, -+ [2][1][RTW89_CN][23] = 127, -+ [2][1][RTW89_UK][23] = 127, -+ [2][1][RTW89_FCC][25] = 127, -+ [2][1][RTW89_ETSI][25] = 127, -+ [2][1][RTW89_MKK][25] = 127, -+ [2][1][RTW89_IC][25] = 127, -+ [2][1][RTW89_KCC][25] = 127, -+ [2][1][RTW89_ACMA][25] = 127, -+ [2][1][RTW89_CN][25] = 127, -+ [2][1][RTW89_UK][25] = 127, -+ [2][1][RTW89_FCC][27] = 127, -+ [2][1][RTW89_ETSI][27] = 127, -+ [2][1][RTW89_MKK][27] = 127, -+ [2][1][RTW89_IC][27] = 127, -+ [2][1][RTW89_KCC][27] = 127, -+ [2][1][RTW89_ACMA][27] = 127, -+ [2][1][RTW89_CN][27] = 127, -+ [2][1][RTW89_UK][27] = 127, -+ [2][1][RTW89_FCC][29] = 127, -+ [2][1][RTW89_ETSI][29] = 127, -+ [2][1][RTW89_MKK][29] = 127, -+ [2][1][RTW89_IC][29] = 127, -+ [2][1][RTW89_KCC][29] = 127, -+ [2][1][RTW89_ACMA][29] = 127, -+ [2][1][RTW89_CN][29] = 127, -+ [2][1][RTW89_UK][29] = 127, -+ [2][1][RTW89_FCC][31] = 127, -+ [2][1][RTW89_ETSI][31] = 127, -+ [2][1][RTW89_MKK][31] = 127, -+ [2][1][RTW89_IC][31] = 127, -+ [2][1][RTW89_KCC][31] = 127, -+ [2][1][RTW89_ACMA][31] = 127, -+ [2][1][RTW89_CN][31] = 127, -+ [2][1][RTW89_UK][31] = 127, -+ [2][1][RTW89_FCC][33] = 127, -+ [2][1][RTW89_ETSI][33] = 127, -+ [2][1][RTW89_MKK][33] = 127, -+ [2][1][RTW89_IC][33] = 127, -+ [2][1][RTW89_KCC][33] = 127, -+ [2][1][RTW89_ACMA][33] = 127, -+ [2][1][RTW89_CN][33] = 127, -+ [2][1][RTW89_UK][33] = 127, -+ [2][1][RTW89_FCC][35] = 127, -+ [2][1][RTW89_ETSI][35] = 127, -+ [2][1][RTW89_MKK][35] = 127, -+ [2][1][RTW89_IC][35] = 127, -+ [2][1][RTW89_KCC][35] = 127, -+ [2][1][RTW89_ACMA][35] = 127, -+ [2][1][RTW89_CN][35] = 127, -+ [2][1][RTW89_UK][35] = 127, -+ [2][1][RTW89_FCC][37] = 127, -+ [2][1][RTW89_ETSI][37] = 127, -+ [2][1][RTW89_MKK][37] = 127, -+ [2][1][RTW89_IC][37] = 127, -+ [2][1][RTW89_KCC][37] = 127, -+ [2][1][RTW89_ACMA][37] = 127, -+ [2][1][RTW89_CN][37] = 127, -+ [2][1][RTW89_UK][37] = 127, -+ [2][1][RTW89_FCC][38] = 127, -+ [2][1][RTW89_ETSI][38] = 127, -+ [2][1][RTW89_MKK][38] = 127, -+ [2][1][RTW89_IC][38] = 127, -+ [2][1][RTW89_KCC][38] = 127, -+ [2][1][RTW89_ACMA][38] = 127, -+ [2][1][RTW89_CN][38] = 56, -+ [2][1][RTW89_UK][38] = 127, -+ [2][1][RTW89_FCC][40] = 127, -+ [2][1][RTW89_ETSI][40] = 127, -+ [2][1][RTW89_MKK][40] = 127, -+ [2][1][RTW89_IC][40] = 127, -+ [2][1][RTW89_KCC][40] = 127, -+ [2][1][RTW89_ACMA][40] = 127, -+ [2][1][RTW89_CN][40] = 56, -+ [2][1][RTW89_UK][40] = 127, -+ [2][1][RTW89_FCC][42] = 127, -+ [2][1][RTW89_ETSI][42] = 127, -+ [2][1][RTW89_MKK][42] = 127, -+ [2][1][RTW89_IC][42] = 127, -+ [2][1][RTW89_KCC][42] = 127, -+ [2][1][RTW89_ACMA][42] = 127, -+ [2][1][RTW89_CN][42] = 56, -+ [2][1][RTW89_UK][42] = 127, -+ [2][1][RTW89_FCC][44] = 127, -+ [2][1][RTW89_ETSI][44] = 127, -+ [2][1][RTW89_MKK][44] = 127, -+ [2][1][RTW89_IC][44] = 127, -+ [2][1][RTW89_KCC][44] = 127, -+ [2][1][RTW89_ACMA][44] = 127, -+ [2][1][RTW89_CN][44] = 56, -+ [2][1][RTW89_UK][44] = 127, -+ [2][1][RTW89_FCC][46] = 127, -+ [2][1][RTW89_ETSI][46] = 127, -+ [2][1][RTW89_MKK][46] = 127, -+ [2][1][RTW89_IC][46] = 127, -+ [2][1][RTW89_KCC][46] = 127, -+ [2][1][RTW89_ACMA][46] = 127, -+ [2][1][RTW89_CN][46] = 56, -+ [2][1][RTW89_UK][46] = 127, -+ [2][1][RTW89_FCC][48] = 127, -+ [2][1][RTW89_ETSI][48] = 127, -+ [2][1][RTW89_MKK][48] = 127, -+ [2][1][RTW89_IC][48] = 127, -+ [2][1][RTW89_KCC][48] = 127, -+ [2][1][RTW89_ACMA][48] = 127, -+ [2][1][RTW89_CN][48] = 127, -+ [2][1][RTW89_UK][48] = 127, -+ [2][1][RTW89_FCC][50] = 127, -+ [2][1][RTW89_ETSI][50] = 127, -+ [2][1][RTW89_MKK][50] = 127, -+ [2][1][RTW89_IC][50] = 127, -+ [2][1][RTW89_KCC][50] = 127, -+ [2][1][RTW89_ACMA][50] = 127, -+ [2][1][RTW89_CN][50] = 127, -+ [2][1][RTW89_UK][50] = 127, -+ [2][1][RTW89_FCC][52] = 127, -+ [2][1][RTW89_ETSI][52] = 127, -+ [2][1][RTW89_MKK][52] = 127, -+ [2][1][RTW89_IC][52] = 127, -+ [2][1][RTW89_KCC][52] = 127, -+ [2][1][RTW89_ACMA][52] = 127, -+ [2][1][RTW89_CN][52] = 127, -+ [2][1][RTW89_UK][52] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_2g_type2[RTW89_2G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][0][0][RTW89_WW][0] = 58, -+ [0][0][0][0][RTW89_WW][1] = 58, -+ [0][0][0][0][RTW89_WW][2] = 58, -+ [0][0][0][0][RTW89_WW][3] = 58, -+ [0][0][0][0][RTW89_WW][4] = 58, -+ [0][0][0][0][RTW89_WW][5] = 58, -+ [0][0][0][0][RTW89_WW][6] = 58, -+ [0][0][0][0][RTW89_WW][7] = 58, -+ [0][0][0][0][RTW89_WW][8] = 58, -+ [0][0][0][0][RTW89_WW][9] = 58, -+ [0][0][0][0][RTW89_WW][10] = 58, -+ [0][0][0][0][RTW89_WW][11] = 58, -+ [0][0][0][0][RTW89_WW][12] = 52, -+ [0][0][0][0][RTW89_WW][13] = 76, -+ [0][1][0][0][RTW89_WW][0] = 0, -+ [0][1][0][0][RTW89_WW][1] = 0, -+ [0][1][0][0][RTW89_WW][2] = 0, -+ [0][1][0][0][RTW89_WW][3] = 0, -+ [0][1][0][0][RTW89_WW][4] = 0, -+ [0][1][0][0][RTW89_WW][5] = 0, -+ [0][1][0][0][RTW89_WW][6] = 0, -+ [0][1][0][0][RTW89_WW][7] = 0, -+ [0][1][0][0][RTW89_WW][8] = 0, -+ [0][1][0][0][RTW89_WW][9] = 0, -+ [0][1][0][0][RTW89_WW][10] = 0, -+ [0][1][0][0][RTW89_WW][11] = 0, -+ [0][1][0][0][RTW89_WW][12] = 0, -+ [0][1][0][0][RTW89_WW][13] = 0, -+ [1][0][0][0][RTW89_WW][0] = 0, -+ [1][0][0][0][RTW89_WW][1] = 0, -+ [1][0][0][0][RTW89_WW][2] = 58, -+ [1][0][0][0][RTW89_WW][3] = 58, -+ [1][0][0][0][RTW89_WW][4] = 58, -+ [1][0][0][0][RTW89_WW][5] = 58, -+ [1][0][0][0][RTW89_WW][6] = 58, -+ [1][0][0][0][RTW89_WW][7] = 58, -+ [1][0][0][0][RTW89_WW][8] = 58, -+ [1][0][0][0][RTW89_WW][9] = 58, -+ [1][0][0][0][RTW89_WW][10] = 58, -+ [1][0][0][0][RTW89_WW][11] = 0, -+ [1][0][0][0][RTW89_WW][12] = 0, -+ [1][0][0][0][RTW89_WW][13] = 0, -+ [1][1][0][0][RTW89_WW][0] = 0, -+ [1][1][0][0][RTW89_WW][1] = 0, -+ [1][1][0][0][RTW89_WW][2] = 0, -+ [1][1][0][0][RTW89_WW][3] = 0, -+ [1][1][0][0][RTW89_WW][4] = 0, -+ [1][1][0][0][RTW89_WW][5] = 0, -+ [1][1][0][0][RTW89_WW][6] = 0, -+ [1][1][0][0][RTW89_WW][7] = 0, -+ [1][1][0][0][RTW89_WW][8] = 0, -+ [1][1][0][0][RTW89_WW][9] = 0, -+ [1][1][0][0][RTW89_WW][10] = 0, -+ [1][1][0][0][RTW89_WW][11] = 0, -+ [1][1][0][0][RTW89_WW][12] = 0, -+ [1][1][0][0][RTW89_WW][13] = 0, -+ [0][0][1][0][RTW89_WW][0] = 58, -+ [0][0][1][0][RTW89_WW][1] = 60, -+ [0][0][1][0][RTW89_WW][2] = 60, -+ [0][0][1][0][RTW89_WW][3] = 60, -+ [0][0][1][0][RTW89_WW][4] = 60, -+ [0][0][1][0][RTW89_WW][5] = 60, -+ [0][0][1][0][RTW89_WW][6] = 60, -+ [0][0][1][0][RTW89_WW][7] = 60, -+ [0][0][1][0][RTW89_WW][8] = 60, -+ [0][0][1][0][RTW89_WW][9] = 60, -+ [0][0][1][0][RTW89_WW][10] = 60, -+ [0][0][1][0][RTW89_WW][11] = 60, -+ [0][0][1][0][RTW89_WW][12] = 58, -+ [0][0][1][0][RTW89_WW][13] = 0, -+ [0][1][1][0][RTW89_WW][0] = 0, -+ [0][1][1][0][RTW89_WW][1] = 0, -+ [0][1][1][0][RTW89_WW][2] = 0, -+ [0][1][1][0][RTW89_WW][3] = 0, -+ [0][1][1][0][RTW89_WW][4] = 0, -+ [0][1][1][0][RTW89_WW][5] = 0, -+ [0][1][1][0][RTW89_WW][6] = 0, -+ [0][1][1][0][RTW89_WW][7] = 0, -+ [0][1][1][0][RTW89_WW][8] = 0, -+ [0][1][1][0][RTW89_WW][9] = 0, -+ [0][1][1][0][RTW89_WW][10] = 0, -+ [0][1][1][0][RTW89_WW][11] = 0, -+ [0][1][1][0][RTW89_WW][12] = 0, -+ [0][1][1][0][RTW89_WW][13] = 0, -+ [0][0][2][0][RTW89_WW][0] = 60, -+ [0][0][2][0][RTW89_WW][1] = 60, -+ [0][0][2][0][RTW89_WW][2] = 60, -+ [0][0][2][0][RTW89_WW][3] = 60, -+ [0][0][2][0][RTW89_WW][4] = 60, -+ [0][0][2][0][RTW89_WW][5] = 60, -+ [0][0][2][0][RTW89_WW][6] = 60, -+ [0][0][2][0][RTW89_WW][7] = 60, -+ [0][0][2][0][RTW89_WW][8] = 60, -+ [0][0][2][0][RTW89_WW][9] = 60, -+ [0][0][2][0][RTW89_WW][10] = 60, -+ [0][0][2][0][RTW89_WW][11] = 60, -+ [0][0][2][0][RTW89_WW][12] = 60, -+ [0][0][2][0][RTW89_WW][13] = 0, -+ [0][1][2][0][RTW89_WW][0] = 0, -+ [0][1][2][0][RTW89_WW][1] = 0, -+ [0][1][2][0][RTW89_WW][2] = 0, -+ [0][1][2][0][RTW89_WW][3] = 0, -+ [0][1][2][0][RTW89_WW][4] = 0, -+ [0][1][2][0][RTW89_WW][5] = 0, -+ [0][1][2][0][RTW89_WW][6] = 0, -+ [0][1][2][0][RTW89_WW][7] = 0, -+ [0][1][2][0][RTW89_WW][8] = 0, -+ [0][1][2][0][RTW89_WW][9] = 0, -+ [0][1][2][0][RTW89_WW][10] = 0, -+ [0][1][2][0][RTW89_WW][11] = 0, -+ [0][1][2][0][RTW89_WW][12] = 0, -+ [0][1][2][0][RTW89_WW][13] = 0, -+ [0][1][2][1][RTW89_WW][0] = 0, -+ [0][1][2][1][RTW89_WW][1] = 0, -+ [0][1][2][1][RTW89_WW][2] = 0, -+ [0][1][2][1][RTW89_WW][3] = 0, -+ [0][1][2][1][RTW89_WW][4] = 0, -+ [0][1][2][1][RTW89_WW][5] = 0, -+ [0][1][2][1][RTW89_WW][6] = 0, -+ [0][1][2][1][RTW89_WW][7] = 0, -+ [0][1][2][1][RTW89_WW][8] = 0, -+ [0][1][2][1][RTW89_WW][9] = 0, -+ [0][1][2][1][RTW89_WW][10] = 0, -+ [0][1][2][1][RTW89_WW][11] = 0, -+ [0][1][2][1][RTW89_WW][12] = 0, -+ [0][1][2][1][RTW89_WW][13] = 0, -+ [1][0][2][0][RTW89_WW][0] = 0, -+ [1][0][2][0][RTW89_WW][1] = 0, -+ [1][0][2][0][RTW89_WW][2] = 58, -+ [1][0][2][0][RTW89_WW][3] = 58, -+ [1][0][2][0][RTW89_WW][4] = 58, -+ [1][0][2][0][RTW89_WW][5] = 58, -+ [1][0][2][0][RTW89_WW][6] = 58, -+ [1][0][2][0][RTW89_WW][7] = 58, -+ [1][0][2][0][RTW89_WW][8] = 58, -+ [1][0][2][0][RTW89_WW][9] = 58, -+ [1][0][2][0][RTW89_WW][10] = 58, -+ [1][0][2][0][RTW89_WW][11] = 0, -+ [1][0][2][0][RTW89_WW][12] = 0, -+ [1][0][2][0][RTW89_WW][13] = 0, -+ [1][1][2][0][RTW89_WW][0] = 0, -+ [1][1][2][0][RTW89_WW][1] = 0, -+ [1][1][2][0][RTW89_WW][2] = 0, -+ [1][1][2][0][RTW89_WW][3] = 0, -+ [1][1][2][0][RTW89_WW][4] = 0, -+ [1][1][2][0][RTW89_WW][5] = 0, -+ [1][1][2][0][RTW89_WW][6] = 0, -+ [1][1][2][0][RTW89_WW][7] = 0, -+ [1][1][2][0][RTW89_WW][8] = 0, -+ [1][1][2][0][RTW89_WW][9] = 0, -+ [1][1][2][0][RTW89_WW][10] = 0, -+ [1][1][2][0][RTW89_WW][11] = 0, -+ [1][1][2][0][RTW89_WW][12] = 0, -+ [1][1][2][0][RTW89_WW][13] = 0, -+ [1][1][2][1][RTW89_WW][0] = 0, -+ [1][1][2][1][RTW89_WW][1] = 0, -+ [1][1][2][1][RTW89_WW][2] = 0, -+ [1][1][2][1][RTW89_WW][3] = 0, -+ [1][1][2][1][RTW89_WW][4] = 0, -+ [1][1][2][1][RTW89_WW][5] = 0, -+ [1][1][2][1][RTW89_WW][6] = 0, -+ [1][1][2][1][RTW89_WW][7] = 0, -+ [1][1][2][1][RTW89_WW][8] = 0, -+ [1][1][2][1][RTW89_WW][9] = 0, -+ [1][1][2][1][RTW89_WW][10] = 0, -+ [1][1][2][1][RTW89_WW][11] = 0, -+ [1][1][2][1][RTW89_WW][12] = 0, -+ [1][1][2][1][RTW89_WW][13] = 0, -+ [0][0][0][0][RTW89_FCC][0] = 82, -+ [0][0][0][0][RTW89_ETSI][0] = 58, -+ [0][0][0][0][RTW89_MKK][0] = 68, -+ [0][0][0][0][RTW89_IC][0] = 82, -+ [0][0][0][0][RTW89_KCC][0] = 68, -+ [0][0][0][0][RTW89_ACMA][0] = 58, -+ [0][0][0][0][RTW89_CN][0] = 60, -+ [0][0][0][0][RTW89_UK][0] = 58, -+ [0][0][0][0][RTW89_FCC][1] = 82, -+ [0][0][0][0][RTW89_ETSI][1] = 58, -+ [0][0][0][0][RTW89_MKK][1] = 68, -+ [0][0][0][0][RTW89_IC][1] = 82, -+ [0][0][0][0][RTW89_KCC][1] = 68, -+ [0][0][0][0][RTW89_ACMA][1] = 58, -+ [0][0][0][0][RTW89_CN][1] = 60, -+ [0][0][0][0][RTW89_UK][1] = 58, -+ [0][0][0][0][RTW89_FCC][2] = 82, -+ [0][0][0][0][RTW89_ETSI][2] = 58, -+ [0][0][0][0][RTW89_MKK][2] = 68, -+ [0][0][0][0][RTW89_IC][2] = 82, -+ [0][0][0][0][RTW89_KCC][2] = 68, -+ [0][0][0][0][RTW89_ACMA][2] = 58, -+ [0][0][0][0][RTW89_CN][2] = 60, -+ [0][0][0][0][RTW89_UK][2] = 58, -+ [0][0][0][0][RTW89_FCC][3] = 82, -+ [0][0][0][0][RTW89_ETSI][3] = 58, -+ [0][0][0][0][RTW89_MKK][3] = 68, -+ [0][0][0][0][RTW89_IC][3] = 82, -+ [0][0][0][0][RTW89_KCC][3] = 68, -+ [0][0][0][0][RTW89_ACMA][3] = 58, -+ [0][0][0][0][RTW89_CN][3] = 60, -+ [0][0][0][0][RTW89_UK][3] = 58, -+ [0][0][0][0][RTW89_FCC][4] = 82, -+ [0][0][0][0][RTW89_ETSI][4] = 58, -+ [0][0][0][0][RTW89_MKK][4] = 68, -+ [0][0][0][0][RTW89_IC][4] = 82, -+ [0][0][0][0][RTW89_KCC][4] = 68, -+ [0][0][0][0][RTW89_ACMA][4] = 58, -+ [0][0][0][0][RTW89_CN][4] = 60, -+ [0][0][0][0][RTW89_UK][4] = 58, -+ [0][0][0][0][RTW89_FCC][5] = 82, -+ [0][0][0][0][RTW89_ETSI][5] = 58, -+ [0][0][0][0][RTW89_MKK][5] = 68, -+ [0][0][0][0][RTW89_IC][5] = 82, -+ [0][0][0][0][RTW89_KCC][5] = 68, -+ [0][0][0][0][RTW89_ACMA][5] = 58, -+ [0][0][0][0][RTW89_CN][5] = 60, -+ [0][0][0][0][RTW89_UK][5] = 58, -+ [0][0][0][0][RTW89_FCC][6] = 82, -+ [0][0][0][0][RTW89_ETSI][6] = 58, -+ [0][0][0][0][RTW89_MKK][6] = 68, -+ [0][0][0][0][RTW89_IC][6] = 82, -+ [0][0][0][0][RTW89_KCC][6] = 68, -+ [0][0][0][0][RTW89_ACMA][6] = 58, -+ [0][0][0][0][RTW89_CN][6] = 60, -+ [0][0][0][0][RTW89_UK][6] = 58, -+ [0][0][0][0][RTW89_FCC][7] = 82, -+ [0][0][0][0][RTW89_ETSI][7] = 58, -+ [0][0][0][0][RTW89_MKK][7] = 68, -+ [0][0][0][0][RTW89_IC][7] = 82, -+ [0][0][0][0][RTW89_KCC][7] = 68, -+ [0][0][0][0][RTW89_ACMA][7] = 58, -+ [0][0][0][0][RTW89_CN][7] = 60, -+ [0][0][0][0][RTW89_UK][7] = 58, -+ [0][0][0][0][RTW89_FCC][8] = 82, -+ [0][0][0][0][RTW89_ETSI][8] = 58, -+ [0][0][0][0][RTW89_MKK][8] = 68, -+ [0][0][0][0][RTW89_IC][8] = 82, -+ [0][0][0][0][RTW89_KCC][8] = 68, -+ [0][0][0][0][RTW89_ACMA][8] = 58, -+ [0][0][0][0][RTW89_CN][8] = 60, -+ [0][0][0][0][RTW89_UK][8] = 58, -+ [0][0][0][0][RTW89_FCC][9] = 82, -+ [0][0][0][0][RTW89_ETSI][9] = 58, -+ [0][0][0][0][RTW89_MKK][9] = 68, -+ [0][0][0][0][RTW89_IC][9] = 82, -+ [0][0][0][0][RTW89_KCC][9] = 68, -+ [0][0][0][0][RTW89_ACMA][9] = 58, -+ [0][0][0][0][RTW89_CN][9] = 60, -+ [0][0][0][0][RTW89_UK][9] = 58, -+ [0][0][0][0][RTW89_FCC][10] = 80, -+ [0][0][0][0][RTW89_ETSI][10] = 58, -+ [0][0][0][0][RTW89_MKK][10] = 68, -+ [0][0][0][0][RTW89_IC][10] = 80, -+ [0][0][0][0][RTW89_KCC][10] = 68, -+ [0][0][0][0][RTW89_ACMA][10] = 58, -+ [0][0][0][0][RTW89_CN][10] = 60, -+ [0][0][0][0][RTW89_UK][10] = 58, -+ [0][0][0][0][RTW89_FCC][11] = 60, -+ [0][0][0][0][RTW89_ETSI][11] = 58, -+ [0][0][0][0][RTW89_MKK][11] = 68, -+ [0][0][0][0][RTW89_IC][11] = 60, -+ [0][0][0][0][RTW89_KCC][11] = 68, -+ [0][0][0][0][RTW89_ACMA][11] = 58, -+ [0][0][0][0][RTW89_CN][11] = 60, -+ [0][0][0][0][RTW89_UK][11] = 58, -+ [0][0][0][0][RTW89_FCC][12] = 52, -+ [0][0][0][0][RTW89_ETSI][12] = 58, -+ [0][0][0][0][RTW89_MKK][12] = 68, -+ [0][0][0][0][RTW89_IC][12] = 52, -+ [0][0][0][0][RTW89_KCC][12] = 68, -+ [0][0][0][0][RTW89_ACMA][12] = 58, -+ [0][0][0][0][RTW89_CN][12] = 60, -+ [0][0][0][0][RTW89_UK][12] = 58, -+ [0][0][0][0][RTW89_FCC][13] = 127, -+ [0][0][0][0][RTW89_ETSI][13] = 127, -+ [0][0][0][0][RTW89_MKK][13] = 76, -+ [0][0][0][0][RTW89_IC][13] = 127, -+ [0][0][0][0][RTW89_KCC][13] = 127, -+ [0][0][0][0][RTW89_ACMA][13] = 127, -+ [0][0][0][0][RTW89_CN][13] = 127, -+ [0][0][0][0][RTW89_UK][13] = 127, -+ [0][1][0][0][RTW89_FCC][0] = 127, -+ [0][1][0][0][RTW89_ETSI][0] = 127, -+ [0][1][0][0][RTW89_MKK][0] = 127, -+ [0][1][0][0][RTW89_IC][0] = 127, -+ [0][1][0][0][RTW89_KCC][0] = 127, -+ [0][1][0][0][RTW89_ACMA][0] = 127, -+ [0][1][0][0][RTW89_CN][0] = 127, -+ [0][1][0][0][RTW89_UK][0] = 127, -+ [0][1][0][0][RTW89_FCC][1] = 127, -+ [0][1][0][0][RTW89_ETSI][1] = 127, -+ [0][1][0][0][RTW89_MKK][1] = 127, -+ [0][1][0][0][RTW89_IC][1] = 127, -+ [0][1][0][0][RTW89_KCC][1] = 127, -+ [0][1][0][0][RTW89_ACMA][1] = 127, -+ [0][1][0][0][RTW89_CN][1] = 127, -+ [0][1][0][0][RTW89_UK][1] = 127, -+ [0][1][0][0][RTW89_FCC][2] = 127, -+ [0][1][0][0][RTW89_ETSI][2] = 127, -+ [0][1][0][0][RTW89_MKK][2] = 127, -+ [0][1][0][0][RTW89_IC][2] = 127, -+ [0][1][0][0][RTW89_KCC][2] = 127, -+ [0][1][0][0][RTW89_ACMA][2] = 127, -+ [0][1][0][0][RTW89_CN][2] = 127, -+ [0][1][0][0][RTW89_UK][2] = 127, -+ [0][1][0][0][RTW89_FCC][3] = 127, -+ [0][1][0][0][RTW89_ETSI][3] = 127, -+ [0][1][0][0][RTW89_MKK][3] = 127, -+ [0][1][0][0][RTW89_IC][3] = 127, -+ [0][1][0][0][RTW89_KCC][3] = 127, -+ [0][1][0][0][RTW89_ACMA][3] = 127, -+ [0][1][0][0][RTW89_CN][3] = 127, -+ [0][1][0][0][RTW89_UK][3] = 127, -+ [0][1][0][0][RTW89_FCC][4] = 127, -+ [0][1][0][0][RTW89_ETSI][4] = 127, -+ [0][1][0][0][RTW89_MKK][4] = 127, -+ [0][1][0][0][RTW89_IC][4] = 127, -+ [0][1][0][0][RTW89_KCC][4] = 127, -+ [0][1][0][0][RTW89_ACMA][4] = 127, -+ [0][1][0][0][RTW89_CN][4] = 127, -+ [0][1][0][0][RTW89_UK][4] = 127, -+ [0][1][0][0][RTW89_FCC][5] = 127, -+ [0][1][0][0][RTW89_ETSI][5] = 127, -+ [0][1][0][0][RTW89_MKK][5] = 127, -+ [0][1][0][0][RTW89_IC][5] = 127, -+ [0][1][0][0][RTW89_KCC][5] = 127, -+ [0][1][0][0][RTW89_ACMA][5] = 127, -+ [0][1][0][0][RTW89_CN][5] = 127, -+ [0][1][0][0][RTW89_UK][5] = 127, -+ [0][1][0][0][RTW89_FCC][6] = 127, -+ [0][1][0][0][RTW89_ETSI][6] = 127, -+ [0][1][0][0][RTW89_MKK][6] = 127, -+ [0][1][0][0][RTW89_IC][6] = 127, -+ [0][1][0][0][RTW89_KCC][6] = 127, -+ [0][1][0][0][RTW89_ACMA][6] = 127, -+ [0][1][0][0][RTW89_CN][6] = 127, -+ [0][1][0][0][RTW89_UK][6] = 127, -+ [0][1][0][0][RTW89_FCC][7] = 127, -+ [0][1][0][0][RTW89_ETSI][7] = 127, -+ [0][1][0][0][RTW89_MKK][7] = 127, -+ [0][1][0][0][RTW89_IC][7] = 127, -+ [0][1][0][0][RTW89_KCC][7] = 127, -+ [0][1][0][0][RTW89_ACMA][7] = 127, -+ [0][1][0][0][RTW89_CN][7] = 127, -+ [0][1][0][0][RTW89_UK][7] = 127, -+ [0][1][0][0][RTW89_FCC][8] = 127, -+ [0][1][0][0][RTW89_ETSI][8] = 127, -+ [0][1][0][0][RTW89_MKK][8] = 127, -+ [0][1][0][0][RTW89_IC][8] = 127, -+ [0][1][0][0][RTW89_KCC][8] = 127, -+ [0][1][0][0][RTW89_ACMA][8] = 127, -+ [0][1][0][0][RTW89_CN][8] = 127, -+ [0][1][0][0][RTW89_UK][8] = 127, -+ [0][1][0][0][RTW89_FCC][9] = 127, -+ [0][1][0][0][RTW89_ETSI][9] = 127, -+ [0][1][0][0][RTW89_MKK][9] = 127, -+ [0][1][0][0][RTW89_IC][9] = 127, -+ [0][1][0][0][RTW89_KCC][9] = 127, -+ [0][1][0][0][RTW89_ACMA][9] = 127, -+ [0][1][0][0][RTW89_CN][9] = 127, -+ [0][1][0][0][RTW89_UK][9] = 127, -+ [0][1][0][0][RTW89_FCC][10] = 127, -+ [0][1][0][0][RTW89_ETSI][10] = 127, -+ [0][1][0][0][RTW89_MKK][10] = 127, -+ [0][1][0][0][RTW89_IC][10] = 127, -+ [0][1][0][0][RTW89_KCC][10] = 127, -+ [0][1][0][0][RTW89_ACMA][10] = 127, -+ [0][1][0][0][RTW89_CN][10] = 127, -+ [0][1][0][0][RTW89_UK][10] = 127, -+ [0][1][0][0][RTW89_FCC][11] = 127, -+ [0][1][0][0][RTW89_ETSI][11] = 127, -+ [0][1][0][0][RTW89_MKK][11] = 127, -+ [0][1][0][0][RTW89_IC][11] = 127, -+ [0][1][0][0][RTW89_KCC][11] = 127, -+ [0][1][0][0][RTW89_ACMA][11] = 127, -+ [0][1][0][0][RTW89_CN][11] = 127, -+ [0][1][0][0][RTW89_UK][11] = 127, -+ [0][1][0][0][RTW89_FCC][12] = 127, -+ [0][1][0][0][RTW89_ETSI][12] = 127, -+ [0][1][0][0][RTW89_MKK][12] = 127, -+ [0][1][0][0][RTW89_IC][12] = 127, -+ [0][1][0][0][RTW89_KCC][12] = 127, -+ [0][1][0][0][RTW89_ACMA][12] = 127, -+ [0][1][0][0][RTW89_CN][12] = 127, -+ [0][1][0][0][RTW89_UK][12] = 127, -+ [0][1][0][0][RTW89_FCC][13] = 127, -+ [0][1][0][0][RTW89_ETSI][13] = 127, -+ [0][1][0][0][RTW89_MKK][13] = 127, -+ [0][1][0][0][RTW89_IC][13] = 127, -+ [0][1][0][0][RTW89_KCC][13] = 127, -+ [0][1][0][0][RTW89_ACMA][13] = 127, -+ [0][1][0][0][RTW89_CN][13] = 127, -+ [0][1][0][0][RTW89_UK][13] = 127, -+ [1][0][0][0][RTW89_FCC][0] = 127, -+ [1][0][0][0][RTW89_ETSI][0] = 127, -+ [1][0][0][0][RTW89_MKK][0] = 127, -+ [1][0][0][0][RTW89_IC][0] = 127, -+ [1][0][0][0][RTW89_KCC][0] = 127, -+ [1][0][0][0][RTW89_ACMA][0] = 127, -+ [1][0][0][0][RTW89_CN][0] = 127, -+ [1][0][0][0][RTW89_UK][0] = 127, -+ [1][0][0][0][RTW89_FCC][1] = 127, -+ [1][0][0][0][RTW89_ETSI][1] = 127, -+ [1][0][0][0][RTW89_MKK][1] = 127, -+ [1][0][0][0][RTW89_IC][1] = 127, -+ [1][0][0][0][RTW89_KCC][1] = 127, -+ [1][0][0][0][RTW89_ACMA][1] = 127, -+ [1][0][0][0][RTW89_CN][1] = 127, -+ [1][0][0][0][RTW89_UK][1] = 127, -+ [1][0][0][0][RTW89_FCC][2] = 127, -+ [1][0][0][0][RTW89_ETSI][2] = 58, -+ [1][0][0][0][RTW89_MKK][2] = 70, -+ [1][0][0][0][RTW89_IC][2] = 127, -+ [1][0][0][0][RTW89_KCC][2] = 68, -+ [1][0][0][0][RTW89_ACMA][2] = 58, -+ [1][0][0][0][RTW89_CN][2] = 60, -+ [1][0][0][0][RTW89_UK][2] = 58, -+ [1][0][0][0][RTW89_FCC][3] = 127, -+ [1][0][0][0][RTW89_ETSI][3] = 58, -+ [1][0][0][0][RTW89_MKK][3] = 76, -+ [1][0][0][0][RTW89_IC][3] = 127, -+ [1][0][0][0][RTW89_KCC][3] = 68, -+ [1][0][0][0][RTW89_ACMA][3] = 58, -+ [1][0][0][0][RTW89_CN][3] = 60, -+ [1][0][0][0][RTW89_UK][3] = 58, -+ [1][0][0][0][RTW89_FCC][4] = 127, -+ [1][0][0][0][RTW89_ETSI][4] = 58, -+ [1][0][0][0][RTW89_MKK][4] = 76, -+ [1][0][0][0][RTW89_IC][4] = 127, -+ [1][0][0][0][RTW89_KCC][4] = 68, -+ [1][0][0][0][RTW89_ACMA][4] = 58, -+ [1][0][0][0][RTW89_CN][4] = 60, -+ [1][0][0][0][RTW89_UK][4] = 58, -+ [1][0][0][0][RTW89_FCC][5] = 127, -+ [1][0][0][0][RTW89_ETSI][5] = 58, -+ [1][0][0][0][RTW89_MKK][5] = 76, -+ [1][0][0][0][RTW89_IC][5] = 127, -+ [1][0][0][0][RTW89_KCC][5] = 68, -+ [1][0][0][0][RTW89_ACMA][5] = 58, -+ [1][0][0][0][RTW89_CN][5] = 60, -+ [1][0][0][0][RTW89_UK][5] = 58, -+ [1][0][0][0][RTW89_FCC][6] = 127, -+ [1][0][0][0][RTW89_ETSI][6] = 58, -+ [1][0][0][0][RTW89_MKK][6] = 76, -+ [1][0][0][0][RTW89_IC][6] = 127, -+ [1][0][0][0][RTW89_KCC][6] = 68, -+ [1][0][0][0][RTW89_ACMA][6] = 58, -+ [1][0][0][0][RTW89_CN][6] = 60, -+ [1][0][0][0][RTW89_UK][6] = 58, -+ [1][0][0][0][RTW89_FCC][7] = 127, -+ [1][0][0][0][RTW89_ETSI][7] = 58, -+ [1][0][0][0][RTW89_MKK][7] = 76, -+ [1][0][0][0][RTW89_IC][7] = 127, -+ [1][0][0][0][RTW89_KCC][7] = 68, -+ [1][0][0][0][RTW89_ACMA][7] = 58, -+ [1][0][0][0][RTW89_CN][7] = 60, -+ [1][0][0][0][RTW89_UK][7] = 58, -+ [1][0][0][0][RTW89_FCC][8] = 127, -+ [1][0][0][0][RTW89_ETSI][8] = 58, -+ [1][0][0][0][RTW89_MKK][8] = 76, -+ [1][0][0][0][RTW89_IC][8] = 127, -+ [1][0][0][0][RTW89_KCC][8] = 68, -+ [1][0][0][0][RTW89_ACMA][8] = 58, -+ [1][0][0][0][RTW89_CN][8] = 60, -+ [1][0][0][0][RTW89_UK][8] = 58, -+ [1][0][0][0][RTW89_FCC][9] = 127, -+ [1][0][0][0][RTW89_ETSI][9] = 58, -+ [1][0][0][0][RTW89_MKK][9] = 76, -+ [1][0][0][0][RTW89_IC][9] = 127, -+ [1][0][0][0][RTW89_KCC][9] = 68, -+ [1][0][0][0][RTW89_ACMA][9] = 58, -+ [1][0][0][0][RTW89_CN][9] = 60, -+ [1][0][0][0][RTW89_UK][9] = 58, -+ [1][0][0][0][RTW89_FCC][10] = 127, -+ [1][0][0][0][RTW89_ETSI][10] = 58, -+ [1][0][0][0][RTW89_MKK][10] = 66, -+ [1][0][0][0][RTW89_IC][10] = 127, -+ [1][0][0][0][RTW89_KCC][10] = 68, -+ [1][0][0][0][RTW89_ACMA][10] = 58, -+ [1][0][0][0][RTW89_CN][10] = 60, -+ [1][0][0][0][RTW89_UK][10] = 58, -+ [1][0][0][0][RTW89_FCC][11] = 127, -+ [1][0][0][0][RTW89_ETSI][11] = 127, -+ [1][0][0][0][RTW89_MKK][11] = 127, -+ [1][0][0][0][RTW89_IC][11] = 127, -+ [1][0][0][0][RTW89_KCC][11] = 127, -+ [1][0][0][0][RTW89_ACMA][11] = 127, -+ [1][0][0][0][RTW89_CN][11] = 127, -+ [1][0][0][0][RTW89_UK][11] = 127, -+ [1][0][0][0][RTW89_FCC][12] = 127, -+ [1][0][0][0][RTW89_ETSI][12] = 127, -+ [1][0][0][0][RTW89_MKK][12] = 127, -+ [1][0][0][0][RTW89_IC][12] = 127, -+ [1][0][0][0][RTW89_KCC][12] = 127, -+ [1][0][0][0][RTW89_ACMA][12] = 127, -+ [1][0][0][0][RTW89_CN][12] = 127, -+ [1][0][0][0][RTW89_UK][12] = 127, -+ [1][0][0][0][RTW89_FCC][13] = 127, -+ [1][0][0][0][RTW89_ETSI][13] = 127, -+ [1][0][0][0][RTW89_MKK][13] = 127, -+ [1][0][0][0][RTW89_IC][13] = 127, -+ [1][0][0][0][RTW89_KCC][13] = 127, -+ [1][0][0][0][RTW89_ACMA][13] = 127, -+ [1][0][0][0][RTW89_CN][13] = 127, -+ [1][0][0][0][RTW89_UK][13] = 127, -+ [1][1][0][0][RTW89_FCC][0] = 127, -+ [1][1][0][0][RTW89_ETSI][0] = 127, -+ [1][1][0][0][RTW89_MKK][0] = 127, -+ [1][1][0][0][RTW89_IC][0] = 127, -+ [1][1][0][0][RTW89_KCC][0] = 127, -+ [1][1][0][0][RTW89_ACMA][0] = 127, -+ [1][1][0][0][RTW89_CN][0] = 127, -+ [1][1][0][0][RTW89_UK][0] = 127, -+ [1][1][0][0][RTW89_FCC][1] = 127, -+ [1][1][0][0][RTW89_ETSI][1] = 127, -+ [1][1][0][0][RTW89_MKK][1] = 127, -+ [1][1][0][0][RTW89_IC][1] = 127, -+ [1][1][0][0][RTW89_KCC][1] = 127, -+ [1][1][0][0][RTW89_ACMA][1] = 127, -+ [1][1][0][0][RTW89_CN][1] = 127, -+ [1][1][0][0][RTW89_UK][1] = 127, -+ [1][1][0][0][RTW89_FCC][2] = 127, -+ [1][1][0][0][RTW89_ETSI][2] = 127, -+ [1][1][0][0][RTW89_MKK][2] = 127, -+ [1][1][0][0][RTW89_IC][2] = 127, -+ [1][1][0][0][RTW89_KCC][2] = 127, -+ [1][1][0][0][RTW89_ACMA][2] = 127, -+ [1][1][0][0][RTW89_CN][2] = 127, -+ [1][1][0][0][RTW89_UK][2] = 127, -+ [1][1][0][0][RTW89_FCC][3] = 127, -+ [1][1][0][0][RTW89_ETSI][3] = 127, -+ [1][1][0][0][RTW89_MKK][3] = 127, -+ [1][1][0][0][RTW89_IC][3] = 127, -+ [1][1][0][0][RTW89_KCC][3] = 127, -+ [1][1][0][0][RTW89_ACMA][3] = 127, -+ [1][1][0][0][RTW89_CN][3] = 127, -+ [1][1][0][0][RTW89_UK][3] = 127, -+ [1][1][0][0][RTW89_FCC][4] = 127, -+ [1][1][0][0][RTW89_ETSI][4] = 127, -+ [1][1][0][0][RTW89_MKK][4] = 127, -+ [1][1][0][0][RTW89_IC][4] = 127, -+ [1][1][0][0][RTW89_KCC][4] = 127, -+ [1][1][0][0][RTW89_ACMA][4] = 127, -+ [1][1][0][0][RTW89_CN][4] = 127, -+ [1][1][0][0][RTW89_UK][4] = 127, -+ [1][1][0][0][RTW89_FCC][5] = 127, -+ [1][1][0][0][RTW89_ETSI][5] = 127, -+ [1][1][0][0][RTW89_MKK][5] = 127, -+ [1][1][0][0][RTW89_IC][5] = 127, -+ [1][1][0][0][RTW89_KCC][5] = 127, -+ [1][1][0][0][RTW89_ACMA][5] = 127, -+ [1][1][0][0][RTW89_CN][5] = 127, -+ [1][1][0][0][RTW89_UK][5] = 127, -+ [1][1][0][0][RTW89_FCC][6] = 127, -+ [1][1][0][0][RTW89_ETSI][6] = 127, -+ [1][1][0][0][RTW89_MKK][6] = 127, -+ [1][1][0][0][RTW89_IC][6] = 127, -+ [1][1][0][0][RTW89_KCC][6] = 127, -+ [1][1][0][0][RTW89_ACMA][6] = 127, -+ [1][1][0][0][RTW89_CN][6] = 127, -+ [1][1][0][0][RTW89_UK][6] = 127, -+ [1][1][0][0][RTW89_FCC][7] = 127, -+ [1][1][0][0][RTW89_ETSI][7] = 127, -+ [1][1][0][0][RTW89_MKK][7] = 127, -+ [1][1][0][0][RTW89_IC][7] = 127, -+ [1][1][0][0][RTW89_KCC][7] = 127, -+ [1][1][0][0][RTW89_ACMA][7] = 127, -+ [1][1][0][0][RTW89_CN][7] = 127, -+ [1][1][0][0][RTW89_UK][7] = 127, -+ [1][1][0][0][RTW89_FCC][8] = 127, -+ [1][1][0][0][RTW89_ETSI][8] = 127, -+ [1][1][0][0][RTW89_MKK][8] = 127, -+ [1][1][0][0][RTW89_IC][8] = 127, -+ [1][1][0][0][RTW89_KCC][8] = 127, -+ [1][1][0][0][RTW89_ACMA][8] = 127, -+ [1][1][0][0][RTW89_CN][8] = 127, -+ [1][1][0][0][RTW89_UK][8] = 127, -+ [1][1][0][0][RTW89_FCC][9] = 127, -+ [1][1][0][0][RTW89_ETSI][9] = 127, -+ [1][1][0][0][RTW89_MKK][9] = 127, -+ [1][1][0][0][RTW89_IC][9] = 127, -+ [1][1][0][0][RTW89_KCC][9] = 127, -+ [1][1][0][0][RTW89_ACMA][9] = 127, -+ [1][1][0][0][RTW89_CN][9] = 127, -+ [1][1][0][0][RTW89_UK][9] = 127, -+ [1][1][0][0][RTW89_FCC][10] = 127, -+ [1][1][0][0][RTW89_ETSI][10] = 127, -+ [1][1][0][0][RTW89_MKK][10] = 127, -+ [1][1][0][0][RTW89_IC][10] = 127, -+ [1][1][0][0][RTW89_KCC][10] = 127, -+ [1][1][0][0][RTW89_ACMA][10] = 127, -+ [1][1][0][0][RTW89_CN][10] = 127, -+ [1][1][0][0][RTW89_UK][10] = 127, -+ [1][1][0][0][RTW89_FCC][11] = 127, -+ [1][1][0][0][RTW89_ETSI][11] = 127, -+ [1][1][0][0][RTW89_MKK][11] = 127, -+ [1][1][0][0][RTW89_IC][11] = 127, -+ [1][1][0][0][RTW89_KCC][11] = 127, -+ [1][1][0][0][RTW89_ACMA][11] = 127, -+ [1][1][0][0][RTW89_CN][11] = 127, -+ [1][1][0][0][RTW89_UK][11] = 127, -+ [1][1][0][0][RTW89_FCC][12] = 127, -+ [1][1][0][0][RTW89_ETSI][12] = 127, -+ [1][1][0][0][RTW89_MKK][12] = 127, -+ [1][1][0][0][RTW89_IC][12] = 127, -+ [1][1][0][0][RTW89_KCC][12] = 127, -+ [1][1][0][0][RTW89_ACMA][12] = 127, -+ [1][1][0][0][RTW89_CN][12] = 127, -+ [1][1][0][0][RTW89_UK][12] = 127, -+ [1][1][0][0][RTW89_FCC][13] = 127, -+ [1][1][0][0][RTW89_ETSI][13] = 127, -+ [1][1][0][0][RTW89_MKK][13] = 127, -+ [1][1][0][0][RTW89_IC][13] = 127, -+ [1][1][0][0][RTW89_KCC][13] = 127, -+ [1][1][0][0][RTW89_ACMA][13] = 127, -+ [1][1][0][0][RTW89_CN][13] = 127, -+ [1][1][0][0][RTW89_UK][13] = 127, -+ [0][0][1][0][RTW89_FCC][0] = 78, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 72, -+ [0][0][1][0][RTW89_IC][0] = 78, -+ [0][0][1][0][RTW89_KCC][0] = 76, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CN][0] = 60, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][1] = 78, -+ [0][0][1][0][RTW89_ETSI][1] = 60, -+ [0][0][1][0][RTW89_MKK][1] = 74, -+ [0][0][1][0][RTW89_IC][1] = 78, -+ [0][0][1][0][RTW89_KCC][1] = 76, -+ [0][0][1][0][RTW89_ACMA][1] = 60, -+ [0][0][1][0][RTW89_CN][1] = 60, -+ [0][0][1][0][RTW89_UK][1] = 60, -+ [0][0][1][0][RTW89_FCC][2] = 80, -+ [0][0][1][0][RTW89_ETSI][2] = 60, -+ [0][0][1][0][RTW89_MKK][2] = 74, -+ [0][0][1][0][RTW89_IC][2] = 80, -+ [0][0][1][0][RTW89_KCC][2] = 76, -+ [0][0][1][0][RTW89_ACMA][2] = 60, -+ [0][0][1][0][RTW89_CN][2] = 60, -+ [0][0][1][0][RTW89_UK][2] = 60, -+ [0][0][1][0][RTW89_FCC][3] = 80, -+ [0][0][1][0][RTW89_ETSI][3] = 60, -+ [0][0][1][0][RTW89_MKK][3] = 74, -+ [0][0][1][0][RTW89_IC][3] = 80, -+ [0][0][1][0][RTW89_KCC][3] = 76, -+ [0][0][1][0][RTW89_ACMA][3] = 60, -+ [0][0][1][0][RTW89_CN][3] = 60, -+ [0][0][1][0][RTW89_UK][3] = 60, -+ [0][0][1][0][RTW89_FCC][4] = 80, -+ [0][0][1][0][RTW89_ETSI][4] = 60, -+ [0][0][1][0][RTW89_MKK][4] = 74, -+ [0][0][1][0][RTW89_IC][4] = 80, -+ [0][0][1][0][RTW89_KCC][4] = 76, -+ [0][0][1][0][RTW89_ACMA][4] = 60, -+ [0][0][1][0][RTW89_CN][4] = 60, -+ [0][0][1][0][RTW89_UK][4] = 60, -+ [0][0][1][0][RTW89_FCC][5] = 80, -+ [0][0][1][0][RTW89_ETSI][5] = 60, -+ [0][0][1][0][RTW89_MKK][5] = 74, -+ [0][0][1][0][RTW89_IC][5] = 80, -+ [0][0][1][0][RTW89_KCC][5] = 76, -+ [0][0][1][0][RTW89_ACMA][5] = 60, -+ [0][0][1][0][RTW89_CN][5] = 60, -+ [0][0][1][0][RTW89_UK][5] = 60, -+ [0][0][1][0][RTW89_FCC][6] = 80, -+ [0][0][1][0][RTW89_ETSI][6] = 60, -+ [0][0][1][0][RTW89_MKK][6] = 74, -+ [0][0][1][0][RTW89_IC][6] = 80, -+ [0][0][1][0][RTW89_KCC][6] = 76, -+ [0][0][1][0][RTW89_ACMA][6] = 60, -+ [0][0][1][0][RTW89_CN][6] = 60, -+ [0][0][1][0][RTW89_UK][6] = 60, -+ [0][0][1][0][RTW89_FCC][7] = 80, -+ [0][0][1][0][RTW89_ETSI][7] = 60, -+ [0][0][1][0][RTW89_MKK][7] = 74, -+ [0][0][1][0][RTW89_IC][7] = 80, -+ [0][0][1][0][RTW89_KCC][7] = 76, -+ [0][0][1][0][RTW89_ACMA][7] = 60, -+ [0][0][1][0][RTW89_CN][7] = 60, -+ [0][0][1][0][RTW89_UK][7] = 60, -+ [0][0][1][0][RTW89_FCC][8] = 80, -+ [0][0][1][0][RTW89_ETSI][8] = 60, -+ [0][0][1][0][RTW89_MKK][8] = 74, -+ [0][0][1][0][RTW89_IC][8] = 80, -+ [0][0][1][0][RTW89_KCC][8] = 76, -+ [0][0][1][0][RTW89_ACMA][8] = 60, -+ [0][0][1][0][RTW89_CN][8] = 60, -+ [0][0][1][0][RTW89_UK][8] = 60, -+ [0][0][1][0][RTW89_FCC][9] = 76, -+ [0][0][1][0][RTW89_ETSI][9] = 60, -+ [0][0][1][0][RTW89_MKK][9] = 74, -+ [0][0][1][0][RTW89_IC][9] = 76, -+ [0][0][1][0][RTW89_KCC][9] = 74, -+ [0][0][1][0][RTW89_ACMA][9] = 60, -+ [0][0][1][0][RTW89_CN][9] = 60, -+ [0][0][1][0][RTW89_UK][9] = 60, -+ [0][0][1][0][RTW89_FCC][10] = 76, -+ [0][0][1][0][RTW89_ETSI][10] = 60, -+ [0][0][1][0][RTW89_MKK][10] = 74, -+ [0][0][1][0][RTW89_IC][10] = 76, -+ [0][0][1][0][RTW89_KCC][10] = 74, -+ [0][0][1][0][RTW89_ACMA][10] = 60, -+ [0][0][1][0][RTW89_CN][10] = 60, -+ [0][0][1][0][RTW89_UK][10] = 60, -+ [0][0][1][0][RTW89_FCC][11] = 68, -+ [0][0][1][0][RTW89_ETSI][11] = 60, -+ [0][0][1][0][RTW89_MKK][11] = 74, -+ [0][0][1][0][RTW89_IC][11] = 68, -+ [0][0][1][0][RTW89_KCC][11] = 74, -+ [0][0][1][0][RTW89_ACMA][11] = 60, -+ [0][0][1][0][RTW89_CN][11] = 60, -+ [0][0][1][0][RTW89_UK][11] = 60, -+ [0][0][1][0][RTW89_FCC][12] = 64, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 70, -+ [0][0][1][0][RTW89_IC][12] = 64, -+ [0][0][1][0][RTW89_KCC][12] = 74, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CN][12] = 60, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][13] = 127, -+ [0][0][1][0][RTW89_ETSI][13] = 127, -+ [0][0][1][0][RTW89_MKK][13] = 127, -+ [0][0][1][0][RTW89_IC][13] = 127, -+ [0][0][1][0][RTW89_KCC][13] = 127, -+ [0][0][1][0][RTW89_ACMA][13] = 127, -+ [0][0][1][0][RTW89_CN][13] = 127, -+ [0][0][1][0][RTW89_UK][13] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 127, -+ [0][1][1][0][RTW89_ETSI][0] = 127, -+ [0][1][1][0][RTW89_MKK][0] = 127, -+ [0][1][1][0][RTW89_IC][0] = 127, -+ [0][1][1][0][RTW89_KCC][0] = 127, -+ [0][1][1][0][RTW89_ACMA][0] = 127, -+ [0][1][1][0][RTW89_CN][0] = 127, -+ [0][1][1][0][RTW89_UK][0] = 127, -+ [0][1][1][0][RTW89_FCC][1] = 127, -+ [0][1][1][0][RTW89_ETSI][1] = 127, -+ [0][1][1][0][RTW89_MKK][1] = 127, -+ [0][1][1][0][RTW89_IC][1] = 127, -+ [0][1][1][0][RTW89_KCC][1] = 127, -+ [0][1][1][0][RTW89_ACMA][1] = 127, -+ [0][1][1][0][RTW89_CN][1] = 127, -+ [0][1][1][0][RTW89_UK][1] = 127, -+ [0][1][1][0][RTW89_FCC][2] = 127, -+ [0][1][1][0][RTW89_ETSI][2] = 127, -+ [0][1][1][0][RTW89_MKK][2] = 127, -+ [0][1][1][0][RTW89_IC][2] = 127, -+ [0][1][1][0][RTW89_KCC][2] = 127, -+ [0][1][1][0][RTW89_ACMA][2] = 127, -+ [0][1][1][0][RTW89_CN][2] = 127, -+ [0][1][1][0][RTW89_UK][2] = 127, -+ [0][1][1][0][RTW89_FCC][3] = 127, -+ [0][1][1][0][RTW89_ETSI][3] = 127, -+ [0][1][1][0][RTW89_MKK][3] = 127, -+ [0][1][1][0][RTW89_IC][3] = 127, -+ [0][1][1][0][RTW89_KCC][3] = 127, -+ [0][1][1][0][RTW89_ACMA][3] = 127, -+ [0][1][1][0][RTW89_CN][3] = 127, -+ [0][1][1][0][RTW89_UK][3] = 127, -+ [0][1][1][0][RTW89_FCC][4] = 127, -+ [0][1][1][0][RTW89_ETSI][4] = 127, -+ [0][1][1][0][RTW89_MKK][4] = 127, -+ [0][1][1][0][RTW89_IC][4] = 127, -+ [0][1][1][0][RTW89_KCC][4] = 127, -+ [0][1][1][0][RTW89_ACMA][4] = 127, -+ [0][1][1][0][RTW89_CN][4] = 127, -+ [0][1][1][0][RTW89_UK][4] = 127, -+ [0][1][1][0][RTW89_FCC][5] = 127, -+ [0][1][1][0][RTW89_ETSI][5] = 127, -+ [0][1][1][0][RTW89_MKK][5] = 127, -+ [0][1][1][0][RTW89_IC][5] = 127, -+ [0][1][1][0][RTW89_KCC][5] = 127, -+ [0][1][1][0][RTW89_ACMA][5] = 127, -+ [0][1][1][0][RTW89_CN][5] = 127, -+ [0][1][1][0][RTW89_UK][5] = 127, -+ [0][1][1][0][RTW89_FCC][6] = 127, -+ [0][1][1][0][RTW89_ETSI][6] = 127, -+ [0][1][1][0][RTW89_MKK][6] = 127, -+ [0][1][1][0][RTW89_IC][6] = 127, -+ [0][1][1][0][RTW89_KCC][6] = 127, -+ [0][1][1][0][RTW89_ACMA][6] = 127, -+ [0][1][1][0][RTW89_CN][6] = 127, -+ [0][1][1][0][RTW89_UK][6] = 127, -+ [0][1][1][0][RTW89_FCC][7] = 127, -+ [0][1][1][0][RTW89_ETSI][7] = 127, -+ [0][1][1][0][RTW89_MKK][7] = 127, -+ [0][1][1][0][RTW89_IC][7] = 127, -+ [0][1][1][0][RTW89_KCC][7] = 127, -+ [0][1][1][0][RTW89_ACMA][7] = 127, -+ [0][1][1][0][RTW89_CN][7] = 127, -+ [0][1][1][0][RTW89_UK][7] = 127, -+ [0][1][1][0][RTW89_FCC][8] = 127, -+ [0][1][1][0][RTW89_ETSI][8] = 127, -+ [0][1][1][0][RTW89_MKK][8] = 127, -+ [0][1][1][0][RTW89_IC][8] = 127, -+ [0][1][1][0][RTW89_KCC][8] = 127, -+ [0][1][1][0][RTW89_ACMA][8] = 127, -+ [0][1][1][0][RTW89_CN][8] = 127, -+ [0][1][1][0][RTW89_UK][8] = 127, -+ [0][1][1][0][RTW89_FCC][9] = 127, -+ [0][1][1][0][RTW89_ETSI][9] = 127, -+ [0][1][1][0][RTW89_MKK][9] = 127, -+ [0][1][1][0][RTW89_IC][9] = 127, -+ [0][1][1][0][RTW89_KCC][9] = 127, -+ [0][1][1][0][RTW89_ACMA][9] = 127, -+ [0][1][1][0][RTW89_CN][9] = 127, -+ [0][1][1][0][RTW89_UK][9] = 127, -+ [0][1][1][0][RTW89_FCC][10] = 127, -+ [0][1][1][0][RTW89_ETSI][10] = 127, -+ [0][1][1][0][RTW89_MKK][10] = 127, -+ [0][1][1][0][RTW89_IC][10] = 127, -+ [0][1][1][0][RTW89_KCC][10] = 127, -+ [0][1][1][0][RTW89_ACMA][10] = 127, -+ [0][1][1][0][RTW89_CN][10] = 127, -+ [0][1][1][0][RTW89_UK][10] = 127, -+ [0][1][1][0][RTW89_FCC][11] = 127, -+ [0][1][1][0][RTW89_ETSI][11] = 127, -+ [0][1][1][0][RTW89_MKK][11] = 127, -+ [0][1][1][0][RTW89_IC][11] = 127, -+ [0][1][1][0][RTW89_KCC][11] = 127, -+ [0][1][1][0][RTW89_ACMA][11] = 127, -+ [0][1][1][0][RTW89_CN][11] = 127, -+ [0][1][1][0][RTW89_UK][11] = 127, -+ [0][1][1][0][RTW89_FCC][12] = 127, -+ [0][1][1][0][RTW89_ETSI][12] = 127, -+ [0][1][1][0][RTW89_MKK][12] = 127, -+ [0][1][1][0][RTW89_IC][12] = 127, -+ [0][1][1][0][RTW89_KCC][12] = 127, -+ [0][1][1][0][RTW89_ACMA][12] = 127, -+ [0][1][1][0][RTW89_CN][12] = 127, -+ [0][1][1][0][RTW89_UK][12] = 127, -+ [0][1][1][0][RTW89_FCC][13] = 127, -+ [0][1][1][0][RTW89_ETSI][13] = 127, -+ [0][1][1][0][RTW89_MKK][13] = 127, -+ [0][1][1][0][RTW89_IC][13] = 127, -+ [0][1][1][0][RTW89_KCC][13] = 127, -+ [0][1][1][0][RTW89_ACMA][13] = 127, -+ [0][1][1][0][RTW89_CN][13] = 127, -+ [0][1][1][0][RTW89_UK][13] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 78, -+ [0][0][2][0][RTW89_ETSI][0] = 60, -+ [0][0][2][0][RTW89_MKK][0] = 72, -+ [0][0][2][0][RTW89_IC][0] = 78, -+ [0][0][2][0][RTW89_KCC][0] = 76, -+ [0][0][2][0][RTW89_ACMA][0] = 60, -+ [0][0][2][0][RTW89_CN][0] = 60, -+ [0][0][2][0][RTW89_UK][0] = 60, -+ [0][0][2][0][RTW89_FCC][1] = 78, -+ [0][0][2][0][RTW89_ETSI][1] = 60, -+ [0][0][2][0][RTW89_MKK][1] = 76, -+ [0][0][2][0][RTW89_IC][1] = 78, -+ [0][0][2][0][RTW89_KCC][1] = 76, -+ [0][0][2][0][RTW89_ACMA][1] = 60, -+ [0][0][2][0][RTW89_CN][1] = 60, -+ [0][0][2][0][RTW89_UK][1] = 60, -+ [0][0][2][0][RTW89_FCC][2] = 80, -+ [0][0][2][0][RTW89_ETSI][2] = 60, -+ [0][0][2][0][RTW89_MKK][2] = 76, -+ [0][0][2][0][RTW89_IC][2] = 80, -+ [0][0][2][0][RTW89_KCC][2] = 76, -+ [0][0][2][0][RTW89_ACMA][2] = 60, -+ [0][0][2][0][RTW89_CN][2] = 60, -+ [0][0][2][0][RTW89_UK][2] = 60, -+ [0][0][2][0][RTW89_FCC][3] = 80, -+ [0][0][2][0][RTW89_ETSI][3] = 60, -+ [0][0][2][0][RTW89_MKK][3] = 76, -+ [0][0][2][0][RTW89_IC][3] = 80, -+ [0][0][2][0][RTW89_KCC][3] = 76, -+ [0][0][2][0][RTW89_ACMA][3] = 60, -+ [0][0][2][0][RTW89_CN][3] = 60, -+ [0][0][2][0][RTW89_UK][3] = 60, -+ [0][0][2][0][RTW89_FCC][4] = 80, -+ [0][0][2][0][RTW89_ETSI][4] = 60, -+ [0][0][2][0][RTW89_MKK][4] = 76, -+ [0][0][2][0][RTW89_IC][4] = 80, -+ [0][0][2][0][RTW89_KCC][4] = 76, -+ [0][0][2][0][RTW89_ACMA][4] = 60, -+ [0][0][2][0][RTW89_CN][4] = 60, -+ [0][0][2][0][RTW89_UK][4] = 60, -+ [0][0][2][0][RTW89_FCC][5] = 80, -+ [0][0][2][0][RTW89_ETSI][5] = 60, -+ [0][0][2][0][RTW89_MKK][5] = 76, -+ [0][0][2][0][RTW89_IC][5] = 80, -+ [0][0][2][0][RTW89_KCC][5] = 76, -+ [0][0][2][0][RTW89_ACMA][5] = 60, -+ [0][0][2][0][RTW89_CN][5] = 60, -+ [0][0][2][0][RTW89_UK][5] = 60, -+ [0][0][2][0][RTW89_FCC][6] = 80, -+ [0][0][2][0][RTW89_ETSI][6] = 60, -+ [0][0][2][0][RTW89_MKK][6] = 76, -+ [0][0][2][0][RTW89_IC][6] = 80, -+ [0][0][2][0][RTW89_KCC][6] = 76, -+ [0][0][2][0][RTW89_ACMA][6] = 60, -+ [0][0][2][0][RTW89_CN][6] = 60, -+ [0][0][2][0][RTW89_UK][6] = 60, -+ [0][0][2][0][RTW89_FCC][7] = 80, -+ [0][0][2][0][RTW89_ETSI][7] = 60, -+ [0][0][2][0][RTW89_MKK][7] = 76, -+ [0][0][2][0][RTW89_IC][7] = 80, -+ [0][0][2][0][RTW89_KCC][7] = 76, -+ [0][0][2][0][RTW89_ACMA][7] = 60, -+ [0][0][2][0][RTW89_CN][7] = 60, -+ [0][0][2][0][RTW89_UK][7] = 60, -+ [0][0][2][0][RTW89_FCC][8] = 78, -+ [0][0][2][0][RTW89_ETSI][8] = 60, -+ [0][0][2][0][RTW89_MKK][8] = 76, -+ [0][0][2][0][RTW89_IC][8] = 78, -+ [0][0][2][0][RTW89_KCC][8] = 76, -+ [0][0][2][0][RTW89_ACMA][8] = 60, -+ [0][0][2][0][RTW89_CN][8] = 60, -+ [0][0][2][0][RTW89_UK][8] = 60, -+ [0][0][2][0][RTW89_FCC][9] = 74, -+ [0][0][2][0][RTW89_ETSI][9] = 60, -+ [0][0][2][0][RTW89_MKK][9] = 76, -+ [0][0][2][0][RTW89_IC][9] = 74, -+ [0][0][2][0][RTW89_KCC][9] = 76, -+ [0][0][2][0][RTW89_ACMA][9] = 60, -+ [0][0][2][0][RTW89_CN][9] = 60, -+ [0][0][2][0][RTW89_UK][9] = 60, -+ [0][0][2][0][RTW89_FCC][10] = 74, -+ [0][0][2][0][RTW89_ETSI][10] = 60, -+ [0][0][2][0][RTW89_MKK][10] = 76, -+ [0][0][2][0][RTW89_IC][10] = 74, -+ [0][0][2][0][RTW89_KCC][10] = 76, -+ [0][0][2][0][RTW89_ACMA][10] = 60, -+ [0][0][2][0][RTW89_CN][10] = 60, -+ [0][0][2][0][RTW89_UK][10] = 60, -+ [0][0][2][0][RTW89_FCC][11] = 68, -+ [0][0][2][0][RTW89_ETSI][11] = 60, -+ [0][0][2][0][RTW89_MKK][11] = 76, -+ [0][0][2][0][RTW89_IC][11] = 68, -+ [0][0][2][0][RTW89_KCC][11] = 76, -+ [0][0][2][0][RTW89_ACMA][11] = 60, -+ [0][0][2][0][RTW89_CN][11] = 60, -+ [0][0][2][0][RTW89_UK][11] = 60, -+ [0][0][2][0][RTW89_FCC][12] = 68, -+ [0][0][2][0][RTW89_ETSI][12] = 60, -+ [0][0][2][0][RTW89_MKK][12] = 70, -+ [0][0][2][0][RTW89_IC][12] = 68, -+ [0][0][2][0][RTW89_KCC][12] = 76, -+ [0][0][2][0][RTW89_ACMA][12] = 60, -+ [0][0][2][0][RTW89_CN][12] = 60, -+ [0][0][2][0][RTW89_UK][12] = 60, -+ [0][0][2][0][RTW89_FCC][13] = 127, -+ [0][0][2][0][RTW89_ETSI][13] = 127, -+ [0][0][2][0][RTW89_MKK][13] = 127, -+ [0][0][2][0][RTW89_IC][13] = 127, -+ [0][0][2][0][RTW89_KCC][13] = 127, -+ [0][0][2][0][RTW89_ACMA][13] = 127, -+ [0][0][2][0][RTW89_CN][13] = 127, -+ [0][0][2][0][RTW89_UK][13] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 127, -+ [0][1][2][0][RTW89_ETSI][0] = 127, -+ [0][1][2][0][RTW89_MKK][0] = 127, -+ [0][1][2][0][RTW89_IC][0] = 127, -+ [0][1][2][0][RTW89_KCC][0] = 127, -+ [0][1][2][0][RTW89_ACMA][0] = 127, -+ [0][1][2][0][RTW89_CN][0] = 127, -+ [0][1][2][0][RTW89_UK][0] = 127, -+ [0][1][2][0][RTW89_FCC][1] = 127, -+ [0][1][2][0][RTW89_ETSI][1] = 127, -+ [0][1][2][0][RTW89_MKK][1] = 127, -+ [0][1][2][0][RTW89_IC][1] = 127, -+ [0][1][2][0][RTW89_KCC][1] = 127, -+ [0][1][2][0][RTW89_ACMA][1] = 127, -+ [0][1][2][0][RTW89_CN][1] = 127, -+ [0][1][2][0][RTW89_UK][1] = 127, -+ [0][1][2][0][RTW89_FCC][2] = 127, -+ [0][1][2][0][RTW89_ETSI][2] = 127, -+ [0][1][2][0][RTW89_MKK][2] = 127, -+ [0][1][2][0][RTW89_IC][2] = 127, -+ [0][1][2][0][RTW89_KCC][2] = 127, -+ [0][1][2][0][RTW89_ACMA][2] = 127, -+ [0][1][2][0][RTW89_CN][2] = 127, -+ [0][1][2][0][RTW89_UK][2] = 127, -+ [0][1][2][0][RTW89_FCC][3] = 127, -+ [0][1][2][0][RTW89_ETSI][3] = 127, -+ [0][1][2][0][RTW89_MKK][3] = 127, -+ [0][1][2][0][RTW89_IC][3] = 127, -+ [0][1][2][0][RTW89_KCC][3] = 127, -+ [0][1][2][0][RTW89_ACMA][3] = 127, -+ [0][1][2][0][RTW89_CN][3] = 127, -+ [0][1][2][0][RTW89_UK][3] = 127, -+ [0][1][2][0][RTW89_FCC][4] = 127, -+ [0][1][2][0][RTW89_ETSI][4] = 127, -+ [0][1][2][0][RTW89_MKK][4] = 127, -+ [0][1][2][0][RTW89_IC][4] = 127, -+ [0][1][2][0][RTW89_KCC][4] = 127, -+ [0][1][2][0][RTW89_ACMA][4] = 127, -+ [0][1][2][0][RTW89_CN][4] = 127, -+ [0][1][2][0][RTW89_UK][4] = 127, -+ [0][1][2][0][RTW89_FCC][5] = 127, -+ [0][1][2][0][RTW89_ETSI][5] = 127, -+ [0][1][2][0][RTW89_MKK][5] = 127, -+ [0][1][2][0][RTW89_IC][5] = 127, -+ [0][1][2][0][RTW89_KCC][5] = 127, -+ [0][1][2][0][RTW89_ACMA][5] = 127, -+ [0][1][2][0][RTW89_CN][5] = 127, -+ [0][1][2][0][RTW89_UK][5] = 127, -+ [0][1][2][0][RTW89_FCC][6] = 127, -+ [0][1][2][0][RTW89_ETSI][6] = 127, -+ [0][1][2][0][RTW89_MKK][6] = 127, -+ [0][1][2][0][RTW89_IC][6] = 127, -+ [0][1][2][0][RTW89_KCC][6] = 127, -+ [0][1][2][0][RTW89_ACMA][6] = 127, -+ [0][1][2][0][RTW89_CN][6] = 127, -+ [0][1][2][0][RTW89_UK][6] = 127, -+ [0][1][2][0][RTW89_FCC][7] = 127, -+ [0][1][2][0][RTW89_ETSI][7] = 127, -+ [0][1][2][0][RTW89_MKK][7] = 127, -+ [0][1][2][0][RTW89_IC][7] = 127, -+ [0][1][2][0][RTW89_KCC][7] = 127, -+ [0][1][2][0][RTW89_ACMA][7] = 127, -+ [0][1][2][0][RTW89_CN][7] = 127, -+ [0][1][2][0][RTW89_UK][7] = 127, -+ [0][1][2][0][RTW89_FCC][8] = 127, -+ [0][1][2][0][RTW89_ETSI][8] = 127, -+ [0][1][2][0][RTW89_MKK][8] = 127, -+ [0][1][2][0][RTW89_IC][8] = 127, -+ [0][1][2][0][RTW89_KCC][8] = 127, -+ [0][1][2][0][RTW89_ACMA][8] = 127, -+ [0][1][2][0][RTW89_CN][8] = 127, -+ [0][1][2][0][RTW89_UK][8] = 127, -+ [0][1][2][0][RTW89_FCC][9] = 127, -+ [0][1][2][0][RTW89_ETSI][9] = 127, -+ [0][1][2][0][RTW89_MKK][9] = 127, -+ [0][1][2][0][RTW89_IC][9] = 127, -+ [0][1][2][0][RTW89_KCC][9] = 127, -+ [0][1][2][0][RTW89_ACMA][9] = 127, -+ [0][1][2][0][RTW89_CN][9] = 127, -+ [0][1][2][0][RTW89_UK][9] = 127, -+ [0][1][2][0][RTW89_FCC][10] = 127, -+ [0][1][2][0][RTW89_ETSI][10] = 127, -+ [0][1][2][0][RTW89_MKK][10] = 127, -+ [0][1][2][0][RTW89_IC][10] = 127, -+ [0][1][2][0][RTW89_KCC][10] = 127, -+ [0][1][2][0][RTW89_ACMA][10] = 127, -+ [0][1][2][0][RTW89_CN][10] = 127, -+ [0][1][2][0][RTW89_UK][10] = 127, -+ [0][1][2][0][RTW89_FCC][11] = 127, -+ [0][1][2][0][RTW89_ETSI][11] = 127, -+ [0][1][2][0][RTW89_MKK][11] = 127, -+ [0][1][2][0][RTW89_IC][11] = 127, -+ [0][1][2][0][RTW89_KCC][11] = 127, -+ [0][1][2][0][RTW89_ACMA][11] = 127, -+ [0][1][2][0][RTW89_CN][11] = 127, -+ [0][1][2][0][RTW89_UK][11] = 127, -+ [0][1][2][0][RTW89_FCC][12] = 127, -+ [0][1][2][0][RTW89_ETSI][12] = 127, -+ [0][1][2][0][RTW89_MKK][12] = 127, -+ [0][1][2][0][RTW89_IC][12] = 127, -+ [0][1][2][0][RTW89_KCC][12] = 127, -+ [0][1][2][0][RTW89_ACMA][12] = 127, -+ [0][1][2][0][RTW89_CN][12] = 127, -+ [0][1][2][0][RTW89_UK][12] = 127, -+ [0][1][2][0][RTW89_FCC][13] = 127, -+ [0][1][2][0][RTW89_ETSI][13] = 127, -+ [0][1][2][0][RTW89_MKK][13] = 127, -+ [0][1][2][0][RTW89_IC][13] = 127, -+ [0][1][2][0][RTW89_KCC][13] = 127, -+ [0][1][2][0][RTW89_ACMA][13] = 127, -+ [0][1][2][0][RTW89_CN][13] = 127, -+ [0][1][2][0][RTW89_UK][13] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 127, -+ [0][1][2][1][RTW89_ETSI][0] = 127, -+ [0][1][2][1][RTW89_MKK][0] = 127, -+ [0][1][2][1][RTW89_IC][0] = 127, -+ [0][1][2][1][RTW89_KCC][0] = 127, -+ [0][1][2][1][RTW89_ACMA][0] = 127, -+ [0][1][2][1][RTW89_CN][0] = 127, -+ [0][1][2][1][RTW89_UK][0] = 127, -+ [0][1][2][1][RTW89_FCC][1] = 127, -+ [0][1][2][1][RTW89_ETSI][1] = 127, -+ [0][1][2][1][RTW89_MKK][1] = 127, -+ [0][1][2][1][RTW89_IC][1] = 127, -+ [0][1][2][1][RTW89_KCC][1] = 127, -+ [0][1][2][1][RTW89_ACMA][1] = 127, -+ [0][1][2][1][RTW89_CN][1] = 127, -+ [0][1][2][1][RTW89_UK][1] = 127, -+ [0][1][2][1][RTW89_FCC][2] = 127, -+ [0][1][2][1][RTW89_ETSI][2] = 127, -+ [0][1][2][1][RTW89_MKK][2] = 127, -+ [0][1][2][1][RTW89_IC][2] = 127, -+ [0][1][2][1][RTW89_KCC][2] = 127, -+ [0][1][2][1][RTW89_ACMA][2] = 127, -+ [0][1][2][1][RTW89_CN][2] = 127, -+ [0][1][2][1][RTW89_UK][2] = 127, -+ [0][1][2][1][RTW89_FCC][3] = 127, -+ [0][1][2][1][RTW89_ETSI][3] = 127, -+ [0][1][2][1][RTW89_MKK][3] = 127, -+ [0][1][2][1][RTW89_IC][3] = 127, -+ [0][1][2][1][RTW89_KCC][3] = 127, -+ [0][1][2][1][RTW89_ACMA][3] = 127, -+ [0][1][2][1][RTW89_CN][3] = 127, -+ [0][1][2][1][RTW89_UK][3] = 127, -+ [0][1][2][1][RTW89_FCC][4] = 127, -+ [0][1][2][1][RTW89_ETSI][4] = 127, -+ [0][1][2][1][RTW89_MKK][4] = 127, -+ [0][1][2][1][RTW89_IC][4] = 127, -+ [0][1][2][1][RTW89_KCC][4] = 127, -+ [0][1][2][1][RTW89_ACMA][4] = 127, -+ [0][1][2][1][RTW89_CN][4] = 127, -+ [0][1][2][1][RTW89_UK][4] = 127, -+ [0][1][2][1][RTW89_FCC][5] = 127, -+ [0][1][2][1][RTW89_ETSI][5] = 127, -+ [0][1][2][1][RTW89_MKK][5] = 127, -+ [0][1][2][1][RTW89_IC][5] = 127, -+ [0][1][2][1][RTW89_KCC][5] = 127, -+ [0][1][2][1][RTW89_ACMA][5] = 127, -+ [0][1][2][1][RTW89_CN][5] = 127, -+ [0][1][2][1][RTW89_UK][5] = 127, -+ [0][1][2][1][RTW89_FCC][6] = 127, -+ [0][1][2][1][RTW89_ETSI][6] = 127, -+ [0][1][2][1][RTW89_MKK][6] = 127, -+ [0][1][2][1][RTW89_IC][6] = 127, -+ [0][1][2][1][RTW89_KCC][6] = 127, -+ [0][1][2][1][RTW89_ACMA][6] = 127, -+ [0][1][2][1][RTW89_CN][6] = 127, -+ [0][1][2][1][RTW89_UK][6] = 127, -+ [0][1][2][1][RTW89_FCC][7] = 127, -+ [0][1][2][1][RTW89_ETSI][7] = 127, -+ [0][1][2][1][RTW89_MKK][7] = 127, -+ [0][1][2][1][RTW89_IC][7] = 127, -+ [0][1][2][1][RTW89_KCC][7] = 127, -+ [0][1][2][1][RTW89_ACMA][7] = 127, -+ [0][1][2][1][RTW89_CN][7] = 127, -+ [0][1][2][1][RTW89_UK][7] = 127, -+ [0][1][2][1][RTW89_FCC][8] = 127, -+ [0][1][2][1][RTW89_ETSI][8] = 127, -+ [0][1][2][1][RTW89_MKK][8] = 127, -+ [0][1][2][1][RTW89_IC][8] = 127, -+ [0][1][2][1][RTW89_KCC][8] = 127, -+ [0][1][2][1][RTW89_ACMA][8] = 127, -+ [0][1][2][1][RTW89_CN][8] = 127, -+ [0][1][2][1][RTW89_UK][8] = 127, -+ [0][1][2][1][RTW89_FCC][9] = 127, -+ [0][1][2][1][RTW89_ETSI][9] = 127, -+ [0][1][2][1][RTW89_MKK][9] = 127, -+ [0][1][2][1][RTW89_IC][9] = 127, -+ [0][1][2][1][RTW89_KCC][9] = 127, -+ [0][1][2][1][RTW89_ACMA][9] = 127, -+ [0][1][2][1][RTW89_CN][9] = 127, -+ [0][1][2][1][RTW89_UK][9] = 127, -+ [0][1][2][1][RTW89_FCC][10] = 127, -+ [0][1][2][1][RTW89_ETSI][10] = 127, -+ [0][1][2][1][RTW89_MKK][10] = 127, -+ [0][1][2][1][RTW89_IC][10] = 127, -+ [0][1][2][1][RTW89_KCC][10] = 127, -+ [0][1][2][1][RTW89_ACMA][10] = 127, -+ [0][1][2][1][RTW89_CN][10] = 127, -+ [0][1][2][1][RTW89_UK][10] = 127, -+ [0][1][2][1][RTW89_FCC][11] = 127, -+ [0][1][2][1][RTW89_ETSI][11] = 127, -+ [0][1][2][1][RTW89_MKK][11] = 127, -+ [0][1][2][1][RTW89_IC][11] = 127, -+ [0][1][2][1][RTW89_KCC][11] = 127, -+ [0][1][2][1][RTW89_ACMA][11] = 127, -+ [0][1][2][1][RTW89_CN][11] = 127, -+ [0][1][2][1][RTW89_UK][11] = 127, -+ [0][1][2][1][RTW89_FCC][12] = 127, -+ [0][1][2][1][RTW89_ETSI][12] = 127, -+ [0][1][2][1][RTW89_MKK][12] = 127, -+ [0][1][2][1][RTW89_IC][12] = 127, -+ [0][1][2][1][RTW89_KCC][12] = 127, -+ [0][1][2][1][RTW89_ACMA][12] = 127, -+ [0][1][2][1][RTW89_CN][12] = 127, -+ [0][1][2][1][RTW89_UK][12] = 127, -+ [0][1][2][1][RTW89_FCC][13] = 127, -+ [0][1][2][1][RTW89_ETSI][13] = 127, -+ [0][1][2][1][RTW89_MKK][13] = 127, -+ [0][1][2][1][RTW89_IC][13] = 127, -+ [0][1][2][1][RTW89_KCC][13] = 127, -+ [0][1][2][1][RTW89_ACMA][13] = 127, -+ [0][1][2][1][RTW89_CN][13] = 127, -+ [0][1][2][1][RTW89_UK][13] = 127, -+ [1][0][2][0][RTW89_FCC][0] = 127, -+ [1][0][2][0][RTW89_ETSI][0] = 127, -+ [1][0][2][0][RTW89_MKK][0] = 127, -+ [1][0][2][0][RTW89_IC][0] = 127, -+ [1][0][2][0][RTW89_KCC][0] = 127, -+ [1][0][2][0][RTW89_ACMA][0] = 127, -+ [1][0][2][0][RTW89_CN][0] = 127, -+ [1][0][2][0][RTW89_UK][0] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 127, -+ [1][0][2][0][RTW89_ETSI][1] = 127, -+ [1][0][2][0][RTW89_MKK][1] = 127, -+ [1][0][2][0][RTW89_IC][1] = 127, -+ [1][0][2][0][RTW89_KCC][1] = 127, -+ [1][0][2][0][RTW89_ACMA][1] = 127, -+ [1][0][2][0][RTW89_CN][1] = 127, -+ [1][0][2][0][RTW89_UK][1] = 127, -+ [1][0][2][0][RTW89_FCC][2] = 70, -+ [1][0][2][0][RTW89_ETSI][2] = 58, -+ [1][0][2][0][RTW89_MKK][2] = 76, -+ [1][0][2][0][RTW89_IC][2] = 70, -+ [1][0][2][0][RTW89_KCC][2] = 76, -+ [1][0][2][0][RTW89_ACMA][2] = 58, -+ [1][0][2][0][RTW89_CN][2] = 60, -+ [1][0][2][0][RTW89_UK][2] = 58, -+ [1][0][2][0][RTW89_FCC][3] = 70, -+ [1][0][2][0][RTW89_ETSI][3] = 58, -+ [1][0][2][0][RTW89_MKK][3] = 76, -+ [1][0][2][0][RTW89_IC][3] = 70, -+ [1][0][2][0][RTW89_KCC][3] = 76, -+ [1][0][2][0][RTW89_ACMA][3] = 58, -+ [1][0][2][0][RTW89_CN][3] = 60, -+ [1][0][2][0][RTW89_UK][3] = 58, -+ [1][0][2][0][RTW89_FCC][4] = 74, -+ [1][0][2][0][RTW89_ETSI][4] = 58, -+ [1][0][2][0][RTW89_MKK][4] = 76, -+ [1][0][2][0][RTW89_IC][4] = 74, -+ [1][0][2][0][RTW89_KCC][4] = 76, -+ [1][0][2][0][RTW89_ACMA][4] = 58, -+ [1][0][2][0][RTW89_CN][4] = 60, -+ [1][0][2][0][RTW89_UK][4] = 58, -+ [1][0][2][0][RTW89_FCC][5] = 76, -+ [1][0][2][0][RTW89_ETSI][5] = 58, -+ [1][0][2][0][RTW89_MKK][5] = 76, -+ [1][0][2][0][RTW89_IC][5] = 76, -+ [1][0][2][0][RTW89_KCC][5] = 76, -+ [1][0][2][0][RTW89_ACMA][5] = 58, -+ [1][0][2][0][RTW89_CN][5] = 60, -+ [1][0][2][0][RTW89_UK][5] = 58, -+ [1][0][2][0][RTW89_FCC][6] = 76, -+ [1][0][2][0][RTW89_ETSI][6] = 58, -+ [1][0][2][0][RTW89_MKK][6] = 76, -+ [1][0][2][0][RTW89_IC][6] = 76, -+ [1][0][2][0][RTW89_KCC][6] = 76, -+ [1][0][2][0][RTW89_ACMA][6] = 58, -+ [1][0][2][0][RTW89_CN][6] = 60, -+ [1][0][2][0][RTW89_UK][6] = 58, -+ [1][0][2][0][RTW89_FCC][7] = 76, -+ [1][0][2][0][RTW89_ETSI][7] = 58, -+ [1][0][2][0][RTW89_MKK][7] = 76, -+ [1][0][2][0][RTW89_IC][7] = 76, -+ [1][0][2][0][RTW89_KCC][7] = 76, -+ [1][0][2][0][RTW89_ACMA][7] = 58, -+ [1][0][2][0][RTW89_CN][7] = 60, -+ [1][0][2][0][RTW89_UK][7] = 58, -+ [1][0][2][0][RTW89_FCC][8] = 78, -+ [1][0][2][0][RTW89_ETSI][8] = 58, -+ [1][0][2][0][RTW89_MKK][8] = 76, -+ [1][0][2][0][RTW89_IC][8] = 78, -+ [1][0][2][0][RTW89_KCC][8] = 76, -+ [1][0][2][0][RTW89_ACMA][8] = 58, -+ [1][0][2][0][RTW89_CN][8] = 60, -+ [1][0][2][0][RTW89_UK][8] = 58, -+ [1][0][2][0][RTW89_FCC][9] = 74, -+ [1][0][2][0][RTW89_ETSI][9] = 58, -+ [1][0][2][0][RTW89_MKK][9] = 76, -+ [1][0][2][0][RTW89_IC][9] = 74, -+ [1][0][2][0][RTW89_KCC][9] = 76, -+ [1][0][2][0][RTW89_ACMA][9] = 58, -+ [1][0][2][0][RTW89_CN][9] = 60, -+ [1][0][2][0][RTW89_UK][9] = 58, -+ [1][0][2][0][RTW89_FCC][10] = 68, -+ [1][0][2][0][RTW89_ETSI][10] = 58, -+ [1][0][2][0][RTW89_MKK][10] = 76, -+ [1][0][2][0][RTW89_IC][10] = 68, -+ [1][0][2][0][RTW89_KCC][10] = 76, -+ [1][0][2][0][RTW89_ACMA][10] = 58, -+ [1][0][2][0][RTW89_CN][10] = 60, -+ [1][0][2][0][RTW89_UK][10] = 58, -+ [1][0][2][0][RTW89_FCC][11] = 127, -+ [1][0][2][0][RTW89_ETSI][11] = 127, -+ [1][0][2][0][RTW89_MKK][11] = 127, -+ [1][0][2][0][RTW89_IC][11] = 127, -+ [1][0][2][0][RTW89_KCC][11] = 127, -+ [1][0][2][0][RTW89_ACMA][11] = 127, -+ [1][0][2][0][RTW89_CN][11] = 127, -+ [1][0][2][0][RTW89_UK][11] = 127, -+ [1][0][2][0][RTW89_FCC][12] = 127, -+ [1][0][2][0][RTW89_ETSI][12] = 127, -+ [1][0][2][0][RTW89_MKK][12] = 127, -+ [1][0][2][0][RTW89_IC][12] = 127, -+ [1][0][2][0][RTW89_KCC][12] = 127, -+ [1][0][2][0][RTW89_ACMA][12] = 127, -+ [1][0][2][0][RTW89_CN][12] = 127, -+ [1][0][2][0][RTW89_UK][12] = 127, -+ [1][0][2][0][RTW89_FCC][13] = 127, -+ [1][0][2][0][RTW89_ETSI][13] = 127, -+ [1][0][2][0][RTW89_MKK][13] = 127, -+ [1][0][2][0][RTW89_IC][13] = 127, -+ [1][0][2][0][RTW89_KCC][13] = 127, -+ [1][0][2][0][RTW89_ACMA][13] = 127, -+ [1][0][2][0][RTW89_CN][13] = 127, -+ [1][0][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_FCC][0] = 127, -+ [1][1][2][0][RTW89_ETSI][0] = 127, -+ [1][1][2][0][RTW89_MKK][0] = 127, -+ [1][1][2][0][RTW89_IC][0] = 127, -+ [1][1][2][0][RTW89_KCC][0] = 127, -+ [1][1][2][0][RTW89_ACMA][0] = 127, -+ [1][1][2][0][RTW89_CN][0] = 127, -+ [1][1][2][0][RTW89_UK][0] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 127, -+ [1][1][2][0][RTW89_ETSI][1] = 127, -+ [1][1][2][0][RTW89_MKK][1] = 127, -+ [1][1][2][0][RTW89_IC][1] = 127, -+ [1][1][2][0][RTW89_KCC][1] = 127, -+ [1][1][2][0][RTW89_ACMA][1] = 127, -+ [1][1][2][0][RTW89_CN][1] = 127, -+ [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_FCC][2] = 127, -+ [1][1][2][0][RTW89_ETSI][2] = 127, -+ [1][1][2][0][RTW89_MKK][2] = 127, -+ [1][1][2][0][RTW89_IC][2] = 127, -+ [1][1][2][0][RTW89_KCC][2] = 127, -+ [1][1][2][0][RTW89_ACMA][2] = 127, -+ [1][1][2][0][RTW89_CN][2] = 127, -+ [1][1][2][0][RTW89_UK][2] = 127, -+ [1][1][2][0][RTW89_FCC][3] = 127, -+ [1][1][2][0][RTW89_ETSI][3] = 127, -+ [1][1][2][0][RTW89_MKK][3] = 127, -+ [1][1][2][0][RTW89_IC][3] = 127, -+ [1][1][2][0][RTW89_KCC][3] = 127, -+ [1][1][2][0][RTW89_ACMA][3] = 127, -+ [1][1][2][0][RTW89_CN][3] = 127, -+ [1][1][2][0][RTW89_UK][3] = 127, -+ [1][1][2][0][RTW89_FCC][4] = 127, -+ [1][1][2][0][RTW89_ETSI][4] = 127, -+ [1][1][2][0][RTW89_MKK][4] = 127, -+ [1][1][2][0][RTW89_IC][4] = 127, -+ [1][1][2][0][RTW89_KCC][4] = 127, -+ [1][1][2][0][RTW89_ACMA][4] = 127, -+ [1][1][2][0][RTW89_CN][4] = 127, -+ [1][1][2][0][RTW89_UK][4] = 127, -+ [1][1][2][0][RTW89_FCC][5] = 127, -+ [1][1][2][0][RTW89_ETSI][5] = 127, -+ [1][1][2][0][RTW89_MKK][5] = 127, -+ [1][1][2][0][RTW89_IC][5] = 127, -+ [1][1][2][0][RTW89_KCC][5] = 127, -+ [1][1][2][0][RTW89_ACMA][5] = 127, -+ [1][1][2][0][RTW89_CN][5] = 127, -+ [1][1][2][0][RTW89_UK][5] = 127, -+ [1][1][2][0][RTW89_FCC][6] = 127, -+ [1][1][2][0][RTW89_ETSI][6] = 127, -+ [1][1][2][0][RTW89_MKK][6] = 127, -+ [1][1][2][0][RTW89_IC][6] = 127, -+ [1][1][2][0][RTW89_KCC][6] = 127, -+ [1][1][2][0][RTW89_ACMA][6] = 127, -+ [1][1][2][0][RTW89_CN][6] = 127, -+ [1][1][2][0][RTW89_UK][6] = 127, -+ [1][1][2][0][RTW89_FCC][7] = 127, -+ [1][1][2][0][RTW89_ETSI][7] = 127, -+ [1][1][2][0][RTW89_MKK][7] = 127, -+ [1][1][2][0][RTW89_IC][7] = 127, -+ [1][1][2][0][RTW89_KCC][7] = 127, -+ [1][1][2][0][RTW89_ACMA][7] = 127, -+ [1][1][2][0][RTW89_CN][7] = 127, -+ [1][1][2][0][RTW89_UK][7] = 127, -+ [1][1][2][0][RTW89_FCC][8] = 127, -+ [1][1][2][0][RTW89_ETSI][8] = 127, -+ [1][1][2][0][RTW89_MKK][8] = 127, -+ [1][1][2][0][RTW89_IC][8] = 127, -+ [1][1][2][0][RTW89_KCC][8] = 127, -+ [1][1][2][0][RTW89_ACMA][8] = 127, -+ [1][1][2][0][RTW89_CN][8] = 127, -+ [1][1][2][0][RTW89_UK][8] = 127, -+ [1][1][2][0][RTW89_FCC][9] = 127, -+ [1][1][2][0][RTW89_ETSI][9] = 127, -+ [1][1][2][0][RTW89_MKK][9] = 127, -+ [1][1][2][0][RTW89_IC][9] = 127, -+ [1][1][2][0][RTW89_KCC][9] = 127, -+ [1][1][2][0][RTW89_ACMA][9] = 127, -+ [1][1][2][0][RTW89_CN][9] = 127, -+ [1][1][2][0][RTW89_UK][9] = 127, -+ [1][1][2][0][RTW89_FCC][10] = 127, -+ [1][1][2][0][RTW89_ETSI][10] = 127, -+ [1][1][2][0][RTW89_MKK][10] = 127, -+ [1][1][2][0][RTW89_IC][10] = 127, -+ [1][1][2][0][RTW89_KCC][10] = 127, -+ [1][1][2][0][RTW89_ACMA][10] = 127, -+ [1][1][2][0][RTW89_CN][10] = 127, -+ [1][1][2][0][RTW89_UK][10] = 127, -+ [1][1][2][0][RTW89_FCC][11] = 127, -+ [1][1][2][0][RTW89_ETSI][11] = 127, -+ [1][1][2][0][RTW89_MKK][11] = 127, -+ [1][1][2][0][RTW89_IC][11] = 127, -+ [1][1][2][0][RTW89_KCC][11] = 127, -+ [1][1][2][0][RTW89_ACMA][11] = 127, -+ [1][1][2][0][RTW89_CN][11] = 127, -+ [1][1][2][0][RTW89_UK][11] = 127, -+ [1][1][2][0][RTW89_FCC][12] = 127, -+ [1][1][2][0][RTW89_ETSI][12] = 127, -+ [1][1][2][0][RTW89_MKK][12] = 127, -+ [1][1][2][0][RTW89_IC][12] = 127, -+ [1][1][2][0][RTW89_KCC][12] = 127, -+ [1][1][2][0][RTW89_ACMA][12] = 127, -+ [1][1][2][0][RTW89_CN][12] = 127, -+ [1][1][2][0][RTW89_UK][12] = 127, -+ [1][1][2][0][RTW89_FCC][13] = 127, -+ [1][1][2][0][RTW89_ETSI][13] = 127, -+ [1][1][2][0][RTW89_MKK][13] = 127, -+ [1][1][2][0][RTW89_IC][13] = 127, -+ [1][1][2][0][RTW89_KCC][13] = 127, -+ [1][1][2][0][RTW89_ACMA][13] = 127, -+ [1][1][2][0][RTW89_CN][13] = 127, -+ [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_FCC][0] = 127, -+ [1][1][2][1][RTW89_ETSI][0] = 127, -+ [1][1][2][1][RTW89_MKK][0] = 127, -+ [1][1][2][1][RTW89_IC][0] = 127, -+ [1][1][2][1][RTW89_KCC][0] = 127, -+ [1][1][2][1][RTW89_ACMA][0] = 127, -+ [1][1][2][1][RTW89_CN][0] = 127, -+ [1][1][2][1][RTW89_UK][0] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 127, -+ [1][1][2][1][RTW89_ETSI][1] = 127, -+ [1][1][2][1][RTW89_MKK][1] = 127, -+ [1][1][2][1][RTW89_IC][1] = 127, -+ [1][1][2][1][RTW89_KCC][1] = 127, -+ [1][1][2][1][RTW89_ACMA][1] = 127, -+ [1][1][2][1][RTW89_CN][1] = 127, -+ [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_FCC][2] = 127, -+ [1][1][2][1][RTW89_ETSI][2] = 127, -+ [1][1][2][1][RTW89_MKK][2] = 127, -+ [1][1][2][1][RTW89_IC][2] = 127, -+ [1][1][2][1][RTW89_KCC][2] = 127, -+ [1][1][2][1][RTW89_ACMA][2] = 127, -+ [1][1][2][1][RTW89_CN][2] = 127, -+ [1][1][2][1][RTW89_UK][2] = 127, -+ [1][1][2][1][RTW89_FCC][3] = 127, -+ [1][1][2][1][RTW89_ETSI][3] = 127, -+ [1][1][2][1][RTW89_MKK][3] = 127, -+ [1][1][2][1][RTW89_IC][3] = 127, -+ [1][1][2][1][RTW89_KCC][3] = 127, -+ [1][1][2][1][RTW89_ACMA][3] = 127, -+ [1][1][2][1][RTW89_CN][3] = 127, -+ [1][1][2][1][RTW89_UK][3] = 127, -+ [1][1][2][1][RTW89_FCC][4] = 127, -+ [1][1][2][1][RTW89_ETSI][4] = 127, -+ [1][1][2][1][RTW89_MKK][4] = 127, -+ [1][1][2][1][RTW89_IC][4] = 127, -+ [1][1][2][1][RTW89_KCC][4] = 127, -+ [1][1][2][1][RTW89_ACMA][4] = 127, -+ [1][1][2][1][RTW89_CN][4] = 127, -+ [1][1][2][1][RTW89_UK][4] = 127, -+ [1][1][2][1][RTW89_FCC][5] = 127, -+ [1][1][2][1][RTW89_ETSI][5] = 127, -+ [1][1][2][1][RTW89_MKK][5] = 127, -+ [1][1][2][1][RTW89_IC][5] = 127, -+ [1][1][2][1][RTW89_KCC][5] = 127, -+ [1][1][2][1][RTW89_ACMA][5] = 127, -+ [1][1][2][1][RTW89_CN][5] = 127, -+ [1][1][2][1][RTW89_UK][5] = 127, -+ [1][1][2][1][RTW89_FCC][6] = 127, -+ [1][1][2][1][RTW89_ETSI][6] = 127, -+ [1][1][2][1][RTW89_MKK][6] = 127, -+ [1][1][2][1][RTW89_IC][6] = 127, -+ [1][1][2][1][RTW89_KCC][6] = 127, -+ [1][1][2][1][RTW89_ACMA][6] = 127, -+ [1][1][2][1][RTW89_CN][6] = 127, -+ [1][1][2][1][RTW89_UK][6] = 127, -+ [1][1][2][1][RTW89_FCC][7] = 127, -+ [1][1][2][1][RTW89_ETSI][7] = 127, -+ [1][1][2][1][RTW89_MKK][7] = 127, -+ [1][1][2][1][RTW89_IC][7] = 127, -+ [1][1][2][1][RTW89_KCC][7] = 127, -+ [1][1][2][1][RTW89_ACMA][7] = 127, -+ [1][1][2][1][RTW89_CN][7] = 127, -+ [1][1][2][1][RTW89_UK][7] = 127, -+ [1][1][2][1][RTW89_FCC][8] = 127, -+ [1][1][2][1][RTW89_ETSI][8] = 127, -+ [1][1][2][1][RTW89_MKK][8] = 127, -+ [1][1][2][1][RTW89_IC][8] = 127, -+ [1][1][2][1][RTW89_KCC][8] = 127, -+ [1][1][2][1][RTW89_ACMA][8] = 127, -+ [1][1][2][1][RTW89_CN][8] = 127, -+ [1][1][2][1][RTW89_UK][8] = 127, -+ [1][1][2][1][RTW89_FCC][9] = 127, -+ [1][1][2][1][RTW89_ETSI][9] = 127, -+ [1][1][2][1][RTW89_MKK][9] = 127, -+ [1][1][2][1][RTW89_IC][9] = 127, -+ [1][1][2][1][RTW89_KCC][9] = 127, -+ [1][1][2][1][RTW89_ACMA][9] = 127, -+ [1][1][2][1][RTW89_CN][9] = 127, -+ [1][1][2][1][RTW89_UK][9] = 127, -+ [1][1][2][1][RTW89_FCC][10] = 127, -+ [1][1][2][1][RTW89_ETSI][10] = 127, -+ [1][1][2][1][RTW89_MKK][10] = 127, -+ [1][1][2][1][RTW89_IC][10] = 127, -+ [1][1][2][1][RTW89_KCC][10] = 127, -+ [1][1][2][1][RTW89_ACMA][10] = 127, -+ [1][1][2][1][RTW89_CN][10] = 127, -+ [1][1][2][1][RTW89_UK][10] = 127, -+ [1][1][2][1][RTW89_FCC][11] = 127, -+ [1][1][2][1][RTW89_ETSI][11] = 127, -+ [1][1][2][1][RTW89_MKK][11] = 127, -+ [1][1][2][1][RTW89_IC][11] = 127, -+ [1][1][2][1][RTW89_KCC][11] = 127, -+ [1][1][2][1][RTW89_ACMA][11] = 127, -+ [1][1][2][1][RTW89_CN][11] = 127, -+ [1][1][2][1][RTW89_UK][11] = 127, -+ [1][1][2][1][RTW89_FCC][12] = 127, -+ [1][1][2][1][RTW89_ETSI][12] = 127, -+ [1][1][2][1][RTW89_MKK][12] = 127, -+ [1][1][2][1][RTW89_IC][12] = 127, -+ [1][1][2][1][RTW89_KCC][12] = 127, -+ [1][1][2][1][RTW89_ACMA][12] = 127, -+ [1][1][2][1][RTW89_CN][12] = 127, -+ [1][1][2][1][RTW89_UK][12] = 127, -+ [1][1][2][1][RTW89_FCC][13] = 127, -+ [1][1][2][1][RTW89_ETSI][13] = 127, -+ [1][1][2][1][RTW89_MKK][13] = 127, -+ [1][1][2][1][RTW89_IC][13] = 127, -+ [1][1][2][1][RTW89_KCC][13] = 127, -+ [1][1][2][1][RTW89_ACMA][13] = 127, -+ [1][1][2][1][RTW89_CN][13] = 127, -+ [1][1][2][1][RTW89_UK][13] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_5g_type2[RTW89_5G_BW_NUM][RTW89_NTX_NUM] -+ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][1][0][RTW89_WW][0] = 58, -+ [0][0][1][0][RTW89_WW][2] = 58, -+ [0][0][1][0][RTW89_WW][4] = 58, -+ [0][0][1][0][RTW89_WW][6] = 50, -+ [0][0][1][0][RTW89_WW][8] = 58, -+ [0][0][1][0][RTW89_WW][10] = 58, -+ [0][0][1][0][RTW89_WW][12] = 58, -+ [0][0][1][0][RTW89_WW][14] = 58, -+ [0][0][1][0][RTW89_WW][15] = 58, -+ [0][0][1][0][RTW89_WW][17] = 60, -+ [0][0][1][0][RTW89_WW][19] = 60, -+ [0][0][1][0][RTW89_WW][21] = 60, -+ [0][0][1][0][RTW89_WW][23] = 60, -+ [0][0][1][0][RTW89_WW][25] = 60, -+ [0][0][1][0][RTW89_WW][27] = 60, -+ [0][0][1][0][RTW89_WW][29] = 60, -+ [0][0][1][0][RTW89_WW][31] = 60, -+ [0][0][1][0][RTW89_WW][33] = 60, -+ [0][0][1][0][RTW89_WW][35] = 60, -+ [0][0][1][0][RTW89_WW][37] = 74, -+ [0][0][1][0][RTW89_WW][38] = 30, -+ [0][0][1][0][RTW89_WW][40] = 30, -+ [0][0][1][0][RTW89_WW][42] = 30, -+ [0][0][1][0][RTW89_WW][44] = 30, -+ [0][0][1][0][RTW89_WW][46] = 30, -+ [0][0][1][0][RTW89_WW][48] = 72, -+ [0][0][1][0][RTW89_WW][50] = 72, -+ [0][0][1][0][RTW89_WW][52] = 72, -+ [0][1][1][0][RTW89_WW][0] = 0, -+ [0][1][1][0][RTW89_WW][2] = 0, -+ [0][1][1][0][RTW89_WW][4] = 0, -+ [0][1][1][0][RTW89_WW][6] = 0, -+ [0][1][1][0][RTW89_WW][8] = 0, -+ [0][1][1][0][RTW89_WW][10] = 0, -+ [0][1][1][0][RTW89_WW][12] = 0, -+ [0][1][1][0][RTW89_WW][14] = 0, -+ [0][1][1][0][RTW89_WW][15] = 0, -+ [0][1][1][0][RTW89_WW][17] = 0, -+ [0][1][1][0][RTW89_WW][19] = 0, -+ [0][1][1][0][RTW89_WW][21] = 0, -+ [0][1][1][0][RTW89_WW][23] = 0, -+ [0][1][1][0][RTW89_WW][25] = 0, -+ [0][1][1][0][RTW89_WW][27] = 0, -+ [0][1][1][0][RTW89_WW][29] = 0, -+ [0][1][1][0][RTW89_WW][31] = 0, -+ [0][1][1][0][RTW89_WW][33] = 0, -+ [0][1][1][0][RTW89_WW][35] = 0, -+ [0][1][1][0][RTW89_WW][37] = 0, -+ [0][1][1][0][RTW89_WW][38] = 0, -+ [0][1][1][0][RTW89_WW][40] = 0, -+ [0][1][1][0][RTW89_WW][42] = 0, -+ [0][1][1][0][RTW89_WW][44] = 0, -+ [0][1][1][0][RTW89_WW][46] = 0, -+ [0][1][1][0][RTW89_WW][48] = 0, -+ [0][1][1][0][RTW89_WW][50] = 0, -+ [0][1][1][0][RTW89_WW][52] = 0, -+ [0][0][2][0][RTW89_WW][0] = 62, -+ [0][0][2][0][RTW89_WW][2] = 62, -+ [0][0][2][0][RTW89_WW][4] = 62, -+ [0][0][2][0][RTW89_WW][6] = 54, -+ [0][0][2][0][RTW89_WW][8] = 62, -+ [0][0][2][0][RTW89_WW][10] = 62, -+ [0][0][2][0][RTW89_WW][12] = 62, -+ [0][0][2][0][RTW89_WW][14] = 62, -+ [0][0][2][0][RTW89_WW][15] = 60, -+ [0][0][2][0][RTW89_WW][17] = 62, -+ [0][0][2][0][RTW89_WW][19] = 62, -+ [0][0][2][0][RTW89_WW][21] = 62, -+ [0][0][2][0][RTW89_WW][23] = 62, -+ [0][0][2][0][RTW89_WW][25] = 62, -+ [0][0][2][0][RTW89_WW][27] = 62, -+ [0][0][2][0][RTW89_WW][29] = 62, -+ [0][0][2][0][RTW89_WW][31] = 62, -+ [0][0][2][0][RTW89_WW][33] = 62, -+ [0][0][2][0][RTW89_WW][35] = 62, -+ [0][0][2][0][RTW89_WW][37] = 74, -+ [0][0][2][0][RTW89_WW][38] = 30, -+ [0][0][2][0][RTW89_WW][40] = 30, -+ [0][0][2][0][RTW89_WW][42] = 30, -+ [0][0][2][0][RTW89_WW][44] = 30, -+ [0][0][2][0][RTW89_WW][46] = 30, -+ [0][0][2][0][RTW89_WW][48] = 74, -+ [0][0][2][0][RTW89_WW][50] = 74, -+ [0][0][2][0][RTW89_WW][52] = 74, -+ [0][1][2][0][RTW89_WW][0] = 0, -+ [0][1][2][0][RTW89_WW][2] = 0, -+ [0][1][2][0][RTW89_WW][4] = 0, -+ [0][1][2][0][RTW89_WW][6] = 0, -+ [0][1][2][0][RTW89_WW][8] = 0, -+ [0][1][2][0][RTW89_WW][10] = 0, -+ [0][1][2][0][RTW89_WW][12] = 0, -+ [0][1][2][0][RTW89_WW][14] = 0, -+ [0][1][2][0][RTW89_WW][15] = 0, -+ [0][1][2][0][RTW89_WW][17] = 0, -+ [0][1][2][0][RTW89_WW][19] = 0, -+ [0][1][2][0][RTW89_WW][21] = 0, -+ [0][1][2][0][RTW89_WW][23] = 0, -+ [0][1][2][0][RTW89_WW][25] = 0, -+ [0][1][2][0][RTW89_WW][27] = 0, -+ [0][1][2][0][RTW89_WW][29] = 0, -+ [0][1][2][0][RTW89_WW][31] = 0, -+ [0][1][2][0][RTW89_WW][33] = 0, -+ [0][1][2][0][RTW89_WW][35] = 0, -+ [0][1][2][0][RTW89_WW][37] = 0, -+ [0][1][2][0][RTW89_WW][38] = 0, -+ [0][1][2][0][RTW89_WW][40] = 0, -+ [0][1][2][0][RTW89_WW][42] = 0, -+ [0][1][2][0][RTW89_WW][44] = 0, -+ [0][1][2][0][RTW89_WW][46] = 0, -+ [0][1][2][0][RTW89_WW][48] = 0, -+ [0][1][2][0][RTW89_WW][50] = 0, -+ [0][1][2][0][RTW89_WW][52] = 0, -+ [0][1][2][1][RTW89_WW][0] = 0, -+ [0][1][2][1][RTW89_WW][2] = 0, -+ [0][1][2][1][RTW89_WW][4] = 0, -+ [0][1][2][1][RTW89_WW][6] = 0, -+ [0][1][2][1][RTW89_WW][8] = 0, -+ [0][1][2][1][RTW89_WW][10] = 0, -+ [0][1][2][1][RTW89_WW][12] = 0, -+ [0][1][2][1][RTW89_WW][14] = 0, -+ [0][1][2][1][RTW89_WW][15] = 0, -+ [0][1][2][1][RTW89_WW][17] = 0, -+ [0][1][2][1][RTW89_WW][19] = 0, -+ [0][1][2][1][RTW89_WW][21] = 0, -+ [0][1][2][1][RTW89_WW][23] = 0, -+ [0][1][2][1][RTW89_WW][25] = 0, -+ [0][1][2][1][RTW89_WW][27] = 0, -+ [0][1][2][1][RTW89_WW][29] = 0, -+ [0][1][2][1][RTW89_WW][31] = 0, -+ [0][1][2][1][RTW89_WW][33] = 0, -+ [0][1][2][1][RTW89_WW][35] = 0, -+ [0][1][2][1][RTW89_WW][37] = 0, -+ [0][1][2][1][RTW89_WW][38] = 0, -+ [0][1][2][1][RTW89_WW][40] = 0, -+ [0][1][2][1][RTW89_WW][42] = 0, -+ [0][1][2][1][RTW89_WW][44] = 0, -+ [0][1][2][1][RTW89_WW][46] = 0, -+ [0][1][2][1][RTW89_WW][48] = 0, -+ [0][1][2][1][RTW89_WW][50] = 0, -+ [0][1][2][1][RTW89_WW][52] = 0, -+ [1][0][2][0][RTW89_WW][1] = 64, -+ [1][0][2][0][RTW89_WW][5] = 62, -+ [1][0][2][0][RTW89_WW][9] = 64, -+ [1][0][2][0][RTW89_WW][13] = 64, -+ [1][0][2][0][RTW89_WW][16] = 66, -+ [1][0][2][0][RTW89_WW][20] = 66, -+ [1][0][2][0][RTW89_WW][24] = 66, -+ [1][0][2][0][RTW89_WW][28] = 66, -+ [1][0][2][0][RTW89_WW][32] = 66, -+ [1][0][2][0][RTW89_WW][36] = 76, -+ [1][0][2][0][RTW89_WW][39] = 30, -+ [1][0][2][0][RTW89_WW][43] = 30, -+ [1][0][2][0][RTW89_WW][47] = 80, -+ [1][0][2][0][RTW89_WW][51] = 80, -+ [1][1][2][0][RTW89_WW][1] = 0, -+ [1][1][2][0][RTW89_WW][5] = 0, -+ [1][1][2][0][RTW89_WW][9] = 0, -+ [1][1][2][0][RTW89_WW][13] = 0, -+ [1][1][2][0][RTW89_WW][16] = 0, -+ [1][1][2][0][RTW89_WW][20] = 0, -+ [1][1][2][0][RTW89_WW][24] = 0, -+ [1][1][2][0][RTW89_WW][28] = 0, -+ [1][1][2][0][RTW89_WW][32] = 0, -+ [1][1][2][0][RTW89_WW][36] = 0, -+ [1][1][2][0][RTW89_WW][39] = 0, -+ [1][1][2][0][RTW89_WW][43] = 0, -+ [1][1][2][0][RTW89_WW][47] = 0, -+ [1][1][2][0][RTW89_WW][51] = 0, -+ [1][1][2][1][RTW89_WW][1] = 0, -+ [1][1][2][1][RTW89_WW][5] = 0, -+ [1][1][2][1][RTW89_WW][9] = 0, -+ [1][1][2][1][RTW89_WW][13] = 0, -+ [1][1][2][1][RTW89_WW][16] = 0, -+ [1][1][2][1][RTW89_WW][20] = 0, -+ [1][1][2][1][RTW89_WW][24] = 0, -+ [1][1][2][1][RTW89_WW][28] = 0, -+ [1][1][2][1][RTW89_WW][32] = 0, -+ [1][1][2][1][RTW89_WW][36] = 0, -+ [1][1][2][1][RTW89_WW][39] = 0, -+ [1][1][2][1][RTW89_WW][43] = 0, -+ [1][1][2][1][RTW89_WW][47] = 0, -+ [1][1][2][1][RTW89_WW][51] = 0, -+ [2][0][2][0][RTW89_WW][3] = 62, -+ [2][0][2][0][RTW89_WW][11] = 62, -+ [2][0][2][0][RTW89_WW][18] = 64, -+ [2][0][2][0][RTW89_WW][26] = 64, -+ [2][0][2][0][RTW89_WW][34] = 68, -+ [2][0][2][0][RTW89_WW][41] = 30, -+ [2][0][2][0][RTW89_WW][49] = 72, -+ [2][1][2][0][RTW89_WW][3] = 0, -+ [2][1][2][0][RTW89_WW][11] = 0, -+ [2][1][2][0][RTW89_WW][18] = 0, -+ [2][1][2][0][RTW89_WW][26] = 0, -+ [2][1][2][0][RTW89_WW][34] = 0, -+ [2][1][2][0][RTW89_WW][41] = 0, -+ [2][1][2][0][RTW89_WW][49] = 0, -+ [2][1][2][1][RTW89_WW][3] = 0, -+ [2][1][2][1][RTW89_WW][11] = 0, -+ [2][1][2][1][RTW89_WW][18] = 0, -+ [2][1][2][1][RTW89_WW][26] = 0, -+ [2][1][2][1][RTW89_WW][34] = 0, -+ [2][1][2][1][RTW89_WW][41] = 0, -+ [2][1][2][1][RTW89_WW][49] = 0, -+ [3][0][2][0][RTW89_WW][7] = 58, -+ [3][0][2][0][RTW89_WW][22] = 58, -+ [3][0][2][0][RTW89_WW][45] = 0, -+ [3][1][2][0][RTW89_WW][7] = 0, -+ [3][1][2][0][RTW89_WW][22] = 0, -+ [3][1][2][0][RTW89_WW][45] = 0, -+ [3][1][2][1][RTW89_WW][7] = 0, -+ [3][1][2][1][RTW89_WW][22] = 0, -+ [3][1][2][1][RTW89_WW][45] = 0, -+ [0][0][1][0][RTW89_FCC][0] = 78, -+ [0][0][1][0][RTW89_ETSI][0] = 58, -+ [0][0][1][0][RTW89_MKK][0] = 60, -+ [0][0][1][0][RTW89_IC][0] = 62, -+ [0][0][1][0][RTW89_KCC][0] = 74, -+ [0][0][1][0][RTW89_ACMA][0] = 58, -+ [0][0][1][0][RTW89_CN][0] = 60, -+ [0][0][1][0][RTW89_UK][0] = 58, -+ [0][0][1][0][RTW89_FCC][2] = 78, -+ [0][0][1][0][RTW89_ETSI][2] = 58, -+ [0][0][1][0][RTW89_MKK][2] = 60, -+ [0][0][1][0][RTW89_IC][2] = 62, -+ [0][0][1][0][RTW89_KCC][2] = 74, -+ [0][0][1][0][RTW89_ACMA][2] = 58, -+ [0][0][1][0][RTW89_CN][2] = 60, -+ [0][0][1][0][RTW89_UK][2] = 58, -+ [0][0][1][0][RTW89_FCC][4] = 78, -+ [0][0][1][0][RTW89_ETSI][4] = 58, -+ [0][0][1][0][RTW89_MKK][4] = 60, -+ [0][0][1][0][RTW89_IC][4] = 62, -+ [0][0][1][0][RTW89_KCC][4] = 74, -+ [0][0][1][0][RTW89_ACMA][4] = 58, -+ [0][0][1][0][RTW89_CN][4] = 60, -+ [0][0][1][0][RTW89_UK][4] = 58, -+ [0][0][1][0][RTW89_FCC][6] = 78, -+ [0][0][1][0][RTW89_ETSI][6] = 58, -+ [0][0][1][0][RTW89_MKK][6] = 60, -+ [0][0][1][0][RTW89_IC][6] = 62, -+ [0][0][1][0][RTW89_KCC][6] = 50, -+ [0][0][1][0][RTW89_ACMA][6] = 58, -+ [0][0][1][0][RTW89_CN][6] = 60, -+ [0][0][1][0][RTW89_UK][6] = 58, -+ [0][0][1][0][RTW89_FCC][8] = 78, -+ [0][0][1][0][RTW89_ETSI][8] = 58, -+ [0][0][1][0][RTW89_MKK][8] = 60, -+ [0][0][1][0][RTW89_IC][8] = 62, -+ [0][0][1][0][RTW89_KCC][8] = 74, -+ [0][0][1][0][RTW89_ACMA][8] = 58, -+ [0][0][1][0][RTW89_CN][8] = 60, -+ [0][0][1][0][RTW89_UK][8] = 58, -+ [0][0][1][0][RTW89_FCC][10] = 78, -+ [0][0][1][0][RTW89_ETSI][10] = 58, -+ [0][0][1][0][RTW89_MKK][10] = 60, -+ [0][0][1][0][RTW89_IC][10] = 64, -+ [0][0][1][0][RTW89_KCC][10] = 74, -+ [0][0][1][0][RTW89_ACMA][10] = 58, -+ [0][0][1][0][RTW89_CN][10] = 60, -+ [0][0][1][0][RTW89_UK][10] = 58, -+ [0][0][1][0][RTW89_FCC][12] = 78, -+ [0][0][1][0][RTW89_ETSI][12] = 58, -+ [0][0][1][0][RTW89_MKK][12] = 60, -+ [0][0][1][0][RTW89_IC][12] = 64, -+ [0][0][1][0][RTW89_KCC][12] = 74, -+ [0][0][1][0][RTW89_ACMA][12] = 58, -+ [0][0][1][0][RTW89_CN][12] = 60, -+ [0][0][1][0][RTW89_UK][12] = 58, -+ [0][0][1][0][RTW89_FCC][14] = 76, -+ [0][0][1][0][RTW89_ETSI][14] = 58, -+ [0][0][1][0][RTW89_MKK][14] = 60, -+ [0][0][1][0][RTW89_IC][14] = 62, -+ [0][0][1][0][RTW89_KCC][14] = 74, -+ [0][0][1][0][RTW89_ACMA][14] = 58, -+ [0][0][1][0][RTW89_CN][14] = 60, -+ [0][0][1][0][RTW89_UK][14] = 58, -+ [0][0][1][0][RTW89_FCC][15] = 76, -+ [0][0][1][0][RTW89_ETSI][15] = 58, -+ [0][0][1][0][RTW89_MKK][15] = 74, -+ [0][0][1][0][RTW89_IC][15] = 76, -+ [0][0][1][0][RTW89_KCC][15] = 74, -+ [0][0][1][0][RTW89_ACMA][15] = 58, -+ [0][0][1][0][RTW89_CN][15] = 127, -+ [0][0][1][0][RTW89_UK][15] = 58, -+ [0][0][1][0][RTW89_FCC][17] = 78, -+ [0][0][1][0][RTW89_ETSI][17] = 60, -+ [0][0][1][0][RTW89_MKK][17] = 74, -+ [0][0][1][0][RTW89_IC][17] = 78, -+ [0][0][1][0][RTW89_KCC][17] = 74, -+ [0][0][1][0][RTW89_ACMA][17] = 60, -+ [0][0][1][0][RTW89_CN][17] = 127, -+ [0][0][1][0][RTW89_UK][17] = 60, -+ [0][0][1][0][RTW89_FCC][19] = 78, -+ [0][0][1][0][RTW89_ETSI][19] = 60, -+ [0][0][1][0][RTW89_MKK][19] = 74, -+ [0][0][1][0][RTW89_IC][19] = 78, -+ [0][0][1][0][RTW89_KCC][19] = 74, -+ [0][0][1][0][RTW89_ACMA][19] = 60, -+ [0][0][1][0][RTW89_CN][19] = 127, -+ [0][0][1][0][RTW89_UK][19] = 60, -+ [0][0][1][0][RTW89_FCC][21] = 78, -+ [0][0][1][0][RTW89_ETSI][21] = 60, -+ [0][0][1][0][RTW89_MKK][21] = 74, -+ [0][0][1][0][RTW89_IC][21] = 78, -+ [0][0][1][0][RTW89_KCC][21] = 74, -+ [0][0][1][0][RTW89_ACMA][21] = 60, -+ [0][0][1][0][RTW89_CN][21] = 127, -+ [0][0][1][0][RTW89_UK][21] = 60, -+ [0][0][1][0][RTW89_FCC][23] = 78, -+ [0][0][1][0][RTW89_ETSI][23] = 60, -+ [0][0][1][0][RTW89_MKK][23] = 74, -+ [0][0][1][0][RTW89_IC][23] = 78, -+ [0][0][1][0][RTW89_KCC][23] = 74, -+ [0][0][1][0][RTW89_ACMA][23] = 60, -+ [0][0][1][0][RTW89_CN][23] = 127, -+ [0][0][1][0][RTW89_UK][23] = 60, -+ [0][0][1][0][RTW89_FCC][25] = 78, -+ [0][0][1][0][RTW89_ETSI][25] = 60, -+ [0][0][1][0][RTW89_MKK][25] = 74, -+ [0][0][1][0][RTW89_IC][25] = 127, -+ [0][0][1][0][RTW89_KCC][25] = 74, -+ [0][0][1][0][RTW89_ACMA][25] = 127, -+ [0][0][1][0][RTW89_CN][25] = 127, -+ [0][0][1][0][RTW89_UK][25] = 60, -+ [0][0][1][0][RTW89_FCC][27] = 78, -+ [0][0][1][0][RTW89_ETSI][27] = 60, -+ [0][0][1][0][RTW89_MKK][27] = 74, -+ [0][0][1][0][RTW89_IC][27] = 127, -+ [0][0][1][0][RTW89_KCC][27] = 74, -+ [0][0][1][0][RTW89_ACMA][27] = 127, -+ [0][0][1][0][RTW89_CN][27] = 127, -+ [0][0][1][0][RTW89_UK][27] = 60, -+ [0][0][1][0][RTW89_FCC][29] = 78, -+ [0][0][1][0][RTW89_ETSI][29] = 60, -+ [0][0][1][0][RTW89_MKK][29] = 74, -+ [0][0][1][0][RTW89_IC][29] = 127, -+ [0][0][1][0][RTW89_KCC][29] = 74, -+ [0][0][1][0][RTW89_ACMA][29] = 127, -+ [0][0][1][0][RTW89_CN][29] = 127, -+ [0][0][1][0][RTW89_UK][29] = 60, -+ [0][0][1][0][RTW89_FCC][31] = 78, -+ [0][0][1][0][RTW89_ETSI][31] = 60, -+ [0][0][1][0][RTW89_MKK][31] = 74, -+ [0][0][1][0][RTW89_IC][31] = 78, -+ [0][0][1][0][RTW89_KCC][31] = 74, -+ [0][0][1][0][RTW89_ACMA][31] = 60, -+ [0][0][1][0][RTW89_CN][31] = 127, -+ [0][0][1][0][RTW89_UK][31] = 60, -+ [0][0][1][0][RTW89_FCC][33] = 78, -+ [0][0][1][0][RTW89_ETSI][33] = 60, -+ [0][0][1][0][RTW89_MKK][33] = 74, -+ [0][0][1][0][RTW89_IC][33] = 78, -+ [0][0][1][0][RTW89_KCC][33] = 74, -+ [0][0][1][0][RTW89_ACMA][33] = 60, -+ [0][0][1][0][RTW89_CN][33] = 127, -+ [0][0][1][0][RTW89_UK][33] = 60, -+ [0][0][1][0][RTW89_FCC][35] = 70, -+ [0][0][1][0][RTW89_ETSI][35] = 60, -+ [0][0][1][0][RTW89_MKK][35] = 74, -+ [0][0][1][0][RTW89_IC][35] = 70, -+ [0][0][1][0][RTW89_KCC][35] = 74, -+ [0][0][1][0][RTW89_ACMA][35] = 60, -+ [0][0][1][0][RTW89_CN][35] = 127, -+ [0][0][1][0][RTW89_UK][35] = 60, -+ [0][0][1][0][RTW89_FCC][37] = 78, -+ [0][0][1][0][RTW89_ETSI][37] = 127, -+ [0][0][1][0][RTW89_MKK][37] = 74, -+ [0][0][1][0][RTW89_IC][37] = 78, -+ [0][0][1][0][RTW89_KCC][37] = 74, -+ [0][0][1][0][RTW89_ACMA][37] = 74, -+ [0][0][1][0][RTW89_CN][37] = 127, -+ [0][0][1][0][RTW89_UK][37] = 74, -+ [0][0][1][0][RTW89_FCC][38] = 78, -+ [0][0][1][0][RTW89_ETSI][38] = 30, -+ [0][0][1][0][RTW89_MKK][38] = 127, -+ [0][0][1][0][RTW89_IC][38] = 78, -+ [0][0][1][0][RTW89_KCC][38] = 70, -+ [0][0][1][0][RTW89_ACMA][38] = 74, -+ [0][0][1][0][RTW89_CN][38] = 74, -+ [0][0][1][0][RTW89_UK][38] = 58, -+ [0][0][1][0][RTW89_FCC][40] = 78, -+ [0][0][1][0][RTW89_ETSI][40] = 30, -+ [0][0][1][0][RTW89_MKK][40] = 127, -+ [0][0][1][0][RTW89_IC][40] = 78, -+ [0][0][1][0][RTW89_KCC][40] = 74, -+ [0][0][1][0][RTW89_ACMA][40] = 74, -+ [0][0][1][0][RTW89_CN][40] = 74, -+ [0][0][1][0][RTW89_UK][40] = 58, -+ [0][0][1][0][RTW89_FCC][42] = 78, -+ [0][0][1][0][RTW89_ETSI][42] = 30, -+ [0][0][1][0][RTW89_MKK][42] = 127, -+ [0][0][1][0][RTW89_IC][42] = 78, -+ [0][0][1][0][RTW89_KCC][42] = 74, -+ [0][0][1][0][RTW89_ACMA][42] = 74, -+ [0][0][1][0][RTW89_CN][42] = 74, -+ [0][0][1][0][RTW89_UK][42] = 58, -+ [0][0][1][0][RTW89_FCC][44] = 78, -+ [0][0][1][0][RTW89_ETSI][44] = 30, -+ [0][0][1][0][RTW89_MKK][44] = 127, -+ [0][0][1][0][RTW89_IC][44] = 78, -+ [0][0][1][0][RTW89_KCC][44] = 74, -+ [0][0][1][0][RTW89_ACMA][44] = 74, -+ [0][0][1][0][RTW89_CN][44] = 74, -+ [0][0][1][0][RTW89_UK][44] = 58, -+ [0][0][1][0][RTW89_FCC][46] = 78, -+ [0][0][1][0][RTW89_ETSI][46] = 30, -+ [0][0][1][0][RTW89_MKK][46] = 127, -+ [0][0][1][0][RTW89_IC][46] = 78, -+ [0][0][1][0][RTW89_KCC][46] = 74, -+ [0][0][1][0][RTW89_ACMA][46] = 74, -+ [0][0][1][0][RTW89_CN][46] = 74, -+ [0][0][1][0][RTW89_UK][46] = 58, -+ [0][0][1][0][RTW89_FCC][48] = 72, -+ [0][0][1][0][RTW89_ETSI][48] = 127, -+ [0][0][1][0][RTW89_MKK][48] = 127, -+ [0][0][1][0][RTW89_IC][48] = 127, -+ [0][0][1][0][RTW89_KCC][48] = 127, -+ [0][0][1][0][RTW89_ACMA][48] = 127, -+ [0][0][1][0][RTW89_CN][48] = 127, -+ [0][0][1][0][RTW89_UK][48] = 127, -+ [0][0][1][0][RTW89_FCC][50] = 72, -+ [0][0][1][0][RTW89_ETSI][50] = 127, -+ [0][0][1][0][RTW89_MKK][50] = 127, -+ [0][0][1][0][RTW89_IC][50] = 127, -+ [0][0][1][0][RTW89_KCC][50] = 127, -+ [0][0][1][0][RTW89_ACMA][50] = 127, -+ [0][0][1][0][RTW89_CN][50] = 127, -+ [0][0][1][0][RTW89_UK][50] = 127, -+ [0][0][1][0][RTW89_FCC][52] = 72, -+ [0][0][1][0][RTW89_ETSI][52] = 127, -+ [0][0][1][0][RTW89_MKK][52] = 127, -+ [0][0][1][0][RTW89_IC][52] = 127, -+ [0][0][1][0][RTW89_KCC][52] = 127, -+ [0][0][1][0][RTW89_ACMA][52] = 127, -+ [0][0][1][0][RTW89_CN][52] = 127, -+ [0][0][1][0][RTW89_UK][52] = 127, -+ [0][1][1][0][RTW89_FCC][0] = 127, -+ [0][1][1][0][RTW89_ETSI][0] = 127, -+ [0][1][1][0][RTW89_MKK][0] = 127, -+ [0][1][1][0][RTW89_IC][0] = 127, -+ [0][1][1][0][RTW89_KCC][0] = 127, -+ [0][1][1][0][RTW89_ACMA][0] = 127, -+ [0][1][1][0][RTW89_CN][0] = 127, -+ [0][1][1][0][RTW89_UK][0] = 127, -+ [0][1][1][0][RTW89_FCC][2] = 127, -+ [0][1][1][0][RTW89_ETSI][2] = 127, -+ [0][1][1][0][RTW89_MKK][2] = 127, -+ [0][1][1][0][RTW89_IC][2] = 127, -+ [0][1][1][0][RTW89_KCC][2] = 127, -+ [0][1][1][0][RTW89_ACMA][2] = 127, -+ [0][1][1][0][RTW89_CN][2] = 127, -+ [0][1][1][0][RTW89_UK][2] = 127, -+ [0][1][1][0][RTW89_FCC][4] = 127, -+ [0][1][1][0][RTW89_ETSI][4] = 127, -+ [0][1][1][0][RTW89_MKK][4] = 127, -+ [0][1][1][0][RTW89_IC][4] = 127, -+ [0][1][1][0][RTW89_KCC][4] = 127, -+ [0][1][1][0][RTW89_ACMA][4] = 127, -+ [0][1][1][0][RTW89_CN][4] = 127, -+ [0][1][1][0][RTW89_UK][4] = 127, -+ [0][1][1][0][RTW89_FCC][6] = 127, -+ [0][1][1][0][RTW89_ETSI][6] = 127, -+ [0][1][1][0][RTW89_MKK][6] = 127, -+ [0][1][1][0][RTW89_IC][6] = 127, -+ [0][1][1][0][RTW89_KCC][6] = 127, -+ [0][1][1][0][RTW89_ACMA][6] = 127, -+ [0][1][1][0][RTW89_CN][6] = 127, -+ [0][1][1][0][RTW89_UK][6] = 127, -+ [0][1][1][0][RTW89_FCC][8] = 127, -+ [0][1][1][0][RTW89_ETSI][8] = 127, -+ [0][1][1][0][RTW89_MKK][8] = 127, -+ [0][1][1][0][RTW89_IC][8] = 127, -+ [0][1][1][0][RTW89_KCC][8] = 127, -+ [0][1][1][0][RTW89_ACMA][8] = 127, -+ [0][1][1][0][RTW89_CN][8] = 127, -+ [0][1][1][0][RTW89_UK][8] = 127, -+ [0][1][1][0][RTW89_FCC][10] = 127, -+ [0][1][1][0][RTW89_ETSI][10] = 127, -+ [0][1][1][0][RTW89_MKK][10] = 127, -+ [0][1][1][0][RTW89_IC][10] = 127, -+ [0][1][1][0][RTW89_KCC][10] = 127, -+ [0][1][1][0][RTW89_ACMA][10] = 127, -+ [0][1][1][0][RTW89_CN][10] = 127, -+ [0][1][1][0][RTW89_UK][10] = 127, -+ [0][1][1][0][RTW89_FCC][12] = 127, -+ [0][1][1][0][RTW89_ETSI][12] = 127, -+ [0][1][1][0][RTW89_MKK][12] = 127, -+ [0][1][1][0][RTW89_IC][12] = 127, -+ [0][1][1][0][RTW89_KCC][12] = 127, -+ [0][1][1][0][RTW89_ACMA][12] = 127, -+ [0][1][1][0][RTW89_CN][12] = 127, -+ [0][1][1][0][RTW89_UK][12] = 127, -+ [0][1][1][0][RTW89_FCC][14] = 127, -+ [0][1][1][0][RTW89_ETSI][14] = 127, -+ [0][1][1][0][RTW89_MKK][14] = 127, -+ [0][1][1][0][RTW89_IC][14] = 127, -+ [0][1][1][0][RTW89_KCC][14] = 127, -+ [0][1][1][0][RTW89_ACMA][14] = 127, -+ [0][1][1][0][RTW89_CN][14] = 127, -+ [0][1][1][0][RTW89_UK][14] = 127, -+ [0][1][1][0][RTW89_FCC][15] = 127, -+ [0][1][1][0][RTW89_ETSI][15] = 127, -+ [0][1][1][0][RTW89_MKK][15] = 127, -+ [0][1][1][0][RTW89_IC][15] = 127, -+ [0][1][1][0][RTW89_KCC][15] = 127, -+ [0][1][1][0][RTW89_ACMA][15] = 127, -+ [0][1][1][0][RTW89_CN][15] = 127, -+ [0][1][1][0][RTW89_UK][15] = 127, -+ [0][1][1][0][RTW89_FCC][17] = 127, -+ [0][1][1][0][RTW89_ETSI][17] = 127, -+ [0][1][1][0][RTW89_MKK][17] = 127, -+ [0][1][1][0][RTW89_IC][17] = 127, -+ [0][1][1][0][RTW89_KCC][17] = 127, -+ [0][1][1][0][RTW89_ACMA][17] = 127, -+ [0][1][1][0][RTW89_CN][17] = 127, -+ [0][1][1][0][RTW89_UK][17] = 127, -+ [0][1][1][0][RTW89_FCC][19] = 127, -+ [0][1][1][0][RTW89_ETSI][19] = 127, -+ [0][1][1][0][RTW89_MKK][19] = 127, -+ [0][1][1][0][RTW89_IC][19] = 127, -+ [0][1][1][0][RTW89_KCC][19] = 127, -+ [0][1][1][0][RTW89_ACMA][19] = 127, -+ [0][1][1][0][RTW89_CN][19] = 127, -+ [0][1][1][0][RTW89_UK][19] = 127, -+ [0][1][1][0][RTW89_FCC][21] = 127, -+ [0][1][1][0][RTW89_ETSI][21] = 127, -+ [0][1][1][0][RTW89_MKK][21] = 127, -+ [0][1][1][0][RTW89_IC][21] = 127, -+ [0][1][1][0][RTW89_KCC][21] = 127, -+ [0][1][1][0][RTW89_ACMA][21] = 127, -+ [0][1][1][0][RTW89_CN][21] = 127, -+ [0][1][1][0][RTW89_UK][21] = 127, -+ [0][1][1][0][RTW89_FCC][23] = 127, -+ [0][1][1][0][RTW89_ETSI][23] = 127, -+ [0][1][1][0][RTW89_MKK][23] = 127, -+ [0][1][1][0][RTW89_IC][23] = 127, -+ [0][1][1][0][RTW89_KCC][23] = 127, -+ [0][1][1][0][RTW89_ACMA][23] = 127, -+ [0][1][1][0][RTW89_CN][23] = 127, -+ [0][1][1][0][RTW89_UK][23] = 127, -+ [0][1][1][0][RTW89_FCC][25] = 127, -+ [0][1][1][0][RTW89_ETSI][25] = 127, -+ [0][1][1][0][RTW89_MKK][25] = 127, -+ [0][1][1][0][RTW89_IC][25] = 127, -+ [0][1][1][0][RTW89_KCC][25] = 127, -+ [0][1][1][0][RTW89_ACMA][25] = 127, -+ [0][1][1][0][RTW89_CN][25] = 127, -+ [0][1][1][0][RTW89_UK][25] = 127, -+ [0][1][1][0][RTW89_FCC][27] = 127, -+ [0][1][1][0][RTW89_ETSI][27] = 127, -+ [0][1][1][0][RTW89_MKK][27] = 127, -+ [0][1][1][0][RTW89_IC][27] = 127, -+ [0][1][1][0][RTW89_KCC][27] = 127, -+ [0][1][1][0][RTW89_ACMA][27] = 127, -+ [0][1][1][0][RTW89_CN][27] = 127, -+ [0][1][1][0][RTW89_UK][27] = 127, -+ [0][1][1][0][RTW89_FCC][29] = 127, -+ [0][1][1][0][RTW89_ETSI][29] = 127, -+ [0][1][1][0][RTW89_MKK][29] = 127, -+ [0][1][1][0][RTW89_IC][29] = 127, -+ [0][1][1][0][RTW89_KCC][29] = 127, -+ [0][1][1][0][RTW89_ACMA][29] = 127, -+ [0][1][1][0][RTW89_CN][29] = 127, -+ [0][1][1][0][RTW89_UK][29] = 127, -+ [0][1][1][0][RTW89_FCC][31] = 127, -+ [0][1][1][0][RTW89_ETSI][31] = 127, -+ [0][1][1][0][RTW89_MKK][31] = 127, -+ [0][1][1][0][RTW89_IC][31] = 127, -+ [0][1][1][0][RTW89_KCC][31] = 127, -+ [0][1][1][0][RTW89_ACMA][31] = 127, -+ [0][1][1][0][RTW89_CN][31] = 127, -+ [0][1][1][0][RTW89_UK][31] = 127, -+ [0][1][1][0][RTW89_FCC][33] = 127, -+ [0][1][1][0][RTW89_ETSI][33] = 127, -+ [0][1][1][0][RTW89_MKK][33] = 127, -+ [0][1][1][0][RTW89_IC][33] = 127, -+ [0][1][1][0][RTW89_KCC][33] = 127, -+ [0][1][1][0][RTW89_ACMA][33] = 127, -+ [0][1][1][0][RTW89_CN][33] = 127, -+ [0][1][1][0][RTW89_UK][33] = 127, -+ [0][1][1][0][RTW89_FCC][35] = 127, -+ [0][1][1][0][RTW89_ETSI][35] = 127, -+ [0][1][1][0][RTW89_MKK][35] = 127, -+ [0][1][1][0][RTW89_IC][35] = 127, -+ [0][1][1][0][RTW89_KCC][35] = 127, -+ [0][1][1][0][RTW89_ACMA][35] = 127, -+ [0][1][1][0][RTW89_CN][35] = 127, -+ [0][1][1][0][RTW89_UK][35] = 127, -+ [0][1][1][0][RTW89_FCC][37] = 127, -+ [0][1][1][0][RTW89_ETSI][37] = 127, -+ [0][1][1][0][RTW89_MKK][37] = 127, -+ [0][1][1][0][RTW89_IC][37] = 127, -+ [0][1][1][0][RTW89_KCC][37] = 127, -+ [0][1][1][0][RTW89_ACMA][37] = 127, -+ [0][1][1][0][RTW89_CN][37] = 127, -+ [0][1][1][0][RTW89_UK][37] = 127, -+ [0][1][1][0][RTW89_FCC][38] = 127, -+ [0][1][1][0][RTW89_ETSI][38] = 127, -+ [0][1][1][0][RTW89_MKK][38] = 127, -+ [0][1][1][0][RTW89_IC][38] = 127, -+ [0][1][1][0][RTW89_KCC][38] = 127, -+ [0][1][1][0][RTW89_ACMA][38] = 127, -+ [0][1][1][0][RTW89_CN][38] = 127, -+ [0][1][1][0][RTW89_UK][38] = 127, -+ [0][1][1][0][RTW89_FCC][40] = 127, -+ [0][1][1][0][RTW89_ETSI][40] = 127, -+ [0][1][1][0][RTW89_MKK][40] = 127, -+ [0][1][1][0][RTW89_IC][40] = 127, -+ [0][1][1][0][RTW89_KCC][40] = 127, -+ [0][1][1][0][RTW89_ACMA][40] = 127, -+ [0][1][1][0][RTW89_CN][40] = 127, -+ [0][1][1][0][RTW89_UK][40] = 127, -+ [0][1][1][0][RTW89_FCC][42] = 127, -+ [0][1][1][0][RTW89_ETSI][42] = 127, -+ [0][1][1][0][RTW89_MKK][42] = 127, -+ [0][1][1][0][RTW89_IC][42] = 127, -+ [0][1][1][0][RTW89_KCC][42] = 127, -+ [0][1][1][0][RTW89_ACMA][42] = 127, -+ [0][1][1][0][RTW89_CN][42] = 127, -+ [0][1][1][0][RTW89_UK][42] = 127, -+ [0][1][1][0][RTW89_FCC][44] = 127, -+ [0][1][1][0][RTW89_ETSI][44] = 127, -+ [0][1][1][0][RTW89_MKK][44] = 127, -+ [0][1][1][0][RTW89_IC][44] = 127, -+ [0][1][1][0][RTW89_KCC][44] = 127, -+ [0][1][1][0][RTW89_ACMA][44] = 127, -+ [0][1][1][0][RTW89_CN][44] = 127, -+ [0][1][1][0][RTW89_UK][44] = 127, -+ [0][1][1][0][RTW89_FCC][46] = 127, -+ [0][1][1][0][RTW89_ETSI][46] = 127, -+ [0][1][1][0][RTW89_MKK][46] = 127, -+ [0][1][1][0][RTW89_IC][46] = 127, -+ [0][1][1][0][RTW89_KCC][46] = 127, -+ [0][1][1][0][RTW89_ACMA][46] = 127, -+ [0][1][1][0][RTW89_CN][46] = 127, -+ [0][1][1][0][RTW89_UK][46] = 127, -+ [0][1][1][0][RTW89_FCC][48] = 127, -+ [0][1][1][0][RTW89_ETSI][48] = 127, -+ [0][1][1][0][RTW89_MKK][48] = 127, -+ [0][1][1][0][RTW89_IC][48] = 127, -+ [0][1][1][0][RTW89_KCC][48] = 127, -+ [0][1][1][0][RTW89_ACMA][48] = 127, -+ [0][1][1][0][RTW89_CN][48] = 127, -+ [0][1][1][0][RTW89_UK][48] = 127, -+ [0][1][1][0][RTW89_FCC][50] = 127, -+ [0][1][1][0][RTW89_ETSI][50] = 127, -+ [0][1][1][0][RTW89_MKK][50] = 127, -+ [0][1][1][0][RTW89_IC][50] = 127, -+ [0][1][1][0][RTW89_KCC][50] = 127, -+ [0][1][1][0][RTW89_ACMA][50] = 127, -+ [0][1][1][0][RTW89_CN][50] = 127, -+ [0][1][1][0][RTW89_UK][50] = 127, -+ [0][1][1][0][RTW89_FCC][52] = 127, -+ [0][1][1][0][RTW89_ETSI][52] = 127, -+ [0][1][1][0][RTW89_MKK][52] = 127, -+ [0][1][1][0][RTW89_IC][52] = 127, -+ [0][1][1][0][RTW89_KCC][52] = 127, -+ [0][1][1][0][RTW89_ACMA][52] = 127, -+ [0][1][1][0][RTW89_CN][52] = 127, -+ [0][1][1][0][RTW89_UK][52] = 127, -+ [0][0][2][0][RTW89_FCC][0] = 76, -+ [0][0][2][0][RTW89_ETSI][0] = 62, -+ [0][0][2][0][RTW89_MKK][0] = 62, -+ [0][0][2][0][RTW89_IC][0] = 64, -+ [0][0][2][0][RTW89_KCC][0] = 74, -+ [0][0][2][0][RTW89_ACMA][0] = 62, -+ [0][0][2][0][RTW89_CN][0] = 62, -+ [0][0][2][0][RTW89_UK][0] = 62, -+ [0][0][2][0][RTW89_FCC][2] = 78, -+ [0][0][2][0][RTW89_ETSI][2] = 62, -+ [0][0][2][0][RTW89_MKK][2] = 62, -+ [0][0][2][0][RTW89_IC][2] = 64, -+ [0][0][2][0][RTW89_KCC][2] = 74, -+ [0][0][2][0][RTW89_ACMA][2] = 62, -+ [0][0][2][0][RTW89_CN][2] = 62, -+ [0][0][2][0][RTW89_UK][2] = 62, -+ [0][0][2][0][RTW89_FCC][4] = 78, -+ [0][0][2][0][RTW89_ETSI][4] = 62, -+ [0][0][2][0][RTW89_MKK][4] = 62, -+ [0][0][2][0][RTW89_IC][4] = 64, -+ [0][0][2][0][RTW89_KCC][4] = 74, -+ [0][0][2][0][RTW89_ACMA][4] = 62, -+ [0][0][2][0][RTW89_CN][4] = 62, -+ [0][0][2][0][RTW89_UK][4] = 62, -+ [0][0][2][0][RTW89_FCC][6] = 78, -+ [0][0][2][0][RTW89_ETSI][6] = 62, -+ [0][0][2][0][RTW89_MKK][6] = 62, -+ [0][0][2][0][RTW89_IC][6] = 64, -+ [0][0][2][0][RTW89_KCC][6] = 54, -+ [0][0][2][0][RTW89_ACMA][6] = 62, -+ [0][0][2][0][RTW89_CN][6] = 62, -+ [0][0][2][0][RTW89_UK][6] = 62, -+ [0][0][2][0][RTW89_FCC][8] = 78, -+ [0][0][2][0][RTW89_ETSI][8] = 62, -+ [0][0][2][0][RTW89_MKK][8] = 62, -+ [0][0][2][0][RTW89_IC][8] = 64, -+ [0][0][2][0][RTW89_KCC][8] = 74, -+ [0][0][2][0][RTW89_ACMA][8] = 62, -+ [0][0][2][0][RTW89_CN][8] = 62, -+ [0][0][2][0][RTW89_UK][8] = 62, -+ [0][0][2][0][RTW89_FCC][10] = 78, -+ [0][0][2][0][RTW89_ETSI][10] = 62, -+ [0][0][2][0][RTW89_MKK][10] = 62, -+ [0][0][2][0][RTW89_IC][10] = 64, -+ [0][0][2][0][RTW89_KCC][10] = 74, -+ [0][0][2][0][RTW89_ACMA][10] = 62, -+ [0][0][2][0][RTW89_CN][10] = 62, -+ [0][0][2][0][RTW89_UK][10] = 62, -+ [0][0][2][0][RTW89_FCC][12] = 78, -+ [0][0][2][0][RTW89_ETSI][12] = 62, -+ [0][0][2][0][RTW89_MKK][12] = 62, -+ [0][0][2][0][RTW89_IC][12] = 64, -+ [0][0][2][0][RTW89_KCC][12] = 74, -+ [0][0][2][0][RTW89_ACMA][12] = 62, -+ [0][0][2][0][RTW89_CN][12] = 62, -+ [0][0][2][0][RTW89_UK][12] = 62, -+ [0][0][2][0][RTW89_FCC][14] = 74, -+ [0][0][2][0][RTW89_ETSI][14] = 62, -+ [0][0][2][0][RTW89_MKK][14] = 62, -+ [0][0][2][0][RTW89_IC][14] = 64, -+ [0][0][2][0][RTW89_KCC][14] = 74, -+ [0][0][2][0][RTW89_ACMA][14] = 62, -+ [0][0][2][0][RTW89_CN][14] = 62, -+ [0][0][2][0][RTW89_UK][14] = 62, -+ [0][0][2][0][RTW89_FCC][15] = 74, -+ [0][0][2][0][RTW89_ETSI][15] = 60, -+ [0][0][2][0][RTW89_MKK][15] = 74, -+ [0][0][2][0][RTW89_IC][15] = 74, -+ [0][0][2][0][RTW89_KCC][15] = 74, -+ [0][0][2][0][RTW89_ACMA][15] = 60, -+ [0][0][2][0][RTW89_CN][15] = 127, -+ [0][0][2][0][RTW89_UK][15] = 60, -+ [0][0][2][0][RTW89_FCC][17] = 78, -+ [0][0][2][0][RTW89_ETSI][17] = 62, -+ [0][0][2][0][RTW89_MKK][17] = 74, -+ [0][0][2][0][RTW89_IC][17] = 78, -+ [0][0][2][0][RTW89_KCC][17] = 74, -+ [0][0][2][0][RTW89_ACMA][17] = 62, -+ [0][0][2][0][RTW89_CN][17] = 127, -+ [0][0][2][0][RTW89_UK][17] = 62, -+ [0][0][2][0][RTW89_FCC][19] = 78, -+ [0][0][2][0][RTW89_ETSI][19] = 62, -+ [0][0][2][0][RTW89_MKK][19] = 74, -+ [0][0][2][0][RTW89_IC][19] = 78, -+ [0][0][2][0][RTW89_KCC][19] = 74, -+ [0][0][2][0][RTW89_ACMA][19] = 62, -+ [0][0][2][0][RTW89_CN][19] = 127, -+ [0][0][2][0][RTW89_UK][19] = 62, -+ [0][0][2][0][RTW89_FCC][21] = 78, -+ [0][0][2][0][RTW89_ETSI][21] = 62, -+ [0][0][2][0][RTW89_MKK][21] = 74, -+ [0][0][2][0][RTW89_IC][21] = 78, -+ [0][0][2][0][RTW89_KCC][21] = 74, -+ [0][0][2][0][RTW89_ACMA][21] = 62, -+ [0][0][2][0][RTW89_CN][21] = 127, -+ [0][0][2][0][RTW89_UK][21] = 62, -+ [0][0][2][0][RTW89_FCC][23] = 78, -+ [0][0][2][0][RTW89_ETSI][23] = 62, -+ [0][0][2][0][RTW89_MKK][23] = 74, -+ [0][0][2][0][RTW89_IC][23] = 78, -+ [0][0][2][0][RTW89_KCC][23] = 74, -+ [0][0][2][0][RTW89_ACMA][23] = 62, -+ [0][0][2][0][RTW89_CN][23] = 127, -+ [0][0][2][0][RTW89_UK][23] = 62, -+ [0][0][2][0][RTW89_FCC][25] = 78, -+ [0][0][2][0][RTW89_ETSI][25] = 62, -+ [0][0][2][0][RTW89_MKK][25] = 74, -+ [0][0][2][0][RTW89_IC][25] = 127, -+ [0][0][2][0][RTW89_KCC][25] = 74, -+ [0][0][2][0][RTW89_ACMA][25] = 127, -+ [0][0][2][0][RTW89_CN][25] = 127, -+ [0][0][2][0][RTW89_UK][25] = 62, -+ [0][0][2][0][RTW89_FCC][27] = 78, -+ [0][0][2][0][RTW89_ETSI][27] = 62, -+ [0][0][2][0][RTW89_MKK][27] = 74, -+ [0][0][2][0][RTW89_IC][27] = 127, -+ [0][0][2][0][RTW89_KCC][27] = 74, -+ [0][0][2][0][RTW89_ACMA][27] = 127, -+ [0][0][2][0][RTW89_CN][27] = 127, -+ [0][0][2][0][RTW89_UK][27] = 62, -+ [0][0][2][0][RTW89_FCC][29] = 78, -+ [0][0][2][0][RTW89_ETSI][29] = 62, -+ [0][0][2][0][RTW89_MKK][29] = 74, -+ [0][0][2][0][RTW89_IC][29] = 127, -+ [0][0][2][0][RTW89_KCC][29] = 74, -+ [0][0][2][0][RTW89_ACMA][29] = 127, -+ [0][0][2][0][RTW89_CN][29] = 127, -+ [0][0][2][0][RTW89_UK][29] = 62, -+ [0][0][2][0][RTW89_FCC][31] = 78, -+ [0][0][2][0][RTW89_ETSI][31] = 62, -+ [0][0][2][0][RTW89_MKK][31] = 74, -+ [0][0][2][0][RTW89_IC][31] = 78, -+ [0][0][2][0][RTW89_KCC][31] = 74, -+ [0][0][2][0][RTW89_ACMA][31] = 62, -+ [0][0][2][0][RTW89_CN][31] = 127, -+ [0][0][2][0][RTW89_UK][31] = 62, -+ [0][0][2][0][RTW89_FCC][33] = 78, -+ [0][0][2][0][RTW89_ETSI][33] = 62, -+ [0][0][2][0][RTW89_MKK][33] = 74, -+ [0][0][2][0][RTW89_IC][33] = 78, -+ [0][0][2][0][RTW89_KCC][33] = 74, -+ [0][0][2][0][RTW89_ACMA][33] = 62, -+ [0][0][2][0][RTW89_CN][33] = 127, -+ [0][0][2][0][RTW89_UK][33] = 62, -+ [0][0][2][0][RTW89_FCC][35] = 72, -+ [0][0][2][0][RTW89_ETSI][35] = 62, -+ [0][0][2][0][RTW89_MKK][35] = 74, -+ [0][0][2][0][RTW89_IC][35] = 72, -+ [0][0][2][0][RTW89_KCC][35] = 74, -+ [0][0][2][0][RTW89_ACMA][35] = 62, -+ [0][0][2][0][RTW89_CN][35] = 127, -+ [0][0][2][0][RTW89_UK][35] = 62, -+ [0][0][2][0][RTW89_FCC][37] = 78, -+ [0][0][2][0][RTW89_ETSI][37] = 127, -+ [0][0][2][0][RTW89_MKK][37] = 74, -+ [0][0][2][0][RTW89_IC][37] = 78, -+ [0][0][2][0][RTW89_KCC][37] = 74, -+ [0][0][2][0][RTW89_ACMA][37] = 74, -+ [0][0][2][0][RTW89_CN][37] = 127, -+ [0][0][2][0][RTW89_UK][37] = 74, -+ [0][0][2][0][RTW89_FCC][38] = 78, -+ [0][0][2][0][RTW89_ETSI][38] = 30, -+ [0][0][2][0][RTW89_MKK][38] = 127, -+ [0][0][2][0][RTW89_IC][38] = 78, -+ [0][0][2][0][RTW89_KCC][38] = 66, -+ [0][0][2][0][RTW89_ACMA][38] = 74, -+ [0][0][2][0][RTW89_CN][38] = 74, -+ [0][0][2][0][RTW89_UK][38] = 60, -+ [0][0][2][0][RTW89_FCC][40] = 78, -+ [0][0][2][0][RTW89_ETSI][40] = 30, -+ [0][0][2][0][RTW89_MKK][40] = 127, -+ [0][0][2][0][RTW89_IC][40] = 78, -+ [0][0][2][0][RTW89_KCC][40] = 74, -+ [0][0][2][0][RTW89_ACMA][40] = 74, -+ [0][0][2][0][RTW89_CN][40] = 74, -+ [0][0][2][0][RTW89_UK][40] = 60, -+ [0][0][2][0][RTW89_FCC][42] = 78, -+ [0][0][2][0][RTW89_ETSI][42] = 30, -+ [0][0][2][0][RTW89_MKK][42] = 127, -+ [0][0][2][0][RTW89_IC][42] = 78, -+ [0][0][2][0][RTW89_KCC][42] = 74, -+ [0][0][2][0][RTW89_ACMA][42] = 74, -+ [0][0][2][0][RTW89_CN][42] = 74, -+ [0][0][2][0][RTW89_UK][42] = 60, -+ [0][0][2][0][RTW89_FCC][44] = 78, -+ [0][0][2][0][RTW89_ETSI][44] = 30, -+ [0][0][2][0][RTW89_MKK][44] = 127, -+ [0][0][2][0][RTW89_IC][44] = 78, -+ [0][0][2][0][RTW89_KCC][44] = 74, -+ [0][0][2][0][RTW89_ACMA][44] = 74, -+ [0][0][2][0][RTW89_CN][44] = 74, -+ [0][0][2][0][RTW89_UK][44] = 60, -+ [0][0][2][0][RTW89_FCC][46] = 78, -+ [0][0][2][0][RTW89_ETSI][46] = 30, -+ [0][0][2][0][RTW89_MKK][46] = 127, -+ [0][0][2][0][RTW89_IC][46] = 78, -+ [0][0][2][0][RTW89_KCC][46] = 74, -+ [0][0][2][0][RTW89_ACMA][46] = 74, -+ [0][0][2][0][RTW89_CN][46] = 74, -+ [0][0][2][0][RTW89_UK][46] = 60, -+ [0][0][2][0][RTW89_FCC][48] = 74, -+ [0][0][2][0][RTW89_ETSI][48] = 127, -+ [0][0][2][0][RTW89_MKK][48] = 127, -+ [0][0][2][0][RTW89_IC][48] = 127, -+ [0][0][2][0][RTW89_KCC][48] = 127, -+ [0][0][2][0][RTW89_ACMA][48] = 127, -+ [0][0][2][0][RTW89_CN][48] = 127, -+ [0][0][2][0][RTW89_UK][48] = 127, -+ [0][0][2][0][RTW89_FCC][50] = 74, -+ [0][0][2][0][RTW89_ETSI][50] = 127, -+ [0][0][2][0][RTW89_MKK][50] = 127, -+ [0][0][2][0][RTW89_IC][50] = 127, -+ [0][0][2][0][RTW89_KCC][50] = 127, -+ [0][0][2][0][RTW89_ACMA][50] = 127, -+ [0][0][2][0][RTW89_CN][50] = 127, -+ [0][0][2][0][RTW89_UK][50] = 127, -+ [0][0][2][0][RTW89_FCC][52] = 74, -+ [0][0][2][0][RTW89_ETSI][52] = 127, -+ [0][0][2][0][RTW89_MKK][52] = 127, -+ [0][0][2][0][RTW89_IC][52] = 127, -+ [0][0][2][0][RTW89_KCC][52] = 127, -+ [0][0][2][0][RTW89_ACMA][52] = 127, -+ [0][0][2][0][RTW89_CN][52] = 127, -+ [0][0][2][0][RTW89_UK][52] = 127, -+ [0][1][2][0][RTW89_FCC][0] = 127, -+ [0][1][2][0][RTW89_ETSI][0] = 127, -+ [0][1][2][0][RTW89_MKK][0] = 127, -+ [0][1][2][0][RTW89_IC][0] = 127, -+ [0][1][2][0][RTW89_KCC][0] = 127, -+ [0][1][2][0][RTW89_ACMA][0] = 127, -+ [0][1][2][0][RTW89_CN][0] = 127, -+ [0][1][2][0][RTW89_UK][0] = 127, -+ [0][1][2][0][RTW89_FCC][2] = 127, -+ [0][1][2][0][RTW89_ETSI][2] = 127, -+ [0][1][2][0][RTW89_MKK][2] = 127, -+ [0][1][2][0][RTW89_IC][2] = 127, -+ [0][1][2][0][RTW89_KCC][2] = 127, -+ [0][1][2][0][RTW89_ACMA][2] = 127, -+ [0][1][2][0][RTW89_CN][2] = 127, -+ [0][1][2][0][RTW89_UK][2] = 127, -+ [0][1][2][0][RTW89_FCC][4] = 127, -+ [0][1][2][0][RTW89_ETSI][4] = 127, -+ [0][1][2][0][RTW89_MKK][4] = 127, -+ [0][1][2][0][RTW89_IC][4] = 127, -+ [0][1][2][0][RTW89_KCC][4] = 127, -+ [0][1][2][0][RTW89_ACMA][4] = 127, -+ [0][1][2][0][RTW89_CN][4] = 127, -+ [0][1][2][0][RTW89_UK][4] = 127, -+ [0][1][2][0][RTW89_FCC][6] = 127, -+ [0][1][2][0][RTW89_ETSI][6] = 127, -+ [0][1][2][0][RTW89_MKK][6] = 127, -+ [0][1][2][0][RTW89_IC][6] = 127, -+ [0][1][2][0][RTW89_KCC][6] = 127, -+ [0][1][2][0][RTW89_ACMA][6] = 127, -+ [0][1][2][0][RTW89_CN][6] = 127, -+ [0][1][2][0][RTW89_UK][6] = 127, -+ [0][1][2][0][RTW89_FCC][8] = 127, -+ [0][1][2][0][RTW89_ETSI][8] = 127, -+ [0][1][2][0][RTW89_MKK][8] = 127, -+ [0][1][2][0][RTW89_IC][8] = 127, -+ [0][1][2][0][RTW89_KCC][8] = 127, -+ [0][1][2][0][RTW89_ACMA][8] = 127, -+ [0][1][2][0][RTW89_CN][8] = 127, -+ [0][1][2][0][RTW89_UK][8] = 127, -+ [0][1][2][0][RTW89_FCC][10] = 127, -+ [0][1][2][0][RTW89_ETSI][10] = 127, -+ [0][1][2][0][RTW89_MKK][10] = 127, -+ [0][1][2][0][RTW89_IC][10] = 127, -+ [0][1][2][0][RTW89_KCC][10] = 127, -+ [0][1][2][0][RTW89_ACMA][10] = 127, -+ [0][1][2][0][RTW89_CN][10] = 127, -+ [0][1][2][0][RTW89_UK][10] = 127, -+ [0][1][2][0][RTW89_FCC][12] = 127, -+ [0][1][2][0][RTW89_ETSI][12] = 127, -+ [0][1][2][0][RTW89_MKK][12] = 127, -+ [0][1][2][0][RTW89_IC][12] = 127, -+ [0][1][2][0][RTW89_KCC][12] = 127, -+ [0][1][2][0][RTW89_ACMA][12] = 127, -+ [0][1][2][0][RTW89_CN][12] = 127, -+ [0][1][2][0][RTW89_UK][12] = 127, -+ [0][1][2][0][RTW89_FCC][14] = 127, -+ [0][1][2][0][RTW89_ETSI][14] = 127, -+ [0][1][2][0][RTW89_MKK][14] = 127, -+ [0][1][2][0][RTW89_IC][14] = 127, -+ [0][1][2][0][RTW89_KCC][14] = 127, -+ [0][1][2][0][RTW89_ACMA][14] = 127, -+ [0][1][2][0][RTW89_CN][14] = 127, -+ [0][1][2][0][RTW89_UK][14] = 127, -+ [0][1][2][0][RTW89_FCC][15] = 127, -+ [0][1][2][0][RTW89_ETSI][15] = 127, -+ [0][1][2][0][RTW89_MKK][15] = 127, -+ [0][1][2][0][RTW89_IC][15] = 127, -+ [0][1][2][0][RTW89_KCC][15] = 127, -+ [0][1][2][0][RTW89_ACMA][15] = 127, -+ [0][1][2][0][RTW89_CN][15] = 127, -+ [0][1][2][0][RTW89_UK][15] = 127, -+ [0][1][2][0][RTW89_FCC][17] = 127, -+ [0][1][2][0][RTW89_ETSI][17] = 127, -+ [0][1][2][0][RTW89_MKK][17] = 127, -+ [0][1][2][0][RTW89_IC][17] = 127, -+ [0][1][2][0][RTW89_KCC][17] = 127, -+ [0][1][2][0][RTW89_ACMA][17] = 127, -+ [0][1][2][0][RTW89_CN][17] = 127, -+ [0][1][2][0][RTW89_UK][17] = 127, -+ [0][1][2][0][RTW89_FCC][19] = 127, -+ [0][1][2][0][RTW89_ETSI][19] = 127, -+ [0][1][2][0][RTW89_MKK][19] = 127, -+ [0][1][2][0][RTW89_IC][19] = 127, -+ [0][1][2][0][RTW89_KCC][19] = 127, -+ [0][1][2][0][RTW89_ACMA][19] = 127, -+ [0][1][2][0][RTW89_CN][19] = 127, -+ [0][1][2][0][RTW89_UK][19] = 127, -+ [0][1][2][0][RTW89_FCC][21] = 127, -+ [0][1][2][0][RTW89_ETSI][21] = 127, -+ [0][1][2][0][RTW89_MKK][21] = 127, -+ [0][1][2][0][RTW89_IC][21] = 127, -+ [0][1][2][0][RTW89_KCC][21] = 127, -+ [0][1][2][0][RTW89_ACMA][21] = 127, -+ [0][1][2][0][RTW89_CN][21] = 127, -+ [0][1][2][0][RTW89_UK][21] = 127, -+ [0][1][2][0][RTW89_FCC][23] = 127, -+ [0][1][2][0][RTW89_ETSI][23] = 127, -+ [0][1][2][0][RTW89_MKK][23] = 127, -+ [0][1][2][0][RTW89_IC][23] = 127, -+ [0][1][2][0][RTW89_KCC][23] = 127, -+ [0][1][2][0][RTW89_ACMA][23] = 127, -+ [0][1][2][0][RTW89_CN][23] = 127, -+ [0][1][2][0][RTW89_UK][23] = 127, -+ [0][1][2][0][RTW89_FCC][25] = 127, -+ [0][1][2][0][RTW89_ETSI][25] = 127, -+ [0][1][2][0][RTW89_MKK][25] = 127, -+ [0][1][2][0][RTW89_IC][25] = 127, -+ [0][1][2][0][RTW89_KCC][25] = 127, -+ [0][1][2][0][RTW89_ACMA][25] = 127, -+ [0][1][2][0][RTW89_CN][25] = 127, -+ [0][1][2][0][RTW89_UK][25] = 127, -+ [0][1][2][0][RTW89_FCC][27] = 127, -+ [0][1][2][0][RTW89_ETSI][27] = 127, -+ [0][1][2][0][RTW89_MKK][27] = 127, -+ [0][1][2][0][RTW89_IC][27] = 127, -+ [0][1][2][0][RTW89_KCC][27] = 127, -+ [0][1][2][0][RTW89_ACMA][27] = 127, -+ [0][1][2][0][RTW89_CN][27] = 127, -+ [0][1][2][0][RTW89_UK][27] = 127, -+ [0][1][2][0][RTW89_FCC][29] = 127, -+ [0][1][2][0][RTW89_ETSI][29] = 127, -+ [0][1][2][0][RTW89_MKK][29] = 127, -+ [0][1][2][0][RTW89_IC][29] = 127, -+ [0][1][2][0][RTW89_KCC][29] = 127, -+ [0][1][2][0][RTW89_ACMA][29] = 127, -+ [0][1][2][0][RTW89_CN][29] = 127, -+ [0][1][2][0][RTW89_UK][29] = 127, -+ [0][1][2][0][RTW89_FCC][31] = 127, -+ [0][1][2][0][RTW89_ETSI][31] = 127, -+ [0][1][2][0][RTW89_MKK][31] = 127, -+ [0][1][2][0][RTW89_IC][31] = 127, -+ [0][1][2][0][RTW89_KCC][31] = 127, -+ [0][1][2][0][RTW89_ACMA][31] = 127, -+ [0][1][2][0][RTW89_CN][31] = 127, -+ [0][1][2][0][RTW89_UK][31] = 127, -+ [0][1][2][0][RTW89_FCC][33] = 127, -+ [0][1][2][0][RTW89_ETSI][33] = 127, -+ [0][1][2][0][RTW89_MKK][33] = 127, -+ [0][1][2][0][RTW89_IC][33] = 127, -+ [0][1][2][0][RTW89_KCC][33] = 127, -+ [0][1][2][0][RTW89_ACMA][33] = 127, -+ [0][1][2][0][RTW89_CN][33] = 127, -+ [0][1][2][0][RTW89_UK][33] = 127, -+ [0][1][2][0][RTW89_FCC][35] = 127, -+ [0][1][2][0][RTW89_ETSI][35] = 127, -+ [0][1][2][0][RTW89_MKK][35] = 127, -+ [0][1][2][0][RTW89_IC][35] = 127, -+ [0][1][2][0][RTW89_KCC][35] = 127, -+ [0][1][2][0][RTW89_ACMA][35] = 127, -+ [0][1][2][0][RTW89_CN][35] = 127, -+ [0][1][2][0][RTW89_UK][35] = 127, -+ [0][1][2][0][RTW89_FCC][37] = 127, -+ [0][1][2][0][RTW89_ETSI][37] = 127, -+ [0][1][2][0][RTW89_MKK][37] = 127, -+ [0][1][2][0][RTW89_IC][37] = 127, -+ [0][1][2][0][RTW89_KCC][37] = 127, -+ [0][1][2][0][RTW89_ACMA][37] = 127, -+ [0][1][2][0][RTW89_CN][37] = 127, -+ [0][1][2][0][RTW89_UK][37] = 127, -+ [0][1][2][0][RTW89_FCC][38] = 127, -+ [0][1][2][0][RTW89_ETSI][38] = 127, -+ [0][1][2][0][RTW89_MKK][38] = 127, -+ [0][1][2][0][RTW89_IC][38] = 127, -+ [0][1][2][0][RTW89_KCC][38] = 127, -+ [0][1][2][0][RTW89_ACMA][38] = 127, -+ [0][1][2][0][RTW89_CN][38] = 127, -+ [0][1][2][0][RTW89_UK][38] = 127, -+ [0][1][2][0][RTW89_FCC][40] = 127, -+ [0][1][2][0][RTW89_ETSI][40] = 127, -+ [0][1][2][0][RTW89_MKK][40] = 127, -+ [0][1][2][0][RTW89_IC][40] = 127, -+ [0][1][2][0][RTW89_KCC][40] = 127, -+ [0][1][2][0][RTW89_ACMA][40] = 127, -+ [0][1][2][0][RTW89_CN][40] = 127, -+ [0][1][2][0][RTW89_UK][40] = 127, -+ [0][1][2][0][RTW89_FCC][42] = 127, -+ [0][1][2][0][RTW89_ETSI][42] = 127, -+ [0][1][2][0][RTW89_MKK][42] = 127, -+ [0][1][2][0][RTW89_IC][42] = 127, -+ [0][1][2][0][RTW89_KCC][42] = 127, -+ [0][1][2][0][RTW89_ACMA][42] = 127, -+ [0][1][2][0][RTW89_CN][42] = 127, -+ [0][1][2][0][RTW89_UK][42] = 127, -+ [0][1][2][0][RTW89_FCC][44] = 127, -+ [0][1][2][0][RTW89_ETSI][44] = 127, -+ [0][1][2][0][RTW89_MKK][44] = 127, -+ [0][1][2][0][RTW89_IC][44] = 127, -+ [0][1][2][0][RTW89_KCC][44] = 127, -+ [0][1][2][0][RTW89_ACMA][44] = 127, -+ [0][1][2][0][RTW89_CN][44] = 127, -+ [0][1][2][0][RTW89_UK][44] = 127, -+ [0][1][2][0][RTW89_FCC][46] = 127, -+ [0][1][2][0][RTW89_ETSI][46] = 127, -+ [0][1][2][0][RTW89_MKK][46] = 127, -+ [0][1][2][0][RTW89_IC][46] = 127, -+ [0][1][2][0][RTW89_KCC][46] = 127, -+ [0][1][2][0][RTW89_ACMA][46] = 127, -+ [0][1][2][0][RTW89_CN][46] = 127, -+ [0][1][2][0][RTW89_UK][46] = 127, -+ [0][1][2][0][RTW89_FCC][48] = 127, -+ [0][1][2][0][RTW89_ETSI][48] = 127, -+ [0][1][2][0][RTW89_MKK][48] = 127, -+ [0][1][2][0][RTW89_IC][48] = 127, -+ [0][1][2][0][RTW89_KCC][48] = 127, -+ [0][1][2][0][RTW89_ACMA][48] = 127, -+ [0][1][2][0][RTW89_CN][48] = 127, -+ [0][1][2][0][RTW89_UK][48] = 127, -+ [0][1][2][0][RTW89_FCC][50] = 127, -+ [0][1][2][0][RTW89_ETSI][50] = 127, -+ [0][1][2][0][RTW89_MKK][50] = 127, -+ [0][1][2][0][RTW89_IC][50] = 127, -+ [0][1][2][0][RTW89_KCC][50] = 127, -+ [0][1][2][0][RTW89_ACMA][50] = 127, -+ [0][1][2][0][RTW89_CN][50] = 127, -+ [0][1][2][0][RTW89_UK][50] = 127, -+ [0][1][2][0][RTW89_FCC][52] = 127, -+ [0][1][2][0][RTW89_ETSI][52] = 127, -+ [0][1][2][0][RTW89_MKK][52] = 127, -+ [0][1][2][0][RTW89_IC][52] = 127, -+ [0][1][2][0][RTW89_KCC][52] = 127, -+ [0][1][2][0][RTW89_ACMA][52] = 127, -+ [0][1][2][0][RTW89_CN][52] = 127, -+ [0][1][2][0][RTW89_UK][52] = 127, -+ [0][1][2][1][RTW89_FCC][0] = 127, -+ [0][1][2][1][RTW89_ETSI][0] = 127, -+ [0][1][2][1][RTW89_MKK][0] = 127, -+ [0][1][2][1][RTW89_IC][0] = 127, -+ [0][1][2][1][RTW89_KCC][0] = 127, -+ [0][1][2][1][RTW89_ACMA][0] = 127, -+ [0][1][2][1][RTW89_CN][0] = 127, -+ [0][1][2][1][RTW89_UK][0] = 127, -+ [0][1][2][1][RTW89_FCC][2] = 127, -+ [0][1][2][1][RTW89_ETSI][2] = 127, -+ [0][1][2][1][RTW89_MKK][2] = 127, -+ [0][1][2][1][RTW89_IC][2] = 127, -+ [0][1][2][1][RTW89_KCC][2] = 127, -+ [0][1][2][1][RTW89_ACMA][2] = 127, -+ [0][1][2][1][RTW89_CN][2] = 127, -+ [0][1][2][1][RTW89_UK][2] = 127, -+ [0][1][2][1][RTW89_FCC][4] = 127, -+ [0][1][2][1][RTW89_ETSI][4] = 127, -+ [0][1][2][1][RTW89_MKK][4] = 127, -+ [0][1][2][1][RTW89_IC][4] = 127, -+ [0][1][2][1][RTW89_KCC][4] = 127, -+ [0][1][2][1][RTW89_ACMA][4] = 127, -+ [0][1][2][1][RTW89_CN][4] = 127, -+ [0][1][2][1][RTW89_UK][4] = 127, -+ [0][1][2][1][RTW89_FCC][6] = 127, -+ [0][1][2][1][RTW89_ETSI][6] = 127, -+ [0][1][2][1][RTW89_MKK][6] = 127, -+ [0][1][2][1][RTW89_IC][6] = 127, -+ [0][1][2][1][RTW89_KCC][6] = 127, -+ [0][1][2][1][RTW89_ACMA][6] = 127, -+ [0][1][2][1][RTW89_CN][6] = 127, -+ [0][1][2][1][RTW89_UK][6] = 127, -+ [0][1][2][1][RTW89_FCC][8] = 127, -+ [0][1][2][1][RTW89_ETSI][8] = 127, -+ [0][1][2][1][RTW89_MKK][8] = 127, -+ [0][1][2][1][RTW89_IC][8] = 127, -+ [0][1][2][1][RTW89_KCC][8] = 127, -+ [0][1][2][1][RTW89_ACMA][8] = 127, -+ [0][1][2][1][RTW89_CN][8] = 127, -+ [0][1][2][1][RTW89_UK][8] = 127, -+ [0][1][2][1][RTW89_FCC][10] = 127, -+ [0][1][2][1][RTW89_ETSI][10] = 127, -+ [0][1][2][1][RTW89_MKK][10] = 127, -+ [0][1][2][1][RTW89_IC][10] = 127, -+ [0][1][2][1][RTW89_KCC][10] = 127, -+ [0][1][2][1][RTW89_ACMA][10] = 127, -+ [0][1][2][1][RTW89_CN][10] = 127, -+ [0][1][2][1][RTW89_UK][10] = 127, -+ [0][1][2][1][RTW89_FCC][12] = 127, -+ [0][1][2][1][RTW89_ETSI][12] = 127, -+ [0][1][2][1][RTW89_MKK][12] = 127, -+ [0][1][2][1][RTW89_IC][12] = 127, -+ [0][1][2][1][RTW89_KCC][12] = 127, -+ [0][1][2][1][RTW89_ACMA][12] = 127, -+ [0][1][2][1][RTW89_CN][12] = 127, -+ [0][1][2][1][RTW89_UK][12] = 127, -+ [0][1][2][1][RTW89_FCC][14] = 127, -+ [0][1][2][1][RTW89_ETSI][14] = 127, -+ [0][1][2][1][RTW89_MKK][14] = 127, -+ [0][1][2][1][RTW89_IC][14] = 127, -+ [0][1][2][1][RTW89_KCC][14] = 127, -+ [0][1][2][1][RTW89_ACMA][14] = 127, -+ [0][1][2][1][RTW89_CN][14] = 127, -+ [0][1][2][1][RTW89_UK][14] = 127, -+ [0][1][2][1][RTW89_FCC][15] = 127, -+ [0][1][2][1][RTW89_ETSI][15] = 127, -+ [0][1][2][1][RTW89_MKK][15] = 127, -+ [0][1][2][1][RTW89_IC][15] = 127, -+ [0][1][2][1][RTW89_KCC][15] = 127, -+ [0][1][2][1][RTW89_ACMA][15] = 127, -+ [0][1][2][1][RTW89_CN][15] = 127, -+ [0][1][2][1][RTW89_UK][15] = 127, -+ [0][1][2][1][RTW89_FCC][17] = 127, -+ [0][1][2][1][RTW89_ETSI][17] = 127, -+ [0][1][2][1][RTW89_MKK][17] = 127, -+ [0][1][2][1][RTW89_IC][17] = 127, -+ [0][1][2][1][RTW89_KCC][17] = 127, -+ [0][1][2][1][RTW89_ACMA][17] = 127, -+ [0][1][2][1][RTW89_CN][17] = 127, -+ [0][1][2][1][RTW89_UK][17] = 127, -+ [0][1][2][1][RTW89_FCC][19] = 127, -+ [0][1][2][1][RTW89_ETSI][19] = 127, -+ [0][1][2][1][RTW89_MKK][19] = 127, -+ [0][1][2][1][RTW89_IC][19] = 127, -+ [0][1][2][1][RTW89_KCC][19] = 127, -+ [0][1][2][1][RTW89_ACMA][19] = 127, -+ [0][1][2][1][RTW89_CN][19] = 127, -+ [0][1][2][1][RTW89_UK][19] = 127, -+ [0][1][2][1][RTW89_FCC][21] = 127, -+ [0][1][2][1][RTW89_ETSI][21] = 127, -+ [0][1][2][1][RTW89_MKK][21] = 127, -+ [0][1][2][1][RTW89_IC][21] = 127, -+ [0][1][2][1][RTW89_KCC][21] = 127, -+ [0][1][2][1][RTW89_ACMA][21] = 127, -+ [0][1][2][1][RTW89_CN][21] = 127, -+ [0][1][2][1][RTW89_UK][21] = 127, -+ [0][1][2][1][RTW89_FCC][23] = 127, -+ [0][1][2][1][RTW89_ETSI][23] = 127, -+ [0][1][2][1][RTW89_MKK][23] = 127, -+ [0][1][2][1][RTW89_IC][23] = 127, -+ [0][1][2][1][RTW89_KCC][23] = 127, -+ [0][1][2][1][RTW89_ACMA][23] = 127, -+ [0][1][2][1][RTW89_CN][23] = 127, -+ [0][1][2][1][RTW89_UK][23] = 127, -+ [0][1][2][1][RTW89_FCC][25] = 127, -+ [0][1][2][1][RTW89_ETSI][25] = 127, -+ [0][1][2][1][RTW89_MKK][25] = 127, -+ [0][1][2][1][RTW89_IC][25] = 127, -+ [0][1][2][1][RTW89_KCC][25] = 127, -+ [0][1][2][1][RTW89_ACMA][25] = 127, -+ [0][1][2][1][RTW89_CN][25] = 127, -+ [0][1][2][1][RTW89_UK][25] = 127, -+ [0][1][2][1][RTW89_FCC][27] = 127, -+ [0][1][2][1][RTW89_ETSI][27] = 127, -+ [0][1][2][1][RTW89_MKK][27] = 127, -+ [0][1][2][1][RTW89_IC][27] = 127, -+ [0][1][2][1][RTW89_KCC][27] = 127, -+ [0][1][2][1][RTW89_ACMA][27] = 127, -+ [0][1][2][1][RTW89_CN][27] = 127, -+ [0][1][2][1][RTW89_UK][27] = 127, -+ [0][1][2][1][RTW89_FCC][29] = 127, -+ [0][1][2][1][RTW89_ETSI][29] = 127, -+ [0][1][2][1][RTW89_MKK][29] = 127, -+ [0][1][2][1][RTW89_IC][29] = 127, -+ [0][1][2][1][RTW89_KCC][29] = 127, -+ [0][1][2][1][RTW89_ACMA][29] = 127, -+ [0][1][2][1][RTW89_CN][29] = 127, -+ [0][1][2][1][RTW89_UK][29] = 127, -+ [0][1][2][1][RTW89_FCC][31] = 127, -+ [0][1][2][1][RTW89_ETSI][31] = 127, -+ [0][1][2][1][RTW89_MKK][31] = 127, -+ [0][1][2][1][RTW89_IC][31] = 127, -+ [0][1][2][1][RTW89_KCC][31] = 127, -+ [0][1][2][1][RTW89_ACMA][31] = 127, -+ [0][1][2][1][RTW89_CN][31] = 127, -+ [0][1][2][1][RTW89_UK][31] = 127, -+ [0][1][2][1][RTW89_FCC][33] = 127, -+ [0][1][2][1][RTW89_ETSI][33] = 127, -+ [0][1][2][1][RTW89_MKK][33] = 127, -+ [0][1][2][1][RTW89_IC][33] = 127, -+ [0][1][2][1][RTW89_KCC][33] = 127, -+ [0][1][2][1][RTW89_ACMA][33] = 127, -+ [0][1][2][1][RTW89_CN][33] = 127, -+ [0][1][2][1][RTW89_UK][33] = 127, -+ [0][1][2][1][RTW89_FCC][35] = 127, -+ [0][1][2][1][RTW89_ETSI][35] = 127, -+ [0][1][2][1][RTW89_MKK][35] = 127, -+ [0][1][2][1][RTW89_IC][35] = 127, -+ [0][1][2][1][RTW89_KCC][35] = 127, -+ [0][1][2][1][RTW89_ACMA][35] = 127, -+ [0][1][2][1][RTW89_CN][35] = 127, -+ [0][1][2][1][RTW89_UK][35] = 127, -+ [0][1][2][1][RTW89_FCC][37] = 127, -+ [0][1][2][1][RTW89_ETSI][37] = 127, -+ [0][1][2][1][RTW89_MKK][37] = 127, -+ [0][1][2][1][RTW89_IC][37] = 127, -+ [0][1][2][1][RTW89_KCC][37] = 127, -+ [0][1][2][1][RTW89_ACMA][37] = 127, -+ [0][1][2][1][RTW89_CN][37] = 127, -+ [0][1][2][1][RTW89_UK][37] = 127, -+ [0][1][2][1][RTW89_FCC][38] = 127, -+ [0][1][2][1][RTW89_ETSI][38] = 127, -+ [0][1][2][1][RTW89_MKK][38] = 127, -+ [0][1][2][1][RTW89_IC][38] = 127, -+ [0][1][2][1][RTW89_KCC][38] = 127, -+ [0][1][2][1][RTW89_ACMA][38] = 127, -+ [0][1][2][1][RTW89_CN][38] = 127, -+ [0][1][2][1][RTW89_UK][38] = 127, -+ [0][1][2][1][RTW89_FCC][40] = 127, -+ [0][1][2][1][RTW89_ETSI][40] = 127, -+ [0][1][2][1][RTW89_MKK][40] = 127, -+ [0][1][2][1][RTW89_IC][40] = 127, -+ [0][1][2][1][RTW89_KCC][40] = 127, -+ [0][1][2][1][RTW89_ACMA][40] = 127, -+ [0][1][2][1][RTW89_CN][40] = 127, -+ [0][1][2][1][RTW89_UK][40] = 127, -+ [0][1][2][1][RTW89_FCC][42] = 127, -+ [0][1][2][1][RTW89_ETSI][42] = 127, -+ [0][1][2][1][RTW89_MKK][42] = 127, -+ [0][1][2][1][RTW89_IC][42] = 127, -+ [0][1][2][1][RTW89_KCC][42] = 127, -+ [0][1][2][1][RTW89_ACMA][42] = 127, -+ [0][1][2][1][RTW89_CN][42] = 127, -+ [0][1][2][1][RTW89_UK][42] = 127, -+ [0][1][2][1][RTW89_FCC][44] = 127, -+ [0][1][2][1][RTW89_ETSI][44] = 127, -+ [0][1][2][1][RTW89_MKK][44] = 127, -+ [0][1][2][1][RTW89_IC][44] = 127, -+ [0][1][2][1][RTW89_KCC][44] = 127, -+ [0][1][2][1][RTW89_ACMA][44] = 127, -+ [0][1][2][1][RTW89_CN][44] = 127, -+ [0][1][2][1][RTW89_UK][44] = 127, -+ [0][1][2][1][RTW89_FCC][46] = 127, -+ [0][1][2][1][RTW89_ETSI][46] = 127, -+ [0][1][2][1][RTW89_MKK][46] = 127, -+ [0][1][2][1][RTW89_IC][46] = 127, -+ [0][1][2][1][RTW89_KCC][46] = 127, -+ [0][1][2][1][RTW89_ACMA][46] = 127, -+ [0][1][2][1][RTW89_CN][46] = 127, -+ [0][1][2][1][RTW89_UK][46] = 127, -+ [0][1][2][1][RTW89_FCC][48] = 127, -+ [0][1][2][1][RTW89_ETSI][48] = 127, -+ [0][1][2][1][RTW89_MKK][48] = 127, -+ [0][1][2][1][RTW89_IC][48] = 127, -+ [0][1][2][1][RTW89_KCC][48] = 127, -+ [0][1][2][1][RTW89_ACMA][48] = 127, -+ [0][1][2][1][RTW89_CN][48] = 127, -+ [0][1][2][1][RTW89_UK][48] = 127, -+ [0][1][2][1][RTW89_FCC][50] = 127, -+ [0][1][2][1][RTW89_ETSI][50] = 127, -+ [0][1][2][1][RTW89_MKK][50] = 127, -+ [0][1][2][1][RTW89_IC][50] = 127, -+ [0][1][2][1][RTW89_KCC][50] = 127, -+ [0][1][2][1][RTW89_ACMA][50] = 127, -+ [0][1][2][1][RTW89_CN][50] = 127, -+ [0][1][2][1][RTW89_UK][50] = 127, -+ [0][1][2][1][RTW89_FCC][52] = 127, -+ [0][1][2][1][RTW89_ETSI][52] = 127, -+ [0][1][2][1][RTW89_MKK][52] = 127, -+ [0][1][2][1][RTW89_IC][52] = 127, -+ [0][1][2][1][RTW89_KCC][52] = 127, -+ [0][1][2][1][RTW89_ACMA][52] = 127, -+ [0][1][2][1][RTW89_CN][52] = 127, -+ [0][1][2][1][RTW89_UK][52] = 127, -+ [1][0][2][0][RTW89_FCC][1] = 66, -+ [1][0][2][0][RTW89_ETSI][1] = 64, -+ [1][0][2][0][RTW89_MKK][1] = 64, -+ [1][0][2][0][RTW89_IC][1] = 64, -+ [1][0][2][0][RTW89_KCC][1] = 74, -+ [1][0][2][0][RTW89_ACMA][1] = 64, -+ [1][0][2][0][RTW89_CN][1] = 64, -+ [1][0][2][0][RTW89_UK][1] = 64, -+ [1][0][2][0][RTW89_FCC][5] = 80, -+ [1][0][2][0][RTW89_ETSI][5] = 64, -+ [1][0][2][0][RTW89_MKK][5] = 62, -+ [1][0][2][0][RTW89_IC][5] = 64, -+ [1][0][2][0][RTW89_KCC][5] = 66, -+ [1][0][2][0][RTW89_ACMA][5] = 64, -+ [1][0][2][0][RTW89_CN][5] = 64, -+ [1][0][2][0][RTW89_UK][5] = 64, -+ [1][0][2][0][RTW89_FCC][9] = 80, -+ [1][0][2][0][RTW89_ETSI][9] = 64, -+ [1][0][2][0][RTW89_MKK][9] = 64, -+ [1][0][2][0][RTW89_IC][9] = 64, -+ [1][0][2][0][RTW89_KCC][9] = 76, -+ [1][0][2][0][RTW89_ACMA][9] = 64, -+ [1][0][2][0][RTW89_CN][9] = 64, -+ [1][0][2][0][RTW89_UK][9] = 64, -+ [1][0][2][0][RTW89_FCC][13] = 64, -+ [1][0][2][0][RTW89_ETSI][13] = 64, -+ [1][0][2][0][RTW89_MKK][13] = 64, -+ [1][0][2][0][RTW89_IC][13] = 64, -+ [1][0][2][0][RTW89_KCC][13] = 72, -+ [1][0][2][0][RTW89_ACMA][13] = 64, -+ [1][0][2][0][RTW89_CN][13] = 64, -+ [1][0][2][0][RTW89_UK][13] = 64, -+ [1][0][2][0][RTW89_FCC][16] = 66, -+ [1][0][2][0][RTW89_ETSI][16] = 66, -+ [1][0][2][0][RTW89_MKK][16] = 76, -+ [1][0][2][0][RTW89_IC][16] = 66, -+ [1][0][2][0][RTW89_KCC][16] = 74, -+ [1][0][2][0][RTW89_ACMA][16] = 66, -+ [1][0][2][0][RTW89_CN][16] = 127, -+ [1][0][2][0][RTW89_UK][16] = 66, -+ [1][0][2][0][RTW89_FCC][20] = 80, -+ [1][0][2][0][RTW89_ETSI][20] = 66, -+ [1][0][2][0][RTW89_MKK][20] = 76, -+ [1][0][2][0][RTW89_IC][20] = 80, -+ [1][0][2][0][RTW89_KCC][20] = 74, -+ [1][0][2][0][RTW89_ACMA][20] = 66, -+ [1][0][2][0][RTW89_CN][20] = 127, -+ [1][0][2][0][RTW89_UK][20] = 66, -+ [1][0][2][0][RTW89_FCC][24] = 80, -+ [1][0][2][0][RTW89_ETSI][24] = 66, -+ [1][0][2][0][RTW89_MKK][24] = 76, -+ [1][0][2][0][RTW89_IC][24] = 127, -+ [1][0][2][0][RTW89_KCC][24] = 74, -+ [1][0][2][0][RTW89_ACMA][24] = 127, -+ [1][0][2][0][RTW89_CN][24] = 127, -+ [1][0][2][0][RTW89_UK][24] = 66, -+ [1][0][2][0][RTW89_FCC][28] = 80, -+ [1][0][2][0][RTW89_ETSI][28] = 66, -+ [1][0][2][0][RTW89_MKK][28] = 76, -+ [1][0][2][0][RTW89_IC][28] = 127, -+ [1][0][2][0][RTW89_KCC][28] = 74, -+ [1][0][2][0][RTW89_ACMA][28] = 127, -+ [1][0][2][0][RTW89_CN][28] = 127, -+ [1][0][2][0][RTW89_UK][28] = 66, -+ [1][0][2][0][RTW89_FCC][32] = 74, -+ [1][0][2][0][RTW89_ETSI][32] = 66, -+ [1][0][2][0][RTW89_MKK][32] = 76, -+ [1][0][2][0][RTW89_IC][32] = 74, -+ [1][0][2][0][RTW89_KCC][32] = 76, -+ [1][0][2][0][RTW89_ACMA][32] = 66, -+ [1][0][2][0][RTW89_CN][32] = 127, -+ [1][0][2][0][RTW89_UK][32] = 66, -+ [1][0][2][0][RTW89_FCC][36] = 78, -+ [1][0][2][0][RTW89_ETSI][36] = 127, -+ [1][0][2][0][RTW89_MKK][36] = 76, -+ [1][0][2][0][RTW89_IC][36] = 78, -+ [1][0][2][0][RTW89_KCC][36] = 76, -+ [1][0][2][0][RTW89_ACMA][36] = 76, -+ [1][0][2][0][RTW89_CN][36] = 127, -+ [1][0][2][0][RTW89_UK][36] = 76, -+ [1][0][2][0][RTW89_FCC][39] = 80, -+ [1][0][2][0][RTW89_ETSI][39] = 30, -+ [1][0][2][0][RTW89_MKK][39] = 127, -+ [1][0][2][0][RTW89_IC][39] = 80, -+ [1][0][2][0][RTW89_KCC][39] = 68, -+ [1][0][2][0][RTW89_ACMA][39] = 76, -+ [1][0][2][0][RTW89_CN][39] = 70, -+ [1][0][2][0][RTW89_UK][39] = 64, -+ [1][0][2][0][RTW89_FCC][43] = 80, -+ [1][0][2][0][RTW89_ETSI][43] = 30, -+ [1][0][2][0][RTW89_MKK][43] = 127, -+ [1][0][2][0][RTW89_IC][43] = 80, -+ [1][0][2][0][RTW89_KCC][43] = 76, -+ [1][0][2][0][RTW89_ACMA][43] = 76, -+ [1][0][2][0][RTW89_CN][43] = 76, -+ [1][0][2][0][RTW89_UK][43] = 64, -+ [1][0][2][0][RTW89_FCC][47] = 80, -+ [1][0][2][0][RTW89_ETSI][47] = 127, -+ [1][0][2][0][RTW89_MKK][47] = 127, -+ [1][0][2][0][RTW89_IC][47] = 127, -+ [1][0][2][0][RTW89_KCC][47] = 127, -+ [1][0][2][0][RTW89_ACMA][47] = 127, -+ [1][0][2][0][RTW89_CN][47] = 127, -+ [1][0][2][0][RTW89_UK][47] = 127, -+ [1][0][2][0][RTW89_FCC][51] = 80, -+ [1][0][2][0][RTW89_ETSI][51] = 127, -+ [1][0][2][0][RTW89_MKK][51] = 127, -+ [1][0][2][0][RTW89_IC][51] = 127, -+ [1][0][2][0][RTW89_KCC][51] = 127, -+ [1][0][2][0][RTW89_ACMA][51] = 127, -+ [1][0][2][0][RTW89_CN][51] = 127, -+ [1][0][2][0][RTW89_UK][51] = 127, -+ [1][1][2][0][RTW89_FCC][1] = 127, -+ [1][1][2][0][RTW89_ETSI][1] = 127, -+ [1][1][2][0][RTW89_MKK][1] = 127, -+ [1][1][2][0][RTW89_IC][1] = 127, -+ [1][1][2][0][RTW89_KCC][1] = 127, -+ [1][1][2][0][RTW89_ACMA][1] = 127, -+ [1][1][2][0][RTW89_CN][1] = 127, -+ [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_FCC][5] = 127, -+ [1][1][2][0][RTW89_ETSI][5] = 127, -+ [1][1][2][0][RTW89_MKK][5] = 127, -+ [1][1][2][0][RTW89_IC][5] = 127, -+ [1][1][2][0][RTW89_KCC][5] = 127, -+ [1][1][2][0][RTW89_ACMA][5] = 127, -+ [1][1][2][0][RTW89_CN][5] = 127, -+ [1][1][2][0][RTW89_UK][5] = 127, -+ [1][1][2][0][RTW89_FCC][9] = 127, -+ [1][1][2][0][RTW89_ETSI][9] = 127, -+ [1][1][2][0][RTW89_MKK][9] = 127, -+ [1][1][2][0][RTW89_IC][9] = 127, -+ [1][1][2][0][RTW89_KCC][9] = 127, -+ [1][1][2][0][RTW89_ACMA][9] = 127, -+ [1][1][2][0][RTW89_CN][9] = 127, -+ [1][1][2][0][RTW89_UK][9] = 127, -+ [1][1][2][0][RTW89_FCC][13] = 127, -+ [1][1][2][0][RTW89_ETSI][13] = 127, -+ [1][1][2][0][RTW89_MKK][13] = 127, -+ [1][1][2][0][RTW89_IC][13] = 127, -+ [1][1][2][0][RTW89_KCC][13] = 127, -+ [1][1][2][0][RTW89_ACMA][13] = 127, -+ [1][1][2][0][RTW89_CN][13] = 127, -+ [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_FCC][16] = 127, -+ [1][1][2][0][RTW89_ETSI][16] = 127, -+ [1][1][2][0][RTW89_MKK][16] = 127, -+ [1][1][2][0][RTW89_IC][16] = 127, -+ [1][1][2][0][RTW89_KCC][16] = 127, -+ [1][1][2][0][RTW89_ACMA][16] = 127, -+ [1][1][2][0][RTW89_CN][16] = 127, -+ [1][1][2][0][RTW89_UK][16] = 127, -+ [1][1][2][0][RTW89_FCC][20] = 127, -+ [1][1][2][0][RTW89_ETSI][20] = 127, -+ [1][1][2][0][RTW89_MKK][20] = 127, -+ [1][1][2][0][RTW89_IC][20] = 127, -+ [1][1][2][0][RTW89_KCC][20] = 127, -+ [1][1][2][0][RTW89_ACMA][20] = 127, -+ [1][1][2][0][RTW89_CN][20] = 127, -+ [1][1][2][0][RTW89_UK][20] = 127, -+ [1][1][2][0][RTW89_FCC][24] = 127, -+ [1][1][2][0][RTW89_ETSI][24] = 127, -+ [1][1][2][0][RTW89_MKK][24] = 127, -+ [1][1][2][0][RTW89_IC][24] = 127, -+ [1][1][2][0][RTW89_KCC][24] = 127, -+ [1][1][2][0][RTW89_ACMA][24] = 127, -+ [1][1][2][0][RTW89_CN][24] = 127, -+ [1][1][2][0][RTW89_UK][24] = 127, -+ [1][1][2][0][RTW89_FCC][28] = 127, -+ [1][1][2][0][RTW89_ETSI][28] = 127, -+ [1][1][2][0][RTW89_MKK][28] = 127, -+ [1][1][2][0][RTW89_IC][28] = 127, -+ [1][1][2][0][RTW89_KCC][28] = 127, -+ [1][1][2][0][RTW89_ACMA][28] = 127, -+ [1][1][2][0][RTW89_CN][28] = 127, -+ [1][1][2][0][RTW89_UK][28] = 127, -+ [1][1][2][0][RTW89_FCC][32] = 127, -+ [1][1][2][0][RTW89_ETSI][32] = 127, -+ [1][1][2][0][RTW89_MKK][32] = 127, -+ [1][1][2][0][RTW89_IC][32] = 127, -+ [1][1][2][0][RTW89_KCC][32] = 127, -+ [1][1][2][0][RTW89_ACMA][32] = 127, -+ [1][1][2][0][RTW89_CN][32] = 127, -+ [1][1][2][0][RTW89_UK][32] = 127, -+ [1][1][2][0][RTW89_FCC][36] = 127, -+ [1][1][2][0][RTW89_ETSI][36] = 127, -+ [1][1][2][0][RTW89_MKK][36] = 127, -+ [1][1][2][0][RTW89_IC][36] = 127, -+ [1][1][2][0][RTW89_KCC][36] = 127, -+ [1][1][2][0][RTW89_ACMA][36] = 127, -+ [1][1][2][0][RTW89_CN][36] = 127, -+ [1][1][2][0][RTW89_UK][36] = 127, -+ [1][1][2][0][RTW89_FCC][39] = 127, -+ [1][1][2][0][RTW89_ETSI][39] = 127, -+ [1][1][2][0][RTW89_MKK][39] = 127, -+ [1][1][2][0][RTW89_IC][39] = 127, -+ [1][1][2][0][RTW89_KCC][39] = 127, -+ [1][1][2][0][RTW89_ACMA][39] = 127, -+ [1][1][2][0][RTW89_CN][39] = 127, -+ [1][1][2][0][RTW89_UK][39] = 127, -+ [1][1][2][0][RTW89_FCC][43] = 127, -+ [1][1][2][0][RTW89_ETSI][43] = 127, -+ [1][1][2][0][RTW89_MKK][43] = 127, -+ [1][1][2][0][RTW89_IC][43] = 127, -+ [1][1][2][0][RTW89_KCC][43] = 127, -+ [1][1][2][0][RTW89_ACMA][43] = 127, -+ [1][1][2][0][RTW89_CN][43] = 127, -+ [1][1][2][0][RTW89_UK][43] = 127, -+ [1][1][2][0][RTW89_FCC][47] = 127, -+ [1][1][2][0][RTW89_ETSI][47] = 127, -+ [1][1][2][0][RTW89_MKK][47] = 127, -+ [1][1][2][0][RTW89_IC][47] = 127, -+ [1][1][2][0][RTW89_KCC][47] = 127, -+ [1][1][2][0][RTW89_ACMA][47] = 127, -+ [1][1][2][0][RTW89_CN][47] = 127, -+ [1][1][2][0][RTW89_UK][47] = 127, -+ [1][1][2][0][RTW89_FCC][51] = 127, -+ [1][1][2][0][RTW89_ETSI][51] = 127, -+ [1][1][2][0][RTW89_MKK][51] = 127, -+ [1][1][2][0][RTW89_IC][51] = 127, -+ [1][1][2][0][RTW89_KCC][51] = 127, -+ [1][1][2][0][RTW89_ACMA][51] = 127, -+ [1][1][2][0][RTW89_CN][51] = 127, -+ [1][1][2][0][RTW89_UK][51] = 127, -+ [1][1][2][1][RTW89_FCC][1] = 127, -+ [1][1][2][1][RTW89_ETSI][1] = 127, -+ [1][1][2][1][RTW89_MKK][1] = 127, -+ [1][1][2][1][RTW89_IC][1] = 127, -+ [1][1][2][1][RTW89_KCC][1] = 127, -+ [1][1][2][1][RTW89_ACMA][1] = 127, -+ [1][1][2][1][RTW89_CN][1] = 127, -+ [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_FCC][5] = 127, -+ [1][1][2][1][RTW89_ETSI][5] = 127, -+ [1][1][2][1][RTW89_MKK][5] = 127, -+ [1][1][2][1][RTW89_IC][5] = 127, -+ [1][1][2][1][RTW89_KCC][5] = 127, -+ [1][1][2][1][RTW89_ACMA][5] = 127, -+ [1][1][2][1][RTW89_CN][5] = 127, -+ [1][1][2][1][RTW89_UK][5] = 127, -+ [1][1][2][1][RTW89_FCC][9] = 127, -+ [1][1][2][1][RTW89_ETSI][9] = 127, -+ [1][1][2][1][RTW89_MKK][9] = 127, -+ [1][1][2][1][RTW89_IC][9] = 127, -+ [1][1][2][1][RTW89_KCC][9] = 127, -+ [1][1][2][1][RTW89_ACMA][9] = 127, -+ [1][1][2][1][RTW89_CN][9] = 127, -+ [1][1][2][1][RTW89_UK][9] = 127, -+ [1][1][2][1][RTW89_FCC][13] = 127, -+ [1][1][2][1][RTW89_ETSI][13] = 127, -+ [1][1][2][1][RTW89_MKK][13] = 127, -+ [1][1][2][1][RTW89_IC][13] = 127, -+ [1][1][2][1][RTW89_KCC][13] = 127, -+ [1][1][2][1][RTW89_ACMA][13] = 127, -+ [1][1][2][1][RTW89_CN][13] = 127, -+ [1][1][2][1][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_FCC][16] = 127, -+ [1][1][2][1][RTW89_ETSI][16] = 127, -+ [1][1][2][1][RTW89_MKK][16] = 127, -+ [1][1][2][1][RTW89_IC][16] = 127, -+ [1][1][2][1][RTW89_KCC][16] = 127, -+ [1][1][2][1][RTW89_ACMA][16] = 127, -+ [1][1][2][1][RTW89_CN][16] = 127, -+ [1][1][2][1][RTW89_UK][16] = 127, -+ [1][1][2][1][RTW89_FCC][20] = 127, -+ [1][1][2][1][RTW89_ETSI][20] = 127, -+ [1][1][2][1][RTW89_MKK][20] = 127, -+ [1][1][2][1][RTW89_IC][20] = 127, -+ [1][1][2][1][RTW89_KCC][20] = 127, -+ [1][1][2][1][RTW89_ACMA][20] = 127, -+ [1][1][2][1][RTW89_CN][20] = 127, -+ [1][1][2][1][RTW89_UK][20] = 127, -+ [1][1][2][1][RTW89_FCC][24] = 127, -+ [1][1][2][1][RTW89_ETSI][24] = 127, -+ [1][1][2][1][RTW89_MKK][24] = 127, -+ [1][1][2][1][RTW89_IC][24] = 127, -+ [1][1][2][1][RTW89_KCC][24] = 127, -+ [1][1][2][1][RTW89_ACMA][24] = 127, -+ [1][1][2][1][RTW89_CN][24] = 127, -+ [1][1][2][1][RTW89_UK][24] = 127, -+ [1][1][2][1][RTW89_FCC][28] = 127, -+ [1][1][2][1][RTW89_ETSI][28] = 127, -+ [1][1][2][1][RTW89_MKK][28] = 127, -+ [1][1][2][1][RTW89_IC][28] = 127, -+ [1][1][2][1][RTW89_KCC][28] = 127, -+ [1][1][2][1][RTW89_ACMA][28] = 127, -+ [1][1][2][1][RTW89_CN][28] = 127, -+ [1][1][2][1][RTW89_UK][28] = 127, -+ [1][1][2][1][RTW89_FCC][32] = 127, -+ [1][1][2][1][RTW89_ETSI][32] = 127, -+ [1][1][2][1][RTW89_MKK][32] = 127, -+ [1][1][2][1][RTW89_IC][32] = 127, -+ [1][1][2][1][RTW89_KCC][32] = 127, -+ [1][1][2][1][RTW89_ACMA][32] = 127, -+ [1][1][2][1][RTW89_CN][32] = 127, -+ [1][1][2][1][RTW89_UK][32] = 127, -+ [1][1][2][1][RTW89_FCC][36] = 127, -+ [1][1][2][1][RTW89_ETSI][36] = 127, -+ [1][1][2][1][RTW89_MKK][36] = 127, -+ [1][1][2][1][RTW89_IC][36] = 127, -+ [1][1][2][1][RTW89_KCC][36] = 127, -+ [1][1][2][1][RTW89_ACMA][36] = 127, -+ [1][1][2][1][RTW89_CN][36] = 127, -+ [1][1][2][1][RTW89_UK][36] = 127, -+ [1][1][2][1][RTW89_FCC][39] = 127, -+ [1][1][2][1][RTW89_ETSI][39] = 127, -+ [1][1][2][1][RTW89_MKK][39] = 127, -+ [1][1][2][1][RTW89_IC][39] = 127, -+ [1][1][2][1][RTW89_KCC][39] = 127, -+ [1][1][2][1][RTW89_ACMA][39] = 127, -+ [1][1][2][1][RTW89_CN][39] = 127, -+ [1][1][2][1][RTW89_UK][39] = 127, -+ [1][1][2][1][RTW89_FCC][43] = 127, -+ [1][1][2][1][RTW89_ETSI][43] = 127, -+ [1][1][2][1][RTW89_MKK][43] = 127, -+ [1][1][2][1][RTW89_IC][43] = 127, -+ [1][1][2][1][RTW89_KCC][43] = 127, -+ [1][1][2][1][RTW89_ACMA][43] = 127, -+ [1][1][2][1][RTW89_CN][43] = 127, -+ [1][1][2][1][RTW89_UK][43] = 127, -+ [1][1][2][1][RTW89_FCC][47] = 127, -+ [1][1][2][1][RTW89_ETSI][47] = 127, -+ [1][1][2][1][RTW89_MKK][47] = 127, -+ [1][1][2][1][RTW89_IC][47] = 127, -+ [1][1][2][1][RTW89_KCC][47] = 127, -+ [1][1][2][1][RTW89_ACMA][47] = 127, -+ [1][1][2][1][RTW89_CN][47] = 127, -+ [1][1][2][1][RTW89_UK][47] = 127, -+ [1][1][2][1][RTW89_FCC][51] = 127, -+ [1][1][2][1][RTW89_ETSI][51] = 127, -+ [1][1][2][1][RTW89_MKK][51] = 127, -+ [1][1][2][1][RTW89_IC][51] = 127, -+ [1][1][2][1][RTW89_KCC][51] = 127, -+ [1][1][2][1][RTW89_ACMA][51] = 127, -+ [1][1][2][1][RTW89_CN][51] = 127, -+ [1][1][2][1][RTW89_UK][51] = 127, -+ [2][0][2][0][RTW89_FCC][3] = 72, -+ [2][0][2][0][RTW89_ETSI][3] = 64, -+ [2][0][2][0][RTW89_MKK][3] = 62, -+ [2][0][2][0][RTW89_IC][3] = 64, -+ [2][0][2][0][RTW89_KCC][3] = 68, -+ [2][0][2][0][RTW89_ACMA][3] = 64, -+ [2][0][2][0][RTW89_CN][3] = 64, -+ [2][0][2][0][RTW89_UK][3] = 64, -+ [2][0][2][0][RTW89_FCC][11] = 62, -+ [2][0][2][0][RTW89_ETSI][11] = 64, -+ [2][0][2][0][RTW89_MKK][11] = 64, -+ [2][0][2][0][RTW89_IC][11] = 62, -+ [2][0][2][0][RTW89_KCC][11] = 68, -+ [2][0][2][0][RTW89_ACMA][11] = 64, -+ [2][0][2][0][RTW89_CN][11] = 64, -+ [2][0][2][0][RTW89_UK][11] = 64, -+ [2][0][2][0][RTW89_FCC][18] = 66, -+ [2][0][2][0][RTW89_ETSI][18] = 64, -+ [2][0][2][0][RTW89_MKK][18] = 68, -+ [2][0][2][0][RTW89_IC][18] = 66, -+ [2][0][2][0][RTW89_KCC][18] = 68, -+ [2][0][2][0][RTW89_ACMA][18] = 64, -+ [2][0][2][0][RTW89_CN][18] = 127, -+ [2][0][2][0][RTW89_UK][18] = 64, -+ [2][0][2][0][RTW89_FCC][26] = 72, -+ [2][0][2][0][RTW89_ETSI][26] = 64, -+ [2][0][2][0][RTW89_MKK][26] = 68, -+ [2][0][2][0][RTW89_IC][26] = 127, -+ [2][0][2][0][RTW89_KCC][26] = 68, -+ [2][0][2][0][RTW89_ACMA][26] = 127, -+ [2][0][2][0][RTW89_CN][26] = 127, -+ [2][0][2][0][RTW89_UK][26] = 64, -+ [2][0][2][0][RTW89_FCC][34] = 72, -+ [2][0][2][0][RTW89_ETSI][34] = 127, -+ [2][0][2][0][RTW89_MKK][34] = 68, -+ [2][0][2][0][RTW89_IC][34] = 72, -+ [2][0][2][0][RTW89_KCC][34] = 68, -+ [2][0][2][0][RTW89_ACMA][34] = 68, -+ [2][0][2][0][RTW89_CN][34] = 127, -+ [2][0][2][0][RTW89_UK][34] = 68, -+ [2][0][2][0][RTW89_FCC][41] = 72, -+ [2][0][2][0][RTW89_ETSI][41] = 30, -+ [2][0][2][0][RTW89_MKK][41] = 127, -+ [2][0][2][0][RTW89_IC][41] = 72, -+ [2][0][2][0][RTW89_KCC][41] = 64, -+ [2][0][2][0][RTW89_ACMA][41] = 68, -+ [2][0][2][0][RTW89_CN][41] = 68, -+ [2][0][2][0][RTW89_UK][41] = 64, -+ [2][0][2][0][RTW89_FCC][49] = 72, -+ [2][0][2][0][RTW89_ETSI][49] = 127, -+ [2][0][2][0][RTW89_MKK][49] = 127, -+ [2][0][2][0][RTW89_IC][49] = 127, -+ [2][0][2][0][RTW89_KCC][49] = 127, -+ [2][0][2][0][RTW89_ACMA][49] = 127, -+ [2][0][2][0][RTW89_CN][49] = 127, -+ [2][0][2][0][RTW89_UK][49] = 127, -+ [2][1][2][0][RTW89_FCC][3] = 127, -+ [2][1][2][0][RTW89_ETSI][3] = 127, -+ [2][1][2][0][RTW89_MKK][3] = 127, -+ [2][1][2][0][RTW89_IC][3] = 127, -+ [2][1][2][0][RTW89_KCC][3] = 127, -+ [2][1][2][0][RTW89_ACMA][3] = 127, -+ [2][1][2][0][RTW89_CN][3] = 127, -+ [2][1][2][0][RTW89_UK][3] = 127, -+ [2][1][2][0][RTW89_FCC][11] = 127, -+ [2][1][2][0][RTW89_ETSI][11] = 127, -+ [2][1][2][0][RTW89_MKK][11] = 127, -+ [2][1][2][0][RTW89_IC][11] = 127, -+ [2][1][2][0][RTW89_KCC][11] = 127, -+ [2][1][2][0][RTW89_ACMA][11] = 127, -+ [2][1][2][0][RTW89_CN][11] = 127, -+ [2][1][2][0][RTW89_UK][11] = 127, -+ [2][1][2][0][RTW89_FCC][18] = 127, -+ [2][1][2][0][RTW89_ETSI][18] = 127, -+ [2][1][2][0][RTW89_MKK][18] = 127, -+ [2][1][2][0][RTW89_IC][18] = 127, -+ [2][1][2][0][RTW89_KCC][18] = 127, -+ [2][1][2][0][RTW89_ACMA][18] = 127, -+ [2][1][2][0][RTW89_CN][18] = 127, -+ [2][1][2][0][RTW89_UK][18] = 127, -+ [2][1][2][0][RTW89_FCC][26] = 127, -+ [2][1][2][0][RTW89_ETSI][26] = 127, -+ [2][1][2][0][RTW89_MKK][26] = 127, -+ [2][1][2][0][RTW89_IC][26] = 127, -+ [2][1][2][0][RTW89_KCC][26] = 127, -+ [2][1][2][0][RTW89_ACMA][26] = 127, -+ [2][1][2][0][RTW89_CN][26] = 127, -+ [2][1][2][0][RTW89_UK][26] = 127, -+ [2][1][2][0][RTW89_FCC][34] = 127, -+ [2][1][2][0][RTW89_ETSI][34] = 127, -+ [2][1][2][0][RTW89_MKK][34] = 127, -+ [2][1][2][0][RTW89_IC][34] = 127, -+ [2][1][2][0][RTW89_KCC][34] = 127, -+ [2][1][2][0][RTW89_ACMA][34] = 127, -+ [2][1][2][0][RTW89_CN][34] = 127, -+ [2][1][2][0][RTW89_UK][34] = 127, -+ [2][1][2][0][RTW89_FCC][41] = 127, -+ [2][1][2][0][RTW89_ETSI][41] = 127, -+ [2][1][2][0][RTW89_MKK][41] = 127, -+ [2][1][2][0][RTW89_IC][41] = 127, -+ [2][1][2][0][RTW89_KCC][41] = 127, -+ [2][1][2][0][RTW89_ACMA][41] = 127, -+ [2][1][2][0][RTW89_CN][41] = 127, -+ [2][1][2][0][RTW89_UK][41] = 127, -+ [2][1][2][0][RTW89_FCC][49] = 127, -+ [2][1][2][0][RTW89_ETSI][49] = 127, -+ [2][1][2][0][RTW89_MKK][49] = 127, -+ [2][1][2][0][RTW89_IC][49] = 127, -+ [2][1][2][0][RTW89_KCC][49] = 127, -+ [2][1][2][0][RTW89_ACMA][49] = 127, -+ [2][1][2][0][RTW89_CN][49] = 127, -+ [2][1][2][0][RTW89_UK][49] = 127, -+ [2][1][2][1][RTW89_FCC][3] = 127, -+ [2][1][2][1][RTW89_ETSI][3] = 127, -+ [2][1][2][1][RTW89_MKK][3] = 127, -+ [2][1][2][1][RTW89_IC][3] = 127, -+ [2][1][2][1][RTW89_KCC][3] = 127, -+ [2][1][2][1][RTW89_ACMA][3] = 127, -+ [2][1][2][1][RTW89_CN][3] = 127, -+ [2][1][2][1][RTW89_UK][3] = 127, -+ [2][1][2][1][RTW89_FCC][11] = 127, -+ [2][1][2][1][RTW89_ETSI][11] = 127, -+ [2][1][2][1][RTW89_MKK][11] = 127, -+ [2][1][2][1][RTW89_IC][11] = 127, -+ [2][1][2][1][RTW89_KCC][11] = 127, -+ [2][1][2][1][RTW89_ACMA][11] = 127, -+ [2][1][2][1][RTW89_CN][11] = 127, -+ [2][1][2][1][RTW89_UK][11] = 127, -+ [2][1][2][1][RTW89_FCC][18] = 127, -+ [2][1][2][1][RTW89_ETSI][18] = 127, -+ [2][1][2][1][RTW89_MKK][18] = 127, -+ [2][1][2][1][RTW89_IC][18] = 127, -+ [2][1][2][1][RTW89_KCC][18] = 127, -+ [2][1][2][1][RTW89_ACMA][18] = 127, -+ [2][1][2][1][RTW89_CN][18] = 127, -+ [2][1][2][1][RTW89_UK][18] = 127, -+ [2][1][2][1][RTW89_FCC][26] = 127, -+ [2][1][2][1][RTW89_ETSI][26] = 127, -+ [2][1][2][1][RTW89_MKK][26] = 127, -+ [2][1][2][1][RTW89_IC][26] = 127, -+ [2][1][2][1][RTW89_KCC][26] = 127, -+ [2][1][2][1][RTW89_ACMA][26] = 127, -+ [2][1][2][1][RTW89_CN][26] = 127, -+ [2][1][2][1][RTW89_UK][26] = 127, -+ [2][1][2][1][RTW89_FCC][34] = 127, -+ [2][1][2][1][RTW89_ETSI][34] = 127, -+ [2][1][2][1][RTW89_MKK][34] = 127, -+ [2][1][2][1][RTW89_IC][34] = 127, -+ [2][1][2][1][RTW89_KCC][34] = 127, -+ [2][1][2][1][RTW89_ACMA][34] = 127, -+ [2][1][2][1][RTW89_CN][34] = 127, -+ [2][1][2][1][RTW89_UK][34] = 127, -+ [2][1][2][1][RTW89_FCC][41] = 127, -+ [2][1][2][1][RTW89_ETSI][41] = 127, -+ [2][1][2][1][RTW89_MKK][41] = 127, -+ [2][1][2][1][RTW89_IC][41] = 127, -+ [2][1][2][1][RTW89_KCC][41] = 127, -+ [2][1][2][1][RTW89_ACMA][41] = 127, -+ [2][1][2][1][RTW89_CN][41] = 127, -+ [2][1][2][1][RTW89_UK][41] = 127, -+ [2][1][2][1][RTW89_FCC][49] = 127, -+ [2][1][2][1][RTW89_ETSI][49] = 127, -+ [2][1][2][1][RTW89_MKK][49] = 127, -+ [2][1][2][1][RTW89_IC][49] = 127, -+ [2][1][2][1][RTW89_KCC][49] = 127, -+ [2][1][2][1][RTW89_ACMA][49] = 127, -+ [2][1][2][1][RTW89_CN][49] = 127, -+ [2][1][2][1][RTW89_UK][49] = 127, -+ [3][0][2][0][RTW89_FCC][7] = 127, -+ [3][0][2][0][RTW89_ETSI][7] = 127, -+ [3][0][2][0][RTW89_MKK][7] = 127, -+ [3][0][2][0][RTW89_IC][7] = 127, -+ [3][0][2][0][RTW89_KCC][7] = 127, -+ [3][0][2][0][RTW89_ACMA][7] = 127, -+ [3][0][2][0][RTW89_CN][7] = 58, -+ [3][0][2][0][RTW89_UK][7] = 127, -+ [3][0][2][0][RTW89_FCC][22] = 127, -+ [3][0][2][0][RTW89_ETSI][22] = 127, -+ [3][0][2][0][RTW89_MKK][22] = 127, -+ [3][0][2][0][RTW89_IC][22] = 127, -+ [3][0][2][0][RTW89_KCC][22] = 127, -+ [3][0][2][0][RTW89_ACMA][22] = 127, -+ [3][0][2][0][RTW89_CN][22] = 58, -+ [3][0][2][0][RTW89_UK][22] = 127, -+ [3][0][2][0][RTW89_FCC][45] = 127, -+ [3][0][2][0][RTW89_ETSI][45] = 127, -+ [3][0][2][0][RTW89_MKK][45] = 127, -+ [3][0][2][0][RTW89_IC][45] = 127, -+ [3][0][2][0][RTW89_KCC][45] = 127, -+ [3][0][2][0][RTW89_ACMA][45] = 127, -+ [3][0][2][0][RTW89_CN][45] = 127, -+ [3][0][2][0][RTW89_UK][45] = 127, -+ [3][1][2][0][RTW89_FCC][7] = 127, -+ [3][1][2][0][RTW89_ETSI][7] = 127, -+ [3][1][2][0][RTW89_MKK][7] = 127, -+ [3][1][2][0][RTW89_IC][7] = 127, -+ [3][1][2][0][RTW89_KCC][7] = 127, -+ [3][1][2][0][RTW89_ACMA][7] = 127, -+ [3][1][2][0][RTW89_CN][7] = 127, -+ [3][1][2][0][RTW89_UK][7] = 127, -+ [3][1][2][0][RTW89_FCC][22] = 127, -+ [3][1][2][0][RTW89_ETSI][22] = 127, -+ [3][1][2][0][RTW89_MKK][22] = 127, -+ [3][1][2][0][RTW89_IC][22] = 127, -+ [3][1][2][0][RTW89_KCC][22] = 127, -+ [3][1][2][0][RTW89_ACMA][22] = 127, -+ [3][1][2][0][RTW89_CN][22] = 127, -+ [3][1][2][0][RTW89_UK][22] = 127, -+ [3][1][2][0][RTW89_FCC][45] = 127, -+ [3][1][2][0][RTW89_ETSI][45] = 127, -+ [3][1][2][0][RTW89_MKK][45] = 127, -+ [3][1][2][0][RTW89_IC][45] = 127, -+ [3][1][2][0][RTW89_KCC][45] = 127, -+ [3][1][2][0][RTW89_ACMA][45] = 127, -+ [3][1][2][0][RTW89_CN][45] = 127, -+ [3][1][2][0][RTW89_UK][45] = 127, -+ [3][1][2][1][RTW89_FCC][7] = 127, -+ [3][1][2][1][RTW89_ETSI][7] = 127, -+ [3][1][2][1][RTW89_MKK][7] = 127, -+ [3][1][2][1][RTW89_IC][7] = 127, -+ [3][1][2][1][RTW89_KCC][7] = 127, -+ [3][1][2][1][RTW89_ACMA][7] = 127, -+ [3][1][2][1][RTW89_CN][7] = 127, -+ [3][1][2][1][RTW89_UK][7] = 127, -+ [3][1][2][1][RTW89_FCC][22] = 127, -+ [3][1][2][1][RTW89_ETSI][22] = 127, -+ [3][1][2][1][RTW89_MKK][22] = 127, -+ [3][1][2][1][RTW89_IC][22] = 127, -+ [3][1][2][1][RTW89_KCC][22] = 127, -+ [3][1][2][1][RTW89_ACMA][22] = 127, -+ [3][1][2][1][RTW89_CN][22] = 127, -+ [3][1][2][1][RTW89_UK][22] = 127, -+ [3][1][2][1][RTW89_FCC][45] = 127, -+ [3][1][2][1][RTW89_ETSI][45] = 127, -+ [3][1][2][1][RTW89_MKK][45] = 127, -+ [3][1][2][1][RTW89_IC][45] = 127, -+ [3][1][2][1][RTW89_KCC][45] = 127, -+ [3][1][2][1][RTW89_ACMA][45] = 127, -+ [3][1][2][1][RTW89_CN][45] = 127, -+ [3][1][2][1][RTW89_UK][45] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_ru_2g_type2[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 30, -+ [0][0][RTW89_WW][1] = 30, -+ [0][0][RTW89_WW][2] = 30, -+ [0][0][RTW89_WW][3] = 30, -+ [0][0][RTW89_WW][4] = 30, -+ [0][0][RTW89_WW][5] = 30, -+ [0][0][RTW89_WW][6] = 30, -+ [0][0][RTW89_WW][7] = 30, -+ [0][0][RTW89_WW][8] = 30, -+ [0][0][RTW89_WW][9] = 30, -+ [0][0][RTW89_WW][10] = 30, -+ [0][0][RTW89_WW][11] = 30, -+ [0][0][RTW89_WW][12] = 30, -+ [0][0][RTW89_WW][13] = 0, -+ [0][1][RTW89_WW][0] = 20, -+ [0][1][RTW89_WW][1] = 22, -+ [0][1][RTW89_WW][2] = 22, -+ [0][1][RTW89_WW][3] = 22, -+ [0][1][RTW89_WW][4] = 22, -+ [0][1][RTW89_WW][5] = 22, -+ [0][1][RTW89_WW][6] = 22, -+ [0][1][RTW89_WW][7] = 22, -+ [0][1][RTW89_WW][8] = 22, -+ [0][1][RTW89_WW][9] = 22, -+ [0][1][RTW89_WW][10] = 22, -+ [0][1][RTW89_WW][11] = 22, -+ [0][1][RTW89_WW][12] = 20, -+ [0][1][RTW89_WW][13] = 0, -+ [1][0][RTW89_WW][0] = 42, -+ [1][0][RTW89_WW][1] = 42, -+ [1][0][RTW89_WW][2] = 42, -+ [1][0][RTW89_WW][3] = 42, -+ [1][0][RTW89_WW][4] = 42, -+ [1][0][RTW89_WW][5] = 42, -+ [1][0][RTW89_WW][6] = 42, -+ [1][0][RTW89_WW][7] = 42, -+ [1][0][RTW89_WW][8] = 42, -+ [1][0][RTW89_WW][9] = 42, -+ [1][0][RTW89_WW][10] = 42, -+ [1][0][RTW89_WW][11] = 42, -+ [1][0][RTW89_WW][12] = 34, -+ [1][0][RTW89_WW][13] = 0, -+ [1][1][RTW89_WW][0] = 32, -+ [1][1][RTW89_WW][1] = 32, -+ [1][1][RTW89_WW][2] = 32, -+ [1][1][RTW89_WW][3] = 32, -+ [1][1][RTW89_WW][4] = 32, -+ [1][1][RTW89_WW][5] = 32, -+ [1][1][RTW89_WW][6] = 32, -+ [1][1][RTW89_WW][7] = 32, -+ [1][1][RTW89_WW][8] = 32, -+ [1][1][RTW89_WW][9] = 32, -+ [1][1][RTW89_WW][10] = 32, -+ [1][1][RTW89_WW][11] = 32, -+ [1][1][RTW89_WW][12] = 32, -+ [1][1][RTW89_WW][13] = 0, -+ [2][0][RTW89_WW][0] = 54, -+ [2][0][RTW89_WW][1] = 54, -+ [2][0][RTW89_WW][2] = 54, -+ [2][0][RTW89_WW][3] = 54, -+ [2][0][RTW89_WW][4] = 54, -+ [2][0][RTW89_WW][5] = 54, -+ [2][0][RTW89_WW][6] = 54, -+ [2][0][RTW89_WW][7] = 54, -+ [2][0][RTW89_WW][8] = 54, -+ [2][0][RTW89_WW][9] = 54, -+ [2][0][RTW89_WW][10] = 54, -+ [2][0][RTW89_WW][11] = 54, -+ [2][0][RTW89_WW][12] = 34, -+ [2][0][RTW89_WW][13] = 0, -+ [2][1][RTW89_WW][0] = 44, -+ [2][1][RTW89_WW][1] = 44, -+ [2][1][RTW89_WW][2] = 44, -+ [2][1][RTW89_WW][3] = 44, -+ [2][1][RTW89_WW][4] = 44, -+ [2][1][RTW89_WW][5] = 44, -+ [2][1][RTW89_WW][6] = 44, -+ [2][1][RTW89_WW][7] = 44, -+ [2][1][RTW89_WW][8] = 44, -+ [2][1][RTW89_WW][9] = 44, -+ [2][1][RTW89_WW][10] = 44, -+ [2][1][RTW89_WW][11] = 44, -+ [2][1][RTW89_WW][12] = 42, -+ [2][1][RTW89_WW][13] = 0, -+ [0][0][RTW89_FCC][0] = 60, -+ [0][0][RTW89_ETSI][0] = 30, -+ [0][0][RTW89_MKK][0] = 40, -+ [0][0][RTW89_IC][0] = 60, -+ [0][0][RTW89_KCC][0] = 46, -+ [0][0][RTW89_ACMA][0] = 30, -+ [0][0][RTW89_CN][0] = 32, -+ [0][0][RTW89_UK][0] = 30, -+ [0][0][RTW89_FCC][1] = 60, -+ [0][0][RTW89_ETSI][1] = 30, -+ [0][0][RTW89_MKK][1] = 44, -+ [0][0][RTW89_IC][1] = 60, -+ [0][0][RTW89_KCC][1] = 46, -+ [0][0][RTW89_ACMA][1] = 30, -+ [0][0][RTW89_CN][1] = 32, -+ [0][0][RTW89_UK][1] = 30, -+ [0][0][RTW89_FCC][2] = 64, -+ [0][0][RTW89_ETSI][2] = 30, -+ [0][0][RTW89_MKK][2] = 44, -+ [0][0][RTW89_IC][2] = 64, -+ [0][0][RTW89_KCC][2] = 46, -+ [0][0][RTW89_ACMA][2] = 30, -+ [0][0][RTW89_CN][2] = 32, -+ [0][0][RTW89_UK][2] = 30, -+ [0][0][RTW89_FCC][3] = 68, -+ [0][0][RTW89_ETSI][3] = 30, -+ [0][0][RTW89_MKK][3] = 44, -+ [0][0][RTW89_IC][3] = 68, -+ [0][0][RTW89_KCC][3] = 46, -+ [0][0][RTW89_ACMA][3] = 30, -+ [0][0][RTW89_CN][3] = 32, -+ [0][0][RTW89_UK][3] = 30, -+ [0][0][RTW89_FCC][4] = 68, -+ [0][0][RTW89_ETSI][4] = 30, -+ [0][0][RTW89_MKK][4] = 44, -+ [0][0][RTW89_IC][4] = 68, -+ [0][0][RTW89_KCC][4] = 48, -+ [0][0][RTW89_ACMA][4] = 30, -+ [0][0][RTW89_CN][4] = 32, -+ [0][0][RTW89_UK][4] = 30, -+ [0][0][RTW89_FCC][5] = 82, -+ [0][0][RTW89_ETSI][5] = 30, -+ [0][0][RTW89_MKK][5] = 44, -+ [0][0][RTW89_IC][5] = 82, -+ [0][0][RTW89_KCC][5] = 48, -+ [0][0][RTW89_ACMA][5] = 30, -+ [0][0][RTW89_CN][5] = 32, -+ [0][0][RTW89_UK][5] = 30, -+ [0][0][RTW89_FCC][6] = 64, -+ [0][0][RTW89_ETSI][6] = 30, -+ [0][0][RTW89_MKK][6] = 44, -+ [0][0][RTW89_IC][6] = 64, -+ [0][0][RTW89_KCC][6] = 48, -+ [0][0][RTW89_ACMA][6] = 30, -+ [0][0][RTW89_CN][6] = 32, -+ [0][0][RTW89_UK][6] = 30, -+ [0][0][RTW89_FCC][7] = 64, -+ [0][0][RTW89_ETSI][7] = 30, -+ [0][0][RTW89_MKK][7] = 44, -+ [0][0][RTW89_IC][7] = 64, -+ [0][0][RTW89_KCC][7] = 48, -+ [0][0][RTW89_ACMA][7] = 30, -+ [0][0][RTW89_CN][7] = 32, -+ [0][0][RTW89_UK][7] = 30, -+ [0][0][RTW89_FCC][8] = 60, -+ [0][0][RTW89_ETSI][8] = 30, -+ [0][0][RTW89_MKK][8] = 44, -+ [0][0][RTW89_IC][8] = 60, -+ [0][0][RTW89_KCC][8] = 48, -+ [0][0][RTW89_ACMA][8] = 30, -+ [0][0][RTW89_CN][8] = 32, -+ [0][0][RTW89_UK][8] = 30, -+ [0][0][RTW89_FCC][9] = 56, -+ [0][0][RTW89_ETSI][9] = 30, -+ [0][0][RTW89_MKK][9] = 44, -+ [0][0][RTW89_IC][9] = 56, -+ [0][0][RTW89_KCC][9] = 44, -+ [0][0][RTW89_ACMA][9] = 30, -+ [0][0][RTW89_CN][9] = 32, -+ [0][0][RTW89_UK][9] = 30, -+ [0][0][RTW89_FCC][10] = 56, -+ [0][0][RTW89_ETSI][10] = 30, -+ [0][0][RTW89_MKK][10] = 44, -+ [0][0][RTW89_IC][10] = 56, -+ [0][0][RTW89_KCC][10] = 44, -+ [0][0][RTW89_ACMA][10] = 30, -+ [0][0][RTW89_CN][10] = 32, -+ [0][0][RTW89_UK][10] = 30, -+ [0][0][RTW89_FCC][11] = 54, -+ [0][0][RTW89_ETSI][11] = 30, -+ [0][0][RTW89_MKK][11] = 44, -+ [0][0][RTW89_IC][11] = 54, -+ [0][0][RTW89_KCC][11] = 44, -+ [0][0][RTW89_ACMA][11] = 30, -+ [0][0][RTW89_CN][11] = 32, -+ [0][0][RTW89_UK][11] = 30, -+ [0][0][RTW89_FCC][12] = 34, -+ [0][0][RTW89_ETSI][12] = 30, -+ [0][0][RTW89_MKK][12] = 40, -+ [0][0][RTW89_IC][12] = 34, -+ [0][0][RTW89_KCC][12] = 44, -+ [0][0][RTW89_ACMA][12] = 30, -+ [0][0][RTW89_CN][12] = 32, -+ [0][0][RTW89_UK][12] = 30, -+ [0][0][RTW89_FCC][13] = 127, -+ [0][0][RTW89_ETSI][13] = 127, -+ [0][0][RTW89_MKK][13] = 127, -+ [0][0][RTW89_IC][13] = 127, -+ [0][0][RTW89_KCC][13] = 127, -+ [0][0][RTW89_ACMA][13] = 127, -+ [0][0][RTW89_CN][13] = 127, -+ [0][0][RTW89_UK][13] = 127, -+ [0][1][RTW89_FCC][0] = 127, -+ [0][1][RTW89_ETSI][0] = 127, -+ [0][1][RTW89_MKK][0] = 127, -+ [0][1][RTW89_IC][0] = 127, -+ [0][1][RTW89_KCC][0] = 127, -+ [0][1][RTW89_ACMA][0] = 127, -+ [0][1][RTW89_CN][0] = 20, -+ [0][1][RTW89_UK][0] = 127, -+ [0][1][RTW89_FCC][1] = 127, -+ [0][1][RTW89_ETSI][1] = 127, -+ [0][1][RTW89_MKK][1] = 127, -+ [0][1][RTW89_IC][1] = 127, -+ [0][1][RTW89_KCC][1] = 127, -+ [0][1][RTW89_ACMA][1] = 127, -+ [0][1][RTW89_CN][1] = 22, -+ [0][1][RTW89_UK][1] = 127, -+ [0][1][RTW89_FCC][2] = 127, -+ [0][1][RTW89_ETSI][2] = 127, -+ [0][1][RTW89_MKK][2] = 127, -+ [0][1][RTW89_IC][2] = 127, -+ [0][1][RTW89_KCC][2] = 127, -+ [0][1][RTW89_ACMA][2] = 127, -+ [0][1][RTW89_CN][2] = 22, -+ [0][1][RTW89_UK][2] = 127, -+ [0][1][RTW89_FCC][3] = 127, -+ [0][1][RTW89_ETSI][3] = 127, -+ [0][1][RTW89_MKK][3] = 127, -+ [0][1][RTW89_IC][3] = 127, -+ [0][1][RTW89_KCC][3] = 127, -+ [0][1][RTW89_ACMA][3] = 127, -+ [0][1][RTW89_CN][3] = 22, -+ [0][1][RTW89_UK][3] = 127, -+ [0][1][RTW89_FCC][4] = 127, -+ [0][1][RTW89_ETSI][4] = 127, -+ [0][1][RTW89_MKK][4] = 127, -+ [0][1][RTW89_IC][4] = 127, -+ [0][1][RTW89_KCC][4] = 127, -+ [0][1][RTW89_ACMA][4] = 127, -+ [0][1][RTW89_CN][4] = 22, -+ [0][1][RTW89_UK][4] = 127, -+ [0][1][RTW89_FCC][5] = 127, -+ [0][1][RTW89_ETSI][5] = 127, -+ [0][1][RTW89_MKK][5] = 127, -+ [0][1][RTW89_IC][5] = 127, -+ [0][1][RTW89_KCC][5] = 127, -+ [0][1][RTW89_ACMA][5] = 127, -+ [0][1][RTW89_CN][5] = 22, -+ [0][1][RTW89_UK][5] = 127, -+ [0][1][RTW89_FCC][6] = 127, -+ [0][1][RTW89_ETSI][6] = 127, -+ [0][1][RTW89_MKK][6] = 127, -+ [0][1][RTW89_IC][6] = 127, -+ [0][1][RTW89_KCC][6] = 127, -+ [0][1][RTW89_ACMA][6] = 127, -+ [0][1][RTW89_CN][6] = 22, -+ [0][1][RTW89_UK][6] = 127, -+ [0][1][RTW89_FCC][7] = 127, -+ [0][1][RTW89_ETSI][7] = 127, -+ [0][1][RTW89_MKK][7] = 127, -+ [0][1][RTW89_IC][7] = 127, -+ [0][1][RTW89_KCC][7] = 127, -+ [0][1][RTW89_ACMA][7] = 127, -+ [0][1][RTW89_CN][7] = 22, -+ [0][1][RTW89_UK][7] = 127, -+ [0][1][RTW89_FCC][8] = 127, -+ [0][1][RTW89_ETSI][8] = 127, -+ [0][1][RTW89_MKK][8] = 127, -+ [0][1][RTW89_IC][8] = 127, -+ [0][1][RTW89_KCC][8] = 127, -+ [0][1][RTW89_ACMA][8] = 127, -+ [0][1][RTW89_CN][8] = 22, -+ [0][1][RTW89_UK][8] = 127, -+ [0][1][RTW89_FCC][9] = 127, -+ [0][1][RTW89_ETSI][9] = 127, -+ [0][1][RTW89_MKK][9] = 127, -+ [0][1][RTW89_IC][9] = 127, -+ [0][1][RTW89_KCC][9] = 127, -+ [0][1][RTW89_ACMA][9] = 127, -+ [0][1][RTW89_CN][9] = 22, -+ [0][1][RTW89_UK][9] = 127, -+ [0][1][RTW89_FCC][10] = 127, -+ [0][1][RTW89_ETSI][10] = 127, -+ [0][1][RTW89_MKK][10] = 127, -+ [0][1][RTW89_IC][10] = 127, -+ [0][1][RTW89_KCC][10] = 127, -+ [0][1][RTW89_ACMA][10] = 127, -+ [0][1][RTW89_CN][10] = 22, -+ [0][1][RTW89_UK][10] = 127, -+ [0][1][RTW89_FCC][11] = 127, -+ [0][1][RTW89_ETSI][11] = 127, -+ [0][1][RTW89_MKK][11] = 127, -+ [0][1][RTW89_IC][11] = 127, -+ [0][1][RTW89_KCC][11] = 127, -+ [0][1][RTW89_ACMA][11] = 127, -+ [0][1][RTW89_CN][11] = 22, -+ [0][1][RTW89_UK][11] = 127, -+ [0][1][RTW89_FCC][12] = 127, -+ [0][1][RTW89_ETSI][12] = 127, -+ [0][1][RTW89_MKK][12] = 127, -+ [0][1][RTW89_IC][12] = 127, -+ [0][1][RTW89_KCC][12] = 127, -+ [0][1][RTW89_ACMA][12] = 127, -+ [0][1][RTW89_CN][12] = 20, -+ [0][1][RTW89_UK][12] = 127, -+ [0][1][RTW89_FCC][13] = 127, -+ [0][1][RTW89_ETSI][13] = 127, -+ [0][1][RTW89_MKK][13] = 127, -+ [0][1][RTW89_IC][13] = 127, -+ [0][1][RTW89_KCC][13] = 127, -+ [0][1][RTW89_ACMA][13] = 127, -+ [0][1][RTW89_CN][13] = 127, -+ [0][1][RTW89_UK][13] = 127, -+ [1][0][RTW89_FCC][0] = 70, -+ [1][0][RTW89_ETSI][0] = 42, -+ [1][0][RTW89_MKK][0] = 52, -+ [1][0][RTW89_IC][0] = 70, -+ [1][0][RTW89_KCC][0] = 56, -+ [1][0][RTW89_ACMA][0] = 42, -+ [1][0][RTW89_CN][0] = 42, -+ [1][0][RTW89_UK][0] = 42, -+ [1][0][RTW89_FCC][1] = 70, -+ [1][0][RTW89_ETSI][1] = 42, -+ [1][0][RTW89_MKK][1] = 52, -+ [1][0][RTW89_IC][1] = 70, -+ [1][0][RTW89_KCC][1] = 56, -+ [1][0][RTW89_ACMA][1] = 42, -+ [1][0][RTW89_CN][1] = 44, -+ [1][0][RTW89_UK][1] = 42, -+ [1][0][RTW89_FCC][2] = 74, -+ [1][0][RTW89_ETSI][2] = 42, -+ [1][0][RTW89_MKK][2] = 52, -+ [1][0][RTW89_IC][2] = 74, -+ [1][0][RTW89_KCC][2] = 56, -+ [1][0][RTW89_ACMA][2] = 42, -+ [1][0][RTW89_CN][2] = 44, -+ [1][0][RTW89_UK][2] = 42, -+ [1][0][RTW89_FCC][3] = 76, -+ [1][0][RTW89_ETSI][3] = 42, -+ [1][0][RTW89_MKK][3] = 52, -+ [1][0][RTW89_IC][3] = 76, -+ [1][0][RTW89_KCC][3] = 56, -+ [1][0][RTW89_ACMA][3] = 42, -+ [1][0][RTW89_CN][3] = 44, -+ [1][0][RTW89_UK][3] = 42, -+ [1][0][RTW89_FCC][4] = 76, -+ [1][0][RTW89_ETSI][4] = 42, -+ [1][0][RTW89_MKK][4] = 52, -+ [1][0][RTW89_IC][4] = 76, -+ [1][0][RTW89_KCC][4] = 56, -+ [1][0][RTW89_ACMA][4] = 42, -+ [1][0][RTW89_CN][4] = 44, -+ [1][0][RTW89_UK][4] = 42, -+ [1][0][RTW89_FCC][5] = 82, -+ [1][0][RTW89_ETSI][5] = 42, -+ [1][0][RTW89_MKK][5] = 52, -+ [1][0][RTW89_IC][5] = 82, -+ [1][0][RTW89_KCC][5] = 56, -+ [1][0][RTW89_ACMA][5] = 42, -+ [1][0][RTW89_CN][5] = 44, -+ [1][0][RTW89_UK][5] = 42, -+ [1][0][RTW89_FCC][6] = 72, -+ [1][0][RTW89_ETSI][6] = 42, -+ [1][0][RTW89_MKK][6] = 52, -+ [1][0][RTW89_IC][6] = 72, -+ [1][0][RTW89_KCC][6] = 56, -+ [1][0][RTW89_ACMA][6] = 42, -+ [1][0][RTW89_CN][6] = 44, -+ [1][0][RTW89_UK][6] = 42, -+ [1][0][RTW89_FCC][7] = 72, -+ [1][0][RTW89_ETSI][7] = 42, -+ [1][0][RTW89_MKK][7] = 52, -+ [1][0][RTW89_IC][7] = 72, -+ [1][0][RTW89_KCC][7] = 56, -+ [1][0][RTW89_ACMA][7] = 42, -+ [1][0][RTW89_CN][7] = 44, -+ [1][0][RTW89_UK][7] = 42, -+ [1][0][RTW89_FCC][8] = 72, -+ [1][0][RTW89_ETSI][8] = 42, -+ [1][0][RTW89_MKK][8] = 52, -+ [1][0][RTW89_IC][8] = 72, -+ [1][0][RTW89_KCC][8] = 56, -+ [1][0][RTW89_ACMA][8] = 42, -+ [1][0][RTW89_CN][8] = 44, -+ [1][0][RTW89_UK][8] = 42, -+ [1][0][RTW89_FCC][9] = 68, -+ [1][0][RTW89_ETSI][9] = 42, -+ [1][0][RTW89_MKK][9] = 52, -+ [1][0][RTW89_IC][9] = 68, -+ [1][0][RTW89_KCC][9] = 58, -+ [1][0][RTW89_ACMA][9] = 42, -+ [1][0][RTW89_CN][9] = 44, -+ [1][0][RTW89_UK][9] = 42, -+ [1][0][RTW89_FCC][10] = 68, -+ [1][0][RTW89_ETSI][10] = 42, -+ [1][0][RTW89_MKK][10] = 52, -+ [1][0][RTW89_IC][10] = 68, -+ [1][0][RTW89_KCC][10] = 58, -+ [1][0][RTW89_ACMA][10] = 42, -+ [1][0][RTW89_CN][10] = 44, -+ [1][0][RTW89_UK][10] = 42, -+ [1][0][RTW89_FCC][11] = 66, -+ [1][0][RTW89_ETSI][11] = 42, -+ [1][0][RTW89_MKK][11] = 52, -+ [1][0][RTW89_IC][11] = 66, -+ [1][0][RTW89_KCC][11] = 58, -+ [1][0][RTW89_ACMA][11] = 42, -+ [1][0][RTW89_CN][11] = 44, -+ [1][0][RTW89_UK][11] = 42, -+ [1][0][RTW89_FCC][12] = 34, -+ [1][0][RTW89_ETSI][12] = 42, -+ [1][0][RTW89_MKK][12] = 52, -+ [1][0][RTW89_IC][12] = 34, -+ [1][0][RTW89_KCC][12] = 58, -+ [1][0][RTW89_ACMA][12] = 42, -+ [1][0][RTW89_CN][12] = 42, -+ [1][0][RTW89_UK][12] = 42, -+ [1][0][RTW89_FCC][13] = 127, -+ [1][0][RTW89_ETSI][13] = 127, -+ [1][0][RTW89_MKK][13] = 127, -+ [1][0][RTW89_IC][13] = 127, -+ [1][0][RTW89_KCC][13] = 127, -+ [1][0][RTW89_ACMA][13] = 127, -+ [1][0][RTW89_CN][13] = 127, -+ [1][0][RTW89_UK][13] = 127, -+ [1][1][RTW89_FCC][0] = 127, -+ [1][1][RTW89_ETSI][0] = 127, -+ [1][1][RTW89_MKK][0] = 127, -+ [1][1][RTW89_IC][0] = 127, -+ [1][1][RTW89_KCC][0] = 127, -+ [1][1][RTW89_ACMA][0] = 127, -+ [1][1][RTW89_CN][0] = 32, -+ [1][1][RTW89_UK][0] = 127, -+ [1][1][RTW89_FCC][1] = 127, -+ [1][1][RTW89_ETSI][1] = 127, -+ [1][1][RTW89_MKK][1] = 127, -+ [1][1][RTW89_IC][1] = 127, -+ [1][1][RTW89_KCC][1] = 127, -+ [1][1][RTW89_ACMA][1] = 127, -+ [1][1][RTW89_CN][1] = 32, -+ [1][1][RTW89_UK][1] = 127, -+ [1][1][RTW89_FCC][2] = 127, -+ [1][1][RTW89_ETSI][2] = 127, -+ [1][1][RTW89_MKK][2] = 127, -+ [1][1][RTW89_IC][2] = 127, -+ [1][1][RTW89_KCC][2] = 127, -+ [1][1][RTW89_ACMA][2] = 127, -+ [1][1][RTW89_CN][2] = 32, -+ [1][1][RTW89_UK][2] = 127, -+ [1][1][RTW89_FCC][3] = 127, -+ [1][1][RTW89_ETSI][3] = 127, -+ [1][1][RTW89_MKK][3] = 127, -+ [1][1][RTW89_IC][3] = 127, -+ [1][1][RTW89_KCC][3] = 127, -+ [1][1][RTW89_ACMA][3] = 127, -+ [1][1][RTW89_CN][3] = 32, -+ [1][1][RTW89_UK][3] = 127, -+ [1][1][RTW89_FCC][4] = 127, -+ [1][1][RTW89_ETSI][4] = 127, -+ [1][1][RTW89_MKK][4] = 127, -+ [1][1][RTW89_IC][4] = 127, -+ [1][1][RTW89_KCC][4] = 127, -+ [1][1][RTW89_ACMA][4] = 127, -+ [1][1][RTW89_CN][4] = 32, -+ [1][1][RTW89_UK][4] = 127, -+ [1][1][RTW89_FCC][5] = 127, -+ [1][1][RTW89_ETSI][5] = 127, -+ [1][1][RTW89_MKK][5] = 127, -+ [1][1][RTW89_IC][5] = 127, -+ [1][1][RTW89_KCC][5] = 127, -+ [1][1][RTW89_ACMA][5] = 127, -+ [1][1][RTW89_CN][5] = 32, -+ [1][1][RTW89_UK][5] = 127, -+ [1][1][RTW89_FCC][6] = 127, -+ [1][1][RTW89_ETSI][6] = 127, -+ [1][1][RTW89_MKK][6] = 127, -+ [1][1][RTW89_IC][6] = 127, -+ [1][1][RTW89_KCC][6] = 127, -+ [1][1][RTW89_ACMA][6] = 127, -+ [1][1][RTW89_CN][6] = 32, -+ [1][1][RTW89_UK][6] = 127, -+ [1][1][RTW89_FCC][7] = 127, -+ [1][1][RTW89_ETSI][7] = 127, -+ [1][1][RTW89_MKK][7] = 127, -+ [1][1][RTW89_IC][7] = 127, -+ [1][1][RTW89_KCC][7] = 127, -+ [1][1][RTW89_ACMA][7] = 127, -+ [1][1][RTW89_CN][7] = 32, -+ [1][1][RTW89_UK][7] = 127, -+ [1][1][RTW89_FCC][8] = 127, -+ [1][1][RTW89_ETSI][8] = 127, -+ [1][1][RTW89_MKK][8] = 127, -+ [1][1][RTW89_IC][8] = 127, -+ [1][1][RTW89_KCC][8] = 127, -+ [1][1][RTW89_ACMA][8] = 127, -+ [1][1][RTW89_CN][8] = 32, -+ [1][1][RTW89_UK][8] = 127, -+ [1][1][RTW89_FCC][9] = 127, -+ [1][1][RTW89_ETSI][9] = 127, -+ [1][1][RTW89_MKK][9] = 127, -+ [1][1][RTW89_IC][9] = 127, -+ [1][1][RTW89_KCC][9] = 127, -+ [1][1][RTW89_ACMA][9] = 127, -+ [1][1][RTW89_CN][9] = 32, -+ [1][1][RTW89_UK][9] = 127, -+ [1][1][RTW89_FCC][10] = 127, -+ [1][1][RTW89_ETSI][10] = 127, -+ [1][1][RTW89_MKK][10] = 127, -+ [1][1][RTW89_IC][10] = 127, -+ [1][1][RTW89_KCC][10] = 127, -+ [1][1][RTW89_ACMA][10] = 127, -+ [1][1][RTW89_CN][10] = 32, -+ [1][1][RTW89_UK][10] = 127, -+ [1][1][RTW89_FCC][11] = 127, -+ [1][1][RTW89_ETSI][11] = 127, -+ [1][1][RTW89_MKK][11] = 127, -+ [1][1][RTW89_IC][11] = 127, -+ [1][1][RTW89_KCC][11] = 127, -+ [1][1][RTW89_ACMA][11] = 127, -+ [1][1][RTW89_CN][11] = 32, -+ [1][1][RTW89_UK][11] = 127, -+ [1][1][RTW89_FCC][12] = 127, -+ [1][1][RTW89_ETSI][12] = 127, -+ [1][1][RTW89_MKK][12] = 127, -+ [1][1][RTW89_IC][12] = 127, -+ [1][1][RTW89_KCC][12] = 127, -+ [1][1][RTW89_ACMA][12] = 127, -+ [1][1][RTW89_CN][12] = 32, -+ [1][1][RTW89_UK][12] = 127, -+ [1][1][RTW89_FCC][13] = 127, -+ [1][1][RTW89_ETSI][13] = 127, -+ [1][1][RTW89_MKK][13] = 127, -+ [1][1][RTW89_IC][13] = 127, -+ [1][1][RTW89_KCC][13] = 127, -+ [1][1][RTW89_ACMA][13] = 127, -+ [1][1][RTW89_CN][13] = 127, -+ [1][1][RTW89_UK][13] = 127, -+ [2][0][RTW89_FCC][0] = 74, -+ [2][0][RTW89_ETSI][0] = 54, -+ [2][0][RTW89_MKK][0] = 64, -+ [2][0][RTW89_IC][0] = 74, -+ [2][0][RTW89_KCC][0] = 68, -+ [2][0][RTW89_ACMA][0] = 54, -+ [2][0][RTW89_CN][0] = 56, -+ [2][0][RTW89_UK][0] = 54, -+ [2][0][RTW89_FCC][1] = 74, -+ [2][0][RTW89_ETSI][1] = 54, -+ [2][0][RTW89_MKK][1] = 64, -+ [2][0][RTW89_IC][1] = 74, -+ [2][0][RTW89_KCC][1] = 68, -+ [2][0][RTW89_ACMA][1] = 54, -+ [2][0][RTW89_CN][1] = 56, -+ [2][0][RTW89_UK][1] = 54, -+ [2][0][RTW89_FCC][2] = 76, -+ [2][0][RTW89_ETSI][2] = 54, -+ [2][0][RTW89_MKK][2] = 64, -+ [2][0][RTW89_IC][2] = 76, -+ [2][0][RTW89_KCC][2] = 68, -+ [2][0][RTW89_ACMA][2] = 54, -+ [2][0][RTW89_CN][2] = 56, -+ [2][0][RTW89_UK][2] = 54, -+ [2][0][RTW89_FCC][3] = 76, -+ [2][0][RTW89_ETSI][3] = 54, -+ [2][0][RTW89_MKK][3] = 64, -+ [2][0][RTW89_IC][3] = 76, -+ [2][0][RTW89_KCC][3] = 68, -+ [2][0][RTW89_ACMA][3] = 54, -+ [2][0][RTW89_CN][3] = 56, -+ [2][0][RTW89_UK][3] = 54, -+ [2][0][RTW89_FCC][4] = 76, -+ [2][0][RTW89_ETSI][4] = 54, -+ [2][0][RTW89_MKK][4] = 64, -+ [2][0][RTW89_IC][4] = 76, -+ [2][0][RTW89_KCC][4] = 68, -+ [2][0][RTW89_ACMA][4] = 54, -+ [2][0][RTW89_CN][4] = 56, -+ [2][0][RTW89_UK][4] = 54, -+ [2][0][RTW89_FCC][5] = 80, -+ [2][0][RTW89_ETSI][5] = 54, -+ [2][0][RTW89_MKK][5] = 64, -+ [2][0][RTW89_IC][5] = 80, -+ [2][0][RTW89_KCC][5] = 68, -+ [2][0][RTW89_ACMA][5] = 54, -+ [2][0][RTW89_CN][5] = 56, -+ [2][0][RTW89_UK][5] = 54, -+ [2][0][RTW89_FCC][6] = 72, -+ [2][0][RTW89_ETSI][6] = 54, -+ [2][0][RTW89_MKK][6] = 64, -+ [2][0][RTW89_IC][6] = 72, -+ [2][0][RTW89_KCC][6] = 68, -+ [2][0][RTW89_ACMA][6] = 54, -+ [2][0][RTW89_CN][6] = 56, -+ [2][0][RTW89_UK][6] = 54, -+ [2][0][RTW89_FCC][7] = 72, -+ [2][0][RTW89_ETSI][7] = 54, -+ [2][0][RTW89_MKK][7] = 64, -+ [2][0][RTW89_IC][7] = 72, -+ [2][0][RTW89_KCC][7] = 68, -+ [2][0][RTW89_ACMA][7] = 54, -+ [2][0][RTW89_CN][7] = 56, -+ [2][0][RTW89_UK][7] = 54, -+ [2][0][RTW89_FCC][8] = 72, -+ [2][0][RTW89_ETSI][8] = 54, -+ [2][0][RTW89_MKK][8] = 64, -+ [2][0][RTW89_IC][8] = 72, -+ [2][0][RTW89_KCC][8] = 68, -+ [2][0][RTW89_ACMA][8] = 54, -+ [2][0][RTW89_CN][8] = 56, -+ [2][0][RTW89_UK][8] = 54, -+ [2][0][RTW89_FCC][9] = 70, -+ [2][0][RTW89_ETSI][9] = 54, -+ [2][0][RTW89_MKK][9] = 64, -+ [2][0][RTW89_IC][9] = 70, -+ [2][0][RTW89_KCC][9] = 68, -+ [2][0][RTW89_ACMA][9] = 54, -+ [2][0][RTW89_CN][9] = 56, -+ [2][0][RTW89_UK][9] = 54, -+ [2][0][RTW89_FCC][10] = 70, -+ [2][0][RTW89_ETSI][10] = 54, -+ [2][0][RTW89_MKK][10] = 64, -+ [2][0][RTW89_IC][10] = 70, -+ [2][0][RTW89_KCC][10] = 68, -+ [2][0][RTW89_ACMA][10] = 54, -+ [2][0][RTW89_CN][10] = 56, -+ [2][0][RTW89_UK][10] = 54, -+ [2][0][RTW89_FCC][11] = 62, -+ [2][0][RTW89_ETSI][11] = 54, -+ [2][0][RTW89_MKK][11] = 64, -+ [2][0][RTW89_IC][11] = 62, -+ [2][0][RTW89_KCC][11] = 68, -+ [2][0][RTW89_ACMA][11] = 54, -+ [2][0][RTW89_CN][11] = 56, -+ [2][0][RTW89_UK][11] = 54, -+ [2][0][RTW89_FCC][12] = 34, -+ [2][0][RTW89_ETSI][12] = 54, -+ [2][0][RTW89_MKK][12] = 64, -+ [2][0][RTW89_IC][12] = 34, -+ [2][0][RTW89_KCC][12] = 68, -+ [2][0][RTW89_ACMA][12] = 54, -+ [2][0][RTW89_CN][12] = 56, -+ [2][0][RTW89_UK][12] = 54, -+ [2][0][RTW89_FCC][13] = 127, -+ [2][0][RTW89_ETSI][13] = 127, -+ [2][0][RTW89_MKK][13] = 127, -+ [2][0][RTW89_IC][13] = 127, -+ [2][0][RTW89_KCC][13] = 127, -+ [2][0][RTW89_ACMA][13] = 127, -+ [2][0][RTW89_CN][13] = 127, -+ [2][0][RTW89_UK][13] = 127, -+ [2][1][RTW89_FCC][0] = 127, -+ [2][1][RTW89_ETSI][0] = 127, -+ [2][1][RTW89_MKK][0] = 127, -+ [2][1][RTW89_IC][0] = 127, -+ [2][1][RTW89_KCC][0] = 127, -+ [2][1][RTW89_ACMA][0] = 127, -+ [2][1][RTW89_CN][0] = 44, -+ [2][1][RTW89_UK][0] = 127, -+ [2][1][RTW89_FCC][1] = 127, -+ [2][1][RTW89_ETSI][1] = 127, -+ [2][1][RTW89_MKK][1] = 127, -+ [2][1][RTW89_IC][1] = 127, -+ [2][1][RTW89_KCC][1] = 127, -+ [2][1][RTW89_ACMA][1] = 127, -+ [2][1][RTW89_CN][1] = 44, -+ [2][1][RTW89_UK][1] = 127, -+ [2][1][RTW89_FCC][2] = 127, -+ [2][1][RTW89_ETSI][2] = 127, -+ [2][1][RTW89_MKK][2] = 127, -+ [2][1][RTW89_IC][2] = 127, -+ [2][1][RTW89_KCC][2] = 127, -+ [2][1][RTW89_ACMA][2] = 127, -+ [2][1][RTW89_CN][2] = 44, -+ [2][1][RTW89_UK][2] = 127, -+ [2][1][RTW89_FCC][3] = 127, -+ [2][1][RTW89_ETSI][3] = 127, -+ [2][1][RTW89_MKK][3] = 127, -+ [2][1][RTW89_IC][3] = 127, -+ [2][1][RTW89_KCC][3] = 127, -+ [2][1][RTW89_ACMA][3] = 127, -+ [2][1][RTW89_CN][3] = 44, -+ [2][1][RTW89_UK][3] = 127, -+ [2][1][RTW89_FCC][4] = 127, -+ [2][1][RTW89_ETSI][4] = 127, -+ [2][1][RTW89_MKK][4] = 127, -+ [2][1][RTW89_IC][4] = 127, -+ [2][1][RTW89_KCC][4] = 127, -+ [2][1][RTW89_ACMA][4] = 127, -+ [2][1][RTW89_CN][4] = 44, -+ [2][1][RTW89_UK][4] = 127, -+ [2][1][RTW89_FCC][5] = 127, -+ [2][1][RTW89_ETSI][5] = 127, -+ [2][1][RTW89_MKK][5] = 127, -+ [2][1][RTW89_IC][5] = 127, -+ [2][1][RTW89_KCC][5] = 127, -+ [2][1][RTW89_ACMA][5] = 127, -+ [2][1][RTW89_CN][5] = 44, -+ [2][1][RTW89_UK][5] = 127, -+ [2][1][RTW89_FCC][6] = 127, -+ [2][1][RTW89_ETSI][6] = 127, -+ [2][1][RTW89_MKK][6] = 127, -+ [2][1][RTW89_IC][6] = 127, -+ [2][1][RTW89_KCC][6] = 127, -+ [2][1][RTW89_ACMA][6] = 127, -+ [2][1][RTW89_CN][6] = 44, -+ [2][1][RTW89_UK][6] = 127, -+ [2][1][RTW89_FCC][7] = 127, -+ [2][1][RTW89_ETSI][7] = 127, -+ [2][1][RTW89_MKK][7] = 127, -+ [2][1][RTW89_IC][7] = 127, -+ [2][1][RTW89_KCC][7] = 127, -+ [2][1][RTW89_ACMA][7] = 127, -+ [2][1][RTW89_CN][7] = 44, -+ [2][1][RTW89_UK][7] = 127, -+ [2][1][RTW89_FCC][8] = 127, -+ [2][1][RTW89_ETSI][8] = 127, -+ [2][1][RTW89_MKK][8] = 127, -+ [2][1][RTW89_IC][8] = 127, -+ [2][1][RTW89_KCC][8] = 127, -+ [2][1][RTW89_ACMA][8] = 127, -+ [2][1][RTW89_CN][8] = 44, -+ [2][1][RTW89_UK][8] = 127, -+ [2][1][RTW89_FCC][9] = 127, -+ [2][1][RTW89_ETSI][9] = 127, -+ [2][1][RTW89_MKK][9] = 127, -+ [2][1][RTW89_IC][9] = 127, -+ [2][1][RTW89_KCC][9] = 127, -+ [2][1][RTW89_ACMA][9] = 127, -+ [2][1][RTW89_CN][9] = 44, -+ [2][1][RTW89_UK][9] = 127, -+ [2][1][RTW89_FCC][10] = 127, -+ [2][1][RTW89_ETSI][10] = 127, -+ [2][1][RTW89_MKK][10] = 127, -+ [2][1][RTW89_IC][10] = 127, -+ [2][1][RTW89_KCC][10] = 127, -+ [2][1][RTW89_ACMA][10] = 127, -+ [2][1][RTW89_CN][10] = 44, -+ [2][1][RTW89_UK][10] = 127, -+ [2][1][RTW89_FCC][11] = 127, -+ [2][1][RTW89_ETSI][11] = 127, -+ [2][1][RTW89_MKK][11] = 127, -+ [2][1][RTW89_IC][11] = 127, -+ [2][1][RTW89_KCC][11] = 127, -+ [2][1][RTW89_ACMA][11] = 127, -+ [2][1][RTW89_CN][11] = 44, -+ [2][1][RTW89_UK][11] = 127, -+ [2][1][RTW89_FCC][12] = 127, -+ [2][1][RTW89_ETSI][12] = 127, -+ [2][1][RTW89_MKK][12] = 127, -+ [2][1][RTW89_IC][12] = 127, -+ [2][1][RTW89_KCC][12] = 127, -+ [2][1][RTW89_ACMA][12] = 127, -+ [2][1][RTW89_CN][12] = 42, -+ [2][1][RTW89_UK][12] = 127, -+ [2][1][RTW89_FCC][13] = 127, -+ [2][1][RTW89_ETSI][13] = 127, -+ [2][1][RTW89_MKK][13] = 127, -+ [2][1][RTW89_IC][13] = 127, -+ [2][1][RTW89_KCC][13] = 127, -+ [2][1][RTW89_ACMA][13] = 127, -+ [2][1][RTW89_CN][13] = 127, -+ [2][1][RTW89_UK][13] = 127, -+}; -+ -+static -+const s8 rtw89_8851b_txpwr_lmt_ru_5g_type2[RTW89_RU_NUM][RTW89_NTX_NUM] -+ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { -+ [0][0][RTW89_WW][0] = 16, -+ [0][0][RTW89_WW][2] = 16, -+ [0][0][RTW89_WW][4] = 16, -+ [0][0][RTW89_WW][6] = 16, -+ [0][0][RTW89_WW][8] = 16, -+ [0][0][RTW89_WW][10] = 16, -+ [0][0][RTW89_WW][12] = 16, -+ [0][0][RTW89_WW][14] = 16, -+ [0][0][RTW89_WW][15] = 24, -+ [0][0][RTW89_WW][17] = 24, -+ [0][0][RTW89_WW][19] = 24, -+ [0][0][RTW89_WW][21] = 24, -+ [0][0][RTW89_WW][23] = 24, -+ [0][0][RTW89_WW][25] = 24, -+ [0][0][RTW89_WW][27] = 24, -+ [0][0][RTW89_WW][29] = 24, -+ [0][0][RTW89_WW][31] = 24, -+ [0][0][RTW89_WW][33] = 24, -+ [0][0][RTW89_WW][35] = 24, -+ [0][0][RTW89_WW][37] = 44, -+ [0][0][RTW89_WW][38] = 24, -+ [0][0][RTW89_WW][40] = 24, -+ [0][0][RTW89_WW][42] = 24, -+ [0][0][RTW89_WW][44] = 24, -+ [0][0][RTW89_WW][46] = 24, -+ [0][0][RTW89_WW][48] = 40, -+ [0][0][RTW89_WW][50] = 42, -+ [0][0][RTW89_WW][52] = 38, -+ [0][1][RTW89_WW][0] = 4, -+ [0][1][RTW89_WW][2] = 4, -+ [0][1][RTW89_WW][4] = 4, -+ [0][1][RTW89_WW][6] = 4, -+ [0][1][RTW89_WW][8] = 4, -+ [0][1][RTW89_WW][10] = 4, -+ [0][1][RTW89_WW][12] = 4, -+ [0][1][RTW89_WW][14] = 4, -+ [0][1][RTW89_WW][15] = 0, -+ [0][1][RTW89_WW][17] = 0, -+ [0][1][RTW89_WW][19] = 0, -+ [0][1][RTW89_WW][21] = 0, -+ [0][1][RTW89_WW][23] = 0, -+ [0][1][RTW89_WW][25] = 0, -+ [0][1][RTW89_WW][27] = 0, -+ [0][1][RTW89_WW][29] = 0, -+ [0][1][RTW89_WW][31] = 0, -+ [0][1][RTW89_WW][33] = 0, -+ [0][1][RTW89_WW][35] = 0, -+ [0][1][RTW89_WW][37] = 0, -+ [0][1][RTW89_WW][38] = 42, -+ [0][1][RTW89_WW][40] = 42, -+ [0][1][RTW89_WW][42] = 42, -+ [0][1][RTW89_WW][44] = 42, -+ [0][1][RTW89_WW][46] = 42, -+ [0][1][RTW89_WW][48] = 0, -+ [0][1][RTW89_WW][50] = 0, -+ [0][1][RTW89_WW][52] = 0, -+ [1][0][RTW89_WW][0] = 26, -+ [1][0][RTW89_WW][2] = 26, -+ [1][0][RTW89_WW][4] = 26, -+ [1][0][RTW89_WW][6] = 26, -+ [1][0][RTW89_WW][8] = 26, -+ [1][0][RTW89_WW][10] = 26, -+ [1][0][RTW89_WW][12] = 26, -+ [1][0][RTW89_WW][14] = 26, -+ [1][0][RTW89_WW][15] = 34, -+ [1][0][RTW89_WW][17] = 34, -+ [1][0][RTW89_WW][19] = 34, -+ [1][0][RTW89_WW][21] = 34, -+ [1][0][RTW89_WW][23] = 34, -+ [1][0][RTW89_WW][25] = 34, -+ [1][0][RTW89_WW][27] = 34, -+ [1][0][RTW89_WW][29] = 34, -+ [1][0][RTW89_WW][31] = 34, -+ [1][0][RTW89_WW][33] = 34, -+ [1][0][RTW89_WW][35] = 34, -+ [1][0][RTW89_WW][37] = 54, -+ [1][0][RTW89_WW][38] = 28, -+ [1][0][RTW89_WW][40] = 28, -+ [1][0][RTW89_WW][42] = 28, -+ [1][0][RTW89_WW][44] = 28, -+ [1][0][RTW89_WW][46] = 28, -+ [1][0][RTW89_WW][48] = 52, -+ [1][0][RTW89_WW][50] = 52, -+ [1][0][RTW89_WW][52] = 50, -+ [1][1][RTW89_WW][0] = 14, -+ [1][1][RTW89_WW][2] = 14, -+ [1][1][RTW89_WW][4] = 14, -+ [1][1][RTW89_WW][6] = 14, -+ [1][1][RTW89_WW][8] = 14, -+ [1][1][RTW89_WW][10] = 14, -+ [1][1][RTW89_WW][12] = 14, -+ [1][1][RTW89_WW][14] = 14, -+ [1][1][RTW89_WW][15] = 0, -+ [1][1][RTW89_WW][17] = 0, -+ [1][1][RTW89_WW][19] = 0, -+ [1][1][RTW89_WW][21] = 0, -+ [1][1][RTW89_WW][23] = 0, -+ [1][1][RTW89_WW][25] = 0, -+ [1][1][RTW89_WW][27] = 0, -+ [1][1][RTW89_WW][29] = 0, -+ [1][1][RTW89_WW][31] = 0, -+ [1][1][RTW89_WW][33] = 0, -+ [1][1][RTW89_WW][35] = 0, -+ [1][1][RTW89_WW][37] = 0, -+ [1][1][RTW89_WW][38] = 54, -+ [1][1][RTW89_WW][40] = 54, -+ [1][1][RTW89_WW][42] = 54, -+ [1][1][RTW89_WW][44] = 54, -+ [1][1][RTW89_WW][46] = 54, -+ [1][1][RTW89_WW][48] = 0, -+ [1][1][RTW89_WW][50] = 0, -+ [1][1][RTW89_WW][52] = 0, -+ [2][0][RTW89_WW][0] = 40, -+ [2][0][RTW89_WW][2] = 40, -+ [2][0][RTW89_WW][4] = 40, -+ [2][0][RTW89_WW][6] = 40, -+ [2][0][RTW89_WW][8] = 40, -+ [2][0][RTW89_WW][10] = 40, -+ [2][0][RTW89_WW][12] = 40, -+ [2][0][RTW89_WW][14] = 40, -+ [2][0][RTW89_WW][15] = 46, -+ [2][0][RTW89_WW][17] = 46, -+ [2][0][RTW89_WW][19] = 46, -+ [2][0][RTW89_WW][21] = 46, -+ [2][0][RTW89_WW][23] = 46, -+ [2][0][RTW89_WW][25] = 46, -+ [2][0][RTW89_WW][27] = 46, -+ [2][0][RTW89_WW][29] = 46, -+ [2][0][RTW89_WW][31] = 46, -+ [2][0][RTW89_WW][33] = 46, -+ [2][0][RTW89_WW][35] = 46, -+ [2][0][RTW89_WW][37] = 66, -+ [2][0][RTW89_WW][38] = 28, -+ [2][0][RTW89_WW][40] = 28, -+ [2][0][RTW89_WW][42] = 28, -+ [2][0][RTW89_WW][44] = 28, -+ [2][0][RTW89_WW][46] = 28, -+ [2][0][RTW89_WW][48] = 62, -+ [2][0][RTW89_WW][50] = 62, -+ [2][0][RTW89_WW][52] = 60, -+ [2][1][RTW89_WW][0] = 28, -+ [2][1][RTW89_WW][2] = 28, -+ [2][1][RTW89_WW][4] = 28, -+ [2][1][RTW89_WW][6] = 28, -+ [2][1][RTW89_WW][8] = 28, -+ [2][1][RTW89_WW][10] = 28, -+ [2][1][RTW89_WW][12] = 28, -+ [2][1][RTW89_WW][14] = 28, -+ [2][1][RTW89_WW][15] = 0, -+ [2][1][RTW89_WW][17] = 0, -+ [2][1][RTW89_WW][19] = 0, -+ [2][1][RTW89_WW][21] = 0, -+ [2][1][RTW89_WW][23] = 0, -+ [2][1][RTW89_WW][25] = 0, -+ [2][1][RTW89_WW][27] = 0, -+ [2][1][RTW89_WW][29] = 0, -+ [2][1][RTW89_WW][31] = 0, -+ [2][1][RTW89_WW][33] = 0, -+ [2][1][RTW89_WW][35] = 0, -+ [2][1][RTW89_WW][37] = 0, -+ [2][1][RTW89_WW][38] = 56, -+ [2][1][RTW89_WW][40] = 56, -+ [2][1][RTW89_WW][42] = 56, -+ [2][1][RTW89_WW][44] = 56, -+ [2][1][RTW89_WW][46] = 56, -+ [2][1][RTW89_WW][48] = 0, -+ [2][1][RTW89_WW][50] = 0, -+ [2][1][RTW89_WW][52] = 0, -+ [0][0][RTW89_FCC][0] = 50, -+ [0][0][RTW89_ETSI][0] = 24, -+ [0][0][RTW89_MKK][0] = 26, -+ [0][0][RTW89_IC][0] = 28, -+ [0][0][RTW89_KCC][0] = 42, -+ [0][0][RTW89_ACMA][0] = 24, -+ [0][0][RTW89_CN][0] = 16, -+ [0][0][RTW89_UK][0] = 24, -+ [0][0][RTW89_FCC][2] = 54, -+ [0][0][RTW89_ETSI][2] = 24, -+ [0][0][RTW89_MKK][2] = 26, -+ [0][0][RTW89_IC][2] = 28, -+ [0][0][RTW89_KCC][2] = 42, -+ [0][0][RTW89_ACMA][2] = 24, -+ [0][0][RTW89_CN][2] = 16, -+ [0][0][RTW89_UK][2] = 24, -+ [0][0][RTW89_FCC][4] = 50, -+ [0][0][RTW89_ETSI][4] = 24, -+ [0][0][RTW89_MKK][4] = 26, -+ [0][0][RTW89_IC][4] = 28, -+ [0][0][RTW89_KCC][4] = 42, -+ [0][0][RTW89_ACMA][4] = 24, -+ [0][0][RTW89_CN][4] = 16, -+ [0][0][RTW89_UK][4] = 24, -+ [0][0][RTW89_FCC][6] = 50, -+ [0][0][RTW89_ETSI][6] = 24, -+ [0][0][RTW89_MKK][6] = 26, -+ [0][0][RTW89_IC][6] = 28, -+ [0][0][RTW89_KCC][6] = 18, -+ [0][0][RTW89_ACMA][6] = 24, -+ [0][0][RTW89_CN][6] = 16, -+ [0][0][RTW89_UK][6] = 24, -+ [0][0][RTW89_FCC][8] = 52, -+ [0][0][RTW89_ETSI][8] = 24, -+ [0][0][RTW89_MKK][8] = 26, -+ [0][0][RTW89_IC][8] = 52, -+ [0][0][RTW89_KCC][8] = 42, -+ [0][0][RTW89_ACMA][8] = 24, -+ [0][0][RTW89_CN][8] = 16, -+ [0][0][RTW89_UK][8] = 24, -+ [0][0][RTW89_FCC][10] = 52, -+ [0][0][RTW89_ETSI][10] = 24, -+ [0][0][RTW89_MKK][10] = 26, -+ [0][0][RTW89_IC][10] = 52, -+ [0][0][RTW89_KCC][10] = 42, -+ [0][0][RTW89_ACMA][10] = 24, -+ [0][0][RTW89_CN][10] = 16, -+ [0][0][RTW89_UK][10] = 24, -+ [0][0][RTW89_FCC][12] = 56, -+ [0][0][RTW89_ETSI][12] = 24, -+ [0][0][RTW89_MKK][12] = 26, -+ [0][0][RTW89_IC][12] = 56, -+ [0][0][RTW89_KCC][12] = 44, -+ [0][0][RTW89_ACMA][12] = 24, -+ [0][0][RTW89_CN][12] = 16, -+ [0][0][RTW89_UK][12] = 24, -+ [0][0][RTW89_FCC][14] = 56, -+ [0][0][RTW89_ETSI][14] = 24, -+ [0][0][RTW89_MKK][14] = 26, -+ [0][0][RTW89_IC][14] = 56, -+ [0][0][RTW89_KCC][14] = 44, -+ [0][0][RTW89_ACMA][14] = 24, -+ [0][0][RTW89_CN][14] = 16, -+ [0][0][RTW89_UK][14] = 24, -+ [0][0][RTW89_FCC][15] = 52, -+ [0][0][RTW89_ETSI][15] = 24, -+ [0][0][RTW89_MKK][15] = 46, -+ [0][0][RTW89_IC][15] = 52, -+ [0][0][RTW89_KCC][15] = 44, -+ [0][0][RTW89_ACMA][15] = 24, -+ [0][0][RTW89_CN][15] = 127, -+ [0][0][RTW89_UK][15] = 24, -+ [0][0][RTW89_FCC][17] = 52, -+ [0][0][RTW89_ETSI][17] = 24, -+ [0][0][RTW89_MKK][17] = 50, -+ [0][0][RTW89_IC][17] = 52, -+ [0][0][RTW89_KCC][17] = 44, -+ [0][0][RTW89_ACMA][17] = 24, -+ [0][0][RTW89_CN][17] = 127, -+ [0][0][RTW89_UK][17] = 24, -+ [0][0][RTW89_FCC][19] = 52, -+ [0][0][RTW89_ETSI][19] = 24, -+ [0][0][RTW89_MKK][19] = 50, -+ [0][0][RTW89_IC][19] = 52, -+ [0][0][RTW89_KCC][19] = 44, -+ [0][0][RTW89_ACMA][19] = 24, -+ [0][0][RTW89_CN][19] = 127, -+ [0][0][RTW89_UK][19] = 24, -+ [0][0][RTW89_FCC][21] = 52, -+ [0][0][RTW89_ETSI][21] = 24, -+ [0][0][RTW89_MKK][21] = 50, -+ [0][0][RTW89_IC][21] = 52, -+ [0][0][RTW89_KCC][21] = 44, -+ [0][0][RTW89_ACMA][21] = 24, -+ [0][0][RTW89_CN][21] = 127, -+ [0][0][RTW89_UK][21] = 24, -+ [0][0][RTW89_FCC][23] = 52, -+ [0][0][RTW89_ETSI][23] = 24, -+ [0][0][RTW89_MKK][23] = 50, -+ [0][0][RTW89_IC][23] = 52, -+ [0][0][RTW89_KCC][23] = 44, -+ [0][0][RTW89_ACMA][23] = 24, -+ [0][0][RTW89_CN][23] = 127, -+ [0][0][RTW89_UK][23] = 24, -+ [0][0][RTW89_FCC][25] = 52, -+ [0][0][RTW89_ETSI][25] = 24, -+ [0][0][RTW89_MKK][25] = 50, -+ [0][0][RTW89_IC][25] = 127, -+ [0][0][RTW89_KCC][25] = 44, -+ [0][0][RTW89_ACMA][25] = 127, -+ [0][0][RTW89_CN][25] = 127, -+ [0][0][RTW89_UK][25] = 24, -+ [0][0][RTW89_FCC][27] = 52, -+ [0][0][RTW89_ETSI][27] = 24, -+ [0][0][RTW89_MKK][27] = 50, -+ [0][0][RTW89_IC][27] = 127, -+ [0][0][RTW89_KCC][27] = 42, -+ [0][0][RTW89_ACMA][27] = 127, -+ [0][0][RTW89_CN][27] = 127, -+ [0][0][RTW89_UK][27] = 24, -+ [0][0][RTW89_FCC][29] = 52, -+ [0][0][RTW89_ETSI][29] = 24, -+ [0][0][RTW89_MKK][29] = 50, -+ [0][0][RTW89_IC][29] = 127, -+ [0][0][RTW89_KCC][29] = 42, -+ [0][0][RTW89_ACMA][29] = 127, -+ [0][0][RTW89_CN][29] = 127, -+ [0][0][RTW89_UK][29] = 24, -+ [0][0][RTW89_FCC][31] = 52, -+ [0][0][RTW89_ETSI][31] = 24, -+ [0][0][RTW89_MKK][31] = 50, -+ [0][0][RTW89_IC][31] = 56, -+ [0][0][RTW89_KCC][31] = 42, -+ [0][0][RTW89_ACMA][31] = 24, -+ [0][0][RTW89_CN][31] = 127, -+ [0][0][RTW89_UK][31] = 24, -+ [0][0][RTW89_FCC][33] = 56, -+ [0][0][RTW89_ETSI][33] = 24, -+ [0][0][RTW89_MKK][33] = 50, -+ [0][0][RTW89_IC][33] = 56, -+ [0][0][RTW89_KCC][33] = 42, -+ [0][0][RTW89_ACMA][33] = 24, -+ [0][0][RTW89_CN][33] = 127, -+ [0][0][RTW89_UK][33] = 24, -+ [0][0][RTW89_FCC][35] = 56, -+ [0][0][RTW89_ETSI][35] = 24, -+ [0][0][RTW89_MKK][35] = 50, -+ [0][0][RTW89_IC][35] = 56, -+ [0][0][RTW89_KCC][35] = 42, -+ [0][0][RTW89_ACMA][35] = 24, -+ [0][0][RTW89_CN][35] = 127, -+ [0][0][RTW89_UK][35] = 24, -+ [0][0][RTW89_FCC][37] = 84, -+ [0][0][RTW89_ETSI][37] = 127, -+ [0][0][RTW89_MKK][37] = 46, -+ [0][0][RTW89_IC][37] = 84, -+ [0][0][RTW89_KCC][37] = 44, -+ [0][0][RTW89_ACMA][37] = 50, -+ [0][0][RTW89_CN][37] = 127, -+ [0][0][RTW89_UK][37] = 52, -+ [0][0][RTW89_FCC][38] = 68, -+ [0][0][RTW89_ETSI][38] = 28, -+ [0][0][RTW89_MKK][38] = 127, -+ [0][0][RTW89_IC][38] = 68, -+ [0][0][RTW89_KCC][38] = 44, -+ [0][0][RTW89_ACMA][38] = 84, -+ [0][0][RTW89_CN][38] = 54, -+ [0][0][RTW89_UK][38] = 24, -+ [0][0][RTW89_FCC][40] = 68, -+ [0][0][RTW89_ETSI][40] = 28, -+ [0][0][RTW89_MKK][40] = 127, -+ [0][0][RTW89_IC][40] = 68, -+ [0][0][RTW89_KCC][40] = 44, -+ [0][0][RTW89_ACMA][40] = 84, -+ [0][0][RTW89_CN][40] = 54, -+ [0][0][RTW89_UK][40] = 24, -+ [0][0][RTW89_FCC][42] = 70, -+ [0][0][RTW89_ETSI][42] = 28, -+ [0][0][RTW89_MKK][42] = 127, -+ [0][0][RTW89_IC][42] = 70, -+ [0][0][RTW89_KCC][42] = 44, -+ [0][0][RTW89_ACMA][42] = 84, -+ [0][0][RTW89_CN][42] = 54, -+ [0][0][RTW89_UK][42] = 24, -+ [0][0][RTW89_FCC][44] = 62, -+ [0][0][RTW89_ETSI][44] = 28, -+ [0][0][RTW89_MKK][44] = 127, -+ [0][0][RTW89_IC][44] = 62, -+ [0][0][RTW89_KCC][44] = 44, -+ [0][0][RTW89_ACMA][44] = 84, -+ [0][0][RTW89_CN][44] = 54, -+ [0][0][RTW89_UK][44] = 24, -+ [0][0][RTW89_FCC][46] = 62, -+ [0][0][RTW89_ETSI][46] = 28, -+ [0][0][RTW89_MKK][46] = 127, -+ [0][0][RTW89_IC][46] = 62, -+ [0][0][RTW89_KCC][46] = 44, -+ [0][0][RTW89_ACMA][46] = 84, -+ [0][0][RTW89_CN][46] = 54, -+ [0][0][RTW89_UK][46] = 24, -+ [0][0][RTW89_FCC][48] = 40, -+ [0][0][RTW89_ETSI][48] = 127, -+ [0][0][RTW89_MKK][48] = 127, -+ [0][0][RTW89_IC][48] = 127, -+ [0][0][RTW89_KCC][48] = 127, -+ [0][0][RTW89_ACMA][48] = 127, -+ [0][0][RTW89_CN][48] = 127, -+ [0][0][RTW89_UK][48] = 127, -+ [0][0][RTW89_FCC][50] = 42, -+ [0][0][RTW89_ETSI][50] = 127, -+ [0][0][RTW89_MKK][50] = 127, -+ [0][0][RTW89_IC][50] = 127, -+ [0][0][RTW89_KCC][50] = 127, -+ [0][0][RTW89_ACMA][50] = 127, -+ [0][0][RTW89_CN][50] = 127, -+ [0][0][RTW89_UK][50] = 127, -+ [0][0][RTW89_FCC][52] = 38, -+ [0][0][RTW89_ETSI][52] = 127, -+ [0][0][RTW89_MKK][52] = 127, -+ [0][0][RTW89_IC][52] = 127, -+ [0][0][RTW89_KCC][52] = 127, -+ [0][0][RTW89_ACMA][52] = 127, -+ [0][0][RTW89_CN][52] = 127, -+ [0][0][RTW89_UK][52] = 127, -+ [0][1][RTW89_FCC][0] = 127, -+ [0][1][RTW89_ETSI][0] = 127, -+ [0][1][RTW89_MKK][0] = 127, -+ [0][1][RTW89_IC][0] = 127, -+ [0][1][RTW89_KCC][0] = 127, -+ [0][1][RTW89_ACMA][0] = 127, -+ [0][1][RTW89_CN][0] = 4, -+ [0][1][RTW89_UK][0] = 127, -+ [0][1][RTW89_FCC][2] = 127, -+ [0][1][RTW89_ETSI][2] = 127, -+ [0][1][RTW89_MKK][2] = 127, -+ [0][1][RTW89_IC][2] = 127, -+ [0][1][RTW89_KCC][2] = 127, -+ [0][1][RTW89_ACMA][2] = 127, -+ [0][1][RTW89_CN][2] = 4, -+ [0][1][RTW89_UK][2] = 127, -+ [0][1][RTW89_FCC][4] = 127, -+ [0][1][RTW89_ETSI][4] = 127, -+ [0][1][RTW89_MKK][4] = 127, -+ [0][1][RTW89_IC][4] = 127, -+ [0][1][RTW89_KCC][4] = 127, -+ [0][1][RTW89_ACMA][4] = 127, -+ [0][1][RTW89_CN][4] = 4, -+ [0][1][RTW89_UK][4] = 127, -+ [0][1][RTW89_FCC][6] = 127, -+ [0][1][RTW89_ETSI][6] = 127, -+ [0][1][RTW89_MKK][6] = 127, -+ [0][1][RTW89_IC][6] = 127, -+ [0][1][RTW89_KCC][6] = 127, -+ [0][1][RTW89_ACMA][6] = 127, -+ [0][1][RTW89_CN][6] = 4, -+ [0][1][RTW89_UK][6] = 127, -+ [0][1][RTW89_FCC][8] = 127, -+ [0][1][RTW89_ETSI][8] = 127, -+ [0][1][RTW89_MKK][8] = 127, -+ [0][1][RTW89_IC][8] = 127, -+ [0][1][RTW89_KCC][8] = 127, -+ [0][1][RTW89_ACMA][8] = 127, -+ [0][1][RTW89_CN][8] = 4, -+ [0][1][RTW89_UK][8] = 127, -+ [0][1][RTW89_FCC][10] = 127, -+ [0][1][RTW89_ETSI][10] = 127, -+ [0][1][RTW89_MKK][10] = 127, -+ [0][1][RTW89_IC][10] = 127, -+ [0][1][RTW89_KCC][10] = 127, -+ [0][1][RTW89_ACMA][10] = 127, -+ [0][1][RTW89_CN][10] = 4, -+ [0][1][RTW89_UK][10] = 127, -+ [0][1][RTW89_FCC][12] = 127, -+ [0][1][RTW89_ETSI][12] = 127, -+ [0][1][RTW89_MKK][12] = 127, -+ [0][1][RTW89_IC][12] = 127, -+ [0][1][RTW89_KCC][12] = 127, -+ [0][1][RTW89_ACMA][12] = 127, -+ [0][1][RTW89_CN][12] = 4, -+ [0][1][RTW89_UK][12] = 127, -+ [0][1][RTW89_FCC][14] = 127, -+ [0][1][RTW89_ETSI][14] = 127, -+ [0][1][RTW89_MKK][14] = 127, -+ [0][1][RTW89_IC][14] = 127, -+ [0][1][RTW89_KCC][14] = 127, -+ [0][1][RTW89_ACMA][14] = 127, -+ [0][1][RTW89_CN][14] = 4, -+ [0][1][RTW89_UK][14] = 127, -+ [0][1][RTW89_FCC][15] = 127, -+ [0][1][RTW89_ETSI][15] = 127, -+ [0][1][RTW89_MKK][15] = 127, -+ [0][1][RTW89_IC][15] = 127, -+ [0][1][RTW89_KCC][15] = 127, -+ [0][1][RTW89_ACMA][15] = 127, -+ [0][1][RTW89_CN][15] = 127, -+ [0][1][RTW89_UK][15] = 127, -+ [0][1][RTW89_FCC][17] = 127, -+ [0][1][RTW89_ETSI][17] = 127, -+ [0][1][RTW89_MKK][17] = 127, -+ [0][1][RTW89_IC][17] = 127, -+ [0][1][RTW89_KCC][17] = 127, -+ [0][1][RTW89_ACMA][17] = 127, -+ [0][1][RTW89_CN][17] = 127, -+ [0][1][RTW89_UK][17] = 127, -+ [0][1][RTW89_FCC][19] = 127, -+ [0][1][RTW89_ETSI][19] = 127, -+ [0][1][RTW89_MKK][19] = 127, -+ [0][1][RTW89_IC][19] = 127, -+ [0][1][RTW89_KCC][19] = 127, -+ [0][1][RTW89_ACMA][19] = 127, -+ [0][1][RTW89_CN][19] = 127, -+ [0][1][RTW89_UK][19] = 127, -+ [0][1][RTW89_FCC][21] = 127, -+ [0][1][RTW89_ETSI][21] = 127, -+ [0][1][RTW89_MKK][21] = 127, -+ [0][1][RTW89_IC][21] = 127, -+ [0][1][RTW89_KCC][21] = 127, -+ [0][1][RTW89_ACMA][21] = 127, -+ [0][1][RTW89_CN][21] = 127, -+ [0][1][RTW89_UK][21] = 127, -+ [0][1][RTW89_FCC][23] = 127, -+ [0][1][RTW89_ETSI][23] = 127, -+ [0][1][RTW89_MKK][23] = 127, -+ [0][1][RTW89_IC][23] = 127, -+ [0][1][RTW89_KCC][23] = 127, -+ [0][1][RTW89_ACMA][23] = 127, -+ [0][1][RTW89_CN][23] = 127, -+ [0][1][RTW89_UK][23] = 127, -+ [0][1][RTW89_FCC][25] = 127, -+ [0][1][RTW89_ETSI][25] = 127, -+ [0][1][RTW89_MKK][25] = 127, -+ [0][1][RTW89_IC][25] = 127, -+ [0][1][RTW89_KCC][25] = 127, -+ [0][1][RTW89_ACMA][25] = 127, -+ [0][1][RTW89_CN][25] = 127, -+ [0][1][RTW89_UK][25] = 127, -+ [0][1][RTW89_FCC][27] = 127, -+ [0][1][RTW89_ETSI][27] = 127, -+ [0][1][RTW89_MKK][27] = 127, -+ [0][1][RTW89_IC][27] = 127, -+ [0][1][RTW89_KCC][27] = 127, -+ [0][1][RTW89_ACMA][27] = 127, -+ [0][1][RTW89_CN][27] = 127, -+ [0][1][RTW89_UK][27] = 127, -+ [0][1][RTW89_FCC][29] = 127, -+ [0][1][RTW89_ETSI][29] = 127, -+ [0][1][RTW89_MKK][29] = 127, -+ [0][1][RTW89_IC][29] = 127, -+ [0][1][RTW89_KCC][29] = 127, -+ [0][1][RTW89_ACMA][29] = 127, -+ [0][1][RTW89_CN][29] = 127, -+ [0][1][RTW89_UK][29] = 127, -+ [0][1][RTW89_FCC][31] = 127, -+ [0][1][RTW89_ETSI][31] = 127, -+ [0][1][RTW89_MKK][31] = 127, -+ [0][1][RTW89_IC][31] = 127, -+ [0][1][RTW89_KCC][31] = 127, -+ [0][1][RTW89_ACMA][31] = 127, -+ [0][1][RTW89_CN][31] = 127, -+ [0][1][RTW89_UK][31] = 127, -+ [0][1][RTW89_FCC][33] = 127, -+ [0][1][RTW89_ETSI][33] = 127, -+ [0][1][RTW89_MKK][33] = 127, -+ [0][1][RTW89_IC][33] = 127, -+ [0][1][RTW89_KCC][33] = 127, -+ [0][1][RTW89_ACMA][33] = 127, -+ [0][1][RTW89_CN][33] = 127, -+ [0][1][RTW89_UK][33] = 127, -+ [0][1][RTW89_FCC][35] = 127, -+ [0][1][RTW89_ETSI][35] = 127, -+ [0][1][RTW89_MKK][35] = 127, -+ [0][1][RTW89_IC][35] = 127, -+ [0][1][RTW89_KCC][35] = 127, -+ [0][1][RTW89_ACMA][35] = 127, -+ [0][1][RTW89_CN][35] = 127, -+ [0][1][RTW89_UK][35] = 127, -+ [0][1][RTW89_FCC][37] = 127, -+ [0][1][RTW89_ETSI][37] = 127, -+ [0][1][RTW89_MKK][37] = 127, -+ [0][1][RTW89_IC][37] = 127, -+ [0][1][RTW89_KCC][37] = 127, -+ [0][1][RTW89_ACMA][37] = 127, -+ [0][1][RTW89_CN][37] = 127, -+ [0][1][RTW89_UK][37] = 127, -+ [0][1][RTW89_FCC][38] = 127, -+ [0][1][RTW89_ETSI][38] = 127, -+ [0][1][RTW89_MKK][38] = 127, -+ [0][1][RTW89_IC][38] = 127, -+ [0][1][RTW89_KCC][38] = 127, -+ [0][1][RTW89_ACMA][38] = 127, -+ [0][1][RTW89_CN][38] = 42, -+ [0][1][RTW89_UK][38] = 127, -+ [0][1][RTW89_FCC][40] = 127, -+ [0][1][RTW89_ETSI][40] = 127, -+ [0][1][RTW89_MKK][40] = 127, -+ [0][1][RTW89_IC][40] = 127, -+ [0][1][RTW89_KCC][40] = 127, -+ [0][1][RTW89_ACMA][40] = 127, -+ [0][1][RTW89_CN][40] = 42, -+ [0][1][RTW89_UK][40] = 127, -+ [0][1][RTW89_FCC][42] = 127, -+ [0][1][RTW89_ETSI][42] = 127, -+ [0][1][RTW89_MKK][42] = 127, -+ [0][1][RTW89_IC][42] = 127, -+ [0][1][RTW89_KCC][42] = 127, -+ [0][1][RTW89_ACMA][42] = 127, -+ [0][1][RTW89_CN][42] = 42, -+ [0][1][RTW89_UK][42] = 127, -+ [0][1][RTW89_FCC][44] = 127, -+ [0][1][RTW89_ETSI][44] = 127, -+ [0][1][RTW89_MKK][44] = 127, -+ [0][1][RTW89_IC][44] = 127, -+ [0][1][RTW89_KCC][44] = 127, -+ [0][1][RTW89_ACMA][44] = 127, -+ [0][1][RTW89_CN][44] = 42, -+ [0][1][RTW89_UK][44] = 127, -+ [0][1][RTW89_FCC][46] = 127, -+ [0][1][RTW89_ETSI][46] = 127, -+ [0][1][RTW89_MKK][46] = 127, -+ [0][1][RTW89_IC][46] = 127, -+ [0][1][RTW89_KCC][46] = 127, -+ [0][1][RTW89_ACMA][46] = 127, -+ [0][1][RTW89_CN][46] = 42, -+ [0][1][RTW89_UK][46] = 127, -+ [0][1][RTW89_FCC][48] = 127, -+ [0][1][RTW89_ETSI][48] = 127, -+ [0][1][RTW89_MKK][48] = 127, -+ [0][1][RTW89_IC][48] = 127, -+ [0][1][RTW89_KCC][48] = 127, -+ [0][1][RTW89_ACMA][48] = 127, -+ [0][1][RTW89_CN][48] = 127, -+ [0][1][RTW89_UK][48] = 127, -+ [0][1][RTW89_FCC][50] = 127, -+ [0][1][RTW89_ETSI][50] = 127, -+ [0][1][RTW89_MKK][50] = 127, -+ [0][1][RTW89_IC][50] = 127, -+ [0][1][RTW89_KCC][50] = 127, -+ [0][1][RTW89_ACMA][50] = 127, -+ [0][1][RTW89_CN][50] = 127, -+ [0][1][RTW89_UK][50] = 127, -+ [0][1][RTW89_FCC][52] = 127, -+ [0][1][RTW89_ETSI][52] = 127, -+ [0][1][RTW89_MKK][52] = 127, -+ [0][1][RTW89_IC][52] = 127, -+ [0][1][RTW89_KCC][52] = 127, -+ [0][1][RTW89_ACMA][52] = 127, -+ [0][1][RTW89_CN][52] = 127, -+ [0][1][RTW89_UK][52] = 127, -+ [1][0][RTW89_FCC][0] = 64, -+ [1][0][RTW89_ETSI][0] = 34, -+ [1][0][RTW89_MKK][0] = 38, -+ [1][0][RTW89_IC][0] = 38, -+ [1][0][RTW89_KCC][0] = 52, -+ [1][0][RTW89_ACMA][0] = 34, -+ [1][0][RTW89_CN][0] = 26, -+ [1][0][RTW89_UK][0] = 34, -+ [1][0][RTW89_FCC][2] = 66, -+ [1][0][RTW89_ETSI][2] = 34, -+ [1][0][RTW89_MKK][2] = 38, -+ [1][0][RTW89_IC][2] = 38, -+ [1][0][RTW89_KCC][2] = 52, -+ [1][0][RTW89_ACMA][2] = 34, -+ [1][0][RTW89_CN][2] = 26, -+ [1][0][RTW89_UK][2] = 34, -+ [1][0][RTW89_FCC][4] = 60, -+ [1][0][RTW89_ETSI][4] = 34, -+ [1][0][RTW89_MKK][4] = 36, -+ [1][0][RTW89_IC][4] = 38, -+ [1][0][RTW89_KCC][4] = 52, -+ [1][0][RTW89_ACMA][4] = 34, -+ [1][0][RTW89_CN][4] = 26, -+ [1][0][RTW89_UK][4] = 34, -+ [1][0][RTW89_FCC][6] = 60, -+ [1][0][RTW89_ETSI][6] = 34, -+ [1][0][RTW89_MKK][6] = 36, -+ [1][0][RTW89_IC][6] = 38, -+ [1][0][RTW89_KCC][6] = 32, -+ [1][0][RTW89_ACMA][6] = 34, -+ [1][0][RTW89_CN][6] = 26, -+ [1][0][RTW89_UK][6] = 34, -+ [1][0][RTW89_FCC][8] = 62, -+ [1][0][RTW89_ETSI][8] = 34, -+ [1][0][RTW89_MKK][8] = 38, -+ [1][0][RTW89_IC][8] = 62, -+ [1][0][RTW89_KCC][8] = 52, -+ [1][0][RTW89_ACMA][8] = 34, -+ [1][0][RTW89_CN][8] = 26, -+ [1][0][RTW89_UK][8] = 34, -+ [1][0][RTW89_FCC][10] = 62, -+ [1][0][RTW89_ETSI][10] = 34, -+ [1][0][RTW89_MKK][10] = 38, -+ [1][0][RTW89_IC][10] = 62, -+ [1][0][RTW89_KCC][10] = 52, -+ [1][0][RTW89_ACMA][10] = 34, -+ [1][0][RTW89_CN][10] = 26, -+ [1][0][RTW89_UK][10] = 34, -+ [1][0][RTW89_FCC][12] = 62, -+ [1][0][RTW89_ETSI][12] = 34, -+ [1][0][RTW89_MKK][12] = 38, -+ [1][0][RTW89_IC][12] = 62, -+ [1][0][RTW89_KCC][12] = 54, -+ [1][0][RTW89_ACMA][12] = 34, -+ [1][0][RTW89_CN][12] = 26, -+ [1][0][RTW89_UK][12] = 34, -+ [1][0][RTW89_FCC][14] = 62, -+ [1][0][RTW89_ETSI][14] = 34, -+ [1][0][RTW89_MKK][14] = 38, -+ [1][0][RTW89_IC][14] = 62, -+ [1][0][RTW89_KCC][14] = 54, -+ [1][0][RTW89_ACMA][14] = 34, -+ [1][0][RTW89_CN][14] = 26, -+ [1][0][RTW89_UK][14] = 34, -+ [1][0][RTW89_FCC][15] = 60, -+ [1][0][RTW89_ETSI][15] = 34, -+ [1][0][RTW89_MKK][15] = 58, -+ [1][0][RTW89_IC][15] = 60, -+ [1][0][RTW89_KCC][15] = 54, -+ [1][0][RTW89_ACMA][15] = 34, -+ [1][0][RTW89_CN][15] = 127, -+ [1][0][RTW89_UK][15] = 34, -+ [1][0][RTW89_FCC][17] = 60, -+ [1][0][RTW89_ETSI][17] = 34, -+ [1][0][RTW89_MKK][17] = 58, -+ [1][0][RTW89_IC][17] = 60, -+ [1][0][RTW89_KCC][17] = 54, -+ [1][0][RTW89_ACMA][17] = 34, -+ [1][0][RTW89_CN][17] = 127, -+ [1][0][RTW89_UK][17] = 34, -+ [1][0][RTW89_FCC][19] = 62, -+ [1][0][RTW89_ETSI][19] = 34, -+ [1][0][RTW89_MKK][19] = 58, -+ [1][0][RTW89_IC][19] = 62, -+ [1][0][RTW89_KCC][19] = 54, -+ [1][0][RTW89_ACMA][19] = 34, -+ [1][0][RTW89_CN][19] = 127, -+ [1][0][RTW89_UK][19] = 34, -+ [1][0][RTW89_FCC][21] = 62, -+ [1][0][RTW89_ETSI][21] = 34, -+ [1][0][RTW89_MKK][21] = 58, -+ [1][0][RTW89_IC][21] = 62, -+ [1][0][RTW89_KCC][21] = 54, -+ [1][0][RTW89_ACMA][21] = 34, -+ [1][0][RTW89_CN][21] = 127, -+ [1][0][RTW89_UK][21] = 34, -+ [1][0][RTW89_FCC][23] = 62, -+ [1][0][RTW89_ETSI][23] = 34, -+ [1][0][RTW89_MKK][23] = 58, -+ [1][0][RTW89_IC][23] = 62, -+ [1][0][RTW89_KCC][23] = 54, -+ [1][0][RTW89_ACMA][23] = 34, -+ [1][0][RTW89_CN][23] = 127, -+ [1][0][RTW89_UK][23] = 34, -+ [1][0][RTW89_FCC][25] = 62, -+ [1][0][RTW89_ETSI][25] = 34, -+ [1][0][RTW89_MKK][25] = 58, -+ [1][0][RTW89_IC][25] = 127, -+ [1][0][RTW89_KCC][25] = 54, -+ [1][0][RTW89_ACMA][25] = 127, -+ [1][0][RTW89_CN][25] = 127, -+ [1][0][RTW89_UK][25] = 34, -+ [1][0][RTW89_FCC][27] = 62, -+ [1][0][RTW89_ETSI][27] = 34, -+ [1][0][RTW89_MKK][27] = 58, -+ [1][0][RTW89_IC][27] = 127, -+ [1][0][RTW89_KCC][27] = 54, -+ [1][0][RTW89_ACMA][27] = 127, -+ [1][0][RTW89_CN][27] = 127, -+ [1][0][RTW89_UK][27] = 34, -+ [1][0][RTW89_FCC][29] = 62, -+ [1][0][RTW89_ETSI][29] = 34, -+ [1][0][RTW89_MKK][29] = 58, -+ [1][0][RTW89_IC][29] = 127, -+ [1][0][RTW89_KCC][29] = 54, -+ [1][0][RTW89_ACMA][29] = 127, -+ [1][0][RTW89_CN][29] = 127, -+ [1][0][RTW89_UK][29] = 34, -+ [1][0][RTW89_FCC][31] = 62, -+ [1][0][RTW89_ETSI][31] = 34, -+ [1][0][RTW89_MKK][31] = 58, -+ [1][0][RTW89_IC][31] = 64, -+ [1][0][RTW89_KCC][31] = 54, -+ [1][0][RTW89_ACMA][31] = 34, -+ [1][0][RTW89_CN][31] = 127, -+ [1][0][RTW89_UK][31] = 34, -+ [1][0][RTW89_FCC][33] = 64, -+ [1][0][RTW89_ETSI][33] = 34, -+ [1][0][RTW89_MKK][33] = 58, -+ [1][0][RTW89_IC][33] = 64, -+ [1][0][RTW89_KCC][33] = 54, -+ [1][0][RTW89_ACMA][33] = 34, -+ [1][0][RTW89_CN][33] = 127, -+ [1][0][RTW89_UK][33] = 34, -+ [1][0][RTW89_FCC][35] = 64, -+ [1][0][RTW89_ETSI][35] = 34, -+ [1][0][RTW89_MKK][35] = 58, -+ [1][0][RTW89_IC][35] = 64, -+ [1][0][RTW89_KCC][35] = 54, -+ [1][0][RTW89_ACMA][35] = 34, -+ [1][0][RTW89_CN][35] = 127, -+ [1][0][RTW89_UK][35] = 34, -+ [1][0][RTW89_FCC][37] = 76, -+ [1][0][RTW89_ETSI][37] = 127, -+ [1][0][RTW89_MKK][37] = 56, -+ [1][0][RTW89_IC][37] = 76, -+ [1][0][RTW89_KCC][37] = 54, -+ [1][0][RTW89_ACMA][37] = 62, -+ [1][0][RTW89_CN][37] = 127, -+ [1][0][RTW89_UK][37] = 62, -+ [1][0][RTW89_FCC][38] = 82, -+ [1][0][RTW89_ETSI][38] = 28, -+ [1][0][RTW89_MKK][38] = 127, -+ [1][0][RTW89_IC][38] = 82, -+ [1][0][RTW89_KCC][38] = 54, -+ [1][0][RTW89_ACMA][38] = 84, -+ [1][0][RTW89_CN][38] = 66, -+ [1][0][RTW89_UK][38] = 34, -+ [1][0][RTW89_FCC][40] = 82, -+ [1][0][RTW89_ETSI][40] = 28, -+ [1][0][RTW89_MKK][40] = 127, -+ [1][0][RTW89_IC][40] = 82, -+ [1][0][RTW89_KCC][40] = 54, -+ [1][0][RTW89_ACMA][40] = 84, -+ [1][0][RTW89_CN][40] = 66, -+ [1][0][RTW89_UK][40] = 34, -+ [1][0][RTW89_FCC][42] = 78, -+ [1][0][RTW89_ETSI][42] = 28, -+ [1][0][RTW89_MKK][42] = 127, -+ [1][0][RTW89_IC][42] = 78, -+ [1][0][RTW89_KCC][42] = 54, -+ [1][0][RTW89_ACMA][42] = 84, -+ [1][0][RTW89_CN][42] = 66, -+ [1][0][RTW89_UK][42] = 34, -+ [1][0][RTW89_FCC][44] = 82, -+ [1][0][RTW89_ETSI][44] = 28, -+ [1][0][RTW89_MKK][44] = 127, -+ [1][0][RTW89_IC][44] = 82, -+ [1][0][RTW89_KCC][44] = 54, -+ [1][0][RTW89_ACMA][44] = 84, -+ [1][0][RTW89_CN][44] = 66, -+ [1][0][RTW89_UK][44] = 34, -+ [1][0][RTW89_FCC][46] = 82, -+ [1][0][RTW89_ETSI][46] = 28, -+ [1][0][RTW89_MKK][46] = 127, -+ [1][0][RTW89_IC][46] = 82, -+ [1][0][RTW89_KCC][46] = 54, -+ [1][0][RTW89_ACMA][46] = 84, -+ [1][0][RTW89_CN][46] = 66, -+ [1][0][RTW89_UK][46] = 34, -+ [1][0][RTW89_FCC][48] = 52, -+ [1][0][RTW89_ETSI][48] = 127, -+ [1][0][RTW89_MKK][48] = 127, -+ [1][0][RTW89_IC][48] = 127, -+ [1][0][RTW89_KCC][48] = 127, -+ [1][0][RTW89_ACMA][48] = 127, -+ [1][0][RTW89_CN][48] = 127, -+ [1][0][RTW89_UK][48] = 127, -+ [1][0][RTW89_FCC][50] = 52, -+ [1][0][RTW89_ETSI][50] = 127, -+ [1][0][RTW89_MKK][50] = 127, -+ [1][0][RTW89_IC][50] = 127, -+ [1][0][RTW89_KCC][50] = 127, -+ [1][0][RTW89_ACMA][50] = 127, -+ [1][0][RTW89_CN][50] = 127, -+ [1][0][RTW89_UK][50] = 127, -+ [1][0][RTW89_FCC][52] = 50, -+ [1][0][RTW89_ETSI][52] = 127, -+ [1][0][RTW89_MKK][52] = 127, -+ [1][0][RTW89_IC][52] = 127, -+ [1][0][RTW89_KCC][52] = 127, -+ [1][0][RTW89_ACMA][52] = 127, -+ [1][0][RTW89_CN][52] = 127, -+ [1][0][RTW89_UK][52] = 127, -+ [1][1][RTW89_FCC][0] = 127, -+ [1][1][RTW89_ETSI][0] = 127, -+ [1][1][RTW89_MKK][0] = 127, -+ [1][1][RTW89_IC][0] = 127, -+ [1][1][RTW89_KCC][0] = 127, -+ [1][1][RTW89_ACMA][0] = 127, -+ [1][1][RTW89_CN][0] = 14, -+ [1][1][RTW89_UK][0] = 127, -+ [1][1][RTW89_FCC][2] = 127, -+ [1][1][RTW89_ETSI][2] = 127, -+ [1][1][RTW89_MKK][2] = 127, -+ [1][1][RTW89_IC][2] = 127, -+ [1][1][RTW89_KCC][2] = 127, -+ [1][1][RTW89_ACMA][2] = 127, -+ [1][1][RTW89_CN][2] = 14, -+ [1][1][RTW89_UK][2] = 127, -+ [1][1][RTW89_FCC][4] = 127, -+ [1][1][RTW89_ETSI][4] = 127, -+ [1][1][RTW89_MKK][4] = 127, -+ [1][1][RTW89_IC][4] = 127, -+ [1][1][RTW89_KCC][4] = 127, -+ [1][1][RTW89_ACMA][4] = 127, -+ [1][1][RTW89_CN][4] = 14, -+ [1][1][RTW89_UK][4] = 127, -+ [1][1][RTW89_FCC][6] = 127, -+ [1][1][RTW89_ETSI][6] = 127, -+ [1][1][RTW89_MKK][6] = 127, -+ [1][1][RTW89_IC][6] = 127, -+ [1][1][RTW89_KCC][6] = 127, -+ [1][1][RTW89_ACMA][6] = 127, -+ [1][1][RTW89_CN][6] = 14, -+ [1][1][RTW89_UK][6] = 127, -+ [1][1][RTW89_FCC][8] = 127, -+ [1][1][RTW89_ETSI][8] = 127, -+ [1][1][RTW89_MKK][8] = 127, -+ [1][1][RTW89_IC][8] = 127, -+ [1][1][RTW89_KCC][8] = 127, -+ [1][1][RTW89_ACMA][8] = 127, -+ [1][1][RTW89_CN][8] = 14, -+ [1][1][RTW89_UK][8] = 127, -+ [1][1][RTW89_FCC][10] = 127, -+ [1][1][RTW89_ETSI][10] = 127, -+ [1][1][RTW89_MKK][10] = 127, -+ [1][1][RTW89_IC][10] = 127, -+ [1][1][RTW89_KCC][10] = 127, -+ [1][1][RTW89_ACMA][10] = 127, -+ [1][1][RTW89_CN][10] = 14, -+ [1][1][RTW89_UK][10] = 127, -+ [1][1][RTW89_FCC][12] = 127, -+ [1][1][RTW89_ETSI][12] = 127, -+ [1][1][RTW89_MKK][12] = 127, -+ [1][1][RTW89_IC][12] = 127, -+ [1][1][RTW89_KCC][12] = 127, -+ [1][1][RTW89_ACMA][12] = 127, -+ [1][1][RTW89_CN][12] = 14, -+ [1][1][RTW89_UK][12] = 127, -+ [1][1][RTW89_FCC][14] = 127, -+ [1][1][RTW89_ETSI][14] = 127, -+ [1][1][RTW89_MKK][14] = 127, -+ [1][1][RTW89_IC][14] = 127, -+ [1][1][RTW89_KCC][14] = 127, -+ [1][1][RTW89_ACMA][14] = 127, -+ [1][1][RTW89_CN][14] = 14, -+ [1][1][RTW89_UK][14] = 127, -+ [1][1][RTW89_FCC][15] = 127, -+ [1][1][RTW89_ETSI][15] = 127, -+ [1][1][RTW89_MKK][15] = 127, -+ [1][1][RTW89_IC][15] = 127, -+ [1][1][RTW89_KCC][15] = 127, -+ [1][1][RTW89_ACMA][15] = 127, -+ [1][1][RTW89_CN][15] = 127, -+ [1][1][RTW89_UK][15] = 127, -+ [1][1][RTW89_FCC][17] = 127, -+ [1][1][RTW89_ETSI][17] = 127, -+ [1][1][RTW89_MKK][17] = 127, -+ [1][1][RTW89_IC][17] = 127, -+ [1][1][RTW89_KCC][17] = 127, -+ [1][1][RTW89_ACMA][17] = 127, -+ [1][1][RTW89_CN][17] = 127, -+ [1][1][RTW89_UK][17] = 127, -+ [1][1][RTW89_FCC][19] = 127, -+ [1][1][RTW89_ETSI][19] = 127, -+ [1][1][RTW89_MKK][19] = 127, -+ [1][1][RTW89_IC][19] = 127, -+ [1][1][RTW89_KCC][19] = 127, -+ [1][1][RTW89_ACMA][19] = 127, -+ [1][1][RTW89_CN][19] = 127, -+ [1][1][RTW89_UK][19] = 127, -+ [1][1][RTW89_FCC][21] = 127, -+ [1][1][RTW89_ETSI][21] = 127, -+ [1][1][RTW89_MKK][21] = 127, -+ [1][1][RTW89_IC][21] = 127, -+ [1][1][RTW89_KCC][21] = 127, -+ [1][1][RTW89_ACMA][21] = 127, -+ [1][1][RTW89_CN][21] = 127, -+ [1][1][RTW89_UK][21] = 127, -+ [1][1][RTW89_FCC][23] = 127, -+ [1][1][RTW89_ETSI][23] = 127, -+ [1][1][RTW89_MKK][23] = 127, -+ [1][1][RTW89_IC][23] = 127, -+ [1][1][RTW89_KCC][23] = 127, -+ [1][1][RTW89_ACMA][23] = 127, -+ [1][1][RTW89_CN][23] = 127, -+ [1][1][RTW89_UK][23] = 127, -+ [1][1][RTW89_FCC][25] = 127, -+ [1][1][RTW89_ETSI][25] = 127, -+ [1][1][RTW89_MKK][25] = 127, -+ [1][1][RTW89_IC][25] = 127, -+ [1][1][RTW89_KCC][25] = 127, -+ [1][1][RTW89_ACMA][25] = 127, -+ [1][1][RTW89_CN][25] = 127, -+ [1][1][RTW89_UK][25] = 127, -+ [1][1][RTW89_FCC][27] = 127, -+ [1][1][RTW89_ETSI][27] = 127, -+ [1][1][RTW89_MKK][27] = 127, -+ [1][1][RTW89_IC][27] = 127, -+ [1][1][RTW89_KCC][27] = 127, -+ [1][1][RTW89_ACMA][27] = 127, -+ [1][1][RTW89_CN][27] = 127, -+ [1][1][RTW89_UK][27] = 127, -+ [1][1][RTW89_FCC][29] = 127, -+ [1][1][RTW89_ETSI][29] = 127, -+ [1][1][RTW89_MKK][29] = 127, -+ [1][1][RTW89_IC][29] = 127, -+ [1][1][RTW89_KCC][29] = 127, -+ [1][1][RTW89_ACMA][29] = 127, -+ [1][1][RTW89_CN][29] = 127, -+ [1][1][RTW89_UK][29] = 127, -+ [1][1][RTW89_FCC][31] = 127, -+ [1][1][RTW89_ETSI][31] = 127, -+ [1][1][RTW89_MKK][31] = 127, -+ [1][1][RTW89_IC][31] = 127, -+ [1][1][RTW89_KCC][31] = 127, -+ [1][1][RTW89_ACMA][31] = 127, -+ [1][1][RTW89_CN][31] = 127, -+ [1][1][RTW89_UK][31] = 127, -+ [1][1][RTW89_FCC][33] = 127, -+ [1][1][RTW89_ETSI][33] = 127, -+ [1][1][RTW89_MKK][33] = 127, -+ [1][1][RTW89_IC][33] = 127, -+ [1][1][RTW89_KCC][33] = 127, -+ [1][1][RTW89_ACMA][33] = 127, -+ [1][1][RTW89_CN][33] = 127, -+ [1][1][RTW89_UK][33] = 127, -+ [1][1][RTW89_FCC][35] = 127, -+ [1][1][RTW89_ETSI][35] = 127, -+ [1][1][RTW89_MKK][35] = 127, -+ [1][1][RTW89_IC][35] = 127, -+ [1][1][RTW89_KCC][35] = 127, -+ [1][1][RTW89_ACMA][35] = 127, -+ [1][1][RTW89_CN][35] = 127, -+ [1][1][RTW89_UK][35] = 127, -+ [1][1][RTW89_FCC][37] = 127, -+ [1][1][RTW89_ETSI][37] = 127, -+ [1][1][RTW89_MKK][37] = 127, -+ [1][1][RTW89_IC][37] = 127, -+ [1][1][RTW89_KCC][37] = 127, -+ [1][1][RTW89_ACMA][37] = 127, -+ [1][1][RTW89_CN][37] = 127, -+ [1][1][RTW89_UK][37] = 127, -+ [1][1][RTW89_FCC][38] = 127, -+ [1][1][RTW89_ETSI][38] = 127, -+ [1][1][RTW89_MKK][38] = 127, -+ [1][1][RTW89_IC][38] = 127, -+ [1][1][RTW89_KCC][38] = 127, -+ [1][1][RTW89_ACMA][38] = 127, -+ [1][1][RTW89_CN][38] = 54, -+ [1][1][RTW89_UK][38] = 127, -+ [1][1][RTW89_FCC][40] = 127, -+ [1][1][RTW89_ETSI][40] = 127, -+ [1][1][RTW89_MKK][40] = 127, -+ [1][1][RTW89_IC][40] = 127, -+ [1][1][RTW89_KCC][40] = 127, -+ [1][1][RTW89_ACMA][40] = 127, -+ [1][1][RTW89_CN][40] = 54, -+ [1][1][RTW89_UK][40] = 127, -+ [1][1][RTW89_FCC][42] = 127, -+ [1][1][RTW89_ETSI][42] = 127, -+ [1][1][RTW89_MKK][42] = 127, -+ [1][1][RTW89_IC][42] = 127, -+ [1][1][RTW89_KCC][42] = 127, -+ [1][1][RTW89_ACMA][42] = 127, -+ [1][1][RTW89_CN][42] = 54, -+ [1][1][RTW89_UK][42] = 127, -+ [1][1][RTW89_FCC][44] = 127, -+ [1][1][RTW89_ETSI][44] = 127, -+ [1][1][RTW89_MKK][44] = 127, -+ [1][1][RTW89_IC][44] = 127, -+ [1][1][RTW89_KCC][44] = 127, -+ [1][1][RTW89_ACMA][44] = 127, -+ [1][1][RTW89_CN][44] = 54, -+ [1][1][RTW89_UK][44] = 127, -+ [1][1][RTW89_FCC][46] = 127, -+ [1][1][RTW89_ETSI][46] = 127, -+ [1][1][RTW89_MKK][46] = 127, -+ [1][1][RTW89_IC][46] = 127, -+ [1][1][RTW89_KCC][46] = 127, -+ [1][1][RTW89_ACMA][46] = 127, -+ [1][1][RTW89_CN][46] = 54, -+ [1][1][RTW89_UK][46] = 127, -+ [1][1][RTW89_FCC][48] = 127, -+ [1][1][RTW89_ETSI][48] = 127, -+ [1][1][RTW89_MKK][48] = 127, -+ [1][1][RTW89_IC][48] = 127, -+ [1][1][RTW89_KCC][48] = 127, -+ [1][1][RTW89_ACMA][48] = 127, -+ [1][1][RTW89_CN][48] = 127, -+ [1][1][RTW89_UK][48] = 127, -+ [1][1][RTW89_FCC][50] = 127, -+ [1][1][RTW89_ETSI][50] = 127, -+ [1][1][RTW89_MKK][50] = 127, -+ [1][1][RTW89_IC][50] = 127, -+ [1][1][RTW89_KCC][50] = 127, -+ [1][1][RTW89_ACMA][50] = 127, -+ [1][1][RTW89_CN][50] = 127, -+ [1][1][RTW89_UK][50] = 127, -+ [1][1][RTW89_FCC][52] = 127, -+ [1][1][RTW89_ETSI][52] = 127, -+ [1][1][RTW89_MKK][52] = 127, -+ [1][1][RTW89_IC][52] = 127, -+ [1][1][RTW89_KCC][52] = 127, -+ [1][1][RTW89_ACMA][52] = 127, -+ [1][1][RTW89_CN][52] = 127, -+ [1][1][RTW89_UK][52] = 127, -+ [2][0][RTW89_FCC][0] = 76, -+ [2][0][RTW89_ETSI][0] = 46, -+ [2][0][RTW89_MKK][0] = 48, -+ [2][0][RTW89_IC][0] = 50, -+ [2][0][RTW89_KCC][0] = 64, -+ [2][0][RTW89_ACMA][0] = 46, -+ [2][0][RTW89_CN][0] = 40, -+ [2][0][RTW89_UK][0] = 46, -+ [2][0][RTW89_FCC][2] = 72, -+ [2][0][RTW89_ETSI][2] = 46, -+ [2][0][RTW89_MKK][2] = 48, -+ [2][0][RTW89_IC][2] = 48, -+ [2][0][RTW89_KCC][2] = 64, -+ [2][0][RTW89_ACMA][2] = 46, -+ [2][0][RTW89_CN][2] = 40, -+ [2][0][RTW89_UK][2] = 46, -+ [2][0][RTW89_FCC][4] = 74, -+ [2][0][RTW89_ETSI][4] = 46, -+ [2][0][RTW89_MKK][4] = 48, -+ [2][0][RTW89_IC][4] = 48, -+ [2][0][RTW89_KCC][4] = 64, -+ [2][0][RTW89_ACMA][4] = 46, -+ [2][0][RTW89_CN][4] = 40, -+ [2][0][RTW89_UK][4] = 46, -+ [2][0][RTW89_FCC][6] = 74, -+ [2][0][RTW89_ETSI][6] = 46, -+ [2][0][RTW89_MKK][6] = 48, -+ [2][0][RTW89_IC][6] = 48, -+ [2][0][RTW89_KCC][6] = 40, -+ [2][0][RTW89_ACMA][6] = 46, -+ [2][0][RTW89_CN][6] = 40, -+ [2][0][RTW89_UK][6] = 46, -+ [2][0][RTW89_FCC][8] = 72, -+ [2][0][RTW89_ETSI][8] = 46, -+ [2][0][RTW89_MKK][8] = 48, -+ [2][0][RTW89_IC][8] = 64, -+ [2][0][RTW89_KCC][8] = 66, -+ [2][0][RTW89_ACMA][8] = 46, -+ [2][0][RTW89_CN][8] = 40, -+ [2][0][RTW89_UK][8] = 46, -+ [2][0][RTW89_FCC][10] = 72, -+ [2][0][RTW89_ETSI][10] = 46, -+ [2][0][RTW89_MKK][10] = 48, -+ [2][0][RTW89_IC][10] = 64, -+ [2][0][RTW89_KCC][10] = 66, -+ [2][0][RTW89_ACMA][10] = 46, -+ [2][0][RTW89_CN][10] = 40, -+ [2][0][RTW89_UK][10] = 46, -+ [2][0][RTW89_FCC][12] = 74, -+ [2][0][RTW89_ETSI][12] = 46, -+ [2][0][RTW89_MKK][12] = 48, -+ [2][0][RTW89_IC][12] = 64, -+ [2][0][RTW89_KCC][12] = 64, -+ [2][0][RTW89_ACMA][12] = 46, -+ [2][0][RTW89_CN][12] = 40, -+ [2][0][RTW89_UK][12] = 46, -+ [2][0][RTW89_FCC][14] = 80, -+ [2][0][RTW89_ETSI][14] = 46, -+ [2][0][RTW89_MKK][14] = 48, -+ [2][0][RTW89_IC][14] = 64, -+ [2][0][RTW89_KCC][14] = 64, -+ [2][0][RTW89_ACMA][14] = 46, -+ [2][0][RTW89_CN][14] = 40, -+ [2][0][RTW89_UK][14] = 46, -+ [2][0][RTW89_FCC][15] = 72, -+ [2][0][RTW89_ETSI][15] = 46, -+ [2][0][RTW89_MKK][15] = 70, -+ [2][0][RTW89_IC][15] = 72, -+ [2][0][RTW89_KCC][15] = 66, -+ [2][0][RTW89_ACMA][15] = 46, -+ [2][0][RTW89_CN][15] = 127, -+ [2][0][RTW89_UK][15] = 46, -+ [2][0][RTW89_FCC][17] = 72, -+ [2][0][RTW89_ETSI][17] = 46, -+ [2][0][RTW89_MKK][17] = 70, -+ [2][0][RTW89_IC][17] = 72, -+ [2][0][RTW89_KCC][17] = 66, -+ [2][0][RTW89_ACMA][17] = 46, -+ [2][0][RTW89_CN][17] = 127, -+ [2][0][RTW89_UK][17] = 46, -+ [2][0][RTW89_FCC][19] = 68, -+ [2][0][RTW89_ETSI][19] = 46, -+ [2][0][RTW89_MKK][19] = 70, -+ [2][0][RTW89_IC][19] = 68, -+ [2][0][RTW89_KCC][19] = 66, -+ [2][0][RTW89_ACMA][19] = 46, -+ [2][0][RTW89_CN][19] = 127, -+ [2][0][RTW89_UK][19] = 46, -+ [2][0][RTW89_FCC][21] = 68, -+ [2][0][RTW89_ETSI][21] = 46, -+ [2][0][RTW89_MKK][21] = 70, -+ [2][0][RTW89_IC][21] = 68, -+ [2][0][RTW89_KCC][21] = 66, -+ [2][0][RTW89_ACMA][21] = 46, -+ [2][0][RTW89_CN][21] = 127, -+ [2][0][RTW89_UK][21] = 46, -+ [2][0][RTW89_FCC][23] = 68, -+ [2][0][RTW89_ETSI][23] = 46, -+ [2][0][RTW89_MKK][23] = 70, -+ [2][0][RTW89_IC][23] = 68, -+ [2][0][RTW89_KCC][23] = 66, -+ [2][0][RTW89_ACMA][23] = 46, -+ [2][0][RTW89_CN][23] = 127, -+ [2][0][RTW89_UK][23] = 46, -+ [2][0][RTW89_FCC][25] = 68, -+ [2][0][RTW89_ETSI][25] = 46, -+ [2][0][RTW89_MKK][25] = 70, -+ [2][0][RTW89_IC][25] = 127, -+ [2][0][RTW89_KCC][25] = 66, -+ [2][0][RTW89_ACMA][25] = 127, -+ [2][0][RTW89_CN][25] = 127, -+ [2][0][RTW89_UK][25] = 46, -+ [2][0][RTW89_FCC][27] = 68, -+ [2][0][RTW89_ETSI][27] = 46, -+ [2][0][RTW89_MKK][27] = 70, -+ [2][0][RTW89_IC][27] = 127, -+ [2][0][RTW89_KCC][27] = 64, -+ [2][0][RTW89_ACMA][27] = 127, -+ [2][0][RTW89_CN][27] = 127, -+ [2][0][RTW89_UK][27] = 46, -+ [2][0][RTW89_FCC][29] = 68, -+ [2][0][RTW89_ETSI][29] = 46, -+ [2][0][RTW89_MKK][29] = 70, -+ [2][0][RTW89_IC][29] = 127, -+ [2][0][RTW89_KCC][29] = 64, -+ [2][0][RTW89_ACMA][29] = 127, -+ [2][0][RTW89_CN][29] = 127, -+ [2][0][RTW89_UK][29] = 46, -+ [2][0][RTW89_FCC][31] = 68, -+ [2][0][RTW89_ETSI][31] = 46, -+ [2][0][RTW89_MKK][31] = 70, -+ [2][0][RTW89_IC][31] = 70, -+ [2][0][RTW89_KCC][31] = 64, -+ [2][0][RTW89_ACMA][31] = 46, -+ [2][0][RTW89_CN][31] = 127, -+ [2][0][RTW89_UK][31] = 46, -+ [2][0][RTW89_FCC][33] = 70, -+ [2][0][RTW89_ETSI][33] = 46, -+ [2][0][RTW89_MKK][33] = 70, -+ [2][0][RTW89_IC][33] = 70, -+ [2][0][RTW89_KCC][33] = 64, -+ [2][0][RTW89_ACMA][33] = 46, -+ [2][0][RTW89_CN][33] = 127, -+ [2][0][RTW89_UK][33] = 46, -+ [2][0][RTW89_FCC][35] = 70, -+ [2][0][RTW89_ETSI][35] = 46, -+ [2][0][RTW89_MKK][35] = 70, -+ [2][0][RTW89_IC][35] = 70, -+ [2][0][RTW89_KCC][35] = 64, -+ [2][0][RTW89_ACMA][35] = 46, -+ [2][0][RTW89_CN][35] = 127, -+ [2][0][RTW89_UK][35] = 46, -+ [2][0][RTW89_FCC][37] = 84, -+ [2][0][RTW89_ETSI][37] = 127, -+ [2][0][RTW89_MKK][37] = 68, -+ [2][0][RTW89_IC][37] = 84, -+ [2][0][RTW89_KCC][37] = 66, -+ [2][0][RTW89_ACMA][37] = 74, -+ [2][0][RTW89_CN][37] = 127, -+ [2][0][RTW89_UK][37] = 74, -+ [2][0][RTW89_FCC][38] = 84, -+ [2][0][RTW89_ETSI][38] = 28, -+ [2][0][RTW89_MKK][38] = 127, -+ [2][0][RTW89_IC][38] = 84, -+ [2][0][RTW89_KCC][38] = 64, -+ [2][0][RTW89_ACMA][38] = 84, -+ [2][0][RTW89_CN][38] = 68, -+ [2][0][RTW89_UK][38] = 46, -+ [2][0][RTW89_FCC][40] = 84, -+ [2][0][RTW89_ETSI][40] = 28, -+ [2][0][RTW89_MKK][40] = 127, -+ [2][0][RTW89_IC][40] = 84, -+ [2][0][RTW89_KCC][40] = 64, -+ [2][0][RTW89_ACMA][40] = 84, -+ [2][0][RTW89_CN][40] = 68, -+ [2][0][RTW89_UK][40] = 46, -+ [2][0][RTW89_FCC][42] = 78, -+ [2][0][RTW89_ETSI][42] = 28, -+ [2][0][RTW89_MKK][42] = 127, -+ [2][0][RTW89_IC][42] = 78, -+ [2][0][RTW89_KCC][42] = 66, -+ [2][0][RTW89_ACMA][42] = 84, -+ [2][0][RTW89_CN][42] = 68, -+ [2][0][RTW89_UK][42] = 46, -+ [2][0][RTW89_FCC][44] = 80, -+ [2][0][RTW89_ETSI][44] = 28, -+ [2][0][RTW89_MKK][44] = 127, -+ [2][0][RTW89_IC][44] = 80, -+ [2][0][RTW89_KCC][44] = 66, -+ [2][0][RTW89_ACMA][44] = 84, -+ [2][0][RTW89_CN][44] = 68, -+ [2][0][RTW89_UK][44] = 46, -+ [2][0][RTW89_FCC][46] = 80, -+ [2][0][RTW89_ETSI][46] = 28, -+ [2][0][RTW89_MKK][46] = 127, -+ [2][0][RTW89_IC][46] = 80, -+ [2][0][RTW89_KCC][46] = 66, -+ [2][0][RTW89_ACMA][46] = 84, -+ [2][0][RTW89_CN][46] = 68, -+ [2][0][RTW89_UK][46] = 46, -+ [2][0][RTW89_FCC][48] = 62, -+ [2][0][RTW89_ETSI][48] = 127, -+ [2][0][RTW89_MKK][48] = 127, -+ [2][0][RTW89_IC][48] = 127, -+ [2][0][RTW89_KCC][48] = 127, -+ [2][0][RTW89_ACMA][48] = 127, -+ [2][0][RTW89_CN][48] = 127, -+ [2][0][RTW89_UK][48] = 127, -+ [2][0][RTW89_FCC][50] = 62, -+ [2][0][RTW89_ETSI][50] = 127, -+ [2][0][RTW89_MKK][50] = 127, -+ [2][0][RTW89_IC][50] = 127, -+ [2][0][RTW89_KCC][50] = 127, -+ [2][0][RTW89_ACMA][50] = 127, -+ [2][0][RTW89_CN][50] = 127, -+ [2][0][RTW89_UK][50] = 127, -+ [2][0][RTW89_FCC][52] = 60, -+ [2][0][RTW89_ETSI][52] = 127, -+ [2][0][RTW89_MKK][52] = 127, -+ [2][0][RTW89_IC][52] = 127, -+ [2][0][RTW89_KCC][52] = 127, -+ [2][0][RTW89_ACMA][52] = 127, -+ [2][0][RTW89_CN][52] = 127, -+ [2][0][RTW89_UK][52] = 127, -+ [2][1][RTW89_FCC][0] = 127, -+ [2][1][RTW89_ETSI][0] = 127, -+ [2][1][RTW89_MKK][0] = 127, -+ [2][1][RTW89_IC][0] = 127, -+ [2][1][RTW89_KCC][0] = 127, -+ [2][1][RTW89_ACMA][0] = 127, -+ [2][1][RTW89_CN][0] = 28, -+ [2][1][RTW89_UK][0] = 127, -+ [2][1][RTW89_FCC][2] = 127, -+ [2][1][RTW89_ETSI][2] = 127, -+ [2][1][RTW89_MKK][2] = 127, -+ [2][1][RTW89_IC][2] = 127, -+ [2][1][RTW89_KCC][2] = 127, -+ [2][1][RTW89_ACMA][2] = 127, -+ [2][1][RTW89_CN][2] = 28, -+ [2][1][RTW89_UK][2] = 127, -+ [2][1][RTW89_FCC][4] = 127, -+ [2][1][RTW89_ETSI][4] = 127, -+ [2][1][RTW89_MKK][4] = 127, -+ [2][1][RTW89_IC][4] = 127, -+ [2][1][RTW89_KCC][4] = 127, -+ [2][1][RTW89_ACMA][4] = 127, -+ [2][1][RTW89_CN][4] = 28, -+ [2][1][RTW89_UK][4] = 127, -+ [2][1][RTW89_FCC][6] = 127, -+ [2][1][RTW89_ETSI][6] = 127, -+ [2][1][RTW89_MKK][6] = 127, -+ [2][1][RTW89_IC][6] = 127, -+ [2][1][RTW89_KCC][6] = 127, -+ [2][1][RTW89_ACMA][6] = 127, -+ [2][1][RTW89_CN][6] = 28, -+ [2][1][RTW89_UK][6] = 127, -+ [2][1][RTW89_FCC][8] = 127, -+ [2][1][RTW89_ETSI][8] = 127, -+ [2][1][RTW89_MKK][8] = 127, -+ [2][1][RTW89_IC][8] = 127, -+ [2][1][RTW89_KCC][8] = 127, -+ [2][1][RTW89_ACMA][8] = 127, -+ [2][1][RTW89_CN][8] = 28, -+ [2][1][RTW89_UK][8] = 127, -+ [2][1][RTW89_FCC][10] = 127, -+ [2][1][RTW89_ETSI][10] = 127, -+ [2][1][RTW89_MKK][10] = 127, -+ [2][1][RTW89_IC][10] = 127, -+ [2][1][RTW89_KCC][10] = 127, -+ [2][1][RTW89_ACMA][10] = 127, -+ [2][1][RTW89_CN][10] = 28, -+ [2][1][RTW89_UK][10] = 127, -+ [2][1][RTW89_FCC][12] = 127, -+ [2][1][RTW89_ETSI][12] = 127, -+ [2][1][RTW89_MKK][12] = 127, -+ [2][1][RTW89_IC][12] = 127, -+ [2][1][RTW89_KCC][12] = 127, -+ [2][1][RTW89_ACMA][12] = 127, -+ [2][1][RTW89_CN][12] = 28, -+ [2][1][RTW89_UK][12] = 127, -+ [2][1][RTW89_FCC][14] = 127, -+ [2][1][RTW89_ETSI][14] = 127, -+ [2][1][RTW89_MKK][14] = 127, -+ [2][1][RTW89_IC][14] = 127, -+ [2][1][RTW89_KCC][14] = 127, -+ [2][1][RTW89_ACMA][14] = 127, -+ [2][1][RTW89_CN][14] = 28, -+ [2][1][RTW89_UK][14] = 127, -+ [2][1][RTW89_FCC][15] = 127, -+ [2][1][RTW89_ETSI][15] = 127, -+ [2][1][RTW89_MKK][15] = 127, -+ [2][1][RTW89_IC][15] = 127, -+ [2][1][RTW89_KCC][15] = 127, -+ [2][1][RTW89_ACMA][15] = 127, -+ [2][1][RTW89_CN][15] = 127, -+ [2][1][RTW89_UK][15] = 127, -+ [2][1][RTW89_FCC][17] = 127, -+ [2][1][RTW89_ETSI][17] = 127, -+ [2][1][RTW89_MKK][17] = 127, -+ [2][1][RTW89_IC][17] = 127, -+ [2][1][RTW89_KCC][17] = 127, -+ [2][1][RTW89_ACMA][17] = 127, -+ [2][1][RTW89_CN][17] = 127, -+ [2][1][RTW89_UK][17] = 127, -+ [2][1][RTW89_FCC][19] = 127, -+ [2][1][RTW89_ETSI][19] = 127, -+ [2][1][RTW89_MKK][19] = 127, -+ [2][1][RTW89_IC][19] = 127, -+ [2][1][RTW89_KCC][19] = 127, -+ [2][1][RTW89_ACMA][19] = 127, -+ [2][1][RTW89_CN][19] = 127, -+ [2][1][RTW89_UK][19] = 127, -+ [2][1][RTW89_FCC][21] = 127, -+ [2][1][RTW89_ETSI][21] = 127, -+ [2][1][RTW89_MKK][21] = 127, -+ [2][1][RTW89_IC][21] = 127, -+ [2][1][RTW89_KCC][21] = 127, -+ [2][1][RTW89_ACMA][21] = 127, -+ [2][1][RTW89_CN][21] = 127, -+ [2][1][RTW89_UK][21] = 127, -+ [2][1][RTW89_FCC][23] = 127, -+ [2][1][RTW89_ETSI][23] = 127, -+ [2][1][RTW89_MKK][23] = 127, -+ [2][1][RTW89_IC][23] = 127, -+ [2][1][RTW89_KCC][23] = 127, -+ [2][1][RTW89_ACMA][23] = 127, -+ [2][1][RTW89_CN][23] = 127, -+ [2][1][RTW89_UK][23] = 127, -+ [2][1][RTW89_FCC][25] = 127, -+ [2][1][RTW89_ETSI][25] = 127, -+ [2][1][RTW89_MKK][25] = 127, -+ [2][1][RTW89_IC][25] = 127, -+ [2][1][RTW89_KCC][25] = 127, -+ [2][1][RTW89_ACMA][25] = 127, -+ [2][1][RTW89_CN][25] = 127, -+ [2][1][RTW89_UK][25] = 127, -+ [2][1][RTW89_FCC][27] = 127, -+ [2][1][RTW89_ETSI][27] = 127, -+ [2][1][RTW89_MKK][27] = 127, -+ [2][1][RTW89_IC][27] = 127, -+ [2][1][RTW89_KCC][27] = 127, -+ [2][1][RTW89_ACMA][27] = 127, -+ [2][1][RTW89_CN][27] = 127, -+ [2][1][RTW89_UK][27] = 127, -+ [2][1][RTW89_FCC][29] = 127, -+ [2][1][RTW89_ETSI][29] = 127, -+ [2][1][RTW89_MKK][29] = 127, -+ [2][1][RTW89_IC][29] = 127, -+ [2][1][RTW89_KCC][29] = 127, -+ [2][1][RTW89_ACMA][29] = 127, -+ [2][1][RTW89_CN][29] = 127, -+ [2][1][RTW89_UK][29] = 127, -+ [2][1][RTW89_FCC][31] = 127, -+ [2][1][RTW89_ETSI][31] = 127, -+ [2][1][RTW89_MKK][31] = 127, -+ [2][1][RTW89_IC][31] = 127, -+ [2][1][RTW89_KCC][31] = 127, -+ [2][1][RTW89_ACMA][31] = 127, -+ [2][1][RTW89_CN][31] = 127, -+ [2][1][RTW89_UK][31] = 127, -+ [2][1][RTW89_FCC][33] = 127, -+ [2][1][RTW89_ETSI][33] = 127, -+ [2][1][RTW89_MKK][33] = 127, -+ [2][1][RTW89_IC][33] = 127, -+ [2][1][RTW89_KCC][33] = 127, -+ [2][1][RTW89_ACMA][33] = 127, -+ [2][1][RTW89_CN][33] = 127, -+ [2][1][RTW89_UK][33] = 127, -+ [2][1][RTW89_FCC][35] = 127, -+ [2][1][RTW89_ETSI][35] = 127, -+ [2][1][RTW89_MKK][35] = 127, -+ [2][1][RTW89_IC][35] = 127, -+ [2][1][RTW89_KCC][35] = 127, -+ [2][1][RTW89_ACMA][35] = 127, -+ [2][1][RTW89_CN][35] = 127, -+ [2][1][RTW89_UK][35] = 127, -+ [2][1][RTW89_FCC][37] = 127, -+ [2][1][RTW89_ETSI][37] = 127, -+ [2][1][RTW89_MKK][37] = 127, -+ [2][1][RTW89_IC][37] = 127, -+ [2][1][RTW89_KCC][37] = 127, -+ [2][1][RTW89_ACMA][37] = 127, -+ [2][1][RTW89_CN][37] = 127, -+ [2][1][RTW89_UK][37] = 127, -+ [2][1][RTW89_FCC][38] = 127, -+ [2][1][RTW89_ETSI][38] = 127, -+ [2][1][RTW89_MKK][38] = 127, -+ [2][1][RTW89_IC][38] = 127, -+ [2][1][RTW89_KCC][38] = 127, -+ [2][1][RTW89_ACMA][38] = 127, -+ [2][1][RTW89_CN][38] = 56, -+ [2][1][RTW89_UK][38] = 127, -+ [2][1][RTW89_FCC][40] = 127, -+ [2][1][RTW89_ETSI][40] = 127, -+ [2][1][RTW89_MKK][40] = 127, -+ [2][1][RTW89_IC][40] = 127, -+ [2][1][RTW89_KCC][40] = 127, -+ [2][1][RTW89_ACMA][40] = 127, -+ [2][1][RTW89_CN][40] = 56, -+ [2][1][RTW89_UK][40] = 127, -+ [2][1][RTW89_FCC][42] = 127, -+ [2][1][RTW89_ETSI][42] = 127, -+ [2][1][RTW89_MKK][42] = 127, -+ [2][1][RTW89_IC][42] = 127, -+ [2][1][RTW89_KCC][42] = 127, -+ [2][1][RTW89_ACMA][42] = 127, -+ [2][1][RTW89_CN][42] = 56, -+ [2][1][RTW89_UK][42] = 127, -+ [2][1][RTW89_FCC][44] = 127, -+ [2][1][RTW89_ETSI][44] = 127, -+ [2][1][RTW89_MKK][44] = 127, -+ [2][1][RTW89_IC][44] = 127, -+ [2][1][RTW89_KCC][44] = 127, -+ [2][1][RTW89_ACMA][44] = 127, -+ [2][1][RTW89_CN][44] = 56, -+ [2][1][RTW89_UK][44] = 127, -+ [2][1][RTW89_FCC][46] = 127, -+ [2][1][RTW89_ETSI][46] = 127, -+ [2][1][RTW89_MKK][46] = 127, -+ [2][1][RTW89_IC][46] = 127, -+ [2][1][RTW89_KCC][46] = 127, -+ [2][1][RTW89_ACMA][46] = 127, -+ [2][1][RTW89_CN][46] = 56, -+ [2][1][RTW89_UK][46] = 127, -+ [2][1][RTW89_FCC][48] = 127, -+ [2][1][RTW89_ETSI][48] = 127, -+ [2][1][RTW89_MKK][48] = 127, -+ [2][1][RTW89_IC][48] = 127, -+ [2][1][RTW89_KCC][48] = 127, -+ [2][1][RTW89_ACMA][48] = 127, -+ [2][1][RTW89_CN][48] = 127, -+ [2][1][RTW89_UK][48] = 127, -+ [2][1][RTW89_FCC][50] = 127, -+ [2][1][RTW89_ETSI][50] = 127, -+ [2][1][RTW89_MKK][50] = 127, -+ [2][1][RTW89_IC][50] = 127, -+ [2][1][RTW89_KCC][50] = 127, -+ [2][1][RTW89_ACMA][50] = 127, -+ [2][1][RTW89_CN][50] = 127, -+ [2][1][RTW89_UK][50] = 127, -+ [2][1][RTW89_FCC][52] = 127, -+ [2][1][RTW89_ETSI][52] = 127, -+ [2][1][RTW89_MKK][52] = 127, -+ [2][1][RTW89_IC][52] = 127, -+ [2][1][RTW89_KCC][52] = 127, -+ [2][1][RTW89_ACMA][52] = 127, -+ [2][1][RTW89_CN][52] = 127, -+ [2][1][RTW89_UK][52] = 127, -+}; -+ -+const struct rtw89_phy_table rtw89_8851b_phy_bb_table = { -+ .regs = rtw89_8851b_phy_bb_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8851b_phy_bb_regs), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table = { -+ .regs = rtw89_8851b_phy_bb_reg_gain, -+ .n_regs = ARRAY_SIZE(rtw89_8851b_phy_bb_reg_gain), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_phy_table rtw89_8851b_phy_radioa_table = { -+ .regs = rtw89_8851b_phy_radioa_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8851b_phy_radioa_regs), -+ .rf_path = RF_PATH_A, -+ .config = rtw89_phy_config_rf_reg_v1, -+}; -+ -+const struct rtw89_phy_table rtw89_8851b_phy_nctl_table = { -+ .regs = rtw89_8851b_phy_nctl_regs, -+ .n_regs = ARRAY_SIZE(rtw89_8851b_phy_nctl_regs), -+ .rf_path = 0, /* don't care */ -+}; -+ -+const struct rtw89_txpwr_table rtw89_8851b_byr_table = { -+ .data = rtw89_8851b_txpwr_byrate, -+ .size = ARRAY_SIZE(rtw89_8851b_txpwr_byrate), -+ .load = rtw89_phy_load_txpwr_byrate, -+}; -+ -+const struct rtw89_txpwr_track_cfg rtw89_8851b_trk_cfg = { -+ .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, -+ .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, -+ .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, -+ .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, -+ .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, -+ .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, -+}; -+ -+const struct rtw89_rfe_parms rtw89_8851b_dflt_parms = { -+ .rule_2ghz = { -+ .lmt = &rtw89_8851b_txpwr_lmt_2g, -+ .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_2g, -+ }, -+ .rule_5ghz = { -+ .lmt = &rtw89_8851b_txpwr_lmt_5g, -+ .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g, -+ }, -+}; -+ -+static const struct rtw89_rfe_parms rtw89_8851b_rfe_parms_type2 = { -+ .rule_2ghz = { -+ .lmt = &rtw89_8851b_txpwr_lmt_2g_type2, -+ .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_2g_type2, -+ }, -+ .rule_5ghz = { -+ .lmt = &rtw89_8851b_txpwr_lmt_5g_type2, -+ .lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g_type2, -+ }, -+}; -+ -+const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[] = { -+ { -+ .rfe_parms = &rtw89_8851b_rfe_parms_type2, -+ .rfe_type = 2, -+ }, -+ {}, -+}; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-045-wifi-rtw89-8851b-add-tables-for-RFK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-045-wifi-rtw89-8851b-add-tables-for-RFK.patch deleted file mode 100644 index 1f1701f32..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-045-wifi-rtw89-8851b-add-tables-for-RFK.patch +++ /dev/null @@ -1,596 +0,0 @@ -From 8c36cf0df434e17c9c39a42f87319a6aaca89b05 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 1 Apr 2023 22:25:48 +0800 -Subject: [PATCH 045/136] wifi: rtw89: 8851b: add tables for RFK - -These tables are used by RF calibrations to assist to configure PHY and -RF registers. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230401142548.55466-4-pkshih@realtek.com ---- - .../realtek/rtw89/rtw8851b_rfk_table.c | 534 ++++++++++++++++++ - .../realtek/rtw89/rtw8851b_rfk_table.h | 38 ++ - 2 files changed, 572 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.c -@@ -0,0 +1,534 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#include "rtw8851b_rfk_table.h" -+ -+static const struct rtw89_reg5_def rtw8851b_dadck_setup_defs[] = { -+ RTW89_DECL_RFK_WM(0xc210, 0x003fc000, 0x80), -+ RTW89_DECL_RFK_WM(0xc224, 0x003fc000, 0x80), -+ RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x3), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0x1f), -+ RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x0), -+ RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x1), -+ RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x0), -+ RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x3), -+ RTW89_DECL_RFK_WM(0xc0f4, BIT(2), 0x0), -+ RTW89_DECL_RFK_WM(0xc0f4, BIT(4), 0x0), -+ RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x1), -+ RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x0), -+ RTW89_DECL_RFK_DELAY(1), -+ RTW89_DECL_RFK_WM(0xc0f4, 0x300, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_setup_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_dadck_post_defs[] = { -+ RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x1), -+ RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x0), -+ RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0xc), -+ RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x1), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_post_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_dack_s0_1_defs[] = { -+ RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x3), -+ RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1), -+ RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1), -+ RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_1_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_dack_s0_2_defs[] = { -+ RTW89_DECL_RFK_WM(0xc004, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x0), -+ RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x7), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_2_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_dack_manual_off_defs[] = { -+ RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc210, BIT(0), 0x0), -+ RTW89_DECL_RFK_WM(0xc224, BIT(0), 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_dack_manual_off_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = { -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101), -+ RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2), -+ RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x1), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5), -+ RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf), -+ RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0), -+ RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_80_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_others_defs[] = { -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101), -+ RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2), -+ RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5), -+ RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf), -+ RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x2), -+ RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), -+ RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_others_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_txk_2ghz_defs[] = { -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x80000, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x00800, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x52, 0x00800, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x6), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x10), -+ RTW89_DECL_RFK_DELAY(1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_2ghz_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_txk_5ghz_defs[] = { -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x60, 0x00007, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x7), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x7), -+ RTW89_DECL_RFK_DELAY(1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_5ghz_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_afebb_restore_defs[] = { -+ RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), -+ RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0), -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_afebb_restore_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_macbb_defs[] = { -+ RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0), -+ RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1), -+ RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0xf801fffd), -+ RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x1), -+ RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7), -+ RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3), -+ RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3), -+ RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa), -+ RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0), -+ RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1), -+ RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), -+ RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x1), -+ RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_iqk_bb_afe_defs[] = { -+ RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x1), -+ RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7), -+ RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1), -+ RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3), -+ RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1), -+ RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0), -+ RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3), -+ RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa), -+ RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0), -+ RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1), -+ RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x1f), -+ RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x13), -+ RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0001), -+ RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0041), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_bb_afe_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_sys_defs[] = { -+ RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5), -+ RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5), -+ RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16), -+ RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1f19), -+ RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x1c), -+ RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041), -+ RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041), -+ RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x2001), -+ RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3), -+ RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3), -+ RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e), -+ RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e), -+ RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4), -+ RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4), -+ RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0), -+ RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33), -+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33), -+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_sys_a_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44), -+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44), -+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0), -+ RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f), -+ RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40), -+ RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040), -+ RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000), -+ RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x026d000), -+ RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00), -+ RTW89_DECL_RFK_WM(0x5818, 0x00ffffff, 0x2c18e8), -+ RTW89_DECL_RFK_WM(0x5818, 0x07000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5818, 0xf0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280), -+ RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080), -+ RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x04), -+ RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), -+ RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2), -+ RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121), -+ RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff), -+ RTW89_DECL_RFK_WM(0x5898, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x589c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16), -+ RTW89_DECL_RFK_WM(0x58b0, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000), -+ RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628), -+ RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f), -+ RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f), -+ RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff), -+ RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000), -+ RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0), -+ RTW89_DECL_RFK_WM(0x58cc, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101), -+ RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00), -+ RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff), -+ RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100), -+ RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c), -+ RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f), -+ RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0x800), -+ RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff), -+ RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_he_tb_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x58a0, MASKDWORD, 0x000000fe), -+ RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_he_tb_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_dck_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1), -+ RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1), -+ RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x1), -+ RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x3), -+ RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x5), -+ RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dck_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_dac_gain_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000), -+ RTW89_DECL_RFK_WM(0x5a00, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a04, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a08, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a0c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a10, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a14, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a18, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a1c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a20, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a24, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a28, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a2c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a30, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a34, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a38, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a3c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a40, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a44, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a48, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a4c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a50, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a54, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a58, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a5c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a60, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a64, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a68, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a6c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a70, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a74, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a78, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a7c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a80, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a84, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a88, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a8c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a90, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a94, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a98, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5a9c, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa0, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa4, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aa8, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5aac, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab0, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab4, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ab8, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5abc, MASKDWORD, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5ac0, MASKDWORD, 0x00000000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dac_gain_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_2g[] = { -+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0200e08), -+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x007), -+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_2g); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_5g[] = { -+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0341a08), -+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201417), -+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008), -+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008), -+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808), -+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x0e0e0808), -+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080d18), -+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808), -+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808), -+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_a_defs_5g); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_align_a_2g_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2400), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), -+ RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000), -+ RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3fa), -+ RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x02e), -+ RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x09c), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x3fb00000), -+ RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x02f), -+ RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x09c), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_2g_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_align_a_5g_defs[] = { -+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000), -+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x3b2d24), -+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000), -+ RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3cb), -+ RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x030), -+ RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x73), -+ RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0xd4), -+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000), -+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_5g_defs); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_slope_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1), -+ RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0xf), -+ RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280), -+ RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200), -+ RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00), -+ RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00), -+ RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a), -+ RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28), -+ RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76), -+ RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0), -+ RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1), -+ RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000), -+ RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2), -+ RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000), -+ RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121), -+ RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_track_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0), -+ RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0), -+ RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1), -+ RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff), -+ RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200), -+ RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080), -+ RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_track_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_tssi_mv_avg_defs_a[] = { -+ RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1), -+ RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0), -+ RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1), -+ RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_mv_avg_defs_a); -+ -+static const struct rtw89_reg5_def rtw8851b_nctl_post_defs[] = { -+ RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x3), -+ RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x3), -+ RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13), -+ RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041), -+ RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x1), -+ RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00fffff), -+ RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3), -+ RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x1), -+ RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x1), -+ RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x1), -+ RTW89_DECL_RFK_WM(0x0730, 0x00003800, 0x7), -+ RTW89_DECL_RFK_WM(0x2730, 0x00003800, 0x7), -+ RTW89_DECL_RFK_WM(0x0c7c, 0x00e00000, 0x1), -+ RTW89_DECL_RFK_WM(0x58c0, 0x0001ffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x78c0, 0x0001ffff, 0x00000), -+ RTW89_DECL_RFK_WM(0x58fc, 0x3f000000, 0x00), -+ RTW89_DECL_RFK_WM(0x78fc, 0x3f000000, 0x00), -+}; -+ -+RTW89_DECLARE_RFK_TBL(rtw8851b_nctl_post_defs); ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk_table.h -@@ -0,0 +1,38 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8851B_RFK_TABLE_H__ -+#define __RTW89_8851B_RFK_TABLE_H__ -+ -+#include "phy.h" -+ -+extern const struct rtw89_rfk_tbl rtw8851b_dadck_setup_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_dadck_post_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_1_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_2_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_dack_manual_off_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_80_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_others_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_2ghz_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_5ghz_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_afebb_restore_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_bb_afe_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_dck_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_dac_gain_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_2g_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_5g_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_2g_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_5g_defs_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_track_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_tssi_mv_avg_defs_a_tbl; -+extern const struct rtw89_rfk_tbl rtw8851b_nctl_post_defs_tbl; -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-046-wifi-rtw89-correct-5-MHz-mask-setting.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-046-wifi-rtw89-correct-5-MHz-mask-setting.patch deleted file mode 100644 index 93b47336a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-046-wifi-rtw89-correct-5-MHz-mask-setting.patch +++ /dev/null @@ -1,75 +0,0 @@ -From d33fc8d0368c180fe2338bfae4f5367a66a719f4 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Thu, 6 Apr 2023 15:28:41 +0800 -Subject: [PATCH 046/136] wifi: rtw89: correct 5 MHz mask setting - -Use primary channel index to determine which 5 MHz mask should be enable. -This mask is used to prevent noise from channel edge to effect CCA -threshold in wide bandwidth (>= 40 MHZ). - -Fixes: 1b00e9236a71 ("rtw89: 8852c: add set channel of BB part") -Fixes: 6b0698984eb0 ("wifi: rtw89: 8852b: add chip_ops::set_channel") -Cc: stable@vger.kernel.org -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230406072841.8308-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 9 +++++---- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 9 +++++---- - 2 files changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -1289,7 +1289,7 @@ static void rtw8852b_ctrl_cck_en(struct - static void rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -- u8 pri_ch = chan->primary_channel; -+ u8 pri_ch = chan->pri_ch_idx; - bool mask_5m_low; - bool mask_5m_en; - -@@ -1297,12 +1297,13 @@ static void rtw8852b_5m_mask(struct rtw8 - case RTW89_CHANNEL_WIDTH_40: - /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */ - mask_5m_en = true; -- mask_5m_low = pri_ch == 2; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWER; - break; - case RTW89_CHANNEL_WIDTH_80: - /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ -- mask_5m_en = pri_ch == 3 || pri_ch == 4; -- mask_5m_low = pri_ch == 4; -+ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || -+ pri_ch == RTW89_SC_20_LOWEST; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; - break; - default: - mask_5m_en = false; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -1380,18 +1380,19 @@ static void rtw8852c_5m_mask(struct rtw8 - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx) - { -- u8 pri_ch = chan->primary_channel; -+ u8 pri_ch = chan->pri_ch_idx; - bool mask_5m_low; - bool mask_5m_en; - - switch (chan->band_width) { - case RTW89_CHANNEL_WIDTH_40: - mask_5m_en = true; -- mask_5m_low = pri_ch == 2; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWER; - break; - case RTW89_CHANNEL_WIDTH_80: -- mask_5m_en = ((pri_ch == 3) || (pri_ch == 4)); -- mask_5m_low = pri_ch == 4; -+ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || -+ pri_ch == RTW89_SC_20_LOWEST; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; - break; - default: - mask_5m_en = false; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-047-wifi-rtw89-fix-crash-due-to-null-pointer-of-sta-in-A.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-047-wifi-rtw89-fix-crash-due-to-null-pointer-of-sta-in-A.patch deleted file mode 100644 index 4f00142cb..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-047-wifi-rtw89-fix-crash-due-to-null-pointer-of-sta-in-A.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8551844d2c5b28b6809a45eb4f5d6e931838fd04 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 6 Apr 2023 17:30:09 +0800 -Subject: [PATCH 047/136] wifi: rtw89: fix crash due to null pointer of sta in - AP mode - -In AP mode, 'sta' could be NULL if sending broadcast/multicast packets, -so we should check before accessing, or it causes crash: - - BUG: kernel NULL pointer dereference, address: 0000000000000004 - #PF: supervisor read access in kernel mode - #PF: error_code(0x0000) - not-present page - PGD 0 P4D 0 - Oops: 0000 [#1] PREEMPT SMP PTI - CPU: 2 PID: 92 Comm: kworker/u33:0 Tainted: G OE - Workqueue: rtw89_tx_wq rtw89_core_txq_work [rtw89_core] - RIP: 0010:rtw89_core_tx_update_desc_info+0x2cc/0x7d0 [rtw89_core] - Code: e2 01 41 be 04 00 00 00 41 8b 84 c4 0c 01 00 00 75 0d 45 31 f6 ... - RSP: 0018:ffffb4cf807afce0 EFLAGS: 00010297 - RAX: 0000000000000001 RBX: ffffb4cf807afd48 RCX: 0000000000000000 - RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001 - RBP: ffffb4cf807afd30 R08: ffff9b28c1e59808 R09: ffff9b28c0297100 - R10: 00000000052cf7c4 R11: 00000000052cf7c4 R12: ffff9b28c1602040 - R13: ffff9b28c07b3000 R14: 0000000000000004 R15: 0000000000000000 - FS: 0000000000000000(0000) GS:ffff9b2a73280000(0000) knlGS:0000000000000000 - CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 - CR2: 0000000000000004 CR3: 00000001ca410003 CR4: 00000000000606e0 - Call Trace: - - rtw89_core_tx_write+0x7c/0x100 [rtw89_core] - rtw89_core_txq_work+0x1b4/0x530 [rtw89_core] - process_one_work+0x222/0x3f0 - worker_thread+0x50/0x3f0 - kthread+0x16b/0x190 - ? rescuer_thread+0x3a0/0x3a0 - ? set_kthread_struct+0x50/0x50 - ret_from_fork+0x22/0x30 - - -Fixes: e5307c9cd7ee ("wifi: rtw89: set data lowest rate according to AP supported rate") -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230406093009.5869-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -707,7 +707,7 @@ static u16 rtw89_core_get_data_rate(stru - else - lowest_rate = RTW89_HW_RATE_OFDM6; - -- if (!sta->deflink.supp_rates[chan->band_type]) -+ if (!sta || !sta->deflink.supp_rates[chan->band_type]) - return lowest_rate; - - return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-048-wifi-rtw89-support-WoWLAN-mode-for-8852be.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-048-wifi-rtw89-support-WoWLAN-mode-for-8852be.patch deleted file mode 100644 index 6636f0835..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-048-wifi-rtw89-support-WoWLAN-mode-for-8852be.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 6863ad915d32990aec79e59db9d2a21a5abedf97 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 10 Apr 2023 13:34:37 +0800 -Subject: [PATCH 048/136] wifi: rtw89: support WoWLAN mode for 8852be - -To support WoWLAN mode for 8852be, we add one PLE quota setting and -WoWLAN stub, which shows that supported WLAN events include receiving -magic packet, rekey packet and deauth packet, and disconnecting from AP. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230410053438.10682-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 2 ++ - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 16 ++++++++++++++++ - 3 files changed, 19 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1473,6 +1473,8 @@ const struct rtw89_mac_size_set rtw89_ma - .ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,}, - /* 8852A PCIE WOW */ - .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, -+ /* 8852B PCIE WOW */ -+ .ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, - }; - EXPORT_SYMBOL(rtw89_mac_size); - ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -816,6 +816,7 @@ struct rtw89_mac_size_set { - const struct rtw89_ple_quota ple_qt47; - const struct rtw89_ple_quota ple_qt58; - const struct rtw89_ple_quota ple_qt_52a_wow; -+ const struct rtw89_ple_quota ple_qt_52b_wow; - }; - - extern const struct rtw89_mac_size_set rtw89_mac_size; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -53,6 +53,10 @@ static const struct rtw89_dle_mem rtw885 - &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, - &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, - &rtw89_mac_size.ple_qt58}, -+ [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size6, -+ &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -+ &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, -+ &rtw89_mac_size.ple_qt_52b_wow}, - [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, - &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, - &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, -@@ -2483,6 +2487,15 @@ static const struct rtw89_chip_ops rtw88 - .btc_set_policy = rtw89_btc_set_policy_v1, - }; - -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support rtw_wowlan_stub_8852b = { -+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+ .n_patterns = RTW89_MAX_PATTERN_NUM, -+ .pattern_max_len = RTW89_MAX_PATTERN_SIZE, -+ .pattern_min_len = 1, -+}; -+#endif -+ - const struct rtw89_chip_info rtw8852b_chip_info = { - .chip_id = RTL8852B, - .ops = &rtw8852b_chip_ops, -@@ -2579,6 +2592,9 @@ const struct rtw89_chip_info rtw8852b_ch - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), - .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, -+#ifdef CONFIG_PM -+ .wowlan_stub = &rtw_wowlan_stub_8852b, -+#endif - }; - EXPORT_SYMBOL(rtw8852b_chip_info); - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-049-wifi-rtw89-fix-power-save-function-in-WoWLAN-mode.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-049-wifi-rtw89-fix-power-save-function-in-WoWLAN-mode.patch deleted file mode 100644 index a71b73862..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-049-wifi-rtw89-fix-power-save-function-in-WoWLAN-mode.patch +++ /dev/null @@ -1,77 +0,0 @@ -From deb1b2aed763828b54a5be9be76c3a43c295f9f0 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Mon, 10 Apr 2023 13:34:38 +0800 -Subject: [PATCH 049/136] wifi: rtw89: fix power save function in WoWLAN mode - -In WoWLAN Mode, it's expected that WiFi chip could enter power save mode -only after all setting is finished, but current wow_enter_lps function -break the rule and may lead to WoWLAN function fail in low probability, -so fix it. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230410053438.10682-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 +- - drivers/net/wireless/realtek/rtw89/ps.c | 6 ++++-- - drivers/net/wireless/realtek/rtw89/ps.h | 3 ++- - drivers/net/wireless/realtek/rtw89/wow.c | 2 +- - 4 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2503,7 +2503,7 @@ static void rtw89_vif_enter_lps(struct r - - if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && - rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) -- rtw89_enter_lps(rtwdev, rtwvif); -+ rtw89_enter_lps(rtwdev, rtwvif, true); - } - - static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/ps.c -+++ b/drivers/net/wireless/realtek/rtw89/ps.c -@@ -114,7 +114,8 @@ void rtw89_leave_ps_mode(struct rtw89_de - __rtw89_leave_ps_mode(rtwdev); - } - --void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool ps_mode) - { - lockdep_assert_held(&rtwdev->mutex); - -@@ -122,7 +123,8 @@ void rtw89_enter_lps(struct rtw89_dev *r - return; - - __rtw89_enter_lps(rtwdev, rtwvif->mac_id); -- __rtw89_enter_ps_mode(rtwdev, rtwvif); -+ if (ps_mode) -+ __rtw89_enter_ps_mode(rtwdev, rtwvif); - } - - static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ---- a/drivers/net/wireless/realtek/rtw89/ps.h -+++ b/drivers/net/wireless/realtek/rtw89/ps.h -@@ -5,7 +5,8 @@ - #ifndef __RTW89_PS_H_ - #define __RTW89_PS_H_ - --void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); -+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ bool ps_mode); - void rtw89_leave_lps(struct rtw89_dev *rtwdev); - void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); - void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -30,7 +30,7 @@ static void rtw89_wow_enter_lps(struct r - struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; - -- rtw89_enter_lps(rtwdev, rtwvif); -+ rtw89_enter_lps(rtwdev, rtwvif, false); - } - - static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-050-wifi-rtw89-coex-Enable-Wi-Fi-RX-gain-control-for-fre.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-050-wifi-rtw89-coex-Enable-Wi-Fi-RX-gain-control-for-fre.patch deleted file mode 100644 index 7473018da..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-050-wifi-rtw89-coex-Enable-Wi-Fi-RX-gain-control-for-fre.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 36ef71db559f6a0dc2d7a9af8edb16c387d18ce2 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 12 Apr 2023 09:28:28 +0800 -Subject: [PATCH 050/136] wifi: rtw89: coex: Enable Wi-Fi RX gain control for - free run solution - -When Wi-Fi & Bluetooth are both busy at the same time, Wi-Fi need to -enable RX gain to protect Wi-Fi RX RF ability. Without this configure -the interference from Bluetooth will bring a big impact to Wi-Fi RX. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230412012831.10519-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 4 ++-- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -332,7 +332,7 @@ static const struct rtw89_btc_rf_trx_par - {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ - {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ - {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ - {6, 1, 0, 7}, - {13, 1, 0, 7}, - {13, 1, 0, 7} -@@ -344,7 +344,7 @@ static const struct rtw89_btc_rf_trx_par - {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ - {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ - {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ - {255, 1, 0, 7}, - {255, 1, 0, 7}, - {255, 1, 0, 7} ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2542,7 +2542,7 @@ static const struct rtw89_btc_rf_trx_par - {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ - {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ - {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ - {6, 1, 0, 7}, - {13, 1, 0, 7}, - {13, 1, 0, 7} -@@ -2554,7 +2554,7 @@ static const struct rtw89_btc_rf_trx_par - {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ - {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ - {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -- {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ - {255, 1, 0, 7}, - {255, 1, 0, 7}, - {255, 1, 0, 7} diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-051-wifi-rtw89-coex-Add-path-control-register-to-monitor.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-051-wifi-rtw89-coex-Add-path-control-register-to-monitor.patch deleted file mode 100644 index b071ccf09..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-051-wifi-rtw89-coex-Add-path-control-register-to-monitor.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 9fde30562840837e4e2138bc3f88dba2b9963d98 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 12 Apr 2023 09:28:29 +0800 -Subject: [PATCH 051/136] wifi: rtw89: coex: Add path control register to - monitor list - -Chips use similar hardware for path control, but could different -path/antenna configuration. Add these register to monitor, if there are -wrong settings, these register can help to debug. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230412012831.10519-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 4 +++- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 +++ - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -364,7 +364,9 @@ static const struct rtw89_btc_fbtc_mreg - RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), - RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), - RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), -- RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4738), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4688), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4694), - }; - - static const u8 rtw89_btc_8852b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2576,6 +2576,9 @@ static const struct rtw89_btc_fbtc_mreg - RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), - RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), - RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c), - }; - - static diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-052-wifi-rtw89-coex-Update-function-to-get-BT-RSSI-and-h.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-052-wifi-rtw89-coex-Update-function-to-get-BT-RSSI-and-h.patch deleted file mode 100644 index 9eb9a4a0a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-052-wifi-rtw89-coex-Update-function-to-get-BT-RSSI-and-h.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2380a220316fc2e753014b1862ed579796d29ac5 Mon Sep 17 00:00:00 2001 -From: Ching-Te Ku -Date: Wed, 12 Apr 2023 09:28:30 +0800 -Subject: [PATCH 052/136] wifi: rtw89: coex: Update function to get BT RSSI and - hardware counter - -Correct Bluetooth RSSI count method. The 6dB is the gap between hardware -packet sampled value and real RSSI value. - -Signed-off-by: Ching-Te Ku -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230412012831.10519-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 3 ++- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 3 ++- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 ++- - 3 files changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1832,7 +1832,8 @@ rtw8852a_btc_set_wl_txpwr_ctrl(struct rt - static - s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) - { -- return clamp_t(s8, val, -100, 0) + 100; -+ /* +6 for compensate offset */ -+ return clamp_t(s8, val + 6, -100, 0) + 100; - } - - static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2279,7 +2279,8 @@ do { \ - static - s8 rtw8852b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) - { -- return clamp_t(s8, val, -100, 0) + 100; -+ /* +6 for compensate offset */ -+ return clamp_t(s8, val + 6, -100, 0) + 100; - } - - static ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2533,7 +2533,8 @@ do { \ - static - s8 rtw8852c_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) - { -- return clamp_t(s8, val, -100, 0) + 100; -+ /* +6 for compensate offset */ -+ return clamp_t(s8, val + 6, -100, 0) + 100; - } - - static const struct rtw89_btc_rf_trx_para rtw89_btc_8852c_rf_ul[] = { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-053-wifi-rtw89-coex-send-more-hardware-module-info-to-fi.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-053-wifi-rtw89-coex-send-more-hardware-module-info-to-fi.patch deleted file mode 100644 index 07029dafd..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-053-wifi-rtw89-coex-send-more-hardware-module-info-to-fi.patch +++ /dev/null @@ -1,256 +0,0 @@ -From c0fea064b2647a5069e2c234fb44286c8a205993 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 12 Apr 2023 09:28:31 +0800 -Subject: [PATCH 053/136] wifi: rtw89: coex: send more hardware module info to - firmware for 8851B - -8851B has various hardware module types, so BT coexistence in firmware -needs these information to make decision. Add them to make 8851B work -well. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230412012831.10519-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 5 +- - drivers/net/wireless/realtek/rtw89/fw.c | 64 ++++++------ - drivers/net/wireless/realtek/rtw89/fw.h | 113 +++++++--------------- - 3 files changed, 75 insertions(+), 107 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -959,6 +959,8 @@ struct rtw89_btc_ant_info { - - u8 single_pos: 1;/* Single antenna at S0 or S1 */ - u8 diversity: 1; -+ u8 btg_pos: 2; -+ u8 stream_cnt: 4; - }; - - enum rtw89_tfc_dir { -@@ -1415,8 +1417,9 @@ struct rtw89_btc_module { - u8 bt_solo: 1; - u8 bt_pos: 1; - u8 switch_type: 1; -+ u8 wa_type: 3; - -- u8 rsvd; -+ u8 kt_ver_adie; - }; - - #define RTW89_BTC_DM_MAXSTEP 30 ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -1924,8 +1924,6 @@ fail: - return ret; - } - --#define H2C_LEN_CXDRVHDR 2 --#define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR) - int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -1933,44 +1931,52 @@ int rtw89_fw_h2c_cxdrv_init(struct rtw89 - struct rtw89_btc_init_info *init_info = &dm->init_info; - struct rtw89_btc_module *module = &init_info->module; - struct rtw89_btc_ant_info *ant = &module->ant; -+ struct rtw89_h2c_cxinit *h2c; -+ u32 len = sizeof(*h2c); - struct sk_buff *skb; -- u8 *cmd; - int ret; - -- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_INIT); -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); - return -ENOMEM; - } -- skb_put(skb, H2C_LEN_CXDRVINFO_INIT); -- cmd = skb->data; -+ skb_put(skb, len); -+ h2c = (struct rtw89_h2c_cxinit *)skb->data; - -- RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT); -- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR); -+ h2c->hdr.type = CXDRVINFO_INIT; -+ h2c->hdr.len = len - H2C_LEN_CXDRVHDR; - -- RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type); -- RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num); -- RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation); -- RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos); -- RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity); -- -- RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type); -- RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv); -- RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo); -- RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos); -- RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type); -- -- RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch); -- RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only); -- RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok); -- RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en); -- RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other); -- RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only); -+ h2c->ant_type = ant->type; -+ h2c->ant_num = ant->num; -+ h2c->ant_iso = ant->isolation; -+ h2c->ant_info = -+ u8_encode_bits(ant->single_pos, RTW89_H2C_CXINIT_ANT_INFO_POS) | -+ u8_encode_bits(ant->diversity, RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY) | -+ u8_encode_bits(ant->btg_pos, RTW89_H2C_CXINIT_ANT_INFO_BTG_POS) | -+ u8_encode_bits(ant->stream_cnt, RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT); -+ -+ h2c->mod_rfe = module->rfe_type; -+ h2c->mod_cv = module->cv; -+ h2c->mod_info = -+ u8_encode_bits(module->bt_solo, RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO) | -+ u8_encode_bits(module->bt_pos, RTW89_H2C_CXINIT_MOD_INFO_BT_POS) | -+ u8_encode_bits(module->switch_type, RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE) | -+ u8_encode_bits(module->wa_type, RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE); -+ h2c->mod_adie_kt = module->kt_ver_adie; -+ h2c->wl_gch = init_info->wl_guard_ch; -+ -+ h2c->info = -+ u8_encode_bits(init_info->wl_only, RTW89_H2C_CXINIT_INFO_WL_ONLY) | -+ u8_encode_bits(init_info->wl_init_ok, RTW89_H2C_CXINIT_INFO_WL_INITOK) | -+ u8_encode_bits(init_info->dbcc_en, RTW89_H2C_CXINIT_INFO_DBCC_EN) | -+ u8_encode_bits(init_info->cx_other, RTW89_H2C_CXINIT_INFO_CX_OTHER) | -+ u8_encode_bits(init_info->bt_only, RTW89_H2C_CXINIT_INFO_BT_ONLY); - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, - H2C_CAT_OUTSRC, BTFC_SET, - SET_DRV_INFO, 0, 0, -- H2C_LEN_CXDRVINFO_INIT); -+ len); - - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2197,85 +2197,44 @@ static inline void RTW89_SET_FWCMD_CXHDR - u8p_replace_bits((u8 *)(cmd) + 1, val, GENMASK(7, 0)); - } - --static inline void RTW89_SET_FWCMD_CXINIT_ANT_TYPE(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_ANT_NUM(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_ANT_ISO(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 4, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_ANT_POS(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(1)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_MOD_RFE(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 6, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_MOD_CV(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 7, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(1)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(2)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_WL_GCH(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 10, val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_WL_ONLY(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(0)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_WL_INITOK(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(1)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_DBCC_EN(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(2)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_CX_OTHER(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(3)); --} -- --static inline void RTW89_SET_FWCMD_CXINIT_BT_ONLY(void *cmd, u8 val) --{ -- u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(4)); --} -+struct rtw89_h2c_cxhdr { -+ u8 type; -+ u8 len; -+} __packed; -+ -+#define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr) -+ -+struct rtw89_h2c_cxinit { -+ struct rtw89_h2c_cxhdr hdr; -+ u8 ant_type; -+ u8 ant_num; -+ u8 ant_iso; -+ u8 ant_info; -+ u8 mod_rfe; -+ u8 mod_cv; -+ u8 mod_info; -+ u8 mod_adie_kt; -+ u8 wl_gch; -+ u8 info; -+ u8 rsvd; -+ u8 rsvd1; -+} __packed; -+ -+#define RTW89_H2C_CXINIT_ANT_INFO_POS BIT(0) -+#define RTW89_H2C_CXINIT_ANT_INFO_DIVERSITY BIT(1) -+#define RTW89_H2C_CXINIT_ANT_INFO_BTG_POS GENMASK(3, 2) -+#define RTW89_H2C_CXINIT_ANT_INFO_STREAM_CNT GENMASK(7, 4) -+ -+#define RTW89_H2C_CXINIT_MOD_INFO_BT_SOLO BIT(0) -+#define RTW89_H2C_CXINIT_MOD_INFO_BT_POS BIT(1) -+#define RTW89_H2C_CXINIT_MOD_INFO_SW_TYPE BIT(2) -+#define RTW89_H2C_CXINIT_MOD_INFO_WA_TYPE GENMASK(5, 3) -+ -+#define RTW89_H2C_CXINIT_INFO_WL_ONLY BIT(0) -+#define RTW89_H2C_CXINIT_INFO_WL_INITOK BIT(1) -+#define RTW89_H2C_CXINIT_INFO_DBCC_EN BIT(2) -+#define RTW89_H2C_CXINIT_INFO_CX_OTHER BIT(3) -+#define RTW89_H2C_CXINIT_INFO_BT_ONLY BIT(4) - - static inline void RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(void *cmd, u8 val) - { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-054-wifi-rtw89-prohibit-enter-IPS-during-HW-scan.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-054-wifi-rtw89-prohibit-enter-IPS-during-HW-scan.patch deleted file mode 100644 index 0fa3ceb43..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-054-wifi-rtw89-prohibit-enter-IPS-during-HW-scan.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e579e943bac3b52f69a25738fcbd8be945f72689 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Sat, 15 Apr 2023 11:48:55 +0800 -Subject: [PATCH 054/136] wifi: rtw89: prohibit enter IPS during HW scan - -Mac80211 core may ask driver to change to idle mode during HW scan, -then H2C command for HW scan will send failed since chip is in idle -mode. Therefore, We check the SCANNING flag before entering IPS to -prevent this behavior. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415034900.15679-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -105,7 +105,8 @@ static int rtw89_ops_config(struct ieee8 - } - - if ((changed & IEEE80211_CONF_CHANGE_IDLE) && -- (hw->conf.flags & IEEE80211_CONF_IDLE)) -+ (hw->conf.flags & IEEE80211_CONF_IDLE) && -+ !rtwdev->scanning) - rtw89_enter_ips(rtwdev); - - mutex_unlock(&rtwdev->mutex); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-055-wifi-rtw89-refine-scan-function-after-chanctx.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-055-wifi-rtw89-refine-scan-function-after-chanctx.patch deleted file mode 100644 index 1e872fe2c..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-055-wifi-rtw89-refine-scan-function-after-chanctx.patch +++ /dev/null @@ -1,222 +0,0 @@ -From e7399db231d07f1e5a4179f100ccd0106fdbee03 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Sat, 15 Apr 2023 11:48:56 +0800 -Subject: [PATCH 055/136] wifi: rtw89: refine scan function after chanctx - -Since we can get the current channel definition each interface maps to, -remove store_op function that is no longer required to make things simple. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415034900.15679-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 9 ++++ - drivers/net/wireless/realtek/rtw89/core.h | 7 ++- - drivers/net/wireless/realtek/rtw89/fw.c | 47 ++++++------------- - drivers/net/wireless/realtek/rtw89/fw.h | 1 - - drivers/net/wireless/realtek/rtw89/mac.c | 14 ++++-- - drivers/net/wireless/realtek/rtw89/mac80211.c | 1 - - 6 files changed, 35 insertions(+), 44 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -360,6 +360,15 @@ void rtw89_set_channel(struct rtw89_dev - rtw89_set_entity_state(rtwdev, true); - } - -+void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ struct rtw89_chan *chan) -+{ -+ const struct cfg80211_chan_def *chandef; -+ -+ chandef = rtw89_chandef_get(rtwdev, rtwvif->sub_entity_idx); -+ rtw89_get_channel_params(chandef, chan); -+} -+ - static enum rtw89_core_tx_type - rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, - struct sk_buff *skb) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3936,10 +3936,7 @@ struct rtw89_early_h2c { - struct rtw89_hw_scan_info { - struct ieee80211_vif *scanning_vif; - struct list_head pkt_list[NUM_NL80211_BANDS]; -- u8 op_pri_ch; -- u8 op_chan; -- u8 op_bw; -- u8 op_band; -+ struct rtw89_chan op_chan; - u32 last_chan_idx; - }; - -@@ -4981,6 +4978,8 @@ void rtw89_free_ieee80211_hw(struct rtw8 - void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev); - void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef); - void rtw89_set_channel(struct rtw89_dev *rtwdev); -+void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, -+ struct rtw89_chan *chan); - u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); - void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); - void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2551,7 +2551,7 @@ int rtw89_fw_h2c_scan_offload(struct rtw - struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif) - { -- struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; -+ struct rtw89_chan *op = &rtwdev->scan_info.op_chan; - struct sk_buff *skb; - u8 *cmd; - int ret; -@@ -2573,13 +2573,11 @@ int rtw89_fw_h2c_scan_offload(struct rtw - RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE); - RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE); - if (option->target_ch_mode) { -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, scan_info->op_bw); -+ RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, op->band_width); - RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd, -- scan_info->op_pri_ch); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd, -- scan_info->op_chan); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(cmd, -- scan_info->op_band); -+ op->primary_channel); -+ RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd, op->channel); -+ RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(cmd, op->band_type); - } - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -@@ -3158,6 +3156,7 @@ static void rtw89_hw_scan_add_chan(struc - struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct cfg80211_scan_request *req = rtwvif->scan_req; -+ struct rtw89_chan *op = &rtwdev->scan_info.op_chan; - struct rtw89_pktofld_info *info; - u8 band, probe_count = 0; - int ret; -@@ -3201,10 +3200,10 @@ static void rtw89_hw_scan_add_chan(struc - - switch (chan_type) { - case RTW89_CHAN_OPERATE: -- ch_info->central_ch = scan_info->op_chan; -- ch_info->pri_ch = scan_info->op_pri_ch; -- ch_info->ch_band = scan_info->op_band; -- ch_info->bw = scan_info->op_bw; -+ ch_info->central_ch = op->channel; -+ ch_info->pri_ch = op->primary_channel; -+ ch_info->ch_band = op->band_type; -+ ch_info->bw = op->band_width; - ch_info->tx_null = true; - ch_info->num_pkt = 0; - break; -@@ -3321,6 +3320,7 @@ void rtw89_hw_scan_start(struct rtw89_de - u32 rx_fltr = rtwdev->hal.rx_fltr; - u8 mac_addr[ETH_ALEN]; - -+ rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan); - rtwdev->scan_info.scanning_vif = vif; - rtwdev->scan_info.last_chan_idx = 0; - rtwvif->scan_ies = &scan_req->ies; -@@ -3346,6 +3346,7 @@ void rtw89_hw_scan_start(struct rtw89_de - void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - bool aborted) - { -+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; - struct cfg80211_scan_info info = { - .aborted = aborted, - }; -@@ -3367,11 +3368,9 @@ void rtw89_hw_scan_complete(struct rtw89 - rtwvif = (struct rtw89_vif *)vif->drv_priv; - rtwvif->scan_req = NULL; - rtwvif->scan_ies = NULL; -- rtwdev->scan_info.last_chan_idx = 0; -- rtwdev->scan_info.scanning_vif = NULL; -+ scan_info->last_chan_idx = 0; -+ scan_info->scanning_vif = NULL; - -- if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK) -- rtw89_store_op_chan(rtwdev, false); - rtw89_set_channel(rtwdev); - } - -@@ -3407,24 +3406,6 @@ out: - return ret; - } - --void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup) --{ -- struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; -- const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -- struct rtw89_chan new; -- -- if (backup) { -- scan_info->op_pri_ch = cur->primary_channel; -- scan_info->op_chan = cur->channel; -- scan_info->op_bw = cur->band_width; -- scan_info->op_band = cur->band_type; -- } else { -- rtw89_chan_create(&new, scan_info->op_chan, scan_info->op_pri_ch, -- scan_info->op_band, scan_info->op_bw); -- rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new); -- } --} -- - #define H2C_FW_CPU_EXCEPTION_LEN 4 - #define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566 - int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3713,7 +3713,6 @@ int rtw89_fw_msg_reg(struct rtw89_dev *r - struct rtw89_mac_c2h_info *c2h_info); - int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); - void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); --void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup); - void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, - struct ieee80211_scan_request *req); - void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4194,9 +4194,9 @@ rtw89_mac_c2h_macid_pause(struct rtw89_d - - static bool rtw89_is_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel) - { -- struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; -+ const struct rtw89_chan *op = &rtwdev->scan_info.op_chan; - -- return band == scan_info->op_band && channel == scan_info->op_pri_ch; -+ return band == op->band_type && channel == op->primary_channel; - } - - static void -@@ -4246,11 +4246,15 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_ - } - break; - case RTW89_SCAN_ENTER_CH_NOTIFY: -- rtw89_chan_create(&new, chan, chan, band, RTW89_CHANNEL_WIDTH_20); -- rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new); - if (rtw89_is_op_chan(rtwdev, band, chan)) { -- rtw89_store_op_chan(rtwdev, false); -+ rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx, -+ &rtwdev->scan_info.op_chan); - ieee80211_wake_queues(rtwdev->hw); -+ } else { -+ rtw89_chan_create(&new, chan, chan, band, -+ RTW89_CHANNEL_WIDTH_20); -+ rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx, -+ &new); - } - break; - default: ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -418,7 +418,6 @@ static void rtw89_ops_bss_info_changed(s - rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); - rtw89_mac_port_update(rtwdev, rtwvif); - rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif); -- rtw89_store_op_chan(rtwdev, true); - } else { - /* Abort ongoing scan if cancel_scan isn't issued - * when disconnected by peer diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-056-wifi-rtw89-use-struct-instead-of-macros-to-set-H2C-c.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-056-wifi-rtw89-use-struct-instead-of-macros-to-set-H2C-c.patch deleted file mode 100644 index 1ffa1b123..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-056-wifi-rtw89-use-struct-instead-of-macros-to-set-H2C-c.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 8b048bd5ddf700c72734c4a2a79ecdf082273edb Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 15 Apr 2023 11:48:57 +0800 -Subject: [PATCH 056/136] wifi: rtw89: use struct instead of macros to set H2C - command of hardware scan - -Remove macros that set H2C data. Instead, use struct and -le32_encode_bits() with mask definition to make it clean. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415034900.15679-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 45 ++++++---- - drivers/net/wireless/realtek/rtw89/fw.h | 114 ++++++------------------ - 2 files changed, 51 insertions(+), 108 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2546,44 +2546,51 @@ fail: - return ret; - } - --#define H2C_LEN_SCAN_OFFLOAD 28 - int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, - struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif) - { - struct rtw89_chan *op = &rtwdev->scan_info.op_chan; -+ struct rtw89_h2c_scanofld *h2c; -+ u32 len = sizeof(*h2c); - struct sk_buff *skb; -- u8 *cmd; - int ret; - -- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_SCAN_OFFLOAD); -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); - if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n"); - return -ENOMEM; - } -- skb_put(skb, H2C_LEN_SCAN_OFFLOAD); -- cmd = skb->data; -+ skb_put(skb, len); -+ h2c = (struct rtw89_h2c_scanofld *)skb->data; -+ -+ h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) | -+ le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) | -+ le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) | -+ le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION); -+ -+ h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) | -+ le32_encode_bits(option->target_ch_mode, -+ RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) | -+ le32_encode_bits(RTW89_SCAN_IMMEDIATE, -+ RTW89_H2C_SCANOFLD_W1_START_MODE) | -+ le32_encode_bits(RTW89_SCAN_ONCE, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE); - -- RTW89_SET_FWCMD_SCANOFLD_MACID(cmd, rtwvif->mac_id); -- RTW89_SET_FWCMD_SCANOFLD_PORT_ID(cmd, rtwvif->port); -- RTW89_SET_FWCMD_SCANOFLD_BAND(cmd, RTW89_PHY_0); -- RTW89_SET_FWCMD_SCANOFLD_OPERATION(cmd, option->enable); -- RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(cmd, true); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(cmd, option->target_ch_mode); -- RTW89_SET_FWCMD_SCANOFLD_START_MODE(cmd, RTW89_SCAN_IMMEDIATE); -- RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(cmd, RTW89_SCAN_ONCE); - if (option->target_ch_mode) { -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(cmd, op->band_width); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(cmd, -- op->primary_channel); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(cmd, op->channel); -- RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(cmd, op->band_type); -+ h2c->w1 |= le32_encode_bits(op->band_width, -+ RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW) | -+ le32_encode_bits(op->primary_channel, -+ RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH) | -+ le32_encode_bits(op->channel, -+ RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH); -+ h2c->w0 |= le32_encode_bits(op->band_type, -+ RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND); - } - - rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, - H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, - H2C_FUNC_SCANOFLD, 1, 1, -- H2C_LEN_SCAN_OFFLOAD); -+ len); - - ret = rtw89_h2c_tx(rtwdev, skb, false); - if (ret) { ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -2731,96 +2731,32 @@ static inline void RTW89_SET_FWCMD_CHINF - le32p_replace_bits((__le32 *)((u8 *)(cmd) + 16), val, GENMASK(15, 0)); - } - --static inline void RTW89_SET_FWCMD_SCANOFLD_MACID(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(7, 0)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_NORM_CY(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(15, 8)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_PORT_ID(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(18, 16)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_BAND(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, BIT(19)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_OPERATION(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(21, 20)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BAND(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd)), val, GENMASK(23, 22)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_NOTIFY_END(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, BIT(0)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_MODE(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, BIT(1)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_START_MODE(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, BIT(2)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_SCAN_TYPE(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, GENMASK(4, 3)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TARGET_CH_BW(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, GENMASK(7, 5)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TARGET_PRI_CH(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, GENMASK(15, 8)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TARGET_CENTRAL_CH(void *cmd, -- u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, GENMASK(23, 16)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_PROBE_REQ_PKT_ID(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 4), val, GENMASK(31, 24)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_NORM_PD(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 8), val, GENMASK(15, 0)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_SLOW_PD(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 8), val, GENMASK(23, 16)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TSF_HIGH(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 12), val, GENMASK(31, 0)); --} -- --static inline void RTW89_SET_FWCMD_SCANOFLD_TSF_SLOW(void *cmd, u32 val) --{ -- le32p_replace_bits((__le32 *)((u8 *)(cmd) + 16), val, GENMASK(31, 0)); --} -+struct rtw89_h2c_scanofld { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+ __le32 tsf_high; -+ __le32 tsf_low; -+ __le32 w5; -+ __le32 w6; -+} __packed; -+ -+#define RTW89_H2C_SCANOFLD_W0_MACID GENMASK(7, 0) -+#define RTW89_H2C_SCANOFLD_W0_NORM_CY GENMASK(15, 8) -+#define RTW89_H2C_SCANOFLD_W0_PORT_ID GENMASK(18, 16) -+#define RTW89_H2C_SCANOFLD_W0_BAND BIT(19) -+#define RTW89_H2C_SCANOFLD_W0_OPERATION GENMASK(21, 20) -+#define RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND GENMASK(23, 22) -+#define RTW89_H2C_SCANOFLD_W1_NOTIFY_END BIT(0) -+#define RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE BIT(1) -+#define RTW89_H2C_SCANOFLD_W1_START_MODE BIT(2) -+#define RTW89_H2C_SCANOFLD_W1_SCAN_TYPE GENMASK(4, 3) -+#define RTW89_H2C_SCANOFLD_W1_TARGET_CH_BW GENMASK(7, 5) -+#define RTW89_H2C_SCANOFLD_W1_TARGET_PRI_CH GENMASK(15, 8) -+#define RTW89_H2C_SCANOFLD_W1_TARGET_CENTRAL_CH GENMASK(23, 16) -+#define RTW89_H2C_SCANOFLD_W1_PROBE_REQ_PKT_ID GENMASK(31, 24) -+#define RTW89_H2C_SCANOFLD_W2_NORM_PD GENMASK(15, 0) -+#define RTW89_H2C_SCANOFLD_W2_SLOW_PD GENMASK(23, 16) - - static inline void RTW89_SET_FWCMD_P2P_MACID(void *cmd, u32 val) - { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-057-wifi-rtw89-update-statistics-to-FW-for-fine-tuning-p.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-057-wifi-rtw89-update-statistics-to-FW-for-fine-tuning-p.patch deleted file mode 100644 index 9c5225b16..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-057-wifi-rtw89-update-statistics-to-FW-for-fine-tuning-p.patch +++ /dev/null @@ -1,116 +0,0 @@ -From ac83f380905591beecfe5b29a9ef811e35a3aa8d Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Sat, 15 Apr 2023 11:48:58 +0800 -Subject: [PATCH 057/136] wifi: rtw89: update statistics to FW for fine-tuning - performance - -Since firmware can't have proper statistics, driver update the -statistics periodically to firmware to assist in tuning performance. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415034900.15679-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 4 ++- - drivers/net/wireless/realtek/rtw89/fw.c | 41 +++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/fw.h | 10 ++++++ - 3 files changed, 54 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2494,8 +2494,10 @@ static bool rtw89_traffic_stats_track(st - bool tfc_changed; - - tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats); -- rtw89_for_each_rtwvif(rtwdev, rtwvif) -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) { - rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats); -+ rtw89_fw_h2c_tp_offload(rtwdev, rtwvif); -+ } - - return tfc_changed; - } ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -1855,6 +1855,47 @@ fail: - return ret; - } - -+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) -+{ -+ struct rtw89_traffic_stats *stats = &rtwvif->stats; -+ struct rtw89_h2c_ofld *h2c; -+ u32 len = sizeof(*h2c); -+ struct sk_buff *skb; -+ int ret; -+ -+ if (rtwvif->net_type != RTW89_NET_TYPE_INFRA) -+ return -EINVAL; -+ -+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); -+ if (!skb) { -+ rtw89_err(rtwdev, "failed to alloc skb for h2c tp\n"); -+ return -ENOMEM; -+ } -+ -+ skb_put(skb, len); -+ h2c = (struct rtw89_h2c_ofld *)skb->data; -+ -+ h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) | -+ le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) | -+ le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP); -+ -+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, -+ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, -+ H2C_FUNC_OFLD_TP, 0, 1, len); -+ -+ ret = rtw89_h2c_tx(rtwdev, skb, false); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to send h2c\n"); -+ goto fail; -+ } -+ -+ return 0; -+fail: -+ dev_kfree_skb_any(skb); -+ -+ return ret; -+} -+ - #define H2C_RA_LEN 16 - int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) - { ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3361,6 +3361,14 @@ struct rtw89_h2c_ofld_rssi { - #define RTW89_H2C_OFLD_RSSI_W0_NUM GENMASK(15, 8) - #define RTW89_H2C_OFLD_RSSI_W1_VAL GENMASK(7, 0) - -+struct rtw89_h2c_ofld { -+ __le32 w0; -+} __packed; -+ -+#define RTW89_H2C_OFLD_W0_MAC_ID GENMASK(7, 0) -+#define RTW89_H2C_OFLD_W0_TX_TP GENMASK(17, 8) -+#define RTW89_H2C_OFLD_W0_RX_TP GENMASK(27, 18) -+ - #define RTW89_FW_HDR_SIZE 32 - #define RTW89_FW_SECTION_HDR_SIZE 16 - -@@ -3499,6 +3507,7 @@ struct rtw89_fw_h2c_rf_reg_info { - #define H2C_FUNC_PKT_DROP 0x1b - #define H2C_FUNC_CFG_BCNFLTR 0x1e - #define H2C_FUNC_OFLD_RSSI 0x1f -+#define H2C_FUNC_OFLD_TP 0x20 - - /* CLASS 10 - Security CAM */ - #define H2C_CL_MAC_SEC_CAM 0xa -@@ -3605,6 +3614,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct - bool connect); - int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev, - struct rtw89_rx_phy_ppdu *phy_ppdu); -+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); - int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); - int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev); - int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-058-wifi-rtw89-Disallow-power-save-with-multiple-station.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-058-wifi-rtw89-Disallow-power-save-with-multiple-station.patch deleted file mode 100644 index 5296f30d1..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-058-wifi-rtw89-Disallow-power-save-with-multiple-station.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 982a91642708bb55246a7b169cb573866260124c Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Sat, 15 Apr 2023 11:50:15 +0800 -Subject: [PATCH 058/136] wifi: rtw89: Disallow power save with multiple - stations - -Power saving for more than one station is not supported currently. -Disallow entering PS mode when we have more than one associated -stations. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415035016.15788-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2509,6 +2509,9 @@ static void rtw89_vif_enter_lps(struct r - rtwvif->tdls_peer) - return; - -+ if (rtwdev->total_sta_assoc > 1) -+ return; -+ - if (rtwvif->offchan) - return; - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-059-wifi-rtw89-add-support-of-concurrent-mode.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-059-wifi-rtw89-add-support-of-concurrent-mode.patch deleted file mode 100644 index 9ec366a01..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-059-wifi-rtw89-add-support-of-concurrent-mode.patch +++ /dev/null @@ -1,59 +0,0 @@ -From f22c0bffe8d9528ace89a853c6065b79dcb88c43 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Sat, 15 Apr 2023 11:50:16 +0800 -Subject: [PATCH 059/136] wifi: rtw89: add support of concurrent mode - -Add iface_combination declaration to enable concurrent mode. Only two -interfaces under same frequency is supported currently. We limit the -role combination to be STA + P2P or STA + AP only for now until new -feature is requested. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230415035016.15788-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 25 +++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -156,6 +156,28 @@ static struct ieee80211_rate rtw89_bitra - { .bitrate = 540, .hw_value = 0x0b, }, - }; - -+static const struct ieee80211_iface_limit rtw89_iface_limits[] = { -+ { -+ .max = 1, -+ .types = BIT(NL80211_IFTYPE_STATION), -+ }, -+ { -+ .max = 1, -+ .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | -+ BIT(NL80211_IFTYPE_AP), -+ }, -+}; -+ -+static const struct ieee80211_iface_combination rtw89_iface_combs[] = { -+ { -+ .limits = rtw89_iface_limits, -+ .n_limits = ARRAY_SIZE(rtw89_iface_limits), -+ .max_interfaces = 2, -+ .num_different_channels = 1, -+ } -+}; -+ - bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate) - { - struct ieee80211_rate rate; -@@ -3834,6 +3856,9 @@ struct rtw89_dev *rtw89_alloc_ieee80211_ - if (!hw) - goto err; - -+ hw->wiphy->iface_combinations = rtw89_iface_combs; -+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw89_iface_combs); -+ - rtwdev = hw->priv; - rtwdev->hw = hw; - rtwdev->dev = device; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-060-wifi-rtw89-mac-use-regular-int-as-return-type-of-DLE.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-060-wifi-rtw89-mac-use-regular-int-as-return-type-of-DLE.patch deleted file mode 100644 index c886e640f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-060-wifi-rtw89-mac-use-regular-int-as-return-type-of-DLE.patch +++ /dev/null @@ -1,121 +0,0 @@ -From eaddda248483ff78c4d26f1bf420e5f2af436a74 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 14 Apr 2023 16:22:28 +0800 -Subject: [PATCH 060/136] wifi: rtw89: mac: use regular int as return type of - DLE buffer request - -The function to request DLE (data link engine) buffer uses 'u16' as return -value that mixes error code, so change it to 'int' as regular error code. -Also, treat invalid register value (0xfff) as an error. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230414082228.30766-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 13 ++++--------- - drivers/net/wireless/realtek/rtw89/mac.c | 22 +++++++++++++--------- - drivers/net/wireless/realtek/rtw89/mac.h | 2 +- - drivers/net/wireless/realtek/rtw89/reg.h | 1 + - 4 files changed, 19 insertions(+), 19 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -3069,18 +3069,13 @@ static int rtw89_dbg_trigger_ctrl_error( - { - struct rtw89_cpuio_ctrl ctrl_para = {0}; - u16 pkt_id; -+ int ret; - - rtw89_leave_ps_mode(rtwdev); - -- pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, true); -- switch (pkt_id) { -- case 0xffff: -- return -ETIMEDOUT; -- case 0xfff: -- return -ENOMEM; -- default: -- break; -- } -+ ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, true, &pkt_id); -+ if (ret) -+ return ret; - - /* intentionally, enqueue two pkt, but has only one pkt id */ - ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -2813,7 +2813,7 @@ int rtw89_mac_resume_sch_tx_v1(struct rt - } - EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v1); - --u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd) -+int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id) - { - u32 val, reg; - int ret; -@@ -2828,9 +2828,13 @@ u16 rtw89_mac_dle_buf_req(struct rtw89_d - ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE, - 1, 2000, false, rtwdev, reg); - if (ret) -- return 0xffff; -+ return ret; -+ -+ *pkt_id = FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val); -+ if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID) -+ return -ENOENT; - -- return FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val); -+ return 0; - } - - int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, -@@ -2907,10 +2911,10 @@ static int dle_quota_change(struct rtw89 - - dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU); - -- pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, true); -- if (pkt_id == 0xffff) { -+ ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, true, &pkt_id); -+ if (ret) { - rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n"); -- return -ENOMEM; -+ return ret; - } - - ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; -@@ -2925,10 +2929,10 @@ static int dle_quota_change(struct rtw89 - return -EFAULT; - } - -- pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, false); -- if (pkt_id == 0xffff) { -+ ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, false, &pkt_id); -+ if (ret) { - rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n"); -- return -ENOMEM; -+ return ret; - } - - ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -1149,7 +1149,7 @@ enum rtw89_mac_xtal_si_offset { - int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask); - int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val); - void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); --u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); -+int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id); - int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, - struct rtw89_cpuio_ctrl *ctrl_para, bool wd); - int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -1588,6 +1588,7 @@ - #define R_AX_PL_BUF_STATUS 0x9824 - #define B_AX_WD_BUF_STAT_DONE BIT(31) - #define B_AX_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0) -+#define S_WD_BUF_STAT_PKTID_INVALID GENMASK(11, 0) - - #define R_AX_WD_CPUQ_OP_0 0x9810 - #define R_AX_PL_CPUQ_OP_0 0x9830 diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-061-wifi-rtw89-use-struct-rtw89_phy_sts_ie0-instead-of-m.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-061-wifi-rtw89-use-struct-rtw89_phy_sts_ie0-instead-of-m.patch deleted file mode 100644 index 065989eed..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-061-wifi-rtw89-use-struct-rtw89_phy_sts_ie0-instead-of-m.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 9805500606c256cf61ef73a767d7e797fe5ba18e Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 18 Apr 2023 09:28:14 +0800 -Subject: [PATCH 061/136] wifi: rtw89: use struct rtw89_phy_sts_ie0 instead of - macro to access PHY IE0 status - -To be more clear to know where it gets information from PHY IE0 data, -change to use struct and standard le32_get_bits() to access. This doesn't -change logic at all. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 15 ++++++++++----- - drivers/net/wireless/realtek/rtw89/txrx.h | 16 ++++++++++------ - 2 files changed, 20 insertions(+), 11 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1277,9 +1277,11 @@ static u16 rtw89_core_get_phy_status_ie_ - static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { -+ const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)addr; - s16 cfo; -+ u32 t; - -- phy_ppdu->chan_idx = RTW89_GET_PHY_STS_IE01_CH_IDX(addr); -+ phy_ppdu->chan_idx = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_CH_IDX); - if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) - return; - -@@ -1287,10 +1289,13 @@ static void rtw89_core_parse_phy_status_ - return; - - /* sign conversion for S(12,2) */ -- if (rtwdev->chip->cfo_src_fd) -- cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_FD_CFO(addr), 11); -- else -- cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_PREMB_CFO(addr), 11); -+ if (rtwdev->chip->cfo_src_fd) { -+ t = le32_get_bits(ie->w1, RTW89_PHY_STS_IE01_W1_FD_CFO); -+ cfo = sign_extend32(t, 11); -+ } else { -+ t = le32_get_bits(ie->w1, RTW89_PHY_STS_IE01_W1_PREMB_CFO); -+ cfo = sign_extend32(t, 11); -+ } - - rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); - } ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -298,12 +298,16 @@ - le32_get_bits(*((const __le32 *)ie), GENMASK(4, 0)) - #define RTW89_GET_PHY_STS_IE_LEN(ie) \ - le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5)) --#define RTW89_GET_PHY_STS_IE01_CH_IDX(ie) \ -- le32_get_bits(*((const __le32 *)ie), GENMASK(23, 16)) --#define RTW89_GET_PHY_STS_IE01_FD_CFO(ie) \ -- le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(19, 8)) --#define RTW89_GET_PHY_STS_IE01_PREMB_CFO(ie) \ -- le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(31, 20)) -+ -+struct rtw89_phy_sts_ie0 { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+} __packed; -+ -+#define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16) -+#define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8) -+#define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20) - - enum rtw89_tx_channel { - RTW89_TXCH_ACH0 = 0, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-062-wifi-rtw89-set-capability-of-TX-antenna-diversity.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-062-wifi-rtw89-set-capability-of-TX-antenna-diversity.patch deleted file mode 100644 index eace3291d..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-062-wifi-rtw89-set-capability-of-TX-antenna-diversity.patch +++ /dev/null @@ -1,113 +0,0 @@ -From f48453e058d763e895bde7b072f25b7b519a3500 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 18 Apr 2023 09:28:15 +0800 -Subject: [PATCH 062/136] wifi: rtw89: set capability of TX antenna diversity - -TX antenna diversity is a mechanism to select a proper antenna from two -antenna for single one hardware PHY chip. It chooses antenna with better -EVM or RSSI, and use GPIO to control SPDT to switch selected antenna. - -RFE type from efuse is used to define if a module can support TX antenna -diversity when (type % 3) is 2. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 10 ++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 2 ++ - drivers/net/wireless/realtek/rtw89/mac.c | 9 +++++++++ - drivers/net/wireless/realtek/rtw89/mac80211.c | 7 ++++++- - 4 files changed, 25 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3701,6 +3701,7 @@ static int rtw89_core_register_hw(struct - { - struct ieee80211_hw *hw = rtwdev->hw; - struct rtw89_efuse *efuse = &rtwdev->efuse; -+ struct rtw89_hal *hal = &rtwdev->hal; - int ret; - int tx_headroom = IEEE80211_HT_CTL_LEN; - -@@ -3739,8 +3740,13 @@ static int rtw89_core_register_hw(struct - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); - -- hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; -- hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; -+ if (hal->ant_diversity) { -+ hw->wiphy->available_antennas_tx = 0x3; -+ hw->wiphy->available_antennas_rx = 0x3; -+ } else { -+ hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; -+ hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; -+ } - - hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | - WIPHY_FLAG_TDLS_EXTERNAL_SETUP | ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3423,6 +3423,8 @@ struct rtw89_hal { - u8 tx_nss; - u8 rx_nss; - bool tx_path_diversity; -+ bool ant_diversity; -+ bool ant_diversity_fixed; - bool support_cckpd; - bool support_igi; - atomic_t roc_entity_idx; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -2598,6 +2598,7 @@ static int rtw89_mac_read_phycap(struct - - int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev) - { -+ struct rtw89_efuse *efuse = &rtwdev->efuse; - struct rtw89_hal *hal = &rtwdev->hal; - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_mac_c2h_info c2h_info = {0}; -@@ -2629,6 +2630,13 @@ int rtw89_mac_setup_phycap(struct rtw89_ - hal->tx_path_diversity = true; - } - -+ if (chip->rf_path_num == 1) { -+ hal->antenna_tx = RF_A; -+ hal->antenna_rx = RF_A; -+ if ((efuse->rfe_type % 3) == 2) -+ hal->ant_diversity = true; -+ } -+ - rtw89_debug(rtwdev, RTW89_DBG_FW, - "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n", - hal->tx_nss, tx_nss, chip->tx_nss, -@@ -2637,6 +2645,7 @@ int rtw89_mac_setup_phycap(struct rtw89_ - "ant num/bitmap: tx=%d/0x%x rx=%d/0x%x\n", - tx_ant, hal->antenna_tx, rx_ant, hal->antenna_rx); - rtw89_debug(rtwdev, RTW89_DBG_FW, "TX path diversity=%d\n", hal->tx_path_diversity); -+ rtw89_debug(rtwdev, RTW89_DBG_FW, "Antenna diversity=%d\n", hal->ant_diversity); - - return 0; - } ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -762,13 +762,18 @@ int rtw89_ops_set_antenna(struct ieee802 - struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_hal *hal = &rtwdev->hal; - -- if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) -+ if (hal->ant_diversity) { -+ if (tx_ant != rx_ant || hweight32(tx_ant) != 1) -+ return -EINVAL; -+ } else if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) { - return -EINVAL; -+ } - - mutex_lock(&rtwdev->mutex); - hal->antenna_tx = tx_ant; - hal->antenna_rx = rx_ant; - hal->tx_path_diversity = false; -+ hal->ant_diversity_fixed = true; - mutex_unlock(&rtwdev->mutex); - - return 0; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-063-wifi-rtw89-add-RSSI-statistics-for-the-case-of-anten.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-063-wifi-rtw89-add-RSSI-statistics-for-the-case-of-anten.patch deleted file mode 100644 index e0b1d3574..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-063-wifi-rtw89-add-RSSI-statistics-for-the-case-of-anten.patch +++ /dev/null @@ -1,92 +0,0 @@ -From f6b24241cbec5236c061f90d52acb3d9430f2d43 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 18 Apr 2023 09:28:16 +0800 -Subject: [PATCH 063/136] wifi: rtw89: add RSSI statistics for the case of - antenna diversity to debugfs - -RSSI strength is only from PHY path A, but there are two antenna for the -module which supports antenna diversity. So, set RSSI value to index 1 of -RSSI array if current antenna is on antenna B. Then, debugfs can show -two RSSI values with a asterisk mark on selected antenna. - - RSSI: -23 dBm (raw=174, prev=173) [-26, -23*] - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 20 +++++++++++++++++--- - drivers/net/wireless/realtek/rtw89/debug.c | 8 +++++--- - 2 files changed, 22 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1244,10 +1244,22 @@ static void rtw89_core_rx_process_phy_pp - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; -+ u8 ant_pos = U8_MAX; - int i; - -- if (rtwsta->mac_id == phy_ppdu->mac_id && phy_ppdu->to_self) { -- ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); -+ if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) -+ return; -+ -+ if (hal->ant_diversity && hal->antenna_rx) -+ ant_pos = __ffs(hal->antenna_rx); -+ -+ ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); -+ -+ if (ant_pos < ant_num) { -+ ewma_rssi_add(&rtwsta->rssi[ant_pos], phy_ppdu->rssi[0]); -+ } else { - for (i = 0; i < rtwdev->chip->rf_path_num; i++) - ewma_rssi_add(&rtwsta->rssi[i], phy_ppdu->rssi[i]); - } -@@ -2764,6 +2776,8 @@ int rtw89_core_sta_add(struct rtw89_dev - { - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; - int i; - int ret; - -@@ -2777,7 +2791,7 @@ int rtw89_core_sta_add(struct rtw89_dev - rtw89_core_txq_init(rtwdev, sta->txq[i]); - - ewma_rssi_init(&rtwsta->avg_rssi); -- for (i = 0; i < rtwdev->chip->rf_path_num; i++) -+ for (i = 0; i < ant_num; i++) - ewma_rssi_init(&rtwsta->rssi[i]); - - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -3206,6 +3206,8 @@ static void rtw89_sta_info_get_iter(void - struct seq_file *m = (struct seq_file *)data; - struct rtw89_dev *rtwdev = rtwsta->rtwdev; - struct rtw89_hal *hal = &rtwdev->hal; -+ u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; -+ bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; - u8 rssi; - int i; - -@@ -3256,11 +3258,11 @@ static void rtw89_sta_info_get_iter(void - rssi = ewma_rssi_read(&rtwsta->avg_rssi); - seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [", - RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi); -- for (i = 0; i < rtwdev->chip->rf_path_num; i++) { -+ for (i = 0; i < ant_num; i++) { - rssi = ewma_rssi_read(&rtwsta->rssi[i]); - seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi), -- hal->tx_path_diversity && (hal->antenna_tx & BIT(i)) ? "*" : "", -- i + 1 == rtwdev->chip->rf_path_num ? "" : ", "); -+ ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", -+ i + 1 == ant_num ? "" : ", "); - } - seq_puts(m, "]\n"); - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-064-wifi-rtw89-add-EVM-and-SNR-statistics-to-debugfs.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-064-wifi-rtw89-add-EVM-and-SNR-statistics-to-debugfs.patch deleted file mode 100644 index 667121935..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-064-wifi-rtw89-add-EVM-and-SNR-statistics-to-debugfs.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 4bb223a19f9b8c226b357ceedad47a00d88fef3a Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Tue, 18 Apr 2023 09:28:17 +0800 -Subject: [PATCH 064/136] wifi: rtw89: add EVM and SNR statistics to debugfs - -To help debug performance problem, add EVM and SNR statistics to debugfs -that shows - - EVM: [(26.75, 26.75) (25.75, 25.75)] SNR: 40 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 29 ++++++++++++++++++---- - drivers/net/wireless/realtek/rtw89/core.h | 11 ++++++++ - drivers/net/wireless/realtek/rtw89/debug.c | 16 ++++++++++++ - drivers/net/wireless/realtek/rtw89/txrx.h | 3 +++ - 4 files changed, 54 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1247,13 +1247,16 @@ static void rtw89_core_rx_process_phy_pp - struct rtw89_hal *hal = &rtwdev->hal; - u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; - u8 ant_pos = U8_MAX; -+ u8 evm_pos = 0; - int i; - - if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) - return; - -- if (hal->ant_diversity && hal->antenna_rx) -+ if (hal->ant_diversity && hal->antenna_rx) { - ant_pos = __ffs(hal->antenna_rx); -+ evm_pos = ant_pos; -+ } - - ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); - -@@ -1263,6 +1266,12 @@ static void rtw89_core_rx_process_phy_pp - for (i = 0; i < rtwdev->chip->rf_path_num; i++) - ewma_rssi_add(&rtwsta->rssi[i], phy_ppdu->rssi[i]); - } -+ -+ if (phy_ppdu->ofdm.has) { -+ ewma_snr_add(&rtwsta->avg_snr, phy_ppdu->ofdm.avg_snr); -+ ewma_evm_add(&rtwsta->evm_min[evm_pos], phy_ppdu->ofdm.evm_min); -+ ewma_evm_add(&rtwsta->evm_max[evm_pos], phy_ppdu->ofdm.evm_max); -+ } - } - - #define VAR_LEN 0xff -@@ -1300,6 +1309,11 @@ static void rtw89_core_parse_phy_status_ - if (!phy_ppdu->to_self) - return; - -+ phy_ppdu->ofdm.avg_snr = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_AVG_SNR); -+ phy_ppdu->ofdm.evm_max = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MAX); -+ phy_ppdu->ofdm.evm_min = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MIN); -+ phy_ppdu->ofdm.has = true; -+ - /* sign conversion for S(12,2) */ - if (rtwdev->chip->cfo_src_fd) { - t = le32_get_bits(ie->w1, RTW89_PHY_STS_IE01_W1_FD_CFO); -@@ -1350,9 +1364,6 @@ static int rtw89_core_rx_process_phy_ppd - return -EINVAL; - } - rtw89_core_update_phy_ppdu(phy_ppdu); -- ieee80211_iterate_stations_atomic(rtwdev->hw, -- rtw89_core_rx_process_phy_ppdu_iter, -- phy_ppdu); - - return 0; - } -@@ -1393,6 +1404,10 @@ static void rtw89_core_rx_process_phy_st - rtw89_debug(rtwdev, RTW89_DBG_TXRX, "parse phy sts failed\n"); - else - phy_ppdu->valid = true; -+ -+ ieee80211_iterate_stations_atomic(rtwdev->hw, -+ rtw89_core_rx_process_phy_ppdu_iter, -+ phy_ppdu); - } - - static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev, -@@ -2791,8 +2806,12 @@ int rtw89_core_sta_add(struct rtw89_dev - rtw89_core_txq_init(rtwdev, sta->txq[i]); - - ewma_rssi_init(&rtwsta->avg_rssi); -- for (i = 0; i < ant_num; i++) -+ ewma_snr_init(&rtwsta->avg_snr); -+ for (i = 0; i < ant_num; i++) { - ewma_rssi_init(&rtwsta->rssi[i]); -+ ewma_evm_init(&rtwsta->evm_min[i]); -+ ewma_evm_init(&rtwsta->evm_max[i]); -+ } - - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - /* for station mode, assign the mac_id from itself */ ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -551,6 +551,12 @@ struct rtw89_rx_phy_ppdu { - u8 chan_idx; - u8 ie; - u16 rate; -+ struct { -+ bool has; -+ u8 avg_snr; -+ u8 evm_max; -+ u8 evm_min; -+ } ofdm; - bool to_self; - bool valid; - }; -@@ -2533,6 +2539,8 @@ struct rtw89_ra_report { - }; - - DECLARE_EWMA(rssi, 10, 16); -+DECLARE_EWMA(evm, 10, 16); -+DECLARE_EWMA(snr, 10, 16); - - struct rtw89_ba_cam_entry { - struct list_head list; -@@ -2595,6 +2603,9 @@ struct rtw89_sta { - u8 prev_rssi; - struct ewma_rssi avg_rssi; - struct ewma_rssi rssi[RF_PATH_MAX]; -+ struct ewma_snr avg_snr; -+ struct ewma_evm evm_min[RF_PATH_MAX]; -+ struct ewma_evm evm_max[RF_PATH_MAX]; - struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; - struct ieee80211_rx_status rx_status; - u16 rx_hw_rate; ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -3208,7 +3208,9 @@ static void rtw89_sta_info_get_iter(void - struct rtw89_hal *hal = &rtwdev->hal; - u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; - bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity; -+ u8 evm_min, evm_max; - u8 rssi; -+ u8 snr; - int i; - - seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id); -@@ -3265,6 +3267,20 @@ static void rtw89_sta_info_get_iter(void - i + 1 == ant_num ? "" : ", "); - } - seq_puts(m, "]\n"); -+ -+ seq_puts(m, "EVM: ["); -+ for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) { -+ evm_min = ewma_evm_read(&rtwsta->evm_min[i]); -+ evm_max = ewma_evm_read(&rtwsta->evm_max[i]); -+ -+ seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ", -+ evm_min >> 2, (evm_min & 0x3) * 25, -+ evm_max >> 2, (evm_max & 0x3) * 25); -+ } -+ seq_puts(m, "]\t"); -+ -+ snr = ewma_snr_read(&rtwsta->avg_snr); -+ seq_printf(m, "SNR: %u\n", snr); - } - - static void ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -308,6 +308,9 @@ struct rtw89_phy_sts_ie0 { - #define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16) - #define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8) - #define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20) -+#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0) -+#define RTW89_PHY_STS_IE01_W2_EVM_MAX GENMASK(15, 8) -+#define RTW89_PHY_STS_IE01_W2_EVM_MIN GENMASK(23, 16) - - enum rtw89_tx_channel { - RTW89_TXCH_ACH0 = 0, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-065-wifi-rtw89-initialize-antenna-for-antenna-diversity.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-065-wifi-rtw89-initialize-antenna-for-antenna-diversity.patch deleted file mode 100644 index 90fb8fef3..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-065-wifi-rtw89-initialize-antenna-for-antenna-diversity.patch +++ /dev/null @@ -1,149 +0,0 @@ -From a90c613d099ff63587b60bfcfb0f4f1a7bb83252 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Tue, 18 Apr 2023 09:28:18 +0800 -Subject: [PATCH 065/136] wifi: rtw89: initialize antenna for antenna diversity - -Initialize basic antenna switch settings according to hardware module -design, and set to default antenna A. The set antenna function will be -called dynamically to switch antenna according to EVM and RSSI. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/phy.c | 69 ++++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/reg.h | 21 +++++++- - 2 files changed, 88 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2946,6 +2946,44 @@ static void rtw89_phy_ul_tb_info_init(st - rtw89_phy_read32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN); - } - -+static void rtw89_phy_antdiv_reg_init(struct rtw89_dev *rtwdev) -+{ -+ rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_ANT_TRAIN_EN, -+ 0x0, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_TX_ANT_SEL, -+ 0x0, RTW89_PHY_0); -+ -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_TRSW_TX_EXTEND, -+ 0x0, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_HW_ANTSW_DIS_BY_GNT_BT, -+ 0x0, RTW89_PHY_0); -+ -+ rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_BT_FORCE_ANTIDX_EN, -+ 0x0, RTW89_PHY_0); -+ -+ rtw89_phy_write32_idx(rtwdev, R_RFSW_CTRL_ANT0_BASE, B_RFSW_CTRL_ANT_MAPPING, -+ 0x0100, RTW89_PHY_0); -+ -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_BTG_TRX, -+ 0x1, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_HW_CTRL, -+ 0x0, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_2G, -+ 0x0, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_5G, -+ 0x0, RTW89_PHY_0); -+} -+ -+static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_hal *hal = &rtwdev->hal; -+ -+ if (!hal->ant_diversity) -+ return; -+ -+ rtw89_phy_antdiv_reg_init(rtwdev); -+} -+ - static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) - { - struct rtw89_phy_stat *phystat = &rtwdev->phystat; -@@ -4114,6 +4152,35 @@ void rtw89_phy_tx_path_div_track(struct - &done); - } - -+#define ANTDIV_MAIN 0 -+#define ANTDIV_AUX 1 -+ -+static void rtw89_phy_antdiv_set_ant(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_hal *hal = &rtwdev->hal; -+ u8 default_ant, optional_ant; -+ -+ if (!hal->ant_diversity || hal->antenna_tx == 0) -+ return; -+ -+ if (hal->antenna_tx == RF_B) { -+ default_ant = ANTDIV_AUX; -+ optional_ant = ANTDIV_MAIN; -+ } else { -+ default_ant = ANTDIV_MAIN; -+ optional_ant = ANTDIV_AUX; -+ } -+ -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_CGCS_CTRL, -+ default_ant, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ORI, -+ default_ant, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ALT, -+ optional_ant, RTW89_PHY_0); -+ rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_TX_ORI, -+ default_ant, RTW89_PHY_0); -+} -+ - static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) - { - rtw89_phy_ccx_top_setting_init(rtwdev); -@@ -4133,6 +4200,8 @@ void rtw89_phy_dm_init(struct rtw89_dev - rtw89_phy_dig_init(rtwdev); - rtw89_phy_cfo_init(rtwdev); - rtw89_phy_ul_tb_info_init(rtwdev); -+ rtw89_phy_antdiv_init(rtwdev); -+ rtw89_phy_antdiv_set_ant(rtwdev); - - rtw89_phy_init_rf_nctl(rtwdev); - rtw89_chip_rfk_init(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3852,6 +3852,9 @@ - #define B_ENABLE_CCK BIT(5) - #define R_RSTB_ASYNC 0x0704 - #define B_RSTB_ASYNC_ALL BIT(1) -+#define R_P0_ANT_SW 0x0728 -+#define B_P0_HW_ANTSW_DIS_BY_GNT_BT BIT(12) -+#define B_P0_TRSW_TX_EXTEND GENMASK(3, 0) - #define R_MAC_PIN_SEL 0x0734 - #define B_CH_IDX_SEG0 GENMASK(23, 16) - #define R_PLCP_HISTOGRAM 0x0738 -@@ -4455,10 +4458,24 @@ - #define B_P0_RFCTM_VAL GENMASK(25, 20) - #define R_P0_RFCTM_RDY BIT(26) - #define R_P0_TRSW 0x5868 --#define B_P0_TRSW_B BIT(0) --#define B_P0_TRSW_A BIT(1) -+#define B_P0_BT_FORCE_ANTIDX_EN BIT(12) - #define B_P0_TRSW_X BIT(2) -+#define B_P0_TRSW_A BIT(1) -+#define B_P0_TX_ANT_SEL BIT(1) -+#define B_P0_TRSW_B BIT(0) -+#define B_P0_ANT_TRAIN_EN BIT(0) - #define B_P0_TRSW_SO_A2 GENMASK(7, 5) -+#define R_P0_ANTSEL 0x586C -+#define B_P0_ANTSEL_SW_5G BIT(25) -+#define B_P0_ANTSEL_SW_2G BIT(23) -+#define B_P0_ANTSEL_BTG_TRX BIT(21) -+#define B_P0_ANTSEL_CGCS_CTRL BIT(17) -+#define B_P0_ANTSEL_HW_CTRL BIT(16) -+#define B_P0_ANTSEL_TX_ORI GENMASK(15, 12) -+#define B_P0_ANTSEL_RX_ALT GENMASK(11, 8) -+#define B_P0_ANTSEL_RX_ORI GENMASK(7, 4) -+#define R_RFSW_CTRL_ANT0_BASE 0x5870 -+#define B_RFSW_CTRL_ANT_MAPPING GENMASK(15, 0) - #define R_P0_RFM 0x5894 - #define B_P0_RFM_DIS_WL BIT(7) - #define B_P0_RFM_TX_OPT BIT(6) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-066-wifi-rtw89-add-RSSI-based-antenna-diversity.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-066-wifi-rtw89-add-RSSI-based-antenna-diversity.patch deleted file mode 100644 index 6811a3b39..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-066-wifi-rtw89-add-RSSI-based-antenna-diversity.patch +++ /dev/null @@ -1,345 +0,0 @@ -From e3715859c75322fae560c46384f944006f367515 Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Tue, 18 Apr 2023 09:28:19 +0800 -Subject: [PATCH 066/136] wifi: rtw89: add RSSI based antenna diversity - -RSSI statistics are grouped by CCK, OFDM or non-legacy rate. These -statistics will be collected in training state for both (main/aux) -antenna. There is a time period (ANTDIV_DELAY) for rate adaptive -settle down before start collect statistics when switch antenna. - -Antenna diversity checks packet count from training state for each -group and use the most one as the final RSSI for comparison, and -then choose the better one as target antenna. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 5 + - drivers/net/wireless/realtek/rtw89/core.h | 20 +++ - drivers/net/wireless/realtek/rtw89/phy.c | 177 ++++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/phy.h | 12 ++ - 4 files changed, 214 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1391,6 +1391,8 @@ static int rtw89_core_rx_parse_phy_sts(s - } - } - -+ rtw89_phy_antdiv_parse(rtwdev, phy_ppdu); -+ - return 0; - } - -@@ -2628,6 +2630,7 @@ static void rtw89_track_work(struct work - rtw89_phy_ra_update(rtwdev); - rtw89_phy_cfo_track(rtwdev); - rtw89_phy_tx_path_div_track(rtwdev); -+ rtw89_phy_antdiv_track(rtwdev); - rtw89_phy_ul_tb_ctrl_track(rtwdev); - - if (rtwdev->lps_enabled && !rtwdev->btc.lps) -@@ -3482,6 +3485,7 @@ void rtw89_core_stop(struct rtw89_dev *r - cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work); - cancel_delayed_work_sync(&rtwdev->cfo_track_work); - cancel_delayed_work_sync(&rtwdev->forbid_ba_work); -+ cancel_delayed_work_sync(&rtwdev->antdiv_work); - - mutex_lock(&rtwdev->mutex); - -@@ -3517,6 +3521,7 @@ int rtw89_core_init(struct rtw89_dev *rt - INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); - INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); - INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work); -+ INIT_DELAYED_WORK(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); - rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); - if (!rtwdev->txq_wq) - return -ENOMEM; ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3127,6 +3127,24 @@ struct rtw89_phy_ul_tb_info { - u8 def_if_bandedge; - }; - -+struct rtw89_antdiv_stats { -+ struct ewma_rssi cck_rssi_avg; -+ struct ewma_rssi ofdm_rssi_avg; -+ struct ewma_rssi non_legacy_rssi_avg; -+ u16 pkt_cnt_cck; -+ u16 pkt_cnt_ofdm; -+ u16 pkt_cnt_non_legacy; -+}; -+ -+struct rtw89_antdiv_info { -+ struct rtw89_antdiv_stats target_stats; -+ struct rtw89_antdiv_stats main_stats; -+ struct rtw89_antdiv_stats aux_stats; -+ u8 training_count; -+ u8 rssi_pre; -+ bool get_stats; -+}; -+ - struct rtw89_chip_info { - enum rtw89_core_chip_id chip_id; - const struct rtw89_chip_ops *ops; -@@ -4099,6 +4117,7 @@ struct rtw89_dev { - struct rtw89_phy_bb_gain_info bb_gain; - struct rtw89_phy_efuse_gain efuse_gain; - struct rtw89_phy_ul_tb_info ul_tb_info; -+ struct rtw89_antdiv_info antdiv; - - struct delayed_work track_work; - struct delayed_work coex_act1_work; -@@ -4107,6 +4126,7 @@ struct rtw89_dev { - struct delayed_work cfo_track_work; - struct delayed_work forbid_ba_work; - struct delayed_work roc_work; -+ struct delayed_work antdiv_work; - struct rtw89_ppdu_sts_info ppdu_sts; - u8 total_sta_assoc; - bool scanning; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -10,6 +10,7 @@ - #include "ps.h" - #include "reg.h" - #include "sar.h" -+#include "txrx.h" - #include "util.h" - - static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, -@@ -2946,6 +2947,67 @@ static void rtw89_phy_ul_tb_info_init(st - rtw89_phy_read32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN); - } - -+static -+void rtw89_phy_antdiv_sts_instance_reset(struct rtw89_antdiv_stats *antdiv_sts) -+{ -+ ewma_rssi_init(&antdiv_sts->cck_rssi_avg); -+ ewma_rssi_init(&antdiv_sts->ofdm_rssi_avg); -+ ewma_rssi_init(&antdiv_sts->non_legacy_rssi_avg); -+ antdiv_sts->pkt_cnt_cck = 0; -+ antdiv_sts->pkt_cnt_ofdm = 0; -+ antdiv_sts->pkt_cnt_non_legacy = 0; -+} -+ -+static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu, -+ struct rtw89_antdiv_stats *stats) -+{ -+ if (GET_DATA_RATE_MODE(phy_ppdu->rate) == DATA_RATE_MODE_NON_HT) { -+ if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) { -+ ewma_rssi_add(&stats->cck_rssi_avg, phy_ppdu->rssi_avg); -+ stats->pkt_cnt_cck++; -+ } else { -+ ewma_rssi_add(&stats->ofdm_rssi_avg, phy_ppdu->rssi_avg); -+ stats->pkt_cnt_ofdm++; -+ } -+ } else { -+ ewma_rssi_add(&stats->non_legacy_rssi_avg, phy_ppdu->rssi_avg); -+ stats->pkt_cnt_non_legacy++; -+ } -+} -+ -+static u8 rtw89_phy_antdiv_sts_instance_get_rssi(struct rtw89_antdiv_stats *stats) -+{ -+ if (stats->pkt_cnt_non_legacy >= stats->pkt_cnt_cck && -+ stats->pkt_cnt_non_legacy >= stats->pkt_cnt_ofdm) -+ return ewma_rssi_read(&stats->non_legacy_rssi_avg); -+ else if (stats->pkt_cnt_ofdm >= stats->pkt_cnt_cck && -+ stats->pkt_cnt_ofdm >= stats->pkt_cnt_non_legacy) -+ return ewma_rssi_read(&stats->ofdm_rssi_avg); -+ else -+ return ewma_rssi_read(&stats->cck_rssi_avg); -+} -+ -+void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu) -+{ -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ -+ if (!hal->ant_diversity || hal->ant_diversity_fixed) -+ return; -+ -+ rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->target_stats); -+ -+ if (!antdiv->get_stats) -+ return; -+ -+ if (hal->antenna_rx == RF_A) -+ rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->main_stats); -+ else if (hal->antenna_rx == RF_B) -+ rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->aux_stats); -+} -+ - static void rtw89_phy_antdiv_reg_init(struct rtw89_dev *rtwdev) - { - rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_ANT_TRAIN_EN, -@@ -2974,13 +3036,26 @@ static void rtw89_phy_antdiv_reg_init(st - 0x0, RTW89_PHY_0); - } - -+static void rtw89_phy_antdiv_sts_reset(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ -+ rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats); -+ rtw89_phy_antdiv_sts_instance_reset(&antdiv->main_stats); -+ rtw89_phy_antdiv_sts_instance_reset(&antdiv->aux_stats); -+} -+ - static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev) - { -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; - struct rtw89_hal *hal = &rtwdev->hal; - - if (!hal->ant_diversity) - return; - -+ antdiv->get_stats = false; -+ antdiv->rssi_pre = 0; -+ rtw89_phy_antdiv_sts_reset(rtwdev); - rtw89_phy_antdiv_reg_init(rtwdev); - } - -@@ -4181,6 +4256,108 @@ static void rtw89_phy_antdiv_set_ant(str - default_ant, RTW89_PHY_0); - } - -+static void rtw89_phy_swap_hal_antenna(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_hal *hal = &rtwdev->hal; -+ -+ hal->antenna_rx = hal->antenna_rx == RF_A ? RF_B : RF_A; -+ hal->antenna_tx = hal->antenna_rx; -+} -+ -+static void rtw89_phy_antdiv_decision_state(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ bool no_change = false; -+ u8 main_rssi, aux_rssi; -+ u32 candidate; -+ -+ antdiv->get_stats = false; -+ antdiv->training_count = 0; -+ -+ main_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->main_stats); -+ aux_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->aux_stats); -+ -+ if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH) -+ candidate = RF_A; -+ else if (aux_rssi > main_rssi + RTW89_TX_DIV_RSSI_RAW_TH) -+ candidate = RF_B; -+ else -+ no_change = true; -+ -+ if (no_change) { -+ /* swap back from training antenna to original */ -+ rtw89_phy_swap_hal_antenna(rtwdev); -+ return; -+ } -+ -+ hal->antenna_tx = candidate; -+ hal->antenna_rx = candidate; -+} -+ -+static void rtw89_phy_antdiv_training_state(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ u64 state_period; -+ -+ if (antdiv->training_count % 2 == 0) { -+ if (antdiv->training_count == 0) -+ rtw89_phy_antdiv_sts_reset(rtwdev); -+ -+ antdiv->get_stats = true; -+ state_period = msecs_to_jiffies(ANTDIV_TRAINNING_INTVL); -+ } else { -+ antdiv->get_stats = false; -+ state_period = msecs_to_jiffies(ANTDIV_DELAY); -+ -+ rtw89_phy_swap_hal_antenna(rtwdev); -+ rtw89_phy_antdiv_set_ant(rtwdev); -+ } -+ -+ antdiv->training_count++; -+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work, -+ state_period); -+} -+ -+void rtw89_phy_antdiv_work(struct work_struct *work) -+{ -+ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, -+ antdiv_work.work); -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ -+ mutex_lock(&rtwdev->mutex); -+ -+ if (antdiv->training_count <= ANTDIV_TRAINNING_CNT) { -+ rtw89_phy_antdiv_training_state(rtwdev); -+ } else { -+ rtw89_phy_antdiv_decision_state(rtwdev); -+ rtw89_phy_antdiv_set_ant(rtwdev); -+ } -+ -+ mutex_unlock(&rtwdev->mutex); -+} -+ -+void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv; -+ struct rtw89_hal *hal = &rtwdev->hal; -+ u8 rssi, rssi_pre; -+ -+ if (!hal->ant_diversity || hal->ant_diversity_fixed) -+ return; -+ -+ rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->target_stats); -+ rssi_pre = antdiv->rssi_pre; -+ antdiv->rssi_pre = rssi; -+ rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats); -+ -+ if (abs((int)rssi - (int)rssi_pre) < ANTDIV_RSSI_DIFF_TH) -+ return; -+ -+ antdiv->training_count = 0; -+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work, 0); -+} -+ - static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) - { - rtw89_phy_ccx_top_setting_init(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/phy.h -+++ b/drivers/net/wireless/realtek/rtw89/phy.h -@@ -67,6 +67,14 @@ - #define UL_TB_TF_CNT_L2H_TH 100 - #define UL_TB_TF_CNT_H2L_TH 70 - -+#define ANTDIV_TRAINNING_CNT 2 -+#define ANTDIV_TRAINNING_INTVL 30 -+#define ANTDIV_DELAY 110 -+#define ANTDIV_TP_DIFF_TH_HIGH 100 -+#define ANTDIV_TP_DIFF_TH_LOW 5 -+#define ANTDIV_EVM_DIFF_TH 8 -+#define ANTDIV_RSSI_DIFF_TH 3 -+ - #define CCX_MAX_PERIOD 2097 - #define CCX_MAX_PERIOD_UNIT 32 - #define MS_TO_4US_RATIO 250 -@@ -549,6 +557,10 @@ void rtw89_phy_set_phy_regs(struct rtw89 - void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev); - void rtw89_phy_dig(struct rtw89_dev *rtwdev); - void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev); -+void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu); -+void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev); -+void rtw89_phy_antdiv_work(struct work_struct *work); - void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); - void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev, - enum rtw89_mac_idx mac_idx, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-067-wifi-rtw89-add-EVM-for-antenna-diversity.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-067-wifi-rtw89-add-EVM-for-antenna-diversity.patch deleted file mode 100644 index 0ef9c81b8..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-067-wifi-rtw89-add-EVM-for-antenna-diversity.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 5feecb40e735b7cb4173328fabfc49ddc2b3b1bc Mon Sep 17 00:00:00 2001 -From: Eric Huang -Date: Tue, 18 Apr 2023 09:28:20 +0800 -Subject: [PATCH 067/136] wifi: rtw89: add EVM for antenna diversity - -Take EVM into consideration when doing antenna diversity, and the priority -is higher than RSSI. Since EVM is more relevant to performance than RSSI, -especially in OTA environment. - -Signed-off-by: Eric Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230418012820.5139-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/phy.c | 17 ++++++++++++++++- - 2 files changed, 17 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3134,6 +3134,7 @@ struct rtw89_antdiv_stats { - u16 pkt_cnt_cck; - u16 pkt_cnt_ofdm; - u16 pkt_cnt_non_legacy; -+ u32 evm; - }; - - struct rtw89_antdiv_info { ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2956,6 +2956,7 @@ void rtw89_phy_antdiv_sts_instance_reset - antdiv_sts->pkt_cnt_cck = 0; - antdiv_sts->pkt_cnt_ofdm = 0; - antdiv_sts->pkt_cnt_non_legacy = 0; -+ antdiv_sts->evm = 0; - } - - static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev, -@@ -2969,10 +2970,12 @@ static void rtw89_phy_antdiv_sts_instanc - } else { - ewma_rssi_add(&stats->ofdm_rssi_avg, phy_ppdu->rssi_avg); - stats->pkt_cnt_ofdm++; -+ stats->evm += phy_ppdu->ofdm.evm_min; - } - } else { - ewma_rssi_add(&stats->non_legacy_rssi_avg, phy_ppdu->rssi_avg); - stats->pkt_cnt_non_legacy++; -+ stats->evm += phy_ppdu->ofdm.evm_min; - } - } - -@@ -2988,6 +2991,11 @@ static u8 rtw89_phy_antdiv_sts_instance_ - return ewma_rssi_read(&stats->cck_rssi_avg); - } - -+static u8 rtw89_phy_antdiv_sts_instance_get_evm(struct rtw89_antdiv_stats *stats) -+{ -+ return phy_div(stats->evm, stats->pkt_cnt_non_legacy + stats->pkt_cnt_ofdm); -+} -+ - void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { -@@ -4270,15 +4278,22 @@ static void rtw89_phy_antdiv_decision_st - struct rtw89_hal *hal = &rtwdev->hal; - bool no_change = false; - u8 main_rssi, aux_rssi; -+ u8 main_evm, aux_evm; - u32 candidate; - - antdiv->get_stats = false; - antdiv->training_count = 0; - - main_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->main_stats); -+ main_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->main_stats); - aux_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->aux_stats); -+ aux_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->aux_stats); - -- if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH) -+ if (main_evm > aux_evm + ANTDIV_EVM_DIFF_TH) -+ candidate = RF_A; -+ else if (aux_evm > main_evm + ANTDIV_EVM_DIFF_TH) -+ candidate = RF_B; -+ else if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH) - candidate = RF_A; - else if (aux_rssi > main_rssi + RTW89_TX_DIV_RSSI_RAW_TH) - candidate = RF_B; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-068-wifi-rtw89-release-bit-in-rtw89_fw_h2c_del_pkt_offlo.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-068-wifi-rtw89-release-bit-in-rtw89_fw_h2c_del_pkt_offlo.patch deleted file mode 100644 index 1304d0749..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-068-wifi-rtw89-release-bit-in-rtw89_fw_h2c_del_pkt_offlo.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 25a7e5072ef1901e671e6f39df40b5028b241804 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 19 Apr 2023 11:45:51 +0000 -Subject: [PATCH 068/136] wifi: rtw89: release bit in - rtw89_fw_h2c_del_pkt_offload() - -We have a pair of FW functions, rtw89_fw_h2c_add_pkt_offload() and -rtw89_fw_h2c_del_pkt_offload(). The rtw89_fw_h2c_add_pkt_offload() -acquires the bit itself, but the bit needs to be released by the -caller of rtw89_fw_h2c_del_pkt_offload(). This looks asymmetrical -and is not friendly to callers. - -Second, if callers always releases the bits, it might make driver -unaligned to bitmap status of FW after some failures of calling -rtw89_fw_h2c_del_pkt_offload(). So, this commit move bit release -into rtw89_fw_h2c_del_pkt_offload(). - -In general, driver will call rtw89_fw_h2c_add_pkt_offload() and -rtw89_fw_h2c_del_pkt_offload(), and then, SW bitmap can align -with FW one. There is one exception when notify_fw is false. -It happens when driver detects FW problems and is going to -reset FW. Only in this case, driver needs to release bits -outside rtw89_fw_h2c_del_pkt_offload(). - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/8cf5d45c5b04e7b680d4eb9dda62056cdce14cec.camel@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -997,8 +997,8 @@ void rtw89_fw_release_general_pkt_list_v - list_for_each_entry_safe(info, tmp, pkt_list, list) { - if (notify_fw) - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -- rtw89_core_release_bit_map(rtwdev->pkt_offload, -- info->id); -+ else -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); - list_del(&info->list); - kfree(info); - } -@@ -2466,6 +2466,7 @@ int rtw89_fw_h2c_del_pkt_offload(struct - goto fail; - } - -+ rtw89_core_release_bit_map(rtwdev->pkt_offload, id); - return 0; - fail: - dev_kfree_skb_any(skb); -@@ -3020,8 +3021,6 @@ static void rtw89_release_pkt_list(struc - - list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -- rtw89_core_release_bit_map(rtwdev->pkt_offload, -- info->id); - list_del(&info->list); - kfree(info); - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-069-wifi-rtw89-refine-packet-offload-delete-flow-of-6-GH.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-069-wifi-rtw89-refine-packet-offload-delete-flow-of-6-GH.patch deleted file mode 100644 index f70498a72..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-069-wifi-rtw89-refine-packet-offload-delete-flow-of-6-GH.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 3ea1cd8d027f189c044de142d58c4b0162396db3 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 19 Apr 2023 11:45:55 +0000 -Subject: [PATCH 069/136] wifi: rtw89: refine packet offload delete flow of 6 - GHz probe - -There are two places where offload packets of 6 GHz probe would be deleted -from FW, i.e. calling rtw89_fw_h2c_del_pkt_offload(). -* rtw89_core_cancel_6ghz_probe_tx() -* rtw89_release_pkt_list() -It is possible that we try to delete the same one from FW twice. Although -it might not be a big problem for now, it will depend on the runtime chip -firmware. So, we add a check to avoid it. In case things becomes complex -due to racing problem, we don't choose to do list_del(info->list) and -kfree(info) in both sides. - -Besides, rtw89_fw_h2c_del_pkt_offload() will needs to wait for completion -after the follow-up commit. However, rtw89_core_cancel_6ghz_probe_tx() -was called in interrupt context. So, we move the stuffs of calling -rtw89_fw_h2c_del_pkt_offload() from rtw89_core_cancel_6ghz_probe_tx() -into a work. Then, we also need a check there before we call it. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/091966e5709cd7caecf9b81f7fd6388ae2b70a7e.camel@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 43 +++++++++++++++++++++-- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/fw.c | 3 +- - drivers/net/wireless/realtek/rtw89/fw.h | 1 + - 4 files changed, 44 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1515,6 +1515,34 @@ static void rtw89_stats_trigger_frame(st - } - } - -+static void rtw89_cancel_6ghz_probe_work(struct work_struct *work) -+{ -+ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, -+ cancel_6ghz_probe_work); -+ struct list_head *pkt_list = rtwdev->scan_info.pkt_list; -+ struct rtw89_pktofld_info *info; -+ -+ mutex_lock(&rtwdev->mutex); -+ -+ if (!rtwdev->scanning) -+ goto out; -+ -+ list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { -+ if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload)) -+ continue; -+ -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ -+ /* Don't delete/free info from pkt_list at this moment. Let it -+ * be deleted/freed in rtw89_release_pkt_list() after scanning, -+ * since if during scanning, pkt_list is accessed in bottom half. -+ */ -+ } -+ -+out: -+ mutex_unlock(&rtwdev->mutex); -+} -+ - static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, - struct sk_buff *skb) - { -@@ -1523,6 +1551,7 @@ static void rtw89_core_cancel_6ghz_probe - struct list_head *pkt_list = rtwdev->scan_info.pkt_list; - struct rtw89_pktofld_info *info; - const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; -+ bool queue_work = false; - - if (rx_status->band != NL80211_BAND_6GHZ) - return; -@@ -1531,16 +1560,22 @@ static void rtw89_core_cancel_6ghz_probe - - list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { - if (ether_addr_equal(info->bssid, mgmt->bssid)) { -- rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ info->cancel = true; -+ queue_work = true; - continue; - } - - if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) - continue; - -- if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) -- rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) { -+ info->cancel = true; -+ queue_work = true; -+ } - } -+ -+ if (queue_work) -+ ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work); - } - - static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, -@@ -3474,6 +3509,7 @@ void rtw89_core_stop(struct rtw89_dev *r - mutex_unlock(&rtwdev->mutex); - - cancel_work_sync(&rtwdev->c2h_work); -+ cancel_work_sync(&rtwdev->cancel_6ghz_probe_work); - cancel_work_sync(&btc->eapol_notify_work); - cancel_work_sync(&btc->arp_notify_work); - cancel_work_sync(&btc->dhcp_notify_work); -@@ -3536,6 +3572,7 @@ int rtw89_core_init(struct rtw89_dev *rt - INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); - INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); - INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); -+ INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); - - skb_queue_head_init(&rtwdev->c2h_queue); - rtw89_core_ppdu_sts_init(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -4086,6 +4086,7 @@ struct rtw89_dev { - struct work_struct c2h_work; - struct work_struct ips_work; - struct work_struct load_firmware_work; -+ struct work_struct cancel_6ghz_probe_work; - - struct list_head early_h2c_list; - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -3020,7 +3020,8 @@ static void rtw89_release_pkt_list(struc - continue; - - list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { -- rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); -+ if (test_bit(info->id, rtwdev->pkt_offload)) -+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); - list_del(&info->list); - kfree(info); - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -277,6 +277,7 @@ struct rtw89_pktofld_info { - u8 ssid_len; - u8 bssid[ETH_ALEN]; - u16 channel_6ghz; -+ bool cancel; - }; - - static inline void RTW89_SET_FWCMD_RA_IS_DIS(void *cmd, u32 val) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-070-wifi-rtw89-packet-offload-wait-for-FW-response.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-070-wifi-rtw89-packet-offload-wait-for-FW-response.patch deleted file mode 100644 index b344cc544..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-070-wifi-rtw89-packet-offload-wait-for-FW-response.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 8febd68be526c9f256c5490dd4b094a70e1b91ba Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 19 Apr 2023 11:45:58 +0000 -Subject: [PATCH 070/136] wifi: rtw89: packet offload wait for FW response - -The H2Cs (host to chip packets) related to packet offload functions -need to wait for FW responses in case FW state machine gets wrong -and makes driver status no longer able to align FW one. In flow, -driver may continuously send multiple H2Cs of packet offload series. -If somehow FW doesn't deal with the former yet but the latter has -gotten in, it might cause the problem mentioned above. - -So, we block these H2Cs by rtw89_wait_for_cond(). And then, when -the corresponding C2Hs (chip to host packets) is received, we call -rtw89_complete_cond(). Besides, RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP's -C2H handler should be executed in interrupt context to make our -wait/complete process work as expected. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/9ae8c1f105901c65e3171276a9fd6c99ae51803f.camel@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 1 + - drivers/net/wireless/realtek/rtw89/core.h | 19 +++++---- - drivers/net/wireless/realtek/rtw89/fw.c | 34 +++++++++------- - drivers/net/wireless/realtek/rtw89/fw.h | 48 +++++++++++++++++------ - drivers/net/wireless/realtek/rtw89/mac.c | 22 ++++++++++- - 5 files changed, 90 insertions(+), 34 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3568,6 +3568,7 @@ int rtw89_core_init(struct rtw89_dev *rt - rtwdev->total_sta_assoc = 0; - - rtw89_init_wait(&rtwdev->mcc.wait); -+ rtw89_init_wait(&rtwdev->mac.fw_ofld_wait); - - INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); - INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3278,14 +3278,6 @@ enum rtw89_host_rpr_mode { - RTW89_RPR_MODE_STF - }; - --struct rtw89_mac_info { -- struct rtw89_dle_info dle_info; -- struct rtw89_hfc_param hfc_param; -- enum rtw89_qta_mode qta_mode; -- u8 rpwm_seq_num; -- u8 cpwm_seq_num; --}; -- - #define RTW89_COMPLETION_BUF_SIZE 24 - #define RTW89_WAIT_COND_IDLE UINT_MAX - -@@ -3308,6 +3300,17 @@ static inline void rtw89_init_wait(struc - atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); - } - -+struct rtw89_mac_info { -+ struct rtw89_dle_info dle_info; -+ struct rtw89_hfc_param hfc_param; -+ enum rtw89_qta_mode qta_mode; -+ u8 rpwm_seq_num; -+ u8 cpwm_seq_num; -+ -+ /* see RTW89_FW_OFLD_WAIT_COND series for wait condition */ -+ struct rtw89_wait_info fw_ofld_wait; -+}; -+ - enum rtw89_fw_type { - RTW89_FW_NORMAL = 1, - RTW89_FW_WOWLAN = 3, ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -14,6 +14,8 @@ - - static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, - struct sk_buff *skb); -+static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, -+ struct rtw89_wait_info *wait, unsigned int cond); - - static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, - bool header) -@@ -2440,7 +2442,9 @@ fail: - #define H2C_LEN_PKT_OFLD 4 - int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) - { -+ struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct sk_buff *skb; -+ unsigned int cond; - u8 *cmd; - int ret; - -@@ -2460,24 +2464,26 @@ int rtw89_fw_h2c_del_pkt_offload(struct - H2C_FUNC_PACKET_OFLD, 1, 1, - H2C_LEN_PKT_OFLD); - -- ret = rtw89_h2c_tx(rtwdev, skb, false); -+ cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); -+ -+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); - if (ret) { -- rtw89_err(rtwdev, "failed to send h2c\n"); -- goto fail; -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "failed to del pkt ofld: id %d, ret %d\n", -+ id, ret); -+ return ret; - } - - rtw89_core_release_bit_map(rtwdev->pkt_offload, id); - return 0; --fail: -- dev_kfree_skb_any(skb); -- -- return ret; - } - - int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, - struct sk_buff *skb_ofld) - { -+ struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct sk_buff *skb; -+ unsigned int cond; - u8 *cmd; - u8 alloc_id; - int ret; -@@ -2508,18 +2514,18 @@ int rtw89_fw_h2c_add_pkt_offload(struct - H2C_FUNC_PACKET_OFLD, 1, 1, - H2C_LEN_PKT_OFLD + skb_ofld->len); - -- ret = rtw89_h2c_tx(rtwdev, skb, false); -+ cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); -+ -+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); - if (ret) { -- rtw89_err(rtwdev, "failed to send h2c\n"); -+ rtw89_debug(rtwdev, RTW89_DBG_FW, -+ "failed to add pkt ofld: id %d, ret %d\n", -+ alloc_id, ret); - rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); -- goto fail; -+ return ret; - } - - return 0; --fail: -- dev_kfree_skb_any(skb); -- -- return ret; - } - - #define H2C_LEN_SCAN_LIST_OFFLOAD 4 ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -138,8 +138,13 @@ enum rtw89_pkt_offload_op { - RTW89_PKT_OFLD_OP_ADD, - RTW89_PKT_OFLD_OP_DEL, - RTW89_PKT_OFLD_OP_READ, -+ -+ NUM_OF_RTW89_PKT_OFFLOAD_OP, - }; - -+#define RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op) \ -+ ((pkt_id) * NUM_OF_RTW89_PKT_OFFLOAD_OP + (pkt_op)) -+ - enum rtw89_scanofld_notify_reason { - RTW89_SCAN_DWELL_NOTIFY, - RTW89_SCAN_PRE_TX_NOTIFY, -@@ -3340,6 +3345,16 @@ static_assert(sizeof(struct rtw89_mac_mc - #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) - -+struct rtw89_c2h_pkt_ofld_rsp { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+} __packed; -+ -+#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID GENMASK(7, 0) -+#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8) -+#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16) -+ - struct rtw89_h2c_bcnfltr { - __le32 w0; - } __packed; -@@ -3498,17 +3513,28 @@ struct rtw89_fw_h2c_rf_reg_info { - - /* CLASS 9 - FW offload */ - #define H2C_CL_MAC_FW_OFLD 0x9 --#define H2C_FUNC_PACKET_OFLD 0x1 --#define H2C_FUNC_MAC_MACID_PAUSE 0x8 --#define H2C_FUNC_USR_EDCA 0xF --#define H2C_FUNC_TSF32_TOGL 0x10 --#define H2C_FUNC_OFLD_CFG 0x14 --#define H2C_FUNC_ADD_SCANOFLD_CH 0x16 --#define H2C_FUNC_SCANOFLD 0x17 --#define H2C_FUNC_PKT_DROP 0x1b --#define H2C_FUNC_CFG_BCNFLTR 0x1e --#define H2C_FUNC_OFLD_RSSI 0x1f --#define H2C_FUNC_OFLD_TP 0x20 -+enum rtw89_fw_ofld_h2c_func { -+ H2C_FUNC_PACKET_OFLD = 0x1, -+ H2C_FUNC_MAC_MACID_PAUSE = 0x8, -+ H2C_FUNC_USR_EDCA = 0xF, -+ H2C_FUNC_TSF32_TOGL = 0x10, -+ H2C_FUNC_OFLD_CFG = 0x14, -+ H2C_FUNC_ADD_SCANOFLD_CH = 0x16, -+ H2C_FUNC_SCANOFLD = 0x17, -+ H2C_FUNC_PKT_DROP = 0x1b, -+ H2C_FUNC_CFG_BCNFLTR = 0x1e, -+ H2C_FUNC_OFLD_RSSI = 0x1f, -+ H2C_FUNC_OFLD_TP = 0x20, -+ -+ NUM_OF_RTW89_FW_OFLD_H2C_FUNC, -+}; -+ -+#define RTW89_FW_OFLD_WAIT_COND(tag, func) \ -+ ((tag) * NUM_OF_RTW89_FW_OFLD_H2C_FUNC + (func)) -+ -+#define RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op) \ -+ RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \ -+ H2C_FUNC_PACKET_OFLD) - - /* CLASS 10 - Security CAM */ - #define H2C_CL_MAC_SEC_CAM 0xa ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4369,9 +4369,22 @@ rtw89_mac_c2h_bcn_cnt(struct rtw89_dev * - } - - static void --rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, -+rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, - u32 len) - { -+ struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; -+ const struct rtw89_c2h_pkt_ofld_rsp *c2h = -+ (const struct rtw89_c2h_pkt_ofld_rsp *)skb_c2h->data; -+ u16 pkt_len = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN); -+ u8 pkt_id = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID); -+ u8 pkt_op = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP); -+ struct rtw89_completion_data data = {}; -+ unsigned int cond; -+ -+ data.err = !pkt_len; -+ cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op); -+ -+ rtw89_complete_cond(wait, cond, &data); - } - - static void -@@ -4579,6 +4592,13 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw - switch (class) { - default: - return false; -+ case RTW89_MAC_C2H_CLASS_OFLD: -+ switch (func) { -+ default: -+ return false; -+ case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP: -+ return true; -+ } - case RTW89_MAC_C2H_CLASS_MCC: - return true; - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-071-wifi-rtw89-mac-handle-C2H-receive-done-ACK-in-interr.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-071-wifi-rtw89-mac-handle-C2H-receive-done-ACK-in-interr.patch deleted file mode 100644 index 36a6939c7..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-071-wifi-rtw89-mac-handle-C2H-receive-done-ACK-in-interr.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 32bb12eb73dceeb78c04a46c333f6f319cf1cebd Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 19 Apr 2023 11:46:01 +0000 -Subject: [PATCH 071/136] wifi: rtw89: mac: handle C2H receive/done ACK in - interrupt context - -We have some MAC H2Cs (host to chip packets), which have no clear -individual C2Hs (chip to host packets) to indicate FW execution -response, but they are going to require to wait for FW completion. -So, we have to deal with this via common MAC C2H receive/done ACKs. - -This commit changes the context, where common MAC C2H receive/done -ACK handlers are executed, to interrupt context. And, code comments -are added to prevent future commits from using it incorrectly. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/c4d766885e00b9f9dcf7954a80096c8b9d21149b.camel@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4336,6 +4336,8 @@ rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_ - static void - rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) - { -+ /* N.B. This will run in interrupt context. */ -+ - rtw89_debug(rtwdev, RTW89_DBG_FW, - "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n", - RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data), -@@ -4347,6 +4349,8 @@ rtw89_mac_c2h_rec_ack(struct rtw89_dev * - static void - rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) - { -+ /* N.B. This will run in interrupt context. */ -+ - rtw89_debug(rtwdev, RTW89_DBG_FW, - "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", - RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), -@@ -4592,6 +4596,14 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw - switch (class) { - default: - return false; -+ case RTW89_MAC_C2H_CLASS_INFO: -+ switch (func) { -+ default: -+ return false; -+ case RTW89_MAC_C2H_FUNC_REC_ACK: -+ case RTW89_MAC_C2H_FUNC_DONE_ACK: -+ return true; -+ } - case RTW89_MAC_C2H_CLASS_OFLD: - switch (func) { - default: diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-072-wifi-rtw89-scan-offload-wait-for-FW-done-ACK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-072-wifi-rtw89-scan-offload-wait-for-FW-done-ACK.patch deleted file mode 100644 index 8c4cd34c7..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-072-wifi-rtw89-scan-offload-wait-for-FW-done-ACK.patch +++ /dev/null @@ -1,182 +0,0 @@ -From b9b632f43f1c8b59ea3d23f7ea941616322dab5a Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 19 Apr 2023 11:46:03 +0000 -Subject: [PATCH 072/136] wifi: rtw89: scan offload wait for FW done ACK - -The following are scan offload related H2C (host to chip) function types. -* H2C_FUNC_ADD_SCANOFLD_CH -* H2C_FUNC_SCANOFLD -Before doing FW scan, we will continuously send multiple H2Cs with above -types which are used to tell FW the scan configuration of this time. But, -if FW doesn't handle one of these H2Cs well, the FW scan process might -not run as expected and driver should notice it early. - -So, this commits makes scan offload related H2Cs wait for FW done ACK via -rtw89_wait_for_cond() and rtw89_complete_cond(). And, we check the return -code of these H2Cs from FW. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/a15f4bd594f71d7602ea67698b035805143700c9.camel@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 28 ++++++++--------- - drivers/net/wireless/realtek/rtw89/fw.h | 21 +++++++------ - drivers/net/wireless/realtek/rtw89/mac.c | 39 ++++++++++++++++++++---- - 3 files changed, 58 insertions(+), 30 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2532,9 +2532,11 @@ int rtw89_fw_h2c_add_pkt_offload(struct - int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, - struct list_head *chan_list) - { -+ struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct rtw89_mac_chinfo *ch_info; - struct sk_buff *skb; - int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE; -+ unsigned int cond; - u8 *cmd; - int ret; - -@@ -2581,27 +2583,27 @@ int rtw89_fw_h2c_scan_list_offload(struc - H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, - H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); - -- ret = rtw89_h2c_tx(rtwdev, skb, false); -+ cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH); -+ -+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); - if (ret) { -- rtw89_err(rtwdev, "failed to send h2c\n"); -- goto fail; -+ rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); -+ return ret; - } - - return 0; --fail: -- dev_kfree_skb_any(skb); -- -- return ret; - } - - int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, - struct rtw89_scan_option *option, - struct rtw89_vif *rtwvif) - { -+ struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; - struct rtw89_chan *op = &rtwdev->scan_info.op_chan; - struct rtw89_h2c_scanofld *h2c; - u32 len = sizeof(*h2c); - struct sk_buff *skb; -+ unsigned int cond; - int ret; - - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); -@@ -2640,17 +2642,15 @@ int rtw89_fw_h2c_scan_offload(struct rtw - H2C_FUNC_SCANOFLD, 1, 1, - len); - -- ret = rtw89_h2c_tx(rtwdev, skb, false); -+ cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD); -+ -+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); - if (ret) { -- rtw89_err(rtwdev, "failed to send h2c\n"); -- goto fail; -+ rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); -+ return ret; - } - - return 0; --fail: -- dev_kfree_skb_any(skb); -- -- return ret; - } - - int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3221,16 +3221,17 @@ static inline struct rtw89_fw_c2h_attr * - #define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) - #define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) - --#define RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) --#define RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) --#define RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) --#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(23, 16)) --#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h) \ -- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 24)) -+struct rtw89_c2h_done_ack { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+} __packed; -+ -+#define RTW89_C2H_DONE_ACK_W2_CAT GENMASK(1, 0) -+#define RTW89_C2H_DONE_ACK_W2_CLASS GENMASK(7, 2) -+#define RTW89_C2H_DONE_ACK_W2_FUNC GENMASK(15, 8) -+#define RTW89_C2H_DONE_ACK_W2_H2C_RETURN GENMASK(23, 16) -+#define RTW89_C2H_DONE_ACK_W2_H2C_SEQ GENMASK(31, 24) - - #define RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4347,17 +4347,44 @@ rtw89_mac_c2h_rec_ack(struct rtw89_dev * - } - - static void --rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) -+rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) - { - /* N.B. This will run in interrupt context. */ -+ struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait; -+ const struct rtw89_c2h_done_ack *c2h = -+ (const struct rtw89_c2h_done_ack *)skb_c2h->data; -+ u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT); -+ u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CLASS); -+ u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_FUNC); -+ u8 h2c_return = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_RETURN); -+ u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_SEQ); -+ struct rtw89_completion_data data = {}; -+ unsigned int cond; - - rtw89_debug(rtwdev, RTW89_DBG_FW, - "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", -- RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), -- RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h->data), -- RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h->data), -- RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h->data), -- RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h->data)); -+ h2c_cat, h2c_class, h2c_func, h2c_return, h2c_seq); -+ -+ if (h2c_cat != H2C_CAT_MAC) -+ return; -+ -+ switch (h2c_class) { -+ default: -+ return; -+ case H2C_CL_MAC_FW_OFLD: -+ switch (h2c_func) { -+ default: -+ return; -+ case H2C_FUNC_ADD_SCANOFLD_CH: -+ case H2C_FUNC_SCANOFLD: -+ cond = RTW89_FW_OFLD_WAIT_COND(0, h2c_func); -+ break; -+ } -+ -+ data.err = !!h2c_return; -+ rtw89_complete_cond(fw_ofld_wait, cond, &data); -+ return; -+ } - } - - static void diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-073-wifi-rtw89-8851b-add-8851B-basic-chip_info.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-073-wifi-rtw89-8851b-add-8851B-basic-chip_info.patch deleted file mode 100644 index 01cdfed79..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-073-wifi-rtw89-8851b-add-8851B-basic-chip_info.patch +++ /dev/null @@ -1,140 +0,0 @@ -From c8d89bf6b82f421dda16526233aba264d1331332 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:44 +0800 -Subject: [PATCH 073/136] wifi: rtw89: 8851b: add 8851B basic chip_info - -8851B is a 1x1 80 MHz bandwidth chip working on 2/5 GHz. Add these basic -information, and more settings will be added by functions. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 101 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8851b.h | 15 +++ - 2 files changed, 116 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -0,0 +1,101 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#include "coex.h" -+#include "fw.h" -+#include "mac.h" -+#include "phy.h" -+#include "reg.h" -+#include "rtw8851b.h" -+#include "rtw8851b_table.h" -+#include "txrx.h" -+#include "util.h" -+ -+#define RTW8851B_FW_FORMAT_MAX 0 -+#define RTW8851B_FW_BASENAME "rtw89/rtw8851b_fw" -+#define RTW8851B_MODULE_FIRMWARE \ -+ RTW8851B_FW_BASENAME ".bin" -+ -+static const struct rtw89_chip_ops rtw8851b_chip_ops = { -+ .fem_setup = NULL, -+ .fill_txdesc = rtw89_core_fill_txdesc, -+ .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, -+ .h2c_dctl_sec_cam = NULL, -+}; -+ -+const struct rtw89_chip_info rtw8851b_chip_info = { -+ .chip_id = RTL8851B, -+ .ops = &rtw8851b_chip_ops, -+ .fw_basename = RTW8851B_FW_BASENAME, -+ .fw_format_max = RTW8851B_FW_FORMAT_MAX, -+ .try_ce_fw = true, -+ .fifo_size = 196608, -+ .dle_scc_rsvd_size = 98304, -+ .max_amsdu_limit = 3500, -+ .dis_2g_40m_ul_ofdma = true, -+ .rsvd_ple_ofst = 0x2f800, -+ .wde_qempty_acq_num = 4, -+ .wde_qempty_mgq_sel = 4, -+ .rf_base_addr = {0xe000}, -+ .pwr_on_seq = NULL, -+ .pwr_off_seq = NULL, -+ .bb_table = &rtw89_8851b_phy_bb_table, -+ .bb_gain_table = &rtw89_8851b_phy_bb_gain_table, -+ .rf_table = {&rtw89_8851b_phy_radioa_table,}, -+ .nctl_table = &rtw89_8851b_phy_nctl_table, -+ .byr_table = &rtw89_8851b_byr_table, -+ .dflt_parms = &rtw89_8851b_dflt_parms, -+ .rfe_parms_conf = rtw89_8851b_rfe_parms_conf, -+ .txpwr_factor_rf = 2, -+ .txpwr_factor_mac = 1, -+ .dig_table = NULL, -+ .tssi_dbw_table = NULL, -+ .support_chanctx_num = 0, -+ .support_bands = BIT(NL80211_BAND_2GHZ) | -+ BIT(NL80211_BAND_5GHZ), -+ .support_bw160 = false, -+ .support_ul_tb_ctrl = true, -+ .hw_sec_hdr = false, -+ .rf_path_num = 1, -+ .tx_nss = 1, -+ .rx_nss = 1, -+ .acam_num = 32, -+ .bcam_num = 20, -+ .scam_num = 128, -+ .bacam_num = 2, -+ .bacam_dynamic_num = 4, -+ .bacam_v1 = false, -+ .sec_ctrl_efuse_size = 4, -+ .physical_efuse_size = 1216, -+ .logical_efuse_size = 2048, -+ .limit_efuse_size = 1280, -+ .dav_phy_efuse_size = 0, -+ .dav_log_efuse_size = 0, -+ .phycap_addr = 0x580, -+ .phycap_size = 128, -+ .para_ver = 0, -+ .wlcx_desired = 0x06000000, -+ .btcx_desired = 0x7, -+ .scbd = 0x1, -+ .mailbox = 0x1, -+ -+ .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | -+ BIT(RTW89_PS_MODE_CLK_GATED), -+ .low_power_hci_modes = 0, -+ .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD, -+ .hci_func_en_addr = R_AX_HCI_FUNC_EN, -+ .h2c_desc_size = sizeof(struct rtw89_txwd_body), -+ .txwd_body_size = sizeof(struct rtw89_txwd_body), -+ .bss_clr_map_reg = R_BSS_CLR_MAP_V1, -+ .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | -+ BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | -+ BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), -+ .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, -+}; -+EXPORT_SYMBOL(rtw8851b_chip_info); -+ -+MODULE_FIRMWARE(RTW8851B_MODULE_FIRMWARE); -+MODULE_AUTHOR("Realtek Corporation"); -+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851B driver"); -+MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8851B_H__ -+#define __RTW89_8851B_H__ -+ -+#include "core.h" -+ -+#define RF_PATH_NUM_8851B 1 -+#define BB_PATH_NUM_8851B 1 -+ -+extern const struct rtw89_chip_info rtw8851b_chip_info; -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-074-wifi-rtw89-8851be-add-8851BE-PCI-entry-and-fill-PCI-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-074-wifi-rtw89-8851be-add-8851BE-PCI-entry-and-fill-PCI-.patch deleted file mode 100644 index 692026efa..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-074-wifi-rtw89-8851be-add-8851BE-PCI-entry-and-fill-PCI-.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 99ff8da56322cda9eb9b37021e27b127c2d1cad8 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:45 +0800 -Subject: [PATCH 074/136] wifi: rtw89: 8851be: add 8851BE PCI entry and fill - PCI capabilities - -Add PCI entry to 8851BE with its device ID 10ec:b851, also fill PCI info -according to its capabilities. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-3-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8851be.c | 86 +++++++++++++++++++ - 1 file changed, 86 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851be.c - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#include -+#include -+ -+#include "pci.h" -+#include "reg.h" -+#include "rtw8851b.h" -+ -+static const struct rtw89_pci_info rtw8851b_pci_info = { -+ .txbd_trunc_mode = MAC_AX_BD_TRUNC, -+ .rxbd_trunc_mode = MAC_AX_BD_TRUNC, -+ .rxbd_mode = MAC_AX_RXBD_PKT, -+ .tag_mode = MAC_AX_TAG_MULTI, -+ .tx_burst = MAC_AX_TX_BURST_2048B, -+ .rx_burst = MAC_AX_RX_BURST_128B, -+ .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS, -+ .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS, -+ .multi_tag_num = MAC_AX_TAG_NUM_8, -+ .lbc_en = MAC_AX_PCIE_ENABLE, -+ .lbc_tmr = MAC_AX_LBC_TMR_2MS, -+ .autok_en = MAC_AX_PCIE_DISABLE, -+ .io_rcy_en = MAC_AX_PCIE_DISABLE, -+ .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS, -+ -+ .init_cfg_reg = R_AX_PCIE_INIT_CFG1, -+ .txhci_en_bit = B_AX_TXHCI_EN, -+ .rxhci_en_bit = B_AX_RXHCI_EN, -+ .rxbd_mode_bit = B_AX_RXBD_MODE, -+ .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL, -+ .max_tag_num_mask = B_AX_MAX_TAG_NUM, -+ .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR, -+ .txbd_rwptr_clr2_reg = 0, -+ .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1}, -+ .dma_stop2 = {0}, -+ .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1}, -+ .dma_busy2_reg = 0, -+ .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1, -+ -+ .rpwm_addr = R_AX_PCIE_HRPWM, -+ .cpwm_addr = R_AX_CPWM, -+ .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) | -+ BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) | -+ BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11), -+ .bd_idx_addr_low_power = NULL, -+ .dma_addr_set = &rtw89_pci_ch_dma_addr_set, -+ .bd_ram_table = &rtw89_bd_ram_table_single, -+ -+ .ltr_set = rtw89_pci_ltr_set, -+ .fill_txaddr_info = rtw89_pci_fill_txaddr_info, -+ .config_intr_mask = rtw89_pci_config_intr_mask, -+ .enable_intr = rtw89_pci_enable_intr, -+ .disable_intr = rtw89_pci_disable_intr, -+ .recognize_intrs = rtw89_pci_recognize_intrs, -+}; -+ -+static const struct rtw89_driver_info rtw89_8851be_info = { -+ .chip = &rtw8851b_chip_info, -+ .bus = { -+ .pci = &rtw8851b_pci_info, -+ }, -+}; -+ -+static const struct pci_device_id rtw89_8851be_id_table[] = { -+ { -+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb851), -+ .driver_data = (kernel_ulong_t)&rtw89_8851be_info, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(pci, rtw89_8851be_id_table); -+ -+static struct pci_driver rtw89_8851be_driver = { -+ .name = "rtw89_8851be", -+ .id_table = rtw89_8851be_id_table, -+ .probe = rtw89_pci_probe, -+ .remove = rtw89_pci_remove, -+ .driver.pm = &rtw89_pm_ops, -+}; -+module_pci_driver(rtw89_8851be_driver); -+ -+MODULE_AUTHOR("Realtek Corporation"); -+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BE driver"); -+MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-075-wifi-rtw89-8851b-add-NCTL-post-table.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-075-wifi-rtw89-8851b-add-NCTL-post-table.patch deleted file mode 100644 index 33e96fb22..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-075-wifi-rtw89-8851b-add-NCTL-post-table.patch +++ /dev/null @@ -1,101 +0,0 @@ -From a24be8bbcbd22cfa53134f6dd399f026874aaa72 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:46 +0800 -Subject: [PATCH 075/136] wifi: rtw89: 8851b: add NCTL post table - -NCTL (nano-controller) is used to assist RF calibration that sends -commands to NCTL so it can reduce IO from driver. 8851B needs additional -settings, so add a table to do things. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/phy.c | 6 +++++- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 6 files changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3192,6 +3192,7 @@ struct rtw89_chip_info { - const struct rtw89_phy_table *bb_gain_table; - const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; - const struct rtw89_phy_table *nctl_table; -+ const struct rtw89_rfk_tbl *nctl_post_table; - const struct rtw89_txpwr_table *byr_table; - const struct rtw89_phy_dig_gain_table *dig_table; - const struct rtw89_dig_regs *dig_regs; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1401,7 +1401,8 @@ static void rtw89_phy_init_rf_nctl(struc - rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x3); - rtw89_phy_write32_set(rtwdev, R_GNT_BT_WGT_EN, 0x1); - rtw89_phy_write32_set(rtwdev, R_P0_PATH_RST, 0x8000000); -- rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000); -+ if (chip->chip_id != RTL8851B) -+ rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000); - if (chip->chip_id == RTL8852B) - rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2); - -@@ -1415,6 +1416,9 @@ static void rtw89_phy_init_rf_nctl(struc - - nctl_table = chip->nctl_table; - rtw89_phy_init_reg(rtwdev, nctl_table, rtw89_phy_config_bb_reg, NULL); -+ -+ if (chip->nctl_post_table) -+ rtw89_rfk_parser(rtwdev, chip->nctl_post_table); - } - - static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -8,6 +8,7 @@ - #include "phy.h" - #include "reg.h" - #include "rtw8851b.h" -+#include "rtw8851b_rfk_table.h" - #include "rtw8851b_table.h" - #include "txrx.h" - #include "util.h" -@@ -44,6 +45,7 @@ const struct rtw89_chip_info rtw8851b_ch - .bb_gain_table = &rtw89_8851b_phy_bb_gain_table, - .rf_table = {&rtw89_8851b_phy_radioa_table,}, - .nctl_table = &rtw89_8851b_phy_nctl_table, -+ .nctl_post_table = &rtw8851b_nctl_post_defs_tbl, - .byr_table = &rtw89_8851b_byr_table, - .dflt_parms = &rtw89_8851b_dflt_parms, - .rfe_parms_conf = rtw89_8851b_rfe_parms_conf, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2085,6 +2085,7 @@ const struct rtw89_chip_info rtw8852a_ch - .rf_table = {&rtw89_8852a_phy_radioa_table, - &rtw89_8852a_phy_radiob_table,}, - .nctl_table = &rtw89_8852a_phy_nctl_table, -+ .nctl_post_table = NULL, - .byr_table = &rtw89_8852a_byr_table, - .dflt_parms = &rtw89_8852a_dflt_parms, - .rfe_parms_conf = NULL, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2522,6 +2522,7 @@ const struct rtw89_chip_info rtw8852b_ch - .rf_table = {&rtw89_8852b_phy_radioa_table, - &rtw89_8852b_phy_radiob_table,}, - .nctl_table = &rtw89_8852b_phy_nctl_table, -+ .nctl_post_table = NULL, - .byr_table = &rtw89_8852b_byr_table, - .dflt_parms = &rtw89_8852b_dflt_parms, - .rfe_parms_conf = NULL, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2821,6 +2821,7 @@ const struct rtw89_chip_info rtw8852c_ch - .rf_table = {&rtw89_8852c_phy_radiob_table, - &rtw89_8852c_phy_radioa_table,}, - .nctl_table = &rtw89_8852c_phy_nctl_table, -+ .nctl_post_table = NULL, - .byr_table = &rtw89_8852c_byr_table, - .dflt_parms = &rtw89_8852c_dflt_parms, - .rfe_parms_conf = NULL, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-076-wifi-rtw89-add-CFO-XTAL-registers-field-to-support-8.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-076-wifi-rtw89-add-CFO-XTAL-registers-field-to-support-8.patch deleted file mode 100644 index ccad68808..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-076-wifi-rtw89-add-CFO-XTAL-registers-field-to-support-8.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 0789881aa3703b2ceb4c0f9a9c7d69f3fb7efd8d Mon Sep 17 00:00:00 2001 -From: Chia-Yuan Li -Date: Fri, 21 Apr 2023 10:45:47 +0800 -Subject: [PATCH 076/136] wifi: rtw89: add CFO XTAL registers field to support - 8851B - -Since CFO XTAL registers of 8851B is different from 8852A, add a chip_info -field to define their difference. Other chips use another interface, so -fill NULL to this field. - -Signed-off-by: Chia-Yuan Li -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 7 +++++++ - drivers/net/wireless/realtek/rtw89/phy.c | 16 +++++++++------- - drivers/net/wireless/realtek/rtw89/reg.h | 6 ++++++ - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 7 +++++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 7 +++++++ - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 7 files changed, 38 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3101,6 +3101,12 @@ struct rtw89_imr_info { - u32 tmac_imr_set; - }; - -+struct rtw89_xtal_info { -+ u32 xcap_reg; -+ u32 sc_xo_mask; -+ u32 sc_xi_mask; -+}; -+ - struct rtw89_rrsr_cfgs { - struct rtw89_reg3_def ref_rate; - struct rtw89_reg3_def rsc; -@@ -3246,6 +3252,7 @@ struct rtw89_chip_info { - u32 dma_ch_mask; - u32 edcca_lvl_reg; - const struct wiphy_wowlan_support *wowlan_stub; -+ const struct rtw89_xtal_info *xtal_info; - }; - - union rtw89_bus_info { ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -2343,27 +2343,29 @@ void rtw89_phy_c2h_handle(struct rtw89_d - - static u8 rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo) - { -+ const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info; - u32 reg_mask; - - if (sc_xo) -- reg_mask = B_AX_XTAL_SC_XO_MASK; -+ reg_mask = xtal->sc_xo_mask; - else -- reg_mask = B_AX_XTAL_SC_XI_MASK; -+ reg_mask = xtal->sc_xi_mask; - -- return (u8)rtw89_read32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask); -+ return (u8)rtw89_read32_mask(rtwdev, xtal->xcap_reg, reg_mask); - } - - static void rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo, - u8 val) - { -+ const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info; - u32 reg_mask; - - if (sc_xo) -- reg_mask = B_AX_XTAL_SC_XO_MASK; -+ reg_mask = xtal->sc_xo_mask; - else -- reg_mask = B_AX_XTAL_SC_XI_MASK; -+ reg_mask = xtal->sc_xi_mask; - -- rtw89_write32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask, val); -+ rtw89_write32_mask(rtwdev, xtal->xcap_reg, reg_mask, val); - } - - static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev, -@@ -2376,7 +2378,7 @@ static void rtw89_phy_cfo_set_crystal_ca - if (!force && cfo->crystal_cap == crystal_cap) - return; - crystal_cap = clamp_t(u8, crystal_cap, 0, 127); -- if (chip->chip_id == RTL8852A) { -+ if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) { - rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); - rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); - sc_xo_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, true); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -243,6 +243,12 @@ - #define B_AX_XTAL_SC_XI_MASK GENMASK(16, 10) - #define B_AX_XTAL_SC_MASK GENMASK(6, 0) - -+#define R_AX_XTAL_ON_CTRL3 0x028C -+#define B_AX_XTAL_SC_INIT_A_BLOCK_MASK GENMASK(30, 24) -+#define B_AX_XTAL_SC_LPS_A_BLOCK_MASK GENMASK(22, 16) -+#define B_AX_XTAL_SC_XO_A_BLOCK_MASK GENMASK(14, 8) -+#define B_AX_XTAL_SC_XI_A_BLOCK_MASK GENMASK(6, 0) -+ - #define R_AX_GPIO0_7_FUNC_SEL 0x02D0 - - #define R_AX_EECS_EESK_FUNC_SEL 0x02D8 ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -18,6 +18,12 @@ - #define RTW8851B_MODULE_FIRMWARE \ - RTW8851B_FW_BASENAME ".bin" - -+static const struct rtw89_xtal_info rtw8851b_xtal_info = { -+ .xcap_reg = R_AX_XTAL_ON_CTRL3, -+ .sc_xo_mask = B_AX_XTAL_SC_XO_A_BLOCK_MASK, -+ .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, -+}; -+ - static const struct rtw89_chip_ops rtw8851b_chip_ops = { - .fem_setup = NULL, - .fill_txdesc = rtw89_core_fill_txdesc, -@@ -94,6 +100,7 @@ const struct rtw89_chip_info rtw8851b_ch - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), - .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, -+ .xtal_info = &rtw8851b_xtal_info, - }; - EXPORT_SYMBOL(rtw8851b_chip_info); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -463,6 +463,12 @@ static const struct rtw89_imr_info rtw88 - .tmac_imr_set = B_AX_TMAC_IMR_SET, - }; - -+static const struct rtw89_xtal_info rtw8852a_xtal_info = { -+ .xcap_reg = R_AX_XTAL_ON_CTRL0, -+ .sc_xo_mask = B_AX_XTAL_SC_XO_MASK, -+ .sc_xi_mask = B_AX_XTAL_SC_XI_MASK, -+}; -+ - static const struct rtw89_rrsr_cfgs rtw8852a_rrsr_cfgs = { - .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, - .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, -@@ -2160,6 +2166,7 @@ const struct rtw89_chip_info rtw8852a_ch - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852a, - #endif -+ .xtal_info = &rtw8852a_xtal_info, - }; - EXPORT_SYMBOL(rtw8852a_chip_info); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2599,6 +2599,7 @@ const struct rtw89_chip_info rtw8852b_ch - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852b, - #endif -+ .xtal_info = NULL, - }; - EXPORT_SYMBOL(rtw8852b_chip_info); - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2898,6 +2898,7 @@ const struct rtw89_chip_info rtw8852c_ch - #ifdef CONFIG_PM - .wowlan_stub = &rtw_wowlan_stub_8852c, - #endif -+ .xtal_info = NULL, - }; - EXPORT_SYMBOL(rtw8852c_chip_info); - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-077-wifi-rtw89-use-chip_info-small_fifo_size-to-choose-d.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-077-wifi-rtw89-use-chip_info-small_fifo_size-to-choose-d.patch deleted file mode 100644 index 1b73ab7b0..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-077-wifi-rtw89-use-chip_info-small_fifo_size-to-choose-d.patch +++ /dev/null @@ -1,87 +0,0 @@ -From ce816ab54bc927f893e17e7e6b9b68e30dd4b4a1 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:48 +0800 -Subject: [PATCH 077/136] wifi: rtw89: use chip_info::small_fifo_size to choose - debug_mask - -Previously, 8852B has smaller FIFO size than others, so I use chip_id to -choose debug_mask before. 8851B has similar design, so add a field to -chip_info as a general expression. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/pci.c | 4 ++-- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 6 files changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3159,6 +3159,7 @@ struct rtw89_chip_info { - u8 fw_format_max; - bool try_ce_fw; - u32 fifo_size; -+ bool small_fifo_size; - u32 dle_scc_rsvd_size; - u16 max_amsdu_limit; - bool dis_2g_40m_ul_ofdma; ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -1003,10 +1003,10 @@ static u32 __rtw89_pci_check_and_reclaim - min_cnt = min(bd_cnt, wd_cnt); - if (min_cnt == 0) { - /* This message can be frequently shown in low power mode or -- * high traffic with 8852B, and we have recognized it as normal -+ * high traffic with small FIFO chips, and we have recognized it as normal - * behavior, so print with mask RTW89_DBG_TXRX in these situations. - */ -- if (rtwpci->low_power || chip->chip_id == RTL8852B) -+ if (rtwpci->low_power || chip->small_fifo_size) - debug_mask = RTW89_DBG_TXRX; - else - debug_mask = RTW89_DBG_UNEXP; ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -38,6 +38,7 @@ const struct rtw89_chip_info rtw8851b_ch - .fw_format_max = RTW8851B_FW_FORMAT_MAX, - .try_ce_fw = true, - .fifo_size = 196608, -+ .small_fifo_size = true, - .dle_scc_rsvd_size = 98304, - .max_amsdu_limit = 3500, - .dis_2g_40m_ul_ofdma = true, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2075,6 +2075,7 @@ const struct rtw89_chip_info rtw8852a_ch - .fw_format_max = RTW8852A_FW_FORMAT_MAX, - .try_ce_fw = false, - .fifo_size = 458752, -+ .small_fifo_size = false, - .dle_scc_rsvd_size = 0, - .max_amsdu_limit = 3500, - .dis_2g_40m_ul_ofdma = true, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2506,6 +2506,7 @@ const struct rtw89_chip_info rtw8852b_ch - .fw_format_max = RTW8852B_FW_FORMAT_MAX, - .try_ce_fw = true, - .fifo_size = 196608, -+ .small_fifo_size = true, - .dle_scc_rsvd_size = 98304, - .max_amsdu_limit = 3500, - .dis_2g_40m_ul_ofdma = true, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2805,6 +2805,7 @@ const struct rtw89_chip_info rtw8852c_ch - .fw_format_max = RTW8852C_FW_FORMAT_MAX, - .try_ce_fw = false, - .fifo_size = 458752, -+ .small_fifo_size = false, - .dle_scc_rsvd_size = 0, - .max_amsdu_limit = 8000, - .dis_2g_40m_ul_ofdma = false, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-078-wifi-rtw89-change-naming-of-BA-CAM-from-V1-to-V0_EXT.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-078-wifi-rtw89-change-naming-of-BA-CAM-from-V1-to-V0_EXT.patch deleted file mode 100644 index f4fbb1847..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-078-wifi-rtw89-change-naming-of-BA-CAM-from-V1-to-V0_EXT.patch +++ /dev/null @@ -1,164 +0,0 @@ -From b6335d91607d6297d3f586e8a4dc6ce8f90652e7 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:49 +0800 -Subject: [PATCH 078/136] wifi: rtw89: change naming of BA CAM from V1 to - V0_EXT - -BA CAM of 8852C has more entries and more fields of H2C, and needs -initialization before using. Due to differences from 8852A/8852B, we name -it as V1 before. However, real V1 of BA CAM is introduced now, so change -it to V0_EXT to avoid confusing with firmware design. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 9 ++++++++- - drivers/net/wireless/realtek/rtw89/fw.c | 12 ++++++------ - drivers/net/wireless/realtek/rtw89/fw.h | 6 +++--- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 +- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 +- - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 +- - 7 files changed, 21 insertions(+), 14 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -122,6 +122,13 @@ enum rtw89_cv { - CHIP_CV_INVALID = CHIP_CV_MAX, - }; - -+enum rtw89_bacam_ver { -+ RTW89_BACAM_V0, -+ RTW89_BACAM_V1, -+ -+ RTW89_BACAM_V0_EXT = 99, -+}; -+ - enum rtw89_core_tx_type { - RTW89_CORE_TX_TYPE_DATA, - RTW89_CORE_TX_TYPE_MGMT, -@@ -3182,7 +3189,7 @@ struct rtw89_chip_info { - u8 scam_num; - u8 bacam_num; - u8 bacam_dynamic_num; -- bool bacam_v1; -+ enum rtw89_bacam_ver bacam_ver; - - u8 sec_ctrl_efuse_size; - u32 physical_efuse_size; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -809,7 +809,7 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev - } - skb_put(skb, H2C_BA_CAM_LEN); - SET_BA_CAM_MACID(skb->data, macid); -- if (chip->bacam_v1) -+ if (chip->bacam_ver == RTW89_BACAM_V0_EXT) - SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx); - else - SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx); -@@ -825,7 +825,7 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev - SET_BA_CAM_INIT_REQ(skb->data, 1); - SET_BA_CAM_SSN(skb->data, params->ssn); - -- if (chip->bacam_v1) { -+ if (chip->bacam_ver == RTW89_BACAM_V0_EXT) { - SET_BA_CAM_STD_EN(skb->data, 1); - SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx); - } -@@ -850,8 +850,8 @@ fail: - return ret; - } - --static int rtw89_fw_h2c_init_dynamic_ba_cam_v1(struct rtw89_dev *rtwdev, -- u8 entry_idx, u8 uid) -+static int rtw89_fw_h2c_init_ba_cam_v0_ext(struct rtw89_dev *rtwdev, -+ u8 entry_idx, u8 uid) - { - struct sk_buff *skb; - int ret; -@@ -888,7 +888,7 @@ fail: - return ret; - } - --void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev) -+void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; - u8 entry_idx = chip->bacam_num; -@@ -896,7 +896,7 @@ void rtw89_fw_h2c_init_ba_cam_v1(struct - int i; - - for (i = 0; i < chip->bacam_dynamic_num; i++) { -- rtw89_fw_h2c_init_dynamic_ba_cam_v1(rtwdev, entry_idx, uid); -+ rtw89_fw_h2c_init_ba_cam_v0_ext(rtwdev, entry_idx, uid); - entry_idx++; - uid++; - } ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -3676,7 +3676,7 @@ void rtw89_fw_release_general_pkt_list_v - void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw); - int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, - bool valid, struct ieee80211_ampdu_params *params); --void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev); -+void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev); - - int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, - struct rtw89_lps_parm *lps_param); -@@ -3739,8 +3739,8 @@ static inline void rtw89_fw_h2c_init_ba_ - { - const struct rtw89_chip_info *chip = rtwdev->chip; - -- if (chip->bacam_v1) -- rtw89_fw_h2c_init_ba_cam_v1(rtwdev); -+ if (chip->bacam_ver == RTW89_BACAM_V0_EXT) -+ rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(rtwdev); - } - - #endif ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -74,7 +74,7 @@ const struct rtw89_chip_info rtw8851b_ch - .scam_num = 128, - .bacam_num = 2, - .bacam_dynamic_num = 4, -- .bacam_v1 = false, -+ .bacam_ver = RTW89_BACAM_V0, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 2048, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2115,7 +2115,7 @@ const struct rtw89_chip_info rtw8852a_ch - .scam_num = 128, - .bacam_num = 2, - .bacam_dynamic_num = 4, -- .bacam_v1 = false, -+ .bacam_ver = RTW89_BACAM_V0, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 1536, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2546,7 +2546,7 @@ const struct rtw89_chip_info rtw8852b_ch - .scam_num = 128, - .bacam_num = 2, - .bacam_dynamic_num = 4, -- .bacam_v1 = false, -+ .bacam_ver = RTW89_BACAM_V0, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 2048, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2846,7 +2846,7 @@ const struct rtw89_chip_info rtw8852c_ch - .scam_num = 128, - .bacam_num = 8, - .bacam_dynamic_num = 8, -- .bacam_v1 = true, -+ .bacam_ver = RTW89_BACAM_V0_EXT, - .sec_ctrl_efuse_size = 4, - .physical_efuse_size = 1216, - .logical_efuse_size = 2048, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-079-wifi-rtw89-8851b-add-support-WoWLAN-to-8851B.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-079-wifi-rtw89-8851b-add-support-WoWLAN-to-8851B.patch deleted file mode 100644 index bfb172a44..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-079-wifi-rtw89-8851b-add-support-WoWLAN-to-8851B.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2273dd724a6c6083e126828e56ff9a0a78913449 Mon Sep 17 00:00:00 2001 -From: Chih-Kang Chang -Date: Fri, 21 Apr 2023 10:45:50 +0800 -Subject: [PATCH 079/136] wifi: rtw89: 8851b: add support WoWLAN to 8851B - -Add WoWLAN stub to 8851B, and decalre this chip can support magic packet -and disconnect wakeup. - -Signed-off-by: Chih-Kang Chang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 12 ++++++++++++ - drivers/net/wireless/realtek/rtw89/wow.c | 2 +- - 2 files changed, 13 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -31,6 +31,15 @@ static const struct rtw89_chip_ops rtw88 - .h2c_dctl_sec_cam = NULL, - }; - -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support rtw_wowlan_stub_8851b = { -+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -+ .n_patterns = RTW89_MAX_PATTERN_NUM, -+ .pattern_max_len = RTW89_MAX_PATTERN_SIZE, -+ .pattern_min_len = 1, -+}; -+#endif -+ - const struct rtw89_chip_info rtw8851b_chip_info = { - .chip_id = RTL8851B, - .ops = &rtw8851b_chip_ops, -@@ -101,6 +110,9 @@ const struct rtw89_chip_info rtw8851b_ch - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | - BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), - .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, -+#ifdef CONFIG_PM -+ .wowlan_stub = &rtw_wowlan_stub_8851b, -+#endif - .xtal_info = &rtw8851b_xtal_info, - }; - EXPORT_SYMBOL(rtw8851b_chip_info); ---- a/drivers/net/wireless/realtek/rtw89/wow.c -+++ b/drivers/net/wireless/realtek/rtw89/wow.c -@@ -91,7 +91,7 @@ static void rtw89_wow_show_wakeup_reason - u32 wow_reason_reg; - u8 reason; - -- if (chip_id == RTL8852A || chip_id == RTL8852B) -+ if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) - wow_reason_reg = R_AX_C2HREG_DATA3 + 3; - else - wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-080-wifi-rtw89-8851b-add-DLE-mem-and-HFC-quota.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-080-wifi-rtw89-8851b-add-DLE-mem-and-HFC-quota.patch deleted file mode 100644 index 403c871c0..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-080-wifi-rtw89-8851b-add-DLE-mem-and-HFC-quota.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 85d1539c0273402911cee89cde1190cd4aec731f Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 21 Apr 2023 10:45:51 +0800 -Subject: [PATCH 080/136] wifi: rtw89: 8851b: add DLE mem and HFC quota - -Configure DLE (data link engine) memory size for operating modes. -Similarly, HFC standing for HCI flow control is used to set quota -according to operating modes, which are SCC or download firmware. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230421024551.29994-9-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 2 + - drivers/net/wireless/realtek/rtw89/mac.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 50 +++++++++++++++++++ - 3 files changed, 53 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1475,6 +1475,8 @@ const struct rtw89_mac_size_set rtw89_ma - .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, - /* 8852B PCIE WOW */ - .ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, -+ /* 8851B PCIE WOW */ -+ .ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, - }; - EXPORT_SYMBOL(rtw89_mac_size); - ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -817,6 +817,7 @@ struct rtw89_mac_size_set { - const struct rtw89_ple_quota ple_qt58; - const struct rtw89_ple_quota ple_qt_52a_wow; - const struct rtw89_ple_quota ple_qt_52b_wow; -+ const struct rtw89_ple_quota ple_qt_51b_wow; - }; - - extern const struct rtw89_mac_size_set rtw89_mac_size; ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -18,6 +18,54 @@ - #define RTW8851B_MODULE_FIRMWARE \ - RTW8851B_FW_BASENAME ".bin" - -+static const struct rtw89_hfc_ch_cfg rtw8851b_hfc_chcfg_pcie[] = { -+ {5, 343, grp_0}, /* ACH 0 */ -+ {5, 343, grp_0}, /* ACH 1 */ -+ {5, 343, grp_0}, /* ACH 2 */ -+ {5, 343, grp_0}, /* ACH 3 */ -+ {0, 0, grp_0}, /* ACH 4 */ -+ {0, 0, grp_0}, /* ACH 5 */ -+ {0, 0, grp_0}, /* ACH 6 */ -+ {0, 0, grp_0}, /* ACH 7 */ -+ {4, 344, grp_0}, /* B0MGQ */ -+ {4, 344, grp_0}, /* B0HIQ */ -+ {0, 0, grp_0}, /* B1MGQ */ -+ {0, 0, grp_0}, /* B1HIQ */ -+ {40, 0, 0} /* FWCMDQ */ -+}; -+ -+static const struct rtw89_hfc_pub_cfg rtw8851b_hfc_pubcfg_pcie = { -+ 448, /* Group 0 */ -+ 0, /* Group 1 */ -+ 448, /* Public Max */ -+ 0 /* WP threshold */ -+}; -+ -+static const struct rtw89_hfc_param_ini rtw8851b_hfc_param_ini_pcie[] = { -+ [RTW89_QTA_SCC] = {rtw8851b_hfc_chcfg_pcie, &rtw8851b_hfc_pubcfg_pcie, -+ &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH}, -+ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie, -+ RTW89_HCIFC_POH}, -+ [RTW89_QTA_INVALID] = {NULL}, -+}; -+ -+static const struct rtw89_dle_mem rtw8851b_dle_mem_pcie[] = { -+ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, -+ &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -+ &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, -+ &rtw89_mac_size.ple_qt58}, -+ [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size6, -+ &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -+ &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, -+ &rtw89_mac_size.ple_qt_51b_wow}, -+ [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, -+ &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, -+ &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, -+ &rtw89_mac_size.ple_qt13}, -+ [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, -+ NULL}, -+}; -+ - static const struct rtw89_xtal_info rtw8851b_xtal_info = { - .xcap_reg = R_AX_XTAL_ON_CTRL3, - .sc_xo_mask = B_AX_XTAL_SC_XO_A_BLOCK_MASK, -@@ -52,6 +100,8 @@ const struct rtw89_chip_info rtw8851b_ch - .max_amsdu_limit = 3500, - .dis_2g_40m_ul_ofdma = true, - .rsvd_ple_ofst = 0x2f800, -+ .hfc_param_ini = rtw8851b_hfc_param_ini_pcie, -+ .dle_mem = rtw8851b_dle_mem_pcie, - .wde_qempty_acq_num = 4, - .wde_qempty_mgq_sel = 4, - .rf_base_addr = {0xe000}, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-081-wifi-rtw89-8851b-add-set_channel_rf.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-081-wifi-rtw89-8851b-add-set_channel_rf.patch deleted file mode 100644 index 1ba41a055..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-081-wifi-rtw89-8851b-add-set_channel_rf.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 2a59fe291fb3f1cbe6f08b96b47af84b9fd5b207 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 24 Apr 2023 14:52:38 +0800 -Subject: [PATCH 081/136] wifi: rtw89: 8851b: add set_channel_rf() - -Add to set RF registers according to the channel we want to switch. The -callers will be added afterward. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230424065242.17477-2-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 239 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 14 + - 2 files changed, 253 insertions(+) - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c - create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -0,0 +1,239 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#include "coex.h" -+#include "debug.h" -+#include "mac.h" -+#include "phy.h" -+#include "reg.h" -+#include "rtw8851b.h" -+#include "rtw8851b_rfk.h" -+#include "rtw8851b_rfk_table.h" -+#include "rtw8851b_table.h" -+ -+static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ return RF_A; -+} -+ -+static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ enum rtw89_bandwidth bw, bool dav) -+{ -+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; -+ u32 rf_reg18; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); -+ -+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); -+ if (rf_reg18 == INV_RF_DATA) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]Invalid RF_0x18 for Path-%d\n", path); -+ return; -+ } -+ rf_reg18 &= ~RR_CFGCH_BW; -+ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ case RTW89_CHANNEL_WIDTH_10: -+ case RTW89_CHANNEL_WIDTH_20: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); -+ } -+ -+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | -+ RR_CFGCH_BW2) & RFREG_MASK; -+ rf_reg18 |= RR_CFGCH_BW2; -+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", -+ bw, path, reg18_addr, -+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); -+} -+ -+static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_bandwidth bw) -+{ -+ _bw_setting(rtwdev, RF_PATH_A, bw, true); -+ _bw_setting(rtwdev, RF_PATH_A, bw, false); -+} -+ -+static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) -+{ -+ u32 bak; -+ u32 tmp; -+ int ret; -+ -+ bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, -+ false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); -+ -+ return !!ret; -+} -+ -+static void _lck_check(struct rtw89_dev *rtwdev) -+{ -+ u32 tmp; -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); -+ } -+ -+ udelay(10); -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); -+ _set_s0_arfc18(rtwdev, tmp); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); -+ } -+ -+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); -+ -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); -+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); -+ _set_s0_arfc18(rtwdev, tmp); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); -+ } -+} -+ -+static void _set_ch(struct rtw89_dev *rtwdev, u32 val) -+{ -+ bool timeout; -+ -+ timeout = _set_s0_arfc18(rtwdev, val); -+ if (!timeout) -+ _lck_check(rtwdev); -+} -+ -+static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ u8 central_ch, bool dav) -+{ -+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; -+ bool is_2g_ch = central_ch <= 14; -+ u32 rf_reg18; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); -+ -+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); -+ rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | -+ RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); -+ -+ if (!is_2g_ch) -+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | -+ FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); -+ -+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | -+ RR_CFGCH_BW2) & RFREG_MASK; -+ rf_reg18 |= RR_CFGCH_BW2; -+ -+ if (path == RF_PATH_A && dav) -+ _set_ch(rtwdev, rf_reg18); -+ else -+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); -+ -+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); -+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", -+ central_ch, path, reg18_addr, -+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); -+} -+ -+static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) -+{ -+ _ch_setting(rtwdev, RF_PATH_A, central_ch, true); -+ _ch_setting(rtwdev, RF_PATH_A, central_ch, false); -+} -+ -+static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, -+ enum rtw89_rf_path path) -+{ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); -+ -+ if (bw == RTW89_CHANNEL_WIDTH_20) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); -+ else if (bw == RTW89_CHANNEL_WIDTH_40) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); -+ else if (bw == RTW89_CHANNEL_WIDTH_80) -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); -+ else -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path, -+ rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); -+} -+ -+static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_bandwidth bw) -+{ -+ u8 kpath, path; -+ -+ kpath = _kpath(rtwdev, phy); -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ _set_rxbb_bw(rtwdev, bw, path); -+ } -+} -+ -+static void rtw8851b_ctrl_bw_ch(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, u8 central_ch, -+ enum rtw89_band band, enum rtw89_bandwidth bw) -+{ -+ _ctrl_ch(rtwdev, central_ch); -+ _ctrl_bw(rtwdev, phy, bw); -+ _rxbb_bw(rtwdev, phy, bw); -+} -+ -+void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8851b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, -+ chan->band_width); -+} ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -0,0 +1,14 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2022-2023 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_8851B_RFK_H__ -+#define __RTW89_8851B_RFK_H__ -+ -+#include "core.h" -+ -+void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx); -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-082-wifi-rtw89-8851b-rfk-add-AACK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-082-wifi-rtw89-8851b-rfk-add-AACK.patch deleted file mode 100644 index 717c81890..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-082-wifi-rtw89-8851b-rfk-add-AACK.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 27d5559fd169676496c65a1d07678115c90dfd34 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 24 Apr 2023 14:52:39 +0800 -Subject: [PATCH 082/136] wifi: rtw89: 8851b: rfk: add AACK - -Automatic amplitude control calibration (AACK) is the calibration to ensure -the oscillator is biased for a constant output amplitude. We do this -calibration if card does power on. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230424065242.17477-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 6 +++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 42 +++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 1 + - 3 files changed, 49 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3782,15 +3782,21 @@ - #define RR_LOGEN 0xa3 - #define RR_LOGEN_RPT GENMASK(19, 16) - #define RR_SX 0xaf -+#define RR_IBD 0xc9 -+#define RR_IBD_VAL GENMASK(4, 0) - #define RR_LDO 0xb1 - #define RR_LDO_SEL GENMASK(8, 6) - #define RR_VCO 0xb2 -+#define RR_VCO_SEL GENMASK(9, 8) -+#define RR_VCI 0xb3 -+#define RR_VCI_ON BIT(7) - #define RR_LPF 0xb7 - #define RR_LPF_BUSY BIT(8) - #define RR_XTALX2 0xb8 - #define RR_MALSEL 0xbe - #define RR_SYNFB 0xc5 - #define RR_SYNFB_LK BIT(15) -+#define RR_AACK 0xca - #define RR_LCKST 0xcf - #define RR_LCKST_BIN BIT(0) - #define RR_LCK_TRG 0xd3 ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -17,6 +17,48 @@ static u8 _kpath(struct rtw89_dev *rtwde - return RF_A; - } - -+void rtw8851b_aack(struct rtw89_dev *rtwdev) -+{ -+ u32 tmp05, ib[4]; -+ u32 tmp; -+ int ret; -+ int rek; -+ int i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO AACK\n"); -+ -+ tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); -+ -+ for (rek = 0; rek < 4; rek++) { -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201e); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201f); -+ fsleep(100); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp, -+ 1, 1000, false, -+ rtwdev, RF_PATH_A, 0xd0, BIT(16)); -+ if (ret) -+ rtw89_warn(rtwdev, "[LCK]AACK timeout\n"); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x1); -+ for (i = 0; i < 4; i++) { -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCO, RR_VCO_SEL, i); -+ ib[i] = rtw89_read_rf(rtwdev, RF_PATH_A, RR_IBD, RR_IBD_VAL); -+ } -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x0); -+ -+ if (ib[0] != 0 && ib[1] != 0 && ib[2] != 0 && ib[3] != 0) -+ break; -+ } -+ -+ if (rek != 0) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]AACK rek = %d\n", rek); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -7,6 +7,7 @@ - - #include "core.h" - -+void rtw8851b_aack(struct rtw89_dev *rtwdev); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-083-wifi-rtw89-8851b-rfk-add-RCK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-083-wifi-rtw89-8851b-rfk-add-RCK.patch deleted file mode 100644 index 6c2e7b417..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-083-wifi-rtw89-8851b-rfk-add-RCK.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ae546f0a23904761edeee1a154b94fb38b6195c0 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 24 Apr 2023 14:52:40 +0800 -Subject: [PATCH 083/136] wifi: rtw89: 8851b: rfk: add RCK - -RCK is synchronize RC calibration. Driver triggers this calibration and -sets the result to register. This calibration is needed once when interface -is going to up. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230424065242.17477-4-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 40 +++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 1 + - 2 files changed, 41 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -17,6 +17,41 @@ static u8 _kpath(struct rtw89_dev *rtwde - return RF_A; - } - -+static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ u32 rf_reg5; -+ u32 rck_val; -+ u32 val; -+ int ret; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); -+ -+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); -+ -+ /* RCK trigger */ -+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, -+ false, rtwdev, path, RR_RCKS, BIT(3)); -+ -+ rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", -+ rck_val, ret); -+ -+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", -+ rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); -+} -+ - void rtw8851b_aack(struct rtw89_dev *rtwdev) - { - u32 tmp05, ib[4]; -@@ -59,6 +94,11 @@ void rtw8851b_aack(struct rtw89_dev *rtw - rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); - } - -+void rtw8851b_rck(struct rtw89_dev *rtwdev) -+{ -+ _rck(rtwdev, RF_PATH_A); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -8,6 +8,7 @@ - #include "core.h" - - void rtw8851b_aack(struct rtw89_dev *rtwdev); -+void rtw8851b_rck(struct rtw89_dev *rtwdev); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-084-wifi-rtw89-8851b-rfk-add-DACK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-084-wifi-rtw89-8851b-rfk-add-DACK.patch deleted file mode 100644 index 66bea3053..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-084-wifi-rtw89-8851b-rfk-add-DACK.patch +++ /dev/null @@ -1,432 +0,0 @@ -From 93fbbeedca3bc93abfe5711b62c8749061c66bc0 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 24 Apr 2023 14:52:41 +0800 -Subject: [PATCH 084/136] wifi: rtw89: 8851b: rfk: add DACK - -DACK (digital-to-analog converters calibration) is used to calibrate DAC -to output good quality signals. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230424065242.17477-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 11 + - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 343 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 1 + - 3 files changed, 355 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4759,11 +4759,15 @@ - #define B_IQKINF2_KCNT GENMASK(15, 8) - #define B_IQKINF2_NCTLV GENMASK(7, 0) - #define R_DCOF0 0xC000 -+#define B_DCOF0_RST BIT(17) - #define B_DCOF0_V GENMASK(4, 1) - #define R_DCOF1 0xC004 -+#define B_DCOF1_RST BIT(17) - #define B_DCOF1_S BIT(0) - #define R_DCOF8 0xC020 - #define B_DCOF8_V GENMASK(4, 1) -+#define R_DCOF9 0xC024 -+#define B_DCOF9_RST BIT(17) - #define R_DACK_S0P0 0xC040 - #define B_DACK_S0P0_OK BIT(31) - #define R_DACK_BIAS00 0xc048 -@@ -4815,6 +4819,7 @@ - #define B_ADDCK0D_VAL GENMASK(25, 16) - #define R_ADDCK0 0xC0F4 - #define B_ADDCK0_TRG BIT(11) -+#define B_ADDCK0_IQ BIT(10) - #define B_ADDCK0 GENMASK(9, 8) - #define B_ADDCK0_MAN GENMASK(5, 4) - #define B_ADDCK0_EN BIT(4) -@@ -4826,6 +4831,7 @@ - #define B_ADDCK0_RL0 GENMASK(17, 8) - #define R_ADDCKR0 0xC0FC - #define B_ADDCKR0_A0 GENMASK(19, 10) -+#define B_ADDCKR0_DC GENMASK(15, 4) - #define B_ADDCKR0_A1 GENMASK(9, 0) - #define R_DACK10 0xC100 - #define B_DACK10 GENMASK(4, 1) -@@ -4876,6 +4882,11 @@ - #define R_ADDCKR1 0xC1fC - #define B_ADDCKR1_A0 GENMASK(19, 10) - #define B_ADDCKR1_A1 GENMASK(9, 0) -+#define R_DACKN0_CTL 0xC210 -+#define B_DACKN0_EN BIT(0) -+#define B_DACKN0_V GENMASK(21, 14) -+#define R_DACKN1_CTL 0xC224 -+#define B_DACKN1_V GENMASK(21, 14) - - /* WiFi CPU local domain */ - #define R_AX_WDT_CTRL 0x0040 ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -17,6 +17,344 @@ static u8 _kpath(struct rtw89_dev *rtwde - return RF_A; - } - -+static void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x1); -+} -+ -+static void _drck(struct rtw89_dev *rtwdev) -+{ -+ u32 rck_d; -+ u32 val; -+ int ret; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, -+ 1, 10000, false, -+ rtwdev, R_DRCK_RES, B_DRCK_POL); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); -+ -+ rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, 0x7c00); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, rck_d); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); -+} -+ -+static void _addck_backup(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); -+ -+ dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); -+ dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); -+} -+ -+static void _addck_reload(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, dack->addck_d[0][0]); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, dack->addck_d[0][1]); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); -+} -+ -+static void _dack_backup_s0(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u8 i; -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); -+ -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); -+ dack->msbk_d[0][0][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); -+ dack->msbk_d[0][1][i] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); -+ } -+ -+ dack->biask_d[0][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); -+ dack->biask_d[0][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); -+ dack->dadck_d[0][0] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00) + 24; -+ dack->dadck_d[0][1] = -+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01) + 24; -+} -+ -+static void _dack_reload_by_path(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, u8 index) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 idx_offset, path_offset; -+ u32 offset, reg; -+ u32 tmp; -+ u8 i; -+ -+ if (index == 0) -+ idx_offset = 0; -+ else -+ idx_offset = 0x14; -+ -+ if (path == RF_PATH_A) -+ path_offset = 0; -+ else -+ path_offset = 0x28; -+ -+ offset = idx_offset + path_offset; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_RST, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_RST, 0x1); -+ -+ /* msbk_d: 15/14/13/12 */ -+ tmp = 0x0; -+ for (i = 0; i < 4; i++) -+ tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); -+ reg = 0xc200 + offset; -+ rtw89_phy_write32(rtwdev, reg, tmp); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, -+ rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); -+ -+ /* msbk_d: 11/10/9/8 */ -+ tmp = 0x0; -+ for (i = 0; i < 4; i++) -+ tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); -+ reg = 0xc204 + offset; -+ rtw89_phy_write32(rtwdev, reg, tmp); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, -+ rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); -+ -+ /* msbk_d: 7/6/5/4 */ -+ tmp = 0x0; -+ for (i = 0; i < 4; i++) -+ tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); -+ reg = 0xc208 + offset; -+ rtw89_phy_write32(rtwdev, reg, tmp); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, -+ rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); -+ -+ /* msbk_d: 3/2/1/0 */ -+ tmp = 0x0; -+ for (i = 0; i < 4; i++) -+ tmp |= dack->msbk_d[path][index][i] << (i * 8); -+ reg = 0xc20c + offset; -+ rtw89_phy_write32(rtwdev, reg, tmp); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, -+ rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); -+ -+ /* dadak_d/biask_d */ -+ tmp = 0x0; -+ tmp = (dack->biask_d[path][index] << 22) | -+ (dack->dadck_d[path][index] << 14); -+ reg = 0xc210 + offset; -+ rtw89_phy_write32(rtwdev, reg, tmp); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, -+ rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL + offset, B_DACKN0_EN, 0x1); -+} -+ -+static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ u8 index; -+ -+ for (index = 0; index < 2; index++) -+ _dack_reload_by_path(rtwdev, path, index); -+} -+ -+static void _addck(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 val; -+ int ret; -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0); -+ udelay(1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, -+ 1, 10000, false, -+ rtwdev, R_ADDCKR0, BIT(0)); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); -+ dack->addck_timeout[0] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0); -+} -+ -+static void _new_dadck(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 i_dc, q_dc, ic, qc; -+ u32 val; -+ int ret; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_setup_defs_tbl); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, -+ 1, 10000, false, -+ rtwdev, R_ADDCKR0, BIT(0)); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n"); -+ dack->addck_timeout[0] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DADCK ret = %d\n", ret); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x0); -+ i_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x1); -+ q_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); -+ -+ ic = 0x80 - sign_extend32(i_dc, 11) * 6; -+ qc = 0x80 - sign_extend32(q_dc, 11) * 6; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]before DADCK, i_dc=0x%x, q_dc=0x%x\n", i_dc, q_dc); -+ -+ dack->dadck_d[0][0] = ic; -+ dack->dadck_d[0][1] = qc; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL, B_DACKN0_V, dack->dadck_d[0][0]); -+ rtw89_phy_write32_mask(rtwdev, R_DACKN1_CTL, B_DACKN1_V, dack->dadck_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DACK]after DADCK, 0xc210=0x%x, 0xc224=0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_DACKN0_CTL, MASKDWORD), -+ rtw89_phy_read32_mask(rtwdev, R_DACKN1_CTL, MASKDWORD)); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_post_defs_tbl); -+} -+ -+static bool _dack_s0_poll(struct rtw89_dev *rtwdev) -+{ -+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || -+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) -+ return false; -+ -+ return true; -+} -+ -+static void _dack_s0(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ bool done; -+ int ret; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_1_defs_tbl); -+ _dack_reset(rtwdev, RF_PATH_A); -+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); -+ -+ ret = read_poll_timeout_atomic(_dack_s0_poll, done, done, -+ 1, 10000, false, rtwdev); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); -+ dack->msbk_timeout[0] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_2_defs_tbl); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); -+ -+ _dack_backup_s0(rtwdev); -+ _dack_reload(rtwdev, RF_PATH_A); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); -+} -+ -+static void _dack(struct rtw89_dev *rtwdev) -+{ -+ _dack_s0(rtwdev); -+} -+ -+static void _dack_dump(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u8 i; -+ u8 t; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->addck_d[0][0], dack->addck_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", -+ dack->dadck_d[0][0], dack->dadck_d[0][1]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", -+ dack->biask_d[0][0], dack->biask_d[0][1]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ t = dack->msbk_d[0][0][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); -+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { -+ t = dack->msbk_d[0][1][i]; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); -+ } -+} -+ -+static void _dack_manual_off(struct rtw89_dev *rtwdev) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_dack_manual_off_defs_tbl); -+} -+ -+static void _dac_cal(struct rtw89_dev *rtwdev, bool force) -+{ -+ struct rtw89_dack_info *dack = &rtwdev->dack; -+ u32 rf0_0; -+ -+ dack->dack_done = false; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x2\n"); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); -+ rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]RF0=0x%x\n", rf0_0); -+ -+ _drck(rtwdev); -+ _dack_manual_off(rtwdev); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); -+ -+ _addck(rtwdev); -+ _addck_backup(rtwdev); -+ _addck_reload(rtwdev); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); -+ -+ _dack(rtwdev); -+ _new_dadck(rtwdev); -+ _dack_dump(rtwdev); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); -+ -+ dack->dack_done = true; -+ dack->dack_cnt++; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); -+} -+ - static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - u32 rf_reg5; -@@ -99,6 +437,11 @@ void rtw8851b_rck(struct rtw89_dev *rtwd - _rck(rtwdev, RF_PATH_A); - } - -+void rtw8851b_dack(struct rtw89_dev *rtwdev) -+{ -+ _dac_cal(rtwdev, false); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -9,6 +9,7 @@ - - void rtw8851b_aack(struct rtw89_dev *rtwdev); - void rtw8851b_rck(struct rtw89_dev *rtwdev); -+void rtw8851b_dack(struct rtw89_dev *rtwdev); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-085-wifi-rtw89-8851b-rfk-add-IQK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-085-wifi-rtw89-8851b-rfk-add-IQK.patch deleted file mode 100644 index 57beb1afd..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-085-wifi-rtw89-8851b-rfk-add-IQK.patch +++ /dev/null @@ -1,1203 +0,0 @@ -From a83c6bb22745168dbe6592a9872f262615ee174b Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 24 Apr 2023 14:52:42 +0800 -Subject: [PATCH 085/136] wifi: rtw89: 8851b: rfk: add IQK - -IQ signal calibration is a very important calibration to yield good RF -performance. We do this calibration only if we are going to run on AP -channel. During scanning phase, without this calibration RF performance -is still acceptable because it transmits with low data rate at this phase. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230424065242.17477-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 5 + - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 1111 +++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 1 + - 3 files changed, 1117 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3580,6 +3580,7 @@ - #define RR_MOD_MASK GENMASK(19, 16) - #define RR_MOD_DCK GENMASK(14, 10) - #define RR_MOD_RGM GENMASK(13, 4) -+#define RR_MOD_RXB GENMASK(9, 5) - #define RR_MOD_V_DOWN 0x0 - #define RR_MOD_V_STANDBY 0x1 - #define RR_TXAGC 0x10001 -@@ -3719,6 +3720,7 @@ - #define RR_RXBB 0x83 - #define RR_RXBB_VOBUF GENMASK(15, 12) - #define RR_RXBB_C2G GENMASK(16, 10) -+#define RR_RXBB_C2 GENMASK(11, 8) - #define RR_RXBB_C1G GENMASK(9, 8) - #define RR_RXBB_FATT GENMASK(7, 0) - #define RR_RXBB_ATTR GENMASK(7, 4) -@@ -4601,6 +4603,8 @@ - #define IQK_DF4_TXT_8_25MHZ 0x021 - #define R_IQK_CFG 0x8034 - #define B_IQK_CFG_SET GENMASK(5, 4) -+#define R_IQK_RXA 0x8044 -+#define B_IQK_RXAGC GENMASK(15, 13) - #define R_TPG_SEL 0x8068 - #define R_TPG_MOD 0x806C - #define B_TPG_MOD_F GENMASK(2, 1) -@@ -4648,6 +4652,7 @@ - #define B_PRT_COM_SYNERR BIT(30) - #define B_PRT_COM_DCI GENMASK(27, 16) - #define B_PRT_COM_CORV GENMASK(15, 8) -+#define B_RPT_COM_RDY GENMASK(15, 0) - #define B_PRT_COM_DCQ GENMASK(11, 0) - #define B_PRT_COM_RXOV BIT(8) - #define B_PRT_COM_GL GENMASK(7, 4) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -12,11 +12,83 @@ - #include "rtw8851b_rfk_table.h" - #include "rtw8851b_table.h" - -+#define RTW8851B_RXK_GROUP_NR 4 -+#define RTW8851B_TXK_GROUP_NR 1 -+#define RTW8851B_IQK_VER 0x2a -+#define RTW8851B_IQK_SS 1 -+#define RTW8851B_LOK_GRAM 10 -+ -+enum rtw8851b_iqk_type { -+ ID_TXAGC = 0x0, -+ ID_FLOK_COARSE = 0x1, -+ ID_FLOK_FINE = 0x2, -+ ID_TXK = 0x3, -+ ID_RXAGC = 0x4, -+ ID_RXK = 0x5, -+ ID_NBTXK = 0x6, -+ ID_NBRXK = 0x7, -+ ID_FLOK_VBUFFER = 0x8, -+ ID_A_FLOK_COARSE = 0x9, -+ ID_G_FLOK_COARSE = 0xa, -+ ID_A_FLOK_FINE = 0xb, -+ ID_G_FLOK_FINE = 0xc, -+ ID_IQK_RESTORE = 0x10, -+}; -+ -+static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; -+static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; -+static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; -+static const u32 a_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10C, 0x112, 0x28c, 0x292}; -+static const u32 a_idxattc2[RTW8851B_RXK_GROUP_NR] = {0xf, 0xf, 0xf, 0xf}; -+static const u32 a_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x4, 0x5, 0x6, 0x7}; -+static const u32 a_power_range[RTW8851B_TXK_GROUP_NR] = {0x0}; -+static const u32 a_track_range[RTW8851B_TXK_GROUP_NR] = {0x6}; -+static const u32 a_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x0a}; -+static const u32 a_itqt[RTW8851B_TXK_GROUP_NR] = {0x12}; -+static const u32 g_power_range[RTW8851B_TXK_GROUP_NR] = {0x0}; -+static const u32 g_track_range[RTW8851B_TXK_GROUP_NR] = {0x6}; -+static const u32 g_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x10}; -+static const u32 g_itqt[RTW8851B_TXK_GROUP_NR] = {0x12}; -+ -+static const u32 rtw8851b_backup_bb_regs[] = {0xc0ec, 0xc0e8}; -+static const u32 rtw8851b_backup_rf_regs[] = { -+ 0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; -+ -+#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8851b_backup_bb_regs) -+#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8851b_backup_rf_regs) -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - return RF_A; - } - -+static void _adc_fifo_rst(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); -+ fsleep(10); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1111); -+} -+ -+static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) -+{ -+ u32 rf_mode; -+ u8 path; -+ int ret; -+ -+ for (path = 0; path < RF_PATH_MAX; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, -+ rf_mode != 2, 2, 5000, false, -+ rtwdev, path, 0x00, RR_MOD_MASK); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", -+ path, ret); -+ } -+} -+ - static void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0); -@@ -355,6 +427,1029 @@ static void _dac_cal(struct rtw89_dev *r - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); - } - -+static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) -+{ -+ u32 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); -+ -+ for (i = 0; i <= 0x9f; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, -+ 0x00010000 + i); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI)); -+ } -+ -+ for (i = 0; i <= 0x9f; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, -+ 0x00010000 + i); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ)); -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000000); -+ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00000000); -+} -+ -+static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); -+} -+ -+static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) -+{ -+ bool fail1 = false, fail2 = false; -+ u32 val; -+ int ret; -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, -+ 10, 8200, false, -+ rtwdev, 0xbff8, MASKBYTE0); -+ if (ret) { -+ fail1 = true; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]NCTL1 IQK timeout!!!\n"); -+ } -+ -+ fsleep(10); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, -+ 10, 200, false, -+ rtwdev, R_RPT_COM, B_RPT_COM_RDY); -+ if (ret) { -+ fail2 = true; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]NCTL2 IQK timeout!!!\n"); -+ } -+ -+ fsleep(10); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, ret = %d, notready = %x fail=%d,%d\n", -+ path, ret, fail1 || fail2, fail1, fail2); -+ -+ return fail1 || fail2; -+} -+ -+static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path, u8 ktype) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool notready; -+ u32 iqk_cmd; -+ -+ switch (ktype) { -+ case ID_A_FLOK_COARSE: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_A_FLOK_COARSE ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x108 | (1 << (4 + path)); -+ break; -+ case ID_G_FLOK_COARSE: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_G_FLOK_COARSE ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x108 | (1 << (4 + path)); -+ break; -+ case ID_A_FLOK_FINE: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_A_FLOK_FINE ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x308 | (1 << (4 + path)); -+ break; -+ case ID_G_FLOK_FINE: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_G_FLOK_FINE ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x308 | (1 << (4 + path)); -+ break; -+ case ID_TXK: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_TXK ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); -+ iqk_cmd = 0x008 | (1 << (path + 4)) | -+ (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); -+ break; -+ case ID_RXAGC: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_RXAGC ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x708 | (1 << (4 + path)) | (path << 1); -+ break; -+ case ID_RXK: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_RXK ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ iqk_cmd = 0x008 | (1 << (path + 4)) | -+ (((0xc + iqk_info->iqk_bw[path]) & 0xf) << 8); -+ break; -+ case ID_NBTXK: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_NBTXK ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, -+ 0x00b); -+ iqk_cmd = 0x408 | (1 << (4 + path)); -+ break; -+ case ID_NBRXK: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]============ S%d ID_NBRXK ============\n", path); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, -+ 0x011); -+ iqk_cmd = 0x608 | (1 << (4 + path)); -+ break; -+ default: -+ return false; -+ } -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); -+ notready = _iqk_check_cal(rtwdev, path); -+ if (iqk_info->iqk_sram_en && -+ (ktype == ID_NBRXK || ktype == ID_RXK)) -+ _iqk_sram(rtwdev, path); -+ -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, ktype= %x, id = %x, notready = %x\n", -+ path, ktype, iqk_cmd + 1, notready); -+ -+ return notready; -+} -+ -+static bool _rxk_2g_group_sel(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u32 rf_0; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0; gp < RTW8851B_RXK_GROUP_NR; gp++) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); -+ fsleep(10); -+ rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), -+ rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); -+ -+ if (gp == 0x3) { -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) -+ _iqk_sram(rtwdev, path); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD, iqk_info->nb_rxcfir[path] | 0x2); -+ iqk_info->is_wb_txiqk[path] = false; -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD, 0x40000000); -+ iqk_info->is_wb_txiqk[path] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_rxcfir[path]); -+ return kfail; -+} -+ -+static bool _rxk_5g_group_sel(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u32 rf_0; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0; gp < RTW8851B_RXK_GROUP_NR; gp++) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, 0x03ff0, a_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); -+ fsleep(100); -+ rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), -+ rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB)); -+ -+ if (gp == 0x3) { -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) -+ _iqk_sram(rtwdev, path); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, -+ iqk_info->nb_rxcfir[path] | 0x2); -+ iqk_info->is_wb_txiqk[path] = false; -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, -+ 0x40000000); -+ iqk_info->is_wb_txiqk[path] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_rxcfir[path]); -+ return kfail; -+} -+ -+static bool _iqk_5g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp = 0x3; -+ u32 rf_0; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); -+ fsleep(100); -+ rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), -+ rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); -+ -+ if (gp == 0x3) { -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", -+ path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD, 0x40000002); -+ iqk_info->is_wb_rxiqk[path] = false; -+ } else { -+ iqk_info->is_wb_rxiqk[path] = false; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_rxcfir[path]); -+ -+ return kfail; -+} -+ -+static bool _iqk_2g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp = 0x3; -+ u32 rf_0; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); -+ -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); -+ fsleep(10); -+ rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", -+ path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), -+ rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); -+ -+ if (gp == 0x3) { -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", -+ path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), -+ MASKDWORD, 0x40000002); -+ iqk_info->is_wb_rxiqk[path] = false; -+ } else { -+ iqk_info->is_wb_rxiqk[path] = false; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_rxcfir[path]); -+ return kfail; -+} -+ -+static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ -+ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); -+ -+ if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_80_defs_tbl); -+ else -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_others_defs_tbl); -+} -+ -+static bool _txk_5g_group_sel(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); -+ iqk_info->nb_txcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, a_itqt[gp]); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); -+ iqk_info->is_wb_txiqk[path] = false; -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, 0x40000000); -+ iqk_info->is_wb_txiqk[path] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_txcfir[path]); -+ return kfail; -+} -+ -+static bool _txk_2g_group_sel(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); -+ iqk_info->nb_txcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ MASKDWORD, g_itqt[gp]); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); -+ iqk_info->is_wb_txiqk[path] = false; -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, 0x40000000); -+ iqk_info->is_wb_txiqk[path] = true; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_txcfir[path]); -+ return kfail; -+} -+ -+static bool _iqk_5g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); -+ iqk_info->nb_txcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, 0x40000002); -+ iqk_info->is_wb_rxiqk[path] = false; -+ } else { -+ iqk_info->is_wb_rxiqk[path] = false; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_txcfir[path]); -+ return kfail; -+} -+ -+static bool _iqk_2g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool kfail = false; -+ bool notready; -+ u8 gp; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); -+ iqk_info->nb_txcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD) | 0x2; -+ } -+ -+ if (!notready) -+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); -+ -+ if (kfail) { -+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), -+ MASKDWORD, 0x40000002); -+ iqk_info->is_wb_rxiqk[path] = false; -+ } else { -+ iqk_info->is_wb_rxiqk[path] = false; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, -+ 1 << path, iqk_info->nb_txcfir[path]); -+ return kfail; -+} -+ -+static bool _iqk_2g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ static const u32 g_txbb[RTW8851B_LOK_GRAM] = { -+ 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; -+ static const u32 g_itqt[RTW8851B_LOK_GRAM] = { -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b}; -+ static const u32 g_wa[RTW8851B_LOK_GRAM] = { -+ 0x00, 0x04, 0x08, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; -+ bool fail = false; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x6); -+ -+ for (i = 0; i < RTW8851B_LOK_GRAM; i++) { -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, g_txbb[i]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, g_wa[i]); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, -+ 0x00000109 | (1 << (4 + path))); -+ fail |= _iqk_check_cal(rtwdev, path); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, -+ 0x00000309 | (1 << (4 + path))); -+ fail |= _iqk_check_cal(rtwdev, path); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x58 = %x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); -+ } -+ -+ return fail; -+} -+ -+static bool _iqk_5g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ static const u32 a_txbb[RTW8851B_LOK_GRAM] = { -+ 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; -+ static const u32 a_itqt[RTW8851B_LOK_GRAM] = { -+ 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b, 0x1b, 0x1b, 0x1b}; -+ static const u32 a_wa[RTW8851B_LOK_GRAM] = { -+ 0x80, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97}; -+ bool fail = false; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x7); -+ -+ for (i = 0; i < RTW8851B_LOK_GRAM; i++) { -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, a_txbb[i]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, a_wa[i]); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, -+ 0x00000109 | (1 << (4 + path))); -+ fail |= _iqk_check_cal(rtwdev, path); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, -+ 0x00000309 | (1 << (4 + path))); -+ fail |= _iqk_check_cal(rtwdev, path); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S0, i = %x, 0x58 = %x\n", i, -+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); -+ } -+ -+ return fail; -+} -+ -+static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ -+ switch (iqk_info->iqk_band[path]) { -+ case RTW89_BAND_2G: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_2G\n"); -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_2ghz_defs_tbl); -+ break; -+ case RTW89_BAND_5G: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_5G\n"); -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_5ghz_defs_tbl); -+ break; -+ default: -+ break; -+ } -+} -+ -+#define IQK_LOK_RETRY 1 -+ -+static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ bool lok_is_fail; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ for (i = 0; i < IQK_LOK_RETRY; i++) { -+ _iqk_txk_setting(rtwdev, path); -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ lok_is_fail = _iqk_2g_lok(rtwdev, phy_idx, path); -+ else -+ lok_is_fail = _iqk_5g_lok(rtwdev, phy_idx, path); -+ -+ if (!lok_is_fail) -+ break; -+ } -+ -+ if (iqk_info->is_nbiqk) { -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ iqk_info->iqk_tx_fail[0][path] = -+ _iqk_2g_nbtxk(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_tx_fail[0][path] = -+ _iqk_5g_nbtxk(rtwdev, phy_idx, path); -+ } else { -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ iqk_info->iqk_tx_fail[0][path] = -+ _txk_2g_group_sel(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_tx_fail[0][path] = -+ _txk_5g_group_sel(rtwdev, phy_idx, path); -+ } -+ -+ _iqk_rxclk_setting(rtwdev, path); -+ _iqk_rxk_setting(rtwdev, path); -+ _adc_fifo_rst(rtwdev, phy_idx, path); -+ -+ if (iqk_info->is_nbiqk) { -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ iqk_info->iqk_rx_fail[0][path] = -+ _iqk_2g_nbrxk(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_rx_fail[0][path] = -+ _iqk_5g_nbrxk(rtwdev, phy_idx, path); -+ } else { -+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) -+ iqk_info->iqk_rx_fail[0][path] = -+ _rxk_2g_group_sel(rtwdev, phy_idx, path); -+ else -+ iqk_info->iqk_rx_fail[0][path] = -+ _rxk_5g_group_sel(rtwdev, phy_idx, path); -+ } -+} -+ -+static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, -+ u32 backup_bb_reg_val[]) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { -+ backup_bb_reg_val[i] = -+ rtw89_phy_read32_mask(rtwdev, rtw8851b_backup_bb_regs[i], -+ MASKDWORD); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]backup bb reg : %x, value =%x\n", -+ rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); -+ } -+} -+ -+static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, -+ u32 backup_rf_reg_val[], u8 rf_path) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { -+ backup_rf_reg_val[i] = -+ rtw89_read_rf(rtwdev, rf_path, -+ rtw8851b_backup_rf_regs[i], RFREG_MASK); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path, -+ rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); -+ } -+} -+ -+static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, -+ const u32 backup_bb_reg_val[]) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { -+ rtw89_phy_write32_mask(rtwdev, rtw8851b_backup_bb_regs[i], -+ MASKDWORD, backup_bb_reg_val[i]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]restore bb reg : %x, value =%x\n", -+ rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); -+ } -+} -+ -+static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, -+ const u32 backup_rf_reg_val[], u8 rf_path) -+{ -+ u32 i; -+ -+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { -+ rtw89_write_rf(rtwdev, rf_path, rtw8851b_backup_rf_regs[i], -+ RFREG_MASK, backup_rf_reg_val[i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, -+ rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); -+ } -+} -+ -+static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ u8 path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u8 idx = 0; -+ -+ iqk_info->iqk_band[path] = chan->band_type; -+ iqk_info->iqk_bw[path] = chan->band_width; -+ iqk_info->iqk_ch[path] = chan->channel; -+ iqk_info->iqk_table_idx[path] = idx; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", -+ path, phy, rtwdev->dbcc_en ? "on" : "off", -+ iqk_info->iqk_band[path] == 0 ? "2G" : -+ iqk_info->iqk_band[path] == 1 ? "5G" : "6G", -+ iqk_info->iqk_ch[path], -+ iqk_info->iqk_bw[path] == 0 ? "20M" : -+ iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", -+ iqk_info->iqk_times, idx); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", -+ path, iqk_info->syn1to2); -+} -+ -+static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, -+ u8 path) -+{ -+ _iqk_by_path(rtwdev, phy_idx, path); -+} -+ -+static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) -+{ -+ bool fail; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00001219); -+ fsleep(10); -+ fail = _iqk_check_cal(rtwdev, path); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail=%d\n", fail); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); -+} -+ -+static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_afebb_restore_defs_tbl); -+} -+ -+static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); -+} -+ -+static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_defs_tbl); -+} -+ -+static void _iqk_init(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u8 idx, path; -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0); -+ -+ if (iqk_info->is_iqk_init) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); -+ -+ iqk_info->is_iqk_init = true; -+ iqk_info->is_nbiqk = false; -+ iqk_info->iqk_fft_en = false; -+ iqk_info->iqk_sram_en = false; -+ iqk_info->iqk_cfir_en = false; -+ iqk_info->iqk_xym_en = false; -+ iqk_info->thermal_rek_en = false; -+ iqk_info->iqk_times = 0x0; -+ -+ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { -+ iqk_info->iqk_channel[idx] = 0x0; -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ iqk_info->lok_cor_fail[idx][path] = false; -+ iqk_info->lok_fin_fail[idx][path] = false; -+ iqk_info->iqk_tx_fail[idx][path] = false; -+ iqk_info->iqk_rx_fail[idx][path] = false; -+ iqk_info->iqk_table_idx[path] = 0x0; -+ } -+ } -+} -+ -+static void _doiqk(struct rtw89_dev *rtwdev, bool force, -+ enum rtw89_phy_idx phy_idx, u8 path) -+{ -+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB); -+ u32 backup_rf_val[RTW8851B_IQK_SS][BACKUP_RF_REGS_NR]; -+ u32 backup_bb_val[BACKUP_BB_REGS_NR]; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, -+ BTC_WRFK_ONESHOT_START); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]==========IQK strat!!!!!==========\n"); -+ iqk_info->iqk_times++; -+ iqk_info->kcount = 0; -+ iqk_info->version = RTW8851B_IQK_VER; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); -+ _iqk_get_ch_info(rtwdev, phy_idx, path); -+ -+ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); -+ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ _iqk_macbb_setting(rtwdev, phy_idx, path); -+ _iqk_preset(rtwdev, path); -+ _iqk_start_iqk(rtwdev, phy_idx, path); -+ _iqk_restore(rtwdev, path); -+ _iqk_afebb_restore(rtwdev, phy_idx, path); -+ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); -+ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, -+ BTC_WRFK_ONESHOT_STOP); -+} -+ -+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) -+{ -+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); -+} -+ - static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - u32 rf_reg5; -@@ -442,6 +1537,22 @@ void rtw8851b_dack(struct rtw89_dev *rtw - _dac_cal(rtwdev, false); - } - -+void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ _iqk_init(rtwdev); -+ _iqk(rtwdev, phy_idx, false); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -10,6 +10,7 @@ - void rtw8851b_aack(struct rtw89_dev *rtwdev); - void rtw8851b_rck(struct rtw89_dev *rtwdev); - void rtw8851b_dack(struct rtw89_dev *rtwdev); -+void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-086-wifi-rtw89-fix-rtw89_read_chip_ver-for-RTL8852B-and-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-086-wifi-rtw89-fix-rtw89_read_chip_ver-for-RTL8852B-and-.patch deleted file mode 100644 index 56b6bfcae..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-086-wifi-rtw89-fix-rtw89_read_chip_ver-for-RTL8852B-and-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 9d4f491b860ea6d04471c3342093b86a46eee63e Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 21 Apr 2023 13:44:04 +0300 -Subject: [PATCH 086/136] wifi: rtw89: fix rtw89_read_chip_ver() for RTL8852B - and RTL8851B - -The if statement is reversed so it will not record the chip version. -This was detected using Smatch: - - drivers/net/wireless/realtek/rtw89/core.c:3593 rtw89_read_chip_ver() - error: uninitialized symbol 'val'. - -Fixes: a6fb2bb84654 ("wifi: rtw89: read version of analog hardware") -Signed-off-by: Dan Carpenter -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/e4d912a2-37f8-4068-8861-7b9494ae731b@kili.mountain ---- - drivers/net/wireless/realtek/rtw89/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3668,7 +3668,7 @@ static void rtw89_read_chip_ver(struct r - - if (chip->chip_id == RTL8852B || chip->chip_id == RTL8851B) { - ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CV, &val); -- if (!ret) -+ if (ret) - return; - - rtwdev->hal.acv = u8_get_bits(val, XTAL_SI_ACV_MASK); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-087-wifi-rtw89-introduce-realtek-ACPI-DSM-method.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-087-wifi-rtw89-introduce-realtek-ACPI-DSM-method.patch deleted file mode 100644 index 1ee48f49c..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-087-wifi-rtw89-introduce-realtek-ACPI-DSM-method.patch +++ /dev/null @@ -1,114 +0,0 @@ -From e897b0bef38a8b40101c0e6e009395506c256460 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 8 May 2023 16:12:09 +0800 -Subject: [PATCH 087/136] wifi: rtw89: introduce realtek ACPI DSM method - -Introduce realtek ACPI DSM method to get required BIOS -configurations. It will be used in the following commits. - -And, enum rtw89_acpi_dsm_func is added for listing the functions -which are currently recognized. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508081211.38760-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/Makefile | 3 +- - drivers/net/wireless/realtek/rtw89/acpi.c | 52 +++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/acpi.h | 21 +++++++++ - 3 files changed, 75 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/wireless/realtek/rtw89/acpi.c - create mode 100644 drivers/net/wireless/realtek/rtw89/acpi.h - ---- a/drivers/net/wireless/realtek/rtw89/Makefile -+++ b/drivers/net/wireless/realtek/rtw89/Makefile -@@ -13,7 +13,8 @@ rtw89_core-y += core.o \ - coex.o \ - ps.o \ - chan.o \ -- ser.o -+ ser.o \ -+ acpi.o - - rtw89_core-$(CPTCFG_PM) += wow.o - ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/acpi.c -@@ -0,0 +1,52 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* Copyright(c) 2021-2023 Realtek Corporation -+ */ -+ -+#include -+#include -+ -+#include "acpi.h" -+#include "debug.h" -+ -+static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00, -+ 0x82, 0xBD, 0xFE, 0x86, -+ 0x07, 0x80, 0x3A, 0xA7); -+ -+static int rtw89_acpi_dsm_get(struct rtw89_dev *rtwdev, union acpi_object *obj, -+ u8 *value) -+{ -+ switch (obj->type) { -+ case ACPI_TYPE_INTEGER: -+ *value = (u8)obj->integer.value; -+ break; -+ case ACPI_TYPE_BUFFER: -+ *value = obj->buffer.pointer[0]; -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_UNEXP, -+ "acpi dsm return unhandled type: %d\n", obj->type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, -+ enum rtw89_acpi_dsm_func func, u8 *value) -+{ -+ union acpi_object *obj; -+ int ret; -+ -+ obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid, -+ 0, func, NULL); -+ if (!obj) { -+ rtw89_debug(rtwdev, RTW89_DBG_UNEXP, -+ "acpi dsm fail to evaluate func: %d\n", func); -+ return -ENOENT; -+ } -+ -+ ret = rtw89_acpi_dsm_get(rtwdev, obj, value); -+ -+ ACPI_FREE(obj); -+ return ret; -+} ---- /dev/null -+++ b/drivers/net/wireless/realtek/rtw89/acpi.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* Copyright(c) 2021-2023 Realtek Corporation -+ */ -+ -+#ifndef __RTW89_ACPI_H__ -+#define __RTW89_ACPI_H__ -+ -+#include "core.h" -+ -+enum rtw89_acpi_dsm_func { -+ RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2, -+ RTW89_ACPI_DSM_FUNC_6G_DIS = 3, -+ RTW89_ACPI_DSM_FUNC_6G_BP = 4, -+ RTW89_ACPI_DSM_FUNC_TAS_EN = 5, -+ RTW89_ACPI_DSM_FUNC_59G_EN = 6, -+}; -+ -+int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, -+ enum rtw89_acpi_dsm_func func, u8 *value); -+ -+#endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-088-wifi-rtw89-regd-judge-UNII-4-according-to-BIOS-and-c.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-088-wifi-rtw89-regd-judge-UNII-4-according-to-BIOS-and-c.patch deleted file mode 100644 index 7861ba100..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-088-wifi-rtw89-regd-judge-UNII-4-according-to-BIOS-and-c.patch +++ /dev/null @@ -1,173 +0,0 @@ -From a002f98123dd5e6b6d66c1b42a37dfd6e25ade4c Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 8 May 2023 16:12:10 +0800 -Subject: [PATCH 088/136] wifi: rtw89: regd: judge UNII-4 according to BIOS and - chip - -For realtek regulatory, there are following two kinds of configurations -to determine whether to allow UNII-4 band, i.e. 5.9GHz channels. - -1. default setting according to whether chip support it or not -2. evaluate realtek ACPI DSM with RTW89_ACPI_DSM_FUNC_59G_EN (func. 6) - -If (1) is false, we won't try (2) and just disallow UNII-4. Otherwise, -if (2) is not supported or returns a non-specific value, we follow the -default setting either. Besides, this commit aims to add decision logic -in rtw89 regulatory. Actually, driver doesn't register UNII-4 yet. That -will be handled by another commit. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508081211.38760-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 7 ++- - drivers/net/wireless/realtek/rtw89/core.h | 2 + - drivers/net/wireless/realtek/rtw89/regd.c | 51 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 7 files changed, 63 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3850,7 +3850,12 @@ static int rtw89_core_register_hw(struct - return ret; - } - -- hw->wiphy->reg_notifier = rtw89_regd_notifier; -+ ret = rtw89_regd_setup(rtwdev); -+ if (ret) { -+ rtw89_err(rtwdev, "failed to set up regd\n"); -+ goto err_free_supported_band; -+ } -+ - hw->wiphy->sar_capa = &rtw89_sar_capa; - - ret = ieee80211_register_hw(hw); ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3179,6 +3179,7 @@ struct rtw89_chip_info { - u8 support_chanctx_num; - u8 support_bands; - bool support_bw160; -+ bool support_unii4; - bool support_ul_tb_ctrl; - bool hw_sec_hdr; - u8 rf_path_num; -@@ -5044,6 +5045,7 @@ int rtw89_core_release_sta_ba_entry(stru - void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); - int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); - bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate); -+int rtw89_regd_setup(struct rtw89_dev *rtwdev); - int rtw89_regd_init(struct rtw89_dev *rtwdev, - void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); - void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); ---- a/drivers/net/wireless/realtek/rtw89/regd.c -+++ b/drivers/net/wireless/realtek/rtw89/regd.c -@@ -2,6 +2,7 @@ - /* Copyright(c) 2019-2020 Realtek Corporation - */ - -+#include "acpi.h" - #include "debug.h" - #include "ps.h" - -@@ -282,6 +283,56 @@ do { \ - __r->txpwr_regd[RTW89_BAND_6G]); \ - } while (0) - -+static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev, -+ struct wiphy *wiphy) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ bool regd_allow_unii_4 = chip->support_unii4; -+ int ret; -+ u8 val; -+ -+ if (!chip->support_unii4) -+ goto bottom; -+ -+ ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &val); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, -+ "acpi: cannot eval unii 4: %d\n", ret); -+ goto bottom; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, -+ "acpi: eval if allow unii 4: %d\n", val); -+ -+ switch (val) { -+ case 0: -+ regd_allow_unii_4 = false; -+ break; -+ case 1: -+ regd_allow_unii_4 = true; -+ break; -+ default: -+ break; -+ } -+ -+bottom: -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow unii 4: %d\n", -+ regd_allow_unii_4); -+} -+ -+int rtw89_regd_setup(struct rtw89_dev *rtwdev) -+{ -+ struct wiphy *wiphy = rtwdev->hw->wiphy; -+ -+ if (!wiphy) -+ return -EINVAL; -+ -+ rtw89_regd_setup_unii4(rtwdev, wiphy); -+ -+ wiphy->reg_notifier = rtw89_regd_notifier; -+ return 0; -+} -+ - int rtw89_regd_init(struct rtw89_dev *rtwdev, - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -123,6 +123,7 @@ const struct rtw89_chip_info rtw8851b_ch - .support_bands = BIT(NL80211_BAND_2GHZ) | - BIT(NL80211_BAND_5GHZ), - .support_bw160 = false, -+ .support_unii4 = true, - .support_ul_tb_ctrl = true, - .hw_sec_hdr = false, - .rf_path_num = 1, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2105,6 +2105,7 @@ const struct rtw89_chip_info rtw8852a_ch - .support_bands = BIT(NL80211_BAND_2GHZ) | - BIT(NL80211_BAND_5GHZ), - .support_bw160 = false, -+ .support_unii4 = false, - .support_ul_tb_ctrl = false, - .hw_sec_hdr = false, - .rf_path_num = 2, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2536,6 +2536,7 @@ const struct rtw89_chip_info rtw8852b_ch - .support_bands = BIT(NL80211_BAND_2GHZ) | - BIT(NL80211_BAND_5GHZ), - .support_bw160 = false, -+ .support_unii4 = true, - .support_ul_tb_ctrl = true, - .hw_sec_hdr = false, - .rf_path_num = 2, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2836,6 +2836,7 @@ const struct rtw89_chip_info rtw8852c_ch - BIT(NL80211_BAND_5GHZ) | - BIT(NL80211_BAND_6GHZ), - .support_bw160 = true, -+ .support_unii4 = true, - .support_ul_tb_ctrl = false, - .hw_sec_hdr = true, - .rf_path_num = 2, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-089-wifi-rtw89-support-U-NII-4-channels-on-5GHz-band.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-089-wifi-rtw89-support-U-NII-4-channels-on-5GHz-band.patch deleted file mode 100644 index 1bf08be75..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-089-wifi-rtw89-support-U-NII-4-channels-on-5GHz-band.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e3b77c06c8863a53a0d80f7dcaff923c590e3edd Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 8 May 2023 16:12:11 +0800 -Subject: [PATCH 089/136] wifi: rtw89: support U-NII-4 channels on 5GHz band - -U-NII-4 band, i.e 5.9GHz channels, can be supported by chip 8852C, 8852B -and 8851B. But, it is not supported by chip 8852A. Flag support_unii4 is -added in chip info and defined by chip accordingly to indicate that. -We reference this flag of runtime chip to decide whether to register -5.9GHz channels. - -After that, we consider if U-NII-4 band is allowed by our regulatory -rule of U-NII-4. If chip::support_unii4 but not regd::allow_unii4, -we stll do not register 5.9GHz channels. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508081211.38760-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 3 +++ - drivers/net/wireless/realtek/rtw89/regd.c | 10 ++++++++++ - 2 files changed, 13 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -77,6 +77,9 @@ static struct ieee80211_channel rtw89_ch - RTW89_DEF_CHAN_5G(5785, 157), - RTW89_DEF_CHAN_5G(5805, 161), - RTW89_DEF_CHAN_5G_NO_HT40MINUS(5825, 165), -+ RTW89_DEF_CHAN_5G(5845, 169), -+ RTW89_DEF_CHAN_5G(5865, 173), -+ RTW89_DEF_CHAN_5G(5885, 177), - }; - - static struct ieee80211_channel rtw89_channels_6ghz[] = { ---- a/drivers/net/wireless/realtek/rtw89/regd.c -+++ b/drivers/net/wireless/realtek/rtw89/regd.c -@@ -288,6 +288,7 @@ static void rtw89_regd_setup_unii4(struc - { - const struct rtw89_chip_info *chip = rtwdev->chip; - bool regd_allow_unii_4 = chip->support_unii4; -+ struct ieee80211_supported_band *sband; - int ret; - u8 val; - -@@ -318,6 +319,15 @@ static void rtw89_regd_setup_unii4(struc - bottom: - rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow unii 4: %d\n", - regd_allow_unii_4); -+ -+ if (regd_allow_unii_4) -+ return; -+ -+ sband = wiphy->bands[NL80211_BAND_5GHZ]; -+ if (!sband) -+ return; -+ -+ sband->n_channels -= 3; - } - - int rtw89_regd_setup(struct rtw89_dev *rtwdev) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-090-wifi-rtw89-pci-fix-interrupt-enable-mask-for-HALT-C2.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-090-wifi-rtw89-pci-fix-interrupt-enable-mask-for-HALT-C2.patch deleted file mode 100644 index eaae86cc7..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-090-wifi-rtw89-pci-fix-interrupt-enable-mask-for-HALT-C2.patch +++ /dev/null @@ -1,58 +0,0 @@ -From aa70fa4f7dd80e4e495c30ff10a6c373c26902e0 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 8 May 2023 16:43:33 +0800 -Subject: [PATCH 090/136] wifi: rtw89: pci: fix interrupt enable mask for HALT - C2H of RTL8851B - -RTL8851B keeps almost the same interrupt flow as RTL8852A and RTL8852B. -But, it uses a different bitmask for interrupt indicator of FW HALT C2H. -So, we make a chip judgement in pci when configuring interrupt mask. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508084335.42953-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/pci.c | 9 +++++++-- - drivers/net/wireless/realtek/rtw89/pci.h | 1 + - 2 files changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -3216,11 +3216,16 @@ static void rtw89_pci_clear_resource(str - void rtw89_pci_config_intr_mask(struct rtw89_dev *rtwdev) - { - struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ u32 hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN; -+ -+ if (chip->chip_id == RTL8851B) -+ hs0isr_ind_int_en = B_AX_HS0ISR_IND_INT_EN_WKARND; - - rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0; - - if (rtwpci->under_recovery) { -- rtwpci->intrs[0] = B_AX_HS0ISR_IND_INT_EN; -+ rtwpci->intrs[0] = hs0isr_ind_int_en; - rtwpci->intrs[1] = 0; - } else { - rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | -@@ -3230,7 +3235,7 @@ void rtw89_pci_config_intr_mask(struct r - B_AX_RXDMA_STUCK_INT_EN | - B_AX_RDU_INT_EN | - B_AX_RPQBD_FULL_INT_EN | -- B_AX_HS0ISR_IND_INT_EN; -+ hs0isr_ind_int_en; - - rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; - } ---- a/drivers/net/wireless/realtek/rtw89/pci.h -+++ b/drivers/net/wireless/realtek/rtw89/pci.h -@@ -150,6 +150,7 @@ - #define B_AX_HD1ISR_IND_INT_EN BIT(26) - #define B_AX_HD0ISR_IND_INT_EN BIT(25) - #define B_AX_HS0ISR_IND_INT_EN BIT(24) -+#define B_AX_HS0ISR_IND_INT_EN_WKARND BIT(23) - #define B_AX_RETRAIN_INT_EN BIT(21) - #define B_AX_RPQBD_FULL_INT_EN BIT(20) - #define B_AX_RDU_INT_EN BIT(19) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-091-wifi-rtw89-ser-L1-add-pre-M0-and-post-M0-states.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-091-wifi-rtw89-ser-L1-add-pre-M0-and-post-M0-states.patch deleted file mode 100644 index 16ee3c61c..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-091-wifi-rtw89-ser-L1-add-pre-M0-and-post-M0-states.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 56617fd02adbf2ce7e18469895846ba82150cb1f Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Mon, 8 May 2023 16:43:34 +0800 -Subject: [PATCH 091/136] wifi: rtw89: ser: L1 add pre-M0 and post-M0 states - -Newer FW re-design SER (syetem error recovery) L1 (level 1) flow. -New L1 flow will expect two extra states before original L1 flow. - -* Before: -fw --- M1 --> driver -fw <-- M2 --- driver -fw --- M3 --> driver -fw <-- M4 --- driver -fw --- M5 --> driver - -* After: -fw --- pre-M0 --> driver -fw <-- post-M0 --- driver -fw --- M1 --> driver -fw <-- M2 --- driver -fw --- M3 --> driver -fw <-- M4 --- driver -fw --- M5 --> driver - -Then before M1, FW gets one more interval to deal with things that FW -should have handled well. To consider backward/forward compatibility, -FW and driver won't change flow from M1 to M5. (only except that halt -trigger control will change a little bit.) So, there will be two differnt -starting points of SER L1. -* old FW: SER L1 starts from M1 -* new FW: SER L1 starts from pre-M0 -Then, driver adds the new SER L1 entry and also keep the original one -instead of changing it. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508084335.42953-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++ - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - drivers/net/wireless/realtek/rtw89/ser.c | 43 ++++++++++++++++++++++- - 4 files changed, 51 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3946,6 +3946,7 @@ enum rtw89_ser_rcvy_step { - struct rtw89_ser { - u8 state; - u8 alarm_event; -+ bool prehandle_l1; - - struct work_struct ser_hdl_work; - struct delayed_work ser_alarm_work; ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -676,6 +676,7 @@ EXPORT_SYMBOL(rtw89_mac_get_err_status); - - int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) - { -+ struct rtw89_ser *ser = &rtwdev->ser; - u32 halt; - int ret = 0; - -@@ -692,6 +693,11 @@ int rtw89_mac_set_err_status(struct rtw8 - } - - rtw89_write32(rtwdev, R_AX_HALT_H2C, err); -+ -+ if (ser->prehandle_l1 && -+ (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN)) -+ return 0; -+ - rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); - - return 0; ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -642,6 +642,7 @@ enum mac_ax_err_info { - MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010, - - /* L1 */ -+ MAC_AX_ERR_L1_PREERR_DMAC = 0x999, - MAC_AX_ERR_L1_ERR_DMAC = 0x1000, - MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001, - MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002, -@@ -780,6 +781,7 @@ enum mac_ax_err_info { - MAC_AX_ERR_L1_RCVY_EN = 0x0002, - MAC_AX_ERR_L1_RCVY_STOP_REQ = 0x0003, - MAC_AX_ERR_L1_RCVY_START_REQ = 0x0004, -+ MAC_AX_ERR_L1_RESET_START_DMAC = 0x000A, - MAC_AX_ERR_L0_CFG_NOTIFY = 0x0010, - MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011, - MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012, ---- a/drivers/net/wireless/realtek/rtw89/ser.c -+++ b/drivers/net/wireless/realtek/rtw89/ser.c -@@ -20,12 +20,14 @@ enum ser_evt { - SER_EV_NONE, - SER_EV_STATE_IN, - SER_EV_STATE_OUT, -+ SER_EV_L1_RESET_PREPARE, /* pre-M0 */ - SER_EV_L1_RESET, /* M1 */ - SER_EV_DO_RECOVERY, /* M3 */ - SER_EV_MAC_RESET_DONE, /* M5 */ - SER_EV_L2_RESET, - SER_EV_L2_RECFG_DONE, - SER_EV_L2_RECFG_TIMEOUT, -+ SER_EV_M1_TIMEOUT, - SER_EV_M3_TIMEOUT, - SER_EV_FW_M5_TIMEOUT, - SER_EV_L0_RESET, -@@ -34,6 +36,7 @@ enum ser_evt { - - enum ser_state { - SER_IDLE_ST, -+ SER_L1_RESET_PRE_ST, - SER_RESET_TRX_ST, - SER_DO_HCI_ST, - SER_L2_RESET_ST, -@@ -374,6 +377,13 @@ static int hal_stop_dma(struct rtw89_ser - return ret; - } - -+static void hal_send_post_m0_event(struct rtw89_ser *ser) -+{ -+ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); -+ -+ rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_START_DMAC); -+} -+ - static void hal_send_m2_event(struct rtw89_ser *ser) - { - struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); -@@ -398,6 +408,9 @@ static void ser_idle_st_hdl(struct rtw89 - rtw89_hci_recovery_complete(rtwdev); - clear_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags); - break; -+ case SER_EV_L1_RESET_PREPARE: -+ ser_state_goto(ser, SER_L1_RESET_PRE_ST); -+ break; - case SER_EV_L1_RESET: - ser_state_goto(ser, SER_RESET_TRX_ST); - break; -@@ -412,6 +425,28 @@ static void ser_idle_st_hdl(struct rtw89 - } - } - -+static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt) -+{ -+ switch (evt) { -+ case SER_EV_STATE_IN: -+ ser->prehandle_l1 = true; -+ hal_send_post_m0_event(ser); -+ ser_set_alarm(ser, 1000, SER_EV_M1_TIMEOUT); -+ break; -+ case SER_EV_L1_RESET: -+ ser_state_goto(ser, SER_RESET_TRX_ST); -+ break; -+ case SER_EV_M1_TIMEOUT: -+ ser_state_goto(ser, SER_L2_RESET_ST); -+ break; -+ case SER_EV_STATE_OUT: -+ ser_del_alarm(ser); -+ break; -+ default: -+ break; -+ } -+} -+ - static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) - { - struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); -@@ -654,12 +689,14 @@ static const struct event_ent ser_ev_tbl - {SER_EV_NONE, "SER_EV_NONE"}, - {SER_EV_STATE_IN, "SER_EV_STATE_IN"}, - {SER_EV_STATE_OUT, "SER_EV_STATE_OUT"}, -- {SER_EV_L1_RESET, "SER_EV_L1_RESET"}, -+ {SER_EV_L1_RESET_PREPARE, "SER_EV_L1_RESET_PREPARE pre-m0"}, -+ {SER_EV_L1_RESET, "SER_EV_L1_RESET m1"}, - {SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"}, - {SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"}, - {SER_EV_L2_RESET, "SER_EV_L2_RESET"}, - {SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"}, - {SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"}, -+ {SER_EV_M1_TIMEOUT, "SER_EV_M1_TIMEOUT"}, - {SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"}, - {SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"}, - {SER_EV_L0_RESET, "SER_EV_L0_RESET"}, -@@ -668,6 +705,7 @@ static const struct event_ent ser_ev_tbl - - static const struct state_ent ser_st_tbl[] = { - {SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl}, -+ {SER_L1_RESET_PRE_ST, "SER_L1_RESET_PRE_ST", ser_l1_reset_pre_st_hdl}, - {SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl}, - {SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl}, - {SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl} -@@ -713,6 +751,9 @@ int rtw89_ser_notify(struct rtw89_dev *r - rtw89_info(rtwdev, "SER catches error: 0x%x\n", err); - - switch (err) { -+ case MAC_AX_ERR_L1_PREERR_DMAC: /* pre-M0 */ -+ event = SER_EV_L1_RESET_PREPARE; -+ break; - case MAC_AX_ERR_L1_ERR_DMAC: - case MAC_AX_ERR_L0_PROMOTE_TO_L1: - event = SER_EV_L1_RESET; /* M1 */ diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-092-wifi-rtw89-suppress-the-log-for-specific-SER-called-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-092-wifi-rtw89-suppress-the-log-for-specific-SER-called-.patch deleted file mode 100644 index 1eb6eae75..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-092-wifi-rtw89-suppress-the-log-for-specific-SER-called-.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 8130e94e888bf90e495f88d1a1e63c43e1cfbc18 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Mon, 8 May 2023 16:43:35 +0800 -Subject: [PATCH 092/136] wifi: rtw89: suppress the log for specific SER called - CMDPSR_FRZTO - -For 8852CE, there is abnormal state called CMDPSR_FRZTO, -which occasionally happens in some platforms, and could be -found by firmware and fixed in current SER flow, so we add -suppress function to avoid verbose message for this resolved case. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230508084335.42953-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/mac.c | 36 +++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3940,6 +3940,7 @@ enum rtw89_ser_rcvy_step { - RTW89_SER_DRV_STOP_RX, - RTW89_SER_DRV_STOP_RUN, - RTW89_SER_HAL_STOP_DMA, -+ RTW89_SER_SUPPRESS_LOG, - RTW89_NUM_OF_SER_FLAGS - }; - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -644,6 +644,39 @@ static void rtw89_mac_dump_err_status(st - rtw89_info(rtwdev, "<---\n"); - } - -+static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err) -+{ -+ struct rtw89_ser *ser = &rtwdev->ser; -+ u32 dmac_err, imr, isr; -+ int ret; -+ -+ if (rtwdev->chip->chip_id == RTL8852C) { -+ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); -+ if (ret) -+ return true; -+ -+ if (err == MAC_AX_ERR_L1_ERR_DMAC) { -+ dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); -+ imr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR); -+ isr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR); -+ -+ if ((dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) && -+ ((isr & imr) & B_AX_B0_ISR_ERR_CMDPSR_FRZTO)) { -+ set_bit(RTW89_SER_SUPPRESS_LOG, ser->flags); -+ return true; -+ } -+ } else if (err == MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE) { -+ if (test_bit(RTW89_SER_SUPPRESS_LOG, ser->flags)) -+ return true; -+ } else if (err == MAC_AX_ERR_L1_RESET_RECOVERY_DONE) { -+ if (test_and_clear_bit(RTW89_SER_SUPPRESS_LOG, ser->flags)) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ - u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) - { - u32 err, err_scnr; -@@ -667,6 +700,9 @@ u32 rtw89_mac_get_err_status(struct rtw8 - else if (err_scnr == RTW89_RXI300_ERROR) - err = MAC_AX_ERR_RXI300; - -+ if (rtw89_mac_suppress_log(rtwdev, err)) -+ return err; -+ - rtw89_fw_st_dbg_dump(rtwdev); - rtw89_mac_dump_err_status(rtwdev, err); - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-093-wifi-rtw89-8852b-adjust-quota-to-avoid-SER-L1-caused.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-093-wifi-rtw89-8852b-adjust-quota-to-avoid-SER-L1-caused.patch deleted file mode 100644 index 96975d07b..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-093-wifi-rtw89-8852b-adjust-quota-to-avoid-SER-L1-caused.patch +++ /dev/null @@ -1,118 +0,0 @@ -From c0426c446d92023d344131d01d929bc25db7a24e Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Wed, 26 Apr 2023 11:47:37 +0800 -Subject: [PATCH 093/136] wifi: rtw89: 8852b: adjust quota to avoid SER L1 - caused by access null page - -Though SER can recover this case, traffic can get stuck for a while. Fix it -by adjusting page quota to avoid hardware access null page of CMAC/DMAC. - -Fixes: a1cb097168fa ("wifi: rtw89: 8852b: configure DLE mem") -Fixes: 3e870b481733 ("wifi: rtw89: 8852b: add HFC quota arrays") -Cc: stable@vger.kernel.org -Tested-by: Larry Finger -Link: https://github.com/lwfinger/rtw89/issues/226#issuecomment-1520776761 -Link: https://github.com/lwfinger/rtw89/issues/240 -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230426034737.24870-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.c | 4 +++ - drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 28 +++++++++---------- - 3 files changed, 20 insertions(+), 14 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -1467,6 +1467,8 @@ const struct rtw89_mac_size_set rtw89_ma - .wde_size4 = {RTW89_WDE_PG_64, 0, 4096,}, - /* PCIE 64 */ - .wde_size6 = {RTW89_WDE_PG_64, 512, 0,}, -+ /* 8852B PCIE SCC */ -+ .wde_size7 = {RTW89_WDE_PG_64, 510, 2,}, - /* DLFW */ - .wde_size9 = {RTW89_WDE_PG_64, 0, 1024,}, - /* 8852C DLFW */ -@@ -1491,6 +1493,8 @@ const struct rtw89_mac_size_set rtw89_ma - .wde_qt4 = {0, 0, 0, 0,}, - /* PCIE 64 */ - .wde_qt6 = {448, 48, 0, 16,}, -+ /* 8852B PCIE SCC */ -+ .wde_qt7 = {446, 48, 0, 16,}, - /* 8852C DLFW */ - .wde_qt17 = {0, 0, 0, 0,}, - /* 8852C PCIE SCC */ ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -794,6 +794,7 @@ struct rtw89_mac_size_set { - const struct rtw89_dle_size wde_size0; - const struct rtw89_dle_size wde_size4; - const struct rtw89_dle_size wde_size6; -+ const struct rtw89_dle_size wde_size7; - const struct rtw89_dle_size wde_size9; - const struct rtw89_dle_size wde_size18; - const struct rtw89_dle_size wde_size19; -@@ -806,6 +807,7 @@ struct rtw89_mac_size_set { - const struct rtw89_wde_quota wde_qt0; - const struct rtw89_wde_quota wde_qt4; - const struct rtw89_wde_quota wde_qt6; -+ const struct rtw89_wde_quota wde_qt7; - const struct rtw89_wde_quota wde_qt17; - const struct rtw89_wde_quota wde_qt18; - const struct rtw89_ple_quota ple_qt4; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -18,25 +18,25 @@ - RTW8852B_FW_BASENAME "-" __stringify(RTW8852B_FW_FORMAT_MAX) ".bin" - - static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = { -- {5, 343, grp_0}, /* ACH 0 */ -- {5, 343, grp_0}, /* ACH 1 */ -- {5, 343, grp_0}, /* ACH 2 */ -- {5, 343, grp_0}, /* ACH 3 */ -+ {5, 341, grp_0}, /* ACH 0 */ -+ {5, 341, grp_0}, /* ACH 1 */ -+ {4, 342, grp_0}, /* ACH 2 */ -+ {4, 342, grp_0}, /* ACH 3 */ - {0, 0, grp_0}, /* ACH 4 */ - {0, 0, grp_0}, /* ACH 5 */ - {0, 0, grp_0}, /* ACH 6 */ - {0, 0, grp_0}, /* ACH 7 */ -- {4, 344, grp_0}, /* B0MGQ */ -- {4, 344, grp_0}, /* B0HIQ */ -+ {4, 342, grp_0}, /* B0MGQ */ -+ {4, 342, grp_0}, /* B0HIQ */ - {0, 0, grp_0}, /* B1MGQ */ - {0, 0, grp_0}, /* B1HIQ */ - {40, 0, 0} /* FWCMDQ */ - }; - - static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_pcie = { -- 448, /* Group 0 */ -+ 446, /* Group 0 */ - 0, /* Group 1 */ -- 448, /* Public Max */ -+ 446, /* Public Max */ - 0 /* WP threshold */ - }; - -@@ -49,13 +49,13 @@ static const struct rtw89_hfc_param_ini - }; - - static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { -- [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, -- &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -- &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, -+ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size7, -+ &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7, -+ &rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18, - &rtw89_mac_size.ple_qt58}, -- [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size6, -- &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, -- &rtw89_mac_size.wde_qt6, &rtw89_mac_size.ple_qt18, -+ [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size7, -+ &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7, -+ &rtw89_mac_size.wde_qt7, &rtw89_mac_size.ple_qt18, - &rtw89_mac_size.ple_qt_52b_wow}, - [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9, - &rtw89_mac_size.ple_size8, &rtw89_mac_size.wde_qt4, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-094-wifi-rtw89-8851b-add-to-read-efuse-version-to-recogn.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-094-wifi-rtw89-8851b-add-to-read-efuse-version-to-recogn.patch deleted file mode 100644 index 8d5cee33f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-094-wifi-rtw89-8851b-add-to-read-efuse-version-to-recogn.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 40bb2ab49c369b78d1cb37ed63b8a85f3102b239 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:15 +0800 -Subject: [PATCH 094/136] wifi: rtw89: 8851b: add to read efuse version to - recognize hardware version B - -8851B hardware version A and B use different firmware, but register version -code of these two are the same, so add this helper to read efuse version to -determine which version is installed. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/efuse.c | 21 +++++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/efuse.h | 1 + - 2 files changed, 22 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/efuse.c -+++ b/drivers/net/wireless/realtek/rtw89/efuse.c -@@ -7,6 +7,10 @@ - #include "mac.h" - #include "reg.h" - -+#define EF_FV_OFSET 0x5ea -+#define EF_CV_MASK GENMASK(7, 4) -+#define EF_CV_INV 15 -+ - enum rtw89_efuse_bank { - RTW89_EFUSE_BANK_WIFI, - RTW89_EFUSE_BANK_BT, -@@ -328,3 +332,20 @@ out_free: - - return ret; - } -+ -+int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv) -+{ -+ int ret; -+ u8 val; -+ -+ ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false); -+ if (ret) -+ return ret; -+ -+ *ecv = u8_get_bits(val, EF_CV_MASK); -+ if (*ecv == EF_CV_INV) -+ return -ENOENT; -+ -+ return 0; -+} -+EXPORT_SYMBOL(rtw89_read_efuse_ver); ---- a/drivers/net/wireless/realtek/rtw89/efuse.h -+++ b/drivers/net/wireless/realtek/rtw89/efuse.h -@@ -9,5 +9,6 @@ - - int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev); - int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev); -+int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv); - - #endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-095-wifi-rtw89-8851b-configure-GPIO-according-to-RFE-typ.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-095-wifi-rtw89-8851b-configure-GPIO-according-to-RFE-typ.patch deleted file mode 100644 index cee970fae..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-095-wifi-rtw89-8851b-configure-GPIO-according-to-RFE-typ.patch +++ /dev/null @@ -1,194 +0,0 @@ -From f03bd0429f9bc2718ee250b05eb48dc081d4f6b7 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:16 +0800 -Subject: [PATCH 095/136] wifi: rtw89: 8851b: configure GPIO according to RFE - type - -Though 8851BE is a 1x1 chip, but it has two antenna hardware module that -needs additional configuration to help choose antenna we are going to use. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 9 +++ - drivers/net/wireless/realtek/rtw89/phy.c | 1 + - drivers/net/wireless/realtek/rtw89/reg.h | 9 +++ - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 64 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 7 files changed, 86 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -2799,6 +2799,7 @@ struct rtw89_chip_ops { - int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map); - int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); - void (*fem_setup)(struct rtw89_dev *rtwdev); -+ void (*rfe_gpio)(struct rtw89_dev *rtwdev); - void (*rfk_init)(struct rtw89_dev *rtwdev); - void (*rfk_channel)(struct rtw89_dev *rtwdev); - void (*rfk_band_changed)(struct rtw89_dev *rtwdev, -@@ -4700,6 +4701,14 @@ static inline void rtw89_chip_fem_setup( - chip->ops->fem_setup(rtwdev); - } - -+static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ -+ if (chip->ops->rfe_gpio) -+ chip->ops->rfe_gpio(rtwdev); -+} -+ - static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev) - { - const struct rtw89_chip_info *chip = rtwdev->chip; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -4399,6 +4399,7 @@ void rtw89_phy_dm_init(struct rtw89_dev - rtw89_phy_cfo_init(rtwdev); - rtw89_phy_ul_tb_info_init(rtwdev); - rtw89_phy_antdiv_init(rtwdev); -+ rtw89_chip_rfe_gpio(rtwdev); - rtw89_phy_antdiv_set_ant(rtwdev); - - rtw89_phy_init_rf_nctl(rtwdev); ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -254,6 +254,10 @@ - #define R_AX_EECS_EESK_FUNC_SEL 0x02D8 - #define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4) - -+#define R_AX_GPIO16_23_FUNC_SEL 0x02D8 -+#define B_AX_PINMUX_GPIO17_FUNC_SEL_MASK GENMASK(7, 4) -+#define B_AX_PINMUX_GPIO16_FUNC_SEL_MASK GENMASK(3, 0) -+ - #define R_AX_LED1_FUNC_SEL 0x02DC - #define B_AX_PINMUX_EESK_FUNC_SEL_V1_MASK GENMASK(27, 24) - #define PINMUX_EESK_FUNC_SEL_BT_LOG 0x1 -@@ -3846,6 +3850,7 @@ - #define R_RFE_E_A2 0x0334 - #define R_RFE_O_SEL_A2 0x0338 - #define R_RFE_SEL0_A2 0x033C -+#define B_RFE_SEL0_MASK GENMASK(1, 0) - #define R_RFE_SEL32_A2 0x0340 - #define R_CIRST 0x035c - #define B_CIRST_SYN GENMASK(11, 10) -@@ -4490,6 +4495,10 @@ - #define B_P0_ANTSEL_RX_ORI GENMASK(7, 4) - #define R_RFSW_CTRL_ANT0_BASE 0x5870 - #define B_RFSW_CTRL_ANT_MAPPING GENMASK(15, 0) -+#define R_RFE_SEL0_BASE 0x5880 -+#define B_RFE_SEL0_SRC_MASK GENMASK(3, 0) -+#define RFE_SEL0_SRC_ANTSEL_0 8 -+#define R_RFE_INV0 0x5890 - #define R_P0_RFM 0x5894 - #define B_P0_RFM_DIS_WL BIT(7) - #define B_P0_RFM_TX_OPT BIT(6) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -72,8 +72,72 @@ static const struct rtw89_xtal_info rtw8 - .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, - }; - -+static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv, -+ u8 src_sel) -+{ -+ u32 addr, mask; -+ -+ if (gpio_idx >= 32) -+ return; -+ -+ /* 2 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 2 bits */ -+ addr = R_RFE_SEL0_A2 + (gpio_idx / 16) * sizeof(u32); -+ mask = B_RFE_SEL0_MASK << (gpio_idx % 16) * 2; -+ -+ rtw89_phy_write32_mask(rtwdev, addr, mask, RF_PATH_A); -+ rtw89_phy_write32_mask(rtwdev, R_RFE_INV0, BIT(gpio_idx), inv); -+ -+ /* 4 continual 32-bit registers for 32 GPIOs, and each GPIO occupies 4 bits */ -+ addr = R_RFE_SEL0_BASE + (gpio_idx / 8) * sizeof(u32); -+ mask = B_RFE_SEL0_SRC_MASK << (gpio_idx % 8) * 4; -+ -+ rtw89_phy_write32_mask(rtwdev, addr, mask, src_sel); -+} -+ -+static void rtw8851b_set_mac_gpio(struct rtw89_dev *rtwdev, u8 func) -+{ -+ static const struct rtw89_reg3_def func16 = { -+ R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO16_FUNC_SEL_MASK, BIT(3) -+ }; -+ static const struct rtw89_reg3_def func17 = { -+ R_AX_GPIO16_23_FUNC_SEL, B_AX_PINMUX_GPIO17_FUNC_SEL_MASK, BIT(7) >> 4, -+ }; -+ const struct rtw89_reg3_def *def; -+ -+ switch (func) { -+ case 16: -+ def = &func16; -+ break; -+ case 17: -+ def = &func17; -+ break; -+ default: -+ rtw89_warn(rtwdev, "undefined gpio func %d\n", func); -+ return; -+ } -+ -+ rtw89_write8_mask(rtwdev, def->addr, def->mask, def->data); -+} -+ -+static void rtw8851b_rfe_gpio(struct rtw89_dev *rtwdev) -+{ -+ u8 rfe_type = rtwdev->efuse.rfe_type; -+ -+ if (rfe_type > 50) -+ return; -+ -+ if (rfe_type % 3 == 2) { -+ rtw8851b_set_bb_gpio(rtwdev, 16, true, RFE_SEL0_SRC_ANTSEL_0); -+ rtw8851b_set_bb_gpio(rtwdev, 17, false, RFE_SEL0_SRC_ANTSEL_0); -+ -+ rtw8851b_set_mac_gpio(rtwdev, 16); -+ rtw8851b_set_mac_gpio(rtwdev, 17); -+ } -+} -+ - static const struct rtw89_chip_ops rtw8851b_chip_ops = { - .fem_setup = NULL, -+ .rfe_gpio = rtw8851b_rfe_gpio, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .h2c_dctl_sec_cam = NULL, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2032,6 +2032,7 @@ static const struct rtw89_chip_ops rtw88 - .read_efuse = rtw8852a_read_efuse, - .read_phycap = rtw8852a_read_phycap, - .fem_setup = rtw8852a_fem_setup, -+ .rfe_gpio = NULL, - .rfk_init = rtw8852a_rfk_init, - .rfk_channel = rtw8852a_rfk_channel, - .rfk_band_changed = rtw8852a_rfk_band_changed, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2454,6 +2454,7 @@ static const struct rtw89_chip_ops rtw88 - .read_efuse = rtw8852b_read_efuse, - .read_phycap = rtw8852b_read_phycap, - .fem_setup = NULL, -+ .rfe_gpio = NULL, - .rfk_init = rtw8852b_rfk_init, - .rfk_channel = rtw8852b_rfk_channel, - .rfk_band_changed = rtw8852b_rfk_band_changed, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2762,6 +2762,7 @@ static const struct rtw89_chip_ops rtw88 - .read_efuse = rtw8852c_read_efuse, - .read_phycap = rtw8852c_read_phycap, - .fem_setup = NULL, -+ .rfe_gpio = NULL, - .rfk_init = rtw8852c_rfk_init, - .rfk_channel = rtw8852c_rfk_channel, - .rfk_band_changed = rtw8852c_rfk_band_changed, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-096-wifi-rtw89-8851b-add-BT-coexistence-support-function.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-096-wifi-rtw89-8851b-add-BT-coexistence-support-function.patch deleted file mode 100644 index e7c42f6d5..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-096-wifi-rtw89-8851b-add-BT-coexistence-support-function.patch +++ /dev/null @@ -1,421 +0,0 @@ -From 4885b17ebb92b3cc54e1064ffe52f688ca83d5c7 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:17 +0800 -Subject: [PATCH 096/136] wifi: rtw89: 8851b: add BT coexistence support - function - -Add 8851B specific parameters of BT coexistence. Since 8851B has special -two antenna hardware module with antenna diversity, BT coexistence needs -to recognize this, so add some fields to store these information for -further use. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/coex.c | 7 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 357 ++++++++++++++++++ - 2 files changed, 364 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -127,6 +127,13 @@ static const u32 cxtbl[] = { - - static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { - /* firmware version must be in decreasing order for each chip */ -+ {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), -+ .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, -+ .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, -+ .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, -+ .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, -+ .info_buf = 1800, .max_role_num = 6, -+ }, - {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), - .fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3, - .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -72,6 +72,52 @@ static const struct rtw89_xtal_info rtw8 - .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, - }; - -+static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_ul[] = { -+ {255, 0, 0, 7}, /* 0 -> original */ -+ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ -+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {6, 1, 0, 7}, -+ {13, 1, 0, 7}, -+ {13, 1, 0, 7} -+}; -+ -+static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_dl[] = { -+ {255, 0, 0, 7}, /* 0 -> original */ -+ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ -+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ -+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ -+ {255, 1, 0, 7}, -+ {255, 1, 0, 7}, -+ {255, 1, 0, 7} -+}; -+ -+static const struct rtw89_btc_fbtc_mreg rtw89_btc_8851b_mon_reg[] = { -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200), -+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4738), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4688), -+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4694), -+}; -+ -+static const u8 rtw89_btc_8851b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; -+static const u8 rtw89_btc_8851b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; -+ - static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv, - u8 src_sel) - { -@@ -135,12 +181,313 @@ static void rtw8851b_rfe_gpio(struct rtw - } - } - -+static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_module *module = &btc->mdinfo; -+ -+ module->rfe_type = rtwdev->efuse.rfe_type; -+ module->cv = rtwdev->hal.cv; -+ module->bt_solo = 0; -+ module->switch_type = BTC_SWITCH_INTERNAL; -+ module->ant.isolation = 10; -+ module->kt_ver_adie = rtwdev->hal.acv; -+ -+ if (module->rfe_type == 0) -+ return; -+ -+ /* rfe_type 3*n+1: 1-Ant(shared), -+ * 3*n+2: 2-Ant+Div(non-shared), -+ * 3*n+3: 2-Ant+no-Div(non-shared) -+ */ -+ module->ant.num = (module->rfe_type % 3 == 1) ? 1 : 2; -+ /* WL-1ss at S0, btg at s0 (On 1 WL RF) */ -+ module->ant.single_pos = RF_PATH_A; -+ module->ant.btg_pos = RF_PATH_A; -+ module->ant.stream_cnt = 1; -+ -+ if (module->ant.num == 1) { -+ module->ant.type = BTC_ANT_SHARED; -+ module->bt_pos = BTC_BT_BTG; -+ module->wa_type = 1; -+ module->ant.diversity = 0; -+ } else { /* ant.num == 2 */ -+ module->ant.type = BTC_ANT_DEDICATED; -+ module->bt_pos = BTC_BT_ALONE; -+ module->switch_type = BTC_SWITCH_EXTERNAL; -+ module->wa_type = 0; -+ if (module->rfe_type % 3 == 2) -+ module->ant.diversity = 1; -+ } -+} -+ -+static -+void rtw8851b_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) -+{ -+ if (group > BTC_BT_SS_GROUP) -+ group--; /* Tx-group=1, Rx-group=2 */ -+ -+ if (rtwdev->btc.mdinfo.ant.type == BTC_ANT_SHARED) /* 1-Ant */ -+ group += 3; -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); -+} -+ -+static void rtw8851b_btc_init_cfg(struct rtw89_dev *rtwdev) -+{ -+ static const struct rtw89_mac_ax_coex coex_params = { -+ .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, -+ .direction = RTW89_MAC_AX_COEX_INNER, -+ }; -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_module *module = &btc->mdinfo; -+ struct rtw89_btc_ant_info *ant = &module->ant; -+ u8 path, path_min, path_max; -+ -+ /* PTA init */ -+ rtw89_mac_coex_init(rtwdev, &coex_params); -+ -+ /* set WL Tx response = Hi-Pri */ -+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); -+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); -+ -+ /* for 1-Ant && 1-ss case: only 1-path */ -+ if (ant->stream_cnt == 1) { -+ path_min = ant->single_pos; -+ path_max = path_min; -+ } else { -+ path_min = RF_PATH_A; -+ path_max = RF_PATH_B; -+ } -+ -+ for (path = path_min; path <= path_max; path++) { -+ /* set rf gnt-debug off */ -+ rtw89_write_rf(rtwdev, path, RR_WLSEL, RFREG_MASK, 0x0); -+ -+ /* set DEBUG_LUT_RFMODE_MASK = 1 to start trx-mask-setup */ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, BIT(17)); -+ -+ /* if GNT_WL=0 && BT=SS_group --> WL Tx/Rx = THRU */ -+ rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_SS_GROUP, 0x5ff); -+ -+ /* if GNT_WL=0 && BT=Rx_group --> WL-Rx = THRU + WL-Tx = MASK */ -+ rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_RX_GROUP, 0x5df); -+ -+ /* if GNT_WL = 0 && BT = Tx_group --> -+ * Shared-Ant && BTG-path:WL mask(0x55f), others:WL THRU(0x5ff) -+ */ -+ if (ant->type == BTC_ANT_SHARED && ant->btg_pos == path) -+ rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x55f); -+ else -+ rtw8851b_set_trx_mask(rtwdev, path, BTC_BT_TX_GROUP, 0x5ff); -+ -+ /* set DEBUG_LUT_RFMODE_MASK = 0 to stop trx-mask-setup */ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0); -+ } -+ -+ /* set PTA break table */ -+ rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); -+ -+ /* enable BT counter 0xda40[16,2] = 2b'11 */ -+ rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); -+ -+ btc->cx.wl.status.map.init_ok = true; -+} -+ -+static -+void rtw8851b_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) -+{ -+ u32 bitmap; -+ u32 reg; -+ -+ switch (map) { -+ case BTC_PRI_MASK_TX_RESP: -+ reg = R_BTC_BT_COEX_MSK_TABLE; -+ bitmap = B_BTC_PRI_MASK_TX_RESP_V1; -+ break; -+ case BTC_PRI_MASK_BEACON: -+ reg = R_AX_WL_PRI_MSK; -+ bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; -+ break; -+ case BTC_PRI_MASK_RX_CCK: -+ reg = R_BTC_BT_COEX_MSK_TABLE; -+ bitmap = B_BTC_PRI_MASK_RXCCK_V1; -+ break; -+ default: -+ return; -+ } -+ -+ if (state) -+ rtw89_write32_set(rtwdev, reg, bitmap); -+ else -+ rtw89_write32_clr(rtwdev, reg, bitmap); -+} -+ -+union rtw8851b_btc_wl_txpwr_ctrl { -+ u32 txpwr_val; -+ struct { -+ union { -+ u16 ctrl_all_time; -+ struct { -+ s16 data:9; -+ u16 rsvd:6; -+ u16 flag:1; -+ } all_time; -+ }; -+ union { -+ u16 ctrl_gnt_bt; -+ struct { -+ s16 data:9; -+ u16 rsvd:7; -+ } gnt_bt; -+ }; -+ }; -+} __packed; -+ -+static void -+rtw8851b_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) -+{ -+ union rtw8851b_btc_wl_txpwr_ctrl arg = { .txpwr_val = txpwr_val }; -+ s32 val; -+ -+#define __write_ctrl(_reg, _msk, _val, _en, _cond) \ -+do { \ -+ u32 _wrt = FIELD_PREP(_msk, _val); \ -+ BUILD_BUG_ON(!!(_msk & _en)); \ -+ if (_cond) \ -+ _wrt |= _en; \ -+ else \ -+ _wrt &= ~_en; \ -+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, _reg, \ -+ _msk | _en, _wrt); \ -+} while (0) -+ -+ switch (arg.ctrl_all_time) { -+ case 0xffff: -+ val = 0; -+ break; -+ default: -+ val = arg.all_time.data; -+ break; -+ } -+ -+ __write_ctrl(R_AX_PWR_RATE_CTRL, B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, -+ val, B_AX_FORCE_PWR_BY_RATE_EN, -+ arg.ctrl_all_time != 0xffff); -+ -+ switch (arg.ctrl_gnt_bt) { -+ case 0xffff: -+ val = 0; -+ break; -+ default: -+ val = arg.gnt_bt.data; -+ break; -+ } -+ -+ __write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val, -+ B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff); -+ -+#undef __write_ctrl -+} -+ -+static -+s8 rtw8851b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) -+{ -+ val = clamp_t(s8, val, -100, 0) + 100; -+ val = min(val + 6, 100); /* compensate offset */ -+ -+ return val; -+} -+ -+static -+void rtw8851b_btc_update_bt_cnt(struct rtw89_dev *rtwdev) -+{ -+ /* Feature move to firmware */ -+} -+ -+static void rtw8851b_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) -+{ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_ant_info *ant = &btc->mdinfo.ant; -+ -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWE, RFREG_MASK, 0x80000); -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWA, RFREG_MASK, 0x1); -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWD1, RFREG_MASK, 0x110); -+ -+ /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ -+ if (state) -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWD0, RFREG_MASK, 0x179c); -+ else -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWD0, RFREG_MASK, 0x208); -+ -+ rtw89_write_rf(rtwdev, ant->btg_pos, RR_LUTWE, RFREG_MASK, 0x0); -+} -+ -+#define LNA2_51B_MA 0x700 -+ -+static const struct rtw89_reg2_def btc_8851b_rf_0[] = {{0x2, 0x0}}; -+static const struct rtw89_reg2_def btc_8851b_rf_1[] = {{0x2, 0x1}}; -+ -+static void rtw8851b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) -+{ -+ /* To improve BT ACI in co-rx -+ * level=0 Default: TIA 1/0= (LNA2,TIAN6) = (7,1)/(5,1) = 21dB/12dB -+ * level=1 Fix LNA2=5: TIA 1/0= (LNA2,TIAN6) = (5,0)/(5,1) = 18dB/12dB -+ */ -+ struct rtw89_btc *btc = &rtwdev->btc; -+ struct rtw89_btc_ant_info *ant = &btc->mdinfo.ant; -+ const struct rtw89_reg2_def *rf; -+ u32 n, i, val; -+ -+ switch (level) { -+ case 0: /* original */ -+ default: -+ btc->dm.wl_lna2 = 0; -+ break; -+ case 1: /* for FDD free-run */ -+ btc->dm.wl_lna2 = 0; -+ break; -+ case 2: /* for BTG Co-Rx*/ -+ btc->dm.wl_lna2 = 1; -+ break; -+ } -+ -+ if (btc->dm.wl_lna2 == 0) { -+ rf = btc_8851b_rf_0; -+ n = ARRAY_SIZE(btc_8851b_rf_0); -+ } else { -+ rf = btc_8851b_rf_1; -+ n = ARRAY_SIZE(btc_8851b_rf_1); -+ } -+ -+ for (i = 0; i < n; i++, rf++) { -+ val = rf->data; -+ /* bit[10] = 1 if non-shared-ant for 8851b */ -+ if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED) -+ val |= 0x4; -+ -+ rtw89_write_rf(rtwdev, ant->btg_pos, rf->addr, LNA2_51B_MA, val); -+ } -+} -+ - static const struct rtw89_chip_ops rtw8851b_chip_ops = { - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .h2c_dctl_sec_cam = NULL, -+ -+ .btc_set_rfe = rtw8851b_btc_set_rfe, -+ .btc_init_cfg = rtw8851b_btc_init_cfg, -+ .btc_set_wl_pri = rtw8851b_btc_set_wl_pri, -+ .btc_set_wl_txpwr_ctrl = rtw8851b_btc_set_wl_txpwr_ctrl, -+ .btc_get_bt_rssi = rtw8851b_btc_get_bt_rssi, -+ .btc_update_bt_cnt = rtw8851b_btc_update_bt_cnt, -+ .btc_wl_s1_standby = rtw8851b_btc_wl_s1_standby, -+ .btc_set_wl_rx_gain = rtw8851b_btc_set_wl_rx_gain, -+ .btc_set_policy = rtw89_btc_set_policy_v1, - }; - - #ifdef CONFIG_PM -@@ -213,6 +560,16 @@ const struct rtw89_chip_info rtw8851b_ch - .scbd = 0x1, - .mailbox = 0x1, - -+ .afh_guard_ch = 6, -+ .wl_rssi_thres = rtw89_btc_8851b_wl_rssi_thres, -+ .bt_rssi_thres = rtw89_btc_8851b_bt_rssi_thres, -+ .rssi_tol = 2, -+ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8851b_mon_reg), -+ .mon_reg = rtw89_btc_8851b_mon_reg, -+ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8851b_rf_ul), -+ .rf_para_ulink = rtw89_btc_8851b_rf_ul, -+ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8851b_rf_dl), -+ .rf_para_dlink = rtw89_btc_8851b_rf_dl, - .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | - BIT(RTW89_PS_MODE_CLK_GATED), - .low_power_hci_modes = 0, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-097-wifi-rtw89-8851b-add-basic-power-on-function.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-097-wifi-rtw89-8851b-add-basic-power-on-function.patch deleted file mode 100644 index 566633a35..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-097-wifi-rtw89-8851b-add-basic-power-on-function.patch +++ /dev/null @@ -1,452 +0,0 @@ -From 31df6df89f9394bc544a4ebad62584d56bff1677 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:18 +0800 -Subject: [PATCH 097/136] wifi: rtw89: 8851b: add basic power on function - -Add basic functions to power on chip and enable and access BB/RF, as -well as reset and hardware settings of BB. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac.h | 2 + - drivers/net/wireless/realtek/rtw89/reg.h | 17 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 327 ++++++++++++++++++ - 3 files changed, 346 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/mac.h -+++ b/drivers/net/wireless/realtek/rtw89/mac.h -@@ -1118,6 +1118,8 @@ enum rtw89_mac_xtal_si_offset { - XTAL_SI_PWR_CUT = 0x10, - #define XTAL_SI_SMALL_PWR_CUT BIT(0) - #define XTAL_SI_BIG_PWR_CUT BIT(1) -+ XTAL_SI_XTAL_DRV = 0x15, -+#define XTAL_SI_DRV_LATCH BIT(4) - XTAL_SI_XTAL_XMD_2 = 0x24, - #define XTAL_SI_LDO_LPS GENMASK(6, 4) - XTAL_SI_XTAL_XMD_4 = 0x26, ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -19,6 +19,8 @@ - #define B_AX_FEN_BBRSTB BIT(0) - - #define R_AX_SYS_PW_CTRL 0x0004 -+#define B_AX_SOP_ASWRM BIT(31) -+#define B_AX_SOP_PWMM_DSWR BIT(29) - #define B_AX_XTAL_OFF_A_DIE BIT(22) - #define B_AX_DIS_WLBT_PDNSUSEN_SOPC BIT(18) - #define B_AX_RDY_SYSPWR BIT(17) -@@ -134,6 +136,8 @@ - #define B_AX_PLATFORM_EN BIT(0) - - #define R_AX_WLLPS_CTRL 0x0090 -+#define B_AX_LPSOP_ASWRM BIT(17) -+#define B_AX_LPSOP_DSWRM BIT(9) - #define B_AX_DIS_WLBT_LPSEN_LOPC BIT(1) - #define SW_LPS_OPTION 0x0001A0B2 - -@@ -222,9 +226,14 @@ - #define B_AX_OCP_L1_MASK GENMASK(15, 13) - #define B_AX_VOL_L1_MASK GENMASK(3, 0) - -+#define R_AX_SPSLDO_ON_CTRL1 0x0204 -+#define B_AX_FPWMDELAY BIT(3) -+ - #define R_AX_LDO_AON_CTRL0 0x0218 - #define B_AX_PD_REGU_L BIT(16) - -+#define R_AX_SPSANA_ON_CTRL1 0x0224 -+ - #define R_AX_WLAN_XTAL_SI_CTRL 0x0270 - #define B_AX_WL_XTAL_SI_CMD_POLL BIT(31) - #define B_AX_BT_XTAL_SI_ERR_FLAG BIT(30) -@@ -237,6 +246,9 @@ - #define B_AX_WL_XTAL_SI_DATA_MASK GENMASK(15, 8) - #define B_AX_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0) - -+#define R_AX_WLAN_XTAL_SI_CONFIG 0x0274 -+#define B_AX_XTAL_SI_ADDR_NOT_CHK BIT(0) -+ - #define R_AX_XTAL_ON_CTRL0 0x0280 - #define B_AX_XTAL_SC_LPS BIT(31) - #define B_AX_XTAL_SC_XO_MASK GENMASK(23, 17) -@@ -267,6 +279,10 @@ - #define B_AX_EESK_PULL_LOW_EN BIT(17) - #define B_AX_EECS_PULL_LOW_EN BIT(16) - -+#define R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN 0x02E4 -+#define B_AX_GPIO16_PULL_LOW_EN_V1 BIT(19) -+#define B_AX_GPIO10_PULL_LOW_EN BIT(10) -+ - #define R_AX_WLRF_CTRL 0x02F0 - #define B_AX_AFC_AFEDIG BIT(17) - #define B_AX_WLRF1_CTRL_7 BIT(15) -@@ -4497,6 +4513,7 @@ - #define B_RFSW_CTRL_ANT_MAPPING GENMASK(15, 0) - #define R_RFE_SEL0_BASE 0x5880 - #define B_RFE_SEL0_SRC_MASK GENMASK(3, 0) -+#define R_RFE_SEL32_BASE 0x5884 - #define RFE_SEL0_SRC_ANTSEL_0 8 - #define R_RFE_INV0 0x5890 - #define R_P0_RFM 0x5894 ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -3,6 +3,7 @@ - */ - - #include "coex.h" -+#include "efuse.h" - #include "fw.h" - #include "mac.h" - #include "phy.h" -@@ -118,6 +119,182 @@ static const struct rtw89_btc_fbtc_mreg - static const u8 rtw89_btc_8851b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40}; - static const u8 rtw89_btc_8851b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; - -+static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev) -+{ -+ u32 val32; -+ u8 val8; -+ u32 ret; -+ -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | -+ B_AX_AFSM_PCIE_SUS_EN); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC); -+ rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR, -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC), -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ -+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI, -+ XTAL_SI_OFF_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI, -+ XTAL_SI_OFF_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI, -+ XTAL_SI_PON_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI, -+ XTAL_SI_PON_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_DRV, 0, XTAL_SI_DRV_LATCH); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); -+ -+ fsleep(1000); -+ -+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); -+ rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); -+ rtw89_write32_set(rtwdev, R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN, -+ B_AX_GPIO10_PULL_LOW_EN | B_AX_GPIO16_PULL_LOW_EN_V1); -+ -+ if (rtwdev->hal.cv == CHIP_CAV) { -+ ret = rtw89_read_efuse_ver(rtwdev, &val8); -+ if (!ret) -+ rtwdev->hal.cv = val8; -+ } -+ -+ rtw89_write32_clr(rtwdev, R_AX_WLAN_XTAL_SI_CONFIG, -+ B_AX_XTAL_SI_ADDR_NOT_CHK); -+ if (rtwdev->hal.cv != CHIP_CAV) { -+ rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL1, B_AX_FPWMDELAY); -+ rtw89_write32_set(rtwdev, R_AX_SPSANA_ON_CTRL1, B_AX_FPWMDELAY); -+ } -+ -+ rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, -+ B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | -+ B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN | -+ B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN | -+ B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN | -+ B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN | -+ B_AX_DMACREG_GCKEN); -+ rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN, -+ B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | -+ B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | -+ B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN | -+ B_AX_RMAC_EN); -+ -+ rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL, B_AX_PINMUX_EESK_FUNC_SEL_MASK, -+ PINMUX_EESK_FUNC_SEL_BT_LOG); -+ -+ return 0; -+} -+ -+static void rtw8851b_patch_swr_pfm2pwm(struct rtw89_dev *rtwdev) -+{ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_PWMM_DSWR); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_ASWRM); -+ rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_LPSOP_DSWRM); -+ rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_LPSOP_ASWRM); -+} -+ -+static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev) -+{ -+ u32 val32; -+ u32 ret; -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF, -+ XTAL_SI_RFC2RF); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC, -+ XTAL_SI_SRAM2RFC); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI); -+ if (ret) -+ return ret; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI); -+ if (ret) -+ return ret; -+ -+ rtw89_write32_set(rtwdev, R_AX_WLAN_XTAL_SI_CONFIG, -+ B_AX_XTAL_SI_ADDR_NOT_CHK); -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); -+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); -+ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB); -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC); -+ -+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC), -+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL); -+ if (ret) -+ return ret; -+ -+ rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); -+ -+ if (rtwdev->hal.cv == CHIP_CAV) { -+ rtw8851b_patch_swr_pfm2pwm(rtwdev); -+ } else { -+ rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL1, B_AX_FPWMDELAY); -+ rtw89_write32_set(rtwdev, R_AX_SPSANA_ON_CTRL1, B_AX_FPWMDELAY); -+ } -+ -+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); -+ -+ return 0; -+} -+ - static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv, - u8 src_sel) - { -@@ -181,6 +358,96 @@ static void rtw8851b_rfe_gpio(struct rtw - } - } - -+static void rtw8851b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ fsleep(1); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+} -+ -+static void rtw8851b_bb_reset(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, -+ B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x1); -+ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); -+ rtw8851b_bb_reset_all(rtwdev, phy_idx); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, -+ B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x3); -+ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); -+} -+ -+static -+void rtw8851b_bb_gpio_trsw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ u8 tx_path_en, u8 trsw_tx, -+ u8 trsw_rx, u8 trsw_a, u8 trsw_b) -+{ -+ u32 mask_ofst = 16; -+ u32 val; -+ -+ if (path != RF_PATH_A) -+ return; -+ -+ mask_ofst += (tx_path_en * 4 + trsw_tx * 2 + trsw_rx) * 2; -+ val = u32_encode_bits(trsw_a, B_P0_TRSW_A) | -+ u32_encode_bits(trsw_b, B_P0_TRSW_B); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TRSW, -+ (B_P0_TRSW_A | B_P0_TRSW_B) << mask_ofst, val); -+} -+ -+static void rtw8851b_bb_gpio_init(struct rtw89_dev *rtwdev) -+{ -+ rtw89_phy_write32_set(rtwdev, R_P0_TRSW, B_P0_TRSW_A); -+ rtw89_phy_write32_clr(rtwdev, R_P0_TRSW, B_P0_TRSW_X); -+ rtw89_phy_write32_clr(rtwdev, R_P0_TRSW, B_P0_TRSW_SO_A2); -+ rtw89_phy_write32(rtwdev, R_RFE_SEL0_BASE, 0x77777777); -+ rtw89_phy_write32(rtwdev, R_RFE_SEL32_BASE, 0x77777777); -+ -+ rtw89_phy_write32(rtwdev, R_RFE_E_A2, 0xffffffff); -+ rtw89_phy_write32(rtwdev, R_RFE_O_SEL_A2, 0); -+ rtw89_phy_write32(rtwdev, R_RFE_SEL0_A2, 0); -+ rtw89_phy_write32(rtwdev, R_RFE_SEL32_A2, 0); -+ -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 0, 0, 1); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 0, 1, 1, 0); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 0, 1, 0); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 0, 1, 1, 1, 0); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 0, 0, 1); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 0, 1, 1, 0); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 0, 1, 0); -+ rtw8851b_bb_gpio_trsw(rtwdev, RF_PATH_A, 1, 1, 1, 1, 0); -+} -+ -+static void rtw8851b_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u32 addr; -+ -+ for (addr = R_AX_PWR_MACID_LMT_TABLE0; -+ addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) -+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); -+} -+ -+static void rtw8851b_bb_sethw(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ -+ rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); -+ -+ rtw8851b_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); -+ rtw8851b_bb_gpio_init(rtwdev); -+ -+ /* read these registers after loading BB parameters */ -+ gain->offset_base[RTW89_PHY_0] = -+ rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK); -+ gain->rssi_base[RTW89_PHY_0] = -+ rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); -+} -+ - static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -472,9 +739,69 @@ static void rtw8851b_btc_set_wl_rx_gain( - } - } - -+static int rtw8851b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) -+{ -+ int ret; -+ -+ rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, -+ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); -+ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); -+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); -+ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG); -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC7, -+ FULL_BIT_MASK); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC7, -+ FULL_BIT_MASK); -+ if (ret) -+ return ret; -+ -+ rtw89_write8(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_XYN_CYCLE); -+ -+ return 0; -+} -+ -+static int rtw8851b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) -+{ -+ u8 wl_rfc_s0; -+ u8 wl_rfc_s1; -+ int ret; -+ -+ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, -+ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); -+ -+ ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, &wl_rfc_s0); -+ if (ret) -+ return ret; -+ wl_rfc_s0 &= ~XTAL_SI_RF00S_EN; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, wl_rfc_s0, -+ FULL_BIT_MASK); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, &wl_rfc_s1); -+ if (ret) -+ return ret; -+ wl_rfc_s1 &= ~XTAL_SI_RF10S_EN; -+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, wl_rfc_s1, -+ FULL_BIT_MASK); -+ return ret; -+} -+ - static const struct rtw89_chip_ops rtw8851b_chip_ops = { -+ .enable_bb_rf = rtw8851b_mac_enable_bb_rf, -+ .disable_bb_rf = rtw8851b_mac_disable_bb_rf, -+ .bb_reset = rtw8851b_bb_reset, -+ .bb_sethw = rtw8851b_bb_sethw, -+ .read_rf = rtw89_phy_read_rf_v1, -+ .write_rf = rtw89_phy_write_rf_v1, - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, -+ .pwr_on_func = rtw8851b_pwr_on_func, -+ .pwr_off_func = rtw8851b_pwr_off_func, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .h2c_dctl_sec_cam = NULL, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-098-wifi-rtw89-8851b-add-set-channel-function.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-098-wifi-rtw89-8851b-add-set-channel-function.patch deleted file mode 100644 index fc7e2120f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-098-wifi-rtw89-8851b-add-set-channel-function.patch +++ /dev/null @@ -1,812 +0,0 @@ -From e948213fb8560f6d6af6058351758f13a35c9f8d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:19 +0800 -Subject: [PATCH 098/136] wifi: rtw89: 8851b: add set channel function - -Set MAC/BB/RF registers according to channel we are going to set. In -additional, certain channels or bands need more deals, such as enable CCK -in 2 GHz band, spur elimination at certain frequencies. - -The set channel helper is used to save/restore states before/after setting -channel, and does reset BB to prevent hardware getting stuck in abnormal -state during switching channel and receiving data. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 14 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 703 ++++++++++++++++++ - 2 files changed, 717 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3999,6 +3999,7 @@ - #define R_S0_HW_SI_DIS 0x1200 - #define B_S0_HW_SI_DIS_W_R_TRIG GENMASK(30, 28) - #define R_P0_RXCK 0x12A0 -+#define B_P0_RXCK_ADJ GENMASK(31, 23) - #define B_P0_RXCK_BW3 BIT(30) - #define B_P0_TXCK_ALL GENMASK(19, 12) - #define B_P0_RXCK_ON BIT(19) -@@ -4155,8 +4156,10 @@ - #define R_DCFO 0x4264 - #define B_DCFO GENMASK(7, 0) - #define R_SEG0CSI 0x42AC -+#define R_SEG0CSI_V1 0x42B0 - #define B_SEG0CSI_IDX GENMASK(10, 0) - #define R_SEG0CSI_EN 0x42C4 -+#define R_SEG0CSI_EN_V1 0x42C8 - #define B_SEG0CSI_EN BIT(23) - #define R_BSS_CLR_MAP 0x43ac - #define R_BSS_CLR_MAP_V1 0x43B0 -@@ -4388,6 +4391,12 @@ - #define B_PATH0_BT_BACKOFF_V1 GENMASK(23, 0) - #define R_PATH1_BT_BACKOFF_V1 0x4AEC - #define B_PATH1_BT_BACKOFF_V1 GENMASK(23, 0) -+#define R_PATH0_TX_CFR 0x4B30 -+#define B_PATH0_TX_CFR_LGC1 GENMASK(19, 10) -+#define B_PATH0_TX_CFR_LGC0 GENMASK(9, 0) -+#define R_PATH0_TX_POLAR_CLIPPING 0x4B3C -+#define B_PATH0_TX_POLAR_CLIPPING_LGC1 GENMASK(19, 16) -+#define B_PATH0_TX_POLAR_CLIPPING_LGC0 GENMASK(15, 12) - #define R_PATH0_FRC_FIR_TYPE_V1 0x4C00 - #define B_PATH0_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0) - #define R_PATH0_NOTCH 0x4C14 -@@ -4843,11 +4852,16 @@ - #define R_P0_CFCH_BW1 0xC0D8 - #define B_P0_CFCH_EX BIT(13) - #define B_P0_CFCH_BW1 GENMASK(8, 5) -+#define R_WDADC 0xC0E4 -+#define B_WDADC_SEL GENMASK(5, 4) - #define R_ADCMOD 0xC0E8 - #define B_ADCMOD_LP GENMASK(31, 16) -+#define R_DCIM 0xC0EC -+#define B_DCIM_FR GENMASK(14, 13) - #define R_ADDCK0D 0xC0F0 - #define B_ADDCK0D_VAL2 GENMASK(31, 26) - #define B_ADDCK0D_VAL GENMASK(25, 16) -+#define B_ADDCK_DS BIT(16) - #define R_ADDCK0 0xC0F4 - #define B_ADDCK0_TRG BIT(11) - #define B_ADDCK0_IQ BIT(10) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -9,6 +9,7 @@ - #include "phy.h" - #include "reg.h" - #include "rtw8851b.h" -+#include "rtw8851b_rfk.h" - #include "rtw8851b_rfk_table.h" - #include "rtw8851b_table.h" - #include "txrx.h" -@@ -358,6 +359,593 @@ static void rtw8851b_rfe_gpio(struct rtw - } - } - -+static void rtw8851b_set_channel_mac(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ u8 mac_idx) -+{ -+ u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx); -+ u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx); -+ u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); -+ u8 txsc20 = 0, txsc40 = 0; -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_80: -+ txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40); -+ fallthrough; -+ case RTW89_CHANNEL_WIDTH_40: -+ txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20); -+ break; -+ default: -+ break; -+ } -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); -+ rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); -+ rtw89_write32(rtwdev, sub_carr, txsc20); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); -+ rtw89_write32(rtwdev, sub_carr, 0); -+ break; -+ default: -+ break; -+ } -+ -+ if (chan->channel > 14) { -+ rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE); -+ rtw89_write8_set(rtwdev, chk_rate, -+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); -+ } else { -+ rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE); -+ rtw89_write8_clr(rtwdev, chk_rate, -+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); -+ } -+} -+ -+static const u32 rtw8851b_sco_barker_threshold[14] = { -+ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, -+ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 -+}; -+ -+static const u32 rtw8851b_sco_cck_threshold[14] = { -+ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, -+ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed -+}; -+ -+static void rtw8851b_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch) -+{ -+ u8 ch_element = primary_ch - 1; -+ -+ rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, -+ rtw8851b_sco_barker_threshold[ch_element]); -+ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, -+ rtw8851b_sco_cck_threshold[ch_element]); -+} -+ -+static u8 rtw8851b_sco_mapping(u8 central_ch) -+{ -+ if (central_ch == 1) -+ return 109; -+ else if (central_ch >= 2 && central_ch <= 6) -+ return 108; -+ else if (central_ch >= 7 && central_ch <= 10) -+ return 107; -+ else if (central_ch >= 11 && central_ch <= 14) -+ return 106; -+ else if (central_ch == 36 || central_ch == 38) -+ return 51; -+ else if (central_ch >= 40 && central_ch <= 58) -+ return 50; -+ else if (central_ch >= 60 && central_ch <= 64) -+ return 49; -+ else if (central_ch == 100 || central_ch == 102) -+ return 48; -+ else if (central_ch >= 104 && central_ch <= 126) -+ return 47; -+ else if (central_ch >= 128 && central_ch <= 151) -+ return 46; -+ else if (central_ch >= 153 && central_ch <= 177) -+ return 45; -+ else -+ return 0; -+} -+ -+struct rtw8851b_bb_gain { -+ u32 gain_g[BB_PATH_NUM_8851B]; -+ u32 gain_a[BB_PATH_NUM_8851B]; -+ u32 gain_mask; -+}; -+ -+static const struct rtw8851b_bb_gain bb_gain_lna[LNA_GAIN_NUM] = { -+ { .gain_g = {0x4678}, .gain_a = {0x45DC}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x4678}, .gain_a = {0x45DC}, -+ .gain_mask = 0xff000000 }, -+ { .gain_g = {0x467C}, .gain_a = {0x4660}, -+ .gain_mask = 0x000000ff }, -+ { .gain_g = {0x467C}, .gain_a = {0x4660}, -+ .gain_mask = 0x0000ff00 }, -+ { .gain_g = {0x467C}, .gain_a = {0x4660}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x467C}, .gain_a = {0x4660}, -+ .gain_mask = 0xff000000 }, -+ { .gain_g = {0x4680}, .gain_a = {0x4664}, -+ .gain_mask = 0x000000ff }, -+}; -+ -+static const struct rtw8851b_bb_gain bb_gain_tia[TIA_GAIN_NUM] = { -+ { .gain_g = {0x4680}, .gain_a = {0x4664}, -+ .gain_mask = 0x00ff0000 }, -+ { .gain_g = {0x4680}, .gain_a = {0x4664}, -+ .gain_mask = 0xff000000 }, -+}; -+ -+static void rtw8851b_set_gain_error(struct rtw89_dev *rtwdev, -+ enum rtw89_subband subband, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; -+ u8 gain_band = rtw89_subband_to_bb_gain_band(subband); -+ s32 val; -+ u32 reg; -+ u32 mask; -+ int i; -+ -+ for (i = 0; i < LNA_GAIN_NUM; i++) { -+ if (subband == RTW89_CH_2G) -+ reg = bb_gain_lna[i].gain_g[path]; -+ else -+ reg = bb_gain_lna[i].gain_a[path]; -+ -+ mask = bb_gain_lna[i].gain_mask; -+ val = gain->lna_gain[gain_band][path][i]; -+ rtw89_phy_write32_mask(rtwdev, reg, mask, val); -+ } -+ -+ for (i = 0; i < TIA_GAIN_NUM; i++) { -+ if (subband == RTW89_CH_2G) -+ reg = bb_gain_tia[i].gain_g[path]; -+ else -+ reg = bb_gain_tia[i].gain_a[path]; -+ -+ mask = bb_gain_tia[i].gain_mask; -+ val = gain->tia_gain[gain_band][path][i]; -+ rtw89_phy_write32_mask(rtwdev, reg, mask, val); -+ } -+} -+ -+static void rtw8851b_set_gain_offset(struct rtw89_dev *rtwdev, -+ enum rtw89_subband subband, -+ enum rtw89_phy_idx phy_idx) -+{ -+ static const u32 rssi_ofst_addr[] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1}; -+ static const u32 gain_err_addr[] = {R_P0_AGC_RSVD}; -+ struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain; -+ enum rtw89_gain_offset gain_ofdm_band; -+ s32 offset_ofdm, offset_cck; -+ s32 offset_a; -+ s32 tmp; -+ u8 path; -+ -+ if (!efuse_gain->comp_valid) -+ goto next; -+ -+ for (path = RF_PATH_A; path < BB_PATH_NUM_8851B; path++) { -+ tmp = efuse_gain->comp[path][subband]; -+ tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX); -+ rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp); -+ } -+ -+next: -+ if (!efuse_gain->offset_valid) -+ return; -+ -+ gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband); -+ -+ offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; -+ -+ tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2)); -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp); -+ -+ offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band]; -+ offset_cck = -efuse_gain->offset[RF_PATH_A][0]; -+ -+ tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0]; -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); -+ -+ tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0]; -+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX); -+ rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx); -+ -+ if (subband == RTW89_CH_2G) { -+ tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1); -+ tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1); -+ rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST, -+ B_RX_RPL_OFST_CCK_MASK, tmp); -+ } -+} -+ -+static -+void rtw8851b_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband) -+{ -+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; -+ u8 band = rtw89_subband_to_bb_gain_band(subband); -+ u32 val; -+ -+ val = u32_encode_bits(gain->rpl_ofst_20[band][RF_PATH_A], B_P0_RPL1_20_MASK) | -+ u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][0], B_P0_RPL1_40_MASK) | -+ u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][1], B_P0_RPL1_41_MASK); -+ val >>= B_P0_RPL1_SHIFT; -+ rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val); -+ -+ val = u32_encode_bits(gain->rpl_ofst_40[band][RF_PATH_A][2], B_P0_RTL2_42_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][0], B_P0_RTL2_80_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][1], B_P0_RTL2_81_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][10], B_P0_RTL2_8A_MASK); -+ rtw89_phy_write32(rtwdev, R_P0_RPL2, val); -+ rtw89_phy_write32(rtwdev, R_P1_RPL2, val); -+ -+ val = u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][2], B_P0_RTL3_82_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][3], B_P0_RTL3_83_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][4], B_P0_RTL3_84_MASK) | -+ u32_encode_bits(gain->rpl_ofst_80[band][RF_PATH_A][9], B_P0_RTL3_89_MASK); -+ rtw89_phy_write32(rtwdev, R_P0_RPL3, val); -+ rtw89_phy_write32(rtwdev, R_P1_RPL3, val); -+} -+ -+static void rtw8851b_ctrl_ch(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 subband = chan->subband_type; -+ u8 central_ch = chan->channel; -+ bool is_2g = central_ch <= 14; -+ u8 sco_comp; -+ -+ if (is_2g) -+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, -+ B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx); -+ else -+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1, -+ B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx); -+ /* SCO compensate FC setting */ -+ sco_comp = rtw8851b_sco_mapping(central_ch); -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx); -+ -+ if (chan->band_type == RTW89_BAND_6G) -+ return; -+ -+ /* CCK parameters */ -+ if (central_ch == 14) { -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc); -+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5); -+ } -+ -+ rtw8851b_set_gain_error(rtwdev, subband, RF_PATH_A); -+ rtw8851b_set_gain_offset(rtwdev, subband, phy_idx); -+ rtw8851b_set_rxsc_rpl_comp(rtwdev, subband); -+} -+ -+static void rtw8851b_bw_setting(struct rtw89_dev *rtwdev, u8 bw) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_MUL, 0xf); -+ rtw89_phy_write32_mask(rtwdev, R_ADCMOD, B_ADCMOD_LP, 0xa); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92); -+ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x1); -+ break; -+ case RTW89_CHANNEL_WIDTH_10: -+ rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0); -+ break; -+ default: -+ rtw89_warn(rtwdev, "Fail to set ADC\n"); -+ } -+} -+ -+static void rtw8851b_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, -+ enum rtw89_phy_idx phy_idx) -+{ -+ switch (bw) { -+ case RTW89_CHANNEL_WIDTH_5: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_10: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_20: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx); -+ break; -+ case RTW89_CHANNEL_WIDTH_40: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, -+ pri_ch, phy_idx); -+ /* CCK primary channel */ -+ if (pri_ch == RTW89_SC_20_UPPER) -+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); -+ -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, -+ pri_ch, phy_idx); -+ break; -+ default: -+ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, -+ pri_ch); -+ } -+ -+ rtw8851b_bw_setting(rtwdev, bw); -+} -+ -+static void rtw8851b_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en) -+{ -+ if (cck_en) { -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_PD_ARBITER_OFF, -+ B_PD_ARBITER_OFF, 0); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); -+ rtw89_phy_write32_mask(rtwdev, R_PD_ARBITER_OFF, -+ B_PD_ARBITER_OFF, 1); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0); -+ } -+} -+ -+static u32 rtw8851b_spur_freq(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan) -+{ -+ u8 center_chan = chan->channel; -+ -+ switch (chan->band_type) { -+ case RTW89_BAND_5G: -+ if (center_chan == 151 || center_chan == 153 || -+ center_chan == 155 || center_chan == 163) -+ return 5760; -+ else if (center_chan == 54 || center_chan == 58) -+ return 5280; -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */ -+#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */ -+#define MAX_TONE_NUM 2048 -+ -+static void rtw8851b_set_csi_tone_idx(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u32 spur_freq; -+ s32 freq_diff, csi_idx, csi_tone_idx; -+ -+ spur_freq = rtw8851b_spur_freq(rtwdev, chan); -+ if (spur_freq == 0) { -+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, -+ 0, phy_idx); -+ return; -+ } -+ -+ freq_diff = (spur_freq - chan->freq) * 1000000; -+ csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125); -+ s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx); -+ -+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_V1, B_SEG0CSI_IDX, -+ csi_tone_idx, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, 1, phy_idx); -+} -+ -+static const struct rtw89_nbi_reg_def rtw8851b_nbi_reg_def = { -+ .notch1_idx = {0x46E4, 0xFF}, -+ .notch1_frac_idx = {0x46E4, 0xC00}, -+ .notch1_en = {0x46E4, 0x1000}, -+ .notch2_idx = {0x47A4, 0xFF}, -+ .notch2_frac_idx = {0x47A4, 0xC00}, -+ .notch2_en = {0x47A4, 0x1000}, -+}; -+ -+static void rtw8851b_set_nbi_tone_idx(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan) -+{ -+ const struct rtw89_nbi_reg_def *nbi = &rtw8851b_nbi_reg_def; -+ s32 nbi_frac_idx, nbi_frac_tone_idx; -+ s32 nbi_idx, nbi_tone_idx; -+ bool notch2_chk = false; -+ u32 spur_freq, fc; -+ s32 freq_diff; -+ -+ spur_freq = rtw8851b_spur_freq(rtwdev, chan); -+ if (spur_freq == 0) { -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, -+ nbi->notch1_en.mask, 0); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, -+ nbi->notch2_en.mask, 0); -+ return; -+ } -+ -+ fc = chan->freq; -+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160) { -+ fc = (spur_freq > fc) ? fc + 40 : fc - 40; -+ if ((fc > spur_freq && -+ chan->channel < chan->primary_channel) || -+ (fc < spur_freq && -+ chan->channel > chan->primary_channel)) -+ notch2_chk = true; -+ } -+ -+ freq_diff = (spur_freq - fc) * 1000000; -+ nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, -+ &nbi_frac_idx); -+ -+ if (chan->band_width == RTW89_CHANNEL_WIDTH_20) { -+ s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx); -+ } else { -+ u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ? -+ 128 : 256; -+ -+ s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx); -+ } -+ nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, -+ CARRIER_SPACING_78_125); -+ -+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) { -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr, -+ nbi->notch2_idx.mask, nbi_tone_idx); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr, -+ nbi->notch2_frac_idx.mask, nbi_frac_tone_idx); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, -+ nbi->notch2_en.mask, 0); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, -+ nbi->notch2_en.mask, 1); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, -+ nbi->notch1_en.mask, 0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_idx.addr, -+ nbi->notch1_idx.mask, nbi_tone_idx); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_frac_idx.addr, -+ nbi->notch1_frac_idx.mask, nbi_frac_tone_idx); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, -+ nbi->notch1_en.mask, 0); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, -+ nbi->notch1_en.mask, 1); -+ rtw89_phy_write32_mask(rtwdev, nbi->notch2_en.addr, -+ nbi->notch2_en.mask, 0); -+ } -+} -+ -+static void rtw8851b_set_cfr(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) -+{ -+ if (chan->band_type == RTW89_BAND_2G && -+ chan->band_width == RTW89_CHANNEL_WIDTH_20 && -+ (chan->channel == 1 || chan->channel == 13)) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, -+ B_PATH0_TX_CFR_LGC0, 0xf8); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, -+ B_PATH0_TX_CFR_LGC1, 0x120); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, -+ B_PATH0_TX_POLAR_CLIPPING_LGC0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, -+ B_PATH0_TX_POLAR_CLIPPING_LGC1, 0x3); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, -+ B_PATH0_TX_CFR_LGC0, 0x120); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_CFR, -+ B_PATH0_TX_CFR_LGC1, 0x3ff); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, -+ B_PATH0_TX_POLAR_CLIPPING_LGC0, 0x3); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_TX_POLAR_CLIPPING, -+ B_PATH0_TX_POLAR_CLIPPING_LGC1, 0x7); -+ } -+} -+ -+static void rtw8851b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 pri_ch = chan->pri_ch_idx; -+ bool mask_5m_low; -+ bool mask_5m_en; -+ -+ switch (chan->band_width) { -+ case RTW89_CHANNEL_WIDTH_40: -+ /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */ -+ mask_5m_en = true; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWER; -+ break; -+ case RTW89_CHANNEL_WIDTH_80: -+ /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ -+ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST || -+ pri_ch == RTW89_SC_20_LOWEST; -+ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST; -+ break; -+ default: -+ mask_5m_en = false; -+ break; -+ } -+ -+ if (!mask_5m_en) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0); -+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, -+ B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx); -+ return; -+ } -+ -+ if (mask_5m_low) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x5); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x5); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0); -+ } -+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1, -+ B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx); -+} -+ - static void rtw8851b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -@@ -368,6 +956,26 @@ static void rtw8851b_bb_reset_all(struct - rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); - } - -+static void rtw8851b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, -+ enum rtw89_phy_idx phy_idx, bool en) -+{ -+ if (en) { -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, -+ B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); -+ if (band == RTW89_BAND_2G) -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1); -+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, -+ B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx); -+ fsleep(1); -+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx); -+ } -+} -+ - static void rtw8851b_bb_reset(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx) - { -@@ -448,6 +1056,99 @@ static void rtw8851b_bb_sethw(struct rtw - rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); - } - -+static void rtw8851b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 band = chan->band_type, chan_idx; -+ bool cck_en = chan->channel <= 14; -+ u8 pri_ch_idx = chan->pri_ch_idx; -+ -+ if (cck_en) -+ rtw8851b_ctrl_sco_cck(rtwdev, chan->primary_channel); -+ -+ rtw8851b_ctrl_ch(rtwdev, chan, phy_idx); -+ rtw8851b_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); -+ rtw8851b_ctrl_cck_en(rtwdev, cck_en); -+ rtw8851b_set_nbi_tone_idx(rtwdev, chan); -+ rtw8851b_set_csi_tone_idx(rtwdev, chan, phy_idx); -+ -+ if (chan->band_type == RTW89_BAND_5G) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); -+ } -+ -+ chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); -+ rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx); -+ rtw8851b_5m_mask(rtwdev, chan, phy_idx); -+ rtw8851b_set_cfr(rtwdev, chan); -+ rtw8851b_bb_reset_all(rtwdev, phy_idx); -+} -+ -+static void rtw8851b_set_channel(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_mac_idx mac_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8851b_set_channel_mac(rtwdev, chan, mac_idx); -+ rtw8851b_set_channel_bb(rtwdev, chan, phy_idx); -+ rtw8851b_set_channel_rf(rtwdev, chan, phy_idx); -+} -+ -+static void rtw8851b_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, -+ enum rtw89_rf_path path) -+{ -+ if (en) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN, 0x0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN, 0x1); -+ } -+} -+ -+static void rtw8851b_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, -+ u8 phy_idx) -+{ -+ rtw8851b_tssi_cont_en(rtwdev, en, RF_PATH_A); -+} -+ -+static void rtw8851b_adc_en(struct rtw89_dev *rtwdev, bool en) -+{ -+ if (en) -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf); -+} -+ -+static void rtw8851b_set_channel_help(struct rtw89_dev *rtwdev, bool enter, -+ struct rtw89_channel_help_params *p, -+ const struct rtw89_chan *chan, -+ enum rtw89_mac_idx mac_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+ if (enter) { -+ rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); -+ rtw8851b_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); -+ rtw8851b_adc_en(rtwdev, false); -+ fsleep(40); -+ rtw8851b_bb_reset_en(rtwdev, chan->band_type, phy_idx, false); -+ } else { -+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); -+ rtw8851b_adc_en(rtwdev, true); -+ rtw8851b_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); -+ rtw8851b_bb_reset_en(rtwdev, chan->band_type, phy_idx, true); -+ rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); -+ } -+} -+ - static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -798,6 +1499,8 @@ static const struct rtw89_chip_ops rtw88 - .bb_sethw = rtw8851b_bb_sethw, - .read_rf = rtw89_phy_read_rf_v1, - .write_rf = rtw89_phy_write_rf_v1, -+ .set_channel = rtw8851b_set_channel, -+ .set_channel_help = rtw8851b_set_channel_help, - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, - .pwr_on_func = rtw8851b_pwr_on_func, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-099-wifi-rtw89-8851b-add-to-parse-efuse-content.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-099-wifi-rtw89-8851b-add-to-parse-efuse-content.patch deleted file mode 100644 index 309f0d263..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-099-wifi-rtw89-8851b-add-to-parse-efuse-content.patch +++ /dev/null @@ -1,311 +0,0 @@ -From f4244d7fbc9163a44272c0a9d86fd0784d28f386 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 12 May 2023 14:12:20 +0800 -Subject: [PATCH 099/136] wifi: rtw89: 8851b: add to parse efuse content - -Parse efuse content to recognize MAC address, RFE type, XTAL offset and -so on. And, parse offset of PHY capability to retrieve TX power -calibration data. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230512061220.16544-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 208 ++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8851b.h | 61 +++++ - 2 files changed, 269 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -296,6 +296,212 @@ static int rtw8851b_pwr_off_func(struct - return 0; - } - -+static void rtw8851b_efuse_parsing(struct rtw89_efuse *efuse, -+ struct rtw8851b_efuse *map) -+{ -+ ether_addr_copy(efuse->addr, map->e.mac_addr); -+ efuse->rfe_type = map->rfe_type; -+ efuse->xtal_cap = map->xtal_k; -+} -+ -+static void rtw8851b_efuse_parsing_tssi(struct rtw89_dev *rtwdev, -+ struct rtw8851b_efuse *map) -+{ -+ struct rtw89_tssi_info *tssi = &rtwdev->tssi; -+ struct rtw8851b_tssi_offset *ofst[] = {&map->path_a_tssi}; -+ u8 i, j; -+ -+ tssi->thermal[RF_PATH_A] = map->path_a_therm; -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, -+ sizeof(ofst[i]->cck_tssi)); -+ -+ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", -+ i, j, tssi->tssi_cck[i][j]); -+ -+ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, -+ sizeof(ofst[i]->bw40_tssi)); -+ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, -+ ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); -+ -+ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", -+ i, j, tssi->tssi_mcs[i][j]); -+ } -+} -+ -+static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low) -+{ -+ if (high) -+ *high = sign_extend32(u8_get_bits(data, GENMASK(7, 4)), 3); -+ if (low) -+ *low = sign_extend32(u8_get_bits(data, GENMASK(3, 0)), 3); -+ -+ return data != 0xff; -+} -+ -+static void rtw8851b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, -+ struct rtw8851b_efuse *map) -+{ -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ bool valid = false; -+ -+ valid |= _decode_efuse_gain(map->rx_gain_2g_cck, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK], -+ NULL); -+ valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM], -+ NULL); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_low, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW], -+ NULL); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_mid, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID], -+ NULL); -+ valid |= _decode_efuse_gain(map->rx_gain_5g_high, -+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH], -+ NULL); -+ -+ gain->offset_valid = valid; -+} -+ -+static int rtw8851b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) -+{ -+ struct rtw89_efuse *efuse = &rtwdev->efuse; -+ struct rtw8851b_efuse *map; -+ -+ map = (struct rtw8851b_efuse *)log_map; -+ -+ efuse->country_code[0] = map->country_code[0]; -+ efuse->country_code[1] = map->country_code[1]; -+ rtw8851b_efuse_parsing_tssi(rtwdev, map); -+ rtw8851b_efuse_parsing_gain_offset(rtwdev, map); -+ -+ switch (rtwdev->hci.type) { -+ case RTW89_HCI_TYPE_PCIE: -+ rtw8851b_efuse_parsing(efuse, map); -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); -+ -+ return 0; -+} -+ -+static void rtw8851b_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ struct rtw89_tssi_info *tssi = &rtwdev->tssi; -+ static const u32 tssi_trim_addr[RF_PATH_NUM_8851B] = {0x5D6}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ bool pg = false; -+ u32 ofst; -+ u8 i, j; -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { -+ /* addrs are in decreasing order */ -+ ofst = tssi_trim_addr[i] - addr - j; -+ tssi->tssi_trim[i][j] = phycap_map[ofst]; -+ -+ if (phycap_map[ofst] != 0xff) -+ pg = true; -+ } -+ } -+ -+ if (!pg) { -+ memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM] no PG, set all trim info to 0\n"); -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) -+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", -+ i, j, tssi->tssi_trim[i][j], -+ tssi_trim_addr[i] - j); -+} -+ -+static void rtw8851b_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, -+ u8 *phycap_map) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ static const u32 thm_trim_addr[RF_PATH_NUM_8851B] = {0x5DF}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", -+ i, info->thermal_trim[i]); -+ -+ if (info->thermal_trim[i] != 0xff) -+ info->pg_thermal_trim = true; -+ } -+} -+ -+static void rtw8851b_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, -+ u8 *phycap_map) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ static const u32 pabias_trim_addr[] = {0x5DE}; -+ u32 addr = rtwdev->chip->phycap_addr; -+ u8 i; -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", -+ i, info->pa_bias_trim[i]); -+ -+ if (info->pa_bias_trim[i] != 0xff) -+ info->pg_pa_bias_trim = true; -+ } -+} -+ -+static void rtw8851b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = { -+ {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8}, -+ }; -+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain; -+ u32 phycap_addr = rtwdev->chip->phycap_addr; -+ bool valid = false; -+ int path, i; -+ u8 data; -+ -+ for (path = 0; path < BB_PATH_NUM_8851B; path++) -+ for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) { -+ if (comp_addrs[path][i] == 0) -+ continue; -+ -+ data = phycap_map[comp_addrs[path][i] - phycap_addr]; -+ valid |= _decode_efuse_gain(data, NULL, -+ &gain->comp[path][i]); -+ } -+ -+ gain->comp_valid = valid; -+} -+ -+static int rtw8851b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) -+{ -+ rtw8851b_phycap_parsing_tssi(rtwdev, phycap_map); -+ rtw8851b_phycap_parsing_thermal_trim(rtwdev, phycap_map); -+ rtw8851b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); -+ rtw8851b_phycap_parsing_gain_comp(rtwdev, phycap_map); -+ -+ return 0; -+} -+ - static void rtw8851b_set_bb_gpio(struct rtw89_dev *rtwdev, u8 gpio_idx, bool inv, - u8 src_sel) - { -@@ -1501,6 +1707,8 @@ static const struct rtw89_chip_ops rtw88 - .write_rf = rtw89_phy_write_rf_v1, - .set_channel = rtw8851b_set_channel, - .set_channel_help = rtw8851b_set_channel_help, -+ .read_efuse = rtw8851b_read_efuse, -+ .read_phycap = rtw8851b_read_phycap, - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, - .pwr_on_func = rtw8851b_pwr_on_func, ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.h -@@ -10,6 +10,67 @@ - #define RF_PATH_NUM_8851B 1 - #define BB_PATH_NUM_8851B 1 - -+struct rtw8851bu_efuse { -+ u8 rsvd[0x88]; -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+struct rtw8851be_efuse { -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+struct rtw8851b_tssi_offset { -+ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; -+ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; -+ u8 rsvd[7]; -+ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; -+} __packed; -+ -+struct rtw8851b_efuse { -+ u8 rsvd[0x210]; -+ struct rtw8851b_tssi_offset path_a_tssi; -+ u8 rsvd1[136]; -+ u8 channel_plan; -+ u8 xtal_k; -+ u8 rsvd2; -+ u8 iqk_lck; -+ u8 rsvd3[8]; -+ u8 eeprom_version; -+ u8 customer_id; -+ u8 tx_bb_swing_2g; -+ u8 tx_bb_swing_5g; -+ u8 tx_cali_pwr_trk_mode; -+ u8 trx_path_selection; -+ u8 rfe_type; -+ u8 country_code[2]; -+ u8 rsvd4[3]; -+ u8 path_a_therm; -+ u8 rsvd5[3]; -+ u8 rx_gain_2g_ofdm; -+ u8 rsvd6; -+ u8 rx_gain_2g_cck; -+ u8 rsvd7; -+ u8 rx_gain_5g_low; -+ u8 rsvd8; -+ u8 rx_gain_5g_mid; -+ u8 rsvd9; -+ u8 rx_gain_5g_high; -+ u8 rsvd10[35]; -+ u8 path_a_cck_pwr_idx[6]; -+ u8 path_a_bw40_1tx_pwr_idx[5]; -+ u8 path_a_ofdm_1tx_pwr_idx_diff:4; -+ u8 path_a_bw20_1tx_pwr_idx_diff:4; -+ u8 path_a_bw20_2tx_pwr_idx_diff:4; -+ u8 path_a_bw40_2tx_pwr_idx_diff:4; -+ u8 path_a_cck_2tx_pwr_idx_diff:4; -+ u8 path_a_ofdm_2tx_pwr_idx_diff:4; -+ u8 rsvd11[0xf2]; -+ union { -+ struct rtw8851bu_efuse u; -+ struct rtw8851be_efuse e; -+ }; -+} __packed; -+ - extern const struct rtw89_chip_info rtw8851b_chip_info; - - #endif diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-100-wifi-rtw89-8851b-rfk-add-RX-DCK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-100-wifi-rtw89-8851b-rfk-add-RX-DCK.patch deleted file mode 100644 index 437e234a1..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-100-wifi-rtw89-8851b-rfk-add-RX-DCK.patch +++ /dev/null @@ -1,172 +0,0 @@ -From fe8a168266eb65d41ebee0b801fffb5278f92a1b Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 13 May 2023 13:44:23 +0800 -Subject: [PATCH 100/136] wifi: rtw89: 8851b: rfk: add RX DCK - -RX DCK is receiver DC calibration. With this calibration, we have proper -DC offset to reflect correct received signal strength indicator. Do this -calibration when bringing up interface and going to run on AP channel. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230513054425.9689-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 1 + - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 111 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 1 + - 3 files changed, 113 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3841,6 +3841,7 @@ - #define RR_CAL_RW BIT(19) - #define RR_LUTWE2 0xee - #define RR_LUTWE2_RTXBW BIT(2) -+#define RR_LUTWE2_DIS BIT(6) - #define RR_LUTWE 0xef - #define RR_LUTWE_LOK BIT(2) - #define RR_RFC 0xf0 ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -35,6 +35,17 @@ enum rtw8851b_iqk_type { - ID_IQK_RESTORE = 0x10, - }; - -+enum rf_mode { -+ RF_SHUT_DOWN = 0x0, -+ RF_STANDBY = 0x1, -+ RF_TX = 0x2, -+ RF_RX = 0x3, -+ RF_TXIQK = 0x4, -+ RF_DPK = 0x5, -+ RF_RXK1 = 0x6, -+ RF_RXK2 = 0x7, -+}; -+ - static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; - static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; - static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; -@@ -427,6 +438,91 @@ static void _dac_cal(struct rtw89_dev *r - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); - } - -+static void _rx_dck_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, bool is_afe) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] ==== S%d RX DCK (%s / CH%d / %s / by %s)====\n", path, -+ chan->band_type == RTW89_BAND_2G ? "2G" : -+ chan->band_type == RTW89_BAND_5G ? "5G" : "6G", -+ chan->channel, -+ chan->band_width == RTW89_CHANNEL_WIDTH_20 ? "20M" : -+ chan->band_width == RTW89_CHANNEL_WIDTH_40 ? "40M" : "80M", -+ is_afe ? "AFE" : "RFC"); -+} -+ -+static void _rxbb_ofst_swap(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) -+{ -+ u32 val, val_i, val_q; -+ -+ val_i = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_S1); -+ val_q = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_S1); -+ -+ val = val_q << 4 | val_i; -+ -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, rf_mode); -+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); -+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] val_i = 0x%x, val_q = 0x%x, 0x3F = 0x%x\n", -+ val_i, val_q, val); -+} -+ -+static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) -+{ -+ u32 val; -+ int ret; -+ -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); -+ -+ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, -+ 2, 2000, false, -+ rtwdev, path, RR_DCK, BIT(8)); -+ -+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] S%d RXDCK finish (ret = %d)\n", -+ path, ret); -+ -+ _rxbb_ofst_swap(rtwdev, path, rf_mode); -+} -+ -+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) -+{ -+ u32 rf_reg5; -+ u8 path; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", -+ 0x2, rtwdev->hal.cv); -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ _rx_dck_info(rtwdev, phy, path, is_afe); -+ -+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ rtw89_phy_write32_mask(rtwdev, -+ R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, 0x1); -+ -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); -+ _set_rx_dck(rtwdev, path, RF_RX); -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ rtw89_phy_write32_mask(rtwdev, -+ R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, 0x0); -+ } -+} -+ - static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) - { - u32 i; -@@ -1553,6 +1649,21 @@ void rtw8851b_iqk(struct rtw89_dev *rtwd - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); - } - -+void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ _rx_dck(rtwdev, phy_idx, false); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -11,6 +11,7 @@ void rtw8851b_aack(struct rtw89_dev *rtw - void rtw8851b_rck(struct rtw89_dev *rtwdev); - void rtw8851b_dack(struct rtw89_dev *rtwdev); - void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); -+void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-101-wifi-rtw89-8851b-rfk-add-DPK.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-101-wifi-rtw89-8851b-rfk-add-DPK.patch deleted file mode 100644 index b6a06b296..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-101-wifi-rtw89-8851b-rfk-add-DPK.patch +++ /dev/null @@ -1,1196 +0,0 @@ -From 0194a95cbe721a1eff4af2587b09213b088281b0 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 13 May 2023 13:44:24 +0800 -Subject: [PATCH 101/136] wifi: rtw89: 8851b: rfk: add DPK - -DPK is short for digital pre-distortion calibration. It can adjusts digital -waveform according to PA linear characteristics dynamically to enhance -TX EVM. - -Do this calibration when we are going to run on AP channel. To prevent -power offset out of boundary, it monitors thermal and set proper boundary -to register. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230513054425.9689-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 13 + - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 1048 +++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 3 + - 3 files changed, 1064 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3325,6 +3325,10 @@ - #define B_AX_TXAGC_BT_EN BIT(1) - #define B_AX_TXAGC_BT_MASK GENMASK(11, 3) - -+#define R_AX_PWR_SWING_OTHER_CTRL0 0xD230 -+#define R_AX_PWR_SWING_OTHER_CTRL0_C1 0xF230 -+#define B_AX_CFIR_BY_RATE_OFF_MASK GENMASK(17, 0) -+ - #define R_AX_PWR_UL_CTRL0 0xD240 - #define R_AX_PWR_UL_CTRL2 0xD248 - #define B_AX_PWR_UL_CFO_MASK GENMASK(2, 0) -@@ -3755,6 +3759,7 @@ - #define RR_RXA_DPK GENMASK(9, 8) - #define RR_RXA_LNA 0x8b - #define RR_RXA2 0x8c -+#define RR_RAA2_SATT GENMASK(15, 13) - #define RR_RAA2_SWATT GENMASK(15, 9) - #define RR_RXA2_C1 GENMASK(12, 10) - #define RR_RXA2_C2 GENMASK(9, 3) -@@ -4074,6 +4079,7 @@ - #define R_TXAGC_BB 0x1C60 - #define B_TXAGC_BB_OFT GENMASK(31, 16) - #define B_TXAGC_BB GENMASK(31, 24) -+#define B_TXAGC_RF GENMASK(5, 0) - #define R_S0_ADDCK 0x1E00 - #define B_S0_ADDCK_I GENMASK(9, 0) - #define B_S0_ADDCK_Q GENMASK(19, 10) -@@ -4647,6 +4653,7 @@ - #define R_MDPK_SYNC 0x8070 - #define B_MDPK_SYNC_SEL BIT(31) - #define B_MDPK_SYNC_MAN GENMASK(31, 28) -+#define B_MDPK_SYNC_DMAN GENMASK(30, 28) - #define R_MDPK_RX_DCK 0x8074 - #define B_MDPK_RX_DCK_EN BIT(31) - #define R_KIP_MOD 0x8078 -@@ -4655,6 +4662,7 @@ - #define R_KIP_SYSCFG 0x8088 - #define R_KIP_CLK 0x808C - #define R_DPK_IDL 0x809C -+#define B_DPK_IDL_SEL GENMASK(10, 9) - #define B_DPK_IDL BIT(8) - #define R_LDL_NORM 0x80A0 - #define B_LDL_NORM_MA BIT(16) -@@ -4673,6 +4681,10 @@ - #define B_KIP_RPT1_SEL GENMASK(21, 16) - #define B_KIP_RPT1_SEL_V1 GENMASK(19, 16) - #define R_SRAM_IQRX 0x80D8 -+#define R_IDL_MPA 0x80DC -+#define B_IDL_DN BIT(31) -+#define B_IDL_MD530 BIT(1) -+#define B_IDL_MD500 BIT(0) - #define R_GAPK 0x80E0 - #define B_GAPK_ADR BIT(0) - #define R_SRAM_IQRX2 0x80E8 -@@ -4760,6 +4772,7 @@ - #define B_DPK_GL_A0 GENMASK(31, 28) - #define B_DPK_GL_A1 GENMASK(17, 0) - #define R_RPT_PER 0x81FC -+#define B_RPT_PER_KSET GENMASK(31, 29) - #define B_RPT_PER_TSSI GENMASK(28, 16) - #define B_RPT_PER_OF GENMASK(15, 8) - #define B_RPT_PER_TH GENMASK(5, 0) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -12,12 +12,47 @@ - #include "rtw8851b_rfk_table.h" - #include "rtw8851b_table.h" - -+#define DPK_VER_8851B 0x5 -+#define DPK_KIP_REG_NUM_8851B 7 -+#define DPK_RF_REG_NUM_8851B 4 -+#define DPK_KSET_NUM 4 - #define RTW8851B_RXK_GROUP_NR 4 - #define RTW8851B_TXK_GROUP_NR 1 - #define RTW8851B_IQK_VER 0x2a - #define RTW8851B_IQK_SS 1 - #define RTW8851B_LOK_GRAM 10 - -+enum dpk_id { -+ LBK_RXIQK = 0x06, -+ SYNC = 0x10, -+ MDPK_IDL = 0x11, -+ MDPK_MPA = 0x12, -+ GAIN_LOSS = 0x13, -+ GAIN_CAL = 0x14, -+ DPK_RXAGC = 0x15, -+ KIP_PRESET = 0x16, -+ KIP_RESTORE = 0x17, -+ DPK_TXAGC = 0x19, -+ D_KIP_PRESET = 0x28, -+ D_TXAGC = 0x29, -+ D_RXAGC = 0x2a, -+ D_SYNC = 0x2b, -+ D_GAIN_LOSS = 0x2c, -+ D_MDPK_IDL = 0x2d, -+ D_MDPK_LDL = 0x2e, -+ D_GAIN_NORM = 0x2f, -+ D_KIP_THERMAL = 0x30, -+ D_KIP_RESTORE = 0x31 -+}; -+ -+enum dpk_agc_step { -+ DPK_AGC_STEP_SYNC_DGAIN, -+ DPK_AGC_STEP_GAIN_LOSS_IDX, -+ DPK_AGC_STEP_GL_GT_CRITERION, -+ DPK_AGC_STEP_GL_LT_CRITERION, -+ DPK_AGC_STEP_SET_TX_GAIN, -+}; -+ - enum rtw8851b_iqk_type { - ID_TXAGC = 0x0, - ID_FLOK_COARSE = 0x1, -@@ -68,6 +103,10 @@ static const u32 rtw8851b_backup_rf_regs - #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8851b_backup_bb_regs) - #define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8851b_backup_rf_regs) - -+static const u32 dpk_kip_reg[DPK_KIP_REG_NUM_8851B] = { -+ 0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8}; -+static const u32 dpk_rf_reg[DPK_RF_REG_NUM_8851B] = {0xde, 0x8f, 0x5, 0x10005}; -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - return RF_A; -@@ -81,6 +120,24 @@ static void _adc_fifo_rst(struct rtw89_d - rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1111); - } - -+static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_bybb) -+{ -+ if (is_bybb) -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); -+ else -+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); -+} -+ -+static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool is_bybb) -+{ -+ if (is_bybb) -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); -+ else -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); -+} -+ - static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) - { - u32 rf_mode; -@@ -1546,6 +1603,964 @@ static void _iqk(struct rtw89_dev *rtwde - _doiqk(rtwdev, force, phy_idx, RF_PATH_A); - } - -+static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 *reg, -+ u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { -+ reg_bkup[path][i] = -+ rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", -+ reg[i] + (path << 8), reg_bkup[path][i]); -+ } -+} -+ -+static void _dpk_bkup_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, -+ u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { -+ rf_bkup[path][i] = rtw89_read_rf(rtwdev, path, rf_reg[i], RFREG_MASK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup RF S%d 0x%x = %x\n", -+ path, rf_reg[i], rf_bkup[path][i]); -+ } -+} -+ -+static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 *reg, -+ u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { -+ rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD, -+ reg_bkup[path][i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Reload 0x%x = %x\n", -+ reg[i] + (path << 8), reg_bkup[path][i]); -+ } -+} -+ -+static void _dpk_reload_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, -+ u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) -+{ -+ u8 i; -+ -+ for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { -+ rtw89_write_rf(rtwdev, path, rf_reg[i], RFREG_MASK, rf_bkup[path][i]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Reload RF S%d 0x%x = %x\n", path, -+ rf_reg[i], rf_bkup[path][i]); -+ } -+} -+ -+static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, enum dpk_id id) -+{ -+ u16 dpk_cmd; -+ u32 val; -+ int ret; -+ -+ dpk_cmd = ((id << 8) | (0x19 + path * 0x12)); -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, -+ 10, 20000, false, -+ rtwdev, 0xbff8, MASKBYTE0); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 1 timeout\n"); -+ -+ udelay(1); -+ -+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, -+ 1, 2000, false, -+ rtwdev, R_RPT_COM, MASKLWORD); -+ if (ret) -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 2 timeout\n"); -+ -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] one-shot for %s = 0x%04x\n", -+ id == 0x28 ? "KIP_PRESET" : -+ id == 0x29 ? "DPK_TXAGC" : -+ id == 0x2a ? "DPK_RXAGC" : -+ id == 0x2b ? "SYNC" : -+ id == 0x2c ? "GAIN_LOSS" : -+ id == 0x2d ? "MDPK_IDL" : -+ id == 0x2f ? "DPK_GAIN_NORM" : -+ id == 0x31 ? "KIP_RESOTRE" : -+ id == 0x6 ? "LBK_RXIQK" : "Unknown id", -+ dpk_cmd); -+} -+ -+static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ bool off) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 kidx = dpk->cur_idx[path]; -+ u8 off_reverse = off ? 0 : 1; -+ u8 val; -+ -+ val = dpk->is_dpk_enable * off_reverse * dpk->bp[path][kidx].path_ok; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ 0xf0000000, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, -+ kidx, val == 0 ? "disable" : "enable"); -+} -+ -+static void _dpk_init(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ u8 kidx = dpk->cur_idx[path]; -+ -+ dpk->bp[path][kidx].path_ok = 0; -+} -+ -+static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ u8 kidx = dpk->cur_idx[path]; -+ -+ dpk->bp[path][kidx].band = chan->band_type; -+ dpk->bp[path][kidx].ch = chan->band_width; -+ dpk->bp[path][kidx].bw = chan->channel; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", -+ path, dpk->cur_idx[path], phy, -+ rtwdev->is_tssi_mode[path] ? "on" : "off", -+ rtwdev->dbcc_en ? "on" : "off", -+ dpk->bp[path][kidx].band == 0 ? "2G" : -+ dpk->bp[path][kidx].band == 1 ? "5G" : "6G", -+ dpk->bp[path][kidx].ch, -+ dpk->bp[path][kidx].bw == 0 ? "20M" : -+ dpk->bp[path][kidx].bw == 1 ? "40M" : -+ dpk->bp[path][kidx].bw == 2 ? "80M" : "160M"); -+} -+ -+static void _dpk_rxagc_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ bool turn_on) -+{ -+ if (path == RF_PATH_A) -+ rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, turn_on); -+ else -+ rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, turn_on); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d RXAGC is %s\n", path, -+ turn_on ? "turn_on" : "turn_off"); -+} -+ -+static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd); -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_bb_afe_defs_tbl); -+ -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x1); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE setting\n", path); -+} -+ -+static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0x00000000); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, 0x00); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE restore\n", path); -+} -+ -+static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, -+ bool is_pause) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), -+ B_P0_TSSI_TRK_EN, is_pause); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, -+ is_pause ? "pause" : "resume"); -+} -+ -+static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { -+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xffe0fa00); -+ } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { -+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xff4009e0); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xf9f007d0); -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG Select for %s\n", -+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : -+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); -+} -+ -+static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool force) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, force); -+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", -+ path, force ? "on" : "off"); -+} -+ -+static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) -+{ -+ if (turn_on) { -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_WR, BIT(18), 0x1); -+ } -+} -+ -+static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path path, bool ctrl_by_kip) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), -+ B_IQK_RFC_ON, ctrl_by_kip); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RFC is controlled by %s\n", -+ ctrl_by_kip ? "KIP" : "BB"); -+} -+ -+static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ B_DPD_SEL, 0x01); -+ -+ _dpk_kip_control_rfc(rtwdev, path, true); -+ _dpk_one_shot(rtwdev, phy, path, D_KIP_PRESET); -+} -+ -+static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ _dpk_one_shot(rtwdev, phy, path, D_KIP_RESTORE); -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ _dpk_txpwr_bb_force(rtwdev, path, false); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); -+} -+ -+static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0x10); -+ -+ dpk->cur_k_set = -+ rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_KSET) - 1; -+} -+ -+static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+ static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { -+ {0x8190, 0x8194, 0x8198, 0x81a4}, -+ {0x81a8, 0x81c4, 0x81c8, 0x81e8} -+ }; -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 cur_k_set = dpk->cur_k_set; -+ u32 para; -+ -+ if (cur_k_set >= DPK_KSET_NUM) { -+ rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); -+ cur_k_set = 2; -+ } -+ -+ para = rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), -+ MASKDWORD); -+ -+ dpk->bp[path][kidx].txagc_dpk = (para >> 10) & 0x3f; -+ dpk->bp[path][kidx].ther_dpk = (para >> 26) & 0x3f; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n", -+ dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, -+ dpk->bp[path][kidx].txagc_dpk); -+} -+ -+static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 corr_val, corr_idx, rxbb; -+ u16 dc_i, dc_q; -+ u8 rxbb_ov; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); -+ -+ corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); -+ corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); -+ dpk->corr_idx[path][kidx] = corr_idx; -+ dpk->corr_val[path][kidx] = corr_val; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); -+ -+ dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); -+ dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); -+ -+ dc_i = abs(sign_extend32(dc_i, 11)); -+ dc_q = abs(sign_extend32(dc_q, 11)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n", -+ path, corr_idx, corr_val, dc_i, dc_q); -+ -+ dpk->dc_i[path][kidx] = dc_i; -+ dpk->dc_q[path][kidx] = dc_q; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x8); -+ rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x31); -+ rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n", -+ path, rxbb, -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), -+ rxbb_ov); -+ -+ if (dc_i > 200 || dc_q > 200 || corr_val < 170) -+ return true; -+ else -+ return false; -+} -+ -+static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 dbm, -+ bool set_from_bb) -+{ -+ if (set_from_bb) { -+ dbm = clamp_t(u8, dbm, 7, 24); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] set S%d txagc to %ddBm\n", path, dbm); -+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), -+ B_TXPWRB_VAL, dbm << 2); -+ } -+ -+ _dpk_one_shot(rtwdev, phy, path, D_TXAGC); -+ _dpk_kset_query(rtwdev, path); -+} -+ -+static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, -+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); -+ _dpk_kip_control_rfc(rtwdev, path, true); -+ -+ _dpk_one_shot(rtwdev, phy, path, D_RXAGC); -+ return _dpk_sync_check(rtwdev, path, kidx); -+} -+ -+static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ u32 rf_11, reg_81cc; -+ u8 cur_rxbb; -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); -+ -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ -+ cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); -+ rf_11 = rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK); -+ reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), -+ B_KIP_IQP_SW); -+ -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x3); -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0xd); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, 0x1f); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x12); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, 0x3); -+ -+ _dpk_kip_control_rfc(rtwdev, path, true); -+ -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, 0x00250025); -+ -+ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); -+ -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ -+ rtw89_write_rf(rtwdev, path, RR_TXIG, RFREG_MASK, rf_11); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, cur_rxbb); -+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, reg_81cc); -+ -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); -+ -+ _dpk_kip_control_rfc(rtwdev, path, true); -+} -+ -+static void _dpk_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50521); -+ rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x7); -+ } else { -+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, -+ 0x50521 | BIT(rtwdev->dbcc_en)); -+ rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); -+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SATT, 0x3); -+ } -+ -+ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); -+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); -+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); -+ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); -+} -+ -+static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000002); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Bypass RXIQC\n"); -+} -+ -+static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) -+{ -+ u16 dgain; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); -+ dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); -+ -+ return dgain; -+} -+ -+static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) -+{ -+ u8 result; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); -+ result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp GL = %d\n", result); -+ -+ return result; -+} -+ -+static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ _dpk_one_shot(rtwdev, phy, path, D_GAIN_LOSS); -+ _dpk_kip_set_txagc(rtwdev, phy, path, 0xff, false); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, 0xf078); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, 0x0); -+ -+ return _dpk_gainloss_read(rtwdev); -+} -+ -+static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, u8 is_check) -+{ -+ u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; -+ u32 val1_sqrt_sum, val2_sqrt_sum; -+ u8 i; -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); -+ -+ if (is_check) { -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); -+ val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); -+ val1_i = abs(sign_extend32(val1_i, 11)); -+ val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); -+ val1_q = abs(sign_extend32(val1_q, 11)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); -+ val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); -+ val2_i = abs(sign_extend32(val2_i, 11)); -+ val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); -+ val2_q = abs(sign_extend32(val2_q, 11)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", -+ phy_div(val1_i * val1_i + val1_q * val1_q, -+ val2_i * val2_i + val2_q * val2_q)); -+ } else { -+ for (i = 0; i < 32; i++) { -+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] PAS_Read[%02d]= 0x%08x\n", i, -+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); -+ } -+ } -+ -+ val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; -+ val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; -+ -+ if (val1_sqrt_sum < val2_sqrt_sum) -+ return 2; -+ else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) -+ return 1; -+ else -+ return 0; -+} -+ -+static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; -+ u8 step = DPK_AGC_STEP_SYNC_DGAIN; -+ u8 goout = 0, agc_cnt = 0; -+ bool is_fail = false; -+ int limit = 200; -+ u8 tmp_rxbb; -+ u16 dgain; -+ -+ do { -+ switch (step) { -+ case DPK_AGC_STEP_SYNC_DGAIN: -+ is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); -+ -+ if (is_fail) { -+ goout = 1; -+ break; -+ } -+ -+ dgain = _dpk_dgain_read(rtwdev); -+ -+ if (dgain > 0x5fc || dgain < 0x556) { -+ _dpk_one_shot(rtwdev, phy, path, D_SYNC); -+ dgain = _dpk_dgain_read(rtwdev); -+ } -+ -+ if (agc_cnt == 0) { -+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) -+ _dpk_bypass_rxiqc(rtwdev, path); -+ else -+ _dpk_lbk_rxiqk(rtwdev, phy, path); -+ } -+ step = DPK_AGC_STEP_GAIN_LOSS_IDX; -+ break; -+ -+ case DPK_AGC_STEP_GAIN_LOSS_IDX: -+ tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); -+ -+ if (_dpk_pas_read(rtwdev, true) == 2 && tmp_gl_idx > 0) -+ step = DPK_AGC_STEP_GL_LT_CRITERION; -+ else if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true) == 1) || -+ tmp_gl_idx >= 7) -+ step = DPK_AGC_STEP_GL_GT_CRITERION; -+ else if (tmp_gl_idx == 0) -+ step = DPK_AGC_STEP_GL_LT_CRITERION; -+ else -+ step = DPK_AGC_STEP_SET_TX_GAIN; -+ break; -+ -+ case DPK_AGC_STEP_GL_GT_CRITERION: -+ if (tmp_dbm <= 7) { -+ goout = 1; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Txagc@lower bound!!\n"); -+ } else { -+ tmp_dbm = max_t(u8, tmp_dbm - 3, 7); -+ _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); -+ } -+ step = DPK_AGC_STEP_SYNC_DGAIN; -+ agc_cnt++; -+ break; -+ -+ case DPK_AGC_STEP_GL_LT_CRITERION: -+ if (tmp_dbm >= 24) { -+ goout = 1; -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Txagc@upper bound!!\n"); -+ } else { -+ tmp_dbm = min_t(u8, tmp_dbm + 2, 24); -+ _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); -+ } -+ step = DPK_AGC_STEP_SYNC_DGAIN; -+ agc_cnt++; -+ break; -+ -+ case DPK_AGC_STEP_SET_TX_GAIN: -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); -+ tmp_rxbb = min_t(u8, tmp_rxbb + tmp_gl_idx, 0x1f); -+ -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, tmp_rxbb); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Adjust RXBB (%+d) = 0x%x\n", -+ tmp_gl_idx, tmp_rxbb); -+ _dpk_kip_control_rfc(rtwdev, path, true); -+ goout = 1; -+ break; -+ default: -+ goout = 1; -+ break; -+ } -+ } while (!goout && agc_cnt < 6 && limit-- > 0); -+ -+ return is_fail; -+} -+ -+static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) -+{ -+ switch (order) { -+ case 0: /* (5,3,1) */ -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); -+ break; -+ case 1: /* (5,3,0) */ -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); -+ break; -+ case 2: /* (5,0,0) */ -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x2); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); -+ break; -+ case 3: /* (7,3,1) */ -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x3); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x3); -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4); -+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); -+ break; -+ default: -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] Wrong MDPD order!!(0x%x)\n", order); -+ break; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", -+ order == 0x0 ? "(5,3,1)" : -+ order == 0x1 ? "(5,3,0)" : -+ order == 0x2 ? "(5,0,0)" : "(7,3,1)"); -+} -+ -+static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, 0x1); -+ -+ if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD500) == 0x1) -+ _dpk_set_mdpd_para(rtwdev, 0x2); -+ else if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD530) == 0x1) -+ _dpk_set_mdpd_para(rtwdev, 0x1); -+ else -+ _dpk_set_mdpd_para(rtwdev, 0x0); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, 0x0); -+ fsleep(1000); -+ -+ _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); -+} -+ -+static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) -+{ -+ u32 order; -+ u8 val; -+ -+ order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); -+ -+ switch (order) { -+ case 0: /* (5,3,1) */ -+ val = 0x6; -+ break; -+ case 1: /* (5,3,0) */ -+ val = 0x2; -+ break; -+ case 2: /* (5,0,0) */ -+ val = 0x0; -+ break; -+ default: -+ val = 0xff; -+ break; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); -+ -+ return val; -+} -+ -+static void _dpk_gain_normalize(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx, bool is_execute) -+{ -+ static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { -+ {0x8190, 0x8194, 0x8198, 0x81a4}, -+ {0x81a8, 0x81c4, 0x81c8, 0x81e8} -+ }; -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 cur_k_set = dpk->cur_k_set; -+ -+ if (cur_k_set >= DPK_KSET_NUM) { -+ rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); -+ cur_k_set = 2; -+ } -+ -+ if (is_execute) { -+ rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), -+ B_DPK_GN_AG, 0x200); -+ rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), -+ B_DPK_GN_EN, 0x3); -+ -+ _dpk_one_shot(rtwdev, phy, path, D_GAIN_NORM); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), -+ 0x0000007F, 0x5b); -+ } -+ -+ dpk->bp[path][kidx].gs = -+ rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), -+ 0x0000007F); -+} -+ -+static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, u8 kidx) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ B_DPD_ORDER, _dpk_order_convert(rtwdev)); -+ -+ dpk->bp[path][kidx].path_ok = -+ dpk->bp[path][kidx].path_ok | BIT(dpk->cur_k_set); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] path_ok = 0x%x\n", -+ path, kidx, dpk->bp[path][kidx].path_ok); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), -+ B_DPD_MEN, dpk->bp[path][kidx].path_ok); -+ -+ _dpk_gain_normalize(rtwdev, phy, path, kidx, false); -+} -+ -+static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u8 kidx = dpk->cur_idx[path]; -+ u8 init_xdbm = 17; -+ bool is_fail; -+ -+ if (dpk->bp[path][kidx].band != RTW89_BAND_2G) -+ init_xdbm = 15; -+ -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ _rfk_rf_direct_cntrl(rtwdev, path, false); -+ rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd); -+ -+ _dpk_rf_setting(rtwdev, path, kidx); -+ _set_rx_dck(rtwdev, path, RF_DPK); -+ -+ _dpk_kip_pwr_clk_onoff(rtwdev, true); -+ _dpk_kip_preset(rtwdev, phy, path, kidx); -+ _dpk_txpwr_bb_force(rtwdev, path, true); -+ _dpk_kip_set_txagc(rtwdev, phy, path, init_xdbm, true); -+ _dpk_tpg_sel(rtwdev, path, kidx); -+ is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, false); -+ if (is_fail) -+ goto _error; -+ -+ _dpk_idl_mpa(rtwdev, phy, path, kidx); -+ _dpk_para_query(rtwdev, path, kidx); -+ -+ _dpk_on(rtwdev, phy, path, kidx); -+_error: -+ _dpk_kip_control_rfc(rtwdev, path, false); -+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d]_K%d %s\n", path, kidx, -+ dpk->cur_k_set, is_fail ? "need Check" : "is Success"); -+ -+ return is_fail; -+} -+ -+static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, -+ enum rtw89_phy_idx phy, u8 kpath) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ u32 kip_bkup[RF_PATH_NUM_8851B][DPK_KIP_REG_NUM_8851B] = {}; -+ u32 rf_bkup[RF_PATH_NUM_8851B][DPK_RF_REG_NUM_8851B] = {}; -+ bool is_fail; -+ u8 path; -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) -+ dpk->cur_idx[path] = 0; -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ _dpk_bkup_kip(rtwdev, dpk_kip_reg, kip_bkup, path); -+ _dpk_bkup_rf(rtwdev, dpk_rf_reg, rf_bkup, path); -+ _dpk_information(rtwdev, phy, path); -+ _dpk_init(rtwdev, path); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ _dpk_tssi_pause(rtwdev, path, true); -+ } -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] ========= S%d[%d] DPK Start =========\n", -+ path, dpk->cur_idx[path]); -+ -+ _dpk_rxagc_onoff(rtwdev, path, false); -+ _rfk_drf_direct_cntrl(rtwdev, path, false); -+ _dpk_bb_afe_setting(rtwdev, path); -+ -+ is_fail = _dpk_main(rtwdev, phy, path); -+ _dpk_onoff(rtwdev, path, is_fail); -+ } -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ if (!(kpath & BIT(path))) -+ continue; -+ -+ _dpk_kip_restore(rtwdev, phy, path); -+ _dpk_reload_kip(rtwdev, dpk_kip_reg, kip_bkup, path); -+ _dpk_reload_rf(rtwdev, dpk_rf_reg, rf_bkup, path); -+ _dpk_bb_afe_restore(rtwdev, path); -+ _dpk_rxagc_onoff(rtwdev, path, true); -+ -+ if (rtwdev->is_tssi_mode[path]) -+ _dpk_tssi_pause(rtwdev, path, false); -+ } -+ -+ _dpk_kip_pwr_clk_onoff(rtwdev, false); -+} -+ -+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[DPK] ****** 8851B DPK Start (Ver: 0x%x, Cv: %d) ******\n", -+ DPK_VER_8851B, rtwdev->hal.cv); -+ -+ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy)); -+} -+ -+static void _dpk_track(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_dpk_info *dpk = &rtwdev->dpk; -+ s8 txagc_bb, txagc_bb_tp, txagc_ofst; -+ s16 pwsf_tssi_ofst; -+ s8 delta_ther = 0; -+ u8 path, kidx; -+ u8 txagc_rf; -+ u8 cur_ther; -+ -+ for (path = 0; path < RF_PATH_NUM_8851B; path++) { -+ kidx = dpk->cur_idx[path]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", -+ path, kidx, dpk->bp[path][kidx].ch); -+ -+ txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), -+ B_TXAGC_RF); -+ txagc_bb = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), -+ MASKBYTE2); -+ txagc_bb_tp = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), -+ B_TXAGC_BTP); -+ -+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), -+ B_KIP_RPT_SEL, 0xf); -+ cur_ther = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), -+ B_RPT_PER_TH); -+ txagc_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), -+ B_RPT_PER_OF); -+ pwsf_tssi_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), -+ B_RPT_PER_TSSI); -+ pwsf_tssi_ofst = sign_extend32(pwsf_tssi_ofst, 12); -+ -+ delta_ther = cur_ther - dpk->bp[path][kidx].ther_dpk; -+ -+ delta_ther = delta_ther * 2 / 3; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n", -+ delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n", -+ txagc_rf - dpk->bp[path][kidx].txagc_dpk, -+ txagc_rf, dpk->bp[path][kidx].txagc_dpk); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n", -+ txagc_ofst, pwsf_tssi_ofst); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", -+ txagc_bb_tp, txagc_bb); -+ -+ if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_DN) == 0x0 && -+ txagc_rf != 0) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[DPK_TRK] New pwsf = 0x%x\n", 0x78 - delta_ther); -+ -+ rtw89_phy_write32_mask(rtwdev, -+ R_DPD_BND + (path << 8) + (kidx << 2), -+ 0x07FC0000, 0x78 - delta_ther); -+ } -+ } -+} -+ - static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - u32 rf_reg5; -@@ -1581,6 +2596,17 @@ static void _rck(struct rtw89_dev *rtwde - rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); - } - -+static void rtw8851b_by_rate_dpd(struct rtw89_dev *rtwdev) -+{ -+ rtw89_write32_mask(rtwdev, R_AX_PWR_SWING_OTHER_CTRL0, -+ B_AX_CFIR_BY_RATE_OFF_MASK, 0x21861); -+} -+ -+void rtw8851b_dpk_init(struct rtw89_dev *rtwdev) -+{ -+ rtw8851b_by_rate_dpd(rtwdev); -+} -+ - void rtw8851b_aack(struct rtw89_dev *rtwdev) - { - u32 tmp05, ib[4]; -@@ -1664,6 +2690,28 @@ void rtw8851b_rx_dck(struct rtw89_dev *r - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); - } - -+void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); -+ u32 tx_en; -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); -+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); -+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); -+ -+ rtwdev->dpk.is_dpk_enable = true; -+ rtwdev->dpk.is_dpk_reload_en = false; -+ _dpk(rtwdev, phy_idx, false); -+ -+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); -+} -+ -+void rtw8851b_dpk_track(struct rtw89_dev *rtwdev) -+{ -+ _dpk_track(rtwdev); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -12,6 +12,9 @@ void rtw8851b_rck(struct rtw89_dev *rtwd - void rtw8851b_dack(struct rtw89_dev *rtwdev); - void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); - void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); -+void rtw8851b_dpk_init(struct rtw89_dev *rtwdev); -+void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); -+void rtw8851b_dpk_track(struct rtw89_dev *rtwdev); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-102-wifi-rtw89-8851b-rfk-add-TSSI.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-102-wifi-rtw89-8851b-rfk-add-TSSI.patch deleted file mode 100644 index 37c0f5448..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-102-wifi-rtw89-8851b-rfk-add-TSSI.patch +++ /dev/null @@ -1,684 +0,0 @@ -From 3f2da9fc17f66af17a1349d4d32f6a6ba245b94d Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 13 May 2023 13:44:25 +0800 -Subject: [PATCH 102/136] wifi: rtw89: 8851b: rfk: add TSSI - -TSSI is transmitter signal strength indication, which is a close-loop -hardware circuit to feedback actual transmitting power as a reference for -next transmission. - -When we setup channel to connect an AP, it does full calibration. When -switching bands or channels, it needs to reset hardware status to prevent -use wrong feedback of previous transmission. - -To do TX power compensation reflecting current temperature, it loads tables -of compensation values into registers according to channel and band group. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230513054425.9689-4-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 617 ++++++++++++++++++ - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 4 + - 2 files changed, 621 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -21,6 +21,9 @@ - #define RTW8851B_IQK_VER 0x2a - #define RTW8851B_IQK_SS 1 - #define RTW8851B_LOK_GRAM 10 -+#define RTW8851B_TSSI_PATH_NR 1 -+ -+#define _TSSI_DE_MASK GENMASK(21, 12) - - enum dpk_id { - LBK_RXIQK = 0x06, -@@ -81,6 +84,14 @@ enum rf_mode { - RF_RXK2 = 0x7, - }; - -+static const u32 _tssi_de_cck_long[RF_PATH_NUM_8851B] = {0x5858}; -+static const u32 _tssi_de_cck_short[RF_PATH_NUM_8851B] = {0x5860}; -+static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8851B] = {0x5838}; -+static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8851B] = {0x5840}; -+static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8851B] = {0x5848}; -+static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8851B] = {0x5850}; -+static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8851B] = {0x5828}; -+static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8851B] = {0x5830}; - static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; - static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; - static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; -@@ -2596,6 +2607,521 @@ static void _rck(struct rtw89_dev *rtwde - rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); - } - -+static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_sys_defs_tbl); -+ -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8851b_tssi_sys_a_defs_2g_tbl, -+ &rtw8851b_tssi_sys_a_defs_5g_tbl); -+} -+ -+static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_defs_a_tbl); -+} -+ -+static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl); -+} -+ -+static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dck_defs_a_tbl); -+} -+ -+static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+#define RTW8851B_TSSI_GET_VAL(ptr, idx) \ -+({ \ -+ s8 *__ptr = (ptr); \ -+ u8 __idx = (idx), __i, __v; \ -+ u32 __val = 0; \ -+ for (__i = 0; __i < 4; __i++) { \ -+ __v = (__ptr[__idx + __i]); \ -+ __val |= (__v << (8 * __i)); \ -+ } \ -+ __val; \ -+}) -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u8 subband = chan->subband_type; -+ const s8 *thm_up_a = NULL; -+ const s8 *thm_down_a = NULL; -+ u8 thermal = 0xff; -+ s8 thm_ofst[64] = {0}; -+ u32 tmp = 0; -+ u8 i, j; -+ -+ switch (subband) { -+ default: -+ case RTW89_CH_2G: -+ thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_2ga_p; -+ thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_2ga_n; -+ break; -+ case RTW89_CH_5G_BAND_1: -+ thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[0]; -+ thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[0]; -+ break; -+ case RTW89_CH_5G_BAND_3: -+ thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[1]; -+ thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[1]; -+ break; -+ case RTW89_CH_5G_BAND_4: -+ thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[2]; -+ thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[2]; -+ break; -+ } -+ -+ if (path == RF_PATH_A) { -+ thermal = tssi_info->thermal[RF_PATH_A]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); -+ -+ if (thermal == 0xff) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); -+ -+ for (i = 0; i < 64; i += 4) { -+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ R_P0_TSSI_BASE + i, 0x0); -+ } -+ -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, -+ thermal); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, -+ thermal); -+ -+ i = 0; -+ for (j = 0; j < 32; j++) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ -thm_down_a[i++] : -+ -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; -+ -+ i = 1; -+ for (j = 63; j >= 32; j--) -+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? -+ thm_up_a[i++] : -+ thm_up_a[DELTA_SWINGIDX_SIZE - 1]; -+ -+ for (i = 0; i < 64; i += 4) { -+ tmp = RTW8851B_TSSI_GET_VAL(thm_ofst, i); -+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] write 0x%x val=0x%08x\n", -+ 0x5c00 + i, tmp); -+ } -+ } -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); -+ } -+#undef RTW8851B_TSSI_GET_VAL -+} -+ -+static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dac_gain_defs_a_tbl); -+} -+ -+static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8851b_tssi_slope_a_defs_2g_tbl, -+ &rtw8851b_tssi_slope_a_defs_5g_tbl); -+} -+ -+static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path, bool all) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ enum rtw89_band band = chan->band_type; -+ -+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, -+ &rtw8851b_tssi_align_a_2g_defs_tbl, -+ &rtw8851b_tssi_align_a_5g_defs_tbl); -+} -+ -+static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_slope_defs_a_tbl); -+} -+ -+static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_track_defs_a_tbl); -+} -+ -+static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_mv_avg_defs_a_tbl); -+} -+ -+static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ _tssi_set_tssi_track(rtwdev, phy, RF_PATH_A); -+ _tssi_set_txagc_offset_mv_avg(rtwdev, phy, RF_PATH_A); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x1); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXGA_V1, RR_TXGA_V1_TRK_EN, 0x1); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x3); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); -+ -+ rtwdev->is_tssi_mode[RF_PATH_A] = true; -+} -+ -+static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); -+ -+ rtwdev->is_tssi_mode[RF_PATH_A] = false; -+} -+ -+static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 2: -+ return 0; -+ case 3 ... 5: -+ return 1; -+ case 6 ... 8: -+ return 2; -+ case 9 ... 11: -+ return 3; -+ case 12 ... 13: -+ return 4; -+ case 14: -+ return 5; -+ } -+ -+ return 0; -+} -+ -+#define TSSI_EXTRA_GROUP_BIT (BIT(31)) -+#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) -+#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) -+#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) -+#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) -+ -+static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 2: -+ return 0; -+ case 3 ... 5: -+ return 1; -+ case 6 ... 8: -+ return 2; -+ case 9 ... 11: -+ return 3; -+ case 12 ... 14: -+ return 4; -+ case 36 ... 40: -+ return 5; -+ case 41 ... 43: -+ return TSSI_EXTRA_GROUP(5); -+ case 44 ... 48: -+ return 6; -+ case 49 ... 51: -+ return TSSI_EXTRA_GROUP(6); -+ case 52 ... 56: -+ return 7; -+ case 57 ... 59: -+ return TSSI_EXTRA_GROUP(7); -+ case 60 ... 64: -+ return 8; -+ case 100 ... 104: -+ return 9; -+ case 105 ... 107: -+ return TSSI_EXTRA_GROUP(9); -+ case 108 ... 112: -+ return 10; -+ case 113 ... 115: -+ return TSSI_EXTRA_GROUP(10); -+ case 116 ... 120: -+ return 11; -+ case 121 ... 123: -+ return TSSI_EXTRA_GROUP(11); -+ case 124 ... 128: -+ return 12; -+ case 129 ... 131: -+ return TSSI_EXTRA_GROUP(12); -+ case 132 ... 136: -+ return 13; -+ case 137 ... 139: -+ return TSSI_EXTRA_GROUP(13); -+ case 140 ... 144: -+ return 14; -+ case 149 ... 153: -+ return 15; -+ case 154 ... 156: -+ return TSSI_EXTRA_GROUP(15); -+ case 157 ... 161: -+ return 16; -+ case 162 ... 164: -+ return TSSI_EXTRA_GROUP(16); -+ case 165 ... 169: -+ return 17; -+ case 170 ... 172: -+ return TSSI_EXTRA_GROUP(17); -+ case 173 ... 177: -+ return 18; -+ } -+ -+ return 0; -+} -+ -+static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) -+{ -+ switch (ch) { -+ case 1 ... 8: -+ return 0; -+ case 9 ... 14: -+ return 1; -+ case 36 ... 48: -+ return 2; -+ case 52 ... 64: -+ return 3; -+ case 100 ... 112: -+ return 4; -+ case 116 ... 128: -+ return 5; -+ case 132 ... 144: -+ return 6; -+ case 149 ... 177: -+ return 7; -+ } -+ -+ return 0; -+} -+ -+static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u32 gidx, gidx_1st, gidx_2nd; -+ u8 ch = chan->channel; -+ s8 de_1st; -+ s8 de_2nd; -+ s8 val; -+ -+ gidx = _tssi_get_ofdm_group(rtwdev, ch); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); -+ -+ if (IS_TSSI_EXTRA_GROUP(gidx)) { -+ gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); -+ gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); -+ de_1st = tssi_info->tssi_mcs[path][gidx_1st]; -+ de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; -+ val = (de_1st + de_2nd) / 2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", -+ path, val, de_1st, de_2nd); -+ } else { -+ val = tssi_info->tssi_mcs[path][gidx]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); -+ } -+ -+ return val; -+} -+ -+static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, -+ enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u32 tgidx, tgidx_1st, tgidx_2nd; -+ u8 ch = chan->channel; -+ s8 tde_1st; -+ s8 tde_2nd; -+ s8 val; -+ -+ tgidx = _tssi_get_trim_group(rtwdev, ch); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", -+ path, tgidx); -+ -+ if (IS_TSSI_EXTRA_GROUP(tgidx)) { -+ tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); -+ tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); -+ tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; -+ tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; -+ val = (tde_1st + tde_2nd) / 2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", -+ path, val, tde_1st, tde_2nd); -+ } else { -+ val = tssi_info->tssi_trim[path][tgidx]; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", -+ path, val); -+ } -+ -+ return val; -+} -+ -+static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 ch = chan->channel; -+ u8 gidx; -+ s8 ofdm_de; -+ s8 trim_de; -+ s32 val; -+ u32 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", -+ phy, ch); -+ -+ for (i = RF_PATH_A; i < RTW8851B_TSSI_PATH_NR; i++) { -+ gidx = _tssi_get_cck_group(rtwdev, ch); -+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); -+ val = tssi_info->tssi_cck[i][gidx] + trim_de; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", -+ i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); -+ -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", -+ _tssi_de_cck_long[i], -+ rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], -+ _TSSI_DE_MASK)); -+ -+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i); -+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); -+ val = ofdm_de + trim_de; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", -+ i, ofdm_de, trim_de); -+ -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); -+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, -+ "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", -+ _tssi_de_mcs_20m[i], -+ rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], -+ _TSSI_DE_MASK)); -+ } -+} -+ -+static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) -+{ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" -+ "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", -+ R_TSSI_PA_K1 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K2 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM1 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM3 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K5 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM2 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD), -+ R_P0_TSSI_ALIM4 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD), -+ R_TSSI_PA_K8 + (path << 13), -+ rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD)); -+} -+ -+static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, enum rtw89_rf_path path) -+{ -+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 channel = chan->channel; -+ u8 band; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s phy=%d path=%d\n", __func__, phy, path); -+ -+ if (channel >= 1 && channel <= 14) -+ band = TSSI_ALIMK_2G; -+ else if (channel >= 36 && channel <= 64) -+ band = TSSI_ALIMK_5GL; -+ else if (channel >= 100 && channel <= 144) -+ band = TSSI_ALIMK_5GM; -+ else if (channel >= 149 && channel <= 177) -+ band = TSSI_ALIMK_5GH; -+ else -+ band = TSSI_ALIMK_2G; -+ -+ if (tssi_info->alignment_done[path][band]) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][0]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][1]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][2]); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, -+ tssi_info->alignment_value[path][band][3]); -+ } -+ -+ _tssi_alimentk_dump_result(rtwdev, path); -+} -+ - static void rtw8851b_by_rate_dpd(struct rtw89_dev *rtwdev) - { - rtw89_write32_mask(rtwdev, R_AX_PWR_SWING_OTHER_CTRL0, -@@ -2712,6 +3238,97 @@ void rtw8851b_dpk_track(struct rtw89_dev - _dpk_track(rtwdev); - } - -+void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en) -+{ -+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_A); -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); -+ -+ _tssi_disable(rtwdev, phy); -+ -+ for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { -+ _tssi_set_sys(rtwdev, phy, i); -+ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); -+ _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); -+ _tssi_set_dck(rtwdev, phy, i); -+ _tssi_set_tmeter_tbl(rtwdev, phy, i); -+ _tssi_set_dac_gain_tbl(rtwdev, phy, i); -+ _tssi_slope_cal_org(rtwdev, phy, i); -+ _tssi_alignment_default(rtwdev, phy, i, true); -+ _tssi_set_tssi_slope(rtwdev, phy, i); -+ } -+ -+ _tssi_enable(rtwdev, phy); -+ _tssi_set_efuse_to_de(rtwdev, phy); -+ -+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); -+} -+ -+void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 channel = chan->channel; -+ u32 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s phy=%d channel=%d\n", __func__, phy, channel); -+ -+ _tssi_disable(rtwdev, phy); -+ -+ for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { -+ _tssi_set_sys(rtwdev, phy, i); -+ _tssi_set_tmeter_tbl(rtwdev, phy, i); -+ _tssi_slope_cal_org(rtwdev, phy, i); -+ _tssi_alignment_default(rtwdev, phy, i, true); -+ } -+ -+ _tssi_enable(rtwdev, phy); -+ _tssi_set_efuse_to_de(rtwdev, phy); -+} -+ -+static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy, bool enable) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u8 channel = chan->channel; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", -+ __func__, channel); -+ -+ if (enable) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x\n", -+ __func__, -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); -+ -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); -+ -+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_A); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x\n", -+ __func__, -+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "======> %s SCAN_END\n", __func__); -+} -+ -+void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, -+ enum rtw89_phy_idx phy_idx) -+{ -+ if (scan_start) -+ rtw8851b_tssi_default_txagc(rtwdev, phy_idx, true); -+ else -+ rtw8851b_tssi_default_txagc(rtwdev, phy_idx, false); -+} -+ - static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, - enum rtw89_bandwidth bw, bool dav) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -15,6 +15,10 @@ void rtw8851b_rx_dck(struct rtw89_dev *r - void rtw8851b_dpk_init(struct rtw89_dev *rtwdev); - void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); - void rtw8851b_dpk_track(struct rtw89_dev *rtwdev); -+void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en); -+void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); -+void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, -+ enum rtw89_phy_idx phy_idx); - void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-103-wifi-rtw89-ser-reset-total_sta_assoc-and-tdls_peer-w.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-103-wifi-rtw89-ser-reset-total_sta_assoc-and-tdls_peer-w.patch deleted file mode 100644 index 9469d7744..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-103-wifi-rtw89-ser-reset-total_sta_assoc-and-tdls_peer-w.patch +++ /dev/null @@ -1,39 +0,0 @@ -From cda66049bab5273c61f09a4ea8c09d1de4d64fc0 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 16 May 2023 16:24:39 +0800 -Subject: [PATCH 103/136] wifi: rtw89: ser: reset total_sta_assoc and tdls_peer - when L2 - -The total_sta_assoc and the tdls_peer are used for statistics accodring -to stations' information. L2 (Level 2) SER (system error recovery) will -call ieee80211_restart_hw() which re-invokes sta_state ops. And then, -the total_sta_assoc and tdls_peer will be re-increased. In case wrong -statistics results, we reset them in SER L2 handling. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230516082441.11154-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/ser.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/ser.c -+++ b/drivers/net/wireless/realtek/rtw89/ser.c -@@ -303,6 +303,7 @@ static void ser_reset_vif(struct rtw89_d - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; - rtwvif->trigger = false; -+ rtwvif->tdls_peer = 0; - } - - static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) -@@ -341,6 +342,8 @@ static void ser_reset_mac_binding(struct - rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); - rtw89_for_each_rtwvif(rtwdev, rtwvif) - ser_reset_vif(rtwdev, rtwvif); -+ -+ rtwdev->total_sta_assoc = 0; - } - - /* hal function */ diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-104-wifi-rtw89-tweak-H2C-TX-waiting-function-for-SER.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-104-wifi-rtw89-tweak-H2C-TX-waiting-function-for-SER.patch deleted file mode 100644 index c105c86a0..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-104-wifi-rtw89-tweak-H2C-TX-waiting-function-for-SER.patch +++ /dev/null @@ -1,78 +0,0 @@ -From b79a84fbbdb0a715b130ab470c241db211539dfb Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 16 May 2023 16:24:40 +0800 -Subject: [PATCH 104/136] wifi: rtw89: tweak H2C TX waiting function for SER - -Some specific H2C (host to chip command) needs waiting until FW ACK by -C2H (chip to host event). However, during SER (system error recovery), -most interrupts are disabled, so we can't receive C2H immediately. It -causes this kind of H2C TX waits will always time out during SER. - -To save time spent by SER, we don't do these redundant waits. And, to -make a difference from -ETIMEDOUT in other cases, we make the function -return 1 for SER case. When some H2C callers really catch `ret == 1` at -runtime, they can determine whether it's reasonable or not, and consider -how to resolve their flow if needed. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230516082441.11154-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 1 + - drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++++ - drivers/net/wireless/realtek/rtw89/ser.c | 2 ++ - 3 files changed, 11 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3505,6 +3505,7 @@ enum rtw89_flags { - RTW89_FLAG_LOW_POWER_MODE, - RTW89_FLAG_INACTIVE_PS, - RTW89_FLAG_CRASH_SIMULATING, -+ RTW89_FLAG_SER_HANDLING, - RTW89_FLAG_WOWLAN, - RTW89_FLAG_FORBIDDEN_TRACK_WROK, - RTW89_FLAG_CHANGING_INTERFACE, ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -3792,6 +3792,11 @@ fail: - return ret; - } - -+/* Return < 0, if failures happen during waiting for the condition. -+ * Return 0, when waiting for the condition succeeds. -+ * Return > 0, if the wait is considered unreachable due to driver/FW design, -+ * where 1 means during SER. -+ */ - static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, - struct rtw89_wait_info *wait, unsigned int cond) - { -@@ -3804,6 +3809,9 @@ static int rtw89_h2c_tx_and_wait(struct - return -EBUSY; - } - -+ if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) -+ return 1; -+ - return rtw89_wait_for_cond(wait, cond); - } - ---- a/drivers/net/wireless/realtek/rtw89/ser.c -+++ b/drivers/net/wireless/realtek/rtw89/ser.c -@@ -409,6 +409,7 @@ static void ser_idle_st_hdl(struct rtw89 - switch (evt) { - case SER_EV_STATE_IN: - rtw89_hci_recovery_complete(rtwdev); -+ clear_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags); - clear_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags); - break; - case SER_EV_L1_RESET_PREPARE: -@@ -421,6 +422,7 @@ static void ser_idle_st_hdl(struct rtw89 - ser_state_goto(ser, SER_L2_RESET_ST); - break; - case SER_EV_STATE_OUT: -+ set_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags); - rtw89_hci_recovery_start(rtwdev); - break; - default: diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-105-wifi-rtw89-refine-packet-offload-handling-under-SER.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-105-wifi-rtw89-refine-packet-offload-handling-under-SER.patch deleted file mode 100644 index cc1cb2205..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-105-wifi-rtw89-refine-packet-offload-handling-under-SER.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 8b21c08ef7df41aa615439beac323a7b3b1df0e6 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Tue, 16 May 2023 16:24:41 +0800 -Subject: [PATCH 105/136] wifi: rtw89: refine packet offload handling under SER - -H2C of packet offload needs to wait FW ACK by C2H. But, it's possible -that packet offload happens during SER (system error recovery), e.g. -SER L2 which restarts HW. More, packet offload flow isn't deferrable. -So, the H2C wait may get `ret == 1` (unreachable). - -However, the logic FW deals with packet offload is simple enough, just -clone content. It means that as long as the H2C is issued successfully, -the thing will succeed sooner or later. Therefore, after we add a debug -log when receiving ACK to packet offload, it would be acceptable that -during SER, packet offload don't really wait for ACK. And, if debugging, -we can still check its debug logs. Besides, we can expect that if we see -SER before receiving ACK to packet offload, those debug logs of the ACK -have a time difference. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230516082441.11154-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 4 ++-- - drivers/net/wireless/realtek/rtw89/mac.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2467,7 +2467,7 @@ int rtw89_fw_h2c_del_pkt_offload(struct - cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); - - ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -- if (ret) { -+ if (ret < 0) { - rtw89_debug(rtwdev, RTW89_DBG_FW, - "failed to del pkt ofld: id %d, ret %d\n", - id, ret); -@@ -2517,7 +2517,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct - cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); - - ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); -- if (ret) { -+ if (ret < 0) { - rtw89_debug(rtwdev, RTW89_DBG_FW, - "failed to add pkt ofld: id %d, ret %d\n", - alloc_id, ret); ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -4460,6 +4460,9 @@ rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_ - struct rtw89_completion_data data = {}; - unsigned int cond; - -+ rtw89_debug(rtwdev, RTW89_DBG_FW, "pkt ofld rsp: id %d op %d len %d\n", -+ pkt_id, pkt_op, pkt_len); -+ - data.err = !pkt_len; - cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op); - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-106-wifi-rtw89-8851b-add-TX-power-related-functions.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-106-wifi-rtw89-8851b-add-TX-power-related-functions.patch deleted file mode 100644 index fa4c8804a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-106-wifi-rtw89-8851b-add-TX-power-related-functions.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 76f2516f79373e17974ce03c52eba4cfea8483e9 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:14:54 +0800 -Subject: [PATCH 106/136] wifi: rtw89: 8851b: add TX power related functions - -Get TX power value from tables according to selected country and channel, -and set proper power to registers. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 254 ++++++++++++++++++ - 1 file changed, 254 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -448,6 +448,34 @@ static void rtw8851b_phycap_parsing_ther - } - } - -+static void rtw8851b_thermal_trim(struct rtw89_dev *rtwdev) -+{ -+#define __thm_setting(raw) \ -+({ \ -+ u8 __v = (raw); \ -+ ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ -+}) -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ u8 i, val; -+ -+ if (!info->pg_thermal_trim) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] no PG, do nothing\n"); -+ -+ return; -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ val = __thm_setting(info->thermal_trim[i]); -+ rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", -+ i, val); -+ } -+#undef __thm_setting -+} -+ - static void rtw8851b_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, - u8 *phycap_map) - { -@@ -468,6 +496,32 @@ static void rtw8851b_phycap_parsing_pa_b - } - } - -+static void rtw8851b_pa_bias_trim(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; -+ u8 pabias_2g, pabias_5g; -+ u8 i; -+ -+ if (!info->pg_pa_bias_trim) { -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] no PG, do nothing\n"); -+ -+ return; -+ } -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) { -+ pabias_2g = u8_get_bits(info->pa_bias_trim[i], GENMASK(3, 0)); -+ pabias_5g = u8_get_bits(info->pa_bias_trim[i], GENMASK(7, 4)); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", -+ i, pabias_2g, pabias_5g); -+ -+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); -+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); -+ } -+} -+ - static void rtw8851b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map) - { - static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = { -@@ -565,6 +619,12 @@ static void rtw8851b_rfe_gpio(struct rtw - } - } - -+static void rtw8851b_power_trim(struct rtw89_dev *rtwdev) -+{ -+ rtw8851b_thermal_trim(rtwdev); -+ rtw8851b_pa_bias_trim(rtwdev); -+} -+ - static void rtw8851b_set_channel_mac(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, - u8 mac_idx) -@@ -1355,6 +1415,195 @@ static void rtw8851b_set_channel_help(st - } - } - -+static u32 rtw8851b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx, s16 ref) -+{ -+ const u16 tssi_16dbm_cw = 0x12c; -+ const u8 base_cw_0db = 0x27; -+ const s8 ofst_int = 0; -+ s16 pwr_s10_3; -+ s16 rf_pwr_cw; -+ u16 bb_pwr_cw; -+ u32 pwr_cw; -+ u32 tssi_ofst_cw; -+ -+ pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); -+ bb_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(2, 0)); -+ rf_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(8, 3)); -+ rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); -+ pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; -+ -+ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", -+ tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); -+ -+ return u32_encode_bits(tssi_ofst_cw, B_DPD_TSSI_CW) | -+ u32_encode_bits(pwr_cw, B_DPD_PWR_CW) | -+ u32_encode_bits(ref, B_DPD_REF); -+} -+ -+static void rtw8851b_set_txpwr_ref(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ static const u32 addr[RF_PATH_NUM_8851B] = {0x5800}; -+ const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF; -+ const u8 ofst_ofdm = 0x4; -+ const u8 ofst_cck = 0x8; -+ const s16 ref_ofdm = 0; -+ const s16 ref_cck = 0; -+ u32 val; -+ u8 i; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); -+ -+ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, -+ B_AX_PWR_REF, 0x0); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); -+ val = rtw8851b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) -+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, -+ phy_idx); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); -+ val = rtw8851b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); -+ -+ for (i = 0; i < RF_PATH_NUM_8851B; i++) -+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, -+ phy_idx); -+} -+ -+static void rtw8851b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ u8 tx_shape_idx, -+ enum rtw89_phy_idx phy_idx) -+{ -+#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2)) -+#define __DFIR_CFG_MASK 0xffffffff -+#define __DFIR_CFG_NR 8 -+#define __DECL_DFIR_PARAM(_name, _val...) \ -+ static const u32 param_ ## _name[] = {_val}; \ -+ static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR) -+ -+ __DECL_DFIR_PARAM(flat, -+ 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053, -+ 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5); -+ __DECL_DFIR_PARAM(sharp, -+ 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090, -+ 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5); -+ __DECL_DFIR_PARAM(sharp_14, -+ 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, -+ 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); -+ u8 ch = chan->channel; -+ const u32 *param; -+ u32 addr; -+ int i; -+ -+ if (ch > 14) { -+ rtw89_warn(rtwdev, -+ "set tx shape dfir by unknown ch: %d on 2G\n", ch); -+ return; -+ } -+ -+ if (ch == 14) -+ param = param_sharp_14; -+ else -+ param = tx_shape_idx == 0 ? param_flat : param_sharp; -+ -+ for (i = 0; i < __DFIR_CFG_NR; i++) { -+ addr = __DFIR_CFG_ADDR(i); -+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, -+ "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]); -+ rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i], -+ phy_idx); -+ } -+ -+#undef __DECL_DFIR_PARAM -+#undef __DFIR_CFG_NR -+#undef __DFIR_CFG_MASK -+#undef __DECL_CFG_ADDR -+} -+ -+static void rtw8851b_set_tx_shape(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ u8 band = chan->band_type; -+ u8 regd = rtw89_regd_get(rtwdev, band); -+ u8 tx_shape_cck = rtw89_8851b_tx_shape[band][RTW89_RS_CCK][regd]; -+ u8 tx_shape_ofdm = rtw89_8851b_tx_shape[band][RTW89_RS_OFDM][regd]; -+ -+ if (band == RTW89_BAND_2G) -+ rtw8851b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx); -+ -+ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, -+ tx_shape_ofdm); -+} -+ -+static void rtw8851b_set_txpwr(struct rtw89_dev *rtwdev, -+ const struct rtw89_chan *chan, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx); -+ rtw8851b_set_tx_shape(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); -+ rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); -+} -+ -+static void rtw8851b_set_txpwr_ctrl(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8851b_set_txpwr_ref(rtwdev, phy_idx); -+} -+ -+static -+void rtw8851b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, -+ s8 pw_ofst, enum rtw89_mac_idx mac_idx) -+{ -+ u32 reg; -+ -+ if (pw_ofst < -16 || pw_ofst > 15) { -+ rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst); -+ return; -+ } -+ -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx); -+ rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); -+ -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx); -+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); -+ -+ pw_ofst = max_t(s8, pw_ofst - 3, -16); -+ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); -+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); -+} -+ -+static int -+rtw8851b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) -+{ -+ int ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000); -+ if (ret) -+ return ret; -+ -+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); -+ if (ret) -+ return ret; -+ -+ rtw8851b_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? -+ RTW89_MAC_1 : RTW89_MAC_0); -+ -+ return 0; -+} -+ - static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -1711,6 +1960,11 @@ static const struct rtw89_chip_ops rtw88 - .read_phycap = rtw8851b_read_phycap, - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, -+ .power_trim = rtw8851b_power_trim, -+ .set_txpwr = rtw8851b_set_txpwr, -+ .set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl, -+ .init_txpwr_unit = rtw8851b_init_txpwr_unit, -+ .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8851b_pwr_on_func, - .pwr_off_func = rtw8851b_pwr_off_func, - .fill_txdesc = rtw89_core_fill_txdesc, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-107-wifi-rtw89-8851b-fill-BB-related-capabilities-to-chi.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-107-wifi-rtw89-8851b-fill-BB-related-capabilities-to-chi.patch deleted file mode 100644 index 0bbbbc485..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-107-wifi-rtw89-8851b-fill-BB-related-capabilities-to-chi.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 68a2cb6b0669bf96bbb203cbb81e57ad122ded42 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:14:55 +0800 -Subject: [PATCH 107/136] wifi: rtw89: 8851b: fill BB related capabilities to - chip_info - -These capabilities include helpers of BT coexistence, RX PPDU status -parser, DIG (dynamic initial gain) and CFO (center frequency offset) -settings. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 2 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 199 ++++++++++++++++++ - 2 files changed, 201 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -4398,6 +4398,8 @@ - #define B_PATH0_BT_BACKOFF_V1 GENMASK(23, 0) - #define R_PATH1_BT_BACKOFF_V1 0x4AEC - #define B_PATH1_BT_BACKOFF_V1 GENMASK(23, 0) -+#define R_DCFO_COMP_S0_V2 0x4B20 -+#define B_DCFO_COMP_S0_MSK_V2 GENMASK(13, 0) - #define R_PATH0_TX_CFR 0x4B30 - #define B_PATH0_TX_CFR_LGC1 GENMASK(19, 10) - #define B_PATH0_TX_CFR_LGC0 GENMASK(9, 0) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -68,12 +68,63 @@ static const struct rtw89_dle_mem rtw885 - NULL}, - }; - -+static const struct rtw89_reg3_def rtw8851b_btc_preagc_en_defs[] = { -+ {0x46D0, GENMASK(1, 0), 0x3}, -+ {0x4AD4, GENMASK(31, 0), 0xf}, -+ {0x4688, GENMASK(23, 16), 0x80}, -+ {0x4688, GENMASK(31, 24), 0x80}, -+ {0x4694, GENMASK(7, 0), 0x80}, -+ {0x4694, GENMASK(15, 8), 0x80}, -+ {0x4AE4, GENMASK(11, 6), 0x34}, -+ {0x4AE4, GENMASK(17, 12), 0x0}, -+ {0x469C, GENMASK(31, 26), 0x34}, -+}; -+ -+static DECLARE_PHY_REG3_TBL(rtw8851b_btc_preagc_en_defs); -+ -+static const struct rtw89_reg3_def rtw8851b_btc_preagc_dis_defs[] = { -+ {0x46D0, GENMASK(1, 0), 0x0}, -+ {0x4AD4, GENMASK(31, 0), 0x60}, -+ {0x4688, GENMASK(23, 16), 0x10}, -+ {0x4690, GENMASK(31, 24), 0x2a}, -+ {0x4694, GENMASK(15, 8), 0x2a}, -+ {0x4AE4, GENMASK(11, 6), 0x26}, -+ {0x4AE4, GENMASK(17, 12), 0x1e}, -+ {0x469C, GENMASK(31, 26), 0x26}, -+}; -+ -+static DECLARE_PHY_REG3_TBL(rtw8851b_btc_preagc_dis_defs); -+ -+static const struct rtw89_reg_def rtw8851b_dcfo_comp = { -+ R_DCFO_COMP_S0_V2, B_DCFO_COMP_S0_MSK_V2 -+}; -+ - static const struct rtw89_xtal_info rtw8851b_xtal_info = { - .xcap_reg = R_AX_XTAL_ON_CTRL3, - .sc_xo_mask = B_AX_XTAL_SC_XO_A_BLOCK_MASK, - .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, - }; - -+static const struct rtw89_dig_regs rtw8851b_dig_regs = { -+ .seg0_pd_reg = R_SEG0R_PD_V1, -+ .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, -+ .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1, -+ .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK}, -+ .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK}, -+ .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1}, -+ .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1}, -+ .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1}, -+ .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1}, -+ .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+ .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2, -+ B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, -+}; -+ - static const struct rtw89_btc_rf_trx_para rtw89_btc_8851b_rf_ul[] = { - {255, 0, 0, 7}, /* 0 -> original */ - {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ -@@ -1604,6 +1655,112 @@ rtw8851b_init_txpwr_unit(struct rtw89_de - return 0; - } - -+static void rtw8851b_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8851b_btc_preagc_en_defs_tbl : -+ &rtw8851b_btc_preagc_dis_defs_tbl); -+ -+ if (!bt_en) { -+ if (chan->band_type == RTW89_BAND_2G) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, -+ B_PATH0_G_LNA6_OP1DB_V1, 0x20); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x30); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, -+ B_PATH0_G_LNA6_OP1DB_V1, 0x1a); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a); -+ } -+ } -+} -+ -+static void rtw8851b_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ -+ if (btg) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, -+ B_PATH0_G_LNA6_OP1DB_V1, 0x20); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x30); -+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1, -+ B_PATH0_BT_SHARE_V1, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1, -+ B_PATH0_BTG_PATH_V1, 0x0); -+ if (chan->band_type == RTW89_BAND_2G) { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, -+ B_PATH0_G_LNA6_OP1DB_V1, 0x80); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x80); -+ } else { -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_LNA6_OP1DB_V1, -+ B_PATH0_G_LNA6_OP1DB_V1, 0x1a); -+ rtw89_phy_write32_mask(rtwdev, R_PATH0_G_TIA0_LNA6_OP1DB_V1, -+ B_PATH0_G_TIA0_LNA6_OP1DB_V1, 0x2a); -+ } -+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc); -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0); -+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1, -+ B_BT_DYN_DC_EST_EN_MSK, 0x1); -+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); -+ } -+} -+ -+static void rtw8851b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, -+ enum rtw89_rf_path_bit rx_path) -+{ -+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); -+ u32 rst_mask0; -+ -+ if (rx_path == RF_A) { -+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1); -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); -+ } -+ -+ rtw8851b_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0); -+ -+ rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; -+ if (rx_path == RF_A) { -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); -+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); -+ } -+} -+ -+static void rtw8851b_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) -+{ -+ rtw8851b_bb_ctrl_rx_path(rtwdev, RF_A); -+ -+ if (rtwdev->hal.rx_nss == 1) { -+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); -+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0); -+ } -+ -+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); -+} -+ - static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -1895,6 +2052,39 @@ static void rtw8851b_btc_set_wl_rx_gain( - } - } - -+static void rtw8851b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu, -+ struct ieee80211_rx_status *status) -+{ -+ u16 chan = phy_ppdu->chan_idx; -+ enum nl80211_band band; -+ u8 ch; -+ -+ if (chan == 0) -+ return; -+ -+ rtw89_decode_chan_idx(rtwdev, chan, &ch, &band); -+ status->freq = ieee80211_channel_to_frequency(ch, band); -+ status->band = band; -+} -+ -+static void rtw8851b_query_ppdu(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_phy_ppdu *phy_ppdu, -+ struct ieee80211_rx_status *status) -+{ -+ u8 path; -+ u8 *rx_power = phy_ppdu->rssi; -+ -+ status->signal = RTW89_RSSI_RAW_TO_DBM(rx_power[RF_PATH_A]); -+ -+ for (path = 0; path < rtwdev->chip->rf_path_num; path++) { -+ status->chains |= BIT(path); -+ status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]); -+ } -+ if (phy_ppdu->valid) -+ rtw8851b_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); -+} -+ - static int rtw8851b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) - { - int ret; -@@ -1964,6 +2154,10 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr = rtw8851b_set_txpwr, - .set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8851b_init_txpwr_unit, -+ .ctrl_btg = rtw8851b_ctrl_btg, -+ .query_ppdu = rtw8851b_query_ppdu, -+ .bb_ctrl_btc_preagc = rtw8851b_bb_ctrl_btc_preagc, -+ .cfg_txrx_path = rtw8851b_bb_cfg_txrx_path, - .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8851b_pwr_on_func, - .pwr_off_func = rtw8851b_pwr_off_func, -@@ -2021,6 +2215,7 @@ const struct rtw89_chip_info rtw8851b_ch - .txpwr_factor_rf = 2, - .txpwr_factor_mac = 1, - .dig_table = NULL, -+ .dig_regs = &rtw8851b_dig_regs, - .tssi_dbw_table = NULL, - .support_chanctx_num = 0, - .support_bands = BIT(NL80211_BAND_2GHZ) | -@@ -2069,6 +2264,10 @@ const struct rtw89_chip_info rtw8851b_ch - .hci_func_en_addr = R_AX_HCI_FUNC_EN, - .h2c_desc_size = sizeof(struct rtw89_txwd_body), - .txwd_body_size = sizeof(struct rtw89_txwd_body), -+ .cfo_src_fd = true, -+ .cfo_hw_comp = true, -+ .dcfo_comp = &rtw8851b_dcfo_comp, -+ .dcfo_comp_sft = 12, - .bss_clr_map_reg = R_BSS_CLR_MAP_V1, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-108-wifi-rtw89-8851b-add-MAC-configurations-to-chip_info.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-108-wifi-rtw89-8851b-add-MAC-configurations-to-chip_info.patch deleted file mode 100644 index d39f154ba..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-108-wifi-rtw89-8851b-add-MAC-configurations-to-chip_info.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 92aa2643235d72bb01206259362d4e0a845ba02a Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:14:56 +0800 -Subject: [PATCH 108/136] wifi: rtw89: 8851b: add MAC configurations to - chip_info - -These configurations include path control, TX grant, TX scheduler, -register-based H2C/C2H and so on. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 89 +++++++++++++++++++ - 1 file changed, 89 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -95,16 +95,92 @@ static const struct rtw89_reg3_def rtw88 - - static DECLARE_PHY_REG3_TBL(rtw8851b_btc_preagc_dis_defs); - -+static const u32 rtw8851b_h2c_regs[RTW89_H2CREG_MAX] = { -+ R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2, -+ R_AX_H2CREG_DATA3 -+}; -+ -+static const u32 rtw8851b_c2h_regs[RTW89_C2HREG_MAX] = { -+ R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2, -+ R_AX_C2HREG_DATA3 -+}; -+ -+static const struct rtw89_page_regs rtw8851b_page_regs = { -+ .hci_fc_ctrl = R_AX_HCI_FC_CTRL, -+ .ch_page_ctrl = R_AX_CH_PAGE_CTRL, -+ .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL, -+ .ach_page_info = R_AX_ACH0_PAGE_INFO, -+ .pub_page_info3 = R_AX_PUB_PAGE_INFO3, -+ .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1, -+ .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2, -+ .pub_page_info1 = R_AX_PUB_PAGE_INFO1, -+ .pub_page_info2 = R_AX_PUB_PAGE_INFO2, -+ .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1, -+ .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2, -+ .wp_page_info1 = R_AX_WP_PAGE_INFO1, -+}; -+ - static const struct rtw89_reg_def rtw8851b_dcfo_comp = { - R_DCFO_COMP_S0_V2, B_DCFO_COMP_S0_MSK_V2 - }; - -+static const struct rtw89_imr_info rtw8851b_imr_info = { -+ .wdrls_imr_set = B_AX_WDRLS_IMR_SET, -+ .wsec_imr_reg = R_AX_SEC_DEBUG, -+ .wsec_imr_set = B_AX_IMR_ERROR, -+ .mpdu_tx_imr_set = 0, -+ .mpdu_rx_imr_set = 0, -+ .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET, -+ .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR, -+ .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR, -+ .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET, -+ .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1, -+ .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR, -+ .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET, -+ .wde_imr_clr = B_AX_WDE_IMR_CLR, -+ .wde_imr_set = B_AX_WDE_IMR_SET, -+ .ple_imr_clr = B_AX_PLE_IMR_CLR, -+ .ple_imr_set = B_AX_PLE_IMR_SET, -+ .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR, -+ .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET, -+ .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR, -+ .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET, -+ .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR, -+ .other_disp_imr_set = 0, -+ .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR, -+ .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR, -+ .bbrpt_err_imr_set = 0, -+ .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR, -+ .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL, -+ .ptcl_imr_set = B_AX_PTCL_IMR_SET, -+ .cdma_imr_0_reg = R_AX_DLE_CTRL, -+ .cdma_imr_0_clr = B_AX_DLE_IMR_CLR, -+ .cdma_imr_0_set = B_AX_DLE_IMR_SET, -+ .cdma_imr_1_reg = 0, -+ .cdma_imr_1_clr = 0, -+ .cdma_imr_1_set = 0, -+ .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR, -+ .phy_intf_imr_clr = 0, -+ .phy_intf_imr_set = 0, -+ .rmac_imr_reg = R_AX_RMAC_ERR_ISR, -+ .rmac_imr_clr = B_AX_RMAC_IMR_CLR, -+ .rmac_imr_set = B_AX_RMAC_IMR_SET, -+ .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR, -+ .tmac_imr_clr = B_AX_TMAC_IMR_CLR, -+ .tmac_imr_set = B_AX_TMAC_IMR_SET, -+}; -+ - static const struct rtw89_xtal_info rtw8851b_xtal_info = { - .xcap_reg = R_AX_XTAL_ON_CTRL3, - .sc_xo_mask = B_AX_XTAL_SC_XO_A_BLOCK_MASK, - .sc_xi_mask = B_AX_XTAL_SC_XI_A_BLOCK_MASK, - }; - -+static const struct rtw89_rrsr_cfgs rtw8851b_rrsr_cfgs = { -+ .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0}, -+ .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2}, -+}; -+ - static const struct rtw89_dig_regs rtw8851b_dig_regs = { - .seg0_pd_reg = R_SEG0R_PD_V1, - .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK, -@@ -2163,6 +2239,10 @@ static const struct rtw89_chip_ops rtw88 - .pwr_off_func = rtw8851b_pwr_off_func, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, -+ .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, -+ .mac_cfg_gnt = rtw89_mac_cfg_gnt, -+ .stop_sch_tx = rtw89_mac_stop_sch_tx, -+ .resume_sch_tx = rtw89_mac_resume_sch_tx, - .h2c_dctl_sec_cam = NULL, - - .btc_set_rfe = rtw8851b_btc_set_rfe, -@@ -2264,10 +2344,19 @@ const struct rtw89_chip_info rtw8851b_ch - .hci_func_en_addr = R_AX_HCI_FUNC_EN, - .h2c_desc_size = sizeof(struct rtw89_txwd_body), - .txwd_body_size = sizeof(struct rtw89_txwd_body), -+ .h2c_ctrl_reg = R_AX_H2CREG_CTRL, -+ .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, -+ .h2c_regs = rtw8851b_h2c_regs, -+ .c2h_ctrl_reg = R_AX_C2HREG_CTRL, -+ .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, -+ .c2h_regs = rtw8851b_c2h_regs, -+ .page_regs = &rtw8851b_page_regs, - .cfo_src_fd = true, - .cfo_hw_comp = true, - .dcfo_comp = &rtw8851b_dcfo_comp, - .dcfo_comp_sft = 12, -+ .imr_info = &rtw8851b_imr_info, -+ .rrsr_cfgs = &rtw8851b_rrsr_cfgs, - .bss_clr_map_reg = R_BSS_CLR_MAP_V1, - .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | - BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-109-wifi-rtw89-8851b-add-RF-configurations.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-109-wifi-rtw89-8851b-add-RF-configurations.patch deleted file mode 100644 index a22d8579a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-109-wifi-rtw89-8851b-add-RF-configurations.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 791af3fb2decc11b2994f7020378dffecd654fcd Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:14:57 +0800 -Subject: [PATCH 109/136] wifi: rtw89: 8851b: add RF configurations - -RF configurations include RF calibrations and getting thermal value. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 61 +++++++++++++++++++ - 1 file changed, 61 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -1542,6 +1542,44 @@ static void rtw8851b_set_channel_help(st - } - } - -+static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev) -+{ -+ rtwdev->is_tssi_mode[RF_PATH_A] = false; -+ rtwdev->is_tssi_mode[RF_PATH_B] = false; -+ -+ rtw8851b_dpk_init(rtwdev); -+ rtw8851b_aack(rtwdev); -+ rtw8851b_rck(rtwdev); -+ rtw8851b_dack(rtwdev); -+ rtw8851b_rx_dck(rtwdev, RTW89_PHY_0); -+} -+ -+static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev) -+{ -+ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; -+ -+ rtw8851b_rx_dck(rtwdev, phy_idx); -+ rtw8851b_iqk(rtwdev, phy_idx); -+ rtw8851b_tssi(rtwdev, phy_idx, true); -+ rtw8851b_dpk(rtwdev, phy_idx); -+} -+ -+static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev, -+ enum rtw89_phy_idx phy_idx) -+{ -+ rtw8851b_tssi_scan(rtwdev, phy_idx); -+} -+ -+static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, bool start) -+{ -+ rtw8851b_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); -+} -+ -+static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev) -+{ -+ rtw8851b_dpk_track(rtwdev); -+} -+ - static u32 rtw8851b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, - enum rtw89_phy_idx phy_idx, s16 ref) - { -@@ -1837,6 +1875,23 @@ static void rtw8851b_bb_cfg_txrx_path(st - rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); - } - -+static u8 rtw8851b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) -+{ -+ if (rtwdev->is_tssi_mode[rf_path]) { -+ u32 addr = R_TSSI_THER + (rf_path << 13); -+ -+ return rtw89_phy_read32_mask(rtwdev, addr, B_TSSI_THER); -+ } -+ -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); -+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); -+ -+ fsleep(200); -+ -+ return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); -+} -+ - static void rtw8851b_btc_set_rfe(struct rtw89_dev *rtwdev) - { - struct rtw89_btc *btc = &rtwdev->btc; -@@ -2226,10 +2281,16 @@ static const struct rtw89_chip_ops rtw88 - .read_phycap = rtw8851b_read_phycap, - .fem_setup = NULL, - .rfe_gpio = rtw8851b_rfe_gpio, -+ .rfk_init = rtw8851b_rfk_init, -+ .rfk_channel = rtw8851b_rfk_channel, -+ .rfk_band_changed = rtw8851b_rfk_band_changed, -+ .rfk_scan = rtw8851b_rfk_scan, -+ .rfk_track = rtw8851b_rfk_track, - .power_trim = rtw8851b_power_trim, - .set_txpwr = rtw8851b_set_txpwr, - .set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl, - .init_txpwr_unit = rtw8851b_init_txpwr_unit, -+ .get_thermal = rtw8851b_get_thermal, - .ctrl_btg = rtw8851b_ctrl_btg, - .query_ppdu = rtw8851b_query_ppdu, - .bb_ctrl_btc_preagc = rtw8851b_bb_ctrl_btc_preagc, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-110-wifi-rtw89-enlarge-supported-length-of-read_reg-debu.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-110-wifi-rtw89-enlarge-supported-length-of-read_reg-debu.patch deleted file mode 100644 index 2cbe76a79..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-110-wifi-rtw89-enlarge-supported-length-of-read_reg-debu.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 4cfad52a5df718a615f8de5ba14370d99537db4c Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:14:58 +0800 -Subject: [PATCH 110/136] wifi: rtw89: enlarge supported length of read_reg - debugfs entry - -The register ranges of upcoming chips are different from current, and even -existing chips have different ranges, so support longer length to dump -registers. Then, user space can decide the ranges according to chip. - -Since arbitrary length (e.g. 7) would be a little complicated, so simply -make length a multiple of 16. The output looks like - -18620000h : 8580801f 82828282 82828282 080800fd - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 23 +++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -30,7 +30,7 @@ struct rtw89_debugfs_priv { - u32 cb_data; - struct { - u32 addr; -- u8 len; -+ u32 len; - } read_reg; - struct { - u32 addr; -@@ -164,12 +164,15 @@ static int rtw89_debug_priv_read_reg_get - { - struct rtw89_debugfs_priv *debugfs_priv = m->private; - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -- u32 addr, data; -- u8 len; -+ u32 addr, end, data, k; -+ u32 len; - - len = debugfs_priv->read_reg.len; - addr = debugfs_priv->read_reg.addr; - -+ if (len > 4) -+ goto ndata; -+ - switch (len) { - case 1: - data = rtw89_read8(rtwdev, addr); -@@ -188,6 +191,20 @@ static int rtw89_debug_priv_read_reg_get - seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data); - - return 0; -+ -+ndata: -+ end = addr + len; -+ -+ for (; addr < end; addr += 16) { -+ seq_printf(m, "%08xh : ", 0x18600000 + addr); -+ for (k = 0; k < 16; k += 4) { -+ data = rtw89_read32(rtwdev, addr + k); -+ seq_printf(m, "%08x ", data); -+ } -+ seq_puts(m, "\n"); -+ } -+ -+ return 0; - } - - static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-111-wifi-rtw89-add-tx_wake-notify-for-8851B.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-111-wifi-rtw89-add-tx_wake-notify-for-8851B.patch deleted file mode 100644 index 329b069ff..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-111-wifi-rtw89-add-tx_wake-notify-for-8851B.patch +++ /dev/null @@ -1,27 +0,0 @@ -From c4ff50149885723f24ef9bc3b0220ee20bca3e03 Mon Sep 17 00:00:00 2001 -From: Chin-Yen Lee -Date: Fri, 19 May 2023 11:14:59 +0800 -Subject: [PATCH 111/136] wifi: rtw89: add tx_wake notify for 8851B - -8851B has the same issue: management frames get stuck when WiFi -chip enters low PS mode, so we also add notify wake function to -trigger WiFi chip wake before forwarding management frames. - -Signed-off-by: Chin-Yen Lee -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -256,6 +256,7 @@ struct __fw_feat_cfg { - } - - static const struct __fw_feat_cfg fw_feat_tbl[] = { -+ __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), - __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-112-wifi-rtw89-8851b-add-8851be-to-Makefile-and-Kconfig.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-112-wifi-rtw89-8851b-add-8851be-to-Makefile-and-Kconfig.patch deleted file mode 100644 index 3927f7fde..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-112-wifi-rtw89-8851b-add-8851be-to-Makefile-and-Kconfig.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 14820388aafb10cd051b0883e92326f5f2012ed4 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 19 May 2023 11:15:00 +0800 -Subject: [PATCH 112/136] wifi: rtw89: 8851b: add 8851be to Makefile and - Kconfig - -Since 8851BE is ready, so add 8851BE to Makefile and Kconfig. Currently, -it can support STA, AP and monitor modes with good performance. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230519031500.21087-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/Kconfig | 14 ++++++++++++++ - drivers/net/wireless/realtek/rtw89/Makefile | 9 +++++++++ - 2 files changed, 23 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/Kconfig -+++ b/drivers/net/wireless/realtek/rtw89/Kconfig -@@ -19,6 +19,9 @@ config RTW89_PCI - tristate - depends on m - -+config RTW89_8851B -+ tristate -+ - config RTW89_8852A - tristate - depends on m -@@ -31,6 +34,17 @@ config RTW89_8852C - tristate - depends on m - -+config RTW89_8851BE -+ tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter" -+ depends on PCI -+ select RTW89_CORE -+ select RTW89_PCI -+ select RTW89_8851B -+ help -+ Select this option will enable support for 8851BE chipset -+ -+ 802.11ax PCIe wireless network (Wi-Fi 6) adapter -+ - config RTW89_8852AE - tristate "Realtek 8852AE PCI wireless network (Wi-Fi 6) adapter" - depends on m ---- a/drivers/net/wireless/realtek/rtw89/Makefile -+++ b/drivers/net/wireless/realtek/rtw89/Makefile -@@ -18,6 +18,15 @@ rtw89_core-y += core.o \ - - rtw89_core-$(CPTCFG_PM) += wow.o - -+obj-$(CPTCFG_RTW89_8851B) += rtw89_8851b.o -+rtw89_8851b-objs := rtw8851b.o \ -+ rtw8851b_table.o \ -+ rtw8851b_rfk.o \ -+ rtw8851b_rfk_table.o -+ -+obj-$(CPTCFG_RTW89_8851BE) += rtw89_8851be.o -+rtw89_8851be-objs := rtw8851be.o -+ - obj-$(CPTCFG_RTW89_8852A) += rtw89_8852a.o - rtw89_8852a-objs := rtw8852a.o \ - rtw8852a_table.o \ diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-113-wifi-rtw89-add-chip_ops-query_rxdesc-and-rxd_len-as-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-113-wifi-rtw89-add-chip_ops-query_rxdesc-and-rxd_len-as-.patch deleted file mode 100644 index c23866c1a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-113-wifi-rtw89-add-chip_ops-query_rxdesc-and-rxd_len-as-.patch +++ /dev/null @@ -1,151 +0,0 @@ -From de9f93385d0f318b3eba0c1026fd2ec8fba2e982 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 22 May 2023 20:25:09 +0800 -Subject: [PATCH 113/136] wifi: rtw89: add chip_ops::query_rxdesc() and rxd_len - as helpers to support newer chips - -The next generation chips use different RX descriptor format, so add -a chip_ops to hook suitable handlers. Also, the length of RX descriptor is -different, so add a variable to store the length according to chip and -descriptor content dynamically. Then, the code can be more general. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522122513.13559-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 4 ++++ - drivers/net/wireless/realtek/rtw89/core.h | 14 ++++++++++++++ - drivers/net/wireless/realtek/rtw89/pci.c | 12 ++++-------- - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + - drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + - 7 files changed, 26 insertions(+), 8 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1819,6 +1819,10 @@ void rtw89_core_query_rxdesc(struct rtw8 - shift_len = desc_info->shift << 1; /* 2-byte unit */ - drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ - desc_info->offset = data_offset + shift_len + drv_info_len; -+ if (desc_info->long_rxdesc) -+ desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long); -+ else -+ desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short); - desc_info->ready = true; - - if (!desc_info->long_rxdesc) ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -776,6 +776,7 @@ struct rtw89_rx_desc_info { - u8 sec_cam_id; - u8 mac_id; - u16 offset; -+ u16 rxd_len; - bool ready; - }; - -@@ -2824,6 +2825,9 @@ struct rtw89_chip_ops { - s8 pw_ofst, enum rtw89_mac_idx mac_idx); - int (*pwr_on_func)(struct rtw89_dev *rtwdev); - int (*pwr_off_func)(struct rtw89_dev *rtwdev); -+ void (*query_rxdesc)(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_desc_info *desc_info, -+ u8 *data, u32 data_offset); - void (*fill_txdesc)(struct rtw89_dev *rtwdev, - struct rtw89_tx_desc_info *desc_info, - void *txdesc); -@@ -4856,6 +4860,16 @@ static inline void rtw89_ctrl_btg(struct - } - - static inline -+void rtw89_chip_query_rxdesc(struct rtw89_dev *rtwdev, -+ struct rtw89_rx_desc_info *desc_info, -+ u8 *data, u32 data_offset) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ -+ chip->ops->query_rxdesc(rtwdev, desc_info, data, data_offset); -+} -+ -+static inline - void rtw89_chip_fill_txdesc(struct rtw89_dev *rtwdev, - struct rtw89_tx_desc_info *desc_info, - void *txdesc) ---- a/drivers/net/wireless/realtek/rtw89/pci.c -+++ b/drivers/net/wireless/realtek/rtw89/pci.c -@@ -265,7 +265,7 @@ static u32 rtw89_pci_rxbd_deliver_skbs(s - goto err_sync_device; - } - -- rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); -+ rtw89_chip_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); - - new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size); - if (!new) -@@ -274,9 +274,7 @@ static u32 rtw89_pci_rxbd_deliver_skbs(s - rx_ring->diliver_skb = new; - - /* first segment has RX desc */ -- offset = desc_info->offset; -- offset += desc_info->long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : -- sizeof(struct rtw89_rxdesc_short); -+ offset = desc_info->offset + desc_info->rxd_len; - } else { - offset = sizeof(struct rtw89_pci_rxbd_info); - if (!new) { -@@ -546,12 +544,10 @@ static u32 rtw89_pci_release_tx_skbs(str - return cnt; - } - -- rtw89_core_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size); -+ rtw89_chip_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size); - - /* first segment has RX desc */ -- offset = desc_info.offset; -- offset += desc_info.long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : -- sizeof(struct rtw89_rxdesc_short); -+ offset = desc_info.offset + desc_info.rxd_len; - for (; offset + rpp_size <= rx_info->len; offset += rpp_size) { - rpp = (struct rtw89_pci_rpp_fmt *)(skb->data + offset); - rtw89_pci_release_rpp(rtwdev, rpp); ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -2298,6 +2298,7 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8851b_pwr_on_func, - .pwr_off_func = rtw8851b_pwr_off_func, -+ .query_rxdesc = rtw89_core_query_rxdesc, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -2050,6 +2050,7 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, - .pwr_on_func = NULL, - .pwr_off_func = NULL, -+ .query_rxdesc = rtw89_core_query_rxdesc, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c -@@ -2472,6 +2472,7 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr_ul_tb_offset = rtw8852b_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8852b_pwr_on_func, - .pwr_off_func = rtw8852b_pwr_off_func, -+ .query_rxdesc = rtw89_core_query_rxdesc, - .fill_txdesc = rtw89_core_fill_txdesc, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, - .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c -@@ -2780,6 +2780,7 @@ static const struct rtw89_chip_ops rtw88 - .set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset, - .pwr_on_func = rtw8852c_pwr_on_func, - .pwr_off_func = rtw8852c_pwr_off_func, -+ .query_rxdesc = rtw89_core_query_rxdesc, - .fill_txdesc = rtw89_core_fill_txdesc_v1, - .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1, - .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-114-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-114-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch deleted file mode 100644 index bb6bff1cc..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-114-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 88bdc3ff956cd9267777ae8557de46bbf2d49e32 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 22 May 2023 20:25:10 +0800 -Subject: [PATCH 114/136] wifi: rtw89: use struct and le32_get_bits to access - RX info - -If received packet type is PPDU status, RX info provides information -attached by MAC hardware, and mention how long BB information attached. - -This conversion patch doesn't change logic at all. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522122513.13559-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 7 +-- - drivers/net/wireless/realtek/rtw89/txrx.h | 53 +++++++++++------------ - 2 files changed, 29 insertions(+), 31 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1213,14 +1213,15 @@ static int rtw89_core_rx_process_mac_ppd - struct sk_buff *skb, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { -+ const struct rtw89_rxinfo *rxinfo = (const struct rtw89_rxinfo *)skb->data; - bool rx_cnt_valid = false; - u8 plcp_size = 0; - u8 usr_num = 0; - u8 *phy_sts; - -- rx_cnt_valid = RTW89_GET_RXINFO_RX_CNT_VLD(skb->data); -- plcp_size = RTW89_GET_RXINFO_PLCP_LEN(skb->data) << 3; -- usr_num = RTW89_GET_RXINFO_USR_NUM(skb->data); -+ rx_cnt_valid = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_RX_CNT_VLD); -+ plcp_size = le32_get_bits(rxinfo->w1, RTW89_RXINFO_W1_PLCP_LEN) << 3; -+ usr_num = le32_get_bits(rxinfo->w0, RTW89_RXINFO_W0_USR_NUM); - if (usr_num > RTW89_PPDU_MAX_USR) { - rtw89_warn(rtwdev, "Invalid user number in mac info\n"); - return -EINVAL; ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -251,34 +251,31 @@ - #define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \ - le32_get_bits((rxdesc)->dword5, GENMASK(7, 0)) - --#define RTW89_GET_RXINFO_USR_NUM(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), GENMASK(3, 0)) --#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), GENMASK(15, 8)) --#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), GENMASK(27, 16)) --#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), BIT(28)) --#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), BIT(29)) --#define RTW89_GET_RXINFO_LONG_RXD(rpt) \ -- le32_get_bits(*((const __le32 *)rpt), GENMASK(31, 30)) --#define RTW89_GET_RXINFO_SERVICE(rpt) \ -- le32_get_bits(*((const __le32 *)(rpt) + 1), GENMASK(15, 0)) --#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \ -- le32_get_bits(*((const __le32 *)(rpt) + 1), GENMASK(23, 16)) --#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(0)) --#define RTW89_GET_RXINFO_DATA(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(1)) --#define RTW89_GET_RXINFO_CTRL(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(2)) --#define RTW89_GET_RXINFO_MGMT(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(3)) --#define RTW89_GET_RXINFO_BCM(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), BIT(4)) --#define RTW89_GET_RXINFO_MACID(rpt, usr) \ -- le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), GENMASK(15, 8)) -+struct rtw89_rxinfo_user { -+ __le32 w0; -+}; -+ -+#define RTW89_RXINFO_USER_MAC_ID_VALID BIT(0) -+#define RTW89_RXINFO_USER_DATA BIT(1) -+#define RTW89_RXINFO_USER_CTRL BIT(2) -+#define RTW89_RXINFO_USER_MGMT BIT(3) -+#define RTW89_RXINFO_USER_BCM BIT(4) -+#define RTW89_RXINFO_USER_MACID GENMASK(15, 8) -+ -+struct rtw89_rxinfo { -+ __le32 w0; -+ __le32 w1; -+ struct rtw89_rxinfo_user user[]; -+} __packed; -+ -+#define RTW89_RXINFO_W0_USR_NUM GENMASK(3, 0) -+#define RTW89_RXINFO_W0_FW_DEFINE GENMASK(15, 8) -+#define RTW89_RXINFO_W0_LSIG_LEN GENMASK(27, 16) -+#define RTW89_RXINFO_W0_IS_TO_SELF BIT(28) -+#define RTW89_RXINFO_W0_RX_CNT_VLD BIT(29) -+#define RTW89_RXINFO_W0_LONG_RXD GENMASK(31, 30) -+#define RTW89_RXINFO_W1_SERVICE GENMASK(15, 0) -+#define RTW89_RXINFO_W1_PLCP_LEN GENMASK(23, 16) - - #define RTW89_GET_PHY_STS_IE_MAP(sts) \ - le32_get_bits(*((const __le32 *)(sts)), GENMASK(4, 0)) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-115-wifi-rtw89-use-struct-and-le32_get_bits-to-access-re.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-115-wifi-rtw89-use-struct-and-le32_get_bits-to-access-re.patch deleted file mode 100644 index 10c45d33b..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-115-wifi-rtw89-use-struct-and-le32_get_bits-to-access-re.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 332debb80488e98f6083238bdf61e6f953d5c180 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 22 May 2023 20:25:11 +0800 -Subject: [PATCH 115/136] wifi: rtw89: use struct and le32_get_bits() to access - received PHY status IEs - -PHY status IEs generated by BB hardware is to provide more detail -information related to received packets, such as RSSI and bandwidth. - -To avoid type casting, change buf type from u8* to void* as well. - -This patch doesn't change logic at all. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522122513.13559-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 53 ++++++++++++++--------- - drivers/net/wireless/realtek/rtw89/core.h | 2 +- - drivers/net/wireless/realtek/rtw89/txrx.h | 37 ++++++++-------- - 3 files changed, 52 insertions(+), 40 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1280,7 +1280,8 @@ static void rtw89_core_rx_process_phy_pp - - #define VAR_LEN 0xff - #define VAR_LEN_UNIT 8 --static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, u8 *addr) -+static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, -+ const struct rtw89_phy_sts_iehdr *iehdr) - { - static const u8 physts_ie_len_tab[32] = { - 16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, -@@ -1290,19 +1291,20 @@ static u16 rtw89_core_get_phy_status_ie_ - u16 ie_len; - u8 ie; - -- ie = RTW89_GET_PHY_STS_IE_TYPE(addr); -+ ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); - if (physts_ie_len_tab[ie] != VAR_LEN) - ie_len = physts_ie_len_tab[ie]; - else -- ie_len = RTW89_GET_PHY_STS_IE_LEN(addr) * VAR_LEN_UNIT; -+ ie_len = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_LEN) * VAR_LEN_UNIT; - - return ie_len; - } - --static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, -+static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, -+ const struct rtw89_phy_sts_iehdr *iehdr, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { -- const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)addr; -+ const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)iehdr; - s16 cfo; - u32 t; - -@@ -1330,15 +1332,17 @@ static void rtw89_core_parse_phy_status_ - rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); - } - --static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, u8 *addr, -+static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, -+ const struct rtw89_phy_sts_iehdr *iehdr, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { - u8 ie; - -- ie = RTW89_GET_PHY_STS_IE_TYPE(addr); -+ ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); -+ - switch (ie) { - case RTW89_PHYSTS_IE01_CMN_OFDM: -- rtw89_core_parse_phy_status_ie01(rtwdev, addr, phy_ppdu); -+ rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu); - break; - default: - break; -@@ -1349,21 +1353,26 @@ static int rtw89_core_process_phy_status - - static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu) - { -+ const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; - u8 *rssi = phy_ppdu->rssi; -- u8 *buf = phy_ppdu->buf; - -- phy_ppdu->ie = RTW89_GET_PHY_STS_IE_MAP(buf); -- phy_ppdu->rssi_avg = RTW89_GET_PHY_STS_RSSI_AVG(buf); -- rssi[RF_PATH_A] = RTW89_GET_PHY_STS_RSSI_A(buf); -- rssi[RF_PATH_B] = RTW89_GET_PHY_STS_RSSI_B(buf); -- rssi[RF_PATH_C] = RTW89_GET_PHY_STS_RSSI_C(buf); -- rssi[RF_PATH_D] = RTW89_GET_PHY_STS_RSSI_D(buf); -+ phy_ppdu->ie = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_IE_MAP); -+ phy_ppdu->rssi_avg = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_RSSI_AVG); -+ rssi[RF_PATH_A] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_A); -+ rssi[RF_PATH_B] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_B); -+ rssi[RF_PATH_C] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_C); -+ rssi[RF_PATH_D] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_D); - } - - static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev, - struct rtw89_rx_phy_ppdu *phy_ppdu) - { -- if (RTW89_GET_PHY_STS_LEN(phy_ppdu->buf) << 3 != phy_ppdu->len) { -+ const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; -+ u32 len_from_header; -+ -+ len_from_header = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_LEN) << 3; -+ -+ if (len_from_header != phy_ppdu->len) { - rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "phy ppdu len mismatch\n"); - return -EINVAL; - } -@@ -1376,17 +1385,19 @@ static int rtw89_core_rx_parse_phy_sts(s - struct rtw89_rx_phy_ppdu *phy_ppdu) - { - u16 ie_len; -- u8 *pos, *end; -+ void *pos, *end; - - /* mark invalid reports and bypass them */ - if (phy_ppdu->ie < RTW89_CCK_PKT) - return -EINVAL; - -- pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; -- end = (u8 *)phy_ppdu->buf + phy_ppdu->len; -+ pos = phy_ppdu->buf + PHY_STS_HDR_LEN; -+ end = phy_ppdu->buf + phy_ppdu->len; - while (pos < end) { -- ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, pos); -- rtw89_core_process_phy_status_ie(rtwdev, pos, phy_ppdu); -+ const struct rtw89_phy_sts_iehdr *iehdr = pos; -+ -+ ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, iehdr); -+ rtw89_core_process_phy_status_ie(rtwdev, iehdr, phy_ppdu); - pos += ie_len; - if (pos > end || ie_len == 0) { - rtw89_debug(rtwdev, RTW89_DBG_TXRX, ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -550,7 +550,7 @@ struct rtw89_rate_desc { - #define RF_PATH_MAX 4 - #define RTW89_MAX_PPDU_CNT 8 - struct rtw89_rx_phy_ppdu { -- u8 *buf; -+ void *buf; - u32 len; - u8 rssi_avg; - u8 rssi[RF_PATH_MAX]; ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -277,24 +277,25 @@ struct rtw89_rxinfo { - #define RTW89_RXINFO_W1_SERVICE GENMASK(15, 0) - #define RTW89_RXINFO_W1_PLCP_LEN GENMASK(23, 16) - --#define RTW89_GET_PHY_STS_IE_MAP(sts) \ -- le32_get_bits(*((const __le32 *)(sts)), GENMASK(4, 0)) --#define RTW89_GET_PHY_STS_RSSI_A(sts) \ -- le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(7, 0)) --#define RTW89_GET_PHY_STS_RSSI_B(sts) \ -- le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(15, 8)) --#define RTW89_GET_PHY_STS_RSSI_C(sts) \ -- le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(23, 16)) --#define RTW89_GET_PHY_STS_RSSI_D(sts) \ -- le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(31, 24)) --#define RTW89_GET_PHY_STS_LEN(sts) \ -- le32_get_bits(*((const __le32 *)sts), GENMASK(15, 8)) --#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \ -- le32_get_bits(*((const __le32 *)sts), GENMASK(31, 24)) --#define RTW89_GET_PHY_STS_IE_TYPE(ie) \ -- le32_get_bits(*((const __le32 *)ie), GENMASK(4, 0)) --#define RTW89_GET_PHY_STS_IE_LEN(ie) \ -- le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5)) -+struct rtw89_phy_sts_hdr { -+ __le32 w0; -+ __le32 w1; -+} __packed; -+ -+#define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0) -+#define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8) -+#define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24) -+#define RTW89_PHY_STS_HDR_W1_RSSI_A GENMASK(7, 0) -+#define RTW89_PHY_STS_HDR_W1_RSSI_B GENMASK(15, 8) -+#define RTW89_PHY_STS_HDR_W1_RSSI_C GENMASK(23, 16) -+#define RTW89_PHY_STS_HDR_W1_RSSI_D GENMASK(31, 24) -+ -+struct rtw89_phy_sts_iehdr { -+ __le32 w0; -+}; -+ -+#define RTW89_PHY_STS_IEHDR_TYPE GENMASK(4, 0) -+#define RTW89_PHY_STS_IEHDR_LEN GENMASK(11, 5) - - struct rtw89_phy_sts_ie0 { - __le32 w0; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-116-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-116-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch deleted file mode 100644 index 7a3ff1659..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-116-wifi-rtw89-use-struct-and-le32_get_bits-to-access-RX.patch +++ /dev/null @@ -1,160 +0,0 @@ -From c26700d2df01d084ee904ca872fd4db67e772c6f Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 22 May 2023 20:25:12 +0800 -Subject: [PATCH 116/136] wifi: rtw89: use struct and le32_get_bits() to access - RX descriptor - -RX descriptor is to provide basic and important information related to -packets, such as packet size, security, MAC ID and so on. Change to use -struct to access these fields, and not change logic at all. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522122513.13559-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 50 ++++++++--------- - drivers/net/wireless/realtek/rtw89/txrx.h | 65 ----------------------- - 2 files changed, 25 insertions(+), 90 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1806,27 +1806,27 @@ void rtw89_core_query_rxdesc(struct rtw8 - u8 shift_len, drv_info_len; - - rxd_s = (struct rtw89_rxdesc_short *)(data + data_offset); -- desc_info->pkt_size = RTW89_GET_RXWD_PKT_SIZE(rxd_s); -- desc_info->drv_info_size = RTW89_GET_RXWD_DRV_INFO_SIZE(rxd_s); -- desc_info->long_rxdesc = RTW89_GET_RXWD_LONG_RXD(rxd_s); -- desc_info->pkt_type = RTW89_GET_RXWD_RPKT_TYPE(rxd_s); -- desc_info->mac_info_valid = RTW89_GET_RXWD_MAC_INFO_VALID(rxd_s); -+ desc_info->pkt_size = le32_get_bits(rxd_s->dword0, AX_RXD_RPKT_LEN_MASK); -+ desc_info->drv_info_size = le32_get_bits(rxd_s->dword0, AX_RXD_DRV_INFO_SIZE_MASK); -+ desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, AX_RXD_LONG_RXD); -+ desc_info->pkt_type = le32_get_bits(rxd_s->dword0, AX_RXD_RPKT_TYPE_MASK); -+ desc_info->mac_info_valid = le32_get_bits(rxd_s->dword0, AX_RXD_MAC_INFO_VLD); - if (chip->chip_id == RTL8852C) -- desc_info->bw = RTW89_GET_RXWD_BW_V1(rxd_s); -+ desc_info->bw = le32_get_bits(rxd_s->dword1, AX_RXD_BW_v1_MASK); - else -- desc_info->bw = RTW89_GET_RXWD_BW(rxd_s); -- desc_info->data_rate = RTW89_GET_RXWD_DATA_RATE(rxd_s); -- desc_info->gi_ltf = RTW89_GET_RXWD_GI_LTF(rxd_s); -- desc_info->user_id = RTW89_GET_RXWD_USER_ID(rxd_s); -- desc_info->sr_en = RTW89_GET_RXWD_SR_EN(rxd_s); -- desc_info->ppdu_cnt = RTW89_GET_RXWD_PPDU_CNT(rxd_s); -- desc_info->ppdu_type = RTW89_GET_RXWD_PPDU_TYPE(rxd_s); -- desc_info->free_run_cnt = RTW89_GET_RXWD_FREE_RUN_CNT(rxd_s); -- desc_info->icv_err = RTW89_GET_RXWD_ICV_ERR(rxd_s); -- desc_info->crc32_err = RTW89_GET_RXWD_CRC32_ERR(rxd_s); -- desc_info->hw_dec = RTW89_GET_RXWD_HW_DEC(rxd_s); -- desc_info->sw_dec = RTW89_GET_RXWD_SW_DEC(rxd_s); -- desc_info->addr1_match = RTW89_GET_RXWD_A1_MATCH(rxd_s); -+ desc_info->bw = le32_get_bits(rxd_s->dword1, AX_RXD_BW_MASK); -+ desc_info->data_rate = le32_get_bits(rxd_s->dword1, AX_RXD_RX_DATARATE_MASK); -+ desc_info->gi_ltf = le32_get_bits(rxd_s->dword1, AX_RXD_RX_GI_LTF_MASK); -+ desc_info->user_id = le32_get_bits(rxd_s->dword1, AX_RXD_USER_ID_MASK); -+ desc_info->sr_en = le32_get_bits(rxd_s->dword1, AX_RXD_SR_EN); -+ desc_info->ppdu_cnt = le32_get_bits(rxd_s->dword1, AX_RXD_PPDU_CNT_MASK); -+ desc_info->ppdu_type = le32_get_bits(rxd_s->dword1, AX_RXD_PPDU_TYPE_MASK); -+ desc_info->free_run_cnt = le32_get_bits(rxd_s->dword2, AX_RXD_FREERUN_CNT_MASK); -+ desc_info->icv_err = le32_get_bits(rxd_s->dword3, AX_RXD_ICV_ERR); -+ desc_info->crc32_err = le32_get_bits(rxd_s->dword3, AX_RXD_CRC32_ERR); -+ desc_info->hw_dec = le32_get_bits(rxd_s->dword3, AX_RXD_HW_DEC); -+ desc_info->sw_dec = le32_get_bits(rxd_s->dword3, AX_RXD_SW_DEC); -+ desc_info->addr1_match = le32_get_bits(rxd_s->dword3, AX_RXD_A1_MATCH); - - shift_len = desc_info->shift << 1; /* 2-byte unit */ - drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ -@@ -1841,12 +1841,12 @@ void rtw89_core_query_rxdesc(struct rtw8 - return; - - rxd_l = (struct rtw89_rxdesc_long *)(data + data_offset); -- desc_info->frame_type = RTW89_GET_RXWD_TYPE(rxd_l); -- desc_info->addr_cam_valid = RTW89_GET_RXWD_ADDR_CAM_VLD(rxd_l); -- desc_info->addr_cam_id = RTW89_GET_RXWD_ADDR_CAM_ID(rxd_l); -- desc_info->sec_cam_id = RTW89_GET_RXWD_SEC_CAM_ID(rxd_l); -- desc_info->mac_id = RTW89_GET_RXWD_MAC_ID(rxd_l); -- desc_info->rx_pl_id = RTW89_GET_RXWD_RX_PL_ID(rxd_l); -+ desc_info->frame_type = le32_get_bits(rxd_l->dword4, AX_RXD_TYPE_MASK); -+ desc_info->addr_cam_valid = le32_get_bits(rxd_l->dword5, AX_RXD_ADDR_CAM_VLD); -+ desc_info->addr_cam_id = le32_get_bits(rxd_l->dword5, AX_RXD_ADDR_CAM_MASK); -+ desc_info->sec_cam_id = le32_get_bits(rxd_l->dword5, AX_RXD_SEC_CAM_IDX_MASK); -+ desc_info->mac_id = le32_get_bits(rxd_l->dword5, AX_RXD_MAC_ID_MASK); -+ desc_info->rx_pl_id = le32_get_bits(rxd_l->dword5, AX_RXD_RX_PL_ID_MASK); - } - EXPORT_SYMBOL(rtw89_core_query_rxdesc); - ---- a/drivers/net/wireless/realtek/rtw89/txrx.h -+++ b/drivers/net/wireless/realtek/rtw89/txrx.h -@@ -186,71 +186,6 @@ - #define AX_RXD_BIP_KEYID BIT(27) - #define AX_RXD_BIP_ENC BIT(28) - --/* RX DESC helpers */ --/* Short Descriptor */ --#define RTW89_GET_RXWD_LONG_RXD(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, BIT(31)) --#define RTW89_GET_RXWD_DRV_INFO_SIZE(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, GENMASK(30, 28)) --#define RTW89_GET_RXWD_RPKT_TYPE(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, GENMASK(27, 24)) --#define RTW89_GET_RXWD_MAC_INFO_VALID(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, BIT(23)) --#define RTW89_GET_RXWD_BB_SEL(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, BIT(22)) --#define RTW89_GET_RXWD_HD_IV_LEN(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, GENMASK(21, 16)) --#define RTW89_GET_RXWD_SHIFT(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, GENMASK(15, 14)) --#define RTW89_GET_RXWD_PKT_SIZE(rxdesc) \ -- le32_get_bits((rxdesc)->dword0, GENMASK(13, 0)) --#define RTW89_GET_RXWD_BW(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(31, 30)) --#define RTW89_GET_RXWD_BW_V1(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(31, 29)) --#define RTW89_GET_RXWD_GI_LTF(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(27, 25)) --#define RTW89_GET_RXWD_DATA_RATE(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(24, 16)) --#define RTW89_GET_RXWD_USER_ID(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(15, 8)) --#define RTW89_GET_RXWD_SR_EN(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, BIT(7)) --#define RTW89_GET_RXWD_PPDU_CNT(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(6, 4)) --#define RTW89_GET_RXWD_PPDU_TYPE(rxdesc) \ -- le32_get_bits((rxdesc)->dword1, GENMASK(3, 0)) --#define RTW89_GET_RXWD_FREE_RUN_CNT(rxdesc) \ -- le32_get_bits((rxdesc)->dword2, GENMASK(31, 0)) --#define RTW89_GET_RXWD_ICV_ERR(rxdesc) \ -- le32_get_bits((rxdesc)->dword3, BIT(10)) --#define RTW89_GET_RXWD_CRC32_ERR(rxdesc) \ -- le32_get_bits((rxdesc)->dword3, BIT(9)) --#define RTW89_GET_RXWD_HW_DEC(rxdesc) \ -- le32_get_bits((rxdesc)->dword3, BIT(2)) --#define RTW89_GET_RXWD_SW_DEC(rxdesc) \ -- le32_get_bits((rxdesc)->dword3, BIT(1)) --#define RTW89_GET_RXWD_A1_MATCH(rxdesc) \ -- le32_get_bits((rxdesc)->dword3, BIT(0)) -- --/* Long Descriptor */ --#define RTW89_GET_RXWD_FRAG(rxdesc) \ -- le32_get_bits((rxdesc)->dword4, GENMASK(31, 28)) --#define RTW89_GET_RXWD_SEQ(rxdesc) \ -- le32_get_bits((rxdesc)->dword4, GENMASK(27, 16)) --#define RTW89_GET_RXWD_TYPE(rxdesc) \ -- le32_get_bits((rxdesc)->dword4, GENMASK(1, 0)) --#define RTW89_GET_RXWD_ADDR_CAM_VLD(rxdesc) \ -- le32_get_bits((rxdesc)->dword5, BIT(28)) --#define RTW89_GET_RXWD_RX_PL_ID(rxdesc) \ -- le32_get_bits((rxdesc)->dword5, GENMASK(27, 24)) --#define RTW89_GET_RXWD_MAC_ID(rxdesc) \ -- le32_get_bits((rxdesc)->dword5, GENMASK(23, 16)) --#define RTW89_GET_RXWD_ADDR_CAM_ID(rxdesc) \ -- le32_get_bits((rxdesc)->dword5, GENMASK(15, 8)) --#define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \ -- le32_get_bits((rxdesc)->dword5, GENMASK(7, 0)) -- - struct rtw89_rxinfo_user { - __le32 w0; - }; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-117-wifi-rtw89-use-struct-to-access-register-based-H2C-C.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-117-wifi-rtw89-use-struct-to-access-register-based-H2C-C.patch deleted file mode 100644 index 9354a572b..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-117-wifi-rtw89-use-struct-to-access-register-based-H2C-C.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 68012b44dfc723a114748a5e67f98a99b2943852 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Mon, 22 May 2023 20:25:13 +0800 -Subject: [PATCH 117/136] wifi: rtw89: use struct to access register-based - H2C/C2H - -The register-based H2C/C2H are used to exchange commands and events with -firmware. The exchange data is limited, but it is relatively simple, -because it can work before HCI initialization. To make these code clean, -use struct to access them. This patch doesn't change logic at all. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522122513.13559-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 18 ++-- - drivers/net/wireless/realtek/rtw89/fw.h | 102 ++++++++++++----------- - drivers/net/wireless/realtek/rtw89/mac.c | 23 ++--- - 3 files changed, 77 insertions(+), 66 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -2917,12 +2917,13 @@ static int rtw89_fw_write_h2c_reg(struct - } - - len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, -- sizeof(info->h2creg[0])); -+ sizeof(info->u.h2creg[0])); -+ -+ u32p_replace_bits(&info->u.hdr.w0, info->id, RTW89_H2CREG_HDR_FUNC_MASK); -+ u32p_replace_bits(&info->u.hdr.w0, len, RTW89_H2CREG_HDR_LEN_MASK); - -- RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id); -- RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len); - for (i = 0; i < RTW89_H2CREG_MAX; i++) -- rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); -+ rtw89_write32(rtwdev, h2c_reg[i], info->u.h2creg[i]); - - fw_info->h2c_counter++; - rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, -@@ -2952,13 +2953,14 @@ static int rtw89_fw_read_c2h_reg(struct - } - - for (i = 0; i < RTW89_C2HREG_MAX; i++) -- info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); -+ info->u.c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); - - rtw89_write8(rtwdev, chip->c2h_ctrl_reg, 0); - -- info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg); -- info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - -- RTW89_C2HREG_HDR_LEN; -+ info->id = u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_FUNC_MASK); -+ info->content_len = -+ (u32_get_bits(info->u.hdr.w0, RTW89_C2HREG_HDR_LEN_MASK) << 2) - -+ RTW89_C2HREG_HDR_LEN; - - fw_info->c2h_counter++; - rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -18,15 +18,51 @@ enum rtw89_fw_dl_status { - RTW89_FWDL_WCPU_FW_INIT_RDY = 7 - }; - --#define RTW89_GET_C2H_HDR_FUNC(info) \ -- u32_get_bits(info, GENMASK(6, 0)) --#define RTW89_GET_C2H_HDR_LEN(info) \ -- u32_get_bits(info, GENMASK(11, 8)) -- --#define RTW89_SET_H2CREG_HDR_FUNC(info, val) \ -- u32p_replace_bits(info, val, GENMASK(6, 0)) --#define RTW89_SET_H2CREG_HDR_LEN(info, val) \ -- u32p_replace_bits(info, val, GENMASK(11, 8)) -+struct rtw89_c2hreg_hdr { -+ u32 w0; -+}; -+ -+#define RTW89_C2HREG_HDR_FUNC_MASK GENMASK(6, 0) -+#define RTW89_C2HREG_HDR_ACK BIT(7) -+#define RTW89_C2HREG_HDR_LEN_MASK GENMASK(11, 8) -+#define RTW89_C2HREG_HDR_SEQ_MASK GENMASK(15, 12) -+ -+struct rtw89_c2hreg_phycap { -+ u32 w0; -+ u32 w1; -+ u32 w2; -+ u32 w3; -+} __packed; -+ -+#define RTW89_C2HREG_PHYCAP_W0_FUNC GENMASK(6, 0) -+#define RTW89_C2HREG_PHYCAP_W0_ACK BIT(7) -+#define RTW89_C2HREG_PHYCAP_W0_LEN GENMASK(11, 8) -+#define RTW89_C2HREG_PHYCAP_W0_SEQ GENMASK(15, 12) -+#define RTW89_C2HREG_PHYCAP_W0_RX_NSS GENMASK(23, 16) -+#define RTW89_C2HREG_PHYCAP_W0_BW GENMASK(31, 24) -+#define RTW89_C2HREG_PHYCAP_W1_TX_NSS GENMASK(7, 0) -+#define RTW89_C2HREG_PHYCAP_W1_PROT GENMASK(15, 8) -+#define RTW89_C2HREG_PHYCAP_W1_NIC GENMASK(23, 16) -+#define RTW89_C2HREG_PHYCAP_W1_WL_FUNC GENMASK(31, 24) -+#define RTW89_C2HREG_PHYCAP_W2_HW_TYPE GENMASK(7, 0) -+#define RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM GENMASK(15, 8) -+#define RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM GENMASK(23, 16) -+ -+struct rtw89_h2creg_hdr { -+ u32 w0; -+}; -+ -+#define RTW89_H2CREG_HDR_FUNC_MASK GENMASK(6, 0) -+#define RTW89_H2CREG_HDR_LEN_MASK GENMASK(11, 8) -+ -+struct rtw89_h2creg_sch_tx_en { -+ u32 w0; -+ u32 w1; -+} __packed; -+ -+#define RTW89_H2CREG_SCH_TX_EN_W0_EN GENMASK(31, 16) -+#define RTW89_H2CREG_SCH_TX_EN_W1_MASK GENMASK(15, 0) -+#define RTW89_H2CREG_SCH_TX_EN_W1_BAND BIT(16) - - #define RTW89_H2CREG_MAX 4 - #define RTW89_C2HREG_MAX 4 -@@ -36,13 +72,21 @@ enum rtw89_fw_dl_status { - struct rtw89_mac_c2h_info { - u8 id; - u8 content_len; -- u32 c2hreg[RTW89_C2HREG_MAX]; -+ union { -+ u32 c2hreg[RTW89_C2HREG_MAX]; -+ struct rtw89_c2hreg_hdr hdr; -+ struct rtw89_c2hreg_phycap phycap; -+ } u; - }; - - struct rtw89_mac_h2c_info { - u8 id; - u8 content_len; -- u32 h2creg[RTW89_H2CREG_MAX]; -+ union { -+ u32 h2creg[RTW89_H2CREG_MAX]; -+ struct rtw89_h2creg_hdr hdr; -+ struct rtw89_h2creg_sch_tx_en sch_tx_en; -+ } u; - }; - - enum rtw89_mac_h2c_type { -@@ -63,33 +107,6 @@ enum rtw89_mac_c2h_type { - RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF - }; - --#define RTW89_GET_C2H_PHYCAP_FUNC(info) \ -- u32_get_bits(*((const u32 *)(info)), GENMASK(6, 0)) --#define RTW89_GET_C2H_PHYCAP_ACK(info) \ -- u32_get_bits(*((const u32 *)(info)), BIT(7)) --#define RTW89_GET_C2H_PHYCAP_LEN(info) \ -- u32_get_bits(*((const u32 *)(info)), GENMASK(11, 8)) --#define RTW89_GET_C2H_PHYCAP_SEQ(info) \ -- u32_get_bits(*((const u32 *)(info)), GENMASK(15, 12)) --#define RTW89_GET_C2H_PHYCAP_RX_NSS(info) \ -- u32_get_bits(*((const u32 *)(info)), GENMASK(23, 16)) --#define RTW89_GET_C2H_PHYCAP_BW(info) \ -- u32_get_bits(*((const u32 *)(info)), GENMASK(31, 24)) --#define RTW89_GET_C2H_PHYCAP_TX_NSS(info) \ -- u32_get_bits(*((const u32 *)(info) + 1), GENMASK(7, 0)) --#define RTW89_GET_C2H_PHYCAP_PROT(info) \ -- u32_get_bits(*((const u32 *)(info) + 1), GENMASK(15, 8)) --#define RTW89_GET_C2H_PHYCAP_NIC(info) \ -- u32_get_bits(*((const u32 *)(info) + 1), GENMASK(23, 16)) --#define RTW89_GET_C2H_PHYCAP_WL_FUNC(info) \ -- u32_get_bits(*((const u32 *)(info) + 1), GENMASK(31, 24)) --#define RTW89_GET_C2H_PHYCAP_HW_TYPE(info) \ -- u32_get_bits(*((const u32 *)(info) + 2), GENMASK(7, 0)) --#define RTW89_GET_C2H_PHYCAP_ANT_TX_NUM(info) \ -- u32_get_bits(*((const u32 *)(info) + 3), GENMASK(15, 8)) --#define RTW89_GET_C2H_PHYCAP_ANT_RX_NUM(info) \ -- u32_get_bits(*((const u32 *)(info) + 3), GENMASK(23, 16)) -- - enum rtw89_fw_c2h_category { - RTW89_C2H_CAT_TEST, - RTW89_C2H_CAT_MAC, -@@ -214,17 +231,6 @@ struct rtw89_fw_macid_pause_grp { - __le32 mask_grp[4]; - } __packed; - --struct rtw89_h2creg_sch_tx_en { -- u8 func:7; -- u8 ack:1; -- u8 total_len:4; -- u8 seq_num:4; -- u16 tx_en:16; -- u16 mask:16; -- u8 band:1; -- u16 rsvd:15; --} __packed; -- - #define RTW89_H2C_MAX_SIZE 2048 - #define RTW89_CHANNEL_TIME 45 - #define RTW89_CHANNEL_TIME_6G 20 ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -2650,6 +2650,7 @@ int rtw89_mac_setup_phycap(struct rtw89_ - struct rtw89_hal *hal = &rtwdev->hal; - const struct rtw89_chip_info *chip = rtwdev->chip; - struct rtw89_mac_c2h_info c2h_info = {0}; -+ const struct rtw89_c2hreg_phycap *phycap; - u8 tx_nss; - u8 rx_nss; - u8 tx_ant; -@@ -2660,10 +2661,12 @@ int rtw89_mac_setup_phycap(struct rtw89_ - if (ret) - return ret; - -- tx_nss = RTW89_GET_C2H_PHYCAP_TX_NSS(c2h_info.c2hreg); -- rx_nss = RTW89_GET_C2H_PHYCAP_RX_NSS(c2h_info.c2hreg); -- tx_ant = RTW89_GET_C2H_PHYCAP_ANT_TX_NUM(c2h_info.c2hreg); -- rx_ant = RTW89_GET_C2H_PHYCAP_ANT_RX_NUM(c2h_info.c2hreg); -+ phycap = &c2h_info.u.phycap; -+ -+ tx_nss = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_TX_NSS); -+ rx_nss = u32_get_bits(phycap->w0, RTW89_C2HREG_PHYCAP_W0_RX_NSS); -+ tx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM); -+ rx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM); - - hal->tx_nss = tx_nss ? min_t(u8, tx_nss, chip->tx_nss) : chip->tx_nss; - hal->rx_nss = rx_nss ? min_t(u8, rx_nss, chip->rx_nss) : chip->rx_nss; -@@ -2704,14 +2707,14 @@ static int rtw89_hw_sch_tx_en_h2c(struct - u32 ret; - struct rtw89_mac_c2h_info c2h_info = {0}; - struct rtw89_mac_h2c_info h2c_info = {0}; -- struct rtw89_h2creg_sch_tx_en *h2creg = -- (struct rtw89_h2creg_sch_tx_en *)h2c_info.h2creg; -+ struct rtw89_h2creg_sch_tx_en *sch_tx_en = &h2c_info.u.sch_tx_en; - - h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN; -- h2c_info.content_len = sizeof(*h2creg) - RTW89_H2CREG_HDR_LEN; -- h2creg->tx_en = tx_en_u16; -- h2creg->mask = mask_u16; -- h2creg->band = band; -+ h2c_info.content_len = sizeof(*sch_tx_en) - RTW89_H2CREG_HDR_LEN; -+ -+ u32p_replace_bits(&sch_tx_en->w0, tx_en_u16, RTW89_H2CREG_SCH_TX_EN_W0_EN); -+ u32p_replace_bits(&sch_tx_en->w1, mask_u16, RTW89_H2CREG_SCH_TX_EN_W1_MASK); -+ u32p_replace_bits(&sch_tx_en->w1, band, RTW89_H2CREG_SCH_TX_EN_W1_BAND); - - ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); - if (ret) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-118-wifi-rtw89-8851b-rfk-Fix-spelling-mistake-KIP_RESOTR.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-118-wifi-rtw89-8851b-rfk-Fix-spelling-mistake-KIP_RESOTR.patch deleted file mode 100644 index 3f595f2d6..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-118-wifi-rtw89-8851b-rfk-Fix-spelling-mistake-KIP_RESOTR.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 56fc4d482783f5e45a6a2b3ec0d9f557908cdf77 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Mon, 22 May 2023 09:59:24 +0100 -Subject: [PATCH 118/136] wifi: rtw89: 8851b: rfk: Fix spelling mistake - KIP_RESOTRE -> KIP_RESTORE - -There is a spelling mistake in a literal string. Fix it. - -Signed-off-by: Colin Ian King -Reviewed-by: Simon Horman -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230522085924.913649-1-colin.i.king@gmail.com ---- - drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -1705,7 +1705,7 @@ static void _dpk_one_shot(struct rtw89_d - id == 0x2c ? "GAIN_LOSS" : - id == 0x2d ? "MDPK_IDL" : - id == 0x2f ? "DPK_GAIN_NORM" : -- id == 0x31 ? "KIP_RESOTRE" : -+ id == 0x31 ? "KIP_RESTORE" : - id == 0x6 ? "LBK_RXIQK" : "Unknown id", - dpk_cmd); - } diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-119-wifi-rtw89-use-flexible-array-member-in-rtw89_btc_bt.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-119-wifi-rtw89-use-flexible-array-member-in-rtw89_btc_bt.patch deleted file mode 100644 index 69af504dd..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-119-wifi-rtw89-use-flexible-array-member-in-rtw89_btc_bt.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 47e612268ea02f7d2bcbaa47528698b5be61a8cf Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Tue, 23 May 2023 13:32:35 +0200 -Subject: [PATCH 119/136] wifi: rtw89: use flexible array member in - rtw89_btc_btf_tlv - -struct rtw89_btc_btf_tlv contains a one-byte member that is intended as a -flexible array: - -In function 'fortify_memcpy_chk', - inlined from '_append_tdma' at drivers/net/wireless/realtek/rtw89/coex.c:1579:3: -include/linux/fortify-string.h:583:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] - 583 | __write_overflow_field(p_size_field, size); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Make this actually use a flexible array to let the compiler understand. - -Signed-off-by: Arnd Bergmann -Reviewed-by: Ping-Ke Shih -Reviewed-by: Gustavo A. R. Silva -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230523113241.2772811-1-arnd@kernel.org ---- - drivers/net/wireless/realtek/rtw89/coex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/coex.c -+++ b/drivers/net/wireless/realtek/rtw89/coex.c -@@ -206,7 +206,7 @@ static const struct rtw89_btc_ver rtw89_ - struct rtw89_btc_btf_tlv { - u8 type; - u8 len; -- u8 val[1]; -+ u8 val[]; - } __packed; - - enum btc_btf_set_report_en { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-120-wifi-rtw89-correct-PS-calculation-for-SUPPORTS_DYNAM.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-120-wifi-rtw89-correct-PS-calculation-for-SUPPORTS_DYNAM.patch deleted file mode 100644 index 25100db8f..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-120-wifi-rtw89-correct-PS-calculation-for-SUPPORTS_DYNAM.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 26a125f550a3bf86ac91d38752f4d446426dfe1c Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 27 May 2023 16:29:38 +0800 -Subject: [PATCH 120/136] wifi: rtw89: correct PS calculation for - SUPPORTS_DYNAMIC_PS - -This driver relies on IEEE80211_CONF_PS of hw->conf.flags to turn off PS or -turn on dynamic PS controlled by driver and firmware. Though this would be -incorrect, it did work before because the flag is always recalculated until -the commit 28977e790b5d ("wifi: mac80211: skip powersave recalc if driver SUPPORTS_DYNAMIC_PS") -is introduced by kernel 5.20 to skip to recalculate IEEE80211_CONF_PS -of hw->conf.flags if driver sets SUPPORTS_DYNAMIC_PS. - -Correct this by doing recalculation while BSS_CHANGED_PS is changed and -interface is added or removed. For now, it is allowed to enter PS only if -single one station vif is working, and it could possible to have PS per -vif after firmware can support it. Without this fix, driver doesn't -enter PS anymore that causes higher power consumption. - -Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") -Cc: stable@vger.kernel.org # 6.1+ -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230527082939.11206-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/mac80211.c | 15 +++++------ - drivers/net/wireless/realtek/rtw89/ps.c | 26 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/ps.h | 1 + - 3 files changed, 33 insertions(+), 9 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -89,15 +89,6 @@ static int rtw89_ops_config(struct ieee8 - !(hw->conf.flags & IEEE80211_CONF_IDLE)) - rtw89_leave_ips(rtwdev); - -- if (changed & IEEE80211_CONF_CHANGE_PS) { -- if (hw->conf.flags & IEEE80211_CONF_PS) { -- rtwdev->lps_enabled = true; -- } else { -- rtw89_leave_lps(rtwdev); -- rtwdev->lps_enabled = false; -- } -- } -- - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, - &hw->conf.chandef); -@@ -168,6 +159,8 @@ static int rtw89_ops_add_interface(struc - rtw89_core_txq_init(rtwdev, vif->txq); - - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START); -+ -+ rtw89_recalc_lps(rtwdev); - out: - mutex_unlock(&rtwdev->mutex); - -@@ -192,6 +185,7 @@ static void rtw89_ops_remove_interface(s - rtw89_mac_remove_vif(rtwdev, rtwvif); - rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); - list_del_init(&rtwvif->list); -+ rtw89_recalc_lps(rtwdev); - rtw89_enter_ips_by_hwflags(rtwdev); - - mutex_unlock(&rtwdev->mutex); -@@ -451,6 +445,9 @@ static void rtw89_ops_bss_info_changed(s - if (changed & BSS_CHANGED_CQM) - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true); - -+ if (changed & BSS_CHANGED_PS) -+ rtw89_recalc_lps(rtwdev); -+ - mutex_unlock(&rtwdev->mutex); - } - ---- a/drivers/net/wireless/realtek/rtw89/ps.c -+++ b/drivers/net/wireless/realtek/rtw89/ps.c -@@ -252,3 +252,29 @@ void rtw89_process_p2p_ps(struct rtw89_d - rtw89_p2p_disable_all_noa(rtwdev, vif); - rtw89_p2p_update_noa(rtwdev, vif); - } -+ -+void rtw89_recalc_lps(struct rtw89_dev *rtwdev) -+{ -+ struct ieee80211_vif *vif, *found_vif = NULL; -+ struct rtw89_vif *rtwvif; -+ int count = 0; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) { -+ vif = rtwvif_to_vif(rtwvif); -+ -+ if (vif->type != NL80211_IFTYPE_STATION) { -+ count = 0; -+ break; -+ } -+ -+ count++; -+ found_vif = vif; -+ } -+ -+ if (count == 1 && found_vif->cfg.ps) { -+ rtwdev->lps_enabled = true; -+ } else { -+ rtw89_leave_lps(rtwdev); -+ rtwdev->lps_enabled = false; -+ } -+} ---- a/drivers/net/wireless/realtek/rtw89/ps.h -+++ b/drivers/net/wireless/realtek/rtw89/ps.h -@@ -15,6 +15,7 @@ void rtw89_enter_ips(struct rtw89_dev *r - void rtw89_leave_ips(struct rtw89_dev *rtwdev); - void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); - void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); -+void rtw89_recalc_lps(struct rtw89_dev *rtwdev); - - static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev) - { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-121-wifi-rtw89-remove-redundant-check-of-entering-LPS.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-121-wifi-rtw89-remove-redundant-check-of-entering-LPS.patch deleted file mode 100644 index 42d4582a5..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-121-wifi-rtw89-remove-redundant-check-of-entering-LPS.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b408f33b35a4de606bfbd0de33b8f971bc5488ba Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Sat, 27 May 2023 16:29:39 +0800 -Subject: [PATCH 121/136] wifi: rtw89: remove redundant check of entering LPS - -Originally, add this check rule to prevent entering LPS if more than one -vif (in station mode) connect to AP. Since we have checked this by previous -commit, remove this redundant check. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230527082939.11206-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2619,9 +2619,6 @@ static void rtw89_vif_enter_lps(struct r - rtwvif->tdls_peer) - return; - -- if (rtwdev->total_sta_assoc > 1) -- return; -- - if (rtwvif->offchan) - return; - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-122-wifi-rtw89-8851b-enable-hw_scan-support.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-122-wifi-rtw89-8851b-enable-hw_scan-support.patch deleted file mode 100644 index 6a3df97ca..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-122-wifi-rtw89-8851b-enable-hw_scan-support.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 9c52e8bf07c7097e09503fcad7cb156deffef619 Mon Sep 17 00:00:00 2001 -From: Po-Hao Huang -Date: Wed, 31 May 2023 14:07:10 +0800 -Subject: [PATCH 122/136] wifi: rtw89: 8851b: enable hw_scan support - -This enables hw_scan for 8851b after firmware version 0.29.37.1. -Extend the channel info struct with padding zeros so newer firmware -can work properly, this change is backward compatible with older -firmware. - -Signed-off-by: Po-Hao Huang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230531060713.57203-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - drivers/net/wireless/realtek/rtw89/fw.h | 2 +- - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -257,6 +257,7 @@ struct __fw_feat_cfg { - - static const struct __fw_feat_cfg fw_feat_tbl[] = { - __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), -+ __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -243,7 +243,7 @@ struct rtw89_fw_macid_pause_grp { - #define RTW89_SCANOFLD_MAX_IE_LEN 512 - #define RTW89_SCANOFLD_PKT_NONE 0xFF - #define RTW89_SCANOFLD_DEBUG_MASK 0x1F --#define RTW89_MAC_CHINFO_SIZE 24 -+#define RTW89_MAC_CHINFO_SIZE 28 - #define RTW89_SCAN_LIST_GUARD 4 - #define RTW89_SCAN_LIST_LIMIT \ - ((RTW89_H2C_MAX_SIZE / RTW89_MAC_CHINFO_SIZE) - RTW89_SCAN_LIST_GUARD) diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-123-wifi-rtw89-debug-txpwr-table-access-only-valid-page-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-123-wifi-rtw89-debug-txpwr-table-access-only-valid-page-.patch deleted file mode 100644 index 425c9865b..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-123-wifi-rtw89-debug-txpwr-table-access-only-valid-page-.patch +++ /dev/null @@ -1,103 +0,0 @@ -From b25e755e5e418aa7b537b8b2a2506c34c53df2d5 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 31 May 2023 14:07:11 +0800 -Subject: [PATCH 123/136] wifi: rtw89: debug: txpwr table access only valid - page according to chip - -We now support RTL8851B which has only single RF path. For chip with -single RF path, TX power page is valid only in single path section. -So, we refine debugfs txpwr table to access TX power page according -to RF path number of runtime chip. It can prevent us from reading -beyond valid sections. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230531060713.57203-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/debug.c | 13 ++++++++++++- - drivers/net/wireless/realtek/rtw89/reg.h | 6 ++++++ - 2 files changed, 18 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -376,6 +376,7 @@ struct txpwr_map { - u8 size; - u32 addr_from; - u32 addr_to; -+ u32 addr_to_1ss; - }; - - #define __GEN_TXPWR_ENT2(_t, _e0, _e1) \ -@@ -413,6 +414,7 @@ static const struct txpwr_map __txpwr_ma - .size = ARRAY_SIZE(__txpwr_ent_byr), - .addr_from = R_AX_PWR_BY_RATE, - .addr_to = R_AX_PWR_BY_RATE_MAX, -+ .addr_to_1ss = R_AX_PWR_BY_RATE_1SS_MAX, - }; - - static const struct txpwr_ent __txpwr_ent_lmt[] = { -@@ -468,6 +470,7 @@ static const struct txpwr_map __txpwr_ma - .size = ARRAY_SIZE(__txpwr_ent_lmt), - .addr_from = R_AX_PWR_LMT, - .addr_to = R_AX_PWR_LMT_MAX, -+ .addr_to_1ss = R_AX_PWR_LMT_1SS_MAX, - }; - - static const struct txpwr_ent __txpwr_ent_lmt_ru[] = { -@@ -495,6 +498,7 @@ static const struct txpwr_map __txpwr_ma - .size = ARRAY_SIZE(__txpwr_ent_lmt_ru), - .addr_from = R_AX_PWR_RU_LMT, - .addr_to = R_AX_PWR_RU_LMT_MAX, -+ .addr_to_1ss = R_AX_PWR_RU_LMT_1SS_MAX, - }; - - static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, -@@ -527,6 +531,8 @@ static int __print_txpwr_map(struct seq_ - const struct txpwr_map *map) - { - u8 fct = rtwdev->chip->txpwr_factor_mac; -+ u8 path_num = rtwdev->chip->rf_path_num; -+ u32 max_valid_addr; - u32 val, addr; - s8 *buf, tmp; - u8 cur, i; -@@ -536,7 +542,12 @@ static int __print_txpwr_map(struct seq_ - if (!buf) - return -ENOMEM; - -- for (addr = map->addr_from; addr <= map->addr_to; addr += 4) { -+ if (path_num == 1) -+ max_valid_addr = map->addr_to_1ss; -+ else -+ max_valid_addr = map->addr_to; -+ -+ for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) { - ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val); - if (ret) - val = MASKDWORD; ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3342,16 +3342,22 @@ - #define B_AX_PWR_UL_TB_2T_MASK GENMASK(4, 0) - #define B_AX_PWR_UL_TB_2T_V1_MASK GENMASK(7, 0) - #define R_AX_PWR_BY_RATE_TABLE0 0xD2C0 -+#define R_AX_PWR_BY_RATE_TABLE6 0xD2D8 - #define R_AX_PWR_BY_RATE_TABLE10 0xD2E8 - #define R_AX_PWR_BY_RATE R_AX_PWR_BY_RATE_TABLE0 -+#define R_AX_PWR_BY_RATE_1SS_MAX R_AX_PWR_BY_RATE_TABLE6 - #define R_AX_PWR_BY_RATE_MAX R_AX_PWR_BY_RATE_TABLE10 - #define R_AX_PWR_LMT_TABLE0 0xD2EC -+#define R_AX_PWR_LMT_TABLE9 0xD310 - #define R_AX_PWR_LMT_TABLE19 0xD338 - #define R_AX_PWR_LMT R_AX_PWR_LMT_TABLE0 -+#define R_AX_PWR_LMT_1SS_MAX R_AX_PWR_LMT_TABLE9 - #define R_AX_PWR_LMT_MAX R_AX_PWR_LMT_TABLE19 - #define R_AX_PWR_RU_LMT_TABLE0 0xD33C -+#define R_AX_PWR_RU_LMT_TABLE5 0xD350 - #define R_AX_PWR_RU_LMT_TABLE11 0xD368 - #define R_AX_PWR_RU_LMT R_AX_PWR_RU_LMT_TABLE0 -+#define R_AX_PWR_RU_LMT_1SS_MAX R_AX_PWR_RU_LMT_TABLE5 - #define R_AX_PWR_RU_LMT_MAX R_AX_PWR_RU_LMT_TABLE11 - #define R_AX_PWR_MACID_LMT_TABLE0 0xD36C - #define R_AX_PWR_MACID_LMT_TABLE127 0xD568 diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-124-wifi-rtw89-set-TX-power-without-precondition-during-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-124-wifi-rtw89-set-TX-power-without-precondition-during-.patch deleted file mode 100644 index a35c498cb..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-124-wifi-rtw89-set-TX-power-without-precondition-during-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From db67b03b04b4363251c0d8eecaf7a631449b6f3d Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 31 May 2023 14:07:12 +0800 -Subject: [PATCH 124/136] wifi: rtw89: set TX power without precondition during - setting channel - -The key condition to check in wrapper of setting TX power is whether entity -is active or not. Before entity is active, we restrict TX power from being -set by outside callers, e.g. SAR/regulatory. - -We mark entity as inactive when powering off MAC. Then, we will mark it as -active when we initialize HW channel stuffs after MAC power on. Although we -can get an active entity after leaving idle phase, TX power doesn't be set -well for default channel until stack set target channel for connection. It -causes that RF things cannot use better TX power during this interval. - -Below are some cases which may encounter this or a similar situation. -* hw scan process before connection - As described above. -* right after restart hardware process (SER L2) - HW stuffs of target channel is initialized after mac80211 restart - hardware, but we unexpectedly need to wait one more command to set - channel again or to set TX power. - -To fix it and improve RF behavior in that interval, during setting channel, -we don't need to check entity state before setting TX power, which actually -is used to restrict outside callers. It means we call chip ops directly to -replace the wrapper call. Then, TX power can be initialized as long as we -initialize/setup HW stuffs on one channel. - -Besides, all chips should configure ops of setting TX power, so we remove -trivial check on pointer. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230531060713.57203-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -336,8 +336,7 @@ void rtw89_core_set_chip_txpwr(struct rt - sub_entity_idx = RTW89_SUB_ENTITY_0; - phy_idx = RTW89_PHY_0; - chan = rtw89_chan_get(rtwdev, sub_entity_idx); -- if (chip->ops->set_txpwr) -- chip->ops->set_txpwr(rtwdev, chan, phy_idx); -+ chip->ops->set_txpwr(rtwdev, chan, phy_idx); - } - - void rtw89_set_channel(struct rtw89_dev *rtwdev) -@@ -373,7 +372,7 @@ void rtw89_set_channel(struct rtw89_dev - - chip->ops->set_channel(rtwdev, &chan, mac_idx, phy_idx); - -- rtw89_core_set_chip_txpwr(rtwdev); -+ chip->ops->set_txpwr(rtwdev, &chan, phy_idx); - - rtw89_chip_set_channel_done(rtwdev, &bak, &chan, mac_idx, phy_idx); - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-125-wifi-rtw89-8851b-configure-CRASH_TRIGGER-feature-for.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-125-wifi-rtw89-8851b-configure-CRASH_TRIGGER-feature-for.patch deleted file mode 100644 index 25d5b090e..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-125-wifi-rtw89-8851b-configure-CRASH_TRIGGER-feature-for.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 57369e2aa2eb9812368c6cf3c4378d1fbe9e8c8a Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Wed, 31 May 2023 14:07:13 +0800 -Subject: [PATCH 125/136] wifi: rtw89: 8851b: configure CRASH_TRIGGER feature - for 8851B - -RTL8851B firmware supports CRASH_TRIGGER feature from v0.29.41.0. -After this is configured, debugfs fw_crash can support type 1 on -RTL8851B to trigger firmware crash and verify L2 recovery through -simulation. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230531060713.57203-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/fw.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -258,6 +258,7 @@ struct __fw_feat_cfg { - static const struct __fw_feat_cfg fw_feat_tbl[] = { - __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), - __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), -+ __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER), - __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-126-wifi-rtw89-refine-clearing-supported-bands-to-check-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-126-wifi-rtw89-refine-clearing-supported-bands-to-check-.patch deleted file mode 100644 index c53af8697..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-126-wifi-rtw89-refine-clearing-supported-bands-to-check-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b7d170d5a670de8d30d2db94179099f52f8df485 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:49 +0800 -Subject: [PATCH 126/136] wifi: rtw89: refine clearing supported bands to check - 2/5 GHz first - -We refine to check if supported bands of NL80211_BAND_2GHZ and -NL80211_BAND_5GHZ exist before freeing their iftype_data. For -now, it does not really encounter problems because all current -chips support both 2 GHz and 5 GHz. But, driver actually allows -chips to declare whether 2/5 GHz are supported or not. In case -some future chips really don't support them, we refine this code. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-2-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -3386,8 +3386,10 @@ static void rtw89_core_clr_supported_ban - { - struct ieee80211_hw *hw = rtwdev->hw; - -- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data); -- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data); -+ if (hw->wiphy->bands[NL80211_BAND_2GHZ]) -+ kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data); -+ if (hw->wiphy->bands[NL80211_BAND_5GHZ]) -+ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data); - if (hw->wiphy->bands[NL80211_BAND_6GHZ]) - kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data); - kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-127-wifi-rtw89-regd-judge-6-GHz-according-to-chip-and-BI.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-127-wifi-rtw89-regd-judge-6-GHz-according-to-chip-and-BI.patch deleted file mode 100644 index 5138df831..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-127-wifi-rtw89-regd-judge-6-GHz-according-to-chip-and-BI.patch +++ /dev/null @@ -1,84 +0,0 @@ -From ffc23511531341936dbddd24ba0e3a08bcdda01c Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:50 +0800 -Subject: [PATCH 127/136] wifi: rtw89: regd: judge 6 GHz according to chip and - BIOS - -We allow platform to disable 6 GHz on chips, which supports 6 GHz, through -BIOS. Driver will evaluate Realtek acpi DSM with RTW89_ACPI_DSM_FUNC_6G_DIS -(function 3) to get whether 6 GHz should be disabled. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-3-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/regd.c | 50 +++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/regd.c -+++ b/drivers/net/wireless/realtek/rtw89/regd.c -@@ -330,6 +330,55 @@ bottom: - sband->n_channels -= 3; - } - -+static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy) -+{ -+ const struct rtw89_chip_info *chip = rtwdev->chip; -+ bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ); -+ bool regd_allow_6ghz = chip_support_6ghz; -+ struct ieee80211_supported_band *sband; -+ int ret; -+ u8 val; -+ -+ if (!chip_support_6ghz) -+ goto bottom; -+ -+ ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &val); -+ if (ret) { -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, -+ "acpi: cannot eval 6ghz: %d\n", ret); -+ goto bottom; -+ } -+ -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, -+ "acpi: eval if disallow 6ghz: %d\n", val); -+ -+ switch (val) { -+ case 0: -+ regd_allow_6ghz = true; -+ break; -+ case 1: -+ regd_allow_6ghz = false; -+ break; -+ default: -+ break; -+ } -+ -+bottom: -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow 6ghz: %d\n", -+ regd_allow_6ghz); -+ -+ if (regd_allow_6ghz) -+ return; -+ -+ sband = wiphy->bands[NL80211_BAND_6GHZ]; -+ if (!sband) -+ return; -+ -+ wiphy->bands[NL80211_BAND_6GHZ] = NULL; -+ kfree(sband->iftype_data); -+ kfree(sband); -+} -+ - int rtw89_regd_setup(struct rtw89_dev *rtwdev) - { - struct wiphy *wiphy = rtwdev->hw->wiphy; -@@ -338,6 +387,7 @@ int rtw89_regd_setup(struct rtw89_dev *r - return -EINVAL; - - rtw89_regd_setup_unii4(rtwdev, wiphy); -+ rtw89_regd_setup_6ghz(rtwdev, wiphy); - - wiphy->reg_notifier = rtw89_regd_notifier; - return 0; diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-128-wifi-rtw89-regd-update-regulatory-map-to-R64-R40.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-128-wifi-rtw89-regd-update-regulatory-map-to-R64-R40.patch deleted file mode 100644 index e5bcfe5f1..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-128-wifi-rtw89-regd-update-regulatory-map-to-R64-R40.patch +++ /dev/null @@ -1,279 +0,0 @@ -From 9468046ff54eb5b72616c8126105bbf2df711253 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:51 +0800 -Subject: [PATCH 128/136] wifi: rtw89: regd: update regulatory map to R64-R40 - -Update notes: -According to Realtek Regulatory R40 and Realtek Channel Plan R64, -configure rtw89_regulatory mapping of 6 GHz for more countries and -adjust rtw89_regulatory mapping of 2/5 GHz for a few countries. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/regd.c | 122 +++++++++++----------- - 1 file changed, 61 insertions(+), 61 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/regd.c -+++ b/drivers/net/wireless/realtek/rtw89/regd.c -@@ -16,20 +16,20 @@ static const struct rtw89_regulatory rtw - - static const struct rtw89_regulatory rtw89_regd_map[] = { - COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA), -- COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE), -- COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA), - COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA), -@@ -66,37 +66,37 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK), - COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR), -- COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE), - COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -104,11 +104,11 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN), -- COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC), -- COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -116,55 +116,55 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_NA), -- COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_NA), -- COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), -+ COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA), -+ COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC), -- COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_NA), -- COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK), -+ COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA), -- COUNTRY_REGD("CC", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA), -+ COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), -+ COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -174,17 +174,17 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("GY", RTW89_NCC, RTW89_NCC, RTW89_NA), -+ COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -195,17 +195,17 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -219,26 +219,26 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC), -+ COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA), - COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_NA), -+ COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -- COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA), - COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -@@ -246,7 +246,7 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA), - COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_NA), -- COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA), -+ COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI), - COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA), diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-129-wifi-rtw89-process-regulatory-for-6-GHz-power-type.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-129-wifi-rtw89-process-regulatory-for-6-GHz-power-type.patch deleted file mode 100644 index 892be2c53..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-129-wifi-rtw89-process-regulatory-for-6-GHz-power-type.patch +++ /dev/null @@ -1,314 +0,0 @@ -From f6baa1d3d5703fe65b87b3149265a1c7f564f450 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:52 +0800 -Subject: [PATCH 129/136] wifi: rtw89: process regulatory for 6 GHz power type - -Configure the corresponding power type for 6 GHz regulatory if we can -determine one single target. Otherwise, we use the default one. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-5-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.c | 7 +- - drivers/net/wireless/realtek/rtw89/core.h | 25 ++++- - drivers/net/wireless/realtek/rtw89/mac80211.c | 9 ++ - drivers/net/wireless/realtek/rtw89/regd.c | 91 ++++++++++++++++--- - 4 files changed, 116 insertions(+), 16 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -2869,6 +2869,8 @@ int rtw89_core_sta_add(struct rtw89_dev - if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { - /* for station mode, assign the mac_id from itself */ - rtwsta->mac_id = rtwvif->mac_id; -+ /* must do rtw89_reg_6ghz_power_recalc() before rfk channel */ -+ rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, true); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, - BTC_ROLE_MSTS_STA_CONN_START); - rtw89_chip_rfk_channel(rtwdev); -@@ -3042,10 +3044,11 @@ int rtw89_core_sta_remove(struct rtw89_d - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; - int ret; - -- if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) -+ if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { -+ rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, false); - rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, - BTC_ROLE_MSTS_STA_DIS_CONN); -- else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { -+ } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { - rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); - - ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -488,6 +488,15 @@ enum rtw89_regulation_type { - RTW89_REGD_NUM, - }; - -+enum rtw89_reg_6ghz_power { -+ RTW89_REG_6GHZ_POWER_VLP = 0, -+ RTW89_REG_6GHZ_POWER_LPI = 1, -+ RTW89_REG_6GHZ_POWER_STD = 2, -+ -+ NUM_OF_RTW89_REG_6GHZ_POWER, -+ RTW89_REG_6GHZ_POWER_DFLT = RTW89_REG_6GHZ_POWER_VLP, -+}; -+ - enum rtw89_fw_pkt_ofld_type { - RTW89_PKT_OFLD_TYPE_PROBE_RSP = 0, - RTW89_PKT_OFLD_TYPE_PS_POLL = 1, -@@ -2682,6 +2691,7 @@ struct rtw89_vif { - struct rtw89_dev *rtwdev; - struct rtw89_roc roc; - enum rtw89_sub_entity_idx sub_entity_idx; -+ enum rtw89_reg_6ghz_power reg_6ghz_power; - - u8 mac_id; - u8 port; -@@ -3807,11 +3817,16 @@ struct rtw89_power_trim_info { - u8 pa_bias_trim[RF_PATH_MAX]; - }; - --struct rtw89_regulatory { -+struct rtw89_regd { - char alpha2[3]; - u8 txpwr_regd[RTW89_BAND_MAX]; - }; - -+struct rtw89_regulatory_info { -+ const struct rtw89_regd *regd; -+ enum rtw89_reg_6ghz_power reg_6ghz_power; -+}; -+ - enum rtw89_ifs_clm_application { - RTW89_IFS_CLM_INIT = 0, - RTW89_IFS_CLM_BACKGROUND = 1, -@@ -4161,7 +4176,7 @@ struct rtw89_dev { - u8 total_sta_assoc; - bool scanning; - -- const struct rtw89_regulatory *regd; -+ struct rtw89_regulatory_info regulatory; - struct rtw89_sar_info sar; - - struct rtw89_btc btc; -@@ -4848,7 +4863,9 @@ static inline void rtw89_load_txpwr_tabl - - static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band) - { -- return rtwdev->regd->txpwr_regd[band]; -+ const struct rtw89_regd *regd = rtwdev->regulatory.regd; -+ -+ return regd->txpwr_regd[band]; - } - - static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) -@@ -5090,5 +5107,7 @@ void rtw89_core_scan_start(struct rtw89_ - const u8 *mac_addr, bool hw_scan); - void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, - struct ieee80211_vif *vif, bool hw_scan); -+void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool active); - - #endif ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -146,6 +146,7 @@ static int rtw89_ops_add_interface(struc - rtwvif->phy_idx = RTW89_PHY_0; - rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; - rtwvif->hit_rule = 0; -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; - ether_addr_copy(rtwvif->mac_addr, vif->addr); - INIT_LIST_HEAD(&rtwvif->general_pkt_list); - -@@ -457,8 +458,16 @@ static int rtw89_ops_start_ap(struct iee - { - struct rtw89_dev *rtwdev = hw->priv; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; -+ const struct rtw89_chan *chan; - - mutex_lock(&rtwdev->mutex); -+ -+ chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx); -+ if (chan->band_type == RTW89_BAND_6G) { -+ mutex_unlock(&rtwdev->mutex); -+ return -EOPNOTSUPP; -+ } -+ - ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid); - rtw89_cam_bssid_changed(rtwdev, rtwvif); - rtw89_mac_port_update(rtwdev, rtwvif); ---- a/drivers/net/wireless/realtek/rtw89/regd.c -+++ b/drivers/net/wireless/realtek/rtw89/regd.c -@@ -5,16 +5,17 @@ - #include "acpi.h" - #include "debug.h" - #include "ps.h" -+#include "util.h" - - #define COUNTRY_REGD(_alpha2, _txpwr_regd...) \ - {.alpha2 = (_alpha2), \ - .txpwr_regd = {_txpwr_regd}, \ - } - --static const struct rtw89_regulatory rtw89_ww_regd = -+static const struct rtw89_regd rtw89_ww_regd = - COUNTRY_REGD("00", RTW89_WW, RTW89_WW); - --static const struct rtw89_regulatory rtw89_regd_map[] = { -+static const struct rtw89_regd rtw89_regd_map[] = { - COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA), - COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_FCC), - COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC), -@@ -255,7 +256,7 @@ static const struct rtw89_regulatory rtw - COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA), - }; - --static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2) -+static const struct rtw89_regd *rtw89_regd_find_reg_by_name(char *alpha2) - { - u32 i; - -@@ -267,7 +268,7 @@ static const struct rtw89_regulatory *rt - return &rtw89_ww_regd; - } - --static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd) -+static bool rtw89_regd_is_ww(const struct rtw89_regd *regd) - { - return regd == &rtw89_ww_regd; - } -@@ -397,21 +398,25 @@ int rtw89_regd_init(struct rtw89_dev *rt - void (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) - { -- const struct rtw89_regulatory *chip_regd; -+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; -+ const struct rtw89_regd *chip_regd; - struct wiphy *wiphy = rtwdev->hw->wiphy; - int ret; - -+ regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; -+ - if (!wiphy) - return -EINVAL; - - chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code); - if (!rtw89_regd_is_ww(chip_regd)) { -- rtwdev->regd = chip_regd; -+ rtwdev->regulatory.regd = chip_regd; - /* Ignore country ie if there is a country domain programmed in chip */ - wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; - wiphy->regulatory_flags |= REGULATORY_STRICT_REG; - -- ret = regulatory_hint(rtwdev->hw->wiphy, rtwdev->regd->alpha2); -+ ret = regulatory_hint(rtwdev->hw->wiphy, -+ rtwdev->regulatory.regd->alpha2); - if (ret) - rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); - -@@ -419,7 +424,7 @@ int rtw89_regd_init(struct rtw89_dev *rt - return 0; - } - -- rtw89_debug_regd(rtwdev, rtwdev->regd, -+ rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, - "worldwide roaming chip, follow the setting of stack"); - return 0; - } -@@ -428,13 +433,13 @@ static void rtw89_regd_notifier_apply(st - struct wiphy *wiphy, - struct regulatory_request *request) - { -- rtwdev->regd = rtw89_regd_find_reg_by_name(request->alpha2); -+ rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2); - /* This notification might be set from the system of distros, - * and it does not expect the regulatory will be modified by - * connecting to an AP (i.e. country ie). - */ - if (request->initiator == NL80211_REGDOM_SET_BY_USER && -- !rtw89_regd_is_ww(rtwdev->regd)) -+ !rtw89_regd_is_ww(rtwdev->regulatory.regd)) - wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; - else - wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; -@@ -454,7 +459,8 @@ void rtw89_regd_notifier(struct wiphy *w - goto exit; - } - rtw89_regd_notifier_apply(rtwdev, wiphy, request); -- rtw89_debug_regd(rtwdev, rtwdev->regd, "get from initiator %d, alpha2", -+ rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, -+ "get from initiator %d, alpha2", - request->initiator); - - rtw89_core_set_chip_txpwr(rtwdev); -@@ -462,3 +468,66 @@ void rtw89_regd_notifier(struct wiphy *w - exit: - mutex_unlock(&rtwdev->mutex); - } -+ -+static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; -+ enum rtw89_reg_6ghz_power sel; -+ const struct rtw89_chan *chan; -+ struct rtw89_vif *rtwvif; -+ int count = 0; -+ -+ rtw89_for_each_rtwvif(rtwdev, rtwvif) { -+ chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx); -+ if (chan->band_type != RTW89_BAND_6G) -+ continue; -+ -+ if (count != 0 && rtwvif->reg_6ghz_power == sel) -+ continue; -+ -+ sel = rtwvif->reg_6ghz_power; -+ count++; -+ } -+ -+ if (count != 1) -+ sel = RTW89_REG_6GHZ_POWER_DFLT; -+ -+ if (regulatory->reg_6ghz_power == sel) -+ return; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_REGD, -+ "recalc 6 GHz reg power type to %d\n", sel); -+ -+ regulatory->reg_6ghz_power = sel; -+ -+ rtw89_core_set_chip_txpwr(rtwdev); -+} -+ -+void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, -+ struct rtw89_vif *rtwvif, bool active) -+{ -+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); -+ -+ lockdep_assert_held(&rtwdev->mutex); -+ -+ if (active) { -+ switch (vif->bss_conf.power_type) { -+ case IEEE80211_REG_VLP_AP: -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP; -+ break; -+ case IEEE80211_REG_LPI_AP: -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI; -+ break; -+ case IEEE80211_REG_SP_AP: -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD; -+ break; -+ default: -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; -+ break; -+ } -+ } else { -+ rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; -+ } -+ -+ __rtw89_reg_6ghz_power_recalc(rtwdev); -+} diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-130-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-130-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch deleted file mode 100644 index 3312a0b48..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-130-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch +++ /dev/null @@ -1,8045 +0,0 @@ -From b742394cfe80a51572ff74e0a57b4b21db1489b1 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:53 +0800 -Subject: [PATCH 130/136] wifi: rtw89: 8852c: update TX power tables to R63 - with 6 GHz power type (1 of 3) - -Update TX power tables to RF version R63. - -TX power tables' changes: -* TX power byrate: - tweak a bit -* TX power limit, TX power limit RU, TX power shape: - configure values for MEXICO, UKRAINE, CHILE, QATAR - tweak a bit on other configured values -* 6 GHz TX power limit, 6 GHz TX power limit RU: - add an extra dimension for 6 GHz regulatory power type, i.e. - STD (standard power), LPI (low power indoor), VLP (very low power) - -Besides, we adjust TX power handling at 6 GHz in phy to consider 6 GHz -regulatory power type. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-6-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8852c_table.c | 3382 +++++++++++++++-- - 1 file changed, 2964 insertions(+), 418 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -28430,11 +28430,11 @@ static const struct rtw89_txpwr_byrate_c - { 2, 0, 1, 4, 4, 0x383c4040, }, - { 2, 0, 2, 0, 4, 0x40404040, }, - { 2, 0, 2, 4, 4, 0x34383c40, }, -- { 2, 0, 2, 8, 4, 0x24282c30, }, -+ { 2, 0, 2, 8, 4, 0x20282c30, }, - { 2, 0, 3, 0, 4, 0x40404040, }, - { 2, 1, 2, 0, 4, 0x40404040, }, - { 2, 1, 2, 4, 4, 0x34383c40, }, -- { 2, 1, 2, 8, 4, 0x24282c30, }, -+ { 2, 1, 2, 8, 4, 0x20282c30, }, - { 2, 1, 3, 0, 4, 0x40404040, }, - { 2, 0, 4, 0, 4, 0x00000000, }, - }; -@@ -28562,32 +28562,50 @@ static const s8 _txpwr_track_delta_swing - const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM] = { - [0][0][RTW89_ACMA] = 0, -+ [0][0][RTW89_CHILE] = 0, - [0][0][RTW89_CN] = 0, - [0][0][RTW89_ETSI] = 0, - [0][0][RTW89_FCC] = 1, - [0][0][RTW89_IC] = 1, - [0][0][RTW89_KCC] = 0, -+ [0][0][RTW89_MEXICO] = 1, - [0][0][RTW89_MKK] = 0, -+ [0][0][RTW89_QATAR] = 0, - [0][0][RTW89_UK] = 0, -+ [0][0][RTW89_UKRAINE] = 0, - [0][1][RTW89_ACMA] = 0, -+ [0][1][RTW89_CHILE] = 0, - [0][1][RTW89_CN] = 0, - [0][1][RTW89_ETSI] = 0, - [0][1][RTW89_FCC] = 3, - [0][1][RTW89_IC] = 3, - [0][1][RTW89_KCC] = 0, -+ [0][1][RTW89_MEXICO] = 3, - [0][1][RTW89_MKK] = 0, -+ [0][1][RTW89_QATAR] = 0, - [0][1][RTW89_UK] = 0, -+ [0][1][RTW89_UKRAINE] = 0, - [1][1][RTW89_ACMA] = 0, -+ [1][1][RTW89_CHILE] = 0, - [1][1][RTW89_CN] = 0, - [1][1][RTW89_ETSI] = 0, - [1][1][RTW89_FCC] = 3, - [1][1][RTW89_IC] = 3, - [1][1][RTW89_KCC] = 0, -+ [1][1][RTW89_MEXICO] = 3, - [1][1][RTW89_MKK] = 0, -+ [1][1][RTW89_QATAR] = 0, - [1][1][RTW89_UK] = 0, -+ [1][1][RTW89_UKRAINE] = 0, -+ [2][1][RTW89_ACMA] = 0, -+ [2][1][RTW89_CHILE] = 0, - [2][1][RTW89_ETSI] = 0, - [2][1][RTW89_FCC] = 0, -+ [2][1][RTW89_IC] = 0, - [2][1][RTW89_KCC] = 0, -+ [2][1][RTW89_MKK] = 0, -+ [2][1][RTW89_QATAR] = 0, -+ [2][1][RTW89_UK] = 0, - }; - - static -@@ -28770,6 +28788,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][0] = 60, - [0][0][0][0][RTW89_CN][0] = 58, - [0][0][0][0][RTW89_UK][0] = 60, -+ [0][0][0][0][RTW89_MEXICO][0] = 76, -+ [0][0][0][0][RTW89_UKRAINE][0] = 60, -+ [0][0][0][0][RTW89_CHILE][0] = 76, -+ [0][0][0][0][RTW89_QATAR][0] = 60, - [0][0][0][0][RTW89_FCC][1] = 76, - [0][0][0][0][RTW89_ETSI][1] = 60, - [0][0][0][0][RTW89_MKK][1] = 68, -@@ -28778,6 +28800,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][1] = 60, - [0][0][0][0][RTW89_CN][1] = 58, - [0][0][0][0][RTW89_UK][1] = 60, -+ [0][0][0][0][RTW89_MEXICO][1] = 76, -+ [0][0][0][0][RTW89_UKRAINE][1] = 60, -+ [0][0][0][0][RTW89_CHILE][1] = 68, -+ [0][0][0][0][RTW89_QATAR][1] = 60, - [0][0][0][0][RTW89_FCC][2] = 76, - [0][0][0][0][RTW89_ETSI][2] = 60, - [0][0][0][0][RTW89_MKK][2] = 68, -@@ -28786,6 +28812,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][2] = 60, - [0][0][0][0][RTW89_CN][2] = 58, - [0][0][0][0][RTW89_UK][2] = 60, -+ [0][0][0][0][RTW89_MEXICO][2] = 76, -+ [0][0][0][0][RTW89_UKRAINE][2] = 60, -+ [0][0][0][0][RTW89_CHILE][2] = 68, -+ [0][0][0][0][RTW89_QATAR][2] = 60, - [0][0][0][0][RTW89_FCC][3] = 76, - [0][0][0][0][RTW89_ETSI][3] = 60, - [0][0][0][0][RTW89_MKK][3] = 68, -@@ -28794,6 +28824,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][3] = 60, - [0][0][0][0][RTW89_CN][3] = 58, - [0][0][0][0][RTW89_UK][3] = 60, -+ [0][0][0][0][RTW89_MEXICO][3] = 76, -+ [0][0][0][0][RTW89_UKRAINE][3] = 60, -+ [0][0][0][0][RTW89_CHILE][3] = 68, -+ [0][0][0][0][RTW89_QATAR][3] = 60, - [0][0][0][0][RTW89_FCC][4] = 76, - [0][0][0][0][RTW89_ETSI][4] = 60, - [0][0][0][0][RTW89_MKK][4] = 68, -@@ -28802,6 +28836,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][4] = 60, - [0][0][0][0][RTW89_CN][4] = 58, - [0][0][0][0][RTW89_UK][4] = 60, -+ [0][0][0][0][RTW89_MEXICO][4] = 76, -+ [0][0][0][0][RTW89_UKRAINE][4] = 60, -+ [0][0][0][0][RTW89_CHILE][4] = 68, -+ [0][0][0][0][RTW89_QATAR][4] = 60, - [0][0][0][0][RTW89_FCC][5] = 76, - [0][0][0][0][RTW89_ETSI][5] = 60, - [0][0][0][0][RTW89_MKK][5] = 68, -@@ -28810,6 +28848,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][5] = 60, - [0][0][0][0][RTW89_CN][5] = 58, - [0][0][0][0][RTW89_UK][5] = 60, -+ [0][0][0][0][RTW89_MEXICO][5] = 76, -+ [0][0][0][0][RTW89_UKRAINE][5] = 60, -+ [0][0][0][0][RTW89_CHILE][5] = 76, -+ [0][0][0][0][RTW89_QATAR][5] = 60, - [0][0][0][0][RTW89_FCC][6] = 76, - [0][0][0][0][RTW89_ETSI][6] = 60, - [0][0][0][0][RTW89_MKK][6] = 68, -@@ -28818,6 +28860,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][6] = 60, - [0][0][0][0][RTW89_CN][6] = 58, - [0][0][0][0][RTW89_UK][6] = 60, -+ [0][0][0][0][RTW89_MEXICO][6] = 76, -+ [0][0][0][0][RTW89_UKRAINE][6] = 60, -+ [0][0][0][0][RTW89_CHILE][6] = 76, -+ [0][0][0][0][RTW89_QATAR][6] = 60, - [0][0][0][0][RTW89_FCC][7] = 76, - [0][0][0][0][RTW89_ETSI][7] = 60, - [0][0][0][0][RTW89_MKK][7] = 68, -@@ -28826,6 +28872,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][7] = 60, - [0][0][0][0][RTW89_CN][7] = 58, - [0][0][0][0][RTW89_UK][7] = 60, -+ [0][0][0][0][RTW89_MEXICO][7] = 76, -+ [0][0][0][0][RTW89_UKRAINE][7] = 60, -+ [0][0][0][0][RTW89_CHILE][7] = 76, -+ [0][0][0][0][RTW89_QATAR][7] = 60, - [0][0][0][0][RTW89_FCC][8] = 76, - [0][0][0][0][RTW89_ETSI][8] = 60, - [0][0][0][0][RTW89_MKK][8] = 68, -@@ -28834,6 +28884,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][8] = 60, - [0][0][0][0][RTW89_CN][8] = 58, - [0][0][0][0][RTW89_UK][8] = 60, -+ [0][0][0][0][RTW89_MEXICO][8] = 76, -+ [0][0][0][0][RTW89_UKRAINE][8] = 60, -+ [0][0][0][0][RTW89_CHILE][8] = 76, -+ [0][0][0][0][RTW89_QATAR][8] = 60, - [0][0][0][0][RTW89_FCC][9] = 76, - [0][0][0][0][RTW89_ETSI][9] = 60, - [0][0][0][0][RTW89_MKK][9] = 68, -@@ -28842,6 +28896,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][9] = 60, - [0][0][0][0][RTW89_CN][9] = 58, - [0][0][0][0][RTW89_UK][9] = 60, -+ [0][0][0][0][RTW89_MEXICO][9] = 76, -+ [0][0][0][0][RTW89_UKRAINE][9] = 60, -+ [0][0][0][0][RTW89_CHILE][9] = 76, -+ [0][0][0][0][RTW89_QATAR][9] = 60, - [0][0][0][0][RTW89_FCC][10] = 76, - [0][0][0][0][RTW89_ETSI][10] = 60, - [0][0][0][0][RTW89_MKK][10] = 68, -@@ -28850,6 +28908,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][10] = 60, - [0][0][0][0][RTW89_CN][10] = 58, - [0][0][0][0][RTW89_UK][10] = 60, -+ [0][0][0][0][RTW89_MEXICO][10] = 76, -+ [0][0][0][0][RTW89_UKRAINE][10] = 60, -+ [0][0][0][0][RTW89_CHILE][10] = 76, -+ [0][0][0][0][RTW89_QATAR][10] = 60, - [0][0][0][0][RTW89_FCC][11] = 58, - [0][0][0][0][RTW89_ETSI][11] = 60, - [0][0][0][0][RTW89_MKK][11] = 68, -@@ -28858,6 +28920,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][11] = 60, - [0][0][0][0][RTW89_CN][11] = 58, - [0][0][0][0][RTW89_UK][11] = 60, -+ [0][0][0][0][RTW89_MEXICO][11] = 58, -+ [0][0][0][0][RTW89_UKRAINE][11] = 60, -+ [0][0][0][0][RTW89_CHILE][11] = 58, -+ [0][0][0][0][RTW89_QATAR][11] = 60, - [0][0][0][0][RTW89_FCC][12] = 46, - [0][0][0][0][RTW89_ETSI][12] = 60, - [0][0][0][0][RTW89_MKK][12] = 68, -@@ -28866,6 +28932,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][12] = 60, - [0][0][0][0][RTW89_CN][12] = 58, - [0][0][0][0][RTW89_UK][12] = 60, -+ [0][0][0][0][RTW89_MEXICO][12] = 46, -+ [0][0][0][0][RTW89_UKRAINE][12] = 60, -+ [0][0][0][0][RTW89_CHILE][12] = 46, -+ [0][0][0][0][RTW89_QATAR][12] = 60, - [0][0][0][0][RTW89_FCC][13] = 127, - [0][0][0][0][RTW89_ETSI][13] = 127, - [0][0][0][0][RTW89_MKK][13] = 72, -@@ -28874,6 +28944,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][0][0][RTW89_ACMA][13] = 127, - [0][0][0][0][RTW89_CN][13] = 127, - [0][0][0][0][RTW89_UK][13] = 127, -+ [0][0][0][0][RTW89_MEXICO][13] = 127, -+ [0][0][0][0][RTW89_UKRAINE][13] = 127, -+ [0][0][0][0][RTW89_CHILE][13] = 127, -+ [0][0][0][0][RTW89_QATAR][13] = 127, - [0][1][0][0][RTW89_FCC][0] = 76, - [0][1][0][0][RTW89_ETSI][0] = 48, - [0][1][0][0][RTW89_MKK][0] = 58, -@@ -28882,6 +28956,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][0] = 48, - [0][1][0][0][RTW89_CN][0] = 42, - [0][1][0][0][RTW89_UK][0] = 48, -+ [0][1][0][0][RTW89_MEXICO][0] = 76, -+ [0][1][0][0][RTW89_UKRAINE][0] = 48, -+ [0][1][0][0][RTW89_CHILE][0] = 76, -+ [0][1][0][0][RTW89_QATAR][0] = 48, - [0][1][0][0][RTW89_FCC][1] = 76, - [0][1][0][0][RTW89_ETSI][1] = 48, - [0][1][0][0][RTW89_MKK][1] = 58, -@@ -28890,6 +28968,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][1] = 48, - [0][1][0][0][RTW89_CN][1] = 42, - [0][1][0][0][RTW89_UK][1] = 48, -+ [0][1][0][0][RTW89_MEXICO][1] = 76, -+ [0][1][0][0][RTW89_UKRAINE][1] = 48, -+ [0][1][0][0][RTW89_CHILE][1] = 54, -+ [0][1][0][0][RTW89_QATAR][1] = 48, - [0][1][0][0][RTW89_FCC][2] = 76, - [0][1][0][0][RTW89_ETSI][2] = 48, - [0][1][0][0][RTW89_MKK][2] = 58, -@@ -28898,6 +28980,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][2] = 48, - [0][1][0][0][RTW89_CN][2] = 42, - [0][1][0][0][RTW89_UK][2] = 48, -+ [0][1][0][0][RTW89_MEXICO][2] = 76, -+ [0][1][0][0][RTW89_UKRAINE][2] = 48, -+ [0][1][0][0][RTW89_CHILE][2] = 54, -+ [0][1][0][0][RTW89_QATAR][2] = 48, - [0][1][0][0][RTW89_FCC][3] = 76, - [0][1][0][0][RTW89_ETSI][3] = 48, - [0][1][0][0][RTW89_MKK][3] = 58, -@@ -28906,6 +28992,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][3] = 48, - [0][1][0][0][RTW89_CN][3] = 42, - [0][1][0][0][RTW89_UK][3] = 48, -+ [0][1][0][0][RTW89_MEXICO][3] = 76, -+ [0][1][0][0][RTW89_UKRAINE][3] = 48, -+ [0][1][0][0][RTW89_CHILE][3] = 54, -+ [0][1][0][0][RTW89_QATAR][3] = 48, - [0][1][0][0][RTW89_FCC][4] = 76, - [0][1][0][0][RTW89_ETSI][4] = 48, - [0][1][0][0][RTW89_MKK][4] = 58, -@@ -28914,6 +29004,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][4] = 48, - [0][1][0][0][RTW89_CN][4] = 42, - [0][1][0][0][RTW89_UK][4] = 48, -+ [0][1][0][0][RTW89_MEXICO][4] = 76, -+ [0][1][0][0][RTW89_UKRAINE][4] = 48, -+ [0][1][0][0][RTW89_CHILE][4] = 54, -+ [0][1][0][0][RTW89_QATAR][4] = 48, - [0][1][0][0][RTW89_FCC][5] = 76, - [0][1][0][0][RTW89_ETSI][5] = 48, - [0][1][0][0][RTW89_MKK][5] = 58, -@@ -28922,6 +29016,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][5] = 48, - [0][1][0][0][RTW89_CN][5] = 42, - [0][1][0][0][RTW89_UK][5] = 48, -+ [0][1][0][0][RTW89_MEXICO][5] = 76, -+ [0][1][0][0][RTW89_UKRAINE][5] = 48, -+ [0][1][0][0][RTW89_CHILE][5] = 76, -+ [0][1][0][0][RTW89_QATAR][5] = 48, - [0][1][0][0][RTW89_FCC][6] = 76, - [0][1][0][0][RTW89_ETSI][6] = 48, - [0][1][0][0][RTW89_MKK][6] = 58, -@@ -28930,6 +29028,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][6] = 48, - [0][1][0][0][RTW89_CN][6] = 42, - [0][1][0][0][RTW89_UK][6] = 48, -+ [0][1][0][0][RTW89_MEXICO][6] = 76, -+ [0][1][0][0][RTW89_UKRAINE][6] = 48, -+ [0][1][0][0][RTW89_CHILE][6] = 76, -+ [0][1][0][0][RTW89_QATAR][6] = 48, - [0][1][0][0][RTW89_FCC][7] = 76, - [0][1][0][0][RTW89_ETSI][7] = 48, - [0][1][0][0][RTW89_MKK][7] = 58, -@@ -28938,6 +29040,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][7] = 48, - [0][1][0][0][RTW89_CN][7] = 42, - [0][1][0][0][RTW89_UK][7] = 48, -+ [0][1][0][0][RTW89_MEXICO][7] = 76, -+ [0][1][0][0][RTW89_UKRAINE][7] = 48, -+ [0][1][0][0][RTW89_CHILE][7] = 76, -+ [0][1][0][0][RTW89_QATAR][7] = 48, - [0][1][0][0][RTW89_FCC][8] = 76, - [0][1][0][0][RTW89_ETSI][8] = 48, - [0][1][0][0][RTW89_MKK][8] = 58, -@@ -28946,6 +29052,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][8] = 48, - [0][1][0][0][RTW89_CN][8] = 42, - [0][1][0][0][RTW89_UK][8] = 48, -+ [0][1][0][0][RTW89_MEXICO][8] = 76, -+ [0][1][0][0][RTW89_UKRAINE][8] = 48, -+ [0][1][0][0][RTW89_CHILE][8] = 76, -+ [0][1][0][0][RTW89_QATAR][8] = 48, - [0][1][0][0][RTW89_FCC][9] = 70, - [0][1][0][0][RTW89_ETSI][9] = 48, - [0][1][0][0][RTW89_MKK][9] = 58, -@@ -28954,6 +29064,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][9] = 48, - [0][1][0][0][RTW89_CN][9] = 42, - [0][1][0][0][RTW89_UK][9] = 48, -+ [0][1][0][0][RTW89_MEXICO][9] = 70, -+ [0][1][0][0][RTW89_UKRAINE][9] = 48, -+ [0][1][0][0][RTW89_CHILE][9] = 70, -+ [0][1][0][0][RTW89_QATAR][9] = 48, - [0][1][0][0][RTW89_FCC][10] = 72, - [0][1][0][0][RTW89_ETSI][10] = 48, - [0][1][0][0][RTW89_MKK][10] = 58, -@@ -28962,6 +29076,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][10] = 48, - [0][1][0][0][RTW89_CN][10] = 42, - [0][1][0][0][RTW89_UK][10] = 48, -+ [0][1][0][0][RTW89_MEXICO][10] = 72, -+ [0][1][0][0][RTW89_UKRAINE][10] = 48, -+ [0][1][0][0][RTW89_CHILE][10] = 72, -+ [0][1][0][0][RTW89_QATAR][10] = 48, - [0][1][0][0][RTW89_FCC][11] = 44, - [0][1][0][0][RTW89_ETSI][11] = 48, - [0][1][0][0][RTW89_MKK][11] = 58, -@@ -28970,6 +29088,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][11] = 48, - [0][1][0][0][RTW89_CN][11] = 42, - [0][1][0][0][RTW89_UK][11] = 48, -+ [0][1][0][0][RTW89_MEXICO][11] = 44, -+ [0][1][0][0][RTW89_UKRAINE][11] = 48, -+ [0][1][0][0][RTW89_CHILE][11] = 44, -+ [0][1][0][0][RTW89_QATAR][11] = 48, - [0][1][0][0][RTW89_FCC][12] = 18, - [0][1][0][0][RTW89_ETSI][12] = 48, - [0][1][0][0][RTW89_MKK][12] = 58, -@@ -28978,6 +29100,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][12] = 48, - [0][1][0][0][RTW89_CN][12] = 42, - [0][1][0][0][RTW89_UK][12] = 48, -+ [0][1][0][0][RTW89_MEXICO][12] = 18, -+ [0][1][0][0][RTW89_UKRAINE][12] = 48, -+ [0][1][0][0][RTW89_CHILE][12] = 18, -+ [0][1][0][0][RTW89_QATAR][12] = 48, - [0][1][0][0][RTW89_FCC][13] = 127, - [0][1][0][0][RTW89_ETSI][13] = 127, - [0][1][0][0][RTW89_MKK][13] = 60, -@@ -28986,6 +29112,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][0][0][RTW89_ACMA][13] = 127, - [0][1][0][0][RTW89_CN][13] = 127, - [0][1][0][0][RTW89_UK][13] = 127, -+ [0][1][0][0][RTW89_MEXICO][13] = 127, -+ [0][1][0][0][RTW89_UKRAINE][13] = 127, -+ [0][1][0][0][RTW89_CHILE][13] = 127, -+ [0][1][0][0][RTW89_QATAR][13] = 127, - [1][0][0][0][RTW89_FCC][0] = 127, - [1][0][0][0][RTW89_ETSI][0] = 127, - [1][0][0][0][RTW89_MKK][0] = 127, -@@ -28994,6 +29124,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][0] = 127, - [1][0][0][0][RTW89_CN][0] = 127, - [1][0][0][0][RTW89_UK][0] = 127, -+ [1][0][0][0][RTW89_MEXICO][0] = 127, -+ [1][0][0][0][RTW89_UKRAINE][0] = 127, -+ [1][0][0][0][RTW89_CHILE][0] = 127, -+ [1][0][0][0][RTW89_QATAR][0] = 127, - [1][0][0][0][RTW89_FCC][1] = 127, - [1][0][0][0][RTW89_ETSI][1] = 127, - [1][0][0][0][RTW89_MKK][1] = 127, -@@ -29002,6 +29136,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][1] = 127, - [1][0][0][0][RTW89_CN][1] = 127, - [1][0][0][0][RTW89_UK][1] = 127, -+ [1][0][0][0][RTW89_MEXICO][1] = 127, -+ [1][0][0][0][RTW89_UKRAINE][1] = 127, -+ [1][0][0][0][RTW89_CHILE][1] = 127, -+ [1][0][0][0][RTW89_QATAR][1] = 127, - [1][0][0][0][RTW89_FCC][2] = 44, - [1][0][0][0][RTW89_ETSI][2] = 60, - [1][0][0][0][RTW89_MKK][2] = 66, -@@ -29010,6 +29148,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][2] = 60, - [1][0][0][0][RTW89_CN][2] = 58, - [1][0][0][0][RTW89_UK][2] = 60, -+ [1][0][0][0][RTW89_MEXICO][2] = 44, -+ [1][0][0][0][RTW89_UKRAINE][2] = 60, -+ [1][0][0][0][RTW89_CHILE][2] = 44, -+ [1][0][0][0][RTW89_QATAR][2] = 60, - [1][0][0][0][RTW89_FCC][3] = 60, - [1][0][0][0][RTW89_ETSI][3] = 60, - [1][0][0][0][RTW89_MKK][3] = 66, -@@ -29018,6 +29160,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][3] = 60, - [1][0][0][0][RTW89_CN][3] = 58, - [1][0][0][0][RTW89_UK][3] = 60, -+ [1][0][0][0][RTW89_MEXICO][3] = 60, -+ [1][0][0][0][RTW89_UKRAINE][3] = 60, -+ [1][0][0][0][RTW89_CHILE][3] = 60, -+ [1][0][0][0][RTW89_QATAR][3] = 60, - [1][0][0][0][RTW89_FCC][4] = 60, - [1][0][0][0][RTW89_ETSI][4] = 60, - [1][0][0][0][RTW89_MKK][4] = 66, -@@ -29026,6 +29172,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][4] = 60, - [1][0][0][0][RTW89_CN][4] = 58, - [1][0][0][0][RTW89_UK][4] = 60, -+ [1][0][0][0][RTW89_MEXICO][4] = 60, -+ [1][0][0][0][RTW89_UKRAINE][4] = 60, -+ [1][0][0][0][RTW89_CHILE][4] = 60, -+ [1][0][0][0][RTW89_QATAR][4] = 60, - [1][0][0][0][RTW89_FCC][5] = 62, - [1][0][0][0][RTW89_ETSI][5] = 60, - [1][0][0][0][RTW89_MKK][5] = 66, -@@ -29034,6 +29184,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][5] = 60, - [1][0][0][0][RTW89_CN][5] = 58, - [1][0][0][0][RTW89_UK][5] = 60, -+ [1][0][0][0][RTW89_MEXICO][5] = 62, -+ [1][0][0][0][RTW89_UKRAINE][5] = 60, -+ [1][0][0][0][RTW89_CHILE][5] = 62, -+ [1][0][0][0][RTW89_QATAR][5] = 60, - [1][0][0][0][RTW89_FCC][6] = 46, - [1][0][0][0][RTW89_ETSI][6] = 60, - [1][0][0][0][RTW89_MKK][6] = 66, -@@ -29042,6 +29196,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][6] = 60, - [1][0][0][0][RTW89_CN][6] = 58, - [1][0][0][0][RTW89_UK][6] = 60, -+ [1][0][0][0][RTW89_MEXICO][6] = 46, -+ [1][0][0][0][RTW89_UKRAINE][6] = 60, -+ [1][0][0][0][RTW89_CHILE][6] = 46, -+ [1][0][0][0][RTW89_QATAR][6] = 60, - [1][0][0][0][RTW89_FCC][7] = 46, - [1][0][0][0][RTW89_ETSI][7] = 60, - [1][0][0][0][RTW89_MKK][7] = 66, -@@ -29050,6 +29208,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][7] = 60, - [1][0][0][0][RTW89_CN][7] = 58, - [1][0][0][0][RTW89_UK][7] = 60, -+ [1][0][0][0][RTW89_MEXICO][7] = 46, -+ [1][0][0][0][RTW89_UKRAINE][7] = 60, -+ [1][0][0][0][RTW89_CHILE][7] = 46, -+ [1][0][0][0][RTW89_QATAR][7] = 60, - [1][0][0][0][RTW89_FCC][8] = 28, - [1][0][0][0][RTW89_ETSI][8] = 60, - [1][0][0][0][RTW89_MKK][8] = 66, -@@ -29058,6 +29220,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][8] = 60, - [1][0][0][0][RTW89_CN][8] = 58, - [1][0][0][0][RTW89_UK][8] = 60, -+ [1][0][0][0][RTW89_MEXICO][8] = 28, -+ [1][0][0][0][RTW89_UKRAINE][8] = 60, -+ [1][0][0][0][RTW89_CHILE][8] = 28, -+ [1][0][0][0][RTW89_QATAR][8] = 60, - [1][0][0][0][RTW89_FCC][9] = 26, - [1][0][0][0][RTW89_ETSI][9] = 60, - [1][0][0][0][RTW89_MKK][9] = 66, -@@ -29066,6 +29232,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][9] = 60, - [1][0][0][0][RTW89_CN][9] = 58, - [1][0][0][0][RTW89_UK][9] = 60, -+ [1][0][0][0][RTW89_MEXICO][9] = 26, -+ [1][0][0][0][RTW89_UKRAINE][9] = 60, -+ [1][0][0][0][RTW89_CHILE][9] = 26, -+ [1][0][0][0][RTW89_QATAR][9] = 60, - [1][0][0][0][RTW89_FCC][10] = 26, - [1][0][0][0][RTW89_ETSI][10] = 60, - [1][0][0][0][RTW89_MKK][10] = 66, -@@ -29074,6 +29244,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][10] = 60, - [1][0][0][0][RTW89_CN][10] = 58, - [1][0][0][0][RTW89_UK][10] = 60, -+ [1][0][0][0][RTW89_MEXICO][10] = 26, -+ [1][0][0][0][RTW89_UKRAINE][10] = 60, -+ [1][0][0][0][RTW89_CHILE][10] = 26, -+ [1][0][0][0][RTW89_QATAR][10] = 60, - [1][0][0][0][RTW89_FCC][11] = 127, - [1][0][0][0][RTW89_ETSI][11] = 127, - [1][0][0][0][RTW89_MKK][11] = 127, -@@ -29082,6 +29256,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][11] = 127, - [1][0][0][0][RTW89_CN][11] = 127, - [1][0][0][0][RTW89_UK][11] = 127, -+ [1][0][0][0][RTW89_MEXICO][11] = 127, -+ [1][0][0][0][RTW89_UKRAINE][11] = 127, -+ [1][0][0][0][RTW89_CHILE][11] = 127, -+ [1][0][0][0][RTW89_QATAR][11] = 127, - [1][0][0][0][RTW89_FCC][12] = 127, - [1][0][0][0][RTW89_ETSI][12] = 127, - [1][0][0][0][RTW89_MKK][12] = 127, -@@ -29090,6 +29268,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][12] = 127, - [1][0][0][0][RTW89_CN][12] = 127, - [1][0][0][0][RTW89_UK][12] = 127, -+ [1][0][0][0][RTW89_MEXICO][12] = 127, -+ [1][0][0][0][RTW89_UKRAINE][12] = 127, -+ [1][0][0][0][RTW89_CHILE][12] = 127, -+ [1][0][0][0][RTW89_QATAR][12] = 127, - [1][0][0][0][RTW89_FCC][13] = 127, - [1][0][0][0][RTW89_ETSI][13] = 127, - [1][0][0][0][RTW89_MKK][13] = 127, -@@ -29098,6 +29280,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][0][0][RTW89_ACMA][13] = 127, - [1][0][0][0][RTW89_CN][13] = 127, - [1][0][0][0][RTW89_UK][13] = 127, -+ [1][0][0][0][RTW89_MEXICO][13] = 127, -+ [1][0][0][0][RTW89_UKRAINE][13] = 127, -+ [1][0][0][0][RTW89_CHILE][13] = 127, -+ [1][0][0][0][RTW89_QATAR][13] = 127, - [1][1][0][0][RTW89_FCC][0] = 127, - [1][1][0][0][RTW89_ETSI][0] = 127, - [1][1][0][0][RTW89_MKK][0] = 127, -@@ -29106,6 +29292,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][0] = 127, - [1][1][0][0][RTW89_CN][0] = 127, - [1][1][0][0][RTW89_UK][0] = 127, -+ [1][1][0][0][RTW89_MEXICO][0] = 127, -+ [1][1][0][0][RTW89_UKRAINE][0] = 127, -+ [1][1][0][0][RTW89_CHILE][0] = 127, -+ [1][1][0][0][RTW89_QATAR][0] = 127, - [1][1][0][0][RTW89_FCC][1] = 127, - [1][1][0][0][RTW89_ETSI][1] = 127, - [1][1][0][0][RTW89_MKK][1] = 127, -@@ -29114,6 +29304,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][1] = 127, - [1][1][0][0][RTW89_CN][1] = 127, - [1][1][0][0][RTW89_UK][1] = 127, -+ [1][1][0][0][RTW89_MEXICO][1] = 127, -+ [1][1][0][0][RTW89_UKRAINE][1] = 127, -+ [1][1][0][0][RTW89_CHILE][1] = 127, -+ [1][1][0][0][RTW89_QATAR][1] = 127, - [1][1][0][0][RTW89_FCC][2] = 46, - [1][1][0][0][RTW89_ETSI][2] = 48, - [1][1][0][0][RTW89_MKK][2] = 58, -@@ -29122,6 +29316,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][2] = 48, - [1][1][0][0][RTW89_CN][2] = 46, - [1][1][0][0][RTW89_UK][2] = 48, -+ [1][1][0][0][RTW89_MEXICO][2] = 46, -+ [1][1][0][0][RTW89_UKRAINE][2] = 48, -+ [1][1][0][0][RTW89_CHILE][2] = 46, -+ [1][1][0][0][RTW89_QATAR][2] = 48, - [1][1][0][0][RTW89_FCC][3] = 46, - [1][1][0][0][RTW89_ETSI][3] = 48, - [1][1][0][0][RTW89_MKK][3] = 58, -@@ -29130,6 +29328,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][3] = 48, - [1][1][0][0][RTW89_CN][3] = 46, - [1][1][0][0][RTW89_UK][3] = 48, -+ [1][1][0][0][RTW89_MEXICO][3] = 46, -+ [1][1][0][0][RTW89_UKRAINE][3] = 48, -+ [1][1][0][0][RTW89_CHILE][3] = 46, -+ [1][1][0][0][RTW89_QATAR][3] = 48, - [1][1][0][0][RTW89_FCC][4] = 46, - [1][1][0][0][RTW89_ETSI][4] = 48, - [1][1][0][0][RTW89_MKK][4] = 58, -@@ -29138,6 +29340,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][4] = 48, - [1][1][0][0][RTW89_CN][4] = 46, - [1][1][0][0][RTW89_UK][4] = 48, -+ [1][1][0][0][RTW89_MEXICO][4] = 46, -+ [1][1][0][0][RTW89_UKRAINE][4] = 48, -+ [1][1][0][0][RTW89_CHILE][4] = 46, -+ [1][1][0][0][RTW89_QATAR][4] = 48, - [1][1][0][0][RTW89_FCC][5] = 48, - [1][1][0][0][RTW89_ETSI][5] = 48, - [1][1][0][0][RTW89_MKK][5] = 58, -@@ -29146,6 +29352,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][5] = 48, - [1][1][0][0][RTW89_CN][5] = 46, - [1][1][0][0][RTW89_UK][5] = 48, -+ [1][1][0][0][RTW89_MEXICO][5] = 48, -+ [1][1][0][0][RTW89_UKRAINE][5] = 48, -+ [1][1][0][0][RTW89_CHILE][5] = 48, -+ [1][1][0][0][RTW89_QATAR][5] = 48, - [1][1][0][0][RTW89_FCC][6] = 40, - [1][1][0][0][RTW89_ETSI][6] = 48, - [1][1][0][0][RTW89_MKK][6] = 58, -@@ -29154,6 +29364,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][6] = 48, - [1][1][0][0][RTW89_CN][6] = 46, - [1][1][0][0][RTW89_UK][6] = 48, -+ [1][1][0][0][RTW89_MEXICO][6] = 40, -+ [1][1][0][0][RTW89_UKRAINE][6] = 48, -+ [1][1][0][0][RTW89_CHILE][6] = 40, -+ [1][1][0][0][RTW89_QATAR][6] = 48, - [1][1][0][0][RTW89_FCC][7] = 40, - [1][1][0][0][RTW89_ETSI][7] = 48, - [1][1][0][0][RTW89_MKK][7] = 58, -@@ -29162,6 +29376,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][7] = 48, - [1][1][0][0][RTW89_CN][7] = 46, - [1][1][0][0][RTW89_UK][7] = 48, -+ [1][1][0][0][RTW89_MEXICO][7] = 40, -+ [1][1][0][0][RTW89_UKRAINE][7] = 48, -+ [1][1][0][0][RTW89_CHILE][7] = 40, -+ [1][1][0][0][RTW89_QATAR][7] = 48, - [1][1][0][0][RTW89_FCC][8] = 14, - [1][1][0][0][RTW89_ETSI][8] = 48, - [1][1][0][0][RTW89_MKK][8] = 58, -@@ -29170,6 +29388,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][8] = 48, - [1][1][0][0][RTW89_CN][8] = 46, - [1][1][0][0][RTW89_UK][8] = 48, -+ [1][1][0][0][RTW89_MEXICO][8] = 14, -+ [1][1][0][0][RTW89_UKRAINE][8] = 48, -+ [1][1][0][0][RTW89_CHILE][8] = 14, -+ [1][1][0][0][RTW89_QATAR][8] = 48, - [1][1][0][0][RTW89_FCC][9] = 14, - [1][1][0][0][RTW89_ETSI][9] = 48, - [1][1][0][0][RTW89_MKK][9] = 58, -@@ -29178,6 +29400,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][9] = 48, - [1][1][0][0][RTW89_CN][9] = 46, - [1][1][0][0][RTW89_UK][9] = 48, -+ [1][1][0][0][RTW89_MEXICO][9] = 14, -+ [1][1][0][0][RTW89_UKRAINE][9] = 48, -+ [1][1][0][0][RTW89_CHILE][9] = 14, -+ [1][1][0][0][RTW89_QATAR][9] = 48, - [1][1][0][0][RTW89_FCC][10] = 12, - [1][1][0][0][RTW89_ETSI][10] = 48, - [1][1][0][0][RTW89_MKK][10] = 56, -@@ -29186,6 +29412,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][10] = 48, - [1][1][0][0][RTW89_CN][10] = 46, - [1][1][0][0][RTW89_UK][10] = 48, -+ [1][1][0][0][RTW89_MEXICO][10] = 12, -+ [1][1][0][0][RTW89_UKRAINE][10] = 48, -+ [1][1][0][0][RTW89_CHILE][10] = 12, -+ [1][1][0][0][RTW89_QATAR][10] = 48, - [1][1][0][0][RTW89_FCC][11] = 127, - [1][1][0][0][RTW89_ETSI][11] = 127, - [1][1][0][0][RTW89_MKK][11] = 127, -@@ -29194,6 +29424,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][11] = 127, - [1][1][0][0][RTW89_CN][11] = 127, - [1][1][0][0][RTW89_UK][11] = 127, -+ [1][1][0][0][RTW89_MEXICO][11] = 127, -+ [1][1][0][0][RTW89_UKRAINE][11] = 127, -+ [1][1][0][0][RTW89_CHILE][11] = 127, -+ [1][1][0][0][RTW89_QATAR][11] = 127, - [1][1][0][0][RTW89_FCC][12] = 127, - [1][1][0][0][RTW89_ETSI][12] = 127, - [1][1][0][0][RTW89_MKK][12] = 127, -@@ -29202,6 +29436,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][12] = 127, - [1][1][0][0][RTW89_CN][12] = 127, - [1][1][0][0][RTW89_UK][12] = 127, -+ [1][1][0][0][RTW89_MEXICO][12] = 127, -+ [1][1][0][0][RTW89_UKRAINE][12] = 127, -+ [1][1][0][0][RTW89_CHILE][12] = 127, -+ [1][1][0][0][RTW89_QATAR][12] = 127, - [1][1][0][0][RTW89_FCC][13] = 127, - [1][1][0][0][RTW89_ETSI][13] = 127, - [1][1][0][0][RTW89_MKK][13] = 127, -@@ -29210,6 +29448,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][0][0][RTW89_ACMA][13] = 127, - [1][1][0][0][RTW89_CN][13] = 127, - [1][1][0][0][RTW89_UK][13] = 127, -+ [1][1][0][0][RTW89_MEXICO][13] = 127, -+ [1][1][0][0][RTW89_UKRAINE][13] = 127, -+ [1][1][0][0][RTW89_CHILE][13] = 127, -+ [1][1][0][0][RTW89_QATAR][13] = 127, - [0][0][1][0][RTW89_FCC][0] = 66, - [0][0][1][0][RTW89_ETSI][0] = 60, - [0][0][1][0][RTW89_MKK][0] = 76, -@@ -29218,6 +29460,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][0] = 60, - [0][0][1][0][RTW89_CN][0] = 58, - [0][0][1][0][RTW89_UK][0] = 60, -+ [0][0][1][0][RTW89_MEXICO][0] = 66, -+ [0][0][1][0][RTW89_UKRAINE][0] = 60, -+ [0][0][1][0][RTW89_CHILE][0] = 66, -+ [0][0][1][0][RTW89_QATAR][0] = 60, - [0][0][1][0][RTW89_FCC][1] = 68, - [0][0][1][0][RTW89_ETSI][1] = 60, - [0][0][1][0][RTW89_MKK][1] = 78, -@@ -29226,6 +29472,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][1] = 60, - [0][0][1][0][RTW89_CN][1] = 58, - [0][0][1][0][RTW89_UK][1] = 60, -+ [0][0][1][0][RTW89_MEXICO][1] = 68, -+ [0][0][1][0][RTW89_UKRAINE][1] = 60, -+ [0][0][1][0][RTW89_CHILE][1] = 68, -+ [0][0][1][0][RTW89_QATAR][1] = 60, - [0][0][1][0][RTW89_FCC][2] = 72, - [0][0][1][0][RTW89_ETSI][2] = 60, - [0][0][1][0][RTW89_MKK][2] = 78, -@@ -29234,6 +29484,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][2] = 60, - [0][0][1][0][RTW89_CN][2] = 58, - [0][0][1][0][RTW89_UK][2] = 60, -+ [0][0][1][0][RTW89_MEXICO][2] = 72, -+ [0][0][1][0][RTW89_UKRAINE][2] = 60, -+ [0][0][1][0][RTW89_CHILE][2] = 62, -+ [0][0][1][0][RTW89_QATAR][2] = 60, - [0][0][1][0][RTW89_FCC][3] = 76, - [0][0][1][0][RTW89_ETSI][3] = 60, - [0][0][1][0][RTW89_MKK][3] = 78, -@@ -29242,6 +29496,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][3] = 60, - [0][0][1][0][RTW89_CN][3] = 58, - [0][0][1][0][RTW89_UK][3] = 60, -+ [0][0][1][0][RTW89_MEXICO][3] = 76, -+ [0][0][1][0][RTW89_UKRAINE][3] = 60, -+ [0][0][1][0][RTW89_CHILE][3] = 62, -+ [0][0][1][0][RTW89_QATAR][3] = 60, - [0][0][1][0][RTW89_FCC][4] = 80, - [0][0][1][0][RTW89_ETSI][4] = 60, - [0][0][1][0][RTW89_MKK][4] = 78, -@@ -29250,6 +29508,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][4] = 60, - [0][0][1][0][RTW89_CN][4] = 58, - [0][0][1][0][RTW89_UK][4] = 60, -+ [0][0][1][0][RTW89_MEXICO][4] = 80, -+ [0][0][1][0][RTW89_UKRAINE][4] = 60, -+ [0][0][1][0][RTW89_CHILE][4] = 62, -+ [0][0][1][0][RTW89_QATAR][4] = 60, - [0][0][1][0][RTW89_FCC][5] = 80, - [0][0][1][0][RTW89_ETSI][5] = 60, - [0][0][1][0][RTW89_MKK][5] = 78, -@@ -29258,6 +29520,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][5] = 60, - [0][0][1][0][RTW89_CN][5] = 58, - [0][0][1][0][RTW89_UK][5] = 60, -+ [0][0][1][0][RTW89_MEXICO][5] = 80, -+ [0][0][1][0][RTW89_UKRAINE][5] = 60, -+ [0][0][1][0][RTW89_CHILE][5] = 80, -+ [0][0][1][0][RTW89_QATAR][5] = 60, - [0][0][1][0][RTW89_FCC][6] = 80, - [0][0][1][0][RTW89_ETSI][6] = 60, - [0][0][1][0][RTW89_MKK][6] = 76, -@@ -29266,6 +29532,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][6] = 60, - [0][0][1][0][RTW89_CN][6] = 58, - [0][0][1][0][RTW89_UK][6] = 60, -+ [0][0][1][0][RTW89_MEXICO][6] = 80, -+ [0][0][1][0][RTW89_UKRAINE][6] = 60, -+ [0][0][1][0][RTW89_CHILE][6] = 70, -+ [0][0][1][0][RTW89_QATAR][6] = 60, - [0][0][1][0][RTW89_FCC][7] = 80, - [0][0][1][0][RTW89_ETSI][7] = 60, - [0][0][1][0][RTW89_MKK][7] = 78, -@@ -29274,6 +29544,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][7] = 60, - [0][0][1][0][RTW89_CN][7] = 58, - [0][0][1][0][RTW89_UK][7] = 60, -+ [0][0][1][0][RTW89_MEXICO][7] = 80, -+ [0][0][1][0][RTW89_UKRAINE][7] = 60, -+ [0][0][1][0][RTW89_CHILE][7] = 70, -+ [0][0][1][0][RTW89_QATAR][7] = 60, - [0][0][1][0][RTW89_FCC][8] = 80, - [0][0][1][0][RTW89_ETSI][8] = 60, - [0][0][1][0][RTW89_MKK][8] = 78, -@@ -29282,6 +29556,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][8] = 60, - [0][0][1][0][RTW89_CN][8] = 58, - [0][0][1][0][RTW89_UK][8] = 60, -+ [0][0][1][0][RTW89_MEXICO][8] = 80, -+ [0][0][1][0][RTW89_UKRAINE][8] = 60, -+ [0][0][1][0][RTW89_CHILE][8] = 70, -+ [0][0][1][0][RTW89_QATAR][8] = 60, - [0][0][1][0][RTW89_FCC][9] = 76, - [0][0][1][0][RTW89_ETSI][9] = 60, - [0][0][1][0][RTW89_MKK][9] = 78, -@@ -29290,6 +29568,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][9] = 60, - [0][0][1][0][RTW89_CN][9] = 58, - [0][0][1][0][RTW89_UK][9] = 60, -+ [0][0][1][0][RTW89_MEXICO][9] = 76, -+ [0][0][1][0][RTW89_UKRAINE][9] = 60, -+ [0][0][1][0][RTW89_CHILE][9] = 76, -+ [0][0][1][0][RTW89_QATAR][9] = 60, - [0][0][1][0][RTW89_FCC][10] = 66, - [0][0][1][0][RTW89_ETSI][10] = 60, - [0][0][1][0][RTW89_MKK][10] = 78, -@@ -29298,6 +29580,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][10] = 60, - [0][0][1][0][RTW89_CN][10] = 58, - [0][0][1][0][RTW89_UK][10] = 60, -+ [0][0][1][0][RTW89_MEXICO][10] = 66, -+ [0][0][1][0][RTW89_UKRAINE][10] = 60, -+ [0][0][1][0][RTW89_CHILE][10] = 66, -+ [0][0][1][0][RTW89_QATAR][10] = 60, - [0][0][1][0][RTW89_FCC][11] = 62, - [0][0][1][0][RTW89_ETSI][11] = 60, - [0][0][1][0][RTW89_MKK][11] = 78, -@@ -29306,6 +29592,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][11] = 60, - [0][0][1][0][RTW89_CN][11] = 58, - [0][0][1][0][RTW89_UK][11] = 60, -+ [0][0][1][0][RTW89_MEXICO][11] = 62, -+ [0][0][1][0][RTW89_UKRAINE][11] = 60, -+ [0][0][1][0][RTW89_CHILE][11] = 62, -+ [0][0][1][0][RTW89_QATAR][11] = 60, - [0][0][1][0][RTW89_FCC][12] = 60, - [0][0][1][0][RTW89_ETSI][12] = 60, - [0][0][1][0][RTW89_MKK][12] = 78, -@@ -29314,6 +29604,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][12] = 60, - [0][0][1][0][RTW89_CN][12] = 58, - [0][0][1][0][RTW89_UK][12] = 60, -+ [0][0][1][0][RTW89_MEXICO][12] = 60, -+ [0][0][1][0][RTW89_UKRAINE][12] = 60, -+ [0][0][1][0][RTW89_CHILE][12] = 60, -+ [0][0][1][0][RTW89_QATAR][12] = 60, - [0][0][1][0][RTW89_FCC][13] = 127, - [0][0][1][0][RTW89_ETSI][13] = 127, - [0][0][1][0][RTW89_MKK][13] = 127, -@@ -29322,6 +29616,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][1][0][RTW89_ACMA][13] = 127, - [0][0][1][0][RTW89_CN][13] = 127, - [0][0][1][0][RTW89_UK][13] = 127, -+ [0][0][1][0][RTW89_MEXICO][13] = 127, -+ [0][0][1][0][RTW89_UKRAINE][13] = 127, -+ [0][0][1][0][RTW89_CHILE][13] = 127, -+ [0][0][1][0][RTW89_QATAR][13] = 127, - [0][1][1][0][RTW89_FCC][0] = 66, - [0][1][1][0][RTW89_ETSI][0] = 48, - [0][1][1][0][RTW89_MKK][0] = 66, -@@ -29330,6 +29628,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][0] = 48, - [0][1][1][0][RTW89_CN][0] = 46, - [0][1][1][0][RTW89_UK][0] = 48, -+ [0][1][1][0][RTW89_MEXICO][0] = 66, -+ [0][1][1][0][RTW89_UKRAINE][0] = 48, -+ [0][1][1][0][RTW89_CHILE][0] = 66, -+ [0][1][1][0][RTW89_QATAR][0] = 48, - [0][1][1][0][RTW89_FCC][1] = 68, - [0][1][1][0][RTW89_ETSI][1] = 48, - [0][1][1][0][RTW89_MKK][1] = 66, -@@ -29338,6 +29640,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][1] = 48, - [0][1][1][0][RTW89_CN][1] = 46, - [0][1][1][0][RTW89_UK][1] = 48, -+ [0][1][1][0][RTW89_MEXICO][1] = 68, -+ [0][1][1][0][RTW89_UKRAINE][1] = 48, -+ [0][1][1][0][RTW89_CHILE][1] = 68, -+ [0][1][1][0][RTW89_QATAR][1] = 48, - [0][1][1][0][RTW89_FCC][2] = 72, - [0][1][1][0][RTW89_ETSI][2] = 48, - [0][1][1][0][RTW89_MKK][2] = 66, -@@ -29346,6 +29652,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][2] = 48, - [0][1][1][0][RTW89_CN][2] = 46, - [0][1][1][0][RTW89_UK][2] = 48, -+ [0][1][1][0][RTW89_MEXICO][2] = 72, -+ [0][1][1][0][RTW89_UKRAINE][2] = 48, -+ [0][1][1][0][RTW89_CHILE][2] = 54, -+ [0][1][1][0][RTW89_QATAR][2] = 48, - [0][1][1][0][RTW89_FCC][3] = 76, - [0][1][1][0][RTW89_ETSI][3] = 48, - [0][1][1][0][RTW89_MKK][3] = 66, -@@ -29354,6 +29664,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][3] = 48, - [0][1][1][0][RTW89_CN][3] = 46, - [0][1][1][0][RTW89_UK][3] = 48, -+ [0][1][1][0][RTW89_MEXICO][3] = 76, -+ [0][1][1][0][RTW89_UKRAINE][3] = 48, -+ [0][1][1][0][RTW89_CHILE][3] = 54, -+ [0][1][1][0][RTW89_QATAR][3] = 48, - [0][1][1][0][RTW89_FCC][4] = 80, - [0][1][1][0][RTW89_ETSI][4] = 48, - [0][1][1][0][RTW89_MKK][4] = 66, -@@ -29362,6 +29676,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][4] = 48, - [0][1][1][0][RTW89_CN][4] = 46, - [0][1][1][0][RTW89_UK][4] = 48, -+ [0][1][1][0][RTW89_MEXICO][4] = 80, -+ [0][1][1][0][RTW89_UKRAINE][4] = 48, -+ [0][1][1][0][RTW89_CHILE][4] = 54, -+ [0][1][1][0][RTW89_QATAR][4] = 48, - [0][1][1][0][RTW89_FCC][5] = 80, - [0][1][1][0][RTW89_ETSI][5] = 48, - [0][1][1][0][RTW89_MKK][5] = 66, -@@ -29370,6 +29688,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][5] = 48, - [0][1][1][0][RTW89_CN][5] = 46, - [0][1][1][0][RTW89_UK][5] = 48, -+ [0][1][1][0][RTW89_MEXICO][5] = 80, -+ [0][1][1][0][RTW89_UKRAINE][5] = 48, -+ [0][1][1][0][RTW89_CHILE][5] = 80, -+ [0][1][1][0][RTW89_QATAR][5] = 48, - [0][1][1][0][RTW89_FCC][6] = 80, - [0][1][1][0][RTW89_ETSI][6] = 48, - [0][1][1][0][RTW89_MKK][6] = 66, -@@ -29378,6 +29700,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][6] = 48, - [0][1][1][0][RTW89_CN][6] = 46, - [0][1][1][0][RTW89_UK][6] = 48, -+ [0][1][1][0][RTW89_MEXICO][6] = 80, -+ [0][1][1][0][RTW89_UKRAINE][6] = 48, -+ [0][1][1][0][RTW89_CHILE][6] = 56, -+ [0][1][1][0][RTW89_QATAR][6] = 48, - [0][1][1][0][RTW89_FCC][7] = 78, - [0][1][1][0][RTW89_ETSI][7] = 48, - [0][1][1][0][RTW89_MKK][7] = 66, -@@ -29386,6 +29712,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][7] = 48, - [0][1][1][0][RTW89_CN][7] = 46, - [0][1][1][0][RTW89_UK][7] = 48, -+ [0][1][1][0][RTW89_MEXICO][7] = 78, -+ [0][1][1][0][RTW89_UKRAINE][7] = 48, -+ [0][1][1][0][RTW89_CHILE][7] = 56, -+ [0][1][1][0][RTW89_QATAR][7] = 48, - [0][1][1][0][RTW89_FCC][8] = 74, - [0][1][1][0][RTW89_ETSI][8] = 48, - [0][1][1][0][RTW89_MKK][8] = 66, -@@ -29394,6 +29724,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][8] = 48, - [0][1][1][0][RTW89_CN][8] = 46, - [0][1][1][0][RTW89_UK][8] = 48, -+ [0][1][1][0][RTW89_MEXICO][8] = 74, -+ [0][1][1][0][RTW89_UKRAINE][8] = 48, -+ [0][1][1][0][RTW89_CHILE][8] = 56, -+ [0][1][1][0][RTW89_QATAR][8] = 48, - [0][1][1][0][RTW89_FCC][9] = 70, - [0][1][1][0][RTW89_ETSI][9] = 48, - [0][1][1][0][RTW89_MKK][9] = 66, -@@ -29402,6 +29736,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][9] = 48, - [0][1][1][0][RTW89_CN][9] = 46, - [0][1][1][0][RTW89_UK][9] = 48, -+ [0][1][1][0][RTW89_MEXICO][9] = 70, -+ [0][1][1][0][RTW89_UKRAINE][9] = 48, -+ [0][1][1][0][RTW89_CHILE][9] = 70, -+ [0][1][1][0][RTW89_QATAR][9] = 48, - [0][1][1][0][RTW89_FCC][10] = 62, - [0][1][1][0][RTW89_ETSI][10] = 48, - [0][1][1][0][RTW89_MKK][10] = 66, -@@ -29410,6 +29748,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][10] = 48, - [0][1][1][0][RTW89_CN][10] = 46, - [0][1][1][0][RTW89_UK][10] = 48, -+ [0][1][1][0][RTW89_MEXICO][10] = 62, -+ [0][1][1][0][RTW89_UKRAINE][10] = 48, -+ [0][1][1][0][RTW89_CHILE][10] = 62, -+ [0][1][1][0][RTW89_QATAR][10] = 48, - [0][1][1][0][RTW89_FCC][11] = 60, - [0][1][1][0][RTW89_ETSI][11] = 48, - [0][1][1][0][RTW89_MKK][11] = 66, -@@ -29418,6 +29760,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][11] = 48, - [0][1][1][0][RTW89_CN][11] = 46, - [0][1][1][0][RTW89_UK][11] = 48, -+ [0][1][1][0][RTW89_MEXICO][11] = 60, -+ [0][1][1][0][RTW89_UKRAINE][11] = 48, -+ [0][1][1][0][RTW89_CHILE][11] = 60, -+ [0][1][1][0][RTW89_QATAR][11] = 48, - [0][1][1][0][RTW89_FCC][12] = 36, - [0][1][1][0][RTW89_ETSI][12] = 48, - [0][1][1][0][RTW89_MKK][12] = 66, -@@ -29426,6 +29772,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][12] = 48, - [0][1][1][0][RTW89_CN][12] = 46, - [0][1][1][0][RTW89_UK][12] = 48, -+ [0][1][1][0][RTW89_MEXICO][12] = 36, -+ [0][1][1][0][RTW89_UKRAINE][12] = 48, -+ [0][1][1][0][RTW89_CHILE][12] = 36, -+ [0][1][1][0][RTW89_QATAR][12] = 48, - [0][1][1][0][RTW89_FCC][13] = 127, - [0][1][1][0][RTW89_ETSI][13] = 127, - [0][1][1][0][RTW89_MKK][13] = 127, -@@ -29434,6 +29784,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][1][0][RTW89_ACMA][13] = 127, - [0][1][1][0][RTW89_CN][13] = 127, - [0][1][1][0][RTW89_UK][13] = 127, -+ [0][1][1][0][RTW89_MEXICO][13] = 127, -+ [0][1][1][0][RTW89_UKRAINE][13] = 127, -+ [0][1][1][0][RTW89_CHILE][13] = 127, -+ [0][1][1][0][RTW89_QATAR][13] = 127, - [0][0][2][0][RTW89_FCC][0] = 66, - [0][0][2][0][RTW89_ETSI][0] = 60, - [0][0][2][0][RTW89_MKK][0] = 78, -@@ -29442,6 +29796,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][0] = 60, - [0][0][2][0][RTW89_CN][0] = 58, - [0][0][2][0][RTW89_UK][0] = 60, -+ [0][0][2][0][RTW89_MEXICO][0] = 66, -+ [0][0][2][0][RTW89_UKRAINE][0] = 60, -+ [0][0][2][0][RTW89_CHILE][0] = 66, -+ [0][0][2][0][RTW89_QATAR][0] = 60, - [0][0][2][0][RTW89_FCC][1] = 70, - [0][0][2][0][RTW89_ETSI][1] = 60, - [0][0][2][0][RTW89_MKK][1] = 78, -@@ -29450,6 +29808,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][1] = 60, - [0][0][2][0][RTW89_CN][1] = 58, - [0][0][2][0][RTW89_UK][1] = 60, -+ [0][0][2][0][RTW89_MEXICO][1] = 70, -+ [0][0][2][0][RTW89_UKRAINE][1] = 60, -+ [0][0][2][0][RTW89_CHILE][1] = 70, -+ [0][0][2][0][RTW89_QATAR][1] = 60, - [0][0][2][0][RTW89_FCC][2] = 74, - [0][0][2][0][RTW89_ETSI][2] = 60, - [0][0][2][0][RTW89_MKK][2] = 78, -@@ -29458,6 +29820,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][2] = 60, - [0][0][2][0][RTW89_CN][2] = 58, - [0][0][2][0][RTW89_UK][2] = 60, -+ [0][0][2][0][RTW89_MEXICO][2] = 74, -+ [0][0][2][0][RTW89_UKRAINE][2] = 60, -+ [0][0][2][0][RTW89_CHILE][2] = 64, -+ [0][0][2][0][RTW89_QATAR][2] = 60, - [0][0][2][0][RTW89_FCC][3] = 78, - [0][0][2][0][RTW89_ETSI][3] = 60, - [0][0][2][0][RTW89_MKK][3] = 78, -@@ -29466,6 +29832,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][3] = 60, - [0][0][2][0][RTW89_CN][3] = 58, - [0][0][2][0][RTW89_UK][3] = 60, -+ [0][0][2][0][RTW89_MEXICO][3] = 78, -+ [0][0][2][0][RTW89_UKRAINE][3] = 60, -+ [0][0][2][0][RTW89_CHILE][3] = 64, -+ [0][0][2][0][RTW89_QATAR][3] = 60, - [0][0][2][0][RTW89_FCC][4] = 80, - [0][0][2][0][RTW89_ETSI][4] = 60, - [0][0][2][0][RTW89_MKK][4] = 78, -@@ -29474,6 +29844,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][4] = 60, - [0][0][2][0][RTW89_CN][4] = 58, - [0][0][2][0][RTW89_UK][4] = 60, -+ [0][0][2][0][RTW89_MEXICO][4] = 80, -+ [0][0][2][0][RTW89_UKRAINE][4] = 60, -+ [0][0][2][0][RTW89_CHILE][4] = 64, -+ [0][0][2][0][RTW89_QATAR][4] = 60, - [0][0][2][0][RTW89_FCC][5] = 80, - [0][0][2][0][RTW89_ETSI][5] = 60, - [0][0][2][0][RTW89_MKK][5] = 78, -@@ -29482,6 +29856,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][5] = 60, - [0][0][2][0][RTW89_CN][5] = 58, - [0][0][2][0][RTW89_UK][5] = 60, -+ [0][0][2][0][RTW89_MEXICO][5] = 80, -+ [0][0][2][0][RTW89_UKRAINE][5] = 60, -+ [0][0][2][0][RTW89_CHILE][5] = 80, -+ [0][0][2][0][RTW89_QATAR][5] = 60, - [0][0][2][0][RTW89_FCC][6] = 80, - [0][0][2][0][RTW89_ETSI][6] = 60, - [0][0][2][0][RTW89_MKK][6] = 78, -@@ -29490,6 +29868,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][6] = 60, - [0][0][2][0][RTW89_CN][6] = 58, - [0][0][2][0][RTW89_UK][6] = 60, -+ [0][0][2][0][RTW89_MEXICO][6] = 80, -+ [0][0][2][0][RTW89_UKRAINE][6] = 60, -+ [0][0][2][0][RTW89_CHILE][6] = 68, -+ [0][0][2][0][RTW89_QATAR][6] = 60, - [0][0][2][0][RTW89_FCC][7] = 80, - [0][0][2][0][RTW89_ETSI][7] = 60, - [0][0][2][0][RTW89_MKK][7] = 78, -@@ -29498,6 +29880,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][7] = 60, - [0][0][2][0][RTW89_CN][7] = 58, - [0][0][2][0][RTW89_UK][7] = 60, -+ [0][0][2][0][RTW89_MEXICO][7] = 80, -+ [0][0][2][0][RTW89_UKRAINE][7] = 60, -+ [0][0][2][0][RTW89_CHILE][7] = 68, -+ [0][0][2][0][RTW89_QATAR][7] = 60, - [0][0][2][0][RTW89_FCC][8] = 78, - [0][0][2][0][RTW89_ETSI][8] = 60, - [0][0][2][0][RTW89_MKK][8] = 78, -@@ -29506,6 +29892,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][8] = 60, - [0][0][2][0][RTW89_CN][8] = 58, - [0][0][2][0][RTW89_UK][8] = 60, -+ [0][0][2][0][RTW89_MEXICO][8] = 78, -+ [0][0][2][0][RTW89_UKRAINE][8] = 60, -+ [0][0][2][0][RTW89_CHILE][8] = 68, -+ [0][0][2][0][RTW89_QATAR][8] = 60, - [0][0][2][0][RTW89_FCC][9] = 74, - [0][0][2][0][RTW89_ETSI][9] = 60, - [0][0][2][0][RTW89_MKK][9] = 78, -@@ -29514,6 +29904,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][9] = 60, - [0][0][2][0][RTW89_CN][9] = 58, - [0][0][2][0][RTW89_UK][9] = 60, -+ [0][0][2][0][RTW89_MEXICO][9] = 74, -+ [0][0][2][0][RTW89_UKRAINE][9] = 60, -+ [0][0][2][0][RTW89_CHILE][9] = 74, -+ [0][0][2][0][RTW89_QATAR][9] = 60, - [0][0][2][0][RTW89_FCC][10] = 62, - [0][0][2][0][RTW89_ETSI][10] = 60, - [0][0][2][0][RTW89_MKK][10] = 78, -@@ -29522,6 +29916,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][10] = 60, - [0][0][2][0][RTW89_CN][10] = 58, - [0][0][2][0][RTW89_UK][10] = 60, -+ [0][0][2][0][RTW89_MEXICO][10] = 62, -+ [0][0][2][0][RTW89_UKRAINE][10] = 60, -+ [0][0][2][0][RTW89_CHILE][10] = 62, -+ [0][0][2][0][RTW89_QATAR][10] = 60, - [0][0][2][0][RTW89_FCC][11] = 60, - [0][0][2][0][RTW89_ETSI][11] = 60, - [0][0][2][0][RTW89_MKK][11] = 78, -@@ -29530,6 +29928,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][11] = 60, - [0][0][2][0][RTW89_CN][11] = 58, - [0][0][2][0][RTW89_UK][11] = 60, -+ [0][0][2][0][RTW89_MEXICO][11] = 60, -+ [0][0][2][0][RTW89_UKRAINE][11] = 60, -+ [0][0][2][0][RTW89_CHILE][11] = 60, -+ [0][0][2][0][RTW89_QATAR][11] = 60, - [0][0][2][0][RTW89_FCC][12] = 38, - [0][0][2][0][RTW89_ETSI][12] = 60, - [0][0][2][0][RTW89_MKK][12] = 78, -@@ -29538,6 +29940,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][12] = 60, - [0][0][2][0][RTW89_CN][12] = 58, - [0][0][2][0][RTW89_UK][12] = 60, -+ [0][0][2][0][RTW89_MEXICO][12] = 38, -+ [0][0][2][0][RTW89_UKRAINE][12] = 60, -+ [0][0][2][0][RTW89_CHILE][12] = 38, -+ [0][0][2][0][RTW89_QATAR][12] = 60, - [0][0][2][0][RTW89_FCC][13] = 127, - [0][0][2][0][RTW89_ETSI][13] = 127, - [0][0][2][0][RTW89_MKK][13] = 127, -@@ -29546,6 +29952,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][0][2][0][RTW89_ACMA][13] = 127, - [0][0][2][0][RTW89_CN][13] = 127, - [0][0][2][0][RTW89_UK][13] = 127, -+ [0][0][2][0][RTW89_MEXICO][13] = 127, -+ [0][0][2][0][RTW89_UKRAINE][13] = 127, -+ [0][0][2][0][RTW89_CHILE][13] = 127, -+ [0][0][2][0][RTW89_QATAR][13] = 127, - [0][1][2][0][RTW89_FCC][0] = 64, - [0][1][2][0][RTW89_ETSI][0] = 48, - [0][1][2][0][RTW89_MKK][0] = 68, -@@ -29554,6 +29964,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][0] = 48, - [0][1][2][0][RTW89_CN][0] = 46, - [0][1][2][0][RTW89_UK][0] = 48, -+ [0][1][2][0][RTW89_MEXICO][0] = 64, -+ [0][1][2][0][RTW89_UKRAINE][0] = 48, -+ [0][1][2][0][RTW89_CHILE][0] = 64, -+ [0][1][2][0][RTW89_QATAR][0] = 48, - [0][1][2][0][RTW89_FCC][1] = 70, - [0][1][2][0][RTW89_ETSI][1] = 48, - [0][1][2][0][RTW89_MKK][1] = 68, -@@ -29562,6 +29976,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][1] = 48, - [0][1][2][0][RTW89_CN][1] = 46, - [0][1][2][0][RTW89_UK][1] = 48, -+ [0][1][2][0][RTW89_MEXICO][1] = 70, -+ [0][1][2][0][RTW89_UKRAINE][1] = 48, -+ [0][1][2][0][RTW89_CHILE][1] = 70, -+ [0][1][2][0][RTW89_QATAR][1] = 48, - [0][1][2][0][RTW89_FCC][2] = 74, - [0][1][2][0][RTW89_ETSI][2] = 48, - [0][1][2][0][RTW89_MKK][2] = 68, -@@ -29570,6 +29988,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][2] = 48, - [0][1][2][0][RTW89_CN][2] = 46, - [0][1][2][0][RTW89_UK][2] = 48, -+ [0][1][2][0][RTW89_MEXICO][2] = 74, -+ [0][1][2][0][RTW89_UKRAINE][2] = 48, -+ [0][1][2][0][RTW89_CHILE][2] = 56, -+ [0][1][2][0][RTW89_QATAR][2] = 48, - [0][1][2][0][RTW89_FCC][3] = 78, - [0][1][2][0][RTW89_ETSI][3] = 48, - [0][1][2][0][RTW89_MKK][3] = 68, -@@ -29578,6 +30000,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][3] = 48, - [0][1][2][0][RTW89_CN][3] = 46, - [0][1][2][0][RTW89_UK][3] = 48, -+ [0][1][2][0][RTW89_MEXICO][3] = 78, -+ [0][1][2][0][RTW89_UKRAINE][3] = 48, -+ [0][1][2][0][RTW89_CHILE][3] = 56, -+ [0][1][2][0][RTW89_QATAR][3] = 48, - [0][1][2][0][RTW89_FCC][4] = 80, - [0][1][2][0][RTW89_ETSI][4] = 48, - [0][1][2][0][RTW89_MKK][4] = 68, -@@ -29586,6 +30012,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][4] = 48, - [0][1][2][0][RTW89_CN][4] = 46, - [0][1][2][0][RTW89_UK][4] = 48, -+ [0][1][2][0][RTW89_MEXICO][4] = 80, -+ [0][1][2][0][RTW89_UKRAINE][4] = 48, -+ [0][1][2][0][RTW89_CHILE][4] = 56, -+ [0][1][2][0][RTW89_QATAR][4] = 48, - [0][1][2][0][RTW89_FCC][5] = 80, - [0][1][2][0][RTW89_ETSI][5] = 48, - [0][1][2][0][RTW89_MKK][5] = 68, -@@ -29594,6 +30024,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][5] = 48, - [0][1][2][0][RTW89_CN][5] = 46, - [0][1][2][0][RTW89_UK][5] = 48, -+ [0][1][2][0][RTW89_MEXICO][5] = 80, -+ [0][1][2][0][RTW89_UKRAINE][5] = 48, -+ [0][1][2][0][RTW89_CHILE][5] = 78, -+ [0][1][2][0][RTW89_QATAR][5] = 48, - [0][1][2][0][RTW89_FCC][6] = 80, - [0][1][2][0][RTW89_ETSI][6] = 48, - [0][1][2][0][RTW89_MKK][6] = 68, -@@ -29602,6 +30036,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][6] = 48, - [0][1][2][0][RTW89_CN][6] = 46, - [0][1][2][0][RTW89_UK][6] = 48, -+ [0][1][2][0][RTW89_MEXICO][6] = 80, -+ [0][1][2][0][RTW89_UKRAINE][6] = 48, -+ [0][1][2][0][RTW89_CHILE][6] = 54, -+ [0][1][2][0][RTW89_QATAR][6] = 48, - [0][1][2][0][RTW89_FCC][7] = 74, - [0][1][2][0][RTW89_ETSI][7] = 48, - [0][1][2][0][RTW89_MKK][7] = 68, -@@ -29610,6 +30048,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][7] = 48, - [0][1][2][0][RTW89_CN][7] = 46, - [0][1][2][0][RTW89_UK][7] = 48, -+ [0][1][2][0][RTW89_MEXICO][7] = 74, -+ [0][1][2][0][RTW89_UKRAINE][7] = 48, -+ [0][1][2][0][RTW89_CHILE][7] = 54, -+ [0][1][2][0][RTW89_QATAR][7] = 48, - [0][1][2][0][RTW89_FCC][8] = 70, - [0][1][2][0][RTW89_ETSI][8] = 48, - [0][1][2][0][RTW89_MKK][8] = 68, -@@ -29618,6 +30060,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][8] = 48, - [0][1][2][0][RTW89_CN][8] = 46, - [0][1][2][0][RTW89_UK][8] = 48, -+ [0][1][2][0][RTW89_MEXICO][8] = 70, -+ [0][1][2][0][RTW89_UKRAINE][8] = 48, -+ [0][1][2][0][RTW89_CHILE][8] = 54, -+ [0][1][2][0][RTW89_QATAR][8] = 48, - [0][1][2][0][RTW89_FCC][9] = 66, - [0][1][2][0][RTW89_ETSI][9] = 48, - [0][1][2][0][RTW89_MKK][9] = 68, -@@ -29626,6 +30072,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][9] = 48, - [0][1][2][0][RTW89_CN][9] = 46, - [0][1][2][0][RTW89_UK][9] = 48, -+ [0][1][2][0][RTW89_MEXICO][9] = 66, -+ [0][1][2][0][RTW89_UKRAINE][9] = 48, -+ [0][1][2][0][RTW89_CHILE][9] = 66, -+ [0][1][2][0][RTW89_QATAR][9] = 48, - [0][1][2][0][RTW89_FCC][10] = 58, - [0][1][2][0][RTW89_ETSI][10] = 48, - [0][1][2][0][RTW89_MKK][10] = 68, -@@ -29634,6 +30084,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][10] = 48, - [0][1][2][0][RTW89_CN][10] = 46, - [0][1][2][0][RTW89_UK][10] = 48, -+ [0][1][2][0][RTW89_MEXICO][10] = 58, -+ [0][1][2][0][RTW89_UKRAINE][10] = 48, -+ [0][1][2][0][RTW89_CHILE][10] = 58, -+ [0][1][2][0][RTW89_QATAR][10] = 48, - [0][1][2][0][RTW89_FCC][11] = 58, - [0][1][2][0][RTW89_ETSI][11] = 48, - [0][1][2][0][RTW89_MKK][11] = 68, -@@ -29642,6 +30096,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][11] = 48, - [0][1][2][0][RTW89_CN][11] = 46, - [0][1][2][0][RTW89_UK][11] = 48, -+ [0][1][2][0][RTW89_MEXICO][11] = 58, -+ [0][1][2][0][RTW89_UKRAINE][11] = 48, -+ [0][1][2][0][RTW89_CHILE][11] = 58, -+ [0][1][2][0][RTW89_QATAR][11] = 48, - [0][1][2][0][RTW89_FCC][12] = 16, - [0][1][2][0][RTW89_ETSI][12] = 48, - [0][1][2][0][RTW89_MKK][12] = 68, -@@ -29650,6 +30108,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][12] = 48, - [0][1][2][0][RTW89_CN][12] = 46, - [0][1][2][0][RTW89_UK][12] = 48, -+ [0][1][2][0][RTW89_MEXICO][12] = 16, -+ [0][1][2][0][RTW89_UKRAINE][12] = 48, -+ [0][1][2][0][RTW89_CHILE][12] = 16, -+ [0][1][2][0][RTW89_QATAR][12] = 48, - [0][1][2][0][RTW89_FCC][13] = 127, - [0][1][2][0][RTW89_ETSI][13] = 127, - [0][1][2][0][RTW89_MKK][13] = 127, -@@ -29658,6 +30120,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][0][RTW89_ACMA][13] = 127, - [0][1][2][0][RTW89_CN][13] = 127, - [0][1][2][0][RTW89_UK][13] = 127, -+ [0][1][2][0][RTW89_MEXICO][13] = 127, -+ [0][1][2][0][RTW89_UKRAINE][13] = 127, -+ [0][1][2][0][RTW89_CHILE][13] = 127, -+ [0][1][2][0][RTW89_QATAR][13] = 127, - [0][1][2][1][RTW89_FCC][0] = 64, - [0][1][2][1][RTW89_ETSI][0] = 36, - [0][1][2][1][RTW89_MKK][0] = 68, -@@ -29666,6 +30132,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][0] = 36, - [0][1][2][1][RTW89_CN][0] = 36, - [0][1][2][1][RTW89_UK][0] = 36, -+ [0][1][2][1][RTW89_MEXICO][0] = 64, -+ [0][1][2][1][RTW89_UKRAINE][0] = 36, -+ [0][1][2][1][RTW89_CHILE][0] = 64, -+ [0][1][2][1][RTW89_QATAR][0] = 36, - [0][1][2][1][RTW89_FCC][1] = 70, - [0][1][2][1][RTW89_ETSI][1] = 36, - [0][1][2][1][RTW89_MKK][1] = 68, -@@ -29674,6 +30144,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][1] = 36, - [0][1][2][1][RTW89_CN][1] = 34, - [0][1][2][1][RTW89_UK][1] = 36, -+ [0][1][2][1][RTW89_MEXICO][1] = 70, -+ [0][1][2][1][RTW89_UKRAINE][1] = 36, -+ [0][1][2][1][RTW89_CHILE][1] = 70, -+ [0][1][2][1][RTW89_QATAR][1] = 36, - [0][1][2][1][RTW89_FCC][2] = 74, - [0][1][2][1][RTW89_ETSI][2] = 36, - [0][1][2][1][RTW89_MKK][2] = 68, -@@ -29682,6 +30156,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][2] = 36, - [0][1][2][1][RTW89_CN][2] = 34, - [0][1][2][1][RTW89_UK][2] = 36, -+ [0][1][2][1][RTW89_MEXICO][2] = 74, -+ [0][1][2][1][RTW89_UKRAINE][2] = 36, -+ [0][1][2][1][RTW89_CHILE][2] = 44, -+ [0][1][2][1][RTW89_QATAR][2] = 36, - [0][1][2][1][RTW89_FCC][3] = 78, - [0][1][2][1][RTW89_ETSI][3] = 36, - [0][1][2][1][RTW89_MKK][3] = 68, -@@ -29690,6 +30168,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][3] = 36, - [0][1][2][1][RTW89_CN][3] = 34, - [0][1][2][1][RTW89_UK][3] = 36, -+ [0][1][2][1][RTW89_MEXICO][3] = 78, -+ [0][1][2][1][RTW89_UKRAINE][3] = 36, -+ [0][1][2][1][RTW89_CHILE][3] = 44, -+ [0][1][2][1][RTW89_QATAR][3] = 36, - [0][1][2][1][RTW89_FCC][4] = 80, - [0][1][2][1][RTW89_ETSI][4] = 36, - [0][1][2][1][RTW89_MKK][4] = 68, -@@ -29698,6 +30180,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][4] = 36, - [0][1][2][1][RTW89_CN][4] = 34, - [0][1][2][1][RTW89_UK][4] = 36, -+ [0][1][2][1][RTW89_MEXICO][4] = 80, -+ [0][1][2][1][RTW89_UKRAINE][4] = 36, -+ [0][1][2][1][RTW89_CHILE][4] = 44, -+ [0][1][2][1][RTW89_QATAR][4] = 36, - [0][1][2][1][RTW89_FCC][5] = 80, - [0][1][2][1][RTW89_ETSI][5] = 36, - [0][1][2][1][RTW89_MKK][5] = 68, -@@ -29706,6 +30192,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][5] = 36, - [0][1][2][1][RTW89_CN][5] = 34, - [0][1][2][1][RTW89_UK][5] = 36, -+ [0][1][2][1][RTW89_MEXICO][5] = 80, -+ [0][1][2][1][RTW89_UKRAINE][5] = 36, -+ [0][1][2][1][RTW89_CHILE][5] = 74, -+ [0][1][2][1][RTW89_QATAR][5] = 36, - [0][1][2][1][RTW89_FCC][6] = 80, - [0][1][2][1][RTW89_ETSI][6] = 36, - [0][1][2][1][RTW89_MKK][6] = 68, -@@ -29714,6 +30204,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][6] = 36, - [0][1][2][1][RTW89_CN][6] = 34, - [0][1][2][1][RTW89_UK][6] = 36, -+ [0][1][2][1][RTW89_MEXICO][6] = 80, -+ [0][1][2][1][RTW89_UKRAINE][6] = 36, -+ [0][1][2][1][RTW89_CHILE][6] = 42, -+ [0][1][2][1][RTW89_QATAR][6] = 36, - [0][1][2][1][RTW89_FCC][7] = 74, - [0][1][2][1][RTW89_ETSI][7] = 36, - [0][1][2][1][RTW89_MKK][7] = 68, -@@ -29722,6 +30216,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][7] = 36, - [0][1][2][1][RTW89_CN][7] = 34, - [0][1][2][1][RTW89_UK][7] = 36, -+ [0][1][2][1][RTW89_MEXICO][7] = 74, -+ [0][1][2][1][RTW89_UKRAINE][7] = 36, -+ [0][1][2][1][RTW89_CHILE][7] = 42, -+ [0][1][2][1][RTW89_QATAR][7] = 36, - [0][1][2][1][RTW89_FCC][8] = 70, - [0][1][2][1][RTW89_ETSI][8] = 36, - [0][1][2][1][RTW89_MKK][8] = 68, -@@ -29730,6 +30228,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][8] = 36, - [0][1][2][1][RTW89_CN][8] = 34, - [0][1][2][1][RTW89_UK][8] = 36, -+ [0][1][2][1][RTW89_MEXICO][8] = 70, -+ [0][1][2][1][RTW89_UKRAINE][8] = 36, -+ [0][1][2][1][RTW89_CHILE][8] = 42, -+ [0][1][2][1][RTW89_QATAR][8] = 36, - [0][1][2][1][RTW89_FCC][9] = 66, - [0][1][2][1][RTW89_ETSI][9] = 36, - [0][1][2][1][RTW89_MKK][9] = 68, -@@ -29738,6 +30240,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][9] = 36, - [0][1][2][1][RTW89_CN][9] = 34, - [0][1][2][1][RTW89_UK][9] = 36, -+ [0][1][2][1][RTW89_MEXICO][9] = 66, -+ [0][1][2][1][RTW89_UKRAINE][9] = 36, -+ [0][1][2][1][RTW89_CHILE][9] = 66, -+ [0][1][2][1][RTW89_QATAR][9] = 36, - [0][1][2][1][RTW89_FCC][10] = 58, - [0][1][2][1][RTW89_ETSI][10] = 36, - [0][1][2][1][RTW89_MKK][10] = 68, -@@ -29746,6 +30252,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][10] = 36, - [0][1][2][1][RTW89_CN][10] = 34, - [0][1][2][1][RTW89_UK][10] = 36, -+ [0][1][2][1][RTW89_MEXICO][10] = 58, -+ [0][1][2][1][RTW89_UKRAINE][10] = 36, -+ [0][1][2][1][RTW89_CHILE][10] = 58, -+ [0][1][2][1][RTW89_QATAR][10] = 36, - [0][1][2][1][RTW89_FCC][11] = 58, - [0][1][2][1][RTW89_ETSI][11] = 36, - [0][1][2][1][RTW89_MKK][11] = 68, -@@ -29754,6 +30264,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][11] = 36, - [0][1][2][1][RTW89_CN][11] = 34, - [0][1][2][1][RTW89_UK][11] = 36, -+ [0][1][2][1][RTW89_MEXICO][11] = 58, -+ [0][1][2][1][RTW89_UKRAINE][11] = 36, -+ [0][1][2][1][RTW89_CHILE][11] = 58, -+ [0][1][2][1][RTW89_QATAR][11] = 36, - [0][1][2][1][RTW89_FCC][12] = 16, - [0][1][2][1][RTW89_ETSI][12] = 36, - [0][1][2][1][RTW89_MKK][12] = 68, -@@ -29762,6 +30276,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][12] = 36, - [0][1][2][1][RTW89_CN][12] = 34, - [0][1][2][1][RTW89_UK][12] = 36, -+ [0][1][2][1][RTW89_MEXICO][12] = 16, -+ [0][1][2][1][RTW89_UKRAINE][12] = 36, -+ [0][1][2][1][RTW89_CHILE][12] = 16, -+ [0][1][2][1][RTW89_QATAR][12] = 36, - [0][1][2][1][RTW89_FCC][13] = 127, - [0][1][2][1][RTW89_ETSI][13] = 127, - [0][1][2][1][RTW89_MKK][13] = 127, -@@ -29770,6 +30288,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [0][1][2][1][RTW89_ACMA][13] = 127, - [0][1][2][1][RTW89_CN][13] = 127, - [0][1][2][1][RTW89_UK][13] = 127, -+ [0][1][2][1][RTW89_MEXICO][13] = 127, -+ [0][1][2][1][RTW89_UKRAINE][13] = 127, -+ [0][1][2][1][RTW89_CHILE][13] = 127, -+ [0][1][2][1][RTW89_QATAR][13] = 127, - [1][0][2][0][RTW89_FCC][0] = 127, - [1][0][2][0][RTW89_ETSI][0] = 127, - [1][0][2][0][RTW89_MKK][0] = 127, -@@ -29778,6 +30300,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][0] = 127, - [1][0][2][0][RTW89_CN][0] = 127, - [1][0][2][0][RTW89_UK][0] = 127, -+ [1][0][2][0][RTW89_MEXICO][0] = 127, -+ [1][0][2][0][RTW89_UKRAINE][0] = 127, -+ [1][0][2][0][RTW89_CHILE][0] = 127, -+ [1][0][2][0][RTW89_QATAR][0] = 127, - [1][0][2][0][RTW89_FCC][1] = 127, - [1][0][2][0][RTW89_ETSI][1] = 127, - [1][0][2][0][RTW89_MKK][1] = 127, -@@ -29786,6 +30312,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][1] = 127, - [1][0][2][0][RTW89_CN][1] = 127, - [1][0][2][0][RTW89_UK][1] = 127, -+ [1][0][2][0][RTW89_MEXICO][1] = 127, -+ [1][0][2][0][RTW89_UKRAINE][1] = 127, -+ [1][0][2][0][RTW89_CHILE][1] = 127, -+ [1][0][2][0][RTW89_QATAR][1] = 127, - [1][0][2][0][RTW89_FCC][2] = 64, - [1][0][2][0][RTW89_ETSI][2] = 60, - [1][0][2][0][RTW89_MKK][2] = 74, -@@ -29794,6 +30324,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][2] = 60, - [1][0][2][0][RTW89_CN][2] = 58, - [1][0][2][0][RTW89_UK][2] = 60, -+ [1][0][2][0][RTW89_MEXICO][2] = 64, -+ [1][0][2][0][RTW89_UKRAINE][2] = 60, -+ [1][0][2][0][RTW89_CHILE][2] = 64, -+ [1][0][2][0][RTW89_QATAR][2] = 60, - [1][0][2][0][RTW89_FCC][3] = 64, - [1][0][2][0][RTW89_ETSI][3] = 60, - [1][0][2][0][RTW89_MKK][3] = 74, -@@ -29802,6 +30336,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][3] = 60, - [1][0][2][0][RTW89_CN][3] = 58, - [1][0][2][0][RTW89_UK][3] = 60, -+ [1][0][2][0][RTW89_MEXICO][3] = 64, -+ [1][0][2][0][RTW89_UKRAINE][3] = 60, -+ [1][0][2][0][RTW89_CHILE][3] = 64, -+ [1][0][2][0][RTW89_QATAR][3] = 60, - [1][0][2][0][RTW89_FCC][4] = 68, - [1][0][2][0][RTW89_ETSI][4] = 60, - [1][0][2][0][RTW89_MKK][4] = 74, -@@ -29810,6 +30348,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][4] = 60, - [1][0][2][0][RTW89_CN][4] = 58, - [1][0][2][0][RTW89_UK][4] = 60, -+ [1][0][2][0][RTW89_MEXICO][4] = 68, -+ [1][0][2][0][RTW89_UKRAINE][4] = 60, -+ [1][0][2][0][RTW89_CHILE][4] = 68, -+ [1][0][2][0][RTW89_QATAR][4] = 60, - [1][0][2][0][RTW89_FCC][5] = 68, - [1][0][2][0][RTW89_ETSI][5] = 60, - [1][0][2][0][RTW89_MKK][5] = 74, -@@ -29818,6 +30360,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][5] = 60, - [1][0][2][0][RTW89_CN][5] = 58, - [1][0][2][0][RTW89_UK][5] = 60, -+ [1][0][2][0][RTW89_MEXICO][5] = 68, -+ [1][0][2][0][RTW89_UKRAINE][5] = 60, -+ [1][0][2][0][RTW89_CHILE][5] = 68, -+ [1][0][2][0][RTW89_QATAR][5] = 60, - [1][0][2][0][RTW89_FCC][6] = 66, - [1][0][2][0][RTW89_ETSI][6] = 60, - [1][0][2][0][RTW89_MKK][6] = 74, -@@ -29826,6 +30372,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][6] = 60, - [1][0][2][0][RTW89_CN][6] = 58, - [1][0][2][0][RTW89_UK][6] = 60, -+ [1][0][2][0][RTW89_MEXICO][6] = 66, -+ [1][0][2][0][RTW89_UKRAINE][6] = 60, -+ [1][0][2][0][RTW89_CHILE][6] = 66, -+ [1][0][2][0][RTW89_QATAR][6] = 60, - [1][0][2][0][RTW89_FCC][7] = 62, - [1][0][2][0][RTW89_ETSI][7] = 60, - [1][0][2][0][RTW89_MKK][7] = 74, -@@ -29834,6 +30384,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][7] = 60, - [1][0][2][0][RTW89_CN][7] = 58, - [1][0][2][0][RTW89_UK][7] = 60, -+ [1][0][2][0][RTW89_MEXICO][7] = 62, -+ [1][0][2][0][RTW89_UKRAINE][7] = 60, -+ [1][0][2][0][RTW89_CHILE][7] = 62, -+ [1][0][2][0][RTW89_QATAR][7] = 60, - [1][0][2][0][RTW89_FCC][8] = 62, - [1][0][2][0][RTW89_ETSI][8] = 60, - [1][0][2][0][RTW89_MKK][8] = 74, -@@ -29842,6 +30396,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][8] = 60, - [1][0][2][0][RTW89_CN][8] = 58, - [1][0][2][0][RTW89_UK][8] = 60, -+ [1][0][2][0][RTW89_MEXICO][8] = 62, -+ [1][0][2][0][RTW89_UKRAINE][8] = 60, -+ [1][0][2][0][RTW89_CHILE][8] = 62, -+ [1][0][2][0][RTW89_QATAR][8] = 60, - [1][0][2][0][RTW89_FCC][9] = 60, - [1][0][2][0][RTW89_ETSI][9] = 60, - [1][0][2][0][RTW89_MKK][9] = 74, -@@ -29850,6 +30408,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][9] = 60, - [1][0][2][0][RTW89_CN][9] = 58, - [1][0][2][0][RTW89_UK][9] = 60, -+ [1][0][2][0][RTW89_MEXICO][9] = 60, -+ [1][0][2][0][RTW89_UKRAINE][9] = 60, -+ [1][0][2][0][RTW89_CHILE][9] = 60, -+ [1][0][2][0][RTW89_QATAR][9] = 60, - [1][0][2][0][RTW89_FCC][10] = 56, - [1][0][2][0][RTW89_ETSI][10] = 60, - [1][0][2][0][RTW89_MKK][10] = 74, -@@ -29858,6 +30420,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][10] = 60, - [1][0][2][0][RTW89_CN][10] = 58, - [1][0][2][0][RTW89_UK][10] = 60, -+ [1][0][2][0][RTW89_MEXICO][10] = 56, -+ [1][0][2][0][RTW89_UKRAINE][10] = 60, -+ [1][0][2][0][RTW89_CHILE][10] = 56, -+ [1][0][2][0][RTW89_QATAR][10] = 60, - [1][0][2][0][RTW89_FCC][11] = 127, - [1][0][2][0][RTW89_ETSI][11] = 127, - [1][0][2][0][RTW89_MKK][11] = 127, -@@ -29866,6 +30432,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][11] = 127, - [1][0][2][0][RTW89_CN][11] = 127, - [1][0][2][0][RTW89_UK][11] = 127, -+ [1][0][2][0][RTW89_MEXICO][11] = 127, -+ [1][0][2][0][RTW89_UKRAINE][11] = 127, -+ [1][0][2][0][RTW89_CHILE][11] = 127, -+ [1][0][2][0][RTW89_QATAR][11] = 127, - [1][0][2][0][RTW89_FCC][12] = 127, - [1][0][2][0][RTW89_ETSI][12] = 127, - [1][0][2][0][RTW89_MKK][12] = 127, -@@ -29874,6 +30444,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][12] = 127, - [1][0][2][0][RTW89_CN][12] = 127, - [1][0][2][0][RTW89_UK][12] = 127, -+ [1][0][2][0][RTW89_MEXICO][12] = 127, -+ [1][0][2][0][RTW89_UKRAINE][12] = 127, -+ [1][0][2][0][RTW89_CHILE][12] = 127, -+ [1][0][2][0][RTW89_QATAR][12] = 127, - [1][0][2][0][RTW89_FCC][13] = 127, - [1][0][2][0][RTW89_ETSI][13] = 127, - [1][0][2][0][RTW89_MKK][13] = 127, -@@ -29882,6 +30456,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][0][2][0][RTW89_ACMA][13] = 127, - [1][0][2][0][RTW89_CN][13] = 127, - [1][0][2][0][RTW89_UK][13] = 127, -+ [1][0][2][0][RTW89_MEXICO][13] = 127, -+ [1][0][2][0][RTW89_UKRAINE][13] = 127, -+ [1][0][2][0][RTW89_CHILE][13] = 127, -+ [1][0][2][0][RTW89_QATAR][13] = 127, - [1][1][2][0][RTW89_FCC][0] = 127, - [1][1][2][0][RTW89_ETSI][0] = 127, - [1][1][2][0][RTW89_MKK][0] = 127, -@@ -29890,6 +30468,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][0] = 127, - [1][1][2][0][RTW89_CN][0] = 127, - [1][1][2][0][RTW89_UK][0] = 127, -+ [1][1][2][0][RTW89_MEXICO][0] = 127, -+ [1][1][2][0][RTW89_UKRAINE][0] = 127, -+ [1][1][2][0][RTW89_CHILE][0] = 127, -+ [1][1][2][0][RTW89_QATAR][0] = 127, - [1][1][2][0][RTW89_FCC][1] = 127, - [1][1][2][0][RTW89_ETSI][1] = 127, - [1][1][2][0][RTW89_MKK][1] = 127, -@@ -29898,6 +30480,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][1] = 127, - [1][1][2][0][RTW89_CN][1] = 127, - [1][1][2][0][RTW89_UK][1] = 127, -+ [1][1][2][0][RTW89_MEXICO][1] = 127, -+ [1][1][2][0][RTW89_UKRAINE][1] = 127, -+ [1][1][2][0][RTW89_CHILE][1] = 127, -+ [1][1][2][0][RTW89_QATAR][1] = 127, - [1][1][2][0][RTW89_FCC][2] = 60, - [1][1][2][0][RTW89_ETSI][2] = 48, - [1][1][2][0][RTW89_MKK][2] = 68, -@@ -29906,6 +30492,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][2] = 48, - [1][1][2][0][RTW89_CN][2] = 34, - [1][1][2][0][RTW89_UK][2] = 48, -+ [1][1][2][0][RTW89_MEXICO][2] = 60, -+ [1][1][2][0][RTW89_UKRAINE][2] = 48, -+ [1][1][2][0][RTW89_CHILE][2] = 60, -+ [1][1][2][0][RTW89_QATAR][2] = 48, - [1][1][2][0][RTW89_FCC][3] = 60, - [1][1][2][0][RTW89_ETSI][3] = 48, - [1][1][2][0][RTW89_MKK][3] = 68, -@@ -29914,6 +30504,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][3] = 48, - [1][1][2][0][RTW89_CN][3] = 34, - [1][1][2][0][RTW89_UK][3] = 48, -+ [1][1][2][0][RTW89_MEXICO][3] = 60, -+ [1][1][2][0][RTW89_UKRAINE][3] = 48, -+ [1][1][2][0][RTW89_CHILE][3] = 56, -+ [1][1][2][0][RTW89_QATAR][3] = 48, - [1][1][2][0][RTW89_FCC][4] = 60, - [1][1][2][0][RTW89_ETSI][4] = 48, - [1][1][2][0][RTW89_MKK][4] = 68, -@@ -29922,6 +30516,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][4] = 48, - [1][1][2][0][RTW89_CN][4] = 34, - [1][1][2][0][RTW89_UK][4] = 48, -+ [1][1][2][0][RTW89_MEXICO][4] = 60, -+ [1][1][2][0][RTW89_UKRAINE][4] = 48, -+ [1][1][2][0][RTW89_CHILE][4] = 56, -+ [1][1][2][0][RTW89_QATAR][4] = 48, - [1][1][2][0][RTW89_FCC][5] = 60, - [1][1][2][0][RTW89_ETSI][5] = 48, - [1][1][2][0][RTW89_MKK][5] = 68, -@@ -29930,6 +30528,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][5] = 48, - [1][1][2][0][RTW89_CN][5] = 34, - [1][1][2][0][RTW89_UK][5] = 48, -+ [1][1][2][0][RTW89_MEXICO][5] = 60, -+ [1][1][2][0][RTW89_UKRAINE][5] = 48, -+ [1][1][2][0][RTW89_CHILE][5] = 60, -+ [1][1][2][0][RTW89_QATAR][5] = 48, - [1][1][2][0][RTW89_FCC][6] = 58, - [1][1][2][0][RTW89_ETSI][6] = 48, - [1][1][2][0][RTW89_MKK][6] = 68, -@@ -29938,6 +30540,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][6] = 48, - [1][1][2][0][RTW89_CN][6] = 34, - [1][1][2][0][RTW89_UK][6] = 48, -+ [1][1][2][0][RTW89_MEXICO][6] = 58, -+ [1][1][2][0][RTW89_UKRAINE][6] = 48, -+ [1][1][2][0][RTW89_CHILE][6] = 52, -+ [1][1][2][0][RTW89_QATAR][6] = 48, - [1][1][2][0][RTW89_FCC][7] = 54, - [1][1][2][0][RTW89_ETSI][7] = 48, - [1][1][2][0][RTW89_MKK][7] = 68, -@@ -29946,6 +30552,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][7] = 48, - [1][1][2][0][RTW89_CN][7] = 34, - [1][1][2][0][RTW89_UK][7] = 48, -+ [1][1][2][0][RTW89_MEXICO][7] = 54, -+ [1][1][2][0][RTW89_UKRAINE][7] = 48, -+ [1][1][2][0][RTW89_CHILE][7] = 52, -+ [1][1][2][0][RTW89_QATAR][7] = 48, - [1][1][2][0][RTW89_FCC][8] = 54, - [1][1][2][0][RTW89_ETSI][8] = 48, - [1][1][2][0][RTW89_MKK][8] = 68, -@@ -29954,6 +30564,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][8] = 48, - [1][1][2][0][RTW89_CN][8] = 34, - [1][1][2][0][RTW89_UK][8] = 48, -+ [1][1][2][0][RTW89_MEXICO][8] = 54, -+ [1][1][2][0][RTW89_UKRAINE][8] = 48, -+ [1][1][2][0][RTW89_CHILE][8] = 54, -+ [1][1][2][0][RTW89_QATAR][8] = 48, - [1][1][2][0][RTW89_FCC][9] = 54, - [1][1][2][0][RTW89_ETSI][9] = 48, - [1][1][2][0][RTW89_MKK][9] = 68, -@@ -29962,6 +30576,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][9] = 48, - [1][1][2][0][RTW89_CN][9] = 34, - [1][1][2][0][RTW89_UK][9] = 48, -+ [1][1][2][0][RTW89_MEXICO][9] = 54, -+ [1][1][2][0][RTW89_UKRAINE][9] = 48, -+ [1][1][2][0][RTW89_CHILE][9] = 54, -+ [1][1][2][0][RTW89_QATAR][9] = 48, - [1][1][2][0][RTW89_FCC][10] = 46, - [1][1][2][0][RTW89_ETSI][10] = 48, - [1][1][2][0][RTW89_MKK][10] = 68, -@@ -29970,6 +30588,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][10] = 48, - [1][1][2][0][RTW89_CN][10] = 34, - [1][1][2][0][RTW89_UK][10] = 48, -+ [1][1][2][0][RTW89_MEXICO][10] = 46, -+ [1][1][2][0][RTW89_UKRAINE][10] = 48, -+ [1][1][2][0][RTW89_CHILE][10] = 46, -+ [1][1][2][0][RTW89_QATAR][10] = 48, - [1][1][2][0][RTW89_FCC][11] = 127, - [1][1][2][0][RTW89_ETSI][11] = 127, - [1][1][2][0][RTW89_MKK][11] = 127, -@@ -29978,6 +30600,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][11] = 127, - [1][1][2][0][RTW89_CN][11] = 127, - [1][1][2][0][RTW89_UK][11] = 127, -+ [1][1][2][0][RTW89_MEXICO][11] = 127, -+ [1][1][2][0][RTW89_UKRAINE][11] = 127, -+ [1][1][2][0][RTW89_CHILE][11] = 127, -+ [1][1][2][0][RTW89_QATAR][11] = 127, - [1][1][2][0][RTW89_FCC][12] = 127, - [1][1][2][0][RTW89_ETSI][12] = 127, - [1][1][2][0][RTW89_MKK][12] = 127, -@@ -29986,6 +30612,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][12] = 127, - [1][1][2][0][RTW89_CN][12] = 127, - [1][1][2][0][RTW89_UK][12] = 127, -+ [1][1][2][0][RTW89_MEXICO][12] = 127, -+ [1][1][2][0][RTW89_UKRAINE][12] = 127, -+ [1][1][2][0][RTW89_CHILE][12] = 127, -+ [1][1][2][0][RTW89_QATAR][12] = 127, - [1][1][2][0][RTW89_FCC][13] = 127, - [1][1][2][0][RTW89_ETSI][13] = 127, - [1][1][2][0][RTW89_MKK][13] = 127, -@@ -29994,6 +30624,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][0][RTW89_ACMA][13] = 127, - [1][1][2][0][RTW89_CN][13] = 127, - [1][1][2][0][RTW89_UK][13] = 127, -+ [1][1][2][0][RTW89_MEXICO][13] = 127, -+ [1][1][2][0][RTW89_UKRAINE][13] = 127, -+ [1][1][2][0][RTW89_CHILE][13] = 127, -+ [1][1][2][0][RTW89_QATAR][13] = 127, - [1][1][2][1][RTW89_FCC][0] = 127, - [1][1][2][1][RTW89_ETSI][0] = 127, - [1][1][2][1][RTW89_MKK][0] = 127, -@@ -30002,6 +30636,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][0] = 127, - [1][1][2][1][RTW89_CN][0] = 127, - [1][1][2][1][RTW89_UK][0] = 127, -+ [1][1][2][1][RTW89_MEXICO][0] = 127, -+ [1][1][2][1][RTW89_UKRAINE][0] = 127, -+ [1][1][2][1][RTW89_CHILE][0] = 127, -+ [1][1][2][1][RTW89_QATAR][0] = 127, - [1][1][2][1][RTW89_FCC][1] = 127, - [1][1][2][1][RTW89_ETSI][1] = 127, - [1][1][2][1][RTW89_MKK][1] = 127, -@@ -30010,6 +30648,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][1] = 127, - [1][1][2][1][RTW89_CN][1] = 127, - [1][1][2][1][RTW89_UK][1] = 127, -+ [1][1][2][1][RTW89_MEXICO][1] = 127, -+ [1][1][2][1][RTW89_UKRAINE][1] = 127, -+ [1][1][2][1][RTW89_CHILE][1] = 127, -+ [1][1][2][1][RTW89_QATAR][1] = 127, - [1][1][2][1][RTW89_FCC][2] = 60, - [1][1][2][1][RTW89_ETSI][2] = 36, - [1][1][2][1][RTW89_MKK][2] = 68, -@@ -30018,6 +30660,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][2] = 36, - [1][1][2][1][RTW89_CN][2] = 34, - [1][1][2][1][RTW89_UK][2] = 36, -+ [1][1][2][1][RTW89_MEXICO][2] = 60, -+ [1][1][2][1][RTW89_UKRAINE][2] = 36, -+ [1][1][2][1][RTW89_CHILE][2] = 60, -+ [1][1][2][1][RTW89_QATAR][2] = 36, - [1][1][2][1][RTW89_FCC][3] = 60, - [1][1][2][1][RTW89_ETSI][3] = 36, - [1][1][2][1][RTW89_MKK][3] = 68, -@@ -30026,6 +30672,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][3] = 36, - [1][1][2][1][RTW89_CN][3] = 34, - [1][1][2][1][RTW89_UK][3] = 36, -+ [1][1][2][1][RTW89_MEXICO][3] = 60, -+ [1][1][2][1][RTW89_UKRAINE][3] = 36, -+ [1][1][2][1][RTW89_CHILE][3] = 44, -+ [1][1][2][1][RTW89_QATAR][3] = 36, - [1][1][2][1][RTW89_FCC][4] = 60, - [1][1][2][1][RTW89_ETSI][4] = 36, - [1][1][2][1][RTW89_MKK][4] = 68, -@@ -30034,6 +30684,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][4] = 36, - [1][1][2][1][RTW89_CN][4] = 34, - [1][1][2][1][RTW89_UK][4] = 36, -+ [1][1][2][1][RTW89_MEXICO][4] = 60, -+ [1][1][2][1][RTW89_UKRAINE][4] = 36, -+ [1][1][2][1][RTW89_CHILE][4] = 44, -+ [1][1][2][1][RTW89_QATAR][4] = 36, - [1][1][2][1][RTW89_FCC][5] = 60, - [1][1][2][1][RTW89_ETSI][5] = 36, - [1][1][2][1][RTW89_MKK][5] = 68, -@@ -30042,6 +30696,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][5] = 36, - [1][1][2][1][RTW89_CN][5] = 34, - [1][1][2][1][RTW89_UK][5] = 36, -+ [1][1][2][1][RTW89_MEXICO][5] = 60, -+ [1][1][2][1][RTW89_UKRAINE][5] = 36, -+ [1][1][2][1][RTW89_CHILE][5] = 60, -+ [1][1][2][1][RTW89_QATAR][5] = 36, - [1][1][2][1][RTW89_FCC][6] = 58, - [1][1][2][1][RTW89_ETSI][6] = 36, - [1][1][2][1][RTW89_MKK][6] = 68, -@@ -30050,6 +30708,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][6] = 36, - [1][1][2][1][RTW89_CN][6] = 34, - [1][1][2][1][RTW89_UK][6] = 36, -+ [1][1][2][1][RTW89_MEXICO][6] = 58, -+ [1][1][2][1][RTW89_UKRAINE][6] = 36, -+ [1][1][2][1][RTW89_CHILE][6] = 40, -+ [1][1][2][1][RTW89_QATAR][6] = 36, - [1][1][2][1][RTW89_FCC][7] = 54, - [1][1][2][1][RTW89_ETSI][7] = 36, - [1][1][2][1][RTW89_MKK][7] = 68, -@@ -30058,6 +30720,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][7] = 36, - [1][1][2][1][RTW89_CN][7] = 34, - [1][1][2][1][RTW89_UK][7] = 36, -+ [1][1][2][1][RTW89_MEXICO][7] = 54, -+ [1][1][2][1][RTW89_UKRAINE][7] = 36, -+ [1][1][2][1][RTW89_CHILE][7] = 40, -+ [1][1][2][1][RTW89_QATAR][7] = 36, - [1][1][2][1][RTW89_FCC][8] = 54, - [1][1][2][1][RTW89_ETSI][8] = 36, - [1][1][2][1][RTW89_MKK][8] = 68, -@@ -30066,6 +30732,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][8] = 36, - [1][1][2][1][RTW89_CN][8] = 34, - [1][1][2][1][RTW89_UK][8] = 36, -+ [1][1][2][1][RTW89_MEXICO][8] = 54, -+ [1][1][2][1][RTW89_UKRAINE][8] = 36, -+ [1][1][2][1][RTW89_CHILE][8] = 54, -+ [1][1][2][1][RTW89_QATAR][8] = 36, - [1][1][2][1][RTW89_FCC][9] = 54, - [1][1][2][1][RTW89_ETSI][9] = 36, - [1][1][2][1][RTW89_MKK][9] = 68, -@@ -30074,6 +30744,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][9] = 36, - [1][1][2][1][RTW89_CN][9] = 34, - [1][1][2][1][RTW89_UK][9] = 36, -+ [1][1][2][1][RTW89_MEXICO][9] = 54, -+ [1][1][2][1][RTW89_UKRAINE][9] = 36, -+ [1][1][2][1][RTW89_CHILE][9] = 54, -+ [1][1][2][1][RTW89_QATAR][9] = 36, - [1][1][2][1][RTW89_FCC][10] = 46, - [1][1][2][1][RTW89_ETSI][10] = 36, - [1][1][2][1][RTW89_MKK][10] = 68, -@@ -30082,6 +30756,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][10] = 36, - [1][1][2][1][RTW89_CN][10] = 36, - [1][1][2][1][RTW89_UK][10] = 36, -+ [1][1][2][1][RTW89_MEXICO][10] = 46, -+ [1][1][2][1][RTW89_UKRAINE][10] = 36, -+ [1][1][2][1][RTW89_CHILE][10] = 46, -+ [1][1][2][1][RTW89_QATAR][10] = 36, - [1][1][2][1][RTW89_FCC][11] = 127, - [1][1][2][1][RTW89_ETSI][11] = 127, - [1][1][2][1][RTW89_MKK][11] = 127, -@@ -30090,6 +30768,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][11] = 127, - [1][1][2][1][RTW89_CN][11] = 127, - [1][1][2][1][RTW89_UK][11] = 127, -+ [1][1][2][1][RTW89_MEXICO][11] = 127, -+ [1][1][2][1][RTW89_UKRAINE][11] = 127, -+ [1][1][2][1][RTW89_CHILE][11] = 127, -+ [1][1][2][1][RTW89_QATAR][11] = 127, - [1][1][2][1][RTW89_FCC][12] = 127, - [1][1][2][1][RTW89_ETSI][12] = 127, - [1][1][2][1][RTW89_MKK][12] = 127, -@@ -30098,6 +30780,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][12] = 127, - [1][1][2][1][RTW89_CN][12] = 127, - [1][1][2][1][RTW89_UK][12] = 127, -+ [1][1][2][1][RTW89_MEXICO][12] = 127, -+ [1][1][2][1][RTW89_UKRAINE][12] = 127, -+ [1][1][2][1][RTW89_CHILE][12] = 127, -+ [1][1][2][1][RTW89_QATAR][12] = 127, - [1][1][2][1][RTW89_FCC][13] = 127, - [1][1][2][1][RTW89_ETSI][13] = 127, - [1][1][2][1][RTW89_MKK][13] = 127, -@@ -30106,6 +30792,10 @@ const s8 rtw89_8852c_txpwr_lmt_2g[RTW89_ - [1][1][2][1][RTW89_ACMA][13] = 127, - [1][1][2][1][RTW89_CN][13] = 127, - [1][1][2][1][RTW89_UK][13] = 127, -+ [1][1][2][1][RTW89_MEXICO][13] = 127, -+ [1][1][2][1][RTW89_UKRAINE][13] = 127, -+ [1][1][2][1][RTW89_CHILE][13] = 127, -+ [1][1][2][1][RTW89_QATAR][13] = 127, - }; - - static -@@ -30120,17 +30810,17 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_WW][10] = 50, - [0][0][1][0][RTW89_WW][12] = 50, - [0][0][1][0][RTW89_WW][14] = 50, -- [0][0][1][0][RTW89_WW][15] = 66, -- [0][0][1][0][RTW89_WW][17] = 66, -- [0][0][1][0][RTW89_WW][19] = 66, -- [0][0][1][0][RTW89_WW][21] = 66, -- [0][0][1][0][RTW89_WW][23] = 66, -- [0][0][1][0][RTW89_WW][25] = 66, -- [0][0][1][0][RTW89_WW][27] = 66, -- [0][0][1][0][RTW89_WW][29] = 66, -- [0][0][1][0][RTW89_WW][31] = 66, -- [0][0][1][0][RTW89_WW][33] = 66, -- [0][0][1][0][RTW89_WW][35] = 60, -+ [0][0][1][0][RTW89_WW][15] = 54, -+ [0][0][1][0][RTW89_WW][17] = 54, -+ [0][0][1][0][RTW89_WW][19] = 54, -+ [0][0][1][0][RTW89_WW][21] = 54, -+ [0][0][1][0][RTW89_WW][23] = 54, -+ [0][0][1][0][RTW89_WW][25] = 54, -+ [0][0][1][0][RTW89_WW][27] = 54, -+ [0][0][1][0][RTW89_WW][29] = 54, -+ [0][0][1][0][RTW89_WW][31] = 54, -+ [0][0][1][0][RTW89_WW][33] = 54, -+ [0][0][1][0][RTW89_WW][35] = 54, - [0][0][1][0][RTW89_WW][37] = 64, - [0][0][1][0][RTW89_WW][38] = 30, - [0][0][1][0][RTW89_WW][40] = 30, -@@ -30144,21 +30834,21 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_WW][2] = 34, - [0][1][1][0][RTW89_WW][4] = 34, - [0][1][1][0][RTW89_WW][6] = 36, -- [0][1][1][0][RTW89_WW][8] = 46, -- [0][1][1][0][RTW89_WW][10] = 46, -- [0][1][1][0][RTW89_WW][12] = 46, -- [0][1][1][0][RTW89_WW][14] = 46, -- [0][1][1][0][RTW89_WW][15] = 54, -- [0][1][1][0][RTW89_WW][17] = 54, -- [0][1][1][0][RTW89_WW][19] = 54, -- [0][1][1][0][RTW89_WW][21] = 54, -- [0][1][1][0][RTW89_WW][23] = 54, -- [0][1][1][0][RTW89_WW][25] = 54, -- [0][1][1][0][RTW89_WW][27] = 54, -- [0][1][1][0][RTW89_WW][29] = 54, -- [0][1][1][0][RTW89_WW][31] = 54, -- [0][1][1][0][RTW89_WW][33] = 54, -- [0][1][1][0][RTW89_WW][35] = 52, -+ [0][1][1][0][RTW89_WW][8] = 42, -+ [0][1][1][0][RTW89_WW][10] = 42, -+ [0][1][1][0][RTW89_WW][12] = 42, -+ [0][1][1][0][RTW89_WW][14] = 42, -+ [0][1][1][0][RTW89_WW][15] = 42, -+ [0][1][1][0][RTW89_WW][17] = 42, -+ [0][1][1][0][RTW89_WW][19] = 42, -+ [0][1][1][0][RTW89_WW][21] = 42, -+ [0][1][1][0][RTW89_WW][23] = 42, -+ [0][1][1][0][RTW89_WW][25] = 42, -+ [0][1][1][0][RTW89_WW][27] = 42, -+ [0][1][1][0][RTW89_WW][29] = 42, -+ [0][1][1][0][RTW89_WW][31] = 42, -+ [0][1][1][0][RTW89_WW][33] = 42, -+ [0][1][1][0][RTW89_WW][35] = 42, - [0][1][1][0][RTW89_WW][37] = 52, - [0][1][1][0][RTW89_WW][38] = 18, - [0][1][1][0][RTW89_WW][40] = 18, -@@ -30176,17 +30866,17 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_WW][10] = 52, - [0][0][2][0][RTW89_WW][12] = 52, - [0][0][2][0][RTW89_WW][14] = 52, -- [0][0][2][0][RTW89_WW][15] = 66, -- [0][0][2][0][RTW89_WW][17] = 66, -- [0][0][2][0][RTW89_WW][19] = 66, -- [0][0][2][0][RTW89_WW][21] = 66, -- [0][0][2][0][RTW89_WW][23] = 66, -- [0][0][2][0][RTW89_WW][25] = 66, -- [0][0][2][0][RTW89_WW][27] = 66, -- [0][0][2][0][RTW89_WW][29] = 66, -- [0][0][2][0][RTW89_WW][31] = 66, -- [0][0][2][0][RTW89_WW][33] = 66, -- [0][0][2][0][RTW89_WW][35] = 56, -+ [0][0][2][0][RTW89_WW][15] = 54, -+ [0][0][2][0][RTW89_WW][17] = 54, -+ [0][0][2][0][RTW89_WW][19] = 54, -+ [0][0][2][0][RTW89_WW][21] = 54, -+ [0][0][2][0][RTW89_WW][23] = 54, -+ [0][0][2][0][RTW89_WW][25] = 54, -+ [0][0][2][0][RTW89_WW][27] = 54, -+ [0][0][2][0][RTW89_WW][29] = 54, -+ [0][0][2][0][RTW89_WW][31] = 54, -+ [0][0][2][0][RTW89_WW][33] = 54, -+ [0][0][2][0][RTW89_WW][35] = 54, - [0][0][2][0][RTW89_WW][37] = 64, - [0][0][2][0][RTW89_WW][38] = 30, - [0][0][2][0][RTW89_WW][40] = 30, -@@ -30204,17 +30894,17 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_WW][10] = 40, - [0][1][2][0][RTW89_WW][12] = 40, - [0][1][2][0][RTW89_WW][14] = 40, -- [0][1][2][0][RTW89_WW][15] = 54, -- [0][1][2][0][RTW89_WW][17] = 54, -- [0][1][2][0][RTW89_WW][19] = 54, -- [0][1][2][0][RTW89_WW][21] = 54, -- [0][1][2][0][RTW89_WW][23] = 54, -- [0][1][2][0][RTW89_WW][25] = 54, -- [0][1][2][0][RTW89_WW][27] = 54, -- [0][1][2][0][RTW89_WW][29] = 54, -- [0][1][2][0][RTW89_WW][31] = 54, -- [0][1][2][0][RTW89_WW][33] = 54, -- [0][1][2][0][RTW89_WW][35] = 46, -+ [0][1][2][0][RTW89_WW][15] = 42, -+ [0][1][2][0][RTW89_WW][17] = 42, -+ [0][1][2][0][RTW89_WW][19] = 42, -+ [0][1][2][0][RTW89_WW][21] = 42, -+ [0][1][2][0][RTW89_WW][23] = 42, -+ [0][1][2][0][RTW89_WW][25] = 42, -+ [0][1][2][0][RTW89_WW][27] = 42, -+ [0][1][2][0][RTW89_WW][29] = 42, -+ [0][1][2][0][RTW89_WW][31] = 42, -+ [0][1][2][0][RTW89_WW][33] = 42, -+ [0][1][2][0][RTW89_WW][35] = 42, - [0][1][2][0][RTW89_WW][37] = 52, - [0][1][2][0][RTW89_WW][38] = 18, - [0][1][2][0][RTW89_WW][40] = 18, -@@ -30224,25 +30914,25 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_WW][48] = 48, - [0][1][2][0][RTW89_WW][50] = 50, - [0][1][2][0][RTW89_WW][52] = 48, -- [0][1][2][1][RTW89_WW][0] = 36, -- [0][1][2][1][RTW89_WW][2] = 36, -- [0][1][2][1][RTW89_WW][4] = 36, -- [0][1][2][1][RTW89_WW][6] = 36, -- [0][1][2][1][RTW89_WW][8] = 36, -- [0][1][2][1][RTW89_WW][10] = 36, -- [0][1][2][1][RTW89_WW][12] = 36, -- [0][1][2][1][RTW89_WW][14] = 36, -- [0][1][2][1][RTW89_WW][15] = 40, -- [0][1][2][1][RTW89_WW][17] = 40, -- [0][1][2][1][RTW89_WW][19] = 40, -- [0][1][2][1][RTW89_WW][21] = 40, -- [0][1][2][1][RTW89_WW][23] = 40, -- [0][1][2][1][RTW89_WW][25] = 40, -- [0][1][2][1][RTW89_WW][27] = 40, -- [0][1][2][1][RTW89_WW][29] = 40, -- [0][1][2][1][RTW89_WW][31] = 40, -- [0][1][2][1][RTW89_WW][33] = 40, -- [0][1][2][1][RTW89_WW][35] = 40, -+ [0][1][2][1][RTW89_WW][0] = 30, -+ [0][1][2][1][RTW89_WW][2] = 30, -+ [0][1][2][1][RTW89_WW][4] = 30, -+ [0][1][2][1][RTW89_WW][6] = 30, -+ [0][1][2][1][RTW89_WW][8] = 30, -+ [0][1][2][1][RTW89_WW][10] = 30, -+ [0][1][2][1][RTW89_WW][12] = 30, -+ [0][1][2][1][RTW89_WW][14] = 30, -+ [0][1][2][1][RTW89_WW][15] = 30, -+ [0][1][2][1][RTW89_WW][17] = 30, -+ [0][1][2][1][RTW89_WW][19] = 30, -+ [0][1][2][1][RTW89_WW][21] = 30, -+ [0][1][2][1][RTW89_WW][23] = 30, -+ [0][1][2][1][RTW89_WW][25] = 30, -+ [0][1][2][1][RTW89_WW][27] = 30, -+ [0][1][2][1][RTW89_WW][29] = 30, -+ [0][1][2][1][RTW89_WW][31] = 30, -+ [0][1][2][1][RTW89_WW][33] = 30, -+ [0][1][2][1][RTW89_WW][35] = 30, - [0][1][2][1][RTW89_WW][37] = 40, - [0][1][2][1][RTW89_WW][38] = 6, - [0][1][2][1][RTW89_WW][40] = 6, -@@ -30256,11 +30946,11 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_WW][5] = 54, - [1][0][2][0][RTW89_WW][9] = 54, - [1][0][2][0][RTW89_WW][13] = 52, -- [1][0][2][0][RTW89_WW][16] = 56, -- [1][0][2][0][RTW89_WW][20] = 56, -- [1][0][2][0][RTW89_WW][24] = 56, -- [1][0][2][0][RTW89_WW][28] = 66, -- [1][0][2][0][RTW89_WW][32] = 62, -+ [1][0][2][0][RTW89_WW][16] = 54, -+ [1][0][2][0][RTW89_WW][20] = 54, -+ [1][0][2][0][RTW89_WW][24] = 54, -+ [1][0][2][0][RTW89_WW][28] = 54, -+ [1][0][2][0][RTW89_WW][32] = 54, - [1][0][2][0][RTW89_WW][36] = 64, - [1][0][2][0][RTW89_WW][39] = 30, - [1][0][2][0][RTW89_WW][43] = 30, -@@ -30270,25 +30960,25 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_WW][5] = 42, - [1][1][2][0][RTW89_WW][9] = 42, - [1][1][2][0][RTW89_WW][13] = 42, -- [1][1][2][0][RTW89_WW][16] = 54, -- [1][1][2][0][RTW89_WW][20] = 54, -- [1][1][2][0][RTW89_WW][24] = 54, -- [1][1][2][0][RTW89_WW][28] = 54, -- [1][1][2][0][RTW89_WW][32] = 54, -+ [1][1][2][0][RTW89_WW][16] = 42, -+ [1][1][2][0][RTW89_WW][20] = 42, -+ [1][1][2][0][RTW89_WW][24] = 42, -+ [1][1][2][0][RTW89_WW][28] = 42, -+ [1][1][2][0][RTW89_WW][32] = 42, - [1][1][2][0][RTW89_WW][36] = 52, - [1][1][2][0][RTW89_WW][39] = 18, - [1][1][2][0][RTW89_WW][43] = 18, - [1][1][2][0][RTW89_WW][47] = 62, - [1][1][2][0][RTW89_WW][51] = 60, -- [1][1][2][1][RTW89_WW][1] = 40, -- [1][1][2][1][RTW89_WW][5] = 40, -- [1][1][2][1][RTW89_WW][9] = 40, -- [1][1][2][1][RTW89_WW][13] = 40, -- [1][1][2][1][RTW89_WW][16] = 40, -- [1][1][2][1][RTW89_WW][20] = 40, -- [1][1][2][1][RTW89_WW][24] = 40, -- [1][1][2][1][RTW89_WW][28] = 40, -- [1][1][2][1][RTW89_WW][32] = 40, -+ [1][1][2][1][RTW89_WW][1] = 30, -+ [1][1][2][1][RTW89_WW][5] = 30, -+ [1][1][2][1][RTW89_WW][9] = 30, -+ [1][1][2][1][RTW89_WW][13] = 30, -+ [1][1][2][1][RTW89_WW][16] = 30, -+ [1][1][2][1][RTW89_WW][20] = 30, -+ [1][1][2][1][RTW89_WW][24] = 30, -+ [1][1][2][1][RTW89_WW][28] = 30, -+ [1][1][2][1][RTW89_WW][32] = 30, - [1][1][2][1][RTW89_WW][36] = 40, - [1][1][2][1][RTW89_WW][39] = 6, - [1][1][2][1][RTW89_WW][43] = 6, -@@ -30296,22 +30986,22 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_WW][51] = 60, - [2][0][2][0][RTW89_WW][3] = 54, - [2][0][2][0][RTW89_WW][11] = 50, -- [2][0][2][0][RTW89_WW][18] = 56, -- [2][0][2][0][RTW89_WW][26] = 60, -+ [2][0][2][0][RTW89_WW][18] = 54, -+ [2][0][2][0][RTW89_WW][26] = 54, - [2][0][2][0][RTW89_WW][34] = 60, - [2][0][2][0][RTW89_WW][41] = 30, - [2][0][2][0][RTW89_WW][49] = 62, -- [2][1][2][0][RTW89_WW][3] = 46, -+ [2][1][2][0][RTW89_WW][3] = 42, - [2][1][2][0][RTW89_WW][11] = 38, -- [2][1][2][0][RTW89_WW][18] = 50, -- [2][1][2][0][RTW89_WW][26] = 52, -+ [2][1][2][0][RTW89_WW][18] = 42, -+ [2][1][2][0][RTW89_WW][26] = 42, - [2][1][2][0][RTW89_WW][34] = 52, - [2][1][2][0][RTW89_WW][41] = 18, - [2][1][2][0][RTW89_WW][49] = 62, -- [2][1][2][1][RTW89_WW][3] = 40, -- [2][1][2][1][RTW89_WW][11] = 38, -- [2][1][2][1][RTW89_WW][18] = 40, -- [2][1][2][1][RTW89_WW][26] = 42, -+ [2][1][2][1][RTW89_WW][3] = 30, -+ [2][1][2][1][RTW89_WW][11] = 30, -+ [2][1][2][1][RTW89_WW][18] = 30, -+ [2][1][2][1][RTW89_WW][26] = 30, - [2][1][2][1][RTW89_WW][34] = 40, - [2][1][2][1][RTW89_WW][41] = 6, - [2][1][2][1][RTW89_WW][49] = 62, -@@ -30328,34 +31018,50 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ETSI][0] = 66, - [0][0][1][0][RTW89_MKK][0] = 66, - [0][0][1][0][RTW89_IC][0] = 60, -- [0][0][1][0][RTW89_KCC][0] = 52, -+ [0][0][1][0][RTW89_KCC][0] = 62, - [0][0][1][0][RTW89_ACMA][0] = 66, - [0][0][1][0][RTW89_CN][0] = 50, - [0][0][1][0][RTW89_UK][0] = 66, -+ [0][0][1][0][RTW89_MEXICO][0] = 62, -+ [0][0][1][0][RTW89_UKRAINE][0] = 54, -+ [0][0][1][0][RTW89_CHILE][0] = 70, -+ [0][0][1][0][RTW89_QATAR][0] = 66, - [0][0][1][0][RTW89_FCC][2] = 72, - [0][0][1][0][RTW89_ETSI][2] = 66, - [0][0][1][0][RTW89_MKK][2] = 66, - [0][0][1][0][RTW89_IC][2] = 60, -- [0][0][1][0][RTW89_KCC][2] = 52, -+ [0][0][1][0][RTW89_KCC][2] = 62, - [0][0][1][0][RTW89_ACMA][2] = 66, - [0][0][1][0][RTW89_CN][2] = 50, - [0][0][1][0][RTW89_UK][2] = 66, -+ [0][0][1][0][RTW89_MEXICO][2] = 62, -+ [0][0][1][0][RTW89_UKRAINE][2] = 54, -+ [0][0][1][0][RTW89_CHILE][2] = 70, -+ [0][0][1][0][RTW89_QATAR][2] = 66, - [0][0][1][0][RTW89_FCC][4] = 72, - [0][0][1][0][RTW89_ETSI][4] = 66, - [0][0][1][0][RTW89_MKK][4] = 66, - [0][0][1][0][RTW89_IC][4] = 60, -- [0][0][1][0][RTW89_KCC][4] = 52, -+ [0][0][1][0][RTW89_KCC][4] = 62, - [0][0][1][0][RTW89_ACMA][4] = 66, - [0][0][1][0][RTW89_CN][4] = 50, - [0][0][1][0][RTW89_UK][4] = 66, -+ [0][0][1][0][RTW89_MEXICO][4] = 62, -+ [0][0][1][0][RTW89_UKRAINE][4] = 54, -+ [0][0][1][0][RTW89_CHILE][4] = 70, -+ [0][0][1][0][RTW89_QATAR][4] = 66, - [0][0][1][0][RTW89_FCC][6] = 72, - [0][0][1][0][RTW89_ETSI][6] = 66, - [0][0][1][0][RTW89_MKK][6] = 66, - [0][0][1][0][RTW89_IC][6] = 58, -- [0][0][1][0][RTW89_KCC][6] = 62, -+ [0][0][1][0][RTW89_KCC][6] = 52, - [0][0][1][0][RTW89_ACMA][6] = 66, - [0][0][1][0][RTW89_CN][6] = 50, - [0][0][1][0][RTW89_UK][6] = 66, -+ [0][0][1][0][RTW89_MEXICO][6] = 62, -+ [0][0][1][0][RTW89_UKRAINE][6] = 54, -+ [0][0][1][0][RTW89_CHILE][6] = 70, -+ [0][0][1][0][RTW89_QATAR][6] = 66, - [0][0][1][0][RTW89_FCC][8] = 72, - [0][0][1][0][RTW89_ETSI][8] = 66, - [0][0][1][0][RTW89_MKK][8] = 66, -@@ -30364,6 +31070,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][8] = 66, - [0][0][1][0][RTW89_CN][8] = 50, - [0][0][1][0][RTW89_UK][8] = 66, -+ [0][0][1][0][RTW89_MEXICO][8] = 72, -+ [0][0][1][0][RTW89_UKRAINE][8] = 54, -+ [0][0][1][0][RTW89_CHILE][8] = 70, -+ [0][0][1][0][RTW89_QATAR][8] = 66, - [0][0][1][0][RTW89_FCC][10] = 72, - [0][0][1][0][RTW89_ETSI][10] = 66, - [0][0][1][0][RTW89_MKK][10] = 66, -@@ -30372,6 +31082,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][10] = 66, - [0][0][1][0][RTW89_CN][10] = 50, - [0][0][1][0][RTW89_UK][10] = 66, -+ [0][0][1][0][RTW89_MEXICO][10] = 72, -+ [0][0][1][0][RTW89_UKRAINE][10] = 54, -+ [0][0][1][0][RTW89_CHILE][10] = 70, -+ [0][0][1][0][RTW89_QATAR][10] = 66, - [0][0][1][0][RTW89_FCC][12] = 72, - [0][0][1][0][RTW89_ETSI][12] = 66, - [0][0][1][0][RTW89_MKK][12] = 66, -@@ -30380,6 +31094,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][12] = 66, - [0][0][1][0][RTW89_CN][12] = 50, - [0][0][1][0][RTW89_UK][12] = 66, -+ [0][0][1][0][RTW89_MEXICO][12] = 72, -+ [0][0][1][0][RTW89_UKRAINE][12] = 54, -+ [0][0][1][0][RTW89_CHILE][12] = 70, -+ [0][0][1][0][RTW89_QATAR][12] = 66, - [0][0][1][0][RTW89_FCC][14] = 70, - [0][0][1][0][RTW89_ETSI][14] = 66, - [0][0][1][0][RTW89_MKK][14] = 66, -@@ -30388,6 +31106,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][14] = 66, - [0][0][1][0][RTW89_CN][14] = 50, - [0][0][1][0][RTW89_UK][14] = 66, -+ [0][0][1][0][RTW89_MEXICO][14] = 70, -+ [0][0][1][0][RTW89_UKRAINE][14] = 54, -+ [0][0][1][0][RTW89_CHILE][14] = 68, -+ [0][0][1][0][RTW89_QATAR][14] = 66, - [0][0][1][0][RTW89_FCC][15] = 72, - [0][0][1][0][RTW89_ETSI][15] = 66, - [0][0][1][0][RTW89_MKK][15] = 70, -@@ -30396,6 +31118,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][15] = 66, - [0][0][1][0][RTW89_CN][15] = 127, - [0][0][1][0][RTW89_UK][15] = 66, -+ [0][0][1][0][RTW89_MEXICO][15] = 72, -+ [0][0][1][0][RTW89_UKRAINE][15] = 54, -+ [0][0][1][0][RTW89_CHILE][15] = 70, -+ [0][0][1][0][RTW89_QATAR][15] = 66, - [0][0][1][0][RTW89_FCC][17] = 72, - [0][0][1][0][RTW89_ETSI][17] = 66, - [0][0][1][0][RTW89_MKK][17] = 70, -@@ -30404,6 +31130,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][17] = 66, - [0][0][1][0][RTW89_CN][17] = 127, - [0][0][1][0][RTW89_UK][17] = 66, -+ [0][0][1][0][RTW89_MEXICO][17] = 72, -+ [0][0][1][0][RTW89_UKRAINE][17] = 54, -+ [0][0][1][0][RTW89_CHILE][17] = 70, -+ [0][0][1][0][RTW89_QATAR][17] = 66, - [0][0][1][0][RTW89_FCC][19] = 72, - [0][0][1][0][RTW89_ETSI][19] = 66, - [0][0][1][0][RTW89_MKK][19] = 70, -@@ -30412,6 +31142,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][19] = 66, - [0][0][1][0][RTW89_CN][19] = 127, - [0][0][1][0][RTW89_UK][19] = 66, -+ [0][0][1][0][RTW89_MEXICO][19] = 72, -+ [0][0][1][0][RTW89_UKRAINE][19] = 54, -+ [0][0][1][0][RTW89_CHILE][19] = 70, -+ [0][0][1][0][RTW89_QATAR][19] = 66, - [0][0][1][0][RTW89_FCC][21] = 72, - [0][0][1][0][RTW89_ETSI][21] = 66, - [0][0][1][0][RTW89_MKK][21] = 70, -@@ -30420,6 +31154,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][21] = 66, - [0][0][1][0][RTW89_CN][21] = 127, - [0][0][1][0][RTW89_UK][21] = 66, -+ [0][0][1][0][RTW89_MEXICO][21] = 72, -+ [0][0][1][0][RTW89_UKRAINE][21] = 54, -+ [0][0][1][0][RTW89_CHILE][21] = 70, -+ [0][0][1][0][RTW89_QATAR][21] = 66, - [0][0][1][0][RTW89_FCC][23] = 72, - [0][0][1][0][RTW89_ETSI][23] = 66, - [0][0][1][0][RTW89_MKK][23] = 70, -@@ -30428,6 +31166,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][23] = 66, - [0][0][1][0][RTW89_CN][23] = 127, - [0][0][1][0][RTW89_UK][23] = 66, -+ [0][0][1][0][RTW89_MEXICO][23] = 72, -+ [0][0][1][0][RTW89_UKRAINE][23] = 54, -+ [0][0][1][0][RTW89_CHILE][23] = 70, -+ [0][0][1][0][RTW89_QATAR][23] = 66, - [0][0][1][0][RTW89_FCC][25] = 72, - [0][0][1][0][RTW89_ETSI][25] = 66, - [0][0][1][0][RTW89_MKK][25] = 70, -@@ -30436,6 +31178,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][25] = 127, - [0][0][1][0][RTW89_CN][25] = 127, - [0][0][1][0][RTW89_UK][25] = 66, -+ [0][0][1][0][RTW89_MEXICO][25] = 72, -+ [0][0][1][0][RTW89_UKRAINE][25] = 54, -+ [0][0][1][0][RTW89_CHILE][25] = 70, -+ [0][0][1][0][RTW89_QATAR][25] = 66, - [0][0][1][0][RTW89_FCC][27] = 72, - [0][0][1][0][RTW89_ETSI][27] = 66, - [0][0][1][0][RTW89_MKK][27] = 70, -@@ -30444,6 +31190,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][27] = 127, - [0][0][1][0][RTW89_CN][27] = 127, - [0][0][1][0][RTW89_UK][27] = 66, -+ [0][0][1][0][RTW89_MEXICO][27] = 72, -+ [0][0][1][0][RTW89_UKRAINE][27] = 54, -+ [0][0][1][0][RTW89_CHILE][27] = 58, -+ [0][0][1][0][RTW89_QATAR][27] = 66, - [0][0][1][0][RTW89_FCC][29] = 72, - [0][0][1][0][RTW89_ETSI][29] = 66, - [0][0][1][0][RTW89_MKK][29] = 70, -@@ -30452,6 +31202,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][29] = 127, - [0][0][1][0][RTW89_CN][29] = 127, - [0][0][1][0][RTW89_UK][29] = 66, -+ [0][0][1][0][RTW89_MEXICO][29] = 72, -+ [0][0][1][0][RTW89_UKRAINE][29] = 54, -+ [0][0][1][0][RTW89_CHILE][29] = 58, -+ [0][0][1][0][RTW89_QATAR][29] = 66, - [0][0][1][0][RTW89_FCC][31] = 72, - [0][0][1][0][RTW89_ETSI][31] = 66, - [0][0][1][0][RTW89_MKK][31] = 70, -@@ -30460,6 +31214,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][31] = 66, - [0][0][1][0][RTW89_CN][31] = 127, - [0][0][1][0][RTW89_UK][31] = 66, -+ [0][0][1][0][RTW89_MEXICO][31] = 72, -+ [0][0][1][0][RTW89_UKRAINE][31] = 54, -+ [0][0][1][0][RTW89_CHILE][31] = 58, -+ [0][0][1][0][RTW89_QATAR][31] = 66, - [0][0][1][0][RTW89_FCC][33] = 72, - [0][0][1][0][RTW89_ETSI][33] = 66, - [0][0][1][0][RTW89_MKK][33] = 70, -@@ -30468,6 +31226,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][33] = 66, - [0][0][1][0][RTW89_CN][33] = 127, - [0][0][1][0][RTW89_UK][33] = 66, -+ [0][0][1][0][RTW89_MEXICO][33] = 72, -+ [0][0][1][0][RTW89_UKRAINE][33] = 54, -+ [0][0][1][0][RTW89_CHILE][33] = 58, -+ [0][0][1][0][RTW89_QATAR][33] = 66, - [0][0][1][0][RTW89_FCC][35] = 60, - [0][0][1][0][RTW89_ETSI][35] = 66, - [0][0][1][0][RTW89_MKK][35] = 70, -@@ -30476,6 +31238,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][35] = 66, - [0][0][1][0][RTW89_CN][35] = 127, - [0][0][1][0][RTW89_UK][35] = 66, -+ [0][0][1][0][RTW89_MEXICO][35] = 60, -+ [0][0][1][0][RTW89_UKRAINE][35] = 54, -+ [0][0][1][0][RTW89_CHILE][35] = 58, -+ [0][0][1][0][RTW89_QATAR][35] = 66, - [0][0][1][0][RTW89_FCC][37] = 72, - [0][0][1][0][RTW89_ETSI][37] = 127, - [0][0][1][0][RTW89_MKK][37] = 70, -@@ -30484,6 +31250,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][37] = 70, - [0][0][1][0][RTW89_CN][37] = 127, - [0][0][1][0][RTW89_UK][37] = 64, -+ [0][0][1][0][RTW89_MEXICO][37] = 72, -+ [0][0][1][0][RTW89_UKRAINE][37] = 127, -+ [0][0][1][0][RTW89_CHILE][37] = 70, -+ [0][0][1][0][RTW89_QATAR][37] = 127, - [0][0][1][0][RTW89_FCC][38] = 72, - [0][0][1][0][RTW89_ETSI][38] = 30, - [0][0][1][0][RTW89_MKK][38] = 127, -@@ -30492,6 +31262,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][38] = 70, - [0][0][1][0][RTW89_CN][38] = 68, - [0][0][1][0][RTW89_UK][38] = 64, -+ [0][0][1][0][RTW89_MEXICO][38] = 72, -+ [0][0][1][0][RTW89_UKRAINE][38] = 30, -+ [0][0][1][0][RTW89_CHILE][38] = 70, -+ [0][0][1][0][RTW89_QATAR][38] = 30, - [0][0][1][0][RTW89_FCC][40] = 72, - [0][0][1][0][RTW89_ETSI][40] = 30, - [0][0][1][0][RTW89_MKK][40] = 127, -@@ -30500,6 +31274,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][40] = 70, - [0][0][1][0][RTW89_CN][40] = 68, - [0][0][1][0][RTW89_UK][40] = 64, -+ [0][0][1][0][RTW89_MEXICO][40] = 72, -+ [0][0][1][0][RTW89_UKRAINE][40] = 30, -+ [0][0][1][0][RTW89_CHILE][40] = 70, -+ [0][0][1][0][RTW89_QATAR][40] = 30, - [0][0][1][0][RTW89_FCC][42] = 72, - [0][0][1][0][RTW89_ETSI][42] = 30, - [0][0][1][0][RTW89_MKK][42] = 127, -@@ -30508,6 +31286,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][42] = 70, - [0][0][1][0][RTW89_CN][42] = 68, - [0][0][1][0][RTW89_UK][42] = 64, -+ [0][0][1][0][RTW89_MEXICO][42] = 72, -+ [0][0][1][0][RTW89_UKRAINE][42] = 30, -+ [0][0][1][0][RTW89_CHILE][42] = 70, -+ [0][0][1][0][RTW89_QATAR][42] = 30, - [0][0][1][0][RTW89_FCC][44] = 72, - [0][0][1][0][RTW89_ETSI][44] = 30, - [0][0][1][0][RTW89_MKK][44] = 127, -@@ -30516,6 +31298,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][44] = 70, - [0][0][1][0][RTW89_CN][44] = 68, - [0][0][1][0][RTW89_UK][44] = 64, -+ [0][0][1][0][RTW89_MEXICO][44] = 72, -+ [0][0][1][0][RTW89_UKRAINE][44] = 30, -+ [0][0][1][0][RTW89_CHILE][44] = 70, -+ [0][0][1][0][RTW89_QATAR][44] = 30, - [0][0][1][0][RTW89_FCC][46] = 72, - [0][0][1][0][RTW89_ETSI][46] = 30, - [0][0][1][0][RTW89_MKK][46] = 127, -@@ -30524,6 +31310,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][46] = 70, - [0][0][1][0][RTW89_CN][46] = 68, - [0][0][1][0][RTW89_UK][46] = 64, -+ [0][0][1][0][RTW89_MEXICO][46] = 72, -+ [0][0][1][0][RTW89_UKRAINE][46] = 30, -+ [0][0][1][0][RTW89_CHILE][46] = 70, -+ [0][0][1][0][RTW89_QATAR][46] = 30, - [0][0][1][0][RTW89_FCC][48] = 72, - [0][0][1][0][RTW89_ETSI][48] = 127, - [0][0][1][0][RTW89_MKK][48] = 127, -@@ -30532,6 +31322,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][48] = 127, - [0][0][1][0][RTW89_CN][48] = 127, - [0][0][1][0][RTW89_UK][48] = 127, -+ [0][0][1][0][RTW89_MEXICO][48] = 127, -+ [0][0][1][0][RTW89_UKRAINE][48] = 127, -+ [0][0][1][0][RTW89_CHILE][48] = 127, -+ [0][0][1][0][RTW89_QATAR][48] = 127, - [0][0][1][0][RTW89_FCC][50] = 72, - [0][0][1][0][RTW89_ETSI][50] = 127, - [0][0][1][0][RTW89_MKK][50] = 127, -@@ -30540,6 +31334,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][50] = 127, - [0][0][1][0][RTW89_CN][50] = 127, - [0][0][1][0][RTW89_UK][50] = 127, -+ [0][0][1][0][RTW89_MEXICO][50] = 127, -+ [0][0][1][0][RTW89_UKRAINE][50] = 127, -+ [0][0][1][0][RTW89_CHILE][50] = 127, -+ [0][0][1][0][RTW89_QATAR][50] = 127, - [0][0][1][0][RTW89_FCC][52] = 72, - [0][0][1][0][RTW89_ETSI][52] = 127, - [0][0][1][0][RTW89_MKK][52] = 127, -@@ -30548,38 +31346,58 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][52] = 127, - [0][0][1][0][RTW89_CN][52] = 127, - [0][0][1][0][RTW89_UK][52] = 127, -+ [0][0][1][0][RTW89_MEXICO][52] = 127, -+ [0][0][1][0][RTW89_UKRAINE][52] = 127, -+ [0][0][1][0][RTW89_CHILE][52] = 127, -+ [0][0][1][0][RTW89_QATAR][52] = 127, - [0][1][1][0][RTW89_FCC][0] = 60, - [0][1][1][0][RTW89_ETSI][0] = 54, - [0][1][1][0][RTW89_MKK][0] = 54, - [0][1][1][0][RTW89_IC][0] = 34, -- [0][1][1][0][RTW89_KCC][0] = 40, -+ [0][1][1][0][RTW89_KCC][0] = 60, - [0][1][1][0][RTW89_ACMA][0] = 54, - [0][1][1][0][RTW89_CN][0] = 46, - [0][1][1][0][RTW89_UK][0] = 54, -+ [0][1][1][0][RTW89_MEXICO][0] = 50, -+ [0][1][1][0][RTW89_UKRAINE][0] = 42, -+ [0][1][1][0][RTW89_CHILE][0] = 60, -+ [0][1][1][0][RTW89_QATAR][0] = 54, - [0][1][1][0][RTW89_FCC][2] = 60, - [0][1][1][0][RTW89_ETSI][2] = 54, - [0][1][1][0][RTW89_MKK][2] = 54, - [0][1][1][0][RTW89_IC][2] = 34, -- [0][1][1][0][RTW89_KCC][2] = 40, -+ [0][1][1][0][RTW89_KCC][2] = 60, - [0][1][1][0][RTW89_ACMA][2] = 54, - [0][1][1][0][RTW89_CN][2] = 46, - [0][1][1][0][RTW89_UK][2] = 54, -+ [0][1][1][0][RTW89_MEXICO][2] = 50, -+ [0][1][1][0][RTW89_UKRAINE][2] = 42, -+ [0][1][1][0][RTW89_CHILE][2] = 60, -+ [0][1][1][0][RTW89_QATAR][2] = 54, - [0][1][1][0][RTW89_FCC][4] = 60, - [0][1][1][0][RTW89_ETSI][4] = 54, - [0][1][1][0][RTW89_MKK][4] = 54, - [0][1][1][0][RTW89_IC][4] = 34, -- [0][1][1][0][RTW89_KCC][4] = 40, -+ [0][1][1][0][RTW89_KCC][4] = 60, - [0][1][1][0][RTW89_ACMA][4] = 54, - [0][1][1][0][RTW89_CN][4] = 46, - [0][1][1][0][RTW89_UK][4] = 54, -+ [0][1][1][0][RTW89_MEXICO][4] = 50, -+ [0][1][1][0][RTW89_UKRAINE][4] = 42, -+ [0][1][1][0][RTW89_CHILE][4] = 60, -+ [0][1][1][0][RTW89_QATAR][4] = 54, - [0][1][1][0][RTW89_FCC][6] = 60, - [0][1][1][0][RTW89_ETSI][6] = 54, - [0][1][1][0][RTW89_MKK][6] = 54, - [0][1][1][0][RTW89_IC][6] = 36, -- [0][1][1][0][RTW89_KCC][6] = 60, -+ [0][1][1][0][RTW89_KCC][6] = 40, - [0][1][1][0][RTW89_ACMA][6] = 54, - [0][1][1][0][RTW89_CN][6] = 46, - [0][1][1][0][RTW89_UK][6] = 54, -+ [0][1][1][0][RTW89_MEXICO][6] = 50, -+ [0][1][1][0][RTW89_UKRAINE][6] = 42, -+ [0][1][1][0][RTW89_CHILE][6] = 60, -+ [0][1][1][0][RTW89_QATAR][6] = 54, - [0][1][1][0][RTW89_FCC][8] = 62, - [0][1][1][0][RTW89_ETSI][8] = 54, - [0][1][1][0][RTW89_MKK][8] = 52, -@@ -30588,6 +31406,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][8] = 54, - [0][1][1][0][RTW89_CN][8] = 46, - [0][1][1][0][RTW89_UK][8] = 54, -+ [0][1][1][0][RTW89_MEXICO][8] = 62, -+ [0][1][1][0][RTW89_UKRAINE][8] = 42, -+ [0][1][1][0][RTW89_CHILE][8] = 62, -+ [0][1][1][0][RTW89_QATAR][8] = 54, - [0][1][1][0][RTW89_FCC][10] = 62, - [0][1][1][0][RTW89_ETSI][10] = 54, - [0][1][1][0][RTW89_MKK][10] = 54, -@@ -30596,6 +31418,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][10] = 54, - [0][1][1][0][RTW89_CN][10] = 46, - [0][1][1][0][RTW89_UK][10] = 54, -+ [0][1][1][0][RTW89_MEXICO][10] = 62, -+ [0][1][1][0][RTW89_UKRAINE][10] = 42, -+ [0][1][1][0][RTW89_CHILE][10] = 62, -+ [0][1][1][0][RTW89_QATAR][10] = 54, - [0][1][1][0][RTW89_FCC][12] = 62, - [0][1][1][0][RTW89_ETSI][12] = 54, - [0][1][1][0][RTW89_MKK][12] = 54, -@@ -30604,6 +31430,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][12] = 54, - [0][1][1][0][RTW89_CN][12] = 46, - [0][1][1][0][RTW89_UK][12] = 54, -+ [0][1][1][0][RTW89_MEXICO][12] = 62, -+ [0][1][1][0][RTW89_UKRAINE][12] = 42, -+ [0][1][1][0][RTW89_CHILE][12] = 62, -+ [0][1][1][0][RTW89_QATAR][12] = 54, - [0][1][1][0][RTW89_FCC][14] = 60, - [0][1][1][0][RTW89_ETSI][14] = 54, - [0][1][1][0][RTW89_MKK][14] = 54, -@@ -30612,6 +31442,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][14] = 54, - [0][1][1][0][RTW89_CN][14] = 46, - [0][1][1][0][RTW89_UK][14] = 54, -+ [0][1][1][0][RTW89_MEXICO][14] = 60, -+ [0][1][1][0][RTW89_UKRAINE][14] = 42, -+ [0][1][1][0][RTW89_CHILE][14] = 60, -+ [0][1][1][0][RTW89_QATAR][14] = 54, - [0][1][1][0][RTW89_FCC][15] = 60, - [0][1][1][0][RTW89_ETSI][15] = 54, - [0][1][1][0][RTW89_MKK][15] = 70, -@@ -30620,6 +31454,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][15] = 54, - [0][1][1][0][RTW89_CN][15] = 127, - [0][1][1][0][RTW89_UK][15] = 54, -+ [0][1][1][0][RTW89_MEXICO][15] = 60, -+ [0][1][1][0][RTW89_UKRAINE][15] = 42, -+ [0][1][1][0][RTW89_CHILE][15] = 60, -+ [0][1][1][0][RTW89_QATAR][15] = 54, - [0][1][1][0][RTW89_FCC][17] = 60, - [0][1][1][0][RTW89_ETSI][17] = 54, - [0][1][1][0][RTW89_MKK][17] = 70, -@@ -30628,6 +31466,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][17] = 54, - [0][1][1][0][RTW89_CN][17] = 127, - [0][1][1][0][RTW89_UK][17] = 54, -+ [0][1][1][0][RTW89_MEXICO][17] = 60, -+ [0][1][1][0][RTW89_UKRAINE][17] = 42, -+ [0][1][1][0][RTW89_CHILE][17] = 60, -+ [0][1][1][0][RTW89_QATAR][17] = 54, - [0][1][1][0][RTW89_FCC][19] = 60, - [0][1][1][0][RTW89_ETSI][19] = 54, - [0][1][1][0][RTW89_MKK][19] = 70, -@@ -30636,6 +31478,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][19] = 54, - [0][1][1][0][RTW89_CN][19] = 127, - [0][1][1][0][RTW89_UK][19] = 54, -+ [0][1][1][0][RTW89_MEXICO][19] = 60, -+ [0][1][1][0][RTW89_UKRAINE][19] = 42, -+ [0][1][1][0][RTW89_CHILE][19] = 60, -+ [0][1][1][0][RTW89_QATAR][19] = 54, - [0][1][1][0][RTW89_FCC][21] = 60, - [0][1][1][0][RTW89_ETSI][21] = 54, - [0][1][1][0][RTW89_MKK][21] = 70, -@@ -30644,6 +31490,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][21] = 54, - [0][1][1][0][RTW89_CN][21] = 127, - [0][1][1][0][RTW89_UK][21] = 54, -+ [0][1][1][0][RTW89_MEXICO][21] = 60, -+ [0][1][1][0][RTW89_UKRAINE][21] = 42, -+ [0][1][1][0][RTW89_CHILE][21] = 60, -+ [0][1][1][0][RTW89_QATAR][21] = 54, - [0][1][1][0][RTW89_FCC][23] = 60, - [0][1][1][0][RTW89_ETSI][23] = 54, - [0][1][1][0][RTW89_MKK][23] = 70, -@@ -30652,6 +31502,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][23] = 54, - [0][1][1][0][RTW89_CN][23] = 127, - [0][1][1][0][RTW89_UK][23] = 54, -+ [0][1][1][0][RTW89_MEXICO][23] = 60, -+ [0][1][1][0][RTW89_UKRAINE][23] = 42, -+ [0][1][1][0][RTW89_CHILE][23] = 60, -+ [0][1][1][0][RTW89_QATAR][23] = 54, - [0][1][1][0][RTW89_FCC][25] = 60, - [0][1][1][0][RTW89_ETSI][25] = 54, - [0][1][1][0][RTW89_MKK][25] = 70, -@@ -30660,6 +31514,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][25] = 127, - [0][1][1][0][RTW89_CN][25] = 127, - [0][1][1][0][RTW89_UK][25] = 54, -+ [0][1][1][0][RTW89_MEXICO][25] = 60, -+ [0][1][1][0][RTW89_UKRAINE][25] = 42, -+ [0][1][1][0][RTW89_CHILE][25] = 60, -+ [0][1][1][0][RTW89_QATAR][25] = 54, - [0][1][1][0][RTW89_FCC][27] = 60, - [0][1][1][0][RTW89_ETSI][27] = 54, - [0][1][1][0][RTW89_MKK][27] = 70, -@@ -30668,6 +31526,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][27] = 127, - [0][1][1][0][RTW89_CN][27] = 127, - [0][1][1][0][RTW89_UK][27] = 54, -+ [0][1][1][0][RTW89_MEXICO][27] = 60, -+ [0][1][1][0][RTW89_UKRAINE][27] = 42, -+ [0][1][1][0][RTW89_CHILE][27] = 52, -+ [0][1][1][0][RTW89_QATAR][27] = 54, - [0][1][1][0][RTW89_FCC][29] = 60, - [0][1][1][0][RTW89_ETSI][29] = 54, - [0][1][1][0][RTW89_MKK][29] = 70, -@@ -30676,6 +31538,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][29] = 127, - [0][1][1][0][RTW89_CN][29] = 127, - [0][1][1][0][RTW89_UK][29] = 54, -+ [0][1][1][0][RTW89_MEXICO][29] = 60, -+ [0][1][1][0][RTW89_UKRAINE][29] = 42, -+ [0][1][1][0][RTW89_CHILE][29] = 52, -+ [0][1][1][0][RTW89_QATAR][29] = 54, - [0][1][1][0][RTW89_FCC][31] = 60, - [0][1][1][0][RTW89_ETSI][31] = 54, - [0][1][1][0][RTW89_MKK][31] = 70, -@@ -30684,6 +31550,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][31] = 54, - [0][1][1][0][RTW89_CN][31] = 127, - [0][1][1][0][RTW89_UK][31] = 54, -+ [0][1][1][0][RTW89_MEXICO][31] = 60, -+ [0][1][1][0][RTW89_UKRAINE][31] = 42, -+ [0][1][1][0][RTW89_CHILE][31] = 52, -+ [0][1][1][0][RTW89_QATAR][31] = 54, - [0][1][1][0][RTW89_FCC][33] = 60, - [0][1][1][0][RTW89_ETSI][33] = 54, - [0][1][1][0][RTW89_MKK][33] = 70, -@@ -30692,6 +31562,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][33] = 54, - [0][1][1][0][RTW89_CN][33] = 127, - [0][1][1][0][RTW89_UK][33] = 54, -+ [0][1][1][0][RTW89_MEXICO][33] = 60, -+ [0][1][1][0][RTW89_UKRAINE][33] = 42, -+ [0][1][1][0][RTW89_CHILE][33] = 52, -+ [0][1][1][0][RTW89_QATAR][33] = 54, - [0][1][1][0][RTW89_FCC][35] = 52, - [0][1][1][0][RTW89_ETSI][35] = 54, - [0][1][1][0][RTW89_MKK][35] = 70, -@@ -30700,6 +31574,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][35] = 54, - [0][1][1][0][RTW89_CN][35] = 127, - [0][1][1][0][RTW89_UK][35] = 54, -+ [0][1][1][0][RTW89_MEXICO][35] = 52, -+ [0][1][1][0][RTW89_UKRAINE][35] = 42, -+ [0][1][1][0][RTW89_CHILE][35] = 52, -+ [0][1][1][0][RTW89_QATAR][35] = 54, - [0][1][1][0][RTW89_FCC][37] = 62, - [0][1][1][0][RTW89_ETSI][37] = 127, - [0][1][1][0][RTW89_MKK][37] = 70, -@@ -30708,6 +31586,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][37] = 64, - [0][1][1][0][RTW89_CN][37] = 127, - [0][1][1][0][RTW89_UK][37] = 52, -+ [0][1][1][0][RTW89_MEXICO][37] = 62, -+ [0][1][1][0][RTW89_UKRAINE][37] = 127, -+ [0][1][1][0][RTW89_CHILE][37] = 62, -+ [0][1][1][0][RTW89_QATAR][37] = 127, - [0][1][1][0][RTW89_FCC][38] = 72, - [0][1][1][0][RTW89_ETSI][38] = 18, - [0][1][1][0][RTW89_MKK][38] = 127, -@@ -30716,6 +31598,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][38] = 70, - [0][1][1][0][RTW89_CN][38] = 64, - [0][1][1][0][RTW89_UK][38] = 52, -+ [0][1][1][0][RTW89_MEXICO][38] = 72, -+ [0][1][1][0][RTW89_UKRAINE][38] = 18, -+ [0][1][1][0][RTW89_CHILE][38] = 70, -+ [0][1][1][0][RTW89_QATAR][38] = 18, - [0][1][1][0][RTW89_FCC][40] = 72, - [0][1][1][0][RTW89_ETSI][40] = 18, - [0][1][1][0][RTW89_MKK][40] = 127, -@@ -30724,6 +31610,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][40] = 70, - [0][1][1][0][RTW89_CN][40] = 64, - [0][1][1][0][RTW89_UK][40] = 52, -+ [0][1][1][0][RTW89_MEXICO][40] = 72, -+ [0][1][1][0][RTW89_UKRAINE][40] = 18, -+ [0][1][1][0][RTW89_CHILE][40] = 70, -+ [0][1][1][0][RTW89_QATAR][40] = 18, - [0][1][1][0][RTW89_FCC][42] = 72, - [0][1][1][0][RTW89_ETSI][42] = 18, - [0][1][1][0][RTW89_MKK][42] = 127, -@@ -30732,6 +31622,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][42] = 70, - [0][1][1][0][RTW89_CN][42] = 64, - [0][1][1][0][RTW89_UK][42] = 52, -+ [0][1][1][0][RTW89_MEXICO][42] = 72, -+ [0][1][1][0][RTW89_UKRAINE][42] = 18, -+ [0][1][1][0][RTW89_CHILE][42] = 70, -+ [0][1][1][0][RTW89_QATAR][42] = 18, - [0][1][1][0][RTW89_FCC][44] = 72, - [0][1][1][0][RTW89_ETSI][44] = 18, - [0][1][1][0][RTW89_MKK][44] = 127, -@@ -30740,6 +31634,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][44] = 70, - [0][1][1][0][RTW89_CN][44] = 60, - [0][1][1][0][RTW89_UK][44] = 52, -+ [0][1][1][0][RTW89_MEXICO][44] = 72, -+ [0][1][1][0][RTW89_UKRAINE][44] = 18, -+ [0][1][1][0][RTW89_CHILE][44] = 70, -+ [0][1][1][0][RTW89_QATAR][44] = 18, - [0][1][1][0][RTW89_FCC][46] = 72, - [0][1][1][0][RTW89_ETSI][46] = 18, - [0][1][1][0][RTW89_MKK][46] = 127, -@@ -30748,6 +31646,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][46] = 70, - [0][1][1][0][RTW89_CN][46] = 60, - [0][1][1][0][RTW89_UK][46] = 52, -+ [0][1][1][0][RTW89_MEXICO][46] = 72, -+ [0][1][1][0][RTW89_UKRAINE][46] = 18, -+ [0][1][1][0][RTW89_CHILE][46] = 70, -+ [0][1][1][0][RTW89_QATAR][46] = 18, - [0][1][1][0][RTW89_FCC][48] = 48, - [0][1][1][0][RTW89_ETSI][48] = 127, - [0][1][1][0][RTW89_MKK][48] = 127, -@@ -30756,6 +31658,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][48] = 127, - [0][1][1][0][RTW89_CN][48] = 127, - [0][1][1][0][RTW89_UK][48] = 127, -+ [0][1][1][0][RTW89_MEXICO][48] = 127, -+ [0][1][1][0][RTW89_UKRAINE][48] = 127, -+ [0][1][1][0][RTW89_CHILE][48] = 127, -+ [0][1][1][0][RTW89_QATAR][48] = 127, - [0][1][1][0][RTW89_FCC][50] = 48, - [0][1][1][0][RTW89_ETSI][50] = 127, - [0][1][1][0][RTW89_MKK][50] = 127, -@@ -30764,6 +31670,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][50] = 127, - [0][1][1][0][RTW89_CN][50] = 127, - [0][1][1][0][RTW89_UK][50] = 127, -+ [0][1][1][0][RTW89_MEXICO][50] = 127, -+ [0][1][1][0][RTW89_UKRAINE][50] = 127, -+ [0][1][1][0][RTW89_CHILE][50] = 127, -+ [0][1][1][0][RTW89_QATAR][50] = 127, - [0][1][1][0][RTW89_FCC][52] = 48, - [0][1][1][0][RTW89_ETSI][52] = 127, - [0][1][1][0][RTW89_MKK][52] = 127, -@@ -30772,38 +31682,58 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][52] = 127, - [0][1][1][0][RTW89_CN][52] = 127, - [0][1][1][0][RTW89_UK][52] = 127, -+ [0][1][1][0][RTW89_MEXICO][52] = 127, -+ [0][1][1][0][RTW89_UKRAINE][52] = 127, -+ [0][1][1][0][RTW89_CHILE][52] = 127, -+ [0][1][1][0][RTW89_QATAR][52] = 127, - [0][0][2][0][RTW89_FCC][0] = 70, - [0][0][2][0][RTW89_ETSI][0] = 66, - [0][0][2][0][RTW89_MKK][0] = 68, - [0][0][2][0][RTW89_IC][0] = 60, -- [0][0][2][0][RTW89_KCC][0] = 54, -+ [0][0][2][0][RTW89_KCC][0] = 68, - [0][0][2][0][RTW89_ACMA][0] = 66, - [0][0][2][0][RTW89_CN][0] = 52, - [0][0][2][0][RTW89_UK][0] = 66, -+ [0][0][2][0][RTW89_MEXICO][0] = 62, -+ [0][0][2][0][RTW89_UKRAINE][0] = 54, -+ [0][0][2][0][RTW89_CHILE][0] = 68, -+ [0][0][2][0][RTW89_QATAR][0] = 66, - [0][0][2][0][RTW89_FCC][2] = 72, - [0][0][2][0][RTW89_ETSI][2] = 66, - [0][0][2][0][RTW89_MKK][2] = 68, - [0][0][2][0][RTW89_IC][2] = 60, -- [0][0][2][0][RTW89_KCC][2] = 54, -+ [0][0][2][0][RTW89_KCC][2] = 68, - [0][0][2][0][RTW89_ACMA][2] = 66, - [0][0][2][0][RTW89_CN][2] = 52, - [0][0][2][0][RTW89_UK][2] = 66, -+ [0][0][2][0][RTW89_MEXICO][2] = 62, -+ [0][0][2][0][RTW89_UKRAINE][2] = 54, -+ [0][0][2][0][RTW89_CHILE][2] = 70, -+ [0][0][2][0][RTW89_QATAR][2] = 66, - [0][0][2][0][RTW89_FCC][4] = 72, - [0][0][2][0][RTW89_ETSI][4] = 66, - [0][0][2][0][RTW89_MKK][4] = 68, - [0][0][2][0][RTW89_IC][4] = 60, -- [0][0][2][0][RTW89_KCC][4] = 54, -+ [0][0][2][0][RTW89_KCC][4] = 68, - [0][0][2][0][RTW89_ACMA][4] = 66, - [0][0][2][0][RTW89_CN][4] = 52, - [0][0][2][0][RTW89_UK][4] = 66, -+ [0][0][2][0][RTW89_MEXICO][4] = 62, -+ [0][0][2][0][RTW89_UKRAINE][4] = 54, -+ [0][0][2][0][RTW89_CHILE][4] = 70, -+ [0][0][2][0][RTW89_QATAR][4] = 66, - [0][0][2][0][RTW89_FCC][6] = 72, - [0][0][2][0][RTW89_ETSI][6] = 66, - [0][0][2][0][RTW89_MKK][6] = 60, - [0][0][2][0][RTW89_IC][6] = 60, -- [0][0][2][0][RTW89_KCC][6] = 68, -+ [0][0][2][0][RTW89_KCC][6] = 54, - [0][0][2][0][RTW89_ACMA][6] = 66, - [0][0][2][0][RTW89_CN][6] = 52, - [0][0][2][0][RTW89_UK][6] = 66, -+ [0][0][2][0][RTW89_MEXICO][6] = 62, -+ [0][0][2][0][RTW89_UKRAINE][6] = 54, -+ [0][0][2][0][RTW89_CHILE][6] = 70, -+ [0][0][2][0][RTW89_QATAR][6] = 66, - [0][0][2][0][RTW89_FCC][8] = 72, - [0][0][2][0][RTW89_ETSI][8] = 66, - [0][0][2][0][RTW89_MKK][8] = 58, -@@ -30812,6 +31742,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][8] = 66, - [0][0][2][0][RTW89_CN][8] = 52, - [0][0][2][0][RTW89_UK][8] = 66, -+ [0][0][2][0][RTW89_MEXICO][8] = 72, -+ [0][0][2][0][RTW89_UKRAINE][8] = 54, -+ [0][0][2][0][RTW89_CHILE][8] = 70, -+ [0][0][2][0][RTW89_QATAR][8] = 66, - [0][0][2][0][RTW89_FCC][10] = 72, - [0][0][2][0][RTW89_ETSI][10] = 66, - [0][0][2][0][RTW89_MKK][10] = 70, -@@ -30820,6 +31754,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][10] = 66, - [0][0][2][0][RTW89_CN][10] = 52, - [0][0][2][0][RTW89_UK][10] = 66, -+ [0][0][2][0][RTW89_MEXICO][10] = 72, -+ [0][0][2][0][RTW89_UKRAINE][10] = 54, -+ [0][0][2][0][RTW89_CHILE][10] = 70, -+ [0][0][2][0][RTW89_QATAR][10] = 66, - [0][0][2][0][RTW89_FCC][12] = 72, - [0][0][2][0][RTW89_ETSI][12] = 66, - [0][0][2][0][RTW89_MKK][12] = 70, -@@ -30828,6 +31766,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][12] = 66, - [0][0][2][0][RTW89_CN][12] = 52, - [0][0][2][0][RTW89_UK][12] = 66, -+ [0][0][2][0][RTW89_MEXICO][12] = 72, -+ [0][0][2][0][RTW89_UKRAINE][12] = 54, -+ [0][0][2][0][RTW89_CHILE][12] = 70, -+ [0][0][2][0][RTW89_QATAR][12] = 66, - [0][0][2][0][RTW89_FCC][14] = 68, - [0][0][2][0][RTW89_ETSI][14] = 66, - [0][0][2][0][RTW89_MKK][14] = 70, -@@ -30836,6 +31778,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][14] = 66, - [0][0][2][0][RTW89_CN][14] = 52, - [0][0][2][0][RTW89_UK][14] = 66, -+ [0][0][2][0][RTW89_MEXICO][14] = 68, -+ [0][0][2][0][RTW89_UKRAINE][14] = 54, -+ [0][0][2][0][RTW89_CHILE][14] = 66, -+ [0][0][2][0][RTW89_QATAR][14] = 66, - [0][0][2][0][RTW89_FCC][15] = 70, - [0][0][2][0][RTW89_ETSI][15] = 66, - [0][0][2][0][RTW89_MKK][15] = 70, -@@ -30844,6 +31790,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][15] = 66, - [0][0][2][0][RTW89_CN][15] = 127, - [0][0][2][0][RTW89_UK][15] = 66, -+ [0][0][2][0][RTW89_MEXICO][15] = 70, -+ [0][0][2][0][RTW89_UKRAINE][15] = 54, -+ [0][0][2][0][RTW89_CHILE][15] = 68, -+ [0][0][2][0][RTW89_QATAR][15] = 66, - [0][0][2][0][RTW89_FCC][17] = 72, - [0][0][2][0][RTW89_ETSI][17] = 66, - [0][0][2][0][RTW89_MKK][17] = 70, -@@ -30852,6 +31802,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][17] = 66, - [0][0][2][0][RTW89_CN][17] = 127, - [0][0][2][0][RTW89_UK][17] = 66, -+ [0][0][2][0][RTW89_MEXICO][17] = 72, -+ [0][0][2][0][RTW89_UKRAINE][17] = 54, -+ [0][0][2][0][RTW89_CHILE][17] = 68, -+ [0][0][2][0][RTW89_QATAR][17] = 66, - [0][0][2][0][RTW89_FCC][19] = 72, - [0][0][2][0][RTW89_ETSI][19] = 66, - [0][0][2][0][RTW89_MKK][19] = 70, -@@ -30860,6 +31814,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][19] = 66, - [0][0][2][0][RTW89_CN][19] = 127, - [0][0][2][0][RTW89_UK][19] = 66, -+ [0][0][2][0][RTW89_MEXICO][19] = 72, -+ [0][0][2][0][RTW89_UKRAINE][19] = 54, -+ [0][0][2][0][RTW89_CHILE][19] = 68, -+ [0][0][2][0][RTW89_QATAR][19] = 66, - [0][0][2][0][RTW89_FCC][21] = 72, - [0][0][2][0][RTW89_ETSI][21] = 66, - [0][0][2][0][RTW89_MKK][21] = 70, -@@ -30868,6 +31826,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][21] = 66, - [0][0][2][0][RTW89_CN][21] = 127, - [0][0][2][0][RTW89_UK][21] = 66, -+ [0][0][2][0][RTW89_MEXICO][21] = 72, -+ [0][0][2][0][RTW89_UKRAINE][21] = 54, -+ [0][0][2][0][RTW89_CHILE][21] = 70, -+ [0][0][2][0][RTW89_QATAR][21] = 66, - [0][0][2][0][RTW89_FCC][23] = 72, - [0][0][2][0][RTW89_ETSI][23] = 66, - [0][0][2][0][RTW89_MKK][23] = 70, -@@ -30876,6 +31838,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][23] = 66, - [0][0][2][0][RTW89_CN][23] = 127, - [0][0][2][0][RTW89_UK][23] = 66, -+ [0][0][2][0][RTW89_MEXICO][23] = 72, -+ [0][0][2][0][RTW89_UKRAINE][23] = 54, -+ [0][0][2][0][RTW89_CHILE][23] = 70, -+ [0][0][2][0][RTW89_QATAR][23] = 66, - [0][0][2][0][RTW89_FCC][25] = 72, - [0][0][2][0][RTW89_ETSI][25] = 66, - [0][0][2][0][RTW89_MKK][25] = 70, -@@ -30884,6 +31850,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][25] = 127, - [0][0][2][0][RTW89_CN][25] = 127, - [0][0][2][0][RTW89_UK][25] = 66, -+ [0][0][2][0][RTW89_MEXICO][25] = 72, -+ [0][0][2][0][RTW89_UKRAINE][25] = 54, -+ [0][0][2][0][RTW89_CHILE][25] = 70, -+ [0][0][2][0][RTW89_QATAR][25] = 66, - [0][0][2][0][RTW89_FCC][27] = 72, - [0][0][2][0][RTW89_ETSI][27] = 66, - [0][0][2][0][RTW89_MKK][27] = 70, -@@ -30892,6 +31862,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][27] = 127, - [0][0][2][0][RTW89_CN][27] = 127, - [0][0][2][0][RTW89_UK][27] = 66, -+ [0][0][2][0][RTW89_MEXICO][27] = 72, -+ [0][0][2][0][RTW89_UKRAINE][27] = 54, -+ [0][0][2][0][RTW89_CHILE][27] = 56, -+ [0][0][2][0][RTW89_QATAR][27] = 66, - [0][0][2][0][RTW89_FCC][29] = 72, - [0][0][2][0][RTW89_ETSI][29] = 66, - [0][0][2][0][RTW89_MKK][29] = 70, -@@ -30900,6 +31874,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][29] = 127, - [0][0][2][0][RTW89_CN][29] = 127, - [0][0][2][0][RTW89_UK][29] = 66, -+ [0][0][2][0][RTW89_MEXICO][29] = 72, -+ [0][0][2][0][RTW89_UKRAINE][29] = 54, -+ [0][0][2][0][RTW89_CHILE][29] = 56, -+ [0][0][2][0][RTW89_QATAR][29] = 66, - [0][0][2][0][RTW89_FCC][31] = 72, - [0][0][2][0][RTW89_ETSI][31] = 66, - [0][0][2][0][RTW89_MKK][31] = 70, -@@ -30908,6 +31886,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][31] = 66, - [0][0][2][0][RTW89_CN][31] = 127, - [0][0][2][0][RTW89_UK][31] = 66, -+ [0][0][2][0][RTW89_MEXICO][31] = 72, -+ [0][0][2][0][RTW89_UKRAINE][31] = 54, -+ [0][0][2][0][RTW89_CHILE][31] = 56, -+ [0][0][2][0][RTW89_QATAR][31] = 66, - [0][0][2][0][RTW89_FCC][33] = 72, - [0][0][2][0][RTW89_ETSI][33] = 66, - [0][0][2][0][RTW89_MKK][33] = 70, -@@ -30916,6 +31898,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][33] = 66, - [0][0][2][0][RTW89_CN][33] = 127, - [0][0][2][0][RTW89_UK][33] = 66, -+ [0][0][2][0][RTW89_MEXICO][33] = 72, -+ [0][0][2][0][RTW89_UKRAINE][33] = 54, -+ [0][0][2][0][RTW89_CHILE][33] = 56, -+ [0][0][2][0][RTW89_QATAR][33] = 66, - [0][0][2][0][RTW89_FCC][35] = 56, - [0][0][2][0][RTW89_ETSI][35] = 66, - [0][0][2][0][RTW89_MKK][35] = 70, -@@ -30924,6 +31910,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][35] = 66, - [0][0][2][0][RTW89_CN][35] = 127, - [0][0][2][0][RTW89_UK][35] = 66, -+ [0][0][2][0][RTW89_MEXICO][35] = 56, -+ [0][0][2][0][RTW89_UKRAINE][35] = 54, -+ [0][0][2][0][RTW89_CHILE][35] = 56, -+ [0][0][2][0][RTW89_QATAR][35] = 66, - [0][0][2][0][RTW89_FCC][37] = 72, - [0][0][2][0][RTW89_ETSI][37] = 127, - [0][0][2][0][RTW89_MKK][37] = 70, -@@ -30932,6 +31922,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][37] = 70, - [0][0][2][0][RTW89_CN][37] = 127, - [0][0][2][0][RTW89_UK][37] = 64, -+ [0][0][2][0][RTW89_MEXICO][37] = 72, -+ [0][0][2][0][RTW89_UKRAINE][37] = 127, -+ [0][0][2][0][RTW89_CHILE][37] = 70, -+ [0][0][2][0][RTW89_QATAR][37] = 127, - [0][0][2][0][RTW89_FCC][38] = 72, - [0][0][2][0][RTW89_ETSI][38] = 30, - [0][0][2][0][RTW89_MKK][38] = 127, -@@ -30940,6 +31934,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][38] = 70, - [0][0][2][0][RTW89_CN][38] = 68, - [0][0][2][0][RTW89_UK][38] = 64, -+ [0][0][2][0][RTW89_MEXICO][38] = 72, -+ [0][0][2][0][RTW89_UKRAINE][38] = 30, -+ [0][0][2][0][RTW89_CHILE][38] = 70, -+ [0][0][2][0][RTW89_QATAR][38] = 30, - [0][0][2][0][RTW89_FCC][40] = 72, - [0][0][2][0][RTW89_ETSI][40] = 30, - [0][0][2][0][RTW89_MKK][40] = 127, -@@ -30948,6 +31946,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][40] = 70, - [0][0][2][0][RTW89_CN][40] = 68, - [0][0][2][0][RTW89_UK][40] = 64, -+ [0][0][2][0][RTW89_MEXICO][40] = 72, -+ [0][0][2][0][RTW89_UKRAINE][40] = 30, -+ [0][0][2][0][RTW89_CHILE][40] = 70, -+ [0][0][2][0][RTW89_QATAR][40] = 30, - [0][0][2][0][RTW89_FCC][42] = 72, - [0][0][2][0][RTW89_ETSI][42] = 30, - [0][0][2][0][RTW89_MKK][42] = 127, -@@ -30956,6 +31958,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][42] = 70, - [0][0][2][0][RTW89_CN][42] = 68, - [0][0][2][0][RTW89_UK][42] = 64, -+ [0][0][2][0][RTW89_MEXICO][42] = 72, -+ [0][0][2][0][RTW89_UKRAINE][42] = 30, -+ [0][0][2][0][RTW89_CHILE][42] = 70, -+ [0][0][2][0][RTW89_QATAR][42] = 30, - [0][0][2][0][RTW89_FCC][44] = 72, - [0][0][2][0][RTW89_ETSI][44] = 30, - [0][0][2][0][RTW89_MKK][44] = 127, -@@ -30964,6 +31970,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][44] = 70, - [0][0][2][0][RTW89_CN][44] = 68, - [0][0][2][0][RTW89_UK][44] = 64, -+ [0][0][2][0][RTW89_MEXICO][44] = 72, -+ [0][0][2][0][RTW89_UKRAINE][44] = 30, -+ [0][0][2][0][RTW89_CHILE][44] = 70, -+ [0][0][2][0][RTW89_QATAR][44] = 30, - [0][0][2][0][RTW89_FCC][46] = 72, - [0][0][2][0][RTW89_ETSI][46] = 30, - [0][0][2][0][RTW89_MKK][46] = 127, -@@ -30972,6 +31982,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][46] = 70, - [0][0][2][0][RTW89_CN][46] = 68, - [0][0][2][0][RTW89_UK][46] = 64, -+ [0][0][2][0][RTW89_MEXICO][46] = 72, -+ [0][0][2][0][RTW89_UKRAINE][46] = 30, -+ [0][0][2][0][RTW89_CHILE][46] = 70, -+ [0][0][2][0][RTW89_QATAR][46] = 30, - [0][0][2][0][RTW89_FCC][48] = 72, - [0][0][2][0][RTW89_ETSI][48] = 127, - [0][0][2][0][RTW89_MKK][48] = 127, -@@ -30980,6 +31994,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][48] = 127, - [0][0][2][0][RTW89_CN][48] = 127, - [0][0][2][0][RTW89_UK][48] = 127, -+ [0][0][2][0][RTW89_MEXICO][48] = 127, -+ [0][0][2][0][RTW89_UKRAINE][48] = 127, -+ [0][0][2][0][RTW89_CHILE][48] = 127, -+ [0][0][2][0][RTW89_QATAR][48] = 127, - [0][0][2][0][RTW89_FCC][50] = 72, - [0][0][2][0][RTW89_ETSI][50] = 127, - [0][0][2][0][RTW89_MKK][50] = 127, -@@ -30988,6 +32006,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][50] = 127, - [0][0][2][0][RTW89_CN][50] = 127, - [0][0][2][0][RTW89_UK][50] = 127, -+ [0][0][2][0][RTW89_MEXICO][50] = 127, -+ [0][0][2][0][RTW89_UKRAINE][50] = 127, -+ [0][0][2][0][RTW89_CHILE][50] = 127, -+ [0][0][2][0][RTW89_QATAR][50] = 127, - [0][0][2][0][RTW89_FCC][52] = 72, - [0][0][2][0][RTW89_ETSI][52] = 127, - [0][0][2][0][RTW89_MKK][52] = 127, -@@ -30996,38 +32018,58 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][52] = 127, - [0][0][2][0][RTW89_CN][52] = 127, - [0][0][2][0][RTW89_UK][52] = 127, -+ [0][0][2][0][RTW89_MEXICO][52] = 127, -+ [0][0][2][0][RTW89_UKRAINE][52] = 127, -+ [0][0][2][0][RTW89_CHILE][52] = 127, -+ [0][0][2][0][RTW89_QATAR][52] = 127, - [0][1][2][0][RTW89_FCC][0] = 60, - [0][1][2][0][RTW89_ETSI][0] = 54, - [0][1][2][0][RTW89_MKK][0] = 54, - [0][1][2][0][RTW89_IC][0] = 36, -- [0][1][2][0][RTW89_KCC][0] = 40, -+ [0][1][2][0][RTW89_KCC][0] = 64, - [0][1][2][0][RTW89_ACMA][0] = 54, - [0][1][2][0][RTW89_CN][0] = 40, - [0][1][2][0][RTW89_UK][0] = 54, -+ [0][1][2][0][RTW89_MEXICO][0] = 50, -+ [0][1][2][0][RTW89_UKRAINE][0] = 42, -+ [0][1][2][0][RTW89_CHILE][0] = 60, -+ [0][1][2][0][RTW89_QATAR][0] = 54, - [0][1][2][0][RTW89_FCC][2] = 62, - [0][1][2][0][RTW89_ETSI][2] = 54, - [0][1][2][0][RTW89_MKK][2] = 54, - [0][1][2][0][RTW89_IC][2] = 36, -- [0][1][2][0][RTW89_KCC][2] = 40, -+ [0][1][2][0][RTW89_KCC][2] = 64, - [0][1][2][0][RTW89_ACMA][2] = 54, - [0][1][2][0][RTW89_CN][2] = 40, - [0][1][2][0][RTW89_UK][2] = 54, -+ [0][1][2][0][RTW89_MEXICO][2] = 50, -+ [0][1][2][0][RTW89_UKRAINE][2] = 42, -+ [0][1][2][0][RTW89_CHILE][2] = 62, -+ [0][1][2][0][RTW89_QATAR][2] = 54, - [0][1][2][0][RTW89_FCC][4] = 62, - [0][1][2][0][RTW89_ETSI][4] = 54, - [0][1][2][0][RTW89_MKK][4] = 54, - [0][1][2][0][RTW89_IC][4] = 36, -- [0][1][2][0][RTW89_KCC][4] = 40, -+ [0][1][2][0][RTW89_KCC][4] = 64, - [0][1][2][0][RTW89_ACMA][4] = 54, - [0][1][2][0][RTW89_CN][4] = 40, - [0][1][2][0][RTW89_UK][4] = 54, -+ [0][1][2][0][RTW89_MEXICO][4] = 50, -+ [0][1][2][0][RTW89_UKRAINE][4] = 42, -+ [0][1][2][0][RTW89_CHILE][4] = 62, -+ [0][1][2][0][RTW89_QATAR][4] = 54, - [0][1][2][0][RTW89_FCC][6] = 62, - [0][1][2][0][RTW89_ETSI][6] = 54, - [0][1][2][0][RTW89_MKK][6] = 50, - [0][1][2][0][RTW89_IC][6] = 38, -- [0][1][2][0][RTW89_KCC][6] = 64, -+ [0][1][2][0][RTW89_KCC][6] = 40, - [0][1][2][0][RTW89_ACMA][6] = 54, - [0][1][2][0][RTW89_CN][6] = 40, - [0][1][2][0][RTW89_UK][6] = 54, -+ [0][1][2][0][RTW89_MEXICO][6] = 50, -+ [0][1][2][0][RTW89_UKRAINE][6] = 42, -+ [0][1][2][0][RTW89_CHILE][6] = 62, -+ [0][1][2][0][RTW89_QATAR][6] = 54, - [0][1][2][0][RTW89_FCC][8] = 62, - [0][1][2][0][RTW89_ETSI][8] = 54, - [0][1][2][0][RTW89_MKK][8] = 42, -@@ -31036,6 +32078,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][8] = 54, - [0][1][2][0][RTW89_CN][8] = 40, - [0][1][2][0][RTW89_UK][8] = 54, -+ [0][1][2][0][RTW89_MEXICO][8] = 62, -+ [0][1][2][0][RTW89_UKRAINE][8] = 42, -+ [0][1][2][0][RTW89_CHILE][8] = 62, -+ [0][1][2][0][RTW89_QATAR][8] = 54, - [0][1][2][0][RTW89_FCC][10] = 62, - [0][1][2][0][RTW89_ETSI][10] = 54, - [0][1][2][0][RTW89_MKK][10] = 54, -@@ -31044,6 +32090,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][10] = 54, - [0][1][2][0][RTW89_CN][10] = 40, - [0][1][2][0][RTW89_UK][10] = 54, -+ [0][1][2][0][RTW89_MEXICO][10] = 62, -+ [0][1][2][0][RTW89_UKRAINE][10] = 42, -+ [0][1][2][0][RTW89_CHILE][10] = 62, -+ [0][1][2][0][RTW89_QATAR][10] = 54, - [0][1][2][0][RTW89_FCC][12] = 62, - [0][1][2][0][RTW89_ETSI][12] = 54, - [0][1][2][0][RTW89_MKK][12] = 54, -@@ -31052,6 +32102,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][12] = 54, - [0][1][2][0][RTW89_CN][12] = 40, - [0][1][2][0][RTW89_UK][12] = 54, -+ [0][1][2][0][RTW89_MEXICO][12] = 62, -+ [0][1][2][0][RTW89_UKRAINE][12] = 42, -+ [0][1][2][0][RTW89_CHILE][12] = 62, -+ [0][1][2][0][RTW89_QATAR][12] = 54, - [0][1][2][0][RTW89_FCC][14] = 62, - [0][1][2][0][RTW89_ETSI][14] = 54, - [0][1][2][0][RTW89_MKK][14] = 54, -@@ -31060,6 +32114,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][14] = 54, - [0][1][2][0][RTW89_CN][14] = 40, - [0][1][2][0][RTW89_UK][14] = 54, -+ [0][1][2][0][RTW89_MEXICO][14] = 62, -+ [0][1][2][0][RTW89_UKRAINE][14] = 42, -+ [0][1][2][0][RTW89_CHILE][14] = 62, -+ [0][1][2][0][RTW89_QATAR][14] = 54, - [0][1][2][0][RTW89_FCC][15] = 60, - [0][1][2][0][RTW89_ETSI][15] = 54, - [0][1][2][0][RTW89_MKK][15] = 68, -@@ -31068,6 +32126,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][15] = 54, - [0][1][2][0][RTW89_CN][15] = 127, - [0][1][2][0][RTW89_UK][15] = 54, -+ [0][1][2][0][RTW89_MEXICO][15] = 60, -+ [0][1][2][0][RTW89_UKRAINE][15] = 42, -+ [0][1][2][0][RTW89_CHILE][15] = 60, -+ [0][1][2][0][RTW89_QATAR][15] = 54, - [0][1][2][0][RTW89_FCC][17] = 62, - [0][1][2][0][RTW89_ETSI][17] = 54, - [0][1][2][0][RTW89_MKK][17] = 68, -@@ -31076,6 +32138,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][17] = 54, - [0][1][2][0][RTW89_CN][17] = 127, - [0][1][2][0][RTW89_UK][17] = 54, -+ [0][1][2][0][RTW89_MEXICO][17] = 62, -+ [0][1][2][0][RTW89_UKRAINE][17] = 42, -+ [0][1][2][0][RTW89_CHILE][17] = 60, -+ [0][1][2][0][RTW89_QATAR][17] = 54, - [0][1][2][0][RTW89_FCC][19] = 62, - [0][1][2][0][RTW89_ETSI][19] = 54, - [0][1][2][0][RTW89_MKK][19] = 68, -@@ -31084,6 +32150,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][19] = 54, - [0][1][2][0][RTW89_CN][19] = 127, - [0][1][2][0][RTW89_UK][19] = 54, -+ [0][1][2][0][RTW89_MEXICO][19] = 62, -+ [0][1][2][0][RTW89_UKRAINE][19] = 42, -+ [0][1][2][0][RTW89_CHILE][19] = 62, -+ [0][1][2][0][RTW89_QATAR][19] = 54, - [0][1][2][0][RTW89_FCC][21] = 62, - [0][1][2][0][RTW89_ETSI][21] = 54, - [0][1][2][0][RTW89_MKK][21] = 68, -@@ -31092,6 +32162,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][21] = 54, - [0][1][2][0][RTW89_CN][21] = 127, - [0][1][2][0][RTW89_UK][21] = 54, -+ [0][1][2][0][RTW89_MEXICO][21] = 62, -+ [0][1][2][0][RTW89_UKRAINE][21] = 42, -+ [0][1][2][0][RTW89_CHILE][21] = 62, -+ [0][1][2][0][RTW89_QATAR][21] = 54, - [0][1][2][0][RTW89_FCC][23] = 62, - [0][1][2][0][RTW89_ETSI][23] = 54, - [0][1][2][0][RTW89_MKK][23] = 68, -@@ -31100,6 +32174,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][23] = 54, - [0][1][2][0][RTW89_CN][23] = 127, - [0][1][2][0][RTW89_UK][23] = 54, -+ [0][1][2][0][RTW89_MEXICO][23] = 62, -+ [0][1][2][0][RTW89_UKRAINE][23] = 42, -+ [0][1][2][0][RTW89_CHILE][23] = 62, -+ [0][1][2][0][RTW89_QATAR][23] = 54, - [0][1][2][0][RTW89_FCC][25] = 62, - [0][1][2][0][RTW89_ETSI][25] = 54, - [0][1][2][0][RTW89_MKK][25] = 68, -@@ -31108,6 +32186,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][25] = 127, - [0][1][2][0][RTW89_CN][25] = 127, - [0][1][2][0][RTW89_UK][25] = 54, -+ [0][1][2][0][RTW89_MEXICO][25] = 62, -+ [0][1][2][0][RTW89_UKRAINE][25] = 42, -+ [0][1][2][0][RTW89_CHILE][25] = 62, -+ [0][1][2][0][RTW89_QATAR][25] = 54, - [0][1][2][0][RTW89_FCC][27] = 62, - [0][1][2][0][RTW89_ETSI][27] = 54, - [0][1][2][0][RTW89_MKK][27] = 68, -@@ -31116,6 +32198,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][27] = 127, - [0][1][2][0][RTW89_CN][27] = 127, - [0][1][2][0][RTW89_UK][27] = 54, -+ [0][1][2][0][RTW89_MEXICO][27] = 62, -+ [0][1][2][0][RTW89_UKRAINE][27] = 42, -+ [0][1][2][0][RTW89_CHILE][27] = 46, -+ [0][1][2][0][RTW89_QATAR][27] = 54, - [0][1][2][0][RTW89_FCC][29] = 62, - [0][1][2][0][RTW89_ETSI][29] = 54, - [0][1][2][0][RTW89_MKK][29] = 68, -@@ -31124,6 +32210,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][29] = 127, - [0][1][2][0][RTW89_CN][29] = 127, - [0][1][2][0][RTW89_UK][29] = 54, -+ [0][1][2][0][RTW89_MEXICO][29] = 62, -+ [0][1][2][0][RTW89_UKRAINE][29] = 42, -+ [0][1][2][0][RTW89_CHILE][29] = 46, -+ [0][1][2][0][RTW89_QATAR][29] = 54, - [0][1][2][0][RTW89_FCC][31] = 62, - [0][1][2][0][RTW89_ETSI][31] = 54, - [0][1][2][0][RTW89_MKK][31] = 68, -@@ -31132,6 +32222,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][31] = 54, - [0][1][2][0][RTW89_CN][31] = 127, - [0][1][2][0][RTW89_UK][31] = 54, -+ [0][1][2][0][RTW89_MEXICO][31] = 62, -+ [0][1][2][0][RTW89_UKRAINE][31] = 42, -+ [0][1][2][0][RTW89_CHILE][31] = 46, -+ [0][1][2][0][RTW89_QATAR][31] = 54, - [0][1][2][0][RTW89_FCC][33] = 62, - [0][1][2][0][RTW89_ETSI][33] = 54, - [0][1][2][0][RTW89_MKK][33] = 68, -@@ -31140,6 +32234,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][33] = 54, - [0][1][2][0][RTW89_CN][33] = 127, - [0][1][2][0][RTW89_UK][33] = 54, -+ [0][1][2][0][RTW89_MEXICO][33] = 62, -+ [0][1][2][0][RTW89_UKRAINE][33] = 42, -+ [0][1][2][0][RTW89_CHILE][33] = 46, -+ [0][1][2][0][RTW89_QATAR][33] = 54, - [0][1][2][0][RTW89_FCC][35] = 46, - [0][1][2][0][RTW89_ETSI][35] = 54, - [0][1][2][0][RTW89_MKK][35] = 68, -@@ -31148,6 +32246,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][35] = 54, - [0][1][2][0][RTW89_CN][35] = 127, - [0][1][2][0][RTW89_UK][35] = 54, -+ [0][1][2][0][RTW89_MEXICO][35] = 46, -+ [0][1][2][0][RTW89_UKRAINE][35] = 42, -+ [0][1][2][0][RTW89_CHILE][35] = 46, -+ [0][1][2][0][RTW89_QATAR][35] = 54, - [0][1][2][0][RTW89_FCC][37] = 64, - [0][1][2][0][RTW89_ETSI][37] = 127, - [0][1][2][0][RTW89_MKK][37] = 68, -@@ -31156,6 +32258,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][37] = 64, - [0][1][2][0][RTW89_CN][37] = 127, - [0][1][2][0][RTW89_UK][37] = 52, -+ [0][1][2][0][RTW89_MEXICO][37] = 64, -+ [0][1][2][0][RTW89_UKRAINE][37] = 127, -+ [0][1][2][0][RTW89_CHILE][37] = 64, -+ [0][1][2][0][RTW89_QATAR][37] = 127, - [0][1][2][0][RTW89_FCC][38] = 72, - [0][1][2][0][RTW89_ETSI][38] = 18, - [0][1][2][0][RTW89_MKK][38] = 127, -@@ -31164,6 +32270,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][38] = 70, - [0][1][2][0][RTW89_CN][38] = 68, - [0][1][2][0][RTW89_UK][38] = 52, -+ [0][1][2][0][RTW89_MEXICO][38] = 72, -+ [0][1][2][0][RTW89_UKRAINE][38] = 18, -+ [0][1][2][0][RTW89_CHILE][38] = 70, -+ [0][1][2][0][RTW89_QATAR][38] = 18, - [0][1][2][0][RTW89_FCC][40] = 72, - [0][1][2][0][RTW89_ETSI][40] = 18, - [0][1][2][0][RTW89_MKK][40] = 127, -@@ -31172,6 +32282,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][40] = 70, - [0][1][2][0][RTW89_CN][40] = 68, - [0][1][2][0][RTW89_UK][40] = 52, -+ [0][1][2][0][RTW89_MEXICO][40] = 72, -+ [0][1][2][0][RTW89_UKRAINE][40] = 18, -+ [0][1][2][0][RTW89_CHILE][40] = 70, -+ [0][1][2][0][RTW89_QATAR][40] = 18, - [0][1][2][0][RTW89_FCC][42] = 72, - [0][1][2][0][RTW89_ETSI][42] = 18, - [0][1][2][0][RTW89_MKK][42] = 127, -@@ -31180,6 +32294,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][42] = 70, - [0][1][2][0][RTW89_CN][42] = 68, - [0][1][2][0][RTW89_UK][42] = 52, -+ [0][1][2][0][RTW89_MEXICO][42] = 72, -+ [0][1][2][0][RTW89_UKRAINE][42] = 18, -+ [0][1][2][0][RTW89_CHILE][42] = 70, -+ [0][1][2][0][RTW89_QATAR][42] = 18, - [0][1][2][0][RTW89_FCC][44] = 72, - [0][1][2][0][RTW89_ETSI][44] = 18, - [0][1][2][0][RTW89_MKK][44] = 127, -@@ -31188,6 +32306,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][44] = 70, - [0][1][2][0][RTW89_CN][44] = 68, - [0][1][2][0][RTW89_UK][44] = 52, -+ [0][1][2][0][RTW89_MEXICO][44] = 72, -+ [0][1][2][0][RTW89_UKRAINE][44] = 18, -+ [0][1][2][0][RTW89_CHILE][44] = 70, -+ [0][1][2][0][RTW89_QATAR][44] = 18, - [0][1][2][0][RTW89_FCC][46] = 72, - [0][1][2][0][RTW89_ETSI][46] = 18, - [0][1][2][0][RTW89_MKK][46] = 127, -@@ -31196,6 +32318,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][46] = 70, - [0][1][2][0][RTW89_CN][46] = 68, - [0][1][2][0][RTW89_UK][46] = 52, -+ [0][1][2][0][RTW89_MEXICO][46] = 72, -+ [0][1][2][0][RTW89_UKRAINE][46] = 18, -+ [0][1][2][0][RTW89_CHILE][46] = 70, -+ [0][1][2][0][RTW89_QATAR][46] = 18, - [0][1][2][0][RTW89_FCC][48] = 48, - [0][1][2][0][RTW89_ETSI][48] = 127, - [0][1][2][0][RTW89_MKK][48] = 127, -@@ -31204,6 +32330,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][48] = 127, - [0][1][2][0][RTW89_CN][48] = 127, - [0][1][2][0][RTW89_UK][48] = 127, -+ [0][1][2][0][RTW89_MEXICO][48] = 127, -+ [0][1][2][0][RTW89_UKRAINE][48] = 127, -+ [0][1][2][0][RTW89_CHILE][48] = 127, -+ [0][1][2][0][RTW89_QATAR][48] = 127, - [0][1][2][0][RTW89_FCC][50] = 50, - [0][1][2][0][RTW89_ETSI][50] = 127, - [0][1][2][0][RTW89_MKK][50] = 127, -@@ -31212,6 +32342,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][50] = 127, - [0][1][2][0][RTW89_CN][50] = 127, - [0][1][2][0][RTW89_UK][50] = 127, -+ [0][1][2][0][RTW89_MEXICO][50] = 127, -+ [0][1][2][0][RTW89_UKRAINE][50] = 127, -+ [0][1][2][0][RTW89_CHILE][50] = 127, -+ [0][1][2][0][RTW89_QATAR][50] = 127, - [0][1][2][0][RTW89_FCC][52] = 48, - [0][1][2][0][RTW89_ETSI][52] = 127, - [0][1][2][0][RTW89_MKK][52] = 127, -@@ -31220,38 +32354,58 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][0][RTW89_ACMA][52] = 127, - [0][1][2][0][RTW89_CN][52] = 127, - [0][1][2][0][RTW89_UK][52] = 127, -+ [0][1][2][0][RTW89_MEXICO][52] = 127, -+ [0][1][2][0][RTW89_UKRAINE][52] = 127, -+ [0][1][2][0][RTW89_CHILE][52] = 127, -+ [0][1][2][0][RTW89_QATAR][52] = 127, - [0][1][2][1][RTW89_FCC][0] = 60, - [0][1][2][1][RTW89_ETSI][0] = 40, - [0][1][2][1][RTW89_MKK][0] = 54, - [0][1][2][1][RTW89_IC][0] = 40, -- [0][1][2][1][RTW89_KCC][0] = 40, -+ [0][1][2][1][RTW89_KCC][0] = 64, - [0][1][2][1][RTW89_ACMA][0] = 40, - [0][1][2][1][RTW89_CN][0] = 36, - [0][1][2][1][RTW89_UK][0] = 40, -+ [0][1][2][1][RTW89_MEXICO][0] = 50, -+ [0][1][2][1][RTW89_UKRAINE][0] = 30, -+ [0][1][2][1][RTW89_CHILE][0] = 60, -+ [0][1][2][1][RTW89_QATAR][0] = 40, - [0][1][2][1][RTW89_FCC][2] = 62, - [0][1][2][1][RTW89_ETSI][2] = 40, - [0][1][2][1][RTW89_MKK][2] = 54, - [0][1][2][1][RTW89_IC][2] = 40, -- [0][1][2][1][RTW89_KCC][2] = 40, -+ [0][1][2][1][RTW89_KCC][2] = 64, - [0][1][2][1][RTW89_ACMA][2] = 40, - [0][1][2][1][RTW89_CN][2] = 36, - [0][1][2][1][RTW89_UK][2] = 40, -+ [0][1][2][1][RTW89_MEXICO][2] = 50, -+ [0][1][2][1][RTW89_UKRAINE][2] = 30, -+ [0][1][2][1][RTW89_CHILE][2] = 60, -+ [0][1][2][1][RTW89_QATAR][2] = 40, - [0][1][2][1][RTW89_FCC][4] = 62, - [0][1][2][1][RTW89_ETSI][4] = 40, - [0][1][2][1][RTW89_MKK][4] = 54, - [0][1][2][1][RTW89_IC][4] = 40, -- [0][1][2][1][RTW89_KCC][4] = 40, -+ [0][1][2][1][RTW89_KCC][4] = 64, - [0][1][2][1][RTW89_ACMA][4] = 40, - [0][1][2][1][RTW89_CN][4] = 36, - [0][1][2][1][RTW89_UK][4] = 40, -+ [0][1][2][1][RTW89_MEXICO][4] = 50, -+ [0][1][2][1][RTW89_UKRAINE][4] = 30, -+ [0][1][2][1][RTW89_CHILE][4] = 60, -+ [0][1][2][1][RTW89_QATAR][4] = 40, - [0][1][2][1][RTW89_FCC][6] = 62, - [0][1][2][1][RTW89_ETSI][6] = 40, - [0][1][2][1][RTW89_MKK][6] = 50, - [0][1][2][1][RTW89_IC][6] = 40, -- [0][1][2][1][RTW89_KCC][6] = 64, -+ [0][1][2][1][RTW89_KCC][6] = 40, - [0][1][2][1][RTW89_ACMA][6] = 40, - [0][1][2][1][RTW89_CN][6] = 36, - [0][1][2][1][RTW89_UK][6] = 40, -+ [0][1][2][1][RTW89_MEXICO][6] = 50, -+ [0][1][2][1][RTW89_UKRAINE][6] = 30, -+ [0][1][2][1][RTW89_CHILE][6] = 60, -+ [0][1][2][1][RTW89_QATAR][6] = 40, - [0][1][2][1][RTW89_FCC][8] = 62, - [0][1][2][1][RTW89_ETSI][8] = 40, - [0][1][2][1][RTW89_MKK][8] = 42, -@@ -31260,6 +32414,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][8] = 40, - [0][1][2][1][RTW89_CN][8] = 36, - [0][1][2][1][RTW89_UK][8] = 40, -+ [0][1][2][1][RTW89_MEXICO][8] = 62, -+ [0][1][2][1][RTW89_UKRAINE][8] = 30, -+ [0][1][2][1][RTW89_CHILE][8] = 60, -+ [0][1][2][1][RTW89_QATAR][8] = 40, - [0][1][2][1][RTW89_FCC][10] = 62, - [0][1][2][1][RTW89_ETSI][10] = 40, - [0][1][2][1][RTW89_MKK][10] = 54, -@@ -31268,6 +32426,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][10] = 40, - [0][1][2][1][RTW89_CN][10] = 36, - [0][1][2][1][RTW89_UK][10] = 40, -+ [0][1][2][1][RTW89_MEXICO][10] = 62, -+ [0][1][2][1][RTW89_UKRAINE][10] = 30, -+ [0][1][2][1][RTW89_CHILE][10] = 60, -+ [0][1][2][1][RTW89_QATAR][10] = 40, - [0][1][2][1][RTW89_FCC][12] = 62, - [0][1][2][1][RTW89_ETSI][12] = 40, - [0][1][2][1][RTW89_MKK][12] = 54, -@@ -31276,6 +32438,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][12] = 40, - [0][1][2][1][RTW89_CN][12] = 36, - [0][1][2][1][RTW89_UK][12] = 40, -+ [0][1][2][1][RTW89_MEXICO][12] = 62, -+ [0][1][2][1][RTW89_UKRAINE][12] = 30, -+ [0][1][2][1][RTW89_CHILE][12] = 60, -+ [0][1][2][1][RTW89_QATAR][12] = 40, - [0][1][2][1][RTW89_FCC][14] = 62, - [0][1][2][1][RTW89_ETSI][14] = 40, - [0][1][2][1][RTW89_MKK][14] = 54, -@@ -31284,6 +32450,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][14] = 40, - [0][1][2][1][RTW89_CN][14] = 36, - [0][1][2][1][RTW89_UK][14] = 40, -+ [0][1][2][1][RTW89_MEXICO][14] = 62, -+ [0][1][2][1][RTW89_UKRAINE][14] = 30, -+ [0][1][2][1][RTW89_CHILE][14] = 60, -+ [0][1][2][1][RTW89_QATAR][14] = 40, - [0][1][2][1][RTW89_FCC][15] = 60, - [0][1][2][1][RTW89_ETSI][15] = 40, - [0][1][2][1][RTW89_MKK][15] = 68, -@@ -31292,6 +32462,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][15] = 40, - [0][1][2][1][RTW89_CN][15] = 127, - [0][1][2][1][RTW89_UK][15] = 40, -+ [0][1][2][1][RTW89_MEXICO][15] = 60, -+ [0][1][2][1][RTW89_UKRAINE][15] = 30, -+ [0][1][2][1][RTW89_CHILE][15] = 60, -+ [0][1][2][1][RTW89_QATAR][15] = 40, - [0][1][2][1][RTW89_FCC][17] = 62, - [0][1][2][1][RTW89_ETSI][17] = 40, - [0][1][2][1][RTW89_MKK][17] = 68, -@@ -31300,6 +32474,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][17] = 40, - [0][1][2][1][RTW89_CN][17] = 127, - [0][1][2][1][RTW89_UK][17] = 40, -+ [0][1][2][1][RTW89_MEXICO][17] = 62, -+ [0][1][2][1][RTW89_UKRAINE][17] = 30, -+ [0][1][2][1][RTW89_CHILE][17] = 60, -+ [0][1][2][1][RTW89_QATAR][17] = 40, - [0][1][2][1][RTW89_FCC][19] = 62, - [0][1][2][1][RTW89_ETSI][19] = 40, - [0][1][2][1][RTW89_MKK][19] = 68, -@@ -31308,6 +32486,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][19] = 40, - [0][1][2][1][RTW89_CN][19] = 127, - [0][1][2][1][RTW89_UK][19] = 40, -+ [0][1][2][1][RTW89_MEXICO][19] = 62, -+ [0][1][2][1][RTW89_UKRAINE][19] = 30, -+ [0][1][2][1][RTW89_CHILE][19] = 60, -+ [0][1][2][1][RTW89_QATAR][19] = 40, - [0][1][2][1][RTW89_FCC][21] = 62, - [0][1][2][1][RTW89_ETSI][21] = 40, - [0][1][2][1][RTW89_MKK][21] = 68, -@@ -31316,6 +32498,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][21] = 40, - [0][1][2][1][RTW89_CN][21] = 127, - [0][1][2][1][RTW89_UK][21] = 40, -+ [0][1][2][1][RTW89_MEXICO][21] = 62, -+ [0][1][2][1][RTW89_UKRAINE][21] = 30, -+ [0][1][2][1][RTW89_CHILE][21] = 60, -+ [0][1][2][1][RTW89_QATAR][21] = 40, - [0][1][2][1][RTW89_FCC][23] = 62, - [0][1][2][1][RTW89_ETSI][23] = 40, - [0][1][2][1][RTW89_MKK][23] = 68, -@@ -31324,6 +32510,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][23] = 40, - [0][1][2][1][RTW89_CN][23] = 127, - [0][1][2][1][RTW89_UK][23] = 40, -+ [0][1][2][1][RTW89_MEXICO][23] = 62, -+ [0][1][2][1][RTW89_UKRAINE][23] = 30, -+ [0][1][2][1][RTW89_CHILE][23] = 60, -+ [0][1][2][1][RTW89_QATAR][23] = 40, - [0][1][2][1][RTW89_FCC][25] = 46, - [0][1][2][1][RTW89_ETSI][25] = 40, - [0][1][2][1][RTW89_MKK][25] = 68, -@@ -31332,6 +32522,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][25] = 127, - [0][1][2][1][RTW89_CN][25] = 127, - [0][1][2][1][RTW89_UK][25] = 40, -+ [0][1][2][1][RTW89_MEXICO][25] = 46, -+ [0][1][2][1][RTW89_UKRAINE][25] = 30, -+ [0][1][2][1][RTW89_CHILE][25] = 60, -+ [0][1][2][1][RTW89_QATAR][25] = 40, - [0][1][2][1][RTW89_FCC][27] = 46, - [0][1][2][1][RTW89_ETSI][27] = 40, - [0][1][2][1][RTW89_MKK][27] = 68, -@@ -31340,6 +32534,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][27] = 127, - [0][1][2][1][RTW89_CN][27] = 127, - [0][1][2][1][RTW89_UK][27] = 40, -+ [0][1][2][1][RTW89_MEXICO][27] = 46, -+ [0][1][2][1][RTW89_UKRAINE][27] = 30, -+ [0][1][2][1][RTW89_CHILE][27] = 46, -+ [0][1][2][1][RTW89_QATAR][27] = 40, - [0][1][2][1][RTW89_FCC][29] = 46, - [0][1][2][1][RTW89_ETSI][29] = 40, - [0][1][2][1][RTW89_MKK][29] = 68, -@@ -31348,6 +32546,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][29] = 127, - [0][1][2][1][RTW89_CN][29] = 127, - [0][1][2][1][RTW89_UK][29] = 40, -+ [0][1][2][1][RTW89_MEXICO][29] = 46, -+ [0][1][2][1][RTW89_UKRAINE][29] = 30, -+ [0][1][2][1][RTW89_CHILE][29] = 46, -+ [0][1][2][1][RTW89_QATAR][29] = 40, - [0][1][2][1][RTW89_FCC][31] = 46, - [0][1][2][1][RTW89_ETSI][31] = 40, - [0][1][2][1][RTW89_MKK][31] = 68, -@@ -31356,6 +32558,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][31] = 40, - [0][1][2][1][RTW89_CN][31] = 127, - [0][1][2][1][RTW89_UK][31] = 40, -+ [0][1][2][1][RTW89_MEXICO][31] = 46, -+ [0][1][2][1][RTW89_UKRAINE][31] = 30, -+ [0][1][2][1][RTW89_CHILE][31] = 46, -+ [0][1][2][1][RTW89_QATAR][31] = 40, - [0][1][2][1][RTW89_FCC][33] = 46, - [0][1][2][1][RTW89_ETSI][33] = 40, - [0][1][2][1][RTW89_MKK][33] = 68, -@@ -31364,6 +32570,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][33] = 40, - [0][1][2][1][RTW89_CN][33] = 127, - [0][1][2][1][RTW89_UK][33] = 40, -+ [0][1][2][1][RTW89_MEXICO][33] = 46, -+ [0][1][2][1][RTW89_UKRAINE][33] = 30, -+ [0][1][2][1][RTW89_CHILE][33] = 46, -+ [0][1][2][1][RTW89_QATAR][33] = 40, - [0][1][2][1][RTW89_FCC][35] = 46, - [0][1][2][1][RTW89_ETSI][35] = 40, - [0][1][2][1][RTW89_MKK][35] = 68, -@@ -31372,6 +32582,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][35] = 40, - [0][1][2][1][RTW89_CN][35] = 127, - [0][1][2][1][RTW89_UK][35] = 40, -+ [0][1][2][1][RTW89_MEXICO][35] = 46, -+ [0][1][2][1][RTW89_UKRAINE][35] = 30, -+ [0][1][2][1][RTW89_CHILE][35] = 46, -+ [0][1][2][1][RTW89_QATAR][35] = 40, - [0][1][2][1][RTW89_FCC][37] = 64, - [0][1][2][1][RTW89_ETSI][37] = 127, - [0][1][2][1][RTW89_MKK][37] = 68, -@@ -31380,6 +32594,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][37] = 64, - [0][1][2][1][RTW89_CN][37] = 127, - [0][1][2][1][RTW89_UK][37] = 40, -+ [0][1][2][1][RTW89_MEXICO][37] = 64, -+ [0][1][2][1][RTW89_UKRAINE][37] = 127, -+ [0][1][2][1][RTW89_CHILE][37] = 64, -+ [0][1][2][1][RTW89_QATAR][37] = 127, - [0][1][2][1][RTW89_FCC][38] = 72, - [0][1][2][1][RTW89_ETSI][38] = 6, - [0][1][2][1][RTW89_MKK][38] = 127, -@@ -31388,6 +32606,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][38] = 70, - [0][1][2][1][RTW89_CN][38] = 60, - [0][1][2][1][RTW89_UK][38] = 40, -+ [0][1][2][1][RTW89_MEXICO][38] = 72, -+ [0][1][2][1][RTW89_UKRAINE][38] = 6, -+ [0][1][2][1][RTW89_CHILE][38] = 60, -+ [0][1][2][1][RTW89_QATAR][38] = 6, - [0][1][2][1][RTW89_FCC][40] = 72, - [0][1][2][1][RTW89_ETSI][40] = 6, - [0][1][2][1][RTW89_MKK][40] = 127, -@@ -31396,6 +32618,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][40] = 70, - [0][1][2][1][RTW89_CN][40] = 60, - [0][1][2][1][RTW89_UK][40] = 40, -+ [0][1][2][1][RTW89_MEXICO][40] = 72, -+ [0][1][2][1][RTW89_UKRAINE][40] = 6, -+ [0][1][2][1][RTW89_CHILE][40] = 60, -+ [0][1][2][1][RTW89_QATAR][40] = 6, - [0][1][2][1][RTW89_FCC][42] = 72, - [0][1][2][1][RTW89_ETSI][42] = 6, - [0][1][2][1][RTW89_MKK][42] = 127, -@@ -31404,6 +32630,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][42] = 70, - [0][1][2][1][RTW89_CN][42] = 60, - [0][1][2][1][RTW89_UK][42] = 40, -+ [0][1][2][1][RTW89_MEXICO][42] = 72, -+ [0][1][2][1][RTW89_UKRAINE][42] = 6, -+ [0][1][2][1][RTW89_CHILE][42] = 60, -+ [0][1][2][1][RTW89_QATAR][42] = 6, - [0][1][2][1][RTW89_FCC][44] = 72, - [0][1][2][1][RTW89_ETSI][44] = 6, - [0][1][2][1][RTW89_MKK][44] = 127, -@@ -31412,6 +32642,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][44] = 70, - [0][1][2][1][RTW89_CN][44] = 54, - [0][1][2][1][RTW89_UK][44] = 40, -+ [0][1][2][1][RTW89_MEXICO][44] = 72, -+ [0][1][2][1][RTW89_UKRAINE][44] = 6, -+ [0][1][2][1][RTW89_CHILE][44] = 60, -+ [0][1][2][1][RTW89_QATAR][44] = 6, - [0][1][2][1][RTW89_FCC][46] = 72, - [0][1][2][1][RTW89_ETSI][46] = 6, - [0][1][2][1][RTW89_MKK][46] = 127, -@@ -31420,6 +32654,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][46] = 70, - [0][1][2][1][RTW89_CN][46] = 54, - [0][1][2][1][RTW89_UK][46] = 40, -+ [0][1][2][1][RTW89_MEXICO][46] = 72, -+ [0][1][2][1][RTW89_UKRAINE][46] = 6, -+ [0][1][2][1][RTW89_CHILE][46] = 60, -+ [0][1][2][1][RTW89_QATAR][46] = 6, - [0][1][2][1][RTW89_FCC][48] = 48, - [0][1][2][1][RTW89_ETSI][48] = 127, - [0][1][2][1][RTW89_MKK][48] = 127, -@@ -31428,6 +32666,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][48] = 127, - [0][1][2][1][RTW89_CN][48] = 127, - [0][1][2][1][RTW89_UK][48] = 127, -+ [0][1][2][1][RTW89_MEXICO][48] = 127, -+ [0][1][2][1][RTW89_UKRAINE][48] = 127, -+ [0][1][2][1][RTW89_CHILE][48] = 127, -+ [0][1][2][1][RTW89_QATAR][48] = 127, - [0][1][2][1][RTW89_FCC][50] = 50, - [0][1][2][1][RTW89_ETSI][50] = 127, - [0][1][2][1][RTW89_MKK][50] = 127, -@@ -31436,6 +32678,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][50] = 127, - [0][1][2][1][RTW89_CN][50] = 127, - [0][1][2][1][RTW89_UK][50] = 127, -+ [0][1][2][1][RTW89_MEXICO][50] = 127, -+ [0][1][2][1][RTW89_UKRAINE][50] = 127, -+ [0][1][2][1][RTW89_CHILE][50] = 127, -+ [0][1][2][1][RTW89_QATAR][50] = 127, - [0][1][2][1][RTW89_FCC][52] = 48, - [0][1][2][1][RTW89_ETSI][52] = 127, - [0][1][2][1][RTW89_MKK][52] = 127, -@@ -31444,22 +32690,34 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][52] = 127, - [0][1][2][1][RTW89_CN][52] = 127, - [0][1][2][1][RTW89_UK][52] = 127, -+ [0][1][2][1][RTW89_MEXICO][52] = 127, -+ [0][1][2][1][RTW89_UKRAINE][52] = 127, -+ [0][1][2][1][RTW89_CHILE][52] = 127, -+ [0][1][2][1][RTW89_QATAR][52] = 127, - [1][0][2][0][RTW89_FCC][1] = 64, - [1][0][2][0][RTW89_ETSI][1] = 66, - [1][0][2][0][RTW89_MKK][1] = 66, - [1][0][2][0][RTW89_IC][1] = 62, -- [1][0][2][0][RTW89_KCC][1] = 66, -+ [1][0][2][0][RTW89_KCC][1] = 54, - [1][0][2][0][RTW89_ACMA][1] = 66, - [1][0][2][0][RTW89_CN][1] = 54, - [1][0][2][0][RTW89_UK][1] = 66, -+ [1][0][2][0][RTW89_MEXICO][1] = 62, -+ [1][0][2][0][RTW89_UKRAINE][1] = 54, -+ [1][0][2][0][RTW89_CHILE][1] = 62, -+ [1][0][2][0][RTW89_QATAR][1] = 66, - [1][0][2][0][RTW89_FCC][5] = 68, - [1][0][2][0][RTW89_ETSI][5] = 66, - [1][0][2][0][RTW89_MKK][5] = 66, - [1][0][2][0][RTW89_IC][5] = 64, -- [1][0][2][0][RTW89_KCC][5] = 54, -+ [1][0][2][0][RTW89_KCC][5] = 66, - [1][0][2][0][RTW89_ACMA][5] = 66, - [1][0][2][0][RTW89_CN][5] = 54, - [1][0][2][0][RTW89_UK][5] = 66, -+ [1][0][2][0][RTW89_MEXICO][5] = 62, -+ [1][0][2][0][RTW89_UKRAINE][5] = 54, -+ [1][0][2][0][RTW89_CHILE][5] = 66, -+ [1][0][2][0][RTW89_QATAR][5] = 66, - [1][0][2][0][RTW89_FCC][9] = 68, - [1][0][2][0][RTW89_ETSI][9] = 66, - [1][0][2][0][RTW89_MKK][9] = 66, -@@ -31468,6 +32726,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][9] = 66, - [1][0][2][0][RTW89_CN][9] = 54, - [1][0][2][0][RTW89_UK][9] = 66, -+ [1][0][2][0][RTW89_MEXICO][9] = 68, -+ [1][0][2][0][RTW89_UKRAINE][9] = 54, -+ [1][0][2][0][RTW89_CHILE][9] = 66, -+ [1][0][2][0][RTW89_QATAR][9] = 66, - [1][0][2][0][RTW89_FCC][13] = 60, - [1][0][2][0][RTW89_ETSI][13] = 66, - [1][0][2][0][RTW89_MKK][13] = 66, -@@ -31476,6 +32738,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][13] = 66, - [1][0][2][0][RTW89_CN][13] = 54, - [1][0][2][0][RTW89_UK][13] = 66, -+ [1][0][2][0][RTW89_MEXICO][13] = 60, -+ [1][0][2][0][RTW89_UKRAINE][13] = 54, -+ [1][0][2][0][RTW89_CHILE][13] = 60, -+ [1][0][2][0][RTW89_QATAR][13] = 66, - [1][0][2][0][RTW89_FCC][16] = 64, - [1][0][2][0][RTW89_ETSI][16] = 66, - [1][0][2][0][RTW89_MKK][16] = 66, -@@ -31484,6 +32750,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][16] = 66, - [1][0][2][0][RTW89_CN][16] = 127, - [1][0][2][0][RTW89_UK][16] = 66, -+ [1][0][2][0][RTW89_MEXICO][16] = 64, -+ [1][0][2][0][RTW89_UKRAINE][16] = 54, -+ [1][0][2][0][RTW89_CHILE][16] = 64, -+ [1][0][2][0][RTW89_QATAR][16] = 66, - [1][0][2][0][RTW89_FCC][20] = 68, - [1][0][2][0][RTW89_ETSI][20] = 66, - [1][0][2][0][RTW89_MKK][20] = 66, -@@ -31492,6 +32762,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][20] = 66, - [1][0][2][0][RTW89_CN][20] = 127, - [1][0][2][0][RTW89_UK][20] = 66, -+ [1][0][2][0][RTW89_MEXICO][20] = 68, -+ [1][0][2][0][RTW89_UKRAINE][20] = 54, -+ [1][0][2][0][RTW89_CHILE][20] = 66, -+ [1][0][2][0][RTW89_QATAR][20] = 66, - [1][0][2][0][RTW89_FCC][24] = 68, - [1][0][2][0][RTW89_ETSI][24] = 66, - [1][0][2][0][RTW89_MKK][24] = 66, -@@ -31500,6 +32774,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][24] = 127, - [1][0][2][0][RTW89_CN][24] = 127, - [1][0][2][0][RTW89_UK][24] = 66, -+ [1][0][2][0][RTW89_MEXICO][24] = 68, -+ [1][0][2][0][RTW89_UKRAINE][24] = 54, -+ [1][0][2][0][RTW89_CHILE][24] = 66, -+ [1][0][2][0][RTW89_QATAR][24] = 66, - [1][0][2][0][RTW89_FCC][28] = 68, - [1][0][2][0][RTW89_ETSI][28] = 66, - [1][0][2][0][RTW89_MKK][28] = 66, -@@ -31508,6 +32786,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][28] = 127, - [1][0][2][0][RTW89_CN][28] = 127, - [1][0][2][0][RTW89_UK][28] = 66, -+ [1][0][2][0][RTW89_MEXICO][28] = 68, -+ [1][0][2][0][RTW89_UKRAINE][28] = 54, -+ [1][0][2][0][RTW89_CHILE][28] = 62, -+ [1][0][2][0][RTW89_QATAR][28] = 66, - [1][0][2][0][RTW89_FCC][32] = 62, - [1][0][2][0][RTW89_ETSI][32] = 66, - [1][0][2][0][RTW89_MKK][32] = 66, -@@ -31516,6 +32798,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][32] = 66, - [1][0][2][0][RTW89_CN][32] = 127, - [1][0][2][0][RTW89_UK][32] = 66, -+ [1][0][2][0][RTW89_MEXICO][32] = 62, -+ [1][0][2][0][RTW89_UKRAINE][32] = 54, -+ [1][0][2][0][RTW89_CHILE][32] = 62, -+ [1][0][2][0][RTW89_QATAR][32] = 66, - [1][0][2][0][RTW89_FCC][36] = 68, - [1][0][2][0][RTW89_ETSI][36] = 127, - [1][0][2][0][RTW89_MKK][36] = 66, -@@ -31524,6 +32810,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][36] = 66, - [1][0][2][0][RTW89_CN][36] = 127, - [1][0][2][0][RTW89_UK][36] = 64, -+ [1][0][2][0][RTW89_MEXICO][36] = 68, -+ [1][0][2][0][RTW89_UKRAINE][36] = 127, -+ [1][0][2][0][RTW89_CHILE][36] = 66, -+ [1][0][2][0][RTW89_QATAR][36] = 127, - [1][0][2][0][RTW89_FCC][39] = 68, - [1][0][2][0][RTW89_ETSI][39] = 30, - [1][0][2][0][RTW89_MKK][39] = 127, -@@ -31532,6 +32822,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][39] = 66, - [1][0][2][0][RTW89_CN][39] = 62, - [1][0][2][0][RTW89_UK][39] = 64, -+ [1][0][2][0][RTW89_MEXICO][39] = 68, -+ [1][0][2][0][RTW89_UKRAINE][39] = 30, -+ [1][0][2][0][RTW89_CHILE][39] = 66, -+ [1][0][2][0][RTW89_QATAR][39] = 30, - [1][0][2][0][RTW89_FCC][43] = 68, - [1][0][2][0][RTW89_ETSI][43] = 30, - [1][0][2][0][RTW89_MKK][43] = 127, -@@ -31540,6 +32834,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][43] = 66, - [1][0][2][0][RTW89_CN][43] = 66, - [1][0][2][0][RTW89_UK][43] = 64, -+ [1][0][2][0][RTW89_MEXICO][43] = 68, -+ [1][0][2][0][RTW89_UKRAINE][43] = 30, -+ [1][0][2][0][RTW89_CHILE][43] = 66, -+ [1][0][2][0][RTW89_QATAR][43] = 30, - [1][0][2][0][RTW89_FCC][47] = 68, - [1][0][2][0][RTW89_ETSI][47] = 127, - [1][0][2][0][RTW89_MKK][47] = 127, -@@ -31548,6 +32846,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][47] = 127, - [1][0][2][0][RTW89_CN][47] = 127, - [1][0][2][0][RTW89_UK][47] = 127, -+ [1][0][2][0][RTW89_MEXICO][47] = 127, -+ [1][0][2][0][RTW89_UKRAINE][47] = 127, -+ [1][0][2][0][RTW89_CHILE][47] = 127, -+ [1][0][2][0][RTW89_QATAR][47] = 127, - [1][0][2][0][RTW89_FCC][51] = 68, - [1][0][2][0][RTW89_ETSI][51] = 127, - [1][0][2][0][RTW89_MKK][51] = 127, -@@ -31556,6 +32858,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][51] = 127, - [1][0][2][0][RTW89_CN][51] = 127, - [1][0][2][0][RTW89_UK][51] = 127, -+ [1][0][2][0][RTW89_MEXICO][51] = 127, -+ [1][0][2][0][RTW89_UKRAINE][51] = 127, -+ [1][0][2][0][RTW89_CHILE][51] = 127, -+ [1][0][2][0][RTW89_QATAR][51] = 127, - [1][1][2][0][RTW89_FCC][1] = 54, - [1][1][2][0][RTW89_ETSI][1] = 54, - [1][1][2][0][RTW89_MKK][1] = 48, -@@ -31564,6 +32870,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][1] = 54, - [1][1][2][0][RTW89_CN][1] = 42, - [1][1][2][0][RTW89_UK][1] = 54, -+ [1][1][2][0][RTW89_MEXICO][1] = 50, -+ [1][1][2][0][RTW89_UKRAINE][1] = 42, -+ [1][1][2][0][RTW89_CHILE][1] = 54, -+ [1][1][2][0][RTW89_QATAR][1] = 54, - [1][1][2][0][RTW89_FCC][5] = 68, - [1][1][2][0][RTW89_ETSI][5] = 54, - [1][1][2][0][RTW89_MKK][5] = 52, -@@ -31572,6 +32882,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][5] = 54, - [1][1][2][0][RTW89_CN][5] = 42, - [1][1][2][0][RTW89_UK][5] = 54, -+ [1][1][2][0][RTW89_MEXICO][5] = 50, -+ [1][1][2][0][RTW89_UKRAINE][5] = 42, -+ [1][1][2][0][RTW89_CHILE][5] = 66, -+ [1][1][2][0][RTW89_QATAR][5] = 54, - [1][1][2][0][RTW89_FCC][9] = 68, - [1][1][2][0][RTW89_ETSI][9] = 54, - [1][1][2][0][RTW89_MKK][9] = 52, -@@ -31580,6 +32894,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][9] = 54, - [1][1][2][0][RTW89_CN][9] = 42, - [1][1][2][0][RTW89_UK][9] = 54, -+ [1][1][2][0][RTW89_MEXICO][9] = 68, -+ [1][1][2][0][RTW89_UKRAINE][9] = 42, -+ [1][1][2][0][RTW89_CHILE][9] = 66, -+ [1][1][2][0][RTW89_QATAR][9] = 54, - [1][1][2][0][RTW89_FCC][13] = 54, - [1][1][2][0][RTW89_ETSI][13] = 54, - [1][1][2][0][RTW89_MKK][13] = 52, -@@ -31588,6 +32906,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][13] = 54, - [1][1][2][0][RTW89_CN][13] = 42, - [1][1][2][0][RTW89_UK][13] = 54, -+ [1][1][2][0][RTW89_MEXICO][13] = 54, -+ [1][1][2][0][RTW89_UKRAINE][13] = 42, -+ [1][1][2][0][RTW89_CHILE][13] = 54, -+ [1][1][2][0][RTW89_QATAR][13] = 54, - [1][1][2][0][RTW89_FCC][16] = 56, - [1][1][2][0][RTW89_ETSI][16] = 54, - [1][1][2][0][RTW89_MKK][16] = 66, -@@ -31596,6 +32918,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][16] = 54, - [1][1][2][0][RTW89_CN][16] = 127, - [1][1][2][0][RTW89_UK][16] = 54, -+ [1][1][2][0][RTW89_MEXICO][16] = 56, -+ [1][1][2][0][RTW89_UKRAINE][16] = 42, -+ [1][1][2][0][RTW89_CHILE][16] = 54, -+ [1][1][2][0][RTW89_QATAR][16] = 54, - [1][1][2][0][RTW89_FCC][20] = 68, - [1][1][2][0][RTW89_ETSI][20] = 54, - [1][1][2][0][RTW89_MKK][20] = 66, -@@ -31604,6 +32930,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][20] = 54, - [1][1][2][0][RTW89_CN][20] = 127, - [1][1][2][0][RTW89_UK][20] = 54, -+ [1][1][2][0][RTW89_MEXICO][20] = 68, -+ [1][1][2][0][RTW89_UKRAINE][20] = 42, -+ [1][1][2][0][RTW89_CHILE][20] = 66, -+ [1][1][2][0][RTW89_QATAR][20] = 54, - [1][1][2][0][RTW89_FCC][24] = 68, - [1][1][2][0][RTW89_ETSI][24] = 54, - [1][1][2][0][RTW89_MKK][24] = 66, -@@ -31612,6 +32942,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][24] = 127, - [1][1][2][0][RTW89_CN][24] = 127, - [1][1][2][0][RTW89_UK][24] = 54, -+ [1][1][2][0][RTW89_MEXICO][24] = 68, -+ [1][1][2][0][RTW89_UKRAINE][24] = 42, -+ [1][1][2][0][RTW89_CHILE][24] = 66, -+ [1][1][2][0][RTW89_QATAR][24] = 54, - [1][1][2][0][RTW89_FCC][28] = 68, - [1][1][2][0][RTW89_ETSI][28] = 54, - [1][1][2][0][RTW89_MKK][28] = 66, -@@ -31620,6 +32954,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][28] = 127, - [1][1][2][0][RTW89_CN][28] = 127, - [1][1][2][0][RTW89_UK][28] = 54, -+ [1][1][2][0][RTW89_MEXICO][28] = 68, -+ [1][1][2][0][RTW89_UKRAINE][28] = 42, -+ [1][1][2][0][RTW89_CHILE][28] = 54, -+ [1][1][2][0][RTW89_QATAR][28] = 54, - [1][1][2][0][RTW89_FCC][32] = 56, - [1][1][2][0][RTW89_ETSI][32] = 54, - [1][1][2][0][RTW89_MKK][32] = 66, -@@ -31628,6 +32966,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][32] = 54, - [1][1][2][0][RTW89_CN][32] = 127, - [1][1][2][0][RTW89_UK][32] = 54, -+ [1][1][2][0][RTW89_MEXICO][32] = 56, -+ [1][1][2][0][RTW89_UKRAINE][32] = 42, -+ [1][1][2][0][RTW89_CHILE][32] = 54, -+ [1][1][2][0][RTW89_QATAR][32] = 54, - [1][1][2][0][RTW89_FCC][36] = 68, - [1][1][2][0][RTW89_ETSI][36] = 127, - [1][1][2][0][RTW89_MKK][36] = 66, -@@ -31636,6 +32978,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][36] = 66, - [1][1][2][0][RTW89_CN][36] = 127, - [1][1][2][0][RTW89_UK][36] = 52, -+ [1][1][2][0][RTW89_MEXICO][36] = 68, -+ [1][1][2][0][RTW89_UKRAINE][36] = 127, -+ [1][1][2][0][RTW89_CHILE][36] = 66, -+ [1][1][2][0][RTW89_QATAR][36] = 127, - [1][1][2][0][RTW89_FCC][39] = 68, - [1][1][2][0][RTW89_ETSI][39] = 18, - [1][1][2][0][RTW89_MKK][39] = 127, -@@ -31644,6 +32990,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][39] = 66, - [1][1][2][0][RTW89_CN][39] = 62, - [1][1][2][0][RTW89_UK][39] = 52, -+ [1][1][2][0][RTW89_MEXICO][39] = 68, -+ [1][1][2][0][RTW89_UKRAINE][39] = 18, -+ [1][1][2][0][RTW89_CHILE][39] = 66, -+ [1][1][2][0][RTW89_QATAR][39] = 18, - [1][1][2][0][RTW89_FCC][43] = 68, - [1][1][2][0][RTW89_ETSI][43] = 18, - [1][1][2][0][RTW89_MKK][43] = 127, -@@ -31652,6 +33002,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][43] = 66, - [1][1][2][0][RTW89_CN][43] = 66, - [1][1][2][0][RTW89_UK][43] = 52, -+ [1][1][2][0][RTW89_MEXICO][43] = 68, -+ [1][1][2][0][RTW89_UKRAINE][43] = 18, -+ [1][1][2][0][RTW89_CHILE][43] = 66, -+ [1][1][2][0][RTW89_QATAR][43] = 18, - [1][1][2][0][RTW89_FCC][47] = 62, - [1][1][2][0][RTW89_ETSI][47] = 127, - [1][1][2][0][RTW89_MKK][47] = 127, -@@ -31660,6 +33014,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][47] = 127, - [1][1][2][0][RTW89_CN][47] = 127, - [1][1][2][0][RTW89_UK][47] = 127, -+ [1][1][2][0][RTW89_MEXICO][47] = 127, -+ [1][1][2][0][RTW89_UKRAINE][47] = 127, -+ [1][1][2][0][RTW89_CHILE][47] = 127, -+ [1][1][2][0][RTW89_QATAR][47] = 127, - [1][1][2][0][RTW89_FCC][51] = 60, - [1][1][2][0][RTW89_ETSI][51] = 127, - [1][1][2][0][RTW89_MKK][51] = 127, -@@ -31668,6 +33026,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][0][RTW89_ACMA][51] = 127, - [1][1][2][0][RTW89_CN][51] = 127, - [1][1][2][0][RTW89_UK][51] = 127, -+ [1][1][2][0][RTW89_MEXICO][51] = 127, -+ [1][1][2][0][RTW89_UKRAINE][51] = 127, -+ [1][1][2][0][RTW89_CHILE][51] = 127, -+ [1][1][2][0][RTW89_QATAR][51] = 127, - [1][1][2][1][RTW89_FCC][1] = 54, - [1][1][2][1][RTW89_ETSI][1] = 40, - [1][1][2][1][RTW89_MKK][1] = 48, -@@ -31676,6 +33038,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][1] = 40, - [1][1][2][1][RTW89_CN][1] = 42, - [1][1][2][1][RTW89_UK][1] = 40, -+ [1][1][2][1][RTW89_MEXICO][1] = 50, -+ [1][1][2][1][RTW89_UKRAINE][1] = 30, -+ [1][1][2][1][RTW89_CHILE][1] = 54, -+ [1][1][2][1][RTW89_QATAR][1] = 40, - [1][1][2][1][RTW89_FCC][5] = 68, - [1][1][2][1][RTW89_ETSI][5] = 40, - [1][1][2][1][RTW89_MKK][5] = 52, -@@ -31684,6 +33050,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][5] = 40, - [1][1][2][1][RTW89_CN][5] = 42, - [1][1][2][1][RTW89_UK][5] = 40, -+ [1][1][2][1][RTW89_MEXICO][5] = 50, -+ [1][1][2][1][RTW89_UKRAINE][5] = 30, -+ [1][1][2][1][RTW89_CHILE][5] = 60, -+ [1][1][2][1][RTW89_QATAR][5] = 40, - [1][1][2][1][RTW89_FCC][9] = 68, - [1][1][2][1][RTW89_ETSI][9] = 40, - [1][1][2][1][RTW89_MKK][9] = 52, -@@ -31692,6 +33062,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][9] = 40, - [1][1][2][1][RTW89_CN][9] = 42, - [1][1][2][1][RTW89_UK][9] = 40, -+ [1][1][2][1][RTW89_MEXICO][9] = 68, -+ [1][1][2][1][RTW89_UKRAINE][9] = 30, -+ [1][1][2][1][RTW89_CHILE][9] = 60, -+ [1][1][2][1][RTW89_QATAR][9] = 40, - [1][1][2][1][RTW89_FCC][13] = 54, - [1][1][2][1][RTW89_ETSI][13] = 40, - [1][1][2][1][RTW89_MKK][13] = 52, -@@ -31700,6 +33074,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][13] = 40, - [1][1][2][1][RTW89_CN][13] = 42, - [1][1][2][1][RTW89_UK][13] = 40, -+ [1][1][2][1][RTW89_MEXICO][13] = 54, -+ [1][1][2][1][RTW89_UKRAINE][13] = 30, -+ [1][1][2][1][RTW89_CHILE][13] = 54, -+ [1][1][2][1][RTW89_QATAR][13] = 40, - [1][1][2][1][RTW89_FCC][16] = 56, - [1][1][2][1][RTW89_ETSI][16] = 40, - [1][1][2][1][RTW89_MKK][16] = 66, -@@ -31708,6 +33086,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][16] = 40, - [1][1][2][1][RTW89_CN][16] = 127, - [1][1][2][1][RTW89_UK][16] = 40, -+ [1][1][2][1][RTW89_MEXICO][16] = 56, -+ [1][1][2][1][RTW89_UKRAINE][16] = 30, -+ [1][1][2][1][RTW89_CHILE][16] = 54, -+ [1][1][2][1][RTW89_QATAR][16] = 40, - [1][1][2][1][RTW89_FCC][20] = 68, - [1][1][2][1][RTW89_ETSI][20] = 40, - [1][1][2][1][RTW89_MKK][20] = 66, -@@ -31716,6 +33098,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][20] = 40, - [1][1][2][1][RTW89_CN][20] = 127, - [1][1][2][1][RTW89_UK][20] = 40, -+ [1][1][2][1][RTW89_MEXICO][20] = 68, -+ [1][1][2][1][RTW89_UKRAINE][20] = 30, -+ [1][1][2][1][RTW89_CHILE][20] = 60, -+ [1][1][2][1][RTW89_QATAR][20] = 40, - [1][1][2][1][RTW89_FCC][24] = 68, - [1][1][2][1][RTW89_ETSI][24] = 40, - [1][1][2][1][RTW89_MKK][24] = 66, -@@ -31724,6 +33110,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][24] = 127, - [1][1][2][1][RTW89_CN][24] = 127, - [1][1][2][1][RTW89_UK][24] = 40, -+ [1][1][2][1][RTW89_MEXICO][24] = 68, -+ [1][1][2][1][RTW89_UKRAINE][24] = 30, -+ [1][1][2][1][RTW89_CHILE][24] = 60, -+ [1][1][2][1][RTW89_QATAR][24] = 40, - [1][1][2][1][RTW89_FCC][28] = 68, - [1][1][2][1][RTW89_ETSI][28] = 40, - [1][1][2][1][RTW89_MKK][28] = 66, -@@ -31732,6 +33122,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][28] = 127, - [1][1][2][1][RTW89_CN][28] = 127, - [1][1][2][1][RTW89_UK][28] = 40, -+ [1][1][2][1][RTW89_MEXICO][28] = 68, -+ [1][1][2][1][RTW89_UKRAINE][28] = 30, -+ [1][1][2][1][RTW89_CHILE][28] = 54, -+ [1][1][2][1][RTW89_QATAR][28] = 40, - [1][1][2][1][RTW89_FCC][32] = 56, - [1][1][2][1][RTW89_ETSI][32] = 40, - [1][1][2][1][RTW89_MKK][32] = 66, -@@ -31740,6 +33134,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][32] = 40, - [1][1][2][1][RTW89_CN][32] = 127, - [1][1][2][1][RTW89_UK][32] = 40, -+ [1][1][2][1][RTW89_MEXICO][32] = 56, -+ [1][1][2][1][RTW89_UKRAINE][32] = 30, -+ [1][1][2][1][RTW89_CHILE][32] = 54, -+ [1][1][2][1][RTW89_QATAR][32] = 40, - [1][1][2][1][RTW89_FCC][36] = 68, - [1][1][2][1][RTW89_ETSI][36] = 127, - [1][1][2][1][RTW89_MKK][36] = 66, -@@ -31748,6 +33146,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][36] = 66, - [1][1][2][1][RTW89_CN][36] = 127, - [1][1][2][1][RTW89_UK][36] = 40, -+ [1][1][2][1][RTW89_MEXICO][36] = 68, -+ [1][1][2][1][RTW89_UKRAINE][36] = 127, -+ [1][1][2][1][RTW89_CHILE][36] = 66, -+ [1][1][2][1][RTW89_QATAR][36] = 127, - [1][1][2][1][RTW89_FCC][39] = 68, - [1][1][2][1][RTW89_ETSI][39] = 6, - [1][1][2][1][RTW89_MKK][39] = 127, -@@ -31756,6 +33158,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][39] = 66, - [1][1][2][1][RTW89_CN][39] = 60, - [1][1][2][1][RTW89_UK][39] = 40, -+ [1][1][2][1][RTW89_MEXICO][39] = 68, -+ [1][1][2][1][RTW89_UKRAINE][39] = 6, -+ [1][1][2][1][RTW89_CHILE][39] = 60, -+ [1][1][2][1][RTW89_QATAR][39] = 6, - [1][1][2][1][RTW89_FCC][43] = 68, - [1][1][2][1][RTW89_ETSI][43] = 6, - [1][1][2][1][RTW89_MKK][43] = 127, -@@ -31764,6 +33170,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][43] = 66, - [1][1][2][1][RTW89_CN][43] = 52, - [1][1][2][1][RTW89_UK][43] = 40, -+ [1][1][2][1][RTW89_MEXICO][43] = 68, -+ [1][1][2][1][RTW89_UKRAINE][43] = 6, -+ [1][1][2][1][RTW89_CHILE][43] = 60, -+ [1][1][2][1][RTW89_QATAR][43] = 6, - [1][1][2][1][RTW89_FCC][47] = 62, - [1][1][2][1][RTW89_ETSI][47] = 127, - [1][1][2][1][RTW89_MKK][47] = 127, -@@ -31772,6 +33182,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][47] = 127, - [1][1][2][1][RTW89_CN][47] = 127, - [1][1][2][1][RTW89_UK][47] = 127, -+ [1][1][2][1][RTW89_MEXICO][47] = 127, -+ [1][1][2][1][RTW89_UKRAINE][47] = 127, -+ [1][1][2][1][RTW89_CHILE][47] = 127, -+ [1][1][2][1][RTW89_QATAR][47] = 127, - [1][1][2][1][RTW89_FCC][51] = 60, - [1][1][2][1][RTW89_ETSI][51] = 127, - [1][1][2][1][RTW89_MKK][51] = 127, -@@ -31780,6 +33194,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][51] = 127, - [1][1][2][1][RTW89_CN][51] = 127, - [1][1][2][1][RTW89_UK][51] = 127, -+ [1][1][2][1][RTW89_MEXICO][51] = 127, -+ [1][1][2][1][RTW89_UKRAINE][51] = 127, -+ [1][1][2][1][RTW89_CHILE][51] = 127, -+ [1][1][2][1][RTW89_QATAR][51] = 127, - [2][0][2][0][RTW89_FCC][3] = 58, - [2][0][2][0][RTW89_ETSI][3] = 60, - [2][0][2][0][RTW89_MKK][3] = 60, -@@ -31788,6 +33206,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][3] = 60, - [2][0][2][0][RTW89_CN][3] = 54, - [2][0][2][0][RTW89_UK][3] = 60, -+ [2][0][2][0][RTW89_MEXICO][3] = 58, -+ [2][0][2][0][RTW89_UKRAINE][3] = 54, -+ [2][0][2][0][RTW89_CHILE][3] = 58, -+ [2][0][2][0][RTW89_QATAR][3] = 60, - [2][0][2][0][RTW89_FCC][11] = 50, - [2][0][2][0][RTW89_ETSI][11] = 60, - [2][0][2][0][RTW89_MKK][11] = 60, -@@ -31796,6 +33218,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][11] = 60, - [2][0][2][0][RTW89_CN][11] = 54, - [2][0][2][0][RTW89_UK][11] = 60, -+ [2][0][2][0][RTW89_MEXICO][11] = 50, -+ [2][0][2][0][RTW89_UKRAINE][11] = 54, -+ [2][0][2][0][RTW89_CHILE][11] = 50, -+ [2][0][2][0][RTW89_QATAR][11] = 60, - [2][0][2][0][RTW89_FCC][18] = 60, - [2][0][2][0][RTW89_ETSI][18] = 60, - [2][0][2][0][RTW89_MKK][18] = 60, -@@ -31804,6 +33230,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][18] = 60, - [2][0][2][0][RTW89_CN][18] = 127, - [2][0][2][0][RTW89_UK][18] = 60, -+ [2][0][2][0][RTW89_MEXICO][18] = 60, -+ [2][0][2][0][RTW89_UKRAINE][18] = 54, -+ [2][0][2][0][RTW89_CHILE][18] = 60, -+ [2][0][2][0][RTW89_QATAR][18] = 60, - [2][0][2][0][RTW89_FCC][26] = 62, - [2][0][2][0][RTW89_ETSI][26] = 60, - [2][0][2][0][RTW89_MKK][26] = 60, -@@ -31812,6 +33242,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][26] = 127, - [2][0][2][0][RTW89_CN][26] = 127, - [2][0][2][0][RTW89_UK][26] = 60, -+ [2][0][2][0][RTW89_MEXICO][26] = 62, -+ [2][0][2][0][RTW89_UKRAINE][26] = 54, -+ [2][0][2][0][RTW89_CHILE][26] = 60, -+ [2][0][2][0][RTW89_QATAR][26] = 60, - [2][0][2][0][RTW89_FCC][34] = 62, - [2][0][2][0][RTW89_ETSI][34] = 127, - [2][0][2][0][RTW89_MKK][34] = 60, -@@ -31820,6 +33254,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][34] = 60, - [2][0][2][0][RTW89_CN][34] = 127, - [2][0][2][0][RTW89_UK][34] = 60, -+ [2][0][2][0][RTW89_MEXICO][34] = 62, -+ [2][0][2][0][RTW89_UKRAINE][34] = 127, -+ [2][0][2][0][RTW89_CHILE][34] = 60, -+ [2][0][2][0][RTW89_QATAR][34] = 127, - [2][0][2][0][RTW89_FCC][41] = 62, - [2][0][2][0][RTW89_ETSI][41] = 30, - [2][0][2][0][RTW89_MKK][41] = 127, -@@ -31828,6 +33266,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][41] = 60, - [2][0][2][0][RTW89_CN][41] = 62, - [2][0][2][0][RTW89_UK][41] = 60, -+ [2][0][2][0][RTW89_MEXICO][41] = 62, -+ [2][0][2][0][RTW89_UKRAINE][41] = 30, -+ [2][0][2][0][RTW89_CHILE][41] = 60, -+ [2][0][2][0][RTW89_QATAR][41] = 30, - [2][0][2][0][RTW89_FCC][49] = 62, - [2][0][2][0][RTW89_ETSI][49] = 127, - [2][0][2][0][RTW89_MKK][49] = 127, -@@ -31836,6 +33278,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_ACMA][49] = 127, - [2][0][2][0][RTW89_CN][49] = 127, - [2][0][2][0][RTW89_UK][49] = 127, -+ [2][0][2][0][RTW89_MEXICO][49] = 127, -+ [2][0][2][0][RTW89_UKRAINE][49] = 127, -+ [2][0][2][0][RTW89_CHILE][49] = 127, -+ [2][0][2][0][RTW89_QATAR][49] = 127, - [2][1][2][0][RTW89_FCC][3] = 48, - [2][1][2][0][RTW89_ETSI][3] = 54, - [2][1][2][0][RTW89_MKK][3] = 56, -@@ -31844,6 +33290,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][3] = 54, - [2][1][2][0][RTW89_CN][3] = 52, - [2][1][2][0][RTW89_UK][3] = 54, -+ [2][1][2][0][RTW89_MEXICO][3] = 48, -+ [2][1][2][0][RTW89_UKRAINE][3] = 42, -+ [2][1][2][0][RTW89_CHILE][3] = 46, -+ [2][1][2][0][RTW89_QATAR][3] = 54, - [2][1][2][0][RTW89_FCC][11] = 38, - [2][1][2][0][RTW89_ETSI][11] = 54, - [2][1][2][0][RTW89_MKK][11] = 54, -@@ -31852,6 +33302,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][11] = 54, - [2][1][2][0][RTW89_CN][11] = 52, - [2][1][2][0][RTW89_UK][11] = 54, -+ [2][1][2][0][RTW89_MEXICO][11] = 38, -+ [2][1][2][0][RTW89_UKRAINE][11] = 42, -+ [2][1][2][0][RTW89_CHILE][11] = 38, -+ [2][1][2][0][RTW89_QATAR][11] = 54, - [2][1][2][0][RTW89_FCC][18] = 50, - [2][1][2][0][RTW89_ETSI][18] = 54, - [2][1][2][0][RTW89_MKK][18] = 60, -@@ -31860,6 +33314,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][18] = 54, - [2][1][2][0][RTW89_CN][18] = 127, - [2][1][2][0][RTW89_UK][18] = 54, -+ [2][1][2][0][RTW89_MEXICO][18] = 50, -+ [2][1][2][0][RTW89_UKRAINE][18] = 42, -+ [2][1][2][0][RTW89_CHILE][18] = 50, -+ [2][1][2][0][RTW89_QATAR][18] = 54, - [2][1][2][0][RTW89_FCC][26] = 52, - [2][1][2][0][RTW89_ETSI][26] = 54, - [2][1][2][0][RTW89_MKK][26] = 56, -@@ -31868,6 +33326,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][26] = 127, - [2][1][2][0][RTW89_CN][26] = 127, - [2][1][2][0][RTW89_UK][26] = 54, -+ [2][1][2][0][RTW89_MEXICO][26] = 52, -+ [2][1][2][0][RTW89_UKRAINE][26] = 42, -+ [2][1][2][0][RTW89_CHILE][26] = 52, -+ [2][1][2][0][RTW89_QATAR][26] = 54, - [2][1][2][0][RTW89_FCC][34] = 62, - [2][1][2][0][RTW89_ETSI][34] = 127, - [2][1][2][0][RTW89_MKK][34] = 60, -@@ -31876,6 +33338,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][34] = 60, - [2][1][2][0][RTW89_CN][34] = 127, - [2][1][2][0][RTW89_UK][34] = 52, -+ [2][1][2][0][RTW89_MEXICO][34] = 62, -+ [2][1][2][0][RTW89_UKRAINE][34] = 127, -+ [2][1][2][0][RTW89_CHILE][34] = 60, -+ [2][1][2][0][RTW89_QATAR][34] = 127, - [2][1][2][0][RTW89_FCC][41] = 60, - [2][1][2][0][RTW89_ETSI][41] = 18, - [2][1][2][0][RTW89_MKK][41] = 127, -@@ -31884,6 +33350,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][41] = 58, - [2][1][2][0][RTW89_CN][41] = 62, - [2][1][2][0][RTW89_UK][41] = 52, -+ [2][1][2][0][RTW89_MEXICO][41] = 60, -+ [2][1][2][0][RTW89_UKRAINE][41] = 18, -+ [2][1][2][0][RTW89_CHILE][41] = 58, -+ [2][1][2][0][RTW89_QATAR][41] = 18, - [2][1][2][0][RTW89_FCC][49] = 62, - [2][1][2][0][RTW89_ETSI][49] = 127, - [2][1][2][0][RTW89_MKK][49] = 127, -@@ -31892,6 +33362,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][0][RTW89_ACMA][49] = 127, - [2][1][2][0][RTW89_CN][49] = 127, - [2][1][2][0][RTW89_UK][49] = 127, -+ [2][1][2][0][RTW89_MEXICO][49] = 127, -+ [2][1][2][0][RTW89_UKRAINE][49] = 127, -+ [2][1][2][0][RTW89_CHILE][49] = 127, -+ [2][1][2][0][RTW89_QATAR][49] = 127, - [2][1][2][1][RTW89_FCC][3] = 48, - [2][1][2][1][RTW89_ETSI][3] = 40, - [2][1][2][1][RTW89_MKK][3] = 56, -@@ -31900,6 +33374,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][3] = 40, - [2][1][2][1][RTW89_CN][3] = 42, - [2][1][2][1][RTW89_UK][3] = 40, -+ [2][1][2][1][RTW89_MEXICO][3] = 48, -+ [2][1][2][1][RTW89_UKRAINE][3] = 30, -+ [2][1][2][1][RTW89_CHILE][3] = 46, -+ [2][1][2][1][RTW89_QATAR][3] = 40, - [2][1][2][1][RTW89_FCC][11] = 38, - [2][1][2][1][RTW89_ETSI][11] = 40, - [2][1][2][1][RTW89_MKK][11] = 54, -@@ -31908,6 +33386,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][11] = 40, - [2][1][2][1][RTW89_CN][11] = 42, - [2][1][2][1][RTW89_UK][11] = 40, -+ [2][1][2][1][RTW89_MEXICO][11] = 38, -+ [2][1][2][1][RTW89_UKRAINE][11] = 30, -+ [2][1][2][1][RTW89_CHILE][11] = 38, -+ [2][1][2][1][RTW89_QATAR][11] = 40, - [2][1][2][1][RTW89_FCC][18] = 50, - [2][1][2][1][RTW89_ETSI][18] = 40, - [2][1][2][1][RTW89_MKK][18] = 60, -@@ -31916,6 +33398,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][18] = 40, - [2][1][2][1][RTW89_CN][18] = 127, - [2][1][2][1][RTW89_UK][18] = 40, -+ [2][1][2][1][RTW89_MEXICO][18] = 50, -+ [2][1][2][1][RTW89_UKRAINE][18] = 30, -+ [2][1][2][1][RTW89_CHILE][18] = 50, -+ [2][1][2][1][RTW89_QATAR][18] = 40, - [2][1][2][1][RTW89_FCC][26] = 52, - [2][1][2][1][RTW89_ETSI][26] = 42, - [2][1][2][1][RTW89_MKK][26] = 56, -@@ -31924,6 +33410,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][26] = 127, - [2][1][2][1][RTW89_CN][26] = 127, - [2][1][2][1][RTW89_UK][26] = 42, -+ [2][1][2][1][RTW89_MEXICO][26] = 52, -+ [2][1][2][1][RTW89_UKRAINE][26] = 30, -+ [2][1][2][1][RTW89_CHILE][26] = 52, -+ [2][1][2][1][RTW89_QATAR][26] = 42, - [2][1][2][1][RTW89_FCC][34] = 62, - [2][1][2][1][RTW89_ETSI][34] = 127, - [2][1][2][1][RTW89_MKK][34] = 60, -@@ -31932,6 +33422,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][34] = 60, - [2][1][2][1][RTW89_CN][34] = 127, - [2][1][2][1][RTW89_UK][34] = 40, -+ [2][1][2][1][RTW89_MEXICO][34] = 62, -+ [2][1][2][1][RTW89_UKRAINE][34] = 127, -+ [2][1][2][1][RTW89_CHILE][34] = 60, -+ [2][1][2][1][RTW89_QATAR][34] = 127, - [2][1][2][1][RTW89_FCC][41] = 60, - [2][1][2][1][RTW89_ETSI][41] = 6, - [2][1][2][1][RTW89_MKK][41] = 127, -@@ -31940,6 +33434,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][41] = 58, - [2][1][2][1][RTW89_CN][41] = 40, - [2][1][2][1][RTW89_UK][41] = 40, -+ [2][1][2][1][RTW89_MEXICO][41] = 60, -+ [2][1][2][1][RTW89_UKRAINE][41] = 6, -+ [2][1][2][1][RTW89_CHILE][41] = 58, -+ [2][1][2][1][RTW89_QATAR][41] = 6, - [2][1][2][1][RTW89_FCC][49] = 62, - [2][1][2][1][RTW89_ETSI][49] = 127, - [2][1][2][1][RTW89_MKK][49] = 127, -@@ -31948,6 +33446,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [2][1][2][1][RTW89_ACMA][49] = 127, - [2][1][2][1][RTW89_CN][49] = 127, - [2][1][2][1][RTW89_UK][49] = 127, -+ [2][1][2][1][RTW89_MEXICO][49] = 127, -+ [2][1][2][1][RTW89_UKRAINE][49] = 127, -+ [2][1][2][1][RTW89_CHILE][49] = 127, -+ [2][1][2][1][RTW89_QATAR][49] = 127, - [3][0][2][0][RTW89_FCC][7] = 40, - [3][0][2][0][RTW89_ETSI][7] = 50, - [3][0][2][0][RTW89_MKK][7] = 50, -@@ -31956,6 +33458,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][0][2][0][RTW89_ACMA][7] = 127, - [3][0][2][0][RTW89_CN][7] = 66, - [3][0][2][0][RTW89_UK][7] = 127, -+ [3][0][2][0][RTW89_MEXICO][7] = 127, -+ [3][0][2][0][RTW89_UKRAINE][7] = 50, -+ [3][0][2][0][RTW89_CHILE][7] = 40, -+ [3][0][2][0][RTW89_QATAR][7] = 50, - [3][0][2][0][RTW89_FCC][22] = 42, - [3][0][2][0][RTW89_ETSI][22] = 50, - [3][0][2][0][RTW89_MKK][22] = 50, -@@ -31964,6 +33470,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][0][2][0][RTW89_ACMA][22] = 127, - [3][0][2][0][RTW89_CN][22] = 66, - [3][0][2][0][RTW89_UK][22] = 127, -+ [3][0][2][0][RTW89_MEXICO][22] = 127, -+ [3][0][2][0][RTW89_UKRAINE][22] = 50, -+ [3][0][2][0][RTW89_CHILE][22] = 42, -+ [3][0][2][0][RTW89_QATAR][22] = 50, - [3][0][2][0][RTW89_FCC][45] = 52, - [3][0][2][0][RTW89_ETSI][45] = 127, - [3][0][2][0][RTW89_MKK][45] = 127, -@@ -31972,6 +33482,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][0][2][0][RTW89_ACMA][45] = 127, - [3][0][2][0][RTW89_CN][45] = 127, - [3][0][2][0][RTW89_UK][45] = 127, -+ [3][0][2][0][RTW89_MEXICO][45] = 127, -+ [3][0][2][0][RTW89_UKRAINE][45] = 127, -+ [3][0][2][0][RTW89_CHILE][45] = 127, -+ [3][0][2][0][RTW89_QATAR][45] = 127, - [3][1][2][0][RTW89_FCC][7] = 32, - [3][1][2][0][RTW89_ETSI][7] = 50, - [3][1][2][0][RTW89_MKK][7] = 36, -@@ -31980,6 +33494,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][0][RTW89_ACMA][7] = 127, - [3][1][2][0][RTW89_CN][7] = 54, - [3][1][2][0][RTW89_UK][7] = 127, -+ [3][1][2][0][RTW89_MEXICO][7] = 127, -+ [3][1][2][0][RTW89_UKRAINE][7] = 50, -+ [3][1][2][0][RTW89_CHILE][7] = 32, -+ [3][1][2][0][RTW89_QATAR][7] = 50, - [3][1][2][0][RTW89_FCC][22] = 36, - [3][1][2][0][RTW89_ETSI][22] = 50, - [3][1][2][0][RTW89_MKK][22] = 48, -@@ -31988,6 +33506,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][0][RTW89_ACMA][22] = 127, - [3][1][2][0][RTW89_CN][22] = 54, - [3][1][2][0][RTW89_UK][22] = 127, -+ [3][1][2][0][RTW89_MEXICO][22] = 127, -+ [3][1][2][0][RTW89_UKRAINE][22] = 50, -+ [3][1][2][0][RTW89_CHILE][22] = 36, -+ [3][1][2][0][RTW89_QATAR][22] = 50, - [3][1][2][0][RTW89_FCC][45] = 46, - [3][1][2][0][RTW89_ETSI][45] = 127, - [3][1][2][0][RTW89_MKK][45] = 127, -@@ -31996,6 +33518,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][0][RTW89_ACMA][45] = 127, - [3][1][2][0][RTW89_CN][45] = 127, - [3][1][2][0][RTW89_UK][45] = 127, -+ [3][1][2][0][RTW89_MEXICO][45] = 127, -+ [3][1][2][0][RTW89_UKRAINE][45] = 127, -+ [3][1][2][0][RTW89_CHILE][45] = 127, -+ [3][1][2][0][RTW89_QATAR][45] = 127, - [3][1][2][1][RTW89_FCC][7] = 32, - [3][1][2][1][RTW89_ETSI][7] = 42, - [3][1][2][1][RTW89_MKK][7] = 36, -@@ -32004,6 +33530,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_ACMA][7] = 127, - [3][1][2][1][RTW89_CN][7] = 42, - [3][1][2][1][RTW89_UK][7] = 127, -+ [3][1][2][1][RTW89_MEXICO][7] = 127, -+ [3][1][2][1][RTW89_UKRAINE][7] = 42, -+ [3][1][2][1][RTW89_CHILE][7] = 32, -+ [3][1][2][1][RTW89_QATAR][7] = 42, - [3][1][2][1][RTW89_FCC][22] = 36, - [3][1][2][1][RTW89_ETSI][22] = 42, - [3][1][2][1][RTW89_MKK][22] = 48, -@@ -32012,6 +33542,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_ACMA][22] = 127, - [3][1][2][1][RTW89_CN][22] = 42, - [3][1][2][1][RTW89_UK][22] = 127, -+ [3][1][2][1][RTW89_MEXICO][22] = 127, -+ [3][1][2][1][RTW89_UKRAINE][22] = 42, -+ [3][1][2][1][RTW89_CHILE][22] = 36, -+ [3][1][2][1][RTW89_QATAR][22] = 42, - [3][1][2][1][RTW89_FCC][45] = 46, - [3][1][2][1][RTW89_ETSI][45] = 127, - [3][1][2][1][RTW89_MKK][45] = 127, -@@ -32020,6 +33554,10 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_ACMA][45] = 127, - [3][1][2][1][RTW89_CN][45] = 127, - [3][1][2][1][RTW89_UK][45] = 127, -+ [3][1][2][1][RTW89_MEXICO][45] = 127, -+ [3][1][2][1][RTW89_UKRAINE][45] = 127, -+ [3][1][2][1][RTW89_CHILE][45] = 127, -+ [3][1][2][1][RTW89_QATAR][45] = 127, - }; - - static -@@ -34017,10 +35555,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [1][0][RTW89_WW][3] = 44, - [1][0][RTW89_WW][4] = 44, - [1][0][RTW89_WW][5] = 44, -- [1][0][RTW89_WW][6] = 44, -- [1][0][RTW89_WW][7] = 44, -- [1][0][RTW89_WW][8] = 44, -- [1][0][RTW89_WW][9] = 44, -+ [1][0][RTW89_WW][6] = 40, -+ [1][0][RTW89_WW][7] = 40, -+ [1][0][RTW89_WW][8] = 40, -+ [1][0][RTW89_WW][9] = 40, - [1][0][RTW89_WW][10] = 44, - [1][0][RTW89_WW][11] = 36, - [1][0][RTW89_WW][12] = 4, -@@ -34031,24 +35569,24 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [1][1][RTW89_WW][3] = 32, - [1][1][RTW89_WW][4] = 32, - [1][1][RTW89_WW][5] = 32, -- [1][1][RTW89_WW][6] = 32, -- [1][1][RTW89_WW][7] = 32, -- [1][1][RTW89_WW][8] = 32, -- [1][1][RTW89_WW][9] = 32, -+ [1][1][RTW89_WW][6] = 30, -+ [1][1][RTW89_WW][7] = 30, -+ [1][1][RTW89_WW][8] = 30, -+ [1][1][RTW89_WW][9] = 30, - [1][1][RTW89_WW][10] = 32, - [1][1][RTW89_WW][11] = 30, - [1][1][RTW89_WW][12] = -6, - [1][1][RTW89_WW][13] = 0, - [2][0][RTW89_WW][0] = 56, -- [2][0][RTW89_WW][1] = 56, -- [2][0][RTW89_WW][2] = 56, -- [2][0][RTW89_WW][3] = 56, -- [2][0][RTW89_WW][4] = 56, -+ [2][0][RTW89_WW][1] = 54, -+ [2][0][RTW89_WW][2] = 54, -+ [2][0][RTW89_WW][3] = 54, -+ [2][0][RTW89_WW][4] = 54, - [2][0][RTW89_WW][5] = 56, -- [2][0][RTW89_WW][6] = 56, -- [2][0][RTW89_WW][7] = 56, -- [2][0][RTW89_WW][8] = 56, -- [2][0][RTW89_WW][9] = 56, -+ [2][0][RTW89_WW][6] = 48, -+ [2][0][RTW89_WW][7] = 48, -+ [2][0][RTW89_WW][8] = 48, -+ [2][0][RTW89_WW][9] = 48, - [2][0][RTW89_WW][10] = 56, - [2][0][RTW89_WW][11] = 48, - [2][0][RTW89_WW][12] = 16, -@@ -34059,10 +35597,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [2][1][RTW89_WW][3] = 44, - [2][1][RTW89_WW][4] = 44, - [2][1][RTW89_WW][5] = 44, -- [2][1][RTW89_WW][6] = 44, -- [2][1][RTW89_WW][7] = 44, -- [2][1][RTW89_WW][8] = 44, -- [2][1][RTW89_WW][9] = 44, -+ [2][1][RTW89_WW][6] = 42, -+ [2][1][RTW89_WW][7] = 42, -+ [2][1][RTW89_WW][8] = 42, -+ [2][1][RTW89_WW][9] = 42, - [2][1][RTW89_WW][10] = 44, - [2][1][RTW89_WW][11] = 44, - [2][1][RTW89_WW][12] = 6, -@@ -34075,6 +35613,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][0][RTW89_ACMA][0] = 34, - [0][0][RTW89_CN][0] = 32, - [0][0][RTW89_UK][0] = 34, -+ [0][0][RTW89_MEXICO][0] = 60, -+ [0][0][RTW89_UKRAINE][0] = 34, -+ [0][0][RTW89_CHILE][0] = 60, -+ [0][0][RTW89_QATAR][0] = 34, - [0][0][RTW89_FCC][1] = 60, - [0][0][RTW89_ETSI][1] = 38, - [0][0][RTW89_MKK][1] = 40, -@@ -34083,6 +35625,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][0][RTW89_ACMA][1] = 38, - [0][0][RTW89_CN][1] = 32, - [0][0][RTW89_UK][1] = 38, -+ [0][0][RTW89_MEXICO][1] = 60, -+ [0][0][RTW89_UKRAINE][1] = 38, -+ [0][0][RTW89_CHILE][1] = 50, -+ [0][0][RTW89_QATAR][1] = 38, - [0][0][RTW89_FCC][2] = 64, - [0][0][RTW89_ETSI][2] = 38, - [0][0][RTW89_MKK][2] = 40, -@@ -34091,6 +35637,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][0][RTW89_ACMA][2] = 38, - [0][0][RTW89_CN][2] = 32, - [0][0][RTW89_UK][2] = 38, -+ [0][0][RTW89_MEXICO][2] = 64, -+ [0][0][RTW89_UKRAINE][2] = 38, -+ [0][0][RTW89_CHILE][2] = 50, -+ [0][0][RTW89_QATAR][2] = 38, - [0][0][RTW89_FCC][3] = 68, - [0][0][RTW89_ETSI][3] = 38, - [0][0][RTW89_MKK][3] = 40, -@@ -34099,78 +35649,118 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][0][RTW89_ACMA][3] = 38, - [0][0][RTW89_CN][3] = 32, - [0][0][RTW89_UK][3] = 38, -+ [0][0][RTW89_MEXICO][3] = 68, -+ [0][0][RTW89_UKRAINE][3] = 38, -+ [0][0][RTW89_CHILE][3] = 50, -+ [0][0][RTW89_QATAR][3] = 38, - [0][0][RTW89_FCC][4] = 68, - [0][0][RTW89_ETSI][4] = 38, - [0][0][RTW89_MKK][4] = 40, - [0][0][RTW89_IC][4] = 68, -- [0][0][RTW89_KCC][4] = 42, -+ [0][0][RTW89_KCC][4] = 44, - [0][0][RTW89_ACMA][4] = 38, - [0][0][RTW89_CN][4] = 32, - [0][0][RTW89_UK][4] = 38, -+ [0][0][RTW89_MEXICO][4] = 68, -+ [0][0][RTW89_UKRAINE][4] = 38, -+ [0][0][RTW89_CHILE][4] = 50, -+ [0][0][RTW89_QATAR][4] = 38, - [0][0][RTW89_FCC][5] = 78, - [0][0][RTW89_ETSI][5] = 38, - [0][0][RTW89_MKK][5] = 40, - [0][0][RTW89_IC][5] = 78, -- [0][0][RTW89_KCC][5] = 42, -+ [0][0][RTW89_KCC][5] = 44, - [0][0][RTW89_ACMA][5] = 38, - [0][0][RTW89_CN][5] = 32, - [0][0][RTW89_UK][5] = 38, -+ [0][0][RTW89_MEXICO][5] = 78, -+ [0][0][RTW89_UKRAINE][5] = 38, -+ [0][0][RTW89_CHILE][5] = 78, -+ [0][0][RTW89_QATAR][5] = 38, - [0][0][RTW89_FCC][6] = 54, - [0][0][RTW89_ETSI][6] = 38, - [0][0][RTW89_MKK][6] = 40, - [0][0][RTW89_IC][6] = 54, -- [0][0][RTW89_KCC][6] = 42, -+ [0][0][RTW89_KCC][6] = 44, - [0][0][RTW89_ACMA][6] = 38, - [0][0][RTW89_CN][6] = 32, - [0][0][RTW89_UK][6] = 38, -+ [0][0][RTW89_MEXICO][6] = 54, -+ [0][0][RTW89_UKRAINE][6] = 38, -+ [0][0][RTW89_CHILE][6] = 36, -+ [0][0][RTW89_QATAR][6] = 38, - [0][0][RTW89_FCC][7] = 54, - [0][0][RTW89_ETSI][7] = 38, - [0][0][RTW89_MKK][7] = 40, - [0][0][RTW89_IC][7] = 54, -- [0][0][RTW89_KCC][7] = 42, -+ [0][0][RTW89_KCC][7] = 44, - [0][0][RTW89_ACMA][7] = 38, - [0][0][RTW89_CN][7] = 32, - [0][0][RTW89_UK][7] = 38, -+ [0][0][RTW89_MEXICO][7] = 54, -+ [0][0][RTW89_UKRAINE][7] = 38, -+ [0][0][RTW89_CHILE][7] = 36, -+ [0][0][RTW89_QATAR][7] = 38, - [0][0][RTW89_FCC][8] = 50, - [0][0][RTW89_ETSI][8] = 38, - [0][0][RTW89_MKK][8] = 40, - [0][0][RTW89_IC][8] = 50, -- [0][0][RTW89_KCC][8] = 42, -+ [0][0][RTW89_KCC][8] = 44, - [0][0][RTW89_ACMA][8] = 38, - [0][0][RTW89_CN][8] = 32, - [0][0][RTW89_UK][8] = 38, -+ [0][0][RTW89_MEXICO][8] = 50, -+ [0][0][RTW89_UKRAINE][8] = 38, -+ [0][0][RTW89_CHILE][8] = 36, -+ [0][0][RTW89_QATAR][8] = 38, - [0][0][RTW89_FCC][9] = 46, - [0][0][RTW89_ETSI][9] = 38, - [0][0][RTW89_MKK][9] = 40, - [0][0][RTW89_IC][9] = 46, -- [0][0][RTW89_KCC][9] = 40, -+ [0][0][RTW89_KCC][9] = 42, - [0][0][RTW89_ACMA][9] = 38, - [0][0][RTW89_CN][9] = 32, - [0][0][RTW89_UK][9] = 38, -+ [0][0][RTW89_MEXICO][9] = 46, -+ [0][0][RTW89_UKRAINE][9] = 38, -+ [0][0][RTW89_CHILE][9] = 36, -+ [0][0][RTW89_QATAR][9] = 38, - [0][0][RTW89_FCC][10] = 46, - [0][0][RTW89_ETSI][10] = 38, - [0][0][RTW89_MKK][10] = 40, - [0][0][RTW89_IC][10] = 46, -- [0][0][RTW89_KCC][10] = 40, -+ [0][0][RTW89_KCC][10] = 42, - [0][0][RTW89_ACMA][10] = 38, - [0][0][RTW89_CN][10] = 32, - [0][0][RTW89_UK][10] = 38, -+ [0][0][RTW89_MEXICO][10] = 46, -+ [0][0][RTW89_UKRAINE][10] = 38, -+ [0][0][RTW89_CHILE][10] = 46, -+ [0][0][RTW89_QATAR][10] = 38, - [0][0][RTW89_FCC][11] = 26, - [0][0][RTW89_ETSI][11] = 38, - [0][0][RTW89_MKK][11] = 40, - [0][0][RTW89_IC][11] = 26, -- [0][0][RTW89_KCC][11] = 40, -+ [0][0][RTW89_KCC][11] = 42, - [0][0][RTW89_ACMA][11] = 38, - [0][0][RTW89_CN][11] = 32, - [0][0][RTW89_UK][11] = 38, -+ [0][0][RTW89_MEXICO][11] = 26, -+ [0][0][RTW89_UKRAINE][11] = 38, -+ [0][0][RTW89_CHILE][11] = 26, -+ [0][0][RTW89_QATAR][11] = 38, - [0][0][RTW89_FCC][12] = -20, - [0][0][RTW89_ETSI][12] = 34, - [0][0][RTW89_MKK][12] = 36, - [0][0][RTW89_IC][12] = -20, -- [0][0][RTW89_KCC][12] = 40, -+ [0][0][RTW89_KCC][12] = 42, - [0][0][RTW89_ACMA][12] = 34, - [0][0][RTW89_CN][12] = 32, - [0][0][RTW89_UK][12] = 34, -+ [0][0][RTW89_MEXICO][12] = -20, -+ [0][0][RTW89_UKRAINE][12] = 34, -+ [0][0][RTW89_CHILE][12] = -20, -+ [0][0][RTW89_QATAR][12] = 34, - [0][0][RTW89_FCC][13] = 127, - [0][0][RTW89_ETSI][13] = 127, - [0][0][RTW89_MKK][13] = 127, -@@ -34179,6 +35769,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][0][RTW89_ACMA][13] = 127, - [0][0][RTW89_CN][13] = 127, - [0][0][RTW89_UK][13] = 127, -+ [0][0][RTW89_MEXICO][13] = 127, -+ [0][0][RTW89_UKRAINE][13] = 127, -+ [0][0][RTW89_CHILE][13] = 127, -+ [0][0][RTW89_QATAR][13] = 127, - [0][1][RTW89_FCC][0] = 56, - [0][1][RTW89_ETSI][0] = 22, - [0][1][RTW89_MKK][0] = 24, -@@ -34187,6 +35781,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][1][RTW89_ACMA][0] = 22, - [0][1][RTW89_CN][0] = 20, - [0][1][RTW89_UK][0] = 22, -+ [0][1][RTW89_MEXICO][0] = 56, -+ [0][1][RTW89_UKRAINE][0] = 22, -+ [0][1][RTW89_CHILE][0] = 56, -+ [0][1][RTW89_QATAR][0] = 22, - [0][1][RTW89_FCC][1] = 56, - [0][1][RTW89_ETSI][1] = 24, - [0][1][RTW89_MKK][1] = 30, -@@ -34195,6 +35793,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][1][RTW89_ACMA][1] = 24, - [0][1][RTW89_CN][1] = 22, - [0][1][RTW89_UK][1] = 24, -+ [0][1][RTW89_MEXICO][1] = 56, -+ [0][1][RTW89_UKRAINE][1] = 24, -+ [0][1][RTW89_CHILE][1] = 40, -+ [0][1][RTW89_QATAR][1] = 24, - [0][1][RTW89_FCC][2] = 60, - [0][1][RTW89_ETSI][2] = 24, - [0][1][RTW89_MKK][2] = 30, -@@ -34203,6 +35805,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][1][RTW89_ACMA][2] = 24, - [0][1][RTW89_CN][2] = 22, - [0][1][RTW89_UK][2] = 24, -+ [0][1][RTW89_MEXICO][2] = 60, -+ [0][1][RTW89_UKRAINE][2] = 24, -+ [0][1][RTW89_CHILE][2] = 40, -+ [0][1][RTW89_QATAR][2] = 24, - [0][1][RTW89_FCC][3] = 64, - [0][1][RTW89_ETSI][3] = 24, - [0][1][RTW89_MKK][3] = 30, -@@ -34211,78 +35817,118 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][1][RTW89_ACMA][3] = 24, - [0][1][RTW89_CN][3] = 22, - [0][1][RTW89_UK][3] = 24, -+ [0][1][RTW89_MEXICO][3] = 64, -+ [0][1][RTW89_UKRAINE][3] = 24, -+ [0][1][RTW89_CHILE][3] = 40, -+ [0][1][RTW89_QATAR][3] = 24, - [0][1][RTW89_FCC][4] = 68, - [0][1][RTW89_ETSI][4] = 24, - [0][1][RTW89_MKK][4] = 30, - [0][1][RTW89_IC][4] = 68, -- [0][1][RTW89_KCC][4] = 28, -+ [0][1][RTW89_KCC][4] = 34, - [0][1][RTW89_ACMA][4] = 24, - [0][1][RTW89_CN][4] = 22, - [0][1][RTW89_UK][4] = 24, -+ [0][1][RTW89_MEXICO][4] = 68, -+ [0][1][RTW89_UKRAINE][4] = 24, -+ [0][1][RTW89_CHILE][4] = 40, -+ [0][1][RTW89_QATAR][4] = 24, - [0][1][RTW89_FCC][5] = 76, - [0][1][RTW89_ETSI][5] = 24, - [0][1][RTW89_MKK][5] = 30, - [0][1][RTW89_IC][5] = 76, -- [0][1][RTW89_KCC][5] = 28, -+ [0][1][RTW89_KCC][5] = 34, - [0][1][RTW89_ACMA][5] = 24, - [0][1][RTW89_CN][5] = 22, - [0][1][RTW89_UK][5] = 24, -+ [0][1][RTW89_MEXICO][5] = 76, -+ [0][1][RTW89_UKRAINE][5] = 24, -+ [0][1][RTW89_CHILE][5] = 76, -+ [0][1][RTW89_QATAR][5] = 24, - [0][1][RTW89_FCC][6] = 54, - [0][1][RTW89_ETSI][6] = 24, - [0][1][RTW89_MKK][6] = 30, - [0][1][RTW89_IC][6] = 54, -- [0][1][RTW89_KCC][6] = 28, -+ [0][1][RTW89_KCC][6] = 34, - [0][1][RTW89_ACMA][6] = 24, - [0][1][RTW89_CN][6] = 22, - [0][1][RTW89_UK][6] = 24, -+ [0][1][RTW89_MEXICO][6] = 54, -+ [0][1][RTW89_UKRAINE][6] = 24, -+ [0][1][RTW89_CHILE][6] = 26, -+ [0][1][RTW89_QATAR][6] = 24, - [0][1][RTW89_FCC][7] = 50, - [0][1][RTW89_ETSI][7] = 24, - [0][1][RTW89_MKK][7] = 30, - [0][1][RTW89_IC][7] = 50, -- [0][1][RTW89_KCC][7] = 28, -+ [0][1][RTW89_KCC][7] = 34, - [0][1][RTW89_ACMA][7] = 24, - [0][1][RTW89_CN][7] = 22, - [0][1][RTW89_UK][7] = 24, -+ [0][1][RTW89_MEXICO][7] = 50, -+ [0][1][RTW89_UKRAINE][7] = 24, -+ [0][1][RTW89_CHILE][7] = 26, -+ [0][1][RTW89_QATAR][7] = 24, - [0][1][RTW89_FCC][8] = 46, - [0][1][RTW89_ETSI][8] = 24, - [0][1][RTW89_MKK][8] = 30, - [0][1][RTW89_IC][8] = 46, -- [0][1][RTW89_KCC][8] = 28, -+ [0][1][RTW89_KCC][8] = 34, - [0][1][RTW89_ACMA][8] = 24, - [0][1][RTW89_CN][8] = 22, - [0][1][RTW89_UK][8] = 24, -+ [0][1][RTW89_MEXICO][8] = 46, -+ [0][1][RTW89_UKRAINE][8] = 24, -+ [0][1][RTW89_CHILE][8] = 26, -+ [0][1][RTW89_QATAR][8] = 24, - [0][1][RTW89_FCC][9] = 42, - [0][1][RTW89_ETSI][9] = 24, - [0][1][RTW89_MKK][9] = 30, - [0][1][RTW89_IC][9] = 42, -- [0][1][RTW89_KCC][9] = 28, -+ [0][1][RTW89_KCC][9] = 32, - [0][1][RTW89_ACMA][9] = 24, - [0][1][RTW89_CN][9] = 22, - [0][1][RTW89_UK][9] = 24, -+ [0][1][RTW89_MEXICO][9] = 42, -+ [0][1][RTW89_UKRAINE][9] = 24, -+ [0][1][RTW89_CHILE][9] = 26, -+ [0][1][RTW89_QATAR][9] = 24, - [0][1][RTW89_FCC][10] = 42, - [0][1][RTW89_ETSI][10] = 24, - [0][1][RTW89_MKK][10] = 30, - [0][1][RTW89_IC][10] = 42, -- [0][1][RTW89_KCC][10] = 28, -+ [0][1][RTW89_KCC][10] = 32, - [0][1][RTW89_ACMA][10] = 24, - [0][1][RTW89_CN][10] = 22, - [0][1][RTW89_UK][10] = 24, -+ [0][1][RTW89_MEXICO][10] = 42, -+ [0][1][RTW89_UKRAINE][10] = 24, -+ [0][1][RTW89_CHILE][10] = 42, -+ [0][1][RTW89_QATAR][10] = 24, - [0][1][RTW89_FCC][11] = 22, - [0][1][RTW89_ETSI][11] = 24, - [0][1][RTW89_MKK][11] = 30, - [0][1][RTW89_IC][11] = 22, -- [0][1][RTW89_KCC][11] = 28, -+ [0][1][RTW89_KCC][11] = 32, - [0][1][RTW89_ACMA][11] = 24, - [0][1][RTW89_CN][11] = 22, - [0][1][RTW89_UK][11] = 24, -+ [0][1][RTW89_MEXICO][11] = 22, -+ [0][1][RTW89_UKRAINE][11] = 24, -+ [0][1][RTW89_CHILE][11] = 22, -+ [0][1][RTW89_QATAR][11] = 24, - [0][1][RTW89_FCC][12] = -30, - [0][1][RTW89_ETSI][12] = 20, - [0][1][RTW89_MKK][12] = 24, - [0][1][RTW89_IC][12] = -30, -- [0][1][RTW89_KCC][12] = 28, -+ [0][1][RTW89_KCC][12] = 32, - [0][1][RTW89_ACMA][12] = 20, - [0][1][RTW89_CN][12] = 20, - [0][1][RTW89_UK][12] = 20, -+ [0][1][RTW89_MEXICO][12] = -30, -+ [0][1][RTW89_UKRAINE][12] = 20, -+ [0][1][RTW89_CHILE][12] = -30, -+ [0][1][RTW89_QATAR][12] = 20, - [0][1][RTW89_FCC][13] = 127, - [0][1][RTW89_ETSI][13] = 127, - [0][1][RTW89_MKK][13] = 127, -@@ -34291,110 +35937,166 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [0][1][RTW89_ACMA][13] = 127, - [0][1][RTW89_CN][13] = 127, - [0][1][RTW89_UK][13] = 127, -+ [0][1][RTW89_MEXICO][13] = 127, -+ [0][1][RTW89_UKRAINE][13] = 127, -+ [0][1][RTW89_CHILE][13] = 127, -+ [0][1][RTW89_QATAR][13] = 127, - [1][0][RTW89_FCC][0] = 66, - [1][0][RTW89_ETSI][0] = 46, - [1][0][RTW89_MKK][0] = 48, - [1][0][RTW89_IC][0] = 66, -- [1][0][RTW89_KCC][0] = 50, -+ [1][0][RTW89_KCC][0] = 54, - [1][0][RTW89_ACMA][0] = 46, - [1][0][RTW89_CN][0] = 42, - [1][0][RTW89_UK][0] = 46, -+ [1][0][RTW89_MEXICO][0] = 66, -+ [1][0][RTW89_UKRAINE][0] = 46, -+ [1][0][RTW89_CHILE][0] = 66, -+ [1][0][RTW89_QATAR][0] = 46, - [1][0][RTW89_FCC][1] = 66, - [1][0][RTW89_ETSI][1] = 46, - [1][0][RTW89_MKK][1] = 48, - [1][0][RTW89_IC][1] = 66, -- [1][0][RTW89_KCC][1] = 50, -+ [1][0][RTW89_KCC][1] = 54, - [1][0][RTW89_ACMA][1] = 46, - [1][0][RTW89_CN][1] = 44, - [1][0][RTW89_UK][1] = 46, -+ [1][0][RTW89_MEXICO][1] = 66, -+ [1][0][RTW89_UKRAINE][1] = 46, -+ [1][0][RTW89_CHILE][1] = 54, -+ [1][0][RTW89_QATAR][1] = 46, - [1][0][RTW89_FCC][2] = 70, - [1][0][RTW89_ETSI][2] = 46, - [1][0][RTW89_MKK][2] = 48, - [1][0][RTW89_IC][2] = 70, -- [1][0][RTW89_KCC][2] = 50, -+ [1][0][RTW89_KCC][2] = 54, - [1][0][RTW89_ACMA][2] = 46, - [1][0][RTW89_CN][2] = 44, - [1][0][RTW89_UK][2] = 46, -+ [1][0][RTW89_MEXICO][2] = 70, -+ [1][0][RTW89_UKRAINE][2] = 46, -+ [1][0][RTW89_CHILE][2] = 54, -+ [1][0][RTW89_QATAR][2] = 46, - [1][0][RTW89_FCC][3] = 72, - [1][0][RTW89_ETSI][3] = 46, - [1][0][RTW89_MKK][3] = 48, - [1][0][RTW89_IC][3] = 72, -- [1][0][RTW89_KCC][3] = 50, -+ [1][0][RTW89_KCC][3] = 54, - [1][0][RTW89_ACMA][3] = 46, - [1][0][RTW89_CN][3] = 44, - [1][0][RTW89_UK][3] = 46, -+ [1][0][RTW89_MEXICO][3] = 72, -+ [1][0][RTW89_UKRAINE][3] = 46, -+ [1][0][RTW89_CHILE][3] = 54, -+ [1][0][RTW89_QATAR][3] = 46, - [1][0][RTW89_FCC][4] = 72, - [1][0][RTW89_ETSI][4] = 46, - [1][0][RTW89_MKK][4] = 48, - [1][0][RTW89_IC][4] = 72, -- [1][0][RTW89_KCC][4] = 50, -+ [1][0][RTW89_KCC][4] = 56, - [1][0][RTW89_ACMA][4] = 46, - [1][0][RTW89_CN][4] = 44, - [1][0][RTW89_UK][4] = 46, -+ [1][0][RTW89_MEXICO][4] = 72, -+ [1][0][RTW89_UKRAINE][4] = 46, -+ [1][0][RTW89_CHILE][4] = 54, -+ [1][0][RTW89_QATAR][4] = 46, - [1][0][RTW89_FCC][5] = 82, - [1][0][RTW89_ETSI][5] = 46, - [1][0][RTW89_MKK][5] = 48, - [1][0][RTW89_IC][5] = 82, -- [1][0][RTW89_KCC][5] = 50, -+ [1][0][RTW89_KCC][5] = 56, - [1][0][RTW89_ACMA][5] = 46, - [1][0][RTW89_CN][5] = 44, - [1][0][RTW89_UK][5] = 46, -+ [1][0][RTW89_MEXICO][5] = 82, -+ [1][0][RTW89_UKRAINE][5] = 46, -+ [1][0][RTW89_CHILE][5] = 82, -+ [1][0][RTW89_QATAR][5] = 46, - [1][0][RTW89_FCC][6] = 58, - [1][0][RTW89_ETSI][6] = 44, - [1][0][RTW89_MKK][6] = 48, - [1][0][RTW89_IC][6] = 58, -- [1][0][RTW89_KCC][6] = 50, -+ [1][0][RTW89_KCC][6] = 56, - [1][0][RTW89_ACMA][6] = 44, - [1][0][RTW89_CN][6] = 44, - [1][0][RTW89_UK][6] = 44, -+ [1][0][RTW89_MEXICO][6] = 58, -+ [1][0][RTW89_UKRAINE][6] = 44, -+ [1][0][RTW89_CHILE][6] = 40, -+ [1][0][RTW89_QATAR][6] = 44, - [1][0][RTW89_FCC][7] = 58, - [1][0][RTW89_ETSI][7] = 46, - [1][0][RTW89_MKK][7] = 48, - [1][0][RTW89_IC][7] = 58, -- [1][0][RTW89_KCC][7] = 50, -+ [1][0][RTW89_KCC][7] = 56, - [1][0][RTW89_ACMA][7] = 46, - [1][0][RTW89_CN][7] = 44, - [1][0][RTW89_UK][7] = 46, -+ [1][0][RTW89_MEXICO][7] = 58, -+ [1][0][RTW89_UKRAINE][7] = 46, -+ [1][0][RTW89_CHILE][7] = 40, -+ [1][0][RTW89_QATAR][7] = 46, - [1][0][RTW89_FCC][8] = 58, - [1][0][RTW89_ETSI][8] = 46, - [1][0][RTW89_MKK][8] = 48, - [1][0][RTW89_IC][8] = 58, -- [1][0][RTW89_KCC][8] = 50, -+ [1][0][RTW89_KCC][8] = 56, - [1][0][RTW89_ACMA][8] = 46, - [1][0][RTW89_CN][8] = 44, - [1][0][RTW89_UK][8] = 46, -+ [1][0][RTW89_MEXICO][8] = 58, -+ [1][0][RTW89_UKRAINE][8] = 46, -+ [1][0][RTW89_CHILE][8] = 40, -+ [1][0][RTW89_QATAR][8] = 46, - [1][0][RTW89_FCC][9] = 54, - [1][0][RTW89_ETSI][9] = 46, - [1][0][RTW89_MKK][9] = 48, - [1][0][RTW89_IC][9] = 54, -- [1][0][RTW89_KCC][9] = 50, -+ [1][0][RTW89_KCC][9] = 56, - [1][0][RTW89_ACMA][9] = 46, - [1][0][RTW89_CN][9] = 44, - [1][0][RTW89_UK][9] = 46, -+ [1][0][RTW89_MEXICO][9] = 54, -+ [1][0][RTW89_UKRAINE][9] = 46, -+ [1][0][RTW89_CHILE][9] = 40, -+ [1][0][RTW89_QATAR][9] = 46, - [1][0][RTW89_FCC][10] = 54, - [1][0][RTW89_ETSI][10] = 46, - [1][0][RTW89_MKK][10] = 48, - [1][0][RTW89_IC][10] = 54, -- [1][0][RTW89_KCC][10] = 50, -+ [1][0][RTW89_KCC][10] = 56, - [1][0][RTW89_ACMA][10] = 46, - [1][0][RTW89_CN][10] = 44, - [1][0][RTW89_UK][10] = 46, -+ [1][0][RTW89_MEXICO][10] = 54, -+ [1][0][RTW89_UKRAINE][10] = 46, -+ [1][0][RTW89_CHILE][10] = 54, -+ [1][0][RTW89_QATAR][10] = 46, - [1][0][RTW89_FCC][11] = 36, - [1][0][RTW89_ETSI][11] = 46, - [1][0][RTW89_MKK][11] = 48, - [1][0][RTW89_IC][11] = 36, -- [1][0][RTW89_KCC][11] = 50, -+ [1][0][RTW89_KCC][11] = 56, - [1][0][RTW89_ACMA][11] = 46, - [1][0][RTW89_CN][11] = 44, - [1][0][RTW89_UK][11] = 46, -+ [1][0][RTW89_MEXICO][11] = 36, -+ [1][0][RTW89_UKRAINE][11] = 46, -+ [1][0][RTW89_CHILE][11] = 36, -+ [1][0][RTW89_QATAR][11] = 46, - [1][0][RTW89_FCC][12] = 4, - [1][0][RTW89_ETSI][12] = 46, - [1][0][RTW89_MKK][12] = 46, - [1][0][RTW89_IC][12] = 4, -- [1][0][RTW89_KCC][12] = 50, -+ [1][0][RTW89_KCC][12] = 56, - [1][0][RTW89_ACMA][12] = 46, - [1][0][RTW89_CN][12] = 42, - [1][0][RTW89_UK][12] = 46, -+ [1][0][RTW89_MEXICO][12] = 4, -+ [1][0][RTW89_UKRAINE][12] = 46, -+ [1][0][RTW89_CHILE][12] = 4, -+ [1][0][RTW89_QATAR][12] = 46, - [1][0][RTW89_FCC][13] = 127, - [1][0][RTW89_ETSI][13] = 127, - [1][0][RTW89_MKK][13] = 127, -@@ -34403,110 +36105,166 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [1][0][RTW89_ACMA][13] = 127, - [1][0][RTW89_CN][13] = 127, - [1][0][RTW89_UK][13] = 127, -+ [1][0][RTW89_MEXICO][13] = 127, -+ [1][0][RTW89_UKRAINE][13] = 127, -+ [1][0][RTW89_CHILE][13] = 127, -+ [1][0][RTW89_QATAR][13] = 127, - [1][1][RTW89_FCC][0] = 58, - [1][1][RTW89_ETSI][0] = 32, - [1][1][RTW89_MKK][0] = 34, - [1][1][RTW89_IC][0] = 58, -- [1][1][RTW89_KCC][0] = 38, -+ [1][1][RTW89_KCC][0] = 42, - [1][1][RTW89_ACMA][0] = 32, - [1][1][RTW89_CN][0] = 32, - [1][1][RTW89_UK][0] = 32, -+ [1][1][RTW89_MEXICO][0] = 58, -+ [1][1][RTW89_UKRAINE][0] = 32, -+ [1][1][RTW89_CHILE][0] = 58, -+ [1][1][RTW89_QATAR][0] = 32, - [1][1][RTW89_FCC][1] = 58, - [1][1][RTW89_ETSI][1] = 34, - [1][1][RTW89_MKK][1] = 34, - [1][1][RTW89_IC][1] = 58, -- [1][1][RTW89_KCC][1] = 38, -+ [1][1][RTW89_KCC][1] = 42, - [1][1][RTW89_ACMA][1] = 34, - [1][1][RTW89_CN][1] = 32, - [1][1][RTW89_UK][1] = 34, -+ [1][1][RTW89_MEXICO][1] = 58, -+ [1][1][RTW89_UKRAINE][1] = 34, -+ [1][1][RTW89_CHILE][1] = 40, -+ [1][1][RTW89_QATAR][1] = 34, - [1][1][RTW89_FCC][2] = 62, - [1][1][RTW89_ETSI][2] = 34, - [1][1][RTW89_MKK][2] = 34, - [1][1][RTW89_IC][2] = 62, -- [1][1][RTW89_KCC][2] = 38, -+ [1][1][RTW89_KCC][2] = 42, - [1][1][RTW89_ACMA][2] = 34, - [1][1][RTW89_CN][2] = 32, - [1][1][RTW89_UK][2] = 34, -+ [1][1][RTW89_MEXICO][2] = 62, -+ [1][1][RTW89_UKRAINE][2] = 34, -+ [1][1][RTW89_CHILE][2] = 40, -+ [1][1][RTW89_QATAR][2] = 34, - [1][1][RTW89_FCC][3] = 66, - [1][1][RTW89_ETSI][3] = 34, - [1][1][RTW89_MKK][3] = 34, - [1][1][RTW89_IC][3] = 66, -- [1][1][RTW89_KCC][3] = 38, -+ [1][1][RTW89_KCC][3] = 42, - [1][1][RTW89_ACMA][3] = 34, - [1][1][RTW89_CN][3] = 32, - [1][1][RTW89_UK][3] = 34, -+ [1][1][RTW89_MEXICO][3] = 66, -+ [1][1][RTW89_UKRAINE][3] = 34, -+ [1][1][RTW89_CHILE][3] = 40, -+ [1][1][RTW89_QATAR][3] = 34, - [1][1][RTW89_FCC][4] = 70, - [1][1][RTW89_ETSI][4] = 34, - [1][1][RTW89_MKK][4] = 34, - [1][1][RTW89_IC][4] = 70, -- [1][1][RTW89_KCC][4] = 38, -+ [1][1][RTW89_KCC][4] = 44, - [1][1][RTW89_ACMA][4] = 34, - [1][1][RTW89_CN][4] = 32, - [1][1][RTW89_UK][4] = 34, -+ [1][1][RTW89_MEXICO][4] = 70, -+ [1][1][RTW89_UKRAINE][4] = 34, -+ [1][1][RTW89_CHILE][4] = 40, -+ [1][1][RTW89_QATAR][4] = 34, - [1][1][RTW89_FCC][5] = 82, - [1][1][RTW89_ETSI][5] = 34, - [1][1][RTW89_MKK][5] = 34, - [1][1][RTW89_IC][5] = 82, -- [1][1][RTW89_KCC][5] = 38, -+ [1][1][RTW89_KCC][5] = 44, - [1][1][RTW89_ACMA][5] = 34, - [1][1][RTW89_CN][5] = 32, - [1][1][RTW89_UK][5] = 34, -+ [1][1][RTW89_MEXICO][5] = 82, -+ [1][1][RTW89_UKRAINE][5] = 34, -+ [1][1][RTW89_CHILE][5] = 78, -+ [1][1][RTW89_QATAR][5] = 34, - [1][1][RTW89_FCC][6] = 60, - [1][1][RTW89_ETSI][6] = 34, - [1][1][RTW89_MKK][6] = 34, - [1][1][RTW89_IC][6] = 60, -- [1][1][RTW89_KCC][6] = 38, -+ [1][1][RTW89_KCC][6] = 44, - [1][1][RTW89_ACMA][6] = 34, - [1][1][RTW89_CN][6] = 32, - [1][1][RTW89_UK][6] = 34, -+ [1][1][RTW89_MEXICO][6] = 60, -+ [1][1][RTW89_UKRAINE][6] = 34, -+ [1][1][RTW89_CHILE][6] = 30, -+ [1][1][RTW89_QATAR][6] = 34, - [1][1][RTW89_FCC][7] = 56, - [1][1][RTW89_ETSI][7] = 34, - [1][1][RTW89_MKK][7] = 34, - [1][1][RTW89_IC][7] = 56, -- [1][1][RTW89_KCC][7] = 38, -+ [1][1][RTW89_KCC][7] = 44, - [1][1][RTW89_ACMA][7] = 34, - [1][1][RTW89_CN][7] = 32, - [1][1][RTW89_UK][7] = 34, -+ [1][1][RTW89_MEXICO][7] = 56, -+ [1][1][RTW89_UKRAINE][7] = 34, -+ [1][1][RTW89_CHILE][7] = 30, -+ [1][1][RTW89_QATAR][7] = 34, - [1][1][RTW89_FCC][8] = 52, - [1][1][RTW89_ETSI][8] = 34, - [1][1][RTW89_MKK][8] = 34, - [1][1][RTW89_IC][8] = 52, -- [1][1][RTW89_KCC][8] = 38, -+ [1][1][RTW89_KCC][8] = 44, - [1][1][RTW89_ACMA][8] = 34, - [1][1][RTW89_CN][8] = 32, - [1][1][RTW89_UK][8] = 34, -+ [1][1][RTW89_MEXICO][8] = 52, -+ [1][1][RTW89_UKRAINE][8] = 34, -+ [1][1][RTW89_CHILE][8] = 30, -+ [1][1][RTW89_QATAR][8] = 34, - [1][1][RTW89_FCC][9] = 48, - [1][1][RTW89_ETSI][9] = 34, - [1][1][RTW89_MKK][9] = 34, - [1][1][RTW89_IC][9] = 48, -- [1][1][RTW89_KCC][9] = 38, -+ [1][1][RTW89_KCC][9] = 44, - [1][1][RTW89_ACMA][9] = 34, - [1][1][RTW89_CN][9] = 32, - [1][1][RTW89_UK][9] = 34, -+ [1][1][RTW89_MEXICO][9] = 48, -+ [1][1][RTW89_UKRAINE][9] = 34, -+ [1][1][RTW89_CHILE][9] = 30, -+ [1][1][RTW89_QATAR][9] = 34, - [1][1][RTW89_FCC][10] = 48, - [1][1][RTW89_ETSI][10] = 34, - [1][1][RTW89_MKK][10] = 34, - [1][1][RTW89_IC][10] = 48, -- [1][1][RTW89_KCC][10] = 38, -+ [1][1][RTW89_KCC][10] = 44, - [1][1][RTW89_ACMA][10] = 34, - [1][1][RTW89_CN][10] = 32, - [1][1][RTW89_UK][10] = 34, -+ [1][1][RTW89_MEXICO][10] = 48, -+ [1][1][RTW89_UKRAINE][10] = 34, -+ [1][1][RTW89_CHILE][10] = 48, -+ [1][1][RTW89_QATAR][10] = 34, - [1][1][RTW89_FCC][11] = 30, - [1][1][RTW89_ETSI][11] = 34, - [1][1][RTW89_MKK][11] = 34, - [1][1][RTW89_IC][11] = 30, -- [1][1][RTW89_KCC][11] = 38, -+ [1][1][RTW89_KCC][11] = 44, - [1][1][RTW89_ACMA][11] = 34, - [1][1][RTW89_CN][11] = 32, - [1][1][RTW89_UK][11] = 34, -+ [1][1][RTW89_MEXICO][11] = 30, -+ [1][1][RTW89_UKRAINE][11] = 34, -+ [1][1][RTW89_CHILE][11] = 30, -+ [1][1][RTW89_QATAR][11] = 34, - [1][1][RTW89_FCC][12] = -6, - [1][1][RTW89_ETSI][12] = 34, - [1][1][RTW89_MKK][12] = 34, - [1][1][RTW89_IC][12] = -6, -- [1][1][RTW89_KCC][12] = 38, -+ [1][1][RTW89_KCC][12] = 44, - [1][1][RTW89_ACMA][12] = 34, - [1][1][RTW89_CN][12] = 32, - [1][1][RTW89_UK][12] = 34, -+ [1][1][RTW89_MEXICO][12] = -6, -+ [1][1][RTW89_UKRAINE][12] = 34, -+ [1][1][RTW89_CHILE][12] = -6, -+ [1][1][RTW89_QATAR][12] = 34, - [1][1][RTW89_FCC][13] = 127, - [1][1][RTW89_ETSI][13] = 127, - [1][1][RTW89_MKK][13] = 127, -@@ -34515,110 +36273,166 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [1][1][RTW89_ACMA][13] = 127, - [1][1][RTW89_CN][13] = 127, - [1][1][RTW89_UK][13] = 127, -+ [1][1][RTW89_MEXICO][13] = 127, -+ [1][1][RTW89_UKRAINE][13] = 127, -+ [1][1][RTW89_CHILE][13] = 127, -+ [1][1][RTW89_QATAR][13] = 127, - [2][0][RTW89_FCC][0] = 70, - [2][0][RTW89_ETSI][0] = 58, - [2][0][RTW89_MKK][0] = 58, - [2][0][RTW89_IC][0] = 70, -- [2][0][RTW89_KCC][0] = 64, -+ [2][0][RTW89_KCC][0] = 60, - [2][0][RTW89_ACMA][0] = 58, - [2][0][RTW89_CN][0] = 56, - [2][0][RTW89_UK][0] = 58, -+ [2][0][RTW89_MEXICO][0] = 70, -+ [2][0][RTW89_UKRAINE][0] = 58, -+ [2][0][RTW89_CHILE][0] = 70, -+ [2][0][RTW89_QATAR][0] = 58, - [2][0][RTW89_FCC][1] = 70, - [2][0][RTW89_ETSI][1] = 58, - [2][0][RTW89_MKK][1] = 58, - [2][0][RTW89_IC][1] = 70, -- [2][0][RTW89_KCC][1] = 64, -+ [2][0][RTW89_KCC][1] = 60, - [2][0][RTW89_ACMA][1] = 58, - [2][0][RTW89_CN][1] = 56, - [2][0][RTW89_UK][1] = 58, -+ [2][0][RTW89_MEXICO][1] = 70, -+ [2][0][RTW89_UKRAINE][1] = 58, -+ [2][0][RTW89_CHILE][1] = 54, -+ [2][0][RTW89_QATAR][1] = 58, - [2][0][RTW89_FCC][2] = 72, - [2][0][RTW89_ETSI][2] = 58, - [2][0][RTW89_MKK][2] = 58, - [2][0][RTW89_IC][2] = 72, -- [2][0][RTW89_KCC][2] = 64, -+ [2][0][RTW89_KCC][2] = 60, - [2][0][RTW89_ACMA][2] = 58, - [2][0][RTW89_CN][2] = 56, - [2][0][RTW89_UK][2] = 58, -+ [2][0][RTW89_MEXICO][2] = 72, -+ [2][0][RTW89_UKRAINE][2] = 58, -+ [2][0][RTW89_CHILE][2] = 54, -+ [2][0][RTW89_QATAR][2] = 58, - [2][0][RTW89_FCC][3] = 72, - [2][0][RTW89_ETSI][3] = 58, - [2][0][RTW89_MKK][3] = 58, - [2][0][RTW89_IC][3] = 72, -- [2][0][RTW89_KCC][3] = 64, -+ [2][0][RTW89_KCC][3] = 60, - [2][0][RTW89_ACMA][3] = 58, - [2][0][RTW89_CN][3] = 56, - [2][0][RTW89_UK][3] = 58, -+ [2][0][RTW89_MEXICO][3] = 72, -+ [2][0][RTW89_UKRAINE][3] = 58, -+ [2][0][RTW89_CHILE][3] = 54, -+ [2][0][RTW89_QATAR][3] = 58, - [2][0][RTW89_FCC][4] = 72, - [2][0][RTW89_ETSI][4] = 58, - [2][0][RTW89_MKK][4] = 58, - [2][0][RTW89_IC][4] = 72, -- [2][0][RTW89_KCC][4] = 64, -+ [2][0][RTW89_KCC][4] = 60, - [2][0][RTW89_ACMA][4] = 58, - [2][0][RTW89_CN][4] = 56, - [2][0][RTW89_UK][4] = 58, -+ [2][0][RTW89_MEXICO][4] = 72, -+ [2][0][RTW89_UKRAINE][4] = 58, -+ [2][0][RTW89_CHILE][4] = 54, -+ [2][0][RTW89_QATAR][4] = 58, - [2][0][RTW89_FCC][5] = 82, - [2][0][RTW89_ETSI][5] = 58, - [2][0][RTW89_MKK][5] = 58, - [2][0][RTW89_IC][5] = 82, -- [2][0][RTW89_KCC][5] = 64, -+ [2][0][RTW89_KCC][5] = 60, - [2][0][RTW89_ACMA][5] = 58, - [2][0][RTW89_CN][5] = 56, - [2][0][RTW89_UK][5] = 58, -+ [2][0][RTW89_MEXICO][5] = 82, -+ [2][0][RTW89_UKRAINE][5] = 58, -+ [2][0][RTW89_CHILE][5] = 82, -+ [2][0][RTW89_QATAR][5] = 58, - [2][0][RTW89_FCC][6] = 66, - [2][0][RTW89_ETSI][6] = 56, - [2][0][RTW89_MKK][6] = 58, - [2][0][RTW89_IC][6] = 66, -- [2][0][RTW89_KCC][6] = 64, -+ [2][0][RTW89_KCC][6] = 60, - [2][0][RTW89_ACMA][6] = 56, - [2][0][RTW89_CN][6] = 56, - [2][0][RTW89_UK][6] = 56, -+ [2][0][RTW89_MEXICO][6] = 66, -+ [2][0][RTW89_UKRAINE][6] = 56, -+ [2][0][RTW89_CHILE][6] = 48, -+ [2][0][RTW89_QATAR][6] = 56, - [2][0][RTW89_FCC][7] = 66, - [2][0][RTW89_ETSI][7] = 58, - [2][0][RTW89_MKK][7] = 58, - [2][0][RTW89_IC][7] = 66, -- [2][0][RTW89_KCC][7] = 64, -+ [2][0][RTW89_KCC][7] = 60, - [2][0][RTW89_ACMA][7] = 58, - [2][0][RTW89_CN][7] = 56, - [2][0][RTW89_UK][7] = 58, -+ [2][0][RTW89_MEXICO][7] = 66, -+ [2][0][RTW89_UKRAINE][7] = 58, -+ [2][0][RTW89_CHILE][7] = 48, -+ [2][0][RTW89_QATAR][7] = 58, - [2][0][RTW89_FCC][8] = 66, - [2][0][RTW89_ETSI][8] = 58, - [2][0][RTW89_MKK][8] = 58, - [2][0][RTW89_IC][8] = 66, -- [2][0][RTW89_KCC][8] = 64, -+ [2][0][RTW89_KCC][8] = 60, - [2][0][RTW89_ACMA][8] = 58, - [2][0][RTW89_CN][8] = 56, - [2][0][RTW89_UK][8] = 58, -+ [2][0][RTW89_MEXICO][8] = 66, -+ [2][0][RTW89_UKRAINE][8] = 58, -+ [2][0][RTW89_CHILE][8] = 48, -+ [2][0][RTW89_QATAR][8] = 58, - [2][0][RTW89_FCC][9] = 64, - [2][0][RTW89_ETSI][9] = 58, - [2][0][RTW89_MKK][9] = 58, - [2][0][RTW89_IC][9] = 64, -- [2][0][RTW89_KCC][9] = 64, -+ [2][0][RTW89_KCC][9] = 60, - [2][0][RTW89_ACMA][9] = 58, - [2][0][RTW89_CN][9] = 56, - [2][0][RTW89_UK][9] = 58, -+ [2][0][RTW89_MEXICO][9] = 64, -+ [2][0][RTW89_UKRAINE][9] = 58, -+ [2][0][RTW89_CHILE][9] = 48, -+ [2][0][RTW89_QATAR][9] = 58, - [2][0][RTW89_FCC][10] = 64, - [2][0][RTW89_ETSI][10] = 58, - [2][0][RTW89_MKK][10] = 58, - [2][0][RTW89_IC][10] = 64, -- [2][0][RTW89_KCC][10] = 64, -+ [2][0][RTW89_KCC][10] = 60, - [2][0][RTW89_ACMA][10] = 58, - [2][0][RTW89_CN][10] = 56, - [2][0][RTW89_UK][10] = 58, -+ [2][0][RTW89_MEXICO][10] = 64, -+ [2][0][RTW89_UKRAINE][10] = 58, -+ [2][0][RTW89_CHILE][10] = 64, -+ [2][0][RTW89_QATAR][10] = 58, - [2][0][RTW89_FCC][11] = 48, - [2][0][RTW89_ETSI][11] = 58, - [2][0][RTW89_MKK][11] = 58, - [2][0][RTW89_IC][11] = 48, -- [2][0][RTW89_KCC][11] = 64, -+ [2][0][RTW89_KCC][11] = 60, - [2][0][RTW89_ACMA][11] = 58, - [2][0][RTW89_CN][11] = 56, - [2][0][RTW89_UK][11] = 58, -+ [2][0][RTW89_MEXICO][11] = 48, -+ [2][0][RTW89_UKRAINE][11] = 58, -+ [2][0][RTW89_CHILE][11] = 48, -+ [2][0][RTW89_QATAR][11] = 58, - [2][0][RTW89_FCC][12] = 16, - [2][0][RTW89_ETSI][12] = 58, - [2][0][RTW89_MKK][12] = 58, - [2][0][RTW89_IC][12] = 16, -- [2][0][RTW89_KCC][12] = 64, -+ [2][0][RTW89_KCC][12] = 60, - [2][0][RTW89_ACMA][12] = 58, - [2][0][RTW89_CN][12] = 56, - [2][0][RTW89_UK][12] = 58, -+ [2][0][RTW89_MEXICO][12] = 16, -+ [2][0][RTW89_UKRAINE][12] = 58, -+ [2][0][RTW89_CHILE][12] = 16, -+ [2][0][RTW89_QATAR][12] = 58, - [2][0][RTW89_FCC][13] = 127, - [2][0][RTW89_ETSI][13] = 127, - [2][0][RTW89_MKK][13] = 127, -@@ -34627,110 +36441,166 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [2][0][RTW89_ACMA][13] = 127, - [2][0][RTW89_CN][13] = 127, - [2][0][RTW89_UK][13] = 127, -+ [2][0][RTW89_MEXICO][13] = 127, -+ [2][0][RTW89_UKRAINE][13] = 127, -+ [2][0][RTW89_CHILE][13] = 127, -+ [2][0][RTW89_QATAR][13] = 127, - [2][1][RTW89_FCC][0] = 64, - [2][1][RTW89_ETSI][0] = 46, - [2][1][RTW89_MKK][0] = 46, - [2][1][RTW89_IC][0] = 64, -- [2][1][RTW89_KCC][0] = 52, -+ [2][1][RTW89_KCC][0] = 48, - [2][1][RTW89_ACMA][0] = 46, - [2][1][RTW89_CN][0] = 44, - [2][1][RTW89_UK][0] = 46, -+ [2][1][RTW89_MEXICO][0] = 64, -+ [2][1][RTW89_UKRAINE][0] = 46, -+ [2][1][RTW89_CHILE][0] = 64, -+ [2][1][RTW89_QATAR][0] = 46, - [2][1][RTW89_FCC][1] = 64, - [2][1][RTW89_ETSI][1] = 46, - [2][1][RTW89_MKK][1] = 46, - [2][1][RTW89_IC][1] = 64, -- [2][1][RTW89_KCC][1] = 52, -+ [2][1][RTW89_KCC][1] = 48, - [2][1][RTW89_ACMA][1] = 46, - [2][1][RTW89_CN][1] = 44, - [2][1][RTW89_UK][1] = 46, -+ [2][1][RTW89_MEXICO][1] = 64, -+ [2][1][RTW89_UKRAINE][1] = 46, -+ [2][1][RTW89_CHILE][1] = 44, -+ [2][1][RTW89_QATAR][1] = 46, - [2][1][RTW89_FCC][2] = 68, - [2][1][RTW89_ETSI][2] = 46, - [2][1][RTW89_MKK][2] = 46, - [2][1][RTW89_IC][2] = 68, -- [2][1][RTW89_KCC][2] = 52, -+ [2][1][RTW89_KCC][2] = 48, - [2][1][RTW89_ACMA][2] = 46, - [2][1][RTW89_CN][2] = 44, - [2][1][RTW89_UK][2] = 46, -+ [2][1][RTW89_MEXICO][2] = 68, -+ [2][1][RTW89_UKRAINE][2] = 46, -+ [2][1][RTW89_CHILE][2] = 44, -+ [2][1][RTW89_QATAR][2] = 46, - [2][1][RTW89_FCC][3] = 72, - [2][1][RTW89_ETSI][3] = 46, - [2][1][RTW89_MKK][3] = 46, - [2][1][RTW89_IC][3] = 72, -- [2][1][RTW89_KCC][3] = 52, -+ [2][1][RTW89_KCC][3] = 48, - [2][1][RTW89_ACMA][3] = 46, - [2][1][RTW89_CN][3] = 44, - [2][1][RTW89_UK][3] = 46, -+ [2][1][RTW89_MEXICO][3] = 72, -+ [2][1][RTW89_UKRAINE][3] = 46, -+ [2][1][RTW89_CHILE][3] = 44, -+ [2][1][RTW89_QATAR][3] = 46, - [2][1][RTW89_FCC][4] = 74, - [2][1][RTW89_ETSI][4] = 46, - [2][1][RTW89_MKK][4] = 46, - [2][1][RTW89_IC][4] = 74, -- [2][1][RTW89_KCC][4] = 50, -+ [2][1][RTW89_KCC][4] = 48, - [2][1][RTW89_ACMA][4] = 46, - [2][1][RTW89_CN][4] = 44, - [2][1][RTW89_UK][4] = 46, -+ [2][1][RTW89_MEXICO][4] = 74, -+ [2][1][RTW89_UKRAINE][4] = 46, -+ [2][1][RTW89_CHILE][4] = 44, -+ [2][1][RTW89_QATAR][4] = 46, - [2][1][RTW89_FCC][5] = 82, - [2][1][RTW89_ETSI][5] = 46, - [2][1][RTW89_MKK][5] = 46, - [2][1][RTW89_IC][5] = 82, -- [2][1][RTW89_KCC][5] = 50, -+ [2][1][RTW89_KCC][5] = 48, - [2][1][RTW89_ACMA][5] = 46, - [2][1][RTW89_CN][5] = 44, - [2][1][RTW89_UK][5] = 46, -+ [2][1][RTW89_MEXICO][5] = 82, -+ [2][1][RTW89_UKRAINE][5] = 46, -+ [2][1][RTW89_CHILE][5] = 78, -+ [2][1][RTW89_QATAR][5] = 46, - [2][1][RTW89_FCC][6] = 72, - [2][1][RTW89_ETSI][6] = 44, - [2][1][RTW89_MKK][6] = 46, - [2][1][RTW89_IC][6] = 72, -- [2][1][RTW89_KCC][6] = 50, -+ [2][1][RTW89_KCC][6] = 48, - [2][1][RTW89_ACMA][6] = 44, - [2][1][RTW89_CN][6] = 44, - [2][1][RTW89_UK][6] = 44, -+ [2][1][RTW89_MEXICO][6] = 72, -+ [2][1][RTW89_UKRAINE][6] = 44, -+ [2][1][RTW89_CHILE][6] = 42, -+ [2][1][RTW89_QATAR][6] = 44, - [2][1][RTW89_FCC][7] = 72, - [2][1][RTW89_ETSI][7] = 46, - [2][1][RTW89_MKK][7] = 46, - [2][1][RTW89_IC][7] = 72, -- [2][1][RTW89_KCC][7] = 50, -+ [2][1][RTW89_KCC][7] = 48, - [2][1][RTW89_ACMA][7] = 46, - [2][1][RTW89_CN][7] = 44, - [2][1][RTW89_UK][7] = 46, -+ [2][1][RTW89_MEXICO][7] = 72, -+ [2][1][RTW89_UKRAINE][7] = 46, -+ [2][1][RTW89_CHILE][7] = 42, -+ [2][1][RTW89_QATAR][7] = 46, - [2][1][RTW89_FCC][8] = 68, - [2][1][RTW89_ETSI][8] = 46, - [2][1][RTW89_MKK][8] = 46, - [2][1][RTW89_IC][8] = 68, -- [2][1][RTW89_KCC][8] = 50, -+ [2][1][RTW89_KCC][8] = 48, - [2][1][RTW89_ACMA][8] = 46, - [2][1][RTW89_CN][8] = 44, - [2][1][RTW89_UK][8] = 46, -+ [2][1][RTW89_MEXICO][8] = 68, -+ [2][1][RTW89_UKRAINE][8] = 46, -+ [2][1][RTW89_CHILE][8] = 42, -+ [2][1][RTW89_QATAR][8] = 46, - [2][1][RTW89_FCC][9] = 64, - [2][1][RTW89_ETSI][9] = 46, - [2][1][RTW89_MKK][9] = 46, - [2][1][RTW89_IC][9] = 64, -- [2][1][RTW89_KCC][9] = 52, -+ [2][1][RTW89_KCC][9] = 48, - [2][1][RTW89_ACMA][9] = 46, - [2][1][RTW89_CN][9] = 44, - [2][1][RTW89_UK][9] = 46, -+ [2][1][RTW89_MEXICO][9] = 64, -+ [2][1][RTW89_UKRAINE][9] = 46, -+ [2][1][RTW89_CHILE][9] = 42, -+ [2][1][RTW89_QATAR][9] = 46, - [2][1][RTW89_FCC][10] = 64, - [2][1][RTW89_ETSI][10] = 46, - [2][1][RTW89_MKK][10] = 46, - [2][1][RTW89_IC][10] = 64, -- [2][1][RTW89_KCC][10] = 52, -+ [2][1][RTW89_KCC][10] = 48, - [2][1][RTW89_ACMA][10] = 46, - [2][1][RTW89_CN][10] = 44, - [2][1][RTW89_UK][10] = 46, -+ [2][1][RTW89_MEXICO][10] = 64, -+ [2][1][RTW89_UKRAINE][10] = 46, -+ [2][1][RTW89_CHILE][10] = 64, -+ [2][1][RTW89_QATAR][10] = 46, - [2][1][RTW89_FCC][11] = 46, - [2][1][RTW89_ETSI][11] = 46, - [2][1][RTW89_MKK][11] = 46, - [2][1][RTW89_IC][11] = 46, -- [2][1][RTW89_KCC][11] = 52, -+ [2][1][RTW89_KCC][11] = 48, - [2][1][RTW89_ACMA][11] = 46, - [2][1][RTW89_CN][11] = 44, - [2][1][RTW89_UK][11] = 46, -+ [2][1][RTW89_MEXICO][11] = 46, -+ [2][1][RTW89_UKRAINE][11] = 46, -+ [2][1][RTW89_CHILE][11] = 46, -+ [2][1][RTW89_QATAR][11] = 46, - [2][1][RTW89_FCC][12] = 6, - [2][1][RTW89_ETSI][12] = 44, - [2][1][RTW89_MKK][12] = 46, - [2][1][RTW89_IC][12] = 6, -- [2][1][RTW89_KCC][12] = 52, -+ [2][1][RTW89_KCC][12] = 48, - [2][1][RTW89_ACMA][12] = 44, - [2][1][RTW89_CN][12] = 42, - [2][1][RTW89_UK][12] = 44, -+ [2][1][RTW89_MEXICO][12] = 6, -+ [2][1][RTW89_UKRAINE][12] = 44, -+ [2][1][RTW89_CHILE][12] = 6, -+ [2][1][RTW89_QATAR][12] = 44, - [2][1][RTW89_FCC][13] = 127, - [2][1][RTW89_ETSI][13] = 127, - [2][1][RTW89_MKK][13] = 127, -@@ -34739,6 +36609,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_2g[RTW - [2][1][RTW89_ACMA][13] = 127, - [2][1][RTW89_CN][13] = 127, - [2][1][RTW89_UK][13] = 127, -+ [2][1][RTW89_MEXICO][13] = 127, -+ [2][1][RTW89_UKRAINE][13] = 127, -+ [2][1][RTW89_CHILE][13] = 127, -+ [2][1][RTW89_QATAR][13] = 127, - }; - - static -@@ -34747,168 +36621,168 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_WW][0] = 16, - [0][0][RTW89_WW][2] = 16, - [0][0][RTW89_WW][4] = 16, -- [0][0][RTW89_WW][6] = 10, -+ [0][0][RTW89_WW][6] = 16, - [0][0][RTW89_WW][8] = 16, - [0][0][RTW89_WW][10] = 16, - [0][0][RTW89_WW][12] = 16, - [0][0][RTW89_WW][14] = 16, -- [0][0][RTW89_WW][15] = 30, -- [0][0][RTW89_WW][17] = 30, -- [0][0][RTW89_WW][19] = 30, -- [0][0][RTW89_WW][21] = 30, -- [0][0][RTW89_WW][23] = 30, -- [0][0][RTW89_WW][25] = 30, -- [0][0][RTW89_WW][27] = 30, -- [0][0][RTW89_WW][29] = 30, -- [0][0][RTW89_WW][31] = 30, -- [0][0][RTW89_WW][33] = 30, -- [0][0][RTW89_WW][35] = 30, -+ [0][0][RTW89_WW][15] = 22, -+ [0][0][RTW89_WW][17] = 22, -+ [0][0][RTW89_WW][19] = 22, -+ [0][0][RTW89_WW][21] = 22, -+ [0][0][RTW89_WW][23] = 22, -+ [0][0][RTW89_WW][25] = 22, -+ [0][0][RTW89_WW][27] = 22, -+ [0][0][RTW89_WW][29] = 22, -+ [0][0][RTW89_WW][31] = 22, -+ [0][0][RTW89_WW][33] = 22, -+ [0][0][RTW89_WW][35] = 22, - [0][0][RTW89_WW][37] = 30, -- [0][0][RTW89_WW][38] = 28, -- [0][0][RTW89_WW][40] = 28, -- [0][0][RTW89_WW][42] = 28, -- [0][0][RTW89_WW][44] = 28, -- [0][0][RTW89_WW][46] = 28, -+ [0][0][RTW89_WW][38] = 26, -+ [0][0][RTW89_WW][40] = 26, -+ [0][0][RTW89_WW][42] = 26, -+ [0][0][RTW89_WW][44] = 26, -+ [0][0][RTW89_WW][46] = 26, - [0][0][RTW89_WW][48] = 46, - [0][0][RTW89_WW][50] = 44, - [0][0][RTW89_WW][52] = 34, - [0][1][RTW89_WW][0] = 4, - [0][1][RTW89_WW][2] = 4, - [0][1][RTW89_WW][4] = 4, -- [0][1][RTW89_WW][6] = 1, -+ [0][1][RTW89_WW][6] = 4, - [0][1][RTW89_WW][8] = 4, - [0][1][RTW89_WW][10] = 4, - [0][1][RTW89_WW][12] = 4, - [0][1][RTW89_WW][14] = 4, -- [0][1][RTW89_WW][15] = 18, -- [0][1][RTW89_WW][17] = 18, -- [0][1][RTW89_WW][19] = 18, -- [0][1][RTW89_WW][21] = 18, -- [0][1][RTW89_WW][23] = 18, -- [0][1][RTW89_WW][25] = 18, -- [0][1][RTW89_WW][27] = 16, -- [0][1][RTW89_WW][29] = 16, -- [0][1][RTW89_WW][31] = 16, -- [0][1][RTW89_WW][33] = 16, -- [0][1][RTW89_WW][35] = 16, -+ [0][1][RTW89_WW][15] = 10, -+ [0][1][RTW89_WW][17] = 10, -+ [0][1][RTW89_WW][19] = 10, -+ [0][1][RTW89_WW][21] = 10, -+ [0][1][RTW89_WW][23] = 10, -+ [0][1][RTW89_WW][25] = 10, -+ [0][1][RTW89_WW][27] = 10, -+ [0][1][RTW89_WW][29] = 10, -+ [0][1][RTW89_WW][31] = 10, -+ [0][1][RTW89_WW][33] = 10, -+ [0][1][RTW89_WW][35] = 10, - [0][1][RTW89_WW][37] = 18, -- [0][1][RTW89_WW][38] = 16, -- [0][1][RTW89_WW][40] = 16, -- [0][1][RTW89_WW][42] = 16, -- [0][1][RTW89_WW][44] = 16, -- [0][1][RTW89_WW][46] = 16, -+ [0][1][RTW89_WW][38] = 14, -+ [0][1][RTW89_WW][40] = 14, -+ [0][1][RTW89_WW][42] = 14, -+ [0][1][RTW89_WW][44] = 14, -+ [0][1][RTW89_WW][46] = 14, - [0][1][RTW89_WW][48] = 20, - [0][1][RTW89_WW][50] = 20, - [0][1][RTW89_WW][52] = 8, - [1][0][RTW89_WW][0] = 26, - [1][0][RTW89_WW][2] = 26, - [1][0][RTW89_WW][4] = 26, -- [1][0][RTW89_WW][6] = 24, -+ [1][0][RTW89_WW][6] = 26, - [1][0][RTW89_WW][8] = 26, - [1][0][RTW89_WW][10] = 26, - [1][0][RTW89_WW][12] = 26, - [1][0][RTW89_WW][14] = 26, -- [1][0][RTW89_WW][15] = 40, -- [1][0][RTW89_WW][17] = 40, -- [1][0][RTW89_WW][19] = 40, -- [1][0][RTW89_WW][21] = 40, -- [1][0][RTW89_WW][23] = 40, -- [1][0][RTW89_WW][25] = 40, -- [1][0][RTW89_WW][27] = 42, -- [1][0][RTW89_WW][29] = 42, -- [1][0][RTW89_WW][31] = 42, -- [1][0][RTW89_WW][33] = 42, -- [1][0][RTW89_WW][35] = 42, -+ [1][0][RTW89_WW][15] = 32, -+ [1][0][RTW89_WW][17] = 32, -+ [1][0][RTW89_WW][19] = 32, -+ [1][0][RTW89_WW][21] = 32, -+ [1][0][RTW89_WW][23] = 32, -+ [1][0][RTW89_WW][25] = 32, -+ [1][0][RTW89_WW][27] = 32, -+ [1][0][RTW89_WW][29] = 32, -+ [1][0][RTW89_WW][31] = 32, -+ [1][0][RTW89_WW][33] = 32, -+ [1][0][RTW89_WW][35] = 32, - [1][0][RTW89_WW][37] = 42, -- [1][0][RTW89_WW][38] = 28, -- [1][0][RTW89_WW][40] = 28, -- [1][0][RTW89_WW][42] = 28, -- [1][0][RTW89_WW][44] = 28, -- [1][0][RTW89_WW][46] = 28, -+ [1][0][RTW89_WW][38] = 26, -+ [1][0][RTW89_WW][40] = 26, -+ [1][0][RTW89_WW][42] = 26, -+ [1][0][RTW89_WW][44] = 26, -+ [1][0][RTW89_WW][46] = 26, - [1][0][RTW89_WW][48] = 56, - [1][0][RTW89_WW][50] = 58, - [1][0][RTW89_WW][52] = 56, - [1][1][RTW89_WW][0] = 14, - [1][1][RTW89_WW][2] = 14, - [1][1][RTW89_WW][4] = 14, -- [1][1][RTW89_WW][6] = 8, -+ [1][1][RTW89_WW][6] = 14, - [1][1][RTW89_WW][8] = 14, - [1][1][RTW89_WW][10] = 14, - [1][1][RTW89_WW][12] = 14, - [1][1][RTW89_WW][14] = 14, -- [1][1][RTW89_WW][15] = 28, -- [1][1][RTW89_WW][17] = 28, -- [1][1][RTW89_WW][19] = 28, -- [1][1][RTW89_WW][21] = 28, -- [1][1][RTW89_WW][23] = 28, -- [1][1][RTW89_WW][25] = 28, -- [1][1][RTW89_WW][27] = 30, -- [1][1][RTW89_WW][29] = 30, -- [1][1][RTW89_WW][31] = 30, -- [1][1][RTW89_WW][33] = 30, -- [1][1][RTW89_WW][35] = 30, -+ [1][1][RTW89_WW][15] = 20, -+ [1][1][RTW89_WW][17] = 20, -+ [1][1][RTW89_WW][19] = 20, -+ [1][1][RTW89_WW][21] = 20, -+ [1][1][RTW89_WW][23] = 20, -+ [1][1][RTW89_WW][25] = 20, -+ [1][1][RTW89_WW][27] = 20, -+ [1][1][RTW89_WW][29] = 20, -+ [1][1][RTW89_WW][31] = 20, -+ [1][1][RTW89_WW][33] = 20, -+ [1][1][RTW89_WW][35] = 20, - [1][1][RTW89_WW][37] = 32, -- [1][1][RTW89_WW][38] = 16, -- [1][1][RTW89_WW][40] = 16, -- [1][1][RTW89_WW][42] = 16, -- [1][1][RTW89_WW][44] = 16, -- [1][1][RTW89_WW][46] = 16, -+ [1][1][RTW89_WW][38] = 14, -+ [1][1][RTW89_WW][40] = 14, -+ [1][1][RTW89_WW][42] = 14, -+ [1][1][RTW89_WW][44] = 14, -+ [1][1][RTW89_WW][46] = 14, - [1][1][RTW89_WW][48] = 34, - [1][1][RTW89_WW][50] = 34, - [1][1][RTW89_WW][52] = 30, - [2][0][RTW89_WW][0] = 40, - [2][0][RTW89_WW][2] = 40, - [2][0][RTW89_WW][4] = 40, -- [2][0][RTW89_WW][6] = 36, -+ [2][0][RTW89_WW][6] = 38, - [2][0][RTW89_WW][8] = 40, - [2][0][RTW89_WW][10] = 40, - [2][0][RTW89_WW][12] = 40, - [2][0][RTW89_WW][14] = 40, -- [2][0][RTW89_WW][15] = 52, -- [2][0][RTW89_WW][17] = 52, -- [2][0][RTW89_WW][19] = 52, -- [2][0][RTW89_WW][21] = 52, -- [2][0][RTW89_WW][23] = 52, -- [2][0][RTW89_WW][25] = 52, -- [2][0][RTW89_WW][27] = 52, -- [2][0][RTW89_WW][29] = 52, -- [2][0][RTW89_WW][31] = 52, -- [2][0][RTW89_WW][33] = 52, -- [2][0][RTW89_WW][35] = 52, -+ [2][0][RTW89_WW][15] = 46, -+ [2][0][RTW89_WW][17] = 46, -+ [2][0][RTW89_WW][19] = 46, -+ [2][0][RTW89_WW][21] = 46, -+ [2][0][RTW89_WW][23] = 46, -+ [2][0][RTW89_WW][25] = 46, -+ [2][0][RTW89_WW][27] = 46, -+ [2][0][RTW89_WW][29] = 46, -+ [2][0][RTW89_WW][31] = 46, -+ [2][0][RTW89_WW][33] = 46, -+ [2][0][RTW89_WW][35] = 46, - [2][0][RTW89_WW][37] = 52, -- [2][0][RTW89_WW][38] = 28, -- [2][0][RTW89_WW][40] = 28, -- [2][0][RTW89_WW][42] = 28, -- [2][0][RTW89_WW][44] = 28, -- [2][0][RTW89_WW][46] = 28, -+ [2][0][RTW89_WW][38] = 26, -+ [2][0][RTW89_WW][40] = 26, -+ [2][0][RTW89_WW][42] = 26, -+ [2][0][RTW89_WW][44] = 26, -+ [2][0][RTW89_WW][46] = 26, - [2][0][RTW89_WW][48] = 64, - [2][0][RTW89_WW][50] = 64, - [2][0][RTW89_WW][52] = 64, - [2][1][RTW89_WW][0] = 26, - [2][1][RTW89_WW][2] = 26, - [2][1][RTW89_WW][4] = 26, -- [2][1][RTW89_WW][6] = 20, -+ [2][1][RTW89_WW][6] = 26, - [2][1][RTW89_WW][8] = 28, - [2][1][RTW89_WW][10] = 28, - [2][1][RTW89_WW][12] = 28, - [2][1][RTW89_WW][14] = 28, -- [2][1][RTW89_WW][15] = 40, -- [2][1][RTW89_WW][17] = 40, -- [2][1][RTW89_WW][19] = 40, -- [2][1][RTW89_WW][21] = 40, -- [2][1][RTW89_WW][23] = 40, -- [2][1][RTW89_WW][25] = 40, -- [2][1][RTW89_WW][27] = 40, -- [2][1][RTW89_WW][29] = 40, -- [2][1][RTW89_WW][31] = 40, -- [2][1][RTW89_WW][33] = 40, -- [2][1][RTW89_WW][35] = 40, -+ [2][1][RTW89_WW][15] = 34, -+ [2][1][RTW89_WW][17] = 34, -+ [2][1][RTW89_WW][19] = 34, -+ [2][1][RTW89_WW][21] = 34, -+ [2][1][RTW89_WW][23] = 34, -+ [2][1][RTW89_WW][25] = 34, -+ [2][1][RTW89_WW][27] = 34, -+ [2][1][RTW89_WW][29] = 34, -+ [2][1][RTW89_WW][31] = 34, -+ [2][1][RTW89_WW][33] = 34, -+ [2][1][RTW89_WW][35] = 34, - [2][1][RTW89_WW][37] = 42, -- [2][1][RTW89_WW][38] = 16, -- [2][1][RTW89_WW][40] = 16, -- [2][1][RTW89_WW][42] = 16, -- [2][1][RTW89_WW][44] = 16, -- [2][1][RTW89_WW][46] = 16, -+ [2][1][RTW89_WW][38] = 14, -+ [2][1][RTW89_WW][40] = 14, -+ [2][1][RTW89_WW][42] = 14, -+ [2][1][RTW89_WW][44] = 14, -+ [2][1][RTW89_WW][46] = 14, - [2][1][RTW89_WW][48] = 40, - [2][1][RTW89_WW][50] = 40, - [2][1][RTW89_WW][52] = 40, -@@ -34920,6 +36794,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][0] = 30, - [0][0][RTW89_CN][0] = 16, - [0][0][RTW89_UK][0] = 30, -+ [0][0][RTW89_MEXICO][0] = 50, -+ [0][0][RTW89_UKRAINE][0] = 22, -+ [0][0][RTW89_CHILE][0] = 50, -+ [0][0][RTW89_QATAR][0] = 30, - [0][0][RTW89_FCC][2] = 50, - [0][0][RTW89_ETSI][2] = 30, - [0][0][RTW89_MKK][2] = 36, -@@ -34928,6 +36806,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][2] = 30, - [0][0][RTW89_CN][2] = 16, - [0][0][RTW89_UK][2] = 30, -+ [0][0][RTW89_MEXICO][2] = 50, -+ [0][0][RTW89_UKRAINE][2] = 22, -+ [0][0][RTW89_CHILE][2] = 50, -+ [0][0][RTW89_QATAR][2] = 30, - [0][0][RTW89_FCC][4] = 50, - [0][0][RTW89_ETSI][4] = 30, - [0][0][RTW89_MKK][4] = 22, -@@ -34936,30 +36818,46 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][4] = 30, - [0][0][RTW89_CN][4] = 16, - [0][0][RTW89_UK][4] = 30, -+ [0][0][RTW89_MEXICO][4] = 50, -+ [0][0][RTW89_UKRAINE][4] = 22, -+ [0][0][RTW89_CHILE][4] = 50, -+ [0][0][RTW89_QATAR][4] = 30, - [0][0][RTW89_FCC][6] = 50, - [0][0][RTW89_ETSI][6] = 30, - [0][0][RTW89_MKK][6] = 22, - [0][0][RTW89_IC][6] = 32, -- [0][0][RTW89_KCC][6] = 10, -+ [0][0][RTW89_KCC][6] = 18, - [0][0][RTW89_ACMA][6] = 30, - [0][0][RTW89_CN][6] = 16, - [0][0][RTW89_UK][6] = 30, -+ [0][0][RTW89_MEXICO][6] = 50, -+ [0][0][RTW89_UKRAINE][6] = 22, -+ [0][0][RTW89_CHILE][6] = 50, -+ [0][0][RTW89_QATAR][6] = 30, - [0][0][RTW89_FCC][8] = 52, - [0][0][RTW89_ETSI][8] = 28, - [0][0][RTW89_MKK][8] = 18, - [0][0][RTW89_IC][8] = 52, -- [0][0][RTW89_KCC][8] = 44, -+ [0][0][RTW89_KCC][8] = 40, - [0][0][RTW89_ACMA][8] = 28, - [0][0][RTW89_CN][8] = 16, - [0][0][RTW89_UK][8] = 28, -+ [0][0][RTW89_MEXICO][8] = 52, -+ [0][0][RTW89_UKRAINE][8] = 22, -+ [0][0][RTW89_CHILE][8] = 52, -+ [0][0][RTW89_QATAR][8] = 28, - [0][0][RTW89_FCC][10] = 52, - [0][0][RTW89_ETSI][10] = 28, - [0][0][RTW89_MKK][10] = 18, - [0][0][RTW89_IC][10] = 52, -- [0][0][RTW89_KCC][10] = 44, -+ [0][0][RTW89_KCC][10] = 40, - [0][0][RTW89_ACMA][10] = 28, - [0][0][RTW89_CN][10] = 16, - [0][0][RTW89_UK][10] = 28, -+ [0][0][RTW89_MEXICO][10] = 52, -+ [0][0][RTW89_UKRAINE][10] = 22, -+ [0][0][RTW89_CHILE][10] = 52, -+ [0][0][RTW89_QATAR][10] = 28, - [0][0][RTW89_FCC][12] = 52, - [0][0][RTW89_ETSI][12] = 28, - [0][0][RTW89_MKK][12] = 34, -@@ -34968,6 +36866,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][12] = 28, - [0][0][RTW89_CN][12] = 16, - [0][0][RTW89_UK][12] = 28, -+ [0][0][RTW89_MEXICO][12] = 52, -+ [0][0][RTW89_UKRAINE][12] = 22, -+ [0][0][RTW89_CHILE][12] = 52, -+ [0][0][RTW89_QATAR][12] = 28, - [0][0][RTW89_FCC][14] = 52, - [0][0][RTW89_ETSI][14] = 28, - [0][0][RTW89_MKK][14] = 34, -@@ -34976,70 +36878,106 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][14] = 28, - [0][0][RTW89_CN][14] = 16, - [0][0][RTW89_UK][14] = 28, -+ [0][0][RTW89_MEXICO][14] = 52, -+ [0][0][RTW89_UKRAINE][14] = 22, -+ [0][0][RTW89_CHILE][14] = 52, -+ [0][0][RTW89_QATAR][14] = 28, - [0][0][RTW89_FCC][15] = 52, - [0][0][RTW89_ETSI][15] = 30, - [0][0][RTW89_MKK][15] = 56, - [0][0][RTW89_IC][15] = 52, -- [0][0][RTW89_KCC][15] = 42, -+ [0][0][RTW89_KCC][15] = 40, - [0][0][RTW89_ACMA][15] = 30, - [0][0][RTW89_CN][15] = 127, - [0][0][RTW89_UK][15] = 30, -+ [0][0][RTW89_MEXICO][15] = 52, -+ [0][0][RTW89_UKRAINE][15] = 22, -+ [0][0][RTW89_CHILE][15] = 52, -+ [0][0][RTW89_QATAR][15] = 30, - [0][0][RTW89_FCC][17] = 52, - [0][0][RTW89_ETSI][17] = 30, - [0][0][RTW89_MKK][17] = 58, - [0][0][RTW89_IC][17] = 52, -- [0][0][RTW89_KCC][17] = 42, -+ [0][0][RTW89_KCC][17] = 40, - [0][0][RTW89_ACMA][17] = 30, - [0][0][RTW89_CN][17] = 127, - [0][0][RTW89_UK][17] = 30, -+ [0][0][RTW89_MEXICO][17] = 52, -+ [0][0][RTW89_UKRAINE][17] = 22, -+ [0][0][RTW89_CHILE][17] = 52, -+ [0][0][RTW89_QATAR][17] = 30, - [0][0][RTW89_FCC][19] = 52, - [0][0][RTW89_ETSI][19] = 30, - [0][0][RTW89_MKK][19] = 58, - [0][0][RTW89_IC][19] = 52, -- [0][0][RTW89_KCC][19] = 42, -+ [0][0][RTW89_KCC][19] = 40, - [0][0][RTW89_ACMA][19] = 30, - [0][0][RTW89_CN][19] = 127, - [0][0][RTW89_UK][19] = 30, -+ [0][0][RTW89_MEXICO][19] = 52, -+ [0][0][RTW89_UKRAINE][19] = 22, -+ [0][0][RTW89_CHILE][19] = 52, -+ [0][0][RTW89_QATAR][19] = 30, - [0][0][RTW89_FCC][21] = 52, - [0][0][RTW89_ETSI][21] = 30, - [0][0][RTW89_MKK][21] = 58, - [0][0][RTW89_IC][21] = 52, -- [0][0][RTW89_KCC][21] = 42, -+ [0][0][RTW89_KCC][21] = 40, - [0][0][RTW89_ACMA][21] = 30, - [0][0][RTW89_CN][21] = 127, - [0][0][RTW89_UK][21] = 30, -+ [0][0][RTW89_MEXICO][21] = 52, -+ [0][0][RTW89_UKRAINE][21] = 22, -+ [0][0][RTW89_CHILE][21] = 52, -+ [0][0][RTW89_QATAR][21] = 30, - [0][0][RTW89_FCC][23] = 52, - [0][0][RTW89_ETSI][23] = 30, - [0][0][RTW89_MKK][23] = 58, - [0][0][RTW89_IC][23] = 52, -- [0][0][RTW89_KCC][23] = 42, -+ [0][0][RTW89_KCC][23] = 40, - [0][0][RTW89_ACMA][23] = 30, - [0][0][RTW89_CN][23] = 127, - [0][0][RTW89_UK][23] = 30, -+ [0][0][RTW89_MEXICO][23] = 52, -+ [0][0][RTW89_UKRAINE][23] = 22, -+ [0][0][RTW89_CHILE][23] = 52, -+ [0][0][RTW89_QATAR][23] = 30, - [0][0][RTW89_FCC][25] = 52, - [0][0][RTW89_ETSI][25] = 30, - [0][0][RTW89_MKK][25] = 58, - [0][0][RTW89_IC][25] = 127, -- [0][0][RTW89_KCC][25] = 42, -+ [0][0][RTW89_KCC][25] = 40, - [0][0][RTW89_ACMA][25] = 127, - [0][0][RTW89_CN][25] = 127, - [0][0][RTW89_UK][25] = 30, -+ [0][0][RTW89_MEXICO][25] = 52, -+ [0][0][RTW89_UKRAINE][25] = 22, -+ [0][0][RTW89_CHILE][25] = 52, -+ [0][0][RTW89_QATAR][25] = 30, - [0][0][RTW89_FCC][27] = 52, - [0][0][RTW89_ETSI][27] = 30, - [0][0][RTW89_MKK][27] = 58, - [0][0][RTW89_IC][27] = 127, -- [0][0][RTW89_KCC][27] = 42, -+ [0][0][RTW89_KCC][27] = 40, - [0][0][RTW89_ACMA][27] = 127, - [0][0][RTW89_CN][27] = 127, - [0][0][RTW89_UK][27] = 30, -+ [0][0][RTW89_MEXICO][27] = 52, -+ [0][0][RTW89_UKRAINE][27] = 22, -+ [0][0][RTW89_CHILE][27] = 52, -+ [0][0][RTW89_QATAR][27] = 30, - [0][0][RTW89_FCC][29] = 52, - [0][0][RTW89_ETSI][29] = 30, - [0][0][RTW89_MKK][29] = 58, - [0][0][RTW89_IC][29] = 127, -- [0][0][RTW89_KCC][29] = 42, -+ [0][0][RTW89_KCC][29] = 40, - [0][0][RTW89_ACMA][29] = 127, - [0][0][RTW89_CN][29] = 127, - [0][0][RTW89_UK][29] = 30, -+ [0][0][RTW89_MEXICO][29] = 52, -+ [0][0][RTW89_UKRAINE][29] = 22, -+ [0][0][RTW89_CHILE][29] = 52, -+ [0][0][RTW89_QATAR][29] = 30, - [0][0][RTW89_FCC][31] = 52, - [0][0][RTW89_ETSI][31] = 30, - [0][0][RTW89_MKK][31] = 58, -@@ -35048,6 +36986,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][31] = 30, - [0][0][RTW89_CN][31] = 127, - [0][0][RTW89_UK][31] = 30, -+ [0][0][RTW89_MEXICO][31] = 52, -+ [0][0][RTW89_UKRAINE][31] = 22, -+ [0][0][RTW89_CHILE][31] = 52, -+ [0][0][RTW89_QATAR][31] = 30, - [0][0][RTW89_FCC][33] = 44, - [0][0][RTW89_ETSI][33] = 30, - [0][0][RTW89_MKK][33] = 58, -@@ -35056,6 +36998,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][33] = 30, - [0][0][RTW89_CN][33] = 127, - [0][0][RTW89_UK][33] = 30, -+ [0][0][RTW89_MEXICO][33] = 44, -+ [0][0][RTW89_UKRAINE][33] = 22, -+ [0][0][RTW89_CHILE][33] = 44, -+ [0][0][RTW89_QATAR][33] = 30, - [0][0][RTW89_FCC][35] = 44, - [0][0][RTW89_ETSI][35] = 30, - [0][0][RTW89_MKK][35] = 58, -@@ -35064,6 +37010,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][35] = 30, - [0][0][RTW89_CN][35] = 127, - [0][0][RTW89_UK][35] = 30, -+ [0][0][RTW89_MEXICO][35] = 44, -+ [0][0][RTW89_UKRAINE][35] = 22, -+ [0][0][RTW89_CHILE][35] = 44, -+ [0][0][RTW89_QATAR][35] = 30, - [0][0][RTW89_FCC][37] = 52, - [0][0][RTW89_ETSI][37] = 127, - [0][0][RTW89_MKK][37] = 58, -@@ -35072,6 +37022,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][37] = 52, - [0][0][RTW89_CN][37] = 127, - [0][0][RTW89_UK][37] = 30, -+ [0][0][RTW89_MEXICO][37] = 52, -+ [0][0][RTW89_UKRAINE][37] = 127, -+ [0][0][RTW89_CHILE][37] = 52, -+ [0][0][RTW89_QATAR][37] = 127, - [0][0][RTW89_FCC][38] = 64, - [0][0][RTW89_ETSI][38] = 28, - [0][0][RTW89_MKK][38] = 127, -@@ -35080,6 +37034,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][38] = 64, - [0][0][RTW89_CN][38] = 54, - [0][0][RTW89_UK][38] = 30, -+ [0][0][RTW89_MEXICO][38] = 64, -+ [0][0][RTW89_UKRAINE][38] = 26, -+ [0][0][RTW89_CHILE][38] = 64, -+ [0][0][RTW89_QATAR][38] = 26, - [0][0][RTW89_FCC][40] = 64, - [0][0][RTW89_ETSI][40] = 28, - [0][0][RTW89_MKK][40] = 127, -@@ -35088,6 +37046,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][40] = 64, - [0][0][RTW89_CN][40] = 54, - [0][0][RTW89_UK][40] = 30, -+ [0][0][RTW89_MEXICO][40] = 64, -+ [0][0][RTW89_UKRAINE][40] = 26, -+ [0][0][RTW89_CHILE][40] = 64, -+ [0][0][RTW89_QATAR][40] = 26, - [0][0][RTW89_FCC][42] = 60, - [0][0][RTW89_ETSI][42] = 28, - [0][0][RTW89_MKK][42] = 127, -@@ -35096,6 +37058,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][42] = 60, - [0][0][RTW89_CN][42] = 54, - [0][0][RTW89_UK][42] = 30, -+ [0][0][RTW89_MEXICO][42] = 60, -+ [0][0][RTW89_UKRAINE][42] = 26, -+ [0][0][RTW89_CHILE][42] = 60, -+ [0][0][RTW89_QATAR][42] = 26, - [0][0][RTW89_FCC][44] = 60, - [0][0][RTW89_ETSI][44] = 28, - [0][0][RTW89_MKK][44] = 127, -@@ -35104,6 +37070,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][44] = 60, - [0][0][RTW89_CN][44] = 54, - [0][0][RTW89_UK][44] = 30, -+ [0][0][RTW89_MEXICO][44] = 60, -+ [0][0][RTW89_UKRAINE][44] = 26, -+ [0][0][RTW89_CHILE][44] = 60, -+ [0][0][RTW89_QATAR][44] = 26, - [0][0][RTW89_FCC][46] = 60, - [0][0][RTW89_ETSI][46] = 28, - [0][0][RTW89_MKK][46] = 127, -@@ -35112,6 +37082,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][46] = 60, - [0][0][RTW89_CN][46] = 54, - [0][0][RTW89_UK][46] = 30, -+ [0][0][RTW89_MEXICO][46] = 60, -+ [0][0][RTW89_UKRAINE][46] = 26, -+ [0][0][RTW89_CHILE][46] = 60, -+ [0][0][RTW89_QATAR][46] = 26, - [0][0][RTW89_FCC][48] = 46, - [0][0][RTW89_ETSI][48] = 127, - [0][0][RTW89_MKK][48] = 127, -@@ -35120,6 +37094,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][48] = 127, - [0][0][RTW89_CN][48] = 127, - [0][0][RTW89_UK][48] = 127, -+ [0][0][RTW89_MEXICO][48] = 127, -+ [0][0][RTW89_UKRAINE][48] = 127, -+ [0][0][RTW89_CHILE][48] = 127, -+ [0][0][RTW89_QATAR][48] = 127, - [0][0][RTW89_FCC][50] = 44, - [0][0][RTW89_ETSI][50] = 127, - [0][0][RTW89_MKK][50] = 127, -@@ -35128,6 +37106,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][50] = 127, - [0][0][RTW89_CN][50] = 127, - [0][0][RTW89_UK][50] = 127, -+ [0][0][RTW89_MEXICO][50] = 127, -+ [0][0][RTW89_UKRAINE][50] = 127, -+ [0][0][RTW89_CHILE][50] = 127, -+ [0][0][RTW89_QATAR][50] = 127, - [0][0][RTW89_FCC][52] = 34, - [0][0][RTW89_ETSI][52] = 127, - [0][0][RTW89_MKK][52] = 127, -@@ -35136,38 +37118,58 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][0][RTW89_ACMA][52] = 127, - [0][0][RTW89_CN][52] = 127, - [0][0][RTW89_UK][52] = 127, -+ [0][0][RTW89_MEXICO][52] = 127, -+ [0][0][RTW89_UKRAINE][52] = 127, -+ [0][0][RTW89_CHILE][52] = 127, -+ [0][0][RTW89_QATAR][52] = 127, - [0][1][RTW89_FCC][0] = 30, - [0][1][RTW89_ETSI][0] = 18, - [0][1][RTW89_MKK][0] = 20, - [0][1][RTW89_IC][0] = 8, -- [0][1][RTW89_KCC][0] = 26, -+ [0][1][RTW89_KCC][0] = 32, - [0][1][RTW89_ACMA][0] = 18, - [0][1][RTW89_CN][0] = 4, - [0][1][RTW89_UK][0] = 18, -+ [0][1][RTW89_MEXICO][0] = 30, -+ [0][1][RTW89_UKRAINE][0] = 10, -+ [0][1][RTW89_CHILE][0] = 30, -+ [0][1][RTW89_QATAR][0] = 18, - [0][1][RTW89_FCC][2] = 32, - [0][1][RTW89_ETSI][2] = 18, - [0][1][RTW89_MKK][2] = 20, - [0][1][RTW89_IC][2] = 8, -- [0][1][RTW89_KCC][2] = 26, -+ [0][1][RTW89_KCC][2] = 32, - [0][1][RTW89_ACMA][2] = 18, - [0][1][RTW89_CN][2] = 4, - [0][1][RTW89_UK][2] = 18, -+ [0][1][RTW89_MEXICO][2] = 32, -+ [0][1][RTW89_UKRAINE][2] = 10, -+ [0][1][RTW89_CHILE][2] = 32, -+ [0][1][RTW89_QATAR][2] = 18, - [0][1][RTW89_FCC][4] = 30, - [0][1][RTW89_ETSI][4] = 18, - [0][1][RTW89_MKK][4] = 8, - [0][1][RTW89_IC][4] = 8, -- [0][1][RTW89_KCC][4] = 26, -+ [0][1][RTW89_KCC][4] = 32, - [0][1][RTW89_ACMA][4] = 18, - [0][1][RTW89_CN][4] = 4, - [0][1][RTW89_UK][4] = 18, -+ [0][1][RTW89_MEXICO][4] = 30, -+ [0][1][RTW89_UKRAINE][4] = 10, -+ [0][1][RTW89_CHILE][4] = 30, -+ [0][1][RTW89_QATAR][4] = 18, - [0][1][RTW89_FCC][6] = 30, - [0][1][RTW89_ETSI][6] = 18, - [0][1][RTW89_MKK][6] = 8, - [0][1][RTW89_IC][6] = 8, -- [0][1][RTW89_KCC][6] = 0, -+ [0][1][RTW89_KCC][6] = 6, - [0][1][RTW89_ACMA][6] = 18, - [0][1][RTW89_CN][6] = 4, - [0][1][RTW89_UK][6] = 18, -+ [0][1][RTW89_MEXICO][6] = 30, -+ [0][1][RTW89_UKRAINE][6] = 10, -+ [0][1][RTW89_CHILE][6] = 30, -+ [0][1][RTW89_QATAR][6] = 18, - [0][1][RTW89_FCC][8] = 30, - [0][1][RTW89_ETSI][8] = 16, - [0][1][RTW89_MKK][8] = 20, -@@ -35176,6 +37178,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][8] = 16, - [0][1][RTW89_CN][8] = 4, - [0][1][RTW89_UK][8] = 16, -+ [0][1][RTW89_MEXICO][8] = 30, -+ [0][1][RTW89_UKRAINE][8] = 10, -+ [0][1][RTW89_CHILE][8] = 30, -+ [0][1][RTW89_QATAR][8] = 16, - [0][1][RTW89_FCC][10] = 30, - [0][1][RTW89_ETSI][10] = 16, - [0][1][RTW89_MKK][10] = 20, -@@ -35184,22 +37190,34 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][10] = 16, - [0][1][RTW89_CN][10] = 4, - [0][1][RTW89_UK][10] = 16, -+ [0][1][RTW89_MEXICO][10] = 30, -+ [0][1][RTW89_UKRAINE][10] = 10, -+ [0][1][RTW89_CHILE][10] = 30, -+ [0][1][RTW89_QATAR][10] = 16, - [0][1][RTW89_FCC][12] = 30, - [0][1][RTW89_ETSI][12] = 16, - [0][1][RTW89_MKK][12] = 34, - [0][1][RTW89_IC][12] = 30, -- [0][1][RTW89_KCC][12] = 28, -+ [0][1][RTW89_KCC][12] = 26, - [0][1][RTW89_ACMA][12] = 16, - [0][1][RTW89_CN][12] = 4, - [0][1][RTW89_UK][12] = 16, -+ [0][1][RTW89_MEXICO][12] = 30, -+ [0][1][RTW89_UKRAINE][12] = 10, -+ [0][1][RTW89_CHILE][12] = 30, -+ [0][1][RTW89_QATAR][12] = 16, - [0][1][RTW89_FCC][14] = 30, - [0][1][RTW89_ETSI][14] = 16, - [0][1][RTW89_MKK][14] = 34, - [0][1][RTW89_IC][14] = 30, -- [0][1][RTW89_KCC][14] = 28, -+ [0][1][RTW89_KCC][14] = 26, - [0][1][RTW89_ACMA][14] = 16, - [0][1][RTW89_CN][14] = 4, - [0][1][RTW89_UK][14] = 16, -+ [0][1][RTW89_MEXICO][14] = 30, -+ [0][1][RTW89_UKRAINE][14] = 10, -+ [0][1][RTW89_CHILE][14] = 30, -+ [0][1][RTW89_QATAR][14] = 16, - [0][1][RTW89_FCC][15] = 32, - [0][1][RTW89_ETSI][15] = 18, - [0][1][RTW89_MKK][15] = 44, -@@ -35208,6 +37226,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][15] = 18, - [0][1][RTW89_CN][15] = 127, - [0][1][RTW89_UK][15] = 18, -+ [0][1][RTW89_MEXICO][15] = 32, -+ [0][1][RTW89_UKRAINE][15] = 10, -+ [0][1][RTW89_CHILE][15] = 32, -+ [0][1][RTW89_QATAR][15] = 18, - [0][1][RTW89_FCC][17] = 32, - [0][1][RTW89_ETSI][17] = 18, - [0][1][RTW89_MKK][17] = 44, -@@ -35216,6 +37238,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][17] = 18, - [0][1][RTW89_CN][17] = 127, - [0][1][RTW89_UK][17] = 18, -+ [0][1][RTW89_MEXICO][17] = 32, -+ [0][1][RTW89_UKRAINE][17] = 10, -+ [0][1][RTW89_CHILE][17] = 32, -+ [0][1][RTW89_QATAR][17] = 18, - [0][1][RTW89_FCC][19] = 32, - [0][1][RTW89_ETSI][19] = 18, - [0][1][RTW89_MKK][19] = 44, -@@ -35224,6 +37250,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][19] = 18, - [0][1][RTW89_CN][19] = 127, - [0][1][RTW89_UK][19] = 18, -+ [0][1][RTW89_MEXICO][19] = 32, -+ [0][1][RTW89_UKRAINE][19] = 10, -+ [0][1][RTW89_CHILE][19] = 32, -+ [0][1][RTW89_QATAR][19] = 18, - [0][1][RTW89_FCC][21] = 32, - [0][1][RTW89_ETSI][21] = 18, - [0][1][RTW89_MKK][21] = 44, -@@ -35232,6 +37262,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][21] = 18, - [0][1][RTW89_CN][21] = 127, - [0][1][RTW89_UK][21] = 18, -+ [0][1][RTW89_MEXICO][21] = 32, -+ [0][1][RTW89_UKRAINE][21] = 10, -+ [0][1][RTW89_CHILE][21] = 32, -+ [0][1][RTW89_QATAR][21] = 18, - [0][1][RTW89_FCC][23] = 32, - [0][1][RTW89_ETSI][23] = 18, - [0][1][RTW89_MKK][23] = 44, -@@ -35240,6 +37274,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][23] = 18, - [0][1][RTW89_CN][23] = 127, - [0][1][RTW89_UK][23] = 18, -+ [0][1][RTW89_MEXICO][23] = 32, -+ [0][1][RTW89_UKRAINE][23] = 10, -+ [0][1][RTW89_CHILE][23] = 32, -+ [0][1][RTW89_QATAR][23] = 18, - [0][1][RTW89_FCC][25] = 32, - [0][1][RTW89_ETSI][25] = 18, - [0][1][RTW89_MKK][25] = 44, -@@ -35248,6 +37286,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][25] = 127, - [0][1][RTW89_CN][25] = 127, - [0][1][RTW89_UK][25] = 18, -+ [0][1][RTW89_MEXICO][25] = 32, -+ [0][1][RTW89_UKRAINE][25] = 10, -+ [0][1][RTW89_CHILE][25] = 32, -+ [0][1][RTW89_QATAR][25] = 18, - [0][1][RTW89_FCC][27] = 32, - [0][1][RTW89_ETSI][27] = 16, - [0][1][RTW89_MKK][27] = 44, -@@ -35256,6 +37298,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][27] = 127, - [0][1][RTW89_CN][27] = 127, - [0][1][RTW89_UK][27] = 16, -+ [0][1][RTW89_MEXICO][27] = 32, -+ [0][1][RTW89_UKRAINE][27] = 10, -+ [0][1][RTW89_CHILE][27] = 32, -+ [0][1][RTW89_QATAR][27] = 16, - [0][1][RTW89_FCC][29] = 32, - [0][1][RTW89_ETSI][29] = 16, - [0][1][RTW89_MKK][29] = 44, -@@ -35264,6 +37310,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][29] = 127, - [0][1][RTW89_CN][29] = 127, - [0][1][RTW89_UK][29] = 16, -+ [0][1][RTW89_MEXICO][29] = 32, -+ [0][1][RTW89_UKRAINE][29] = 10, -+ [0][1][RTW89_CHILE][29] = 32, -+ [0][1][RTW89_QATAR][29] = 16, - [0][1][RTW89_FCC][31] = 32, - [0][1][RTW89_ETSI][31] = 16, - [0][1][RTW89_MKK][31] = 44, -@@ -35272,6 +37322,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][31] = 16, - [0][1][RTW89_CN][31] = 127, - [0][1][RTW89_UK][31] = 16, -+ [0][1][RTW89_MEXICO][31] = 32, -+ [0][1][RTW89_UKRAINE][31] = 10, -+ [0][1][RTW89_CHILE][31] = 32, -+ [0][1][RTW89_QATAR][31] = 16, - [0][1][RTW89_FCC][33] = 30, - [0][1][RTW89_ETSI][33] = 16, - [0][1][RTW89_MKK][33] = 44, -@@ -35280,6 +37334,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][33] = 16, - [0][1][RTW89_CN][33] = 127, - [0][1][RTW89_UK][33] = 16, -+ [0][1][RTW89_MEXICO][33] = 30, -+ [0][1][RTW89_UKRAINE][33] = 10, -+ [0][1][RTW89_CHILE][33] = 30, -+ [0][1][RTW89_QATAR][33] = 16, - [0][1][RTW89_FCC][35] = 30, - [0][1][RTW89_ETSI][35] = 16, - [0][1][RTW89_MKK][35] = 44, -@@ -35288,6 +37346,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][35] = 16, - [0][1][RTW89_CN][35] = 127, - [0][1][RTW89_UK][35] = 16, -+ [0][1][RTW89_MEXICO][35] = 30, -+ [0][1][RTW89_UKRAINE][35] = 10, -+ [0][1][RTW89_CHILE][35] = 30, -+ [0][1][RTW89_QATAR][35] = 16, - [0][1][RTW89_FCC][37] = 34, - [0][1][RTW89_ETSI][37] = 127, - [0][1][RTW89_MKK][37] = 44, -@@ -35296,46 +37358,70 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][37] = 34, - [0][1][RTW89_CN][37] = 127, - [0][1][RTW89_UK][37] = 18, -+ [0][1][RTW89_MEXICO][37] = 34, -+ [0][1][RTW89_UKRAINE][37] = 127, -+ [0][1][RTW89_CHILE][37] = 34, -+ [0][1][RTW89_QATAR][37] = 127, - [0][1][RTW89_FCC][38] = 62, - [0][1][RTW89_ETSI][38] = 16, - [0][1][RTW89_MKK][38] = 127, - [0][1][RTW89_IC][38] = 62, -- [0][1][RTW89_KCC][38] = 28, -+ [0][1][RTW89_KCC][38] = 30, - [0][1][RTW89_ACMA][38] = 62, - [0][1][RTW89_CN][38] = 42, - [0][1][RTW89_UK][38] = 18, -+ [0][1][RTW89_MEXICO][38] = 62, -+ [0][1][RTW89_UKRAINE][38] = 14, -+ [0][1][RTW89_CHILE][38] = 62, -+ [0][1][RTW89_QATAR][38] = 14, - [0][1][RTW89_FCC][40] = 62, - [0][1][RTW89_ETSI][40] = 16, - [0][1][RTW89_MKK][40] = 127, - [0][1][RTW89_IC][40] = 62, -- [0][1][RTW89_KCC][40] = 28, -+ [0][1][RTW89_KCC][40] = 30, - [0][1][RTW89_ACMA][40] = 62, - [0][1][RTW89_CN][40] = 42, - [0][1][RTW89_UK][40] = 18, -+ [0][1][RTW89_MEXICO][40] = 62, -+ [0][1][RTW89_UKRAINE][40] = 14, -+ [0][1][RTW89_CHILE][40] = 62, -+ [0][1][RTW89_QATAR][40] = 14, - [0][1][RTW89_FCC][42] = 58, - [0][1][RTW89_ETSI][42] = 16, - [0][1][RTW89_MKK][42] = 127, - [0][1][RTW89_IC][42] = 58, -- [0][1][RTW89_KCC][42] = 28, -+ [0][1][RTW89_KCC][42] = 30, - [0][1][RTW89_ACMA][42] = 58, - [0][1][RTW89_CN][42] = 42, - [0][1][RTW89_UK][42] = 18, -+ [0][1][RTW89_MEXICO][42] = 58, -+ [0][1][RTW89_UKRAINE][42] = 14, -+ [0][1][RTW89_CHILE][42] = 58, -+ [0][1][RTW89_QATAR][42] = 14, - [0][1][RTW89_FCC][44] = 56, - [0][1][RTW89_ETSI][44] = 16, - [0][1][RTW89_MKK][44] = 127, - [0][1][RTW89_IC][44] = 56, -- [0][1][RTW89_KCC][44] = 28, -+ [0][1][RTW89_KCC][44] = 30, - [0][1][RTW89_ACMA][44] = 56, - [0][1][RTW89_CN][44] = 42, - [0][1][RTW89_UK][44] = 18, -+ [0][1][RTW89_MEXICO][44] = 56, -+ [0][1][RTW89_UKRAINE][44] = 14, -+ [0][1][RTW89_CHILE][44] = 56, -+ [0][1][RTW89_QATAR][44] = 14, - [0][1][RTW89_FCC][46] = 56, - [0][1][RTW89_ETSI][46] = 16, - [0][1][RTW89_MKK][46] = 127, - [0][1][RTW89_IC][46] = 56, -- [0][1][RTW89_KCC][46] = 28, -+ [0][1][RTW89_KCC][46] = 30, - [0][1][RTW89_ACMA][46] = 56, - [0][1][RTW89_CN][46] = 42, - [0][1][RTW89_UK][46] = 18, -+ [0][1][RTW89_MEXICO][46] = 56, -+ [0][1][RTW89_UKRAINE][46] = 14, -+ [0][1][RTW89_CHILE][46] = 56, -+ [0][1][RTW89_QATAR][46] = 14, - [0][1][RTW89_FCC][48] = 20, - [0][1][RTW89_ETSI][48] = 127, - [0][1][RTW89_MKK][48] = 127, -@@ -35344,6 +37430,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][48] = 127, - [0][1][RTW89_CN][48] = 127, - [0][1][RTW89_UK][48] = 127, -+ [0][1][RTW89_MEXICO][48] = 127, -+ [0][1][RTW89_UKRAINE][48] = 127, -+ [0][1][RTW89_CHILE][48] = 127, -+ [0][1][RTW89_QATAR][48] = 127, - [0][1][RTW89_FCC][50] = 20, - [0][1][RTW89_ETSI][50] = 127, - [0][1][RTW89_MKK][50] = 127, -@@ -35352,6 +37442,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][50] = 127, - [0][1][RTW89_CN][50] = 127, - [0][1][RTW89_UK][50] = 127, -+ [0][1][RTW89_MEXICO][50] = 127, -+ [0][1][RTW89_UKRAINE][50] = 127, -+ [0][1][RTW89_CHILE][50] = 127, -+ [0][1][RTW89_QATAR][50] = 127, - [0][1][RTW89_FCC][52] = 8, - [0][1][RTW89_ETSI][52] = 127, - [0][1][RTW89_MKK][52] = 127, -@@ -35360,70 +37454,106 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [0][1][RTW89_ACMA][52] = 127, - [0][1][RTW89_CN][52] = 127, - [0][1][RTW89_UK][52] = 127, -+ [0][1][RTW89_MEXICO][52] = 127, -+ [0][1][RTW89_UKRAINE][52] = 127, -+ [0][1][RTW89_CHILE][52] = 127, -+ [0][1][RTW89_QATAR][52] = 127, - [1][0][RTW89_FCC][0] = 62, - [1][0][RTW89_ETSI][0] = 40, - [1][0][RTW89_MKK][0] = 48, - [1][0][RTW89_IC][0] = 42, -- [1][0][RTW89_KCC][0] = 50, -+ [1][0][RTW89_KCC][0] = 54, - [1][0][RTW89_ACMA][0] = 40, - [1][0][RTW89_CN][0] = 26, - [1][0][RTW89_UK][0] = 40, -+ [1][0][RTW89_MEXICO][0] = 62, -+ [1][0][RTW89_UKRAINE][0] = 32, -+ [1][0][RTW89_CHILE][0] = 62, -+ [1][0][RTW89_QATAR][0] = 40, - [1][0][RTW89_FCC][2] = 62, - [1][0][RTW89_ETSI][2] = 40, - [1][0][RTW89_MKK][2] = 48, - [1][0][RTW89_IC][2] = 42, -- [1][0][RTW89_KCC][2] = 50, -+ [1][0][RTW89_KCC][2] = 54, - [1][0][RTW89_ACMA][2] = 40, - [1][0][RTW89_CN][2] = 26, - [1][0][RTW89_UK][2] = 40, -+ [1][0][RTW89_MEXICO][2] = 62, -+ [1][0][RTW89_UKRAINE][2] = 32, -+ [1][0][RTW89_CHILE][2] = 62, -+ [1][0][RTW89_QATAR][2] = 40, - [1][0][RTW89_FCC][4] = 64, - [1][0][RTW89_ETSI][4] = 40, - [1][0][RTW89_MKK][4] = 40, - [1][0][RTW89_IC][4] = 42, -- [1][0][RTW89_KCC][4] = 50, -+ [1][0][RTW89_KCC][4] = 54, - [1][0][RTW89_ACMA][4] = 40, - [1][0][RTW89_CN][4] = 26, - [1][0][RTW89_UK][4] = 40, -+ [1][0][RTW89_MEXICO][4] = 64, -+ [1][0][RTW89_UKRAINE][4] = 32, -+ [1][0][RTW89_CHILE][4] = 64, -+ [1][0][RTW89_QATAR][4] = 40, - [1][0][RTW89_FCC][6] = 64, - [1][0][RTW89_ETSI][6] = 40, - [1][0][RTW89_MKK][6] = 40, - [1][0][RTW89_IC][6] = 42, -- [1][0][RTW89_KCC][6] = 24, -+ [1][0][RTW89_KCC][6] = 32, - [1][0][RTW89_ACMA][6] = 40, - [1][0][RTW89_CN][6] = 26, - [1][0][RTW89_UK][6] = 40, -+ [1][0][RTW89_MEXICO][6] = 64, -+ [1][0][RTW89_UKRAINE][6] = 32, -+ [1][0][RTW89_CHILE][6] = 64, -+ [1][0][RTW89_QATAR][6] = 40, - [1][0][RTW89_FCC][8] = 62, - [1][0][RTW89_ETSI][8] = 40, - [1][0][RTW89_MKK][8] = 34, - [1][0][RTW89_IC][8] = 62, -- [1][0][RTW89_KCC][8] = 52, -+ [1][0][RTW89_KCC][8] = 50, - [1][0][RTW89_ACMA][8] = 40, - [1][0][RTW89_CN][8] = 26, - [1][0][RTW89_UK][8] = 40, -+ [1][0][RTW89_MEXICO][8] = 62, -+ [1][0][RTW89_UKRAINE][8] = 32, -+ [1][0][RTW89_CHILE][8] = 62, -+ [1][0][RTW89_QATAR][8] = 40, - [1][0][RTW89_FCC][10] = 62, - [1][0][RTW89_ETSI][10] = 40, - [1][0][RTW89_MKK][10] = 34, - [1][0][RTW89_IC][10] = 62, -- [1][0][RTW89_KCC][10] = 52, -+ [1][0][RTW89_KCC][10] = 50, - [1][0][RTW89_ACMA][10] = 40, - [1][0][RTW89_CN][10] = 26, - [1][0][RTW89_UK][10] = 40, -+ [1][0][RTW89_MEXICO][10] = 62, -+ [1][0][RTW89_UKRAINE][10] = 32, -+ [1][0][RTW89_CHILE][10] = 62, -+ [1][0][RTW89_QATAR][10] = 40, - [1][0][RTW89_FCC][12] = 62, - [1][0][RTW89_ETSI][12] = 40, - [1][0][RTW89_MKK][12] = 46, - [1][0][RTW89_IC][12] = 62, -- [1][0][RTW89_KCC][12] = 52, -+ [1][0][RTW89_KCC][12] = 50, - [1][0][RTW89_ACMA][12] = 40, - [1][0][RTW89_CN][12] = 26, - [1][0][RTW89_UK][12] = 40, -+ [1][0][RTW89_MEXICO][12] = 62, -+ [1][0][RTW89_UKRAINE][12] = 32, -+ [1][0][RTW89_CHILE][12] = 62, -+ [1][0][RTW89_QATAR][12] = 40, - [1][0][RTW89_FCC][14] = 62, - [1][0][RTW89_ETSI][14] = 40, - [1][0][RTW89_MKK][14] = 46, - [1][0][RTW89_IC][14] = 62, -- [1][0][RTW89_KCC][14] = 52, -+ [1][0][RTW89_KCC][14] = 50, - [1][0][RTW89_ACMA][14] = 40, - [1][0][RTW89_CN][14] = 26, - [1][0][RTW89_UK][14] = 40, -+ [1][0][RTW89_MEXICO][14] = 62, -+ [1][0][RTW89_UKRAINE][14] = 32, -+ [1][0][RTW89_CHILE][14] = 62, -+ [1][0][RTW89_QATAR][14] = 40, - [1][0][RTW89_FCC][15] = 62, - [1][0][RTW89_ETSI][15] = 40, - [1][0][RTW89_MKK][15] = 62, -@@ -35432,6 +37562,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][15] = 40, - [1][0][RTW89_CN][15] = 127, - [1][0][RTW89_UK][15] = 40, -+ [1][0][RTW89_MEXICO][15] = 62, -+ [1][0][RTW89_UKRAINE][15] = 32, -+ [1][0][RTW89_CHILE][15] = 62, -+ [1][0][RTW89_QATAR][15] = 40, - [1][0][RTW89_FCC][17] = 62, - [1][0][RTW89_ETSI][17] = 40, - [1][0][RTW89_MKK][17] = 68, -@@ -35440,6 +37574,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][17] = 40, - [1][0][RTW89_CN][17] = 127, - [1][0][RTW89_UK][17] = 40, -+ [1][0][RTW89_MEXICO][17] = 62, -+ [1][0][RTW89_UKRAINE][17] = 32, -+ [1][0][RTW89_CHILE][17] = 62, -+ [1][0][RTW89_QATAR][17] = 40, - [1][0][RTW89_FCC][19] = 64, - [1][0][RTW89_ETSI][19] = 40, - [1][0][RTW89_MKK][19] = 68, -@@ -35448,6 +37586,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][19] = 40, - [1][0][RTW89_CN][19] = 127, - [1][0][RTW89_UK][19] = 40, -+ [1][0][RTW89_MEXICO][19] = 64, -+ [1][0][RTW89_UKRAINE][19] = 32, -+ [1][0][RTW89_CHILE][19] = 64, -+ [1][0][RTW89_QATAR][19] = 40, - [1][0][RTW89_FCC][21] = 64, - [1][0][RTW89_ETSI][21] = 40, - [1][0][RTW89_MKK][21] = 68, -@@ -35456,6 +37598,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][21] = 40, - [1][0][RTW89_CN][21] = 127, - [1][0][RTW89_UK][21] = 40, -+ [1][0][RTW89_MEXICO][21] = 64, -+ [1][0][RTW89_UKRAINE][21] = 32, -+ [1][0][RTW89_CHILE][21] = 64, -+ [1][0][RTW89_QATAR][21] = 40, - [1][0][RTW89_FCC][23] = 64, - [1][0][RTW89_ETSI][23] = 40, - [1][0][RTW89_MKK][23] = 68, -@@ -35464,6 +37610,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][23] = 40, - [1][0][RTW89_CN][23] = 127, - [1][0][RTW89_UK][23] = 40, -+ [1][0][RTW89_MEXICO][23] = 64, -+ [1][0][RTW89_UKRAINE][23] = 32, -+ [1][0][RTW89_CHILE][23] = 64, -+ [1][0][RTW89_QATAR][23] = 40, - [1][0][RTW89_FCC][25] = 64, - [1][0][RTW89_ETSI][25] = 40, - [1][0][RTW89_MKK][25] = 68, -@@ -35472,6 +37622,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][25] = 127, - [1][0][RTW89_CN][25] = 127, - [1][0][RTW89_UK][25] = 40, -+ [1][0][RTW89_MEXICO][25] = 64, -+ [1][0][RTW89_UKRAINE][25] = 32, -+ [1][0][RTW89_CHILE][25] = 64, -+ [1][0][RTW89_QATAR][25] = 40, - [1][0][RTW89_FCC][27] = 64, - [1][0][RTW89_ETSI][27] = 42, - [1][0][RTW89_MKK][27] = 68, -@@ -35480,6 +37634,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][27] = 127, - [1][0][RTW89_CN][27] = 127, - [1][0][RTW89_UK][27] = 42, -+ [1][0][RTW89_MEXICO][27] = 64, -+ [1][0][RTW89_UKRAINE][27] = 32, -+ [1][0][RTW89_CHILE][27] = 64, -+ [1][0][RTW89_QATAR][27] = 42, - [1][0][RTW89_FCC][29] = 64, - [1][0][RTW89_ETSI][29] = 42, - [1][0][RTW89_MKK][29] = 68, -@@ -35488,38 +37646,58 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][29] = 127, - [1][0][RTW89_CN][29] = 127, - [1][0][RTW89_UK][29] = 42, -+ [1][0][RTW89_MEXICO][29] = 64, -+ [1][0][RTW89_UKRAINE][29] = 32, -+ [1][0][RTW89_CHILE][29] = 64, -+ [1][0][RTW89_QATAR][29] = 42, - [1][0][RTW89_FCC][31] = 64, - [1][0][RTW89_ETSI][31] = 42, - [1][0][RTW89_MKK][31] = 68, - [1][0][RTW89_IC][31] = 56, -- [1][0][RTW89_KCC][31] = 52, -+ [1][0][RTW89_KCC][31] = 50, - [1][0][RTW89_ACMA][31] = 42, - [1][0][RTW89_CN][31] = 127, - [1][0][RTW89_UK][31] = 42, -+ [1][0][RTW89_MEXICO][31] = 64, -+ [1][0][RTW89_UKRAINE][31] = 32, -+ [1][0][RTW89_CHILE][31] = 64, -+ [1][0][RTW89_QATAR][31] = 42, - [1][0][RTW89_FCC][33] = 56, - [1][0][RTW89_ETSI][33] = 42, - [1][0][RTW89_MKK][33] = 68, - [1][0][RTW89_IC][33] = 56, -- [1][0][RTW89_KCC][33] = 52, -+ [1][0][RTW89_KCC][33] = 50, - [1][0][RTW89_ACMA][33] = 42, - [1][0][RTW89_CN][33] = 127, - [1][0][RTW89_UK][33] = 42, -+ [1][0][RTW89_MEXICO][33] = 56, -+ [1][0][RTW89_UKRAINE][33] = 32, -+ [1][0][RTW89_CHILE][33] = 56, -+ [1][0][RTW89_QATAR][33] = 42, - [1][0][RTW89_FCC][35] = 56, - [1][0][RTW89_ETSI][35] = 42, - [1][0][RTW89_MKK][35] = 68, - [1][0][RTW89_IC][35] = 56, -- [1][0][RTW89_KCC][35] = 52, -+ [1][0][RTW89_KCC][35] = 50, - [1][0][RTW89_ACMA][35] = 42, - [1][0][RTW89_CN][35] = 127, - [1][0][RTW89_UK][35] = 42, -+ [1][0][RTW89_MEXICO][35] = 56, -+ [1][0][RTW89_UKRAINE][35] = 32, -+ [1][0][RTW89_CHILE][35] = 56, -+ [1][0][RTW89_QATAR][35] = 42, - [1][0][RTW89_FCC][37] = 66, - [1][0][RTW89_ETSI][37] = 127, - [1][0][RTW89_MKK][37] = 68, - [1][0][RTW89_IC][37] = 66, -- [1][0][RTW89_KCC][37] = 52, -+ [1][0][RTW89_KCC][37] = 50, - [1][0][RTW89_ACMA][37] = 66, - [1][0][RTW89_CN][37] = 127, - [1][0][RTW89_UK][37] = 42, -+ [1][0][RTW89_MEXICO][37] = 66, -+ [1][0][RTW89_UKRAINE][37] = 127, -+ [1][0][RTW89_CHILE][37] = 66, -+ [1][0][RTW89_QATAR][37] = 127, - [1][0][RTW89_FCC][38] = 76, - [1][0][RTW89_ETSI][38] = 28, - [1][0][RTW89_MKK][38] = 127, -@@ -35528,6 +37706,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][38] = 76, - [1][0][RTW89_CN][38] = 66, - [1][0][RTW89_UK][38] = 44, -+ [1][0][RTW89_MEXICO][38] = 76, -+ [1][0][RTW89_UKRAINE][38] = 26, -+ [1][0][RTW89_CHILE][38] = 76, -+ [1][0][RTW89_QATAR][38] = 26, - [1][0][RTW89_FCC][40] = 76, - [1][0][RTW89_ETSI][40] = 28, - [1][0][RTW89_MKK][40] = 127, -@@ -35536,6 +37718,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][40] = 76, - [1][0][RTW89_CN][40] = 66, - [1][0][RTW89_UK][40] = 44, -+ [1][0][RTW89_MEXICO][40] = 76, -+ [1][0][RTW89_UKRAINE][40] = 26, -+ [1][0][RTW89_CHILE][40] = 76, -+ [1][0][RTW89_QATAR][40] = 26, - [1][0][RTW89_FCC][42] = 68, - [1][0][RTW89_ETSI][42] = 28, - [1][0][RTW89_MKK][42] = 127, -@@ -35544,6 +37730,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][42] = 68, - [1][0][RTW89_CN][42] = 66, - [1][0][RTW89_UK][42] = 44, -+ [1][0][RTW89_MEXICO][42] = 68, -+ [1][0][RTW89_UKRAINE][42] = 26, -+ [1][0][RTW89_CHILE][42] = 68, -+ [1][0][RTW89_QATAR][42] = 26, - [1][0][RTW89_FCC][44] = 70, - [1][0][RTW89_ETSI][44] = 28, - [1][0][RTW89_MKK][44] = 127, -@@ -35552,6 +37742,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][44] = 70, - [1][0][RTW89_CN][44] = 66, - [1][0][RTW89_UK][44] = 42, -+ [1][0][RTW89_MEXICO][44] = 70, -+ [1][0][RTW89_UKRAINE][44] = 26, -+ [1][0][RTW89_CHILE][44] = 70, -+ [1][0][RTW89_QATAR][44] = 26, - [1][0][RTW89_FCC][46] = 70, - [1][0][RTW89_ETSI][46] = 28, - [1][0][RTW89_MKK][46] = 127, -@@ -35560,6 +37754,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][46] = 70, - [1][0][RTW89_CN][46] = 66, - [1][0][RTW89_UK][46] = 42, -+ [1][0][RTW89_MEXICO][46] = 70, -+ [1][0][RTW89_UKRAINE][46] = 26, -+ [1][0][RTW89_CHILE][46] = 70, -+ [1][0][RTW89_QATAR][46] = 26, - [1][0][RTW89_FCC][48] = 56, - [1][0][RTW89_ETSI][48] = 127, - [1][0][RTW89_MKK][48] = 127, -@@ -35568,6 +37766,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][48] = 127, - [1][0][RTW89_CN][48] = 127, - [1][0][RTW89_UK][48] = 127, -+ [1][0][RTW89_MEXICO][48] = 127, -+ [1][0][RTW89_UKRAINE][48] = 127, -+ [1][0][RTW89_CHILE][48] = 127, -+ [1][0][RTW89_QATAR][48] = 127, - [1][0][RTW89_FCC][50] = 58, - [1][0][RTW89_ETSI][50] = 127, - [1][0][RTW89_MKK][50] = 127, -@@ -35576,6 +37778,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][50] = 127, - [1][0][RTW89_CN][50] = 127, - [1][0][RTW89_UK][50] = 127, -+ [1][0][RTW89_MEXICO][50] = 127, -+ [1][0][RTW89_UKRAINE][50] = 127, -+ [1][0][RTW89_CHILE][50] = 127, -+ [1][0][RTW89_QATAR][50] = 127, - [1][0][RTW89_FCC][52] = 56, - [1][0][RTW89_ETSI][52] = 127, - [1][0][RTW89_MKK][52] = 127, -@@ -35584,54 +37790,82 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][0][RTW89_ACMA][52] = 127, - [1][0][RTW89_CN][52] = 127, - [1][0][RTW89_UK][52] = 127, -+ [1][0][RTW89_MEXICO][52] = 127, -+ [1][0][RTW89_UKRAINE][52] = 127, -+ [1][0][RTW89_CHILE][52] = 127, -+ [1][0][RTW89_QATAR][52] = 127, - [1][1][RTW89_FCC][0] = 44, - [1][1][RTW89_ETSI][0] = 30, - [1][1][RTW89_MKK][0] = 34, - [1][1][RTW89_IC][0] = 20, -- [1][1][RTW89_KCC][0] = 34, -+ [1][1][RTW89_KCC][0] = 40, - [1][1][RTW89_ACMA][0] = 30, - [1][1][RTW89_CN][0] = 14, - [1][1][RTW89_UK][0] = 30, -+ [1][1][RTW89_MEXICO][0] = 44, -+ [1][1][RTW89_UKRAINE][0] = 20, -+ [1][1][RTW89_CHILE][0] = 44, -+ [1][1][RTW89_QATAR][0] = 30, - [1][1][RTW89_FCC][2] = 44, - [1][1][RTW89_ETSI][2] = 30, - [1][1][RTW89_MKK][2] = 34, - [1][1][RTW89_IC][2] = 18, -- [1][1][RTW89_KCC][2] = 34, -+ [1][1][RTW89_KCC][2] = 40, - [1][1][RTW89_ACMA][2] = 30, - [1][1][RTW89_CN][2] = 14, - [1][1][RTW89_UK][2] = 30, -+ [1][1][RTW89_MEXICO][2] = 44, -+ [1][1][RTW89_UKRAINE][2] = 20, -+ [1][1][RTW89_CHILE][2] = 44, -+ [1][1][RTW89_QATAR][2] = 30, - [1][1][RTW89_FCC][4] = 46, - [1][1][RTW89_ETSI][4] = 30, - [1][1][RTW89_MKK][4] = 26, - [1][1][RTW89_IC][4] = 20, -- [1][1][RTW89_KCC][4] = 34, -+ [1][1][RTW89_KCC][4] = 40, - [1][1][RTW89_ACMA][4] = 30, - [1][1][RTW89_CN][4] = 14, - [1][1][RTW89_UK][4] = 30, -+ [1][1][RTW89_MEXICO][4] = 46, -+ [1][1][RTW89_UKRAINE][4] = 20, -+ [1][1][RTW89_CHILE][4] = 46, -+ [1][1][RTW89_QATAR][4] = 30, - [1][1][RTW89_FCC][6] = 46, - [1][1][RTW89_ETSI][6] = 30, - [1][1][RTW89_MKK][6] = 26, - [1][1][RTW89_IC][6] = 20, -- [1][1][RTW89_KCC][6] = 8, -+ [1][1][RTW89_KCC][6] = 18, - [1][1][RTW89_ACMA][6] = 30, - [1][1][RTW89_CN][6] = 14, - [1][1][RTW89_UK][6] = 30, -+ [1][1][RTW89_MEXICO][6] = 46, -+ [1][1][RTW89_UKRAINE][6] = 20, -+ [1][1][RTW89_CHILE][6] = 46, -+ [1][1][RTW89_QATAR][6] = 30, - [1][1][RTW89_FCC][8] = 44, - [1][1][RTW89_ETSI][8] = 30, - [1][1][RTW89_MKK][8] = 20, - [1][1][RTW89_IC][8] = 44, -- [1][1][RTW89_KCC][8] = 34, -+ [1][1][RTW89_KCC][8] = 38, - [1][1][RTW89_ACMA][8] = 30, - [1][1][RTW89_CN][8] = 14, - [1][1][RTW89_UK][8] = 30, -+ [1][1][RTW89_MEXICO][8] = 44, -+ [1][1][RTW89_UKRAINE][8] = 20, -+ [1][1][RTW89_CHILE][8] = 44, -+ [1][1][RTW89_QATAR][8] = 30, - [1][1][RTW89_FCC][10] = 44, - [1][1][RTW89_ETSI][10] = 30, - [1][1][RTW89_MKK][10] = 20, - [1][1][RTW89_IC][10] = 44, -- [1][1][RTW89_KCC][10] = 34, -+ [1][1][RTW89_KCC][10] = 38, - [1][1][RTW89_ACMA][10] = 30, - [1][1][RTW89_CN][10] = 14, - [1][1][RTW89_UK][10] = 30, -+ [1][1][RTW89_MEXICO][10] = 44, -+ [1][1][RTW89_UKRAINE][10] = 20, -+ [1][1][RTW89_CHILE][10] = 44, -+ [1][1][RTW89_QATAR][10] = 30, - [1][1][RTW89_FCC][12] = 44, - [1][1][RTW89_ETSI][12] = 30, - [1][1][RTW89_MKK][12] = 34, -@@ -35640,6 +37874,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][1][RTW89_ACMA][12] = 30, - [1][1][RTW89_CN][12] = 14, - [1][1][RTW89_UK][12] = 30, -+ [1][1][RTW89_MEXICO][12] = 44, -+ [1][1][RTW89_UKRAINE][12] = 20, -+ [1][1][RTW89_CHILE][12] = 44, -+ [1][1][RTW89_QATAR][12] = 30, - [1][1][RTW89_FCC][14] = 44, - [1][1][RTW89_ETSI][14] = 30, - [1][1][RTW89_MKK][14] = 34, -@@ -35648,142 +37886,214 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][1][RTW89_ACMA][14] = 30, - [1][1][RTW89_CN][14] = 14, - [1][1][RTW89_UK][14] = 30, -+ [1][1][RTW89_MEXICO][14] = 44, -+ [1][1][RTW89_UKRAINE][14] = 20, -+ [1][1][RTW89_CHILE][14] = 44, -+ [1][1][RTW89_QATAR][14] = 30, - [1][1][RTW89_FCC][15] = 44, - [1][1][RTW89_ETSI][15] = 28, - [1][1][RTW89_MKK][15] = 56, - [1][1][RTW89_IC][15] = 44, -- [1][1][RTW89_KCC][15] = 36, -+ [1][1][RTW89_KCC][15] = 38, - [1][1][RTW89_ACMA][15] = 28, - [1][1][RTW89_CN][15] = 127, - [1][1][RTW89_UK][15] = 28, -+ [1][1][RTW89_MEXICO][15] = 44, -+ [1][1][RTW89_UKRAINE][15] = 20, -+ [1][1][RTW89_CHILE][15] = 44, -+ [1][1][RTW89_QATAR][15] = 28, - [1][1][RTW89_FCC][17] = 44, - [1][1][RTW89_ETSI][17] = 28, - [1][1][RTW89_MKK][17] = 58, - [1][1][RTW89_IC][17] = 44, -- [1][1][RTW89_KCC][17] = 36, -+ [1][1][RTW89_KCC][17] = 38, - [1][1][RTW89_ACMA][17] = 28, - [1][1][RTW89_CN][17] = 127, - [1][1][RTW89_UK][17] = 28, -+ [1][1][RTW89_MEXICO][17] = 44, -+ [1][1][RTW89_UKRAINE][17] = 20, -+ [1][1][RTW89_CHILE][17] = 44, -+ [1][1][RTW89_QATAR][17] = 28, - [1][1][RTW89_FCC][19] = 44, - [1][1][RTW89_ETSI][19] = 28, - [1][1][RTW89_MKK][19] = 58, - [1][1][RTW89_IC][19] = 44, -- [1][1][RTW89_KCC][19] = 36, -+ [1][1][RTW89_KCC][19] = 38, - [1][1][RTW89_ACMA][19] = 28, - [1][1][RTW89_CN][19] = 127, - [1][1][RTW89_UK][19] = 28, -+ [1][1][RTW89_MEXICO][19] = 44, -+ [1][1][RTW89_UKRAINE][19] = 20, -+ [1][1][RTW89_CHILE][19] = 44, -+ [1][1][RTW89_QATAR][19] = 28, - [1][1][RTW89_FCC][21] = 44, - [1][1][RTW89_ETSI][21] = 28, - [1][1][RTW89_MKK][21] = 58, - [1][1][RTW89_IC][21] = 44, -- [1][1][RTW89_KCC][21] = 36, -+ [1][1][RTW89_KCC][21] = 38, - [1][1][RTW89_ACMA][21] = 28, - [1][1][RTW89_CN][21] = 127, - [1][1][RTW89_UK][21] = 28, -+ [1][1][RTW89_MEXICO][21] = 44, -+ [1][1][RTW89_UKRAINE][21] = 20, -+ [1][1][RTW89_CHILE][21] = 44, -+ [1][1][RTW89_QATAR][21] = 28, - [1][1][RTW89_FCC][23] = 44, - [1][1][RTW89_ETSI][23] = 28, - [1][1][RTW89_MKK][23] = 58, - [1][1][RTW89_IC][23] = 44, -- [1][1][RTW89_KCC][23] = 36, -+ [1][1][RTW89_KCC][23] = 38, - [1][1][RTW89_ACMA][23] = 28, - [1][1][RTW89_CN][23] = 127, - [1][1][RTW89_UK][23] = 28, -+ [1][1][RTW89_MEXICO][23] = 44, -+ [1][1][RTW89_UKRAINE][23] = 20, -+ [1][1][RTW89_CHILE][23] = 44, -+ [1][1][RTW89_QATAR][23] = 28, - [1][1][RTW89_FCC][25] = 44, - [1][1][RTW89_ETSI][25] = 28, - [1][1][RTW89_MKK][25] = 58, - [1][1][RTW89_IC][25] = 127, -- [1][1][RTW89_KCC][25] = 36, -+ [1][1][RTW89_KCC][25] = 38, - [1][1][RTW89_ACMA][25] = 127, - [1][1][RTW89_CN][25] = 127, - [1][1][RTW89_UK][25] = 28, -+ [1][1][RTW89_MEXICO][25] = 44, -+ [1][1][RTW89_UKRAINE][25] = 20, -+ [1][1][RTW89_CHILE][25] = 44, -+ [1][1][RTW89_QATAR][25] = 28, - [1][1][RTW89_FCC][27] = 44, - [1][1][RTW89_ETSI][27] = 30, - [1][1][RTW89_MKK][27] = 58, - [1][1][RTW89_IC][27] = 127, -- [1][1][RTW89_KCC][27] = 36, -+ [1][1][RTW89_KCC][27] = 38, - [1][1][RTW89_ACMA][27] = 127, - [1][1][RTW89_CN][27] = 127, - [1][1][RTW89_UK][27] = 30, -+ [1][1][RTW89_MEXICO][27] = 44, -+ [1][1][RTW89_UKRAINE][27] = 20, -+ [1][1][RTW89_CHILE][27] = 44, -+ [1][1][RTW89_QATAR][27] = 30, - [1][1][RTW89_FCC][29] = 44, - [1][1][RTW89_ETSI][29] = 30, - [1][1][RTW89_MKK][29] = 58, - [1][1][RTW89_IC][29] = 127, -- [1][1][RTW89_KCC][29] = 36, -+ [1][1][RTW89_KCC][29] = 38, - [1][1][RTW89_ACMA][29] = 127, - [1][1][RTW89_CN][29] = 127, - [1][1][RTW89_UK][29] = 30, -+ [1][1][RTW89_MEXICO][29] = 44, -+ [1][1][RTW89_UKRAINE][29] = 20, -+ [1][1][RTW89_CHILE][29] = 44, -+ [1][1][RTW89_QATAR][29] = 30, - [1][1][RTW89_FCC][31] = 44, - [1][1][RTW89_ETSI][31] = 30, - [1][1][RTW89_MKK][31] = 58, - [1][1][RTW89_IC][31] = 38, -- [1][1][RTW89_KCC][31] = 36, -+ [1][1][RTW89_KCC][31] = 40, - [1][1][RTW89_ACMA][31] = 30, - [1][1][RTW89_CN][31] = 127, - [1][1][RTW89_UK][31] = 30, -+ [1][1][RTW89_MEXICO][31] = 44, -+ [1][1][RTW89_UKRAINE][31] = 20, -+ [1][1][RTW89_CHILE][31] = 44, -+ [1][1][RTW89_QATAR][31] = 30, - [1][1][RTW89_FCC][33] = 38, - [1][1][RTW89_ETSI][33] = 30, - [1][1][RTW89_MKK][33] = 58, - [1][1][RTW89_IC][33] = 38, -- [1][1][RTW89_KCC][33] = 36, -+ [1][1][RTW89_KCC][33] = 40, - [1][1][RTW89_ACMA][33] = 30, - [1][1][RTW89_CN][33] = 127, - [1][1][RTW89_UK][33] = 30, -+ [1][1][RTW89_MEXICO][33] = 38, -+ [1][1][RTW89_UKRAINE][33] = 20, -+ [1][1][RTW89_CHILE][33] = 38, -+ [1][1][RTW89_QATAR][33] = 30, - [1][1][RTW89_FCC][35] = 38, - [1][1][RTW89_ETSI][35] = 30, - [1][1][RTW89_MKK][35] = 58, - [1][1][RTW89_IC][35] = 38, -- [1][1][RTW89_KCC][35] = 36, -+ [1][1][RTW89_KCC][35] = 40, - [1][1][RTW89_ACMA][35] = 30, - [1][1][RTW89_CN][35] = 127, - [1][1][RTW89_UK][35] = 30, -+ [1][1][RTW89_MEXICO][35] = 38, -+ [1][1][RTW89_UKRAINE][35] = 20, -+ [1][1][RTW89_CHILE][35] = 38, -+ [1][1][RTW89_QATAR][35] = 30, - [1][1][RTW89_FCC][37] = 46, - [1][1][RTW89_ETSI][37] = 127, - [1][1][RTW89_MKK][37] = 58, - [1][1][RTW89_IC][37] = 46, -- [1][1][RTW89_KCC][37] = 36, -+ [1][1][RTW89_KCC][37] = 40, - [1][1][RTW89_ACMA][37] = 46, - [1][1][RTW89_CN][37] = 127, - [1][1][RTW89_UK][37] = 32, -+ [1][1][RTW89_MEXICO][37] = 46, -+ [1][1][RTW89_UKRAINE][37] = 127, -+ [1][1][RTW89_CHILE][37] = 46, -+ [1][1][RTW89_QATAR][37] = 127, - [1][1][RTW89_FCC][38] = 74, - [1][1][RTW89_ETSI][38] = 16, - [1][1][RTW89_MKK][38] = 127, - [1][1][RTW89_IC][38] = 74, -- [1][1][RTW89_KCC][38] = 36, -+ [1][1][RTW89_KCC][38] = 38, - [1][1][RTW89_ACMA][38] = 74, - [1][1][RTW89_CN][38] = 54, - [1][1][RTW89_UK][38] = 30, -+ [1][1][RTW89_MEXICO][38] = 74, -+ [1][1][RTW89_UKRAINE][38] = 14, -+ [1][1][RTW89_CHILE][38] = 72, -+ [1][1][RTW89_QATAR][38] = 14, - [1][1][RTW89_FCC][40] = 74, - [1][1][RTW89_ETSI][40] = 16, - [1][1][RTW89_MKK][40] = 127, - [1][1][RTW89_IC][40] = 74, -- [1][1][RTW89_KCC][40] = 36, -+ [1][1][RTW89_KCC][40] = 38, - [1][1][RTW89_ACMA][40] = 74, - [1][1][RTW89_CN][40] = 54, - [1][1][RTW89_UK][40] = 30, -+ [1][1][RTW89_MEXICO][40] = 74, -+ [1][1][RTW89_UKRAINE][40] = 14, -+ [1][1][RTW89_CHILE][40] = 72, -+ [1][1][RTW89_QATAR][40] = 14, - [1][1][RTW89_FCC][42] = 74, - [1][1][RTW89_ETSI][42] = 16, - [1][1][RTW89_MKK][42] = 127, - [1][1][RTW89_IC][42] = 74, -- [1][1][RTW89_KCC][42] = 36, -+ [1][1][RTW89_KCC][42] = 38, - [1][1][RTW89_ACMA][42] = 74, - [1][1][RTW89_CN][42] = 54, - [1][1][RTW89_UK][42] = 30, -+ [1][1][RTW89_MEXICO][42] = 74, -+ [1][1][RTW89_UKRAINE][42] = 14, -+ [1][1][RTW89_CHILE][42] = 72, -+ [1][1][RTW89_QATAR][42] = 14, - [1][1][RTW89_FCC][44] = 74, - [1][1][RTW89_ETSI][44] = 16, - [1][1][RTW89_MKK][44] = 127, - [1][1][RTW89_IC][44] = 74, -- [1][1][RTW89_KCC][44] = 36, -+ [1][1][RTW89_KCC][44] = 38, - [1][1][RTW89_ACMA][44] = 74, - [1][1][RTW89_CN][44] = 54, - [1][1][RTW89_UK][44] = 30, -+ [1][1][RTW89_MEXICO][44] = 74, -+ [1][1][RTW89_UKRAINE][44] = 14, -+ [1][1][RTW89_CHILE][44] = 72, -+ [1][1][RTW89_QATAR][44] = 14, - [1][1][RTW89_FCC][46] = 74, - [1][1][RTW89_ETSI][46] = 16, - [1][1][RTW89_MKK][46] = 127, - [1][1][RTW89_IC][46] = 74, -- [1][1][RTW89_KCC][46] = 36, -+ [1][1][RTW89_KCC][46] = 38, - [1][1][RTW89_ACMA][46] = 74, - [1][1][RTW89_CN][46] = 54, - [1][1][RTW89_UK][46] = 30, -+ [1][1][RTW89_MEXICO][46] = 74, -+ [1][1][RTW89_UKRAINE][46] = 14, -+ [1][1][RTW89_CHILE][46] = 72, -+ [1][1][RTW89_QATAR][46] = 14, - [1][1][RTW89_FCC][48] = 34, - [1][1][RTW89_ETSI][48] = 127, - [1][1][RTW89_MKK][48] = 127, -@@ -35792,6 +38102,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][1][RTW89_ACMA][48] = 127, - [1][1][RTW89_CN][48] = 127, - [1][1][RTW89_UK][48] = 127, -+ [1][1][RTW89_MEXICO][48] = 127, -+ [1][1][RTW89_UKRAINE][48] = 127, -+ [1][1][RTW89_CHILE][48] = 127, -+ [1][1][RTW89_QATAR][48] = 127, - [1][1][RTW89_FCC][50] = 34, - [1][1][RTW89_ETSI][50] = 127, - [1][1][RTW89_MKK][50] = 127, -@@ -35800,6 +38114,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][1][RTW89_ACMA][50] = 127, - [1][1][RTW89_CN][50] = 127, - [1][1][RTW89_UK][50] = 127, -+ [1][1][RTW89_MEXICO][50] = 127, -+ [1][1][RTW89_UKRAINE][50] = 127, -+ [1][1][RTW89_CHILE][50] = 127, -+ [1][1][RTW89_QATAR][50] = 127, - [1][1][RTW89_FCC][52] = 30, - [1][1][RTW89_ETSI][52] = 127, - [1][1][RTW89_MKK][52] = 127, -@@ -35808,206 +38126,310 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [1][1][RTW89_ACMA][52] = 127, - [1][1][RTW89_CN][52] = 127, - [1][1][RTW89_UK][52] = 127, -+ [1][1][RTW89_MEXICO][52] = 127, -+ [1][1][RTW89_UKRAINE][52] = 127, -+ [1][1][RTW89_CHILE][52] = 127, -+ [1][1][RTW89_QATAR][52] = 127, - [2][0][RTW89_FCC][0] = 68, - [2][0][RTW89_ETSI][0] = 52, - [2][0][RTW89_MKK][0] = 60, - [2][0][RTW89_IC][0] = 52, -- [2][0][RTW89_KCC][0] = 64, -+ [2][0][RTW89_KCC][0] = 60, - [2][0][RTW89_ACMA][0] = 52, - [2][0][RTW89_CN][0] = 40, - [2][0][RTW89_UK][0] = 52, -+ [2][0][RTW89_MEXICO][0] = 62, -+ [2][0][RTW89_UKRAINE][0] = 46, -+ [2][0][RTW89_CHILE][0] = 68, -+ [2][0][RTW89_QATAR][0] = 52, - [2][0][RTW89_FCC][2] = 64, - [2][0][RTW89_ETSI][2] = 52, - [2][0][RTW89_MKK][2] = 60, - [2][0][RTW89_IC][2] = 50, -- [2][0][RTW89_KCC][2] = 64, -+ [2][0][RTW89_KCC][2] = 60, - [2][0][RTW89_ACMA][2] = 52, - [2][0][RTW89_CN][2] = 40, - [2][0][RTW89_UK][2] = 52, -+ [2][0][RTW89_MEXICO][2] = 62, -+ [2][0][RTW89_UKRAINE][2] = 46, -+ [2][0][RTW89_CHILE][2] = 64, -+ [2][0][RTW89_QATAR][2] = 52, - [2][0][RTW89_FCC][4] = 68, - [2][0][RTW89_ETSI][4] = 52, - [2][0][RTW89_MKK][4] = 50, - [2][0][RTW89_IC][4] = 50, -- [2][0][RTW89_KCC][4] = 64, -+ [2][0][RTW89_KCC][4] = 60, - [2][0][RTW89_ACMA][4] = 52, - [2][0][RTW89_CN][4] = 40, - [2][0][RTW89_UK][4] = 52, -+ [2][0][RTW89_MEXICO][4] = 62, -+ [2][0][RTW89_UKRAINE][4] = 46, -+ [2][0][RTW89_CHILE][4] = 68, -+ [2][0][RTW89_QATAR][4] = 52, - [2][0][RTW89_FCC][6] = 68, - [2][0][RTW89_ETSI][6] = 52, - [2][0][RTW89_MKK][6] = 50, - [2][0][RTW89_IC][6] = 50, -- [2][0][RTW89_KCC][6] = 36, -+ [2][0][RTW89_KCC][6] = 38, - [2][0][RTW89_ACMA][6] = 52, - [2][0][RTW89_CN][6] = 40, - [2][0][RTW89_UK][6] = 52, -+ [2][0][RTW89_MEXICO][6] = 62, -+ [2][0][RTW89_UKRAINE][6] = 46, -+ [2][0][RTW89_CHILE][6] = 68, -+ [2][0][RTW89_QATAR][6] = 52, - [2][0][RTW89_FCC][8] = 68, - [2][0][RTW89_ETSI][8] = 52, - [2][0][RTW89_MKK][8] = 44, - [2][0][RTW89_IC][8] = 64, -- [2][0][RTW89_KCC][8] = 62, -+ [2][0][RTW89_KCC][8] = 56, - [2][0][RTW89_ACMA][8] = 52, - [2][0][RTW89_CN][8] = 40, - [2][0][RTW89_UK][8] = 52, -+ [2][0][RTW89_MEXICO][8] = 68, -+ [2][0][RTW89_UKRAINE][8] = 46, -+ [2][0][RTW89_CHILE][8] = 68, -+ [2][0][RTW89_QATAR][8] = 52, - [2][0][RTW89_FCC][10] = 68, - [2][0][RTW89_ETSI][10] = 52, - [2][0][RTW89_MKK][10] = 44, - [2][0][RTW89_IC][10] = 64, -- [2][0][RTW89_KCC][10] = 62, -+ [2][0][RTW89_KCC][10] = 56, - [2][0][RTW89_ACMA][10] = 52, - [2][0][RTW89_CN][10] = 40, - [2][0][RTW89_UK][10] = 52, -+ [2][0][RTW89_MEXICO][10] = 68, -+ [2][0][RTW89_UKRAINE][10] = 46, -+ [2][0][RTW89_CHILE][10] = 68, -+ [2][0][RTW89_QATAR][10] = 52, - [2][0][RTW89_FCC][12] = 68, - [2][0][RTW89_ETSI][12] = 52, - [2][0][RTW89_MKK][12] = 58, - [2][0][RTW89_IC][12] = 64, -- [2][0][RTW89_KCC][12] = 62, -+ [2][0][RTW89_KCC][12] = 58, - [2][0][RTW89_ACMA][12] = 52, - [2][0][RTW89_CN][12] = 40, - [2][0][RTW89_UK][12] = 52, -+ [2][0][RTW89_MEXICO][12] = 68, -+ [2][0][RTW89_UKRAINE][12] = 46, -+ [2][0][RTW89_CHILE][12] = 68, -+ [2][0][RTW89_QATAR][12] = 52, - [2][0][RTW89_FCC][14] = 68, - [2][0][RTW89_ETSI][14] = 52, - [2][0][RTW89_MKK][14] = 58, - [2][0][RTW89_IC][14] = 64, -- [2][0][RTW89_KCC][14] = 62, -+ [2][0][RTW89_KCC][14] = 58, - [2][0][RTW89_ACMA][14] = 52, - [2][0][RTW89_CN][14] = 40, - [2][0][RTW89_UK][14] = 52, -+ [2][0][RTW89_MEXICO][14] = 68, -+ [2][0][RTW89_UKRAINE][14] = 46, -+ [2][0][RTW89_CHILE][14] = 68, -+ [2][0][RTW89_QATAR][14] = 52, - [2][0][RTW89_FCC][15] = 68, - [2][0][RTW89_ETSI][15] = 52, - [2][0][RTW89_MKK][15] = 68, - [2][0][RTW89_IC][15] = 68, -- [2][0][RTW89_KCC][15] = 62, -+ [2][0][RTW89_KCC][15] = 58, - [2][0][RTW89_ACMA][15] = 52, - [2][0][RTW89_CN][15] = 127, - [2][0][RTW89_UK][15] = 52, -+ [2][0][RTW89_MEXICO][15] = 68, -+ [2][0][RTW89_UKRAINE][15] = 46, -+ [2][0][RTW89_CHILE][15] = 68, -+ [2][0][RTW89_QATAR][15] = 52, - [2][0][RTW89_FCC][17] = 68, - [2][0][RTW89_ETSI][17] = 52, - [2][0][RTW89_MKK][17] = 74, - [2][0][RTW89_IC][17] = 68, -- [2][0][RTW89_KCC][17] = 62, -+ [2][0][RTW89_KCC][17] = 58, - [2][0][RTW89_ACMA][17] = 52, - [2][0][RTW89_CN][17] = 127, - [2][0][RTW89_UK][17] = 52, -+ [2][0][RTW89_MEXICO][17] = 68, -+ [2][0][RTW89_UKRAINE][17] = 46, -+ [2][0][RTW89_CHILE][17] = 68, -+ [2][0][RTW89_QATAR][17] = 52, - [2][0][RTW89_FCC][19] = 70, - [2][0][RTW89_ETSI][19] = 52, - [2][0][RTW89_MKK][19] = 74, - [2][0][RTW89_IC][19] = 70, -- [2][0][RTW89_KCC][19] = 62, -+ [2][0][RTW89_KCC][19] = 58, - [2][0][RTW89_ACMA][19] = 52, - [2][0][RTW89_CN][19] = 127, - [2][0][RTW89_UK][19] = 52, -+ [2][0][RTW89_MEXICO][19] = 70, -+ [2][0][RTW89_UKRAINE][19] = 46, -+ [2][0][RTW89_CHILE][19] = 70, -+ [2][0][RTW89_QATAR][19] = 52, - [2][0][RTW89_FCC][21] = 70, - [2][0][RTW89_ETSI][21] = 52, - [2][0][RTW89_MKK][21] = 74, - [2][0][RTW89_IC][21] = 70, -- [2][0][RTW89_KCC][21] = 62, -+ [2][0][RTW89_KCC][21] = 58, - [2][0][RTW89_ACMA][21] = 52, - [2][0][RTW89_CN][21] = 127, - [2][0][RTW89_UK][21] = 52, -+ [2][0][RTW89_MEXICO][21] = 70, -+ [2][0][RTW89_UKRAINE][21] = 46, -+ [2][0][RTW89_CHILE][21] = 70, -+ [2][0][RTW89_QATAR][21] = 52, - [2][0][RTW89_FCC][23] = 70, - [2][0][RTW89_ETSI][23] = 52, - [2][0][RTW89_MKK][23] = 74, - [2][0][RTW89_IC][23] = 70, -- [2][0][RTW89_KCC][23] = 62, -+ [2][0][RTW89_KCC][23] = 58, - [2][0][RTW89_ACMA][23] = 52, - [2][0][RTW89_CN][23] = 127, - [2][0][RTW89_UK][23] = 52, -+ [2][0][RTW89_MEXICO][23] = 70, -+ [2][0][RTW89_UKRAINE][23] = 46, -+ [2][0][RTW89_CHILE][23] = 70, -+ [2][0][RTW89_QATAR][23] = 52, - [2][0][RTW89_FCC][25] = 70, - [2][0][RTW89_ETSI][25] = 52, - [2][0][RTW89_MKK][25] = 74, - [2][0][RTW89_IC][25] = 127, -- [2][0][RTW89_KCC][25] = 62, -+ [2][0][RTW89_KCC][25] = 58, - [2][0][RTW89_ACMA][25] = 127, - [2][0][RTW89_CN][25] = 127, - [2][0][RTW89_UK][25] = 52, -+ [2][0][RTW89_MEXICO][25] = 70, -+ [2][0][RTW89_UKRAINE][25] = 46, -+ [2][0][RTW89_CHILE][25] = 70, -+ [2][0][RTW89_QATAR][25] = 52, - [2][0][RTW89_FCC][27] = 70, - [2][0][RTW89_ETSI][27] = 52, - [2][0][RTW89_MKK][27] = 74, - [2][0][RTW89_IC][27] = 127, -- [2][0][RTW89_KCC][27] = 62, -+ [2][0][RTW89_KCC][27] = 58, - [2][0][RTW89_ACMA][27] = 127, - [2][0][RTW89_CN][27] = 127, - [2][0][RTW89_UK][27] = 52, -+ [2][0][RTW89_MEXICO][27] = 70, -+ [2][0][RTW89_UKRAINE][27] = 46, -+ [2][0][RTW89_CHILE][27] = 70, -+ [2][0][RTW89_QATAR][27] = 52, - [2][0][RTW89_FCC][29] = 70, - [2][0][RTW89_ETSI][29] = 52, - [2][0][RTW89_MKK][29] = 74, - [2][0][RTW89_IC][29] = 127, -- [2][0][RTW89_KCC][29] = 62, -+ [2][0][RTW89_KCC][29] = 58, - [2][0][RTW89_ACMA][29] = 127, - [2][0][RTW89_CN][29] = 127, - [2][0][RTW89_UK][29] = 52, -+ [2][0][RTW89_MEXICO][29] = 70, -+ [2][0][RTW89_UKRAINE][29] = 46, -+ [2][0][RTW89_CHILE][29] = 70, -+ [2][0][RTW89_QATAR][29] = 52, - [2][0][RTW89_FCC][31] = 70, - [2][0][RTW89_ETSI][31] = 52, - [2][0][RTW89_MKK][31] = 74, - [2][0][RTW89_IC][31] = 62, -- [2][0][RTW89_KCC][31] = 62, -+ [2][0][RTW89_KCC][31] = 56, - [2][0][RTW89_ACMA][31] = 52, - [2][0][RTW89_CN][31] = 127, - [2][0][RTW89_UK][31] = 52, -+ [2][0][RTW89_MEXICO][31] = 70, -+ [2][0][RTW89_UKRAINE][31] = 46, -+ [2][0][RTW89_CHILE][31] = 70, -+ [2][0][RTW89_QATAR][31] = 52, - [2][0][RTW89_FCC][33] = 62, - [2][0][RTW89_ETSI][33] = 52, - [2][0][RTW89_MKK][33] = 74, - [2][0][RTW89_IC][33] = 62, -- [2][0][RTW89_KCC][33] = 62, -+ [2][0][RTW89_KCC][33] = 56, - [2][0][RTW89_ACMA][33] = 52, - [2][0][RTW89_CN][33] = 127, - [2][0][RTW89_UK][33] = 52, -+ [2][0][RTW89_MEXICO][33] = 62, -+ [2][0][RTW89_UKRAINE][33] = 46, -+ [2][0][RTW89_CHILE][33] = 62, -+ [2][0][RTW89_QATAR][33] = 52, - [2][0][RTW89_FCC][35] = 62, - [2][0][RTW89_ETSI][35] = 52, - [2][0][RTW89_MKK][35] = 74, - [2][0][RTW89_IC][35] = 62, -- [2][0][RTW89_KCC][35] = 62, -+ [2][0][RTW89_KCC][35] = 56, - [2][0][RTW89_ACMA][35] = 52, - [2][0][RTW89_CN][35] = 127, - [2][0][RTW89_UK][35] = 52, -+ [2][0][RTW89_MEXICO][35] = 62, -+ [2][0][RTW89_UKRAINE][35] = 46, -+ [2][0][RTW89_CHILE][35] = 62, -+ [2][0][RTW89_QATAR][35] = 52, - [2][0][RTW89_FCC][37] = 70, - [2][0][RTW89_ETSI][37] = 127, - [2][0][RTW89_MKK][37] = 74, - [2][0][RTW89_IC][37] = 70, -- [2][0][RTW89_KCC][37] = 62, -+ [2][0][RTW89_KCC][37] = 56, - [2][0][RTW89_ACMA][37] = 70, - [2][0][RTW89_CN][37] = 127, - [2][0][RTW89_UK][37] = 52, -+ [2][0][RTW89_MEXICO][37] = 70, -+ [2][0][RTW89_UKRAINE][37] = 127, -+ [2][0][RTW89_CHILE][37] = 70, -+ [2][0][RTW89_QATAR][37] = 127, - [2][0][RTW89_FCC][38] = 82, - [2][0][RTW89_ETSI][38] = 28, - [2][0][RTW89_MKK][38] = 127, - [2][0][RTW89_IC][38] = 82, -- [2][0][RTW89_KCC][38] = 64, -+ [2][0][RTW89_KCC][38] = 60, - [2][0][RTW89_ACMA][38] = 82, - [2][0][RTW89_CN][38] = 68, - [2][0][RTW89_UK][38] = 54, -+ [2][0][RTW89_MEXICO][38] = 82, -+ [2][0][RTW89_UKRAINE][38] = 26, -+ [2][0][RTW89_CHILE][38] = 82, -+ [2][0][RTW89_QATAR][38] = 26, - [2][0][RTW89_FCC][40] = 82, - [2][0][RTW89_ETSI][40] = 28, - [2][0][RTW89_MKK][40] = 127, - [2][0][RTW89_IC][40] = 82, -- [2][0][RTW89_KCC][40] = 64, -+ [2][0][RTW89_KCC][40] = 60, - [2][0][RTW89_ACMA][40] = 82, - [2][0][RTW89_CN][40] = 68, - [2][0][RTW89_UK][40] = 54, -+ [2][0][RTW89_MEXICO][40] = 82, -+ [2][0][RTW89_UKRAINE][40] = 26, -+ [2][0][RTW89_CHILE][40] = 82, -+ [2][0][RTW89_QATAR][40] = 26, - [2][0][RTW89_FCC][42] = 76, - [2][0][RTW89_ETSI][42] = 28, - [2][0][RTW89_MKK][42] = 127, - [2][0][RTW89_IC][42] = 76, -- [2][0][RTW89_KCC][42] = 64, -+ [2][0][RTW89_KCC][42] = 60, - [2][0][RTW89_ACMA][42] = 76, - [2][0][RTW89_CN][42] = 68, - [2][0][RTW89_UK][42] = 54, -+ [2][0][RTW89_MEXICO][42] = 76, -+ [2][0][RTW89_UKRAINE][42] = 26, -+ [2][0][RTW89_CHILE][42] = 76, -+ [2][0][RTW89_QATAR][42] = 26, - [2][0][RTW89_FCC][44] = 80, - [2][0][RTW89_ETSI][44] = 28, - [2][0][RTW89_MKK][44] = 127, - [2][0][RTW89_IC][44] = 80, -- [2][0][RTW89_KCC][44] = 64, -+ [2][0][RTW89_KCC][44] = 60, - [2][0][RTW89_ACMA][44] = 80, - [2][0][RTW89_CN][44] = 68, - [2][0][RTW89_UK][44] = 54, -+ [2][0][RTW89_MEXICO][44] = 80, -+ [2][0][RTW89_UKRAINE][44] = 26, -+ [2][0][RTW89_CHILE][44] = 80, -+ [2][0][RTW89_QATAR][44] = 26, - [2][0][RTW89_FCC][46] = 80, - [2][0][RTW89_ETSI][46] = 28, - [2][0][RTW89_MKK][46] = 127, - [2][0][RTW89_IC][46] = 80, -- [2][0][RTW89_KCC][46] = 64, -+ [2][0][RTW89_KCC][46] = 60, - [2][0][RTW89_ACMA][46] = 80, - [2][0][RTW89_CN][46] = 68, - [2][0][RTW89_UK][46] = 54, -+ [2][0][RTW89_MEXICO][46] = 80, -+ [2][0][RTW89_UKRAINE][46] = 26, -+ [2][0][RTW89_CHILE][46] = 80, -+ [2][0][RTW89_QATAR][46] = 26, - [2][0][RTW89_FCC][48] = 64, - [2][0][RTW89_ETSI][48] = 127, - [2][0][RTW89_MKK][48] = 127, -@@ -36016,6 +38438,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][0][RTW89_ACMA][48] = 127, - [2][0][RTW89_CN][48] = 127, - [2][0][RTW89_UK][48] = 127, -+ [2][0][RTW89_MEXICO][48] = 127, -+ [2][0][RTW89_UKRAINE][48] = 127, -+ [2][0][RTW89_CHILE][48] = 127, -+ [2][0][RTW89_QATAR][48] = 127, - [2][0][RTW89_FCC][50] = 64, - [2][0][RTW89_ETSI][50] = 127, - [2][0][RTW89_MKK][50] = 127, -@@ -36024,6 +38450,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][0][RTW89_ACMA][50] = 127, - [2][0][RTW89_CN][50] = 127, - [2][0][RTW89_UK][50] = 127, -+ [2][0][RTW89_MEXICO][50] = 127, -+ [2][0][RTW89_UKRAINE][50] = 127, -+ [2][0][RTW89_CHILE][50] = 127, -+ [2][0][RTW89_QATAR][50] = 127, - [2][0][RTW89_FCC][52] = 64, - [2][0][RTW89_ETSI][52] = 127, - [2][0][RTW89_MKK][52] = 127, -@@ -36032,206 +38462,310 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][0][RTW89_ACMA][52] = 127, - [2][0][RTW89_CN][52] = 127, - [2][0][RTW89_UK][52] = 127, -+ [2][0][RTW89_MEXICO][52] = 127, -+ [2][0][RTW89_UKRAINE][52] = 127, -+ [2][0][RTW89_CHILE][52] = 127, -+ [2][0][RTW89_QATAR][52] = 127, - [2][1][RTW89_FCC][0] = 50, - [2][1][RTW89_ETSI][0] = 40, - [2][1][RTW89_MKK][0] = 44, - [2][1][RTW89_IC][0] = 26, -- [2][1][RTW89_KCC][0] = 44, -+ [2][1][RTW89_KCC][0] = 52, - [2][1][RTW89_ACMA][0] = 40, - [2][1][RTW89_CN][0] = 28, - [2][1][RTW89_UK][0] = 40, -+ [2][1][RTW89_MEXICO][0] = 50, -+ [2][1][RTW89_UKRAINE][0] = 34, -+ [2][1][RTW89_CHILE][0] = 50, -+ [2][1][RTW89_QATAR][0] = 40, - [2][1][RTW89_FCC][2] = 50, - [2][1][RTW89_ETSI][2] = 40, - [2][1][RTW89_MKK][2] = 44, - [2][1][RTW89_IC][2] = 26, -- [2][1][RTW89_KCC][2] = 44, -+ [2][1][RTW89_KCC][2] = 52, - [2][1][RTW89_ACMA][2] = 40, - [2][1][RTW89_CN][2] = 28, - [2][1][RTW89_UK][2] = 40, -+ [2][1][RTW89_MEXICO][2] = 50, -+ [2][1][RTW89_UKRAINE][2] = 34, -+ [2][1][RTW89_CHILE][2] = 50, -+ [2][1][RTW89_QATAR][2] = 40, - [2][1][RTW89_FCC][4] = 50, - [2][1][RTW89_ETSI][4] = 40, - [2][1][RTW89_MKK][4] = 36, - [2][1][RTW89_IC][4] = 26, -- [2][1][RTW89_KCC][4] = 44, -+ [2][1][RTW89_KCC][4] = 52, - [2][1][RTW89_ACMA][4] = 40, - [2][1][RTW89_CN][4] = 28, - [2][1][RTW89_UK][4] = 40, -+ [2][1][RTW89_MEXICO][4] = 50, -+ [2][1][RTW89_UKRAINE][4] = 34, -+ [2][1][RTW89_CHILE][4] = 50, -+ [2][1][RTW89_QATAR][4] = 40, - [2][1][RTW89_FCC][6] = 50, - [2][1][RTW89_ETSI][6] = 40, - [2][1][RTW89_MKK][6] = 36, - [2][1][RTW89_IC][6] = 26, -- [2][1][RTW89_KCC][6] = 20, -+ [2][1][RTW89_KCC][6] = 30, - [2][1][RTW89_ACMA][6] = 40, - [2][1][RTW89_CN][6] = 28, - [2][1][RTW89_UK][6] = 40, -+ [2][1][RTW89_MEXICO][6] = 50, -+ [2][1][RTW89_UKRAINE][6] = 34, -+ [2][1][RTW89_CHILE][6] = 50, -+ [2][1][RTW89_QATAR][6] = 40, - [2][1][RTW89_FCC][8] = 50, - [2][1][RTW89_ETSI][8] = 40, - [2][1][RTW89_MKK][8] = 32, - [2][1][RTW89_IC][8] = 50, -- [2][1][RTW89_KCC][8] = 46, -+ [2][1][RTW89_KCC][8] = 50, - [2][1][RTW89_ACMA][8] = 40, - [2][1][RTW89_CN][8] = 28, - [2][1][RTW89_UK][8] = 40, -+ [2][1][RTW89_MEXICO][8] = 50, -+ [2][1][RTW89_UKRAINE][8] = 34, -+ [2][1][RTW89_CHILE][8] = 50, -+ [2][1][RTW89_QATAR][8] = 40, - [2][1][RTW89_FCC][10] = 50, - [2][1][RTW89_ETSI][10] = 40, - [2][1][RTW89_MKK][10] = 32, - [2][1][RTW89_IC][10] = 50, -- [2][1][RTW89_KCC][10] = 46, -+ [2][1][RTW89_KCC][10] = 50, - [2][1][RTW89_ACMA][10] = 40, - [2][1][RTW89_CN][10] = 28, - [2][1][RTW89_UK][10] = 40, -+ [2][1][RTW89_MEXICO][10] = 50, -+ [2][1][RTW89_UKRAINE][10] = 34, -+ [2][1][RTW89_CHILE][10] = 50, -+ [2][1][RTW89_QATAR][10] = 40, - [2][1][RTW89_FCC][12] = 48, - [2][1][RTW89_ETSI][12] = 40, - [2][1][RTW89_MKK][12] = 44, - [2][1][RTW89_IC][12] = 48, -- [2][1][RTW89_KCC][12] = 46, -+ [2][1][RTW89_KCC][12] = 48, - [2][1][RTW89_ACMA][12] = 40, - [2][1][RTW89_CN][12] = 28, - [2][1][RTW89_UK][12] = 40, -+ [2][1][RTW89_MEXICO][12] = 48, -+ [2][1][RTW89_UKRAINE][12] = 34, -+ [2][1][RTW89_CHILE][12] = 48, -+ [2][1][RTW89_QATAR][12] = 40, - [2][1][RTW89_FCC][14] = 48, - [2][1][RTW89_ETSI][14] = 40, - [2][1][RTW89_MKK][14] = 44, - [2][1][RTW89_IC][14] = 48, -- [2][1][RTW89_KCC][14] = 46, -+ [2][1][RTW89_KCC][14] = 48, - [2][1][RTW89_ACMA][14] = 40, - [2][1][RTW89_CN][14] = 28, - [2][1][RTW89_UK][14] = 40, -+ [2][1][RTW89_MEXICO][14] = 48, -+ [2][1][RTW89_UKRAINE][14] = 34, -+ [2][1][RTW89_CHILE][14] = 48, -+ [2][1][RTW89_QATAR][14] = 40, - [2][1][RTW89_FCC][15] = 50, - [2][1][RTW89_ETSI][15] = 40, - [2][1][RTW89_MKK][15] = 66, - [2][1][RTW89_IC][15] = 50, -- [2][1][RTW89_KCC][15] = 46, -+ [2][1][RTW89_KCC][15] = 48, - [2][1][RTW89_ACMA][15] = 40, - [2][1][RTW89_CN][15] = 127, - [2][1][RTW89_UK][15] = 40, -+ [2][1][RTW89_MEXICO][15] = 50, -+ [2][1][RTW89_UKRAINE][15] = 34, -+ [2][1][RTW89_CHILE][15] = 50, -+ [2][1][RTW89_QATAR][15] = 40, - [2][1][RTW89_FCC][17] = 50, - [2][1][RTW89_ETSI][17] = 40, - [2][1][RTW89_MKK][17] = 66, - [2][1][RTW89_IC][17] = 50, -- [2][1][RTW89_KCC][17] = 46, -+ [2][1][RTW89_KCC][17] = 48, - [2][1][RTW89_ACMA][17] = 40, - [2][1][RTW89_CN][17] = 127, - [2][1][RTW89_UK][17] = 40, -+ [2][1][RTW89_MEXICO][17] = 50, -+ [2][1][RTW89_UKRAINE][17] = 34, -+ [2][1][RTW89_CHILE][17] = 50, -+ [2][1][RTW89_QATAR][17] = 40, - [2][1][RTW89_FCC][19] = 50, - [2][1][RTW89_ETSI][19] = 40, - [2][1][RTW89_MKK][19] = 66, - [2][1][RTW89_IC][19] = 50, -- [2][1][RTW89_KCC][19] = 46, -+ [2][1][RTW89_KCC][19] = 48, - [2][1][RTW89_ACMA][19] = 40, - [2][1][RTW89_CN][19] = 127, - [2][1][RTW89_UK][19] = 40, -+ [2][1][RTW89_MEXICO][19] = 50, -+ [2][1][RTW89_UKRAINE][19] = 34, -+ [2][1][RTW89_CHILE][19] = 50, -+ [2][1][RTW89_QATAR][19] = 40, - [2][1][RTW89_FCC][21] = 50, - [2][1][RTW89_ETSI][21] = 40, - [2][1][RTW89_MKK][21] = 66, - [2][1][RTW89_IC][21] = 50, -- [2][1][RTW89_KCC][21] = 46, -+ [2][1][RTW89_KCC][21] = 48, - [2][1][RTW89_ACMA][21] = 40, - [2][1][RTW89_CN][21] = 127, - [2][1][RTW89_UK][21] = 40, -+ [2][1][RTW89_MEXICO][21] = 50, -+ [2][1][RTW89_UKRAINE][21] = 34, -+ [2][1][RTW89_CHILE][21] = 50, -+ [2][1][RTW89_QATAR][21] = 40, - [2][1][RTW89_FCC][23] = 50, - [2][1][RTW89_ETSI][23] = 40, - [2][1][RTW89_MKK][23] = 66, - [2][1][RTW89_IC][23] = 50, -- [2][1][RTW89_KCC][23] = 46, -+ [2][1][RTW89_KCC][23] = 48, - [2][1][RTW89_ACMA][23] = 40, - [2][1][RTW89_CN][23] = 127, - [2][1][RTW89_UK][23] = 40, -+ [2][1][RTW89_MEXICO][23] = 50, -+ [2][1][RTW89_UKRAINE][23] = 34, -+ [2][1][RTW89_CHILE][23] = 50, -+ [2][1][RTW89_QATAR][23] = 40, - [2][1][RTW89_FCC][25] = 50, - [2][1][RTW89_ETSI][25] = 40, - [2][1][RTW89_MKK][25] = 66, - [2][1][RTW89_IC][25] = 127, -- [2][1][RTW89_KCC][25] = 46, -+ [2][1][RTW89_KCC][25] = 48, - [2][1][RTW89_ACMA][25] = 127, - [2][1][RTW89_CN][25] = 127, - [2][1][RTW89_UK][25] = 40, -+ [2][1][RTW89_MEXICO][25] = 50, -+ [2][1][RTW89_UKRAINE][25] = 34, -+ [2][1][RTW89_CHILE][25] = 50, -+ [2][1][RTW89_QATAR][25] = 40, - [2][1][RTW89_FCC][27] = 50, - [2][1][RTW89_ETSI][27] = 40, - [2][1][RTW89_MKK][27] = 66, - [2][1][RTW89_IC][27] = 127, -- [2][1][RTW89_KCC][27] = 46, -+ [2][1][RTW89_KCC][27] = 48, - [2][1][RTW89_ACMA][27] = 127, - [2][1][RTW89_CN][27] = 127, - [2][1][RTW89_UK][27] = 40, -+ [2][1][RTW89_MEXICO][27] = 50, -+ [2][1][RTW89_UKRAINE][27] = 34, -+ [2][1][RTW89_CHILE][27] = 50, -+ [2][1][RTW89_QATAR][27] = 40, - [2][1][RTW89_FCC][29] = 50, - [2][1][RTW89_ETSI][29] = 40, - [2][1][RTW89_MKK][29] = 66, - [2][1][RTW89_IC][29] = 127, -- [2][1][RTW89_KCC][29] = 46, -+ [2][1][RTW89_KCC][29] = 48, - [2][1][RTW89_ACMA][29] = 127, - [2][1][RTW89_CN][29] = 127, - [2][1][RTW89_UK][29] = 40, -+ [2][1][RTW89_MEXICO][29] = 50, -+ [2][1][RTW89_UKRAINE][29] = 34, -+ [2][1][RTW89_CHILE][29] = 50, -+ [2][1][RTW89_QATAR][29] = 40, - [2][1][RTW89_FCC][31] = 50, - [2][1][RTW89_ETSI][31] = 40, - [2][1][RTW89_MKK][31] = 66, - [2][1][RTW89_IC][31] = 48, -- [2][1][RTW89_KCC][31] = 46, -+ [2][1][RTW89_KCC][31] = 48, - [2][1][RTW89_ACMA][31] = 40, - [2][1][RTW89_CN][31] = 127, - [2][1][RTW89_UK][31] = 40, -+ [2][1][RTW89_MEXICO][31] = 50, -+ [2][1][RTW89_UKRAINE][31] = 34, -+ [2][1][RTW89_CHILE][31] = 50, -+ [2][1][RTW89_QATAR][31] = 40, - [2][1][RTW89_FCC][33] = 48, - [2][1][RTW89_ETSI][33] = 40, - [2][1][RTW89_MKK][33] = 66, - [2][1][RTW89_IC][33] = 48, -- [2][1][RTW89_KCC][33] = 46, -+ [2][1][RTW89_KCC][33] = 48, - [2][1][RTW89_ACMA][33] = 40, - [2][1][RTW89_CN][33] = 127, - [2][1][RTW89_UK][33] = 40, -+ [2][1][RTW89_MEXICO][33] = 48, -+ [2][1][RTW89_UKRAINE][33] = 34, -+ [2][1][RTW89_CHILE][33] = 48, -+ [2][1][RTW89_QATAR][33] = 40, - [2][1][RTW89_FCC][35] = 48, - [2][1][RTW89_ETSI][35] = 40, - [2][1][RTW89_MKK][35] = 66, - [2][1][RTW89_IC][35] = 48, -- [2][1][RTW89_KCC][35] = 46, -+ [2][1][RTW89_KCC][35] = 48, - [2][1][RTW89_ACMA][35] = 40, - [2][1][RTW89_CN][35] = 127, - [2][1][RTW89_UK][35] = 40, -+ [2][1][RTW89_MEXICO][35] = 48, -+ [2][1][RTW89_UKRAINE][35] = 34, -+ [2][1][RTW89_CHILE][35] = 48, -+ [2][1][RTW89_QATAR][35] = 40, - [2][1][RTW89_FCC][37] = 52, - [2][1][RTW89_ETSI][37] = 127, - [2][1][RTW89_MKK][37] = 66, - [2][1][RTW89_IC][37] = 52, -- [2][1][RTW89_KCC][37] = 46, -+ [2][1][RTW89_KCC][37] = 48, - [2][1][RTW89_ACMA][37] = 52, - [2][1][RTW89_CN][37] = 127, - [2][1][RTW89_UK][37] = 42, -+ [2][1][RTW89_MEXICO][37] = 52, -+ [2][1][RTW89_UKRAINE][37] = 127, -+ [2][1][RTW89_CHILE][37] = 52, -+ [2][1][RTW89_QATAR][37] = 127, - [2][1][RTW89_FCC][38] = 78, - [2][1][RTW89_ETSI][38] = 16, - [2][1][RTW89_MKK][38] = 127, - [2][1][RTW89_IC][38] = 78, -- [2][1][RTW89_KCC][38] = 46, -+ [2][1][RTW89_KCC][38] = 50, - [2][1][RTW89_ACMA][38] = 78, - [2][1][RTW89_CN][38] = 56, - [2][1][RTW89_UK][38] = 42, -+ [2][1][RTW89_MEXICO][38] = 78, -+ [2][1][RTW89_UKRAINE][38] = 14, -+ [2][1][RTW89_CHILE][38] = 72, -+ [2][1][RTW89_QATAR][38] = 14, - [2][1][RTW89_FCC][40] = 78, - [2][1][RTW89_ETSI][40] = 16, - [2][1][RTW89_MKK][40] = 127, - [2][1][RTW89_IC][40] = 78, -- [2][1][RTW89_KCC][40] = 46, -+ [2][1][RTW89_KCC][40] = 50, - [2][1][RTW89_ACMA][40] = 78, - [2][1][RTW89_CN][40] = 56, - [2][1][RTW89_UK][40] = 42, -+ [2][1][RTW89_MEXICO][40] = 78, -+ [2][1][RTW89_UKRAINE][40] = 14, -+ [2][1][RTW89_CHILE][40] = 72, -+ [2][1][RTW89_QATAR][40] = 14, - [2][1][RTW89_FCC][42] = 78, - [2][1][RTW89_ETSI][42] = 16, - [2][1][RTW89_MKK][42] = 127, - [2][1][RTW89_IC][42] = 78, -- [2][1][RTW89_KCC][42] = 46, -+ [2][1][RTW89_KCC][42] = 50, - [2][1][RTW89_ACMA][42] = 78, - [2][1][RTW89_CN][42] = 56, - [2][1][RTW89_UK][42] = 42, -+ [2][1][RTW89_MEXICO][42] = 78, -+ [2][1][RTW89_UKRAINE][42] = 14, -+ [2][1][RTW89_CHILE][42] = 72, -+ [2][1][RTW89_QATAR][42] = 14, - [2][1][RTW89_FCC][44] = 74, - [2][1][RTW89_ETSI][44] = 16, - [2][1][RTW89_MKK][44] = 127, - [2][1][RTW89_IC][44] = 74, -- [2][1][RTW89_KCC][44] = 46, -+ [2][1][RTW89_KCC][44] = 50, - [2][1][RTW89_ACMA][44] = 74, - [2][1][RTW89_CN][44] = 56, - [2][1][RTW89_UK][44] = 42, -+ [2][1][RTW89_MEXICO][44] = 74, -+ [2][1][RTW89_UKRAINE][44] = 14, -+ [2][1][RTW89_CHILE][44] = 72, -+ [2][1][RTW89_QATAR][44] = 14, - [2][1][RTW89_FCC][46] = 74, - [2][1][RTW89_ETSI][46] = 16, - [2][1][RTW89_MKK][46] = 127, - [2][1][RTW89_IC][46] = 74, -- [2][1][RTW89_KCC][46] = 46, -+ [2][1][RTW89_KCC][46] = 50, - [2][1][RTW89_ACMA][46] = 74, - [2][1][RTW89_CN][46] = 56, - [2][1][RTW89_UK][46] = 42, -+ [2][1][RTW89_MEXICO][46] = 74, -+ [2][1][RTW89_UKRAINE][46] = 14, -+ [2][1][RTW89_CHILE][46] = 72, -+ [2][1][RTW89_QATAR][46] = 14, - [2][1][RTW89_FCC][48] = 40, - [2][1][RTW89_ETSI][48] = 127, - [2][1][RTW89_MKK][48] = 127, -@@ -36240,6 +38774,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][1][RTW89_ACMA][48] = 127, - [2][1][RTW89_CN][48] = 127, - [2][1][RTW89_UK][48] = 127, -+ [2][1][RTW89_MEXICO][48] = 127, -+ [2][1][RTW89_UKRAINE][48] = 127, -+ [2][1][RTW89_CHILE][48] = 127, -+ [2][1][RTW89_QATAR][48] = 127, - [2][1][RTW89_FCC][50] = 40, - [2][1][RTW89_ETSI][50] = 127, - [2][1][RTW89_MKK][50] = 127, -@@ -36248,6 +38786,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][1][RTW89_ACMA][50] = 127, - [2][1][RTW89_CN][50] = 127, - [2][1][RTW89_UK][50] = 127, -+ [2][1][RTW89_MEXICO][50] = 127, -+ [2][1][RTW89_UKRAINE][50] = 127, -+ [2][1][RTW89_CHILE][50] = 127, -+ [2][1][RTW89_QATAR][50] = 127, - [2][1][RTW89_FCC][52] = 40, - [2][1][RTW89_ETSI][52] = 127, - [2][1][RTW89_MKK][52] = 127, -@@ -36256,6 +38798,10 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - [2][1][RTW89_ACMA][52] = 127, - [2][1][RTW89_CN][52] = 127, - [2][1][RTW89_UK][52] = 127, -+ [2][1][RTW89_MEXICO][52] = 127, -+ [2][1][RTW89_UKRAINE][52] = 127, -+ [2][1][RTW89_CHILE][52] = 127, -+ [2][1][RTW89_QATAR][52] = 127, - }; - - static diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-131-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-131-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch deleted file mode 100644 index 787ec1c71..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-131-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch +++ /dev/null @@ -1,11308 +0,0 @@ -From 2a8ec45f4d0eff76cf0cef78b3040ccfd923a72e Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:54 +0800 -Subject: [PATCH 131/136] wifi: rtw89: 8852c: update TX power tables to R63 - with 6 GHz power type (2 of 3) - -Update TX power tables to RF version R63. - -TX power tables' changes: -* TX power byrate: - tweak a bit -* TX power limit, TX power limit RU, TX power shape: - configure values for MEXICO, UKRAINE, CHILE, QATAR - tweak a bit on other configured values -* 6 GHz TX power limit, 6 GHz TX power limit RU: - add an extra dimension for 6 GHz regulatory power type, i.e. - STD (standard power), LPI (low power indoor), VLP (very low power) - -Besides, we adjust TX power handling at 6 GHz in phy to consider 6 GHz -regulatory power type. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-7-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 +- - drivers/net/wireless/realtek/rtw89/phy.c | 8 +- - .../wireless/realtek/rtw89/rtw8852c_table.c | 11227 +++++++++++++--- - 3 files changed, 9282 insertions(+), 1956 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3046,7 +3046,8 @@ struct rtw89_txpwr_rule_5ghz { - struct rtw89_txpwr_rule_6ghz { - const s8 (*lmt)[RTW89_6G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+ [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] -+ [RTW89_6G_CH_NUM]; - const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] - [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; - }; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1626,8 +1626,10 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw - const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; - const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; - const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; -+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; - u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); - u8 regd = rtw89_regd_get(rtwdev, band); -+ u8 reg6 = regulatory->reg_6ghz_power; - s8 lmt = 0, sar; - - switch (band) { -@@ -1646,11 +1648,13 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw - lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_6G: -- lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx]; -+ lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx]; - if (lmt) - break; - -- lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx]; -+ lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][RTW89_WW] -+ [RTW89_REG_6GHZ_POWER_DFLT] -+ [ch_idx]; - break; - default: - rtw89_warn(rtwdev, "unknown band type: %d\n", band); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -33563,1959 +33563,9280 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_ - static - const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM] - [RTW89_RS_LMT_NUM][RTW89_BF_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { -- [0][0][1][0][RTW89_WW][0] = 24, -- [0][0][1][0][RTW89_WW][2] = 22, -- [0][0][1][0][RTW89_WW][4] = 22, -- [0][0][1][0][RTW89_WW][6] = 22, -- [0][0][1][0][RTW89_WW][8] = 22, -- [0][0][1][0][RTW89_WW][10] = 22, -- [0][0][1][0][RTW89_WW][12] = 22, -- [0][0][1][0][RTW89_WW][14] = 22, -- [0][0][1][0][RTW89_WW][15] = 22, -- [0][0][1][0][RTW89_WW][17] = 22, -- [0][0][1][0][RTW89_WW][19] = 22, -- [0][0][1][0][RTW89_WW][21] = 22, -- [0][0][1][0][RTW89_WW][23] = 22, -- [0][0][1][0][RTW89_WW][25] = 22, -- [0][0][1][0][RTW89_WW][27] = 22, -- [0][0][1][0][RTW89_WW][29] = 22, -- [0][0][1][0][RTW89_WW][30] = 22, -- [0][0][1][0][RTW89_WW][32] = 22, -- [0][0][1][0][RTW89_WW][34] = 22, -- [0][0][1][0][RTW89_WW][36] = 22, -- [0][0][1][0][RTW89_WW][38] = 22, -- [0][0][1][0][RTW89_WW][40] = 22, -- [0][0][1][0][RTW89_WW][42] = 22, -- [0][0][1][0][RTW89_WW][44] = 22, -- [0][0][1][0][RTW89_WW][45] = 22, -- [0][0][1][0][RTW89_WW][47] = 22, -- [0][0][1][0][RTW89_WW][49] = 24, -- [0][0][1][0][RTW89_WW][51] = 22, -- [0][0][1][0][RTW89_WW][53] = 22, -- [0][0][1][0][RTW89_WW][55] = 22, -- [0][0][1][0][RTW89_WW][57] = 22, -- [0][0][1][0][RTW89_WW][59] = 22, -- [0][0][1][0][RTW89_WW][60] = 22, -- [0][0][1][0][RTW89_WW][62] = 22, -- [0][0][1][0][RTW89_WW][64] = 22, -- [0][0][1][0][RTW89_WW][66] = 22, -- [0][0][1][0][RTW89_WW][68] = 22, -- [0][0][1][0][RTW89_WW][70] = 24, -- [0][0][1][0][RTW89_WW][72] = 22, -- [0][0][1][0][RTW89_WW][74] = 22, -- [0][0][1][0][RTW89_WW][75] = 22, -- [0][0][1][0][RTW89_WW][77] = 22, -- [0][0][1][0][RTW89_WW][79] = 22, -- [0][0][1][0][RTW89_WW][81] = 22, -- [0][0][1][0][RTW89_WW][83] = 22, -- [0][0][1][0][RTW89_WW][85] = 22, -- [0][0][1][0][RTW89_WW][87] = 22, -- [0][0][1][0][RTW89_WW][89] = 22, -- [0][0][1][0][RTW89_WW][90] = 22, -- [0][0][1][0][RTW89_WW][92] = 22, -- [0][0][1][0][RTW89_WW][94] = 22, -- [0][0][1][0][RTW89_WW][96] = 22, -- [0][0][1][0][RTW89_WW][98] = 22, -- [0][0][1][0][RTW89_WW][100] = 22, -- [0][0][1][0][RTW89_WW][102] = 22, -- [0][0][1][0][RTW89_WW][104] = 22, -- [0][0][1][0][RTW89_WW][105] = 22, -- [0][0][1][0][RTW89_WW][107] = 24, -- [0][0][1][0][RTW89_WW][109] = 24, -- [0][0][1][0][RTW89_WW][111] = 0, -- [0][0][1][0][RTW89_WW][113] = 0, -- [0][0][1][0][RTW89_WW][115] = 0, -- [0][0][1][0][RTW89_WW][117] = 0, -- [0][0][1][0][RTW89_WW][119] = 0, -- [0][1][1][0][RTW89_WW][0] = -2, -- [0][1][1][0][RTW89_WW][2] = -4, -- [0][1][1][0][RTW89_WW][4] = -4, -- [0][1][1][0][RTW89_WW][6] = -4, -- [0][1][1][0][RTW89_WW][8] = -4, -- [0][1][1][0][RTW89_WW][10] = -4, -- [0][1][1][0][RTW89_WW][12] = -4, -- [0][1][1][0][RTW89_WW][14] = -4, -- [0][1][1][0][RTW89_WW][15] = -4, -- [0][1][1][0][RTW89_WW][17] = -4, -- [0][1][1][0][RTW89_WW][19] = -4, -- [0][1][1][0][RTW89_WW][21] = -4, -- [0][1][1][0][RTW89_WW][23] = -4, -- [0][1][1][0][RTW89_WW][25] = -4, -- [0][1][1][0][RTW89_WW][27] = -4, -- [0][1][1][0][RTW89_WW][29] = -4, -- [0][1][1][0][RTW89_WW][30] = -4, -- [0][1][1][0][RTW89_WW][32] = -4, -- [0][1][1][0][RTW89_WW][34] = -4, -- [0][1][1][0][RTW89_WW][36] = -4, -- [0][1][1][0][RTW89_WW][38] = -4, -- [0][1][1][0][RTW89_WW][40] = -4, -- [0][1][1][0][RTW89_WW][42] = -4, -- [0][1][1][0][RTW89_WW][44] = -2, -- [0][1][1][0][RTW89_WW][45] = -2, -- [0][1][1][0][RTW89_WW][47] = -2, -- [0][1][1][0][RTW89_WW][49] = -2, -- [0][1][1][0][RTW89_WW][51] = -2, -- [0][1][1][0][RTW89_WW][53] = -2, -- [0][1][1][0][RTW89_WW][55] = -2, -- [0][1][1][0][RTW89_WW][57] = -2, -- [0][1][1][0][RTW89_WW][59] = -2, -- [0][1][1][0][RTW89_WW][60] = -2, -- [0][1][1][0][RTW89_WW][62] = -2, -- [0][1][1][0][RTW89_WW][64] = -2, -- [0][1][1][0][RTW89_WW][66] = -2, -- [0][1][1][0][RTW89_WW][68] = -2, -- [0][1][1][0][RTW89_WW][70] = -2, -- [0][1][1][0][RTW89_WW][72] = -2, -- [0][1][1][0][RTW89_WW][74] = -2, -- [0][1][1][0][RTW89_WW][75] = -2, -- [0][1][1][0][RTW89_WW][77] = -2, -- [0][1][1][0][RTW89_WW][79] = -2, -- [0][1][1][0][RTW89_WW][81] = -2, -- [0][1][1][0][RTW89_WW][83] = -2, -- [0][1][1][0][RTW89_WW][85] = -2, -- [0][1][1][0][RTW89_WW][87] = -2, -- [0][1][1][0][RTW89_WW][89] = -2, -- [0][1][1][0][RTW89_WW][90] = -2, -- [0][1][1][0][RTW89_WW][92] = -2, -- [0][1][1][0][RTW89_WW][94] = -2, -- [0][1][1][0][RTW89_WW][96] = -2, -- [0][1][1][0][RTW89_WW][98] = -2, -- [0][1][1][0][RTW89_WW][100] = -2, -- [0][1][1][0][RTW89_WW][102] = -2, -- [0][1][1][0][RTW89_WW][104] = -2, -- [0][1][1][0][RTW89_WW][105] = -2, -- [0][1][1][0][RTW89_WW][107] = 1, -- [0][1][1][0][RTW89_WW][109] = 1, -- [0][1][1][0][RTW89_WW][111] = 0, -- [0][1][1][0][RTW89_WW][113] = 0, -- [0][1][1][0][RTW89_WW][115] = 0, -- [0][1][1][0][RTW89_WW][117] = 0, -- [0][1][1][0][RTW89_WW][119] = 0, -- [0][0][2][0][RTW89_WW][0] = 24, -- [0][0][2][0][RTW89_WW][2] = 22, -- [0][0][2][0][RTW89_WW][4] = 22, -- [0][0][2][0][RTW89_WW][6] = 22, -- [0][0][2][0][RTW89_WW][8] = 22, -- [0][0][2][0][RTW89_WW][10] = 22, -- [0][0][2][0][RTW89_WW][12] = 22, -- [0][0][2][0][RTW89_WW][14] = 22, -- [0][0][2][0][RTW89_WW][15] = 22, -- [0][0][2][0][RTW89_WW][17] = 22, -- [0][0][2][0][RTW89_WW][19] = 22, -- [0][0][2][0][RTW89_WW][21] = 22, -- [0][0][2][0][RTW89_WW][23] = 22, -- [0][0][2][0][RTW89_WW][25] = 22, -- [0][0][2][0][RTW89_WW][27] = 22, -- [0][0][2][0][RTW89_WW][29] = 22, -- [0][0][2][0][RTW89_WW][30] = 22, -- [0][0][2][0][RTW89_WW][32] = 22, -- [0][0][2][0][RTW89_WW][34] = 22, -- [0][0][2][0][RTW89_WW][36] = 22, -- [0][0][2][0][RTW89_WW][38] = 22, -- [0][0][2][0][RTW89_WW][40] = 22, -- [0][0][2][0][RTW89_WW][42] = 22, -- [0][0][2][0][RTW89_WW][44] = 22, -- [0][0][2][0][RTW89_WW][45] = 22, -- [0][0][2][0][RTW89_WW][47] = 22, -- [0][0][2][0][RTW89_WW][49] = 24, -- [0][0][2][0][RTW89_WW][51] = 22, -- [0][0][2][0][RTW89_WW][53] = 22, -- [0][0][2][0][RTW89_WW][55] = 22, -- [0][0][2][0][RTW89_WW][57] = 22, -- [0][0][2][0][RTW89_WW][59] = 22, -- [0][0][2][0][RTW89_WW][60] = 22, -- [0][0][2][0][RTW89_WW][62] = 22, -- [0][0][2][0][RTW89_WW][64] = 22, -- [0][0][2][0][RTW89_WW][66] = 22, -- [0][0][2][0][RTW89_WW][68] = 22, -- [0][0][2][0][RTW89_WW][70] = 24, -- [0][0][2][0][RTW89_WW][72] = 22, -- [0][0][2][0][RTW89_WW][74] = 22, -- [0][0][2][0][RTW89_WW][75] = 22, -- [0][0][2][0][RTW89_WW][77] = 22, -- [0][0][2][0][RTW89_WW][79] = 22, -- [0][0][2][0][RTW89_WW][81] = 22, -- [0][0][2][0][RTW89_WW][83] = 22, -- [0][0][2][0][RTW89_WW][85] = 22, -- [0][0][2][0][RTW89_WW][87] = 22, -- [0][0][2][0][RTW89_WW][89] = 22, -- [0][0][2][0][RTW89_WW][90] = 22, -- [0][0][2][0][RTW89_WW][92] = 22, -- [0][0][2][0][RTW89_WW][94] = 22, -- [0][0][2][0][RTW89_WW][96] = 22, -- [0][0][2][0][RTW89_WW][98] = 22, -- [0][0][2][0][RTW89_WW][100] = 22, -- [0][0][2][0][RTW89_WW][102] = 22, -- [0][0][2][0][RTW89_WW][104] = 22, -- [0][0][2][0][RTW89_WW][105] = 22, -- [0][0][2][0][RTW89_WW][107] = 24, -- [0][0][2][0][RTW89_WW][109] = 24, -- [0][0][2][0][RTW89_WW][111] = 0, -- [0][0][2][0][RTW89_WW][113] = 0, -- [0][0][2][0][RTW89_WW][115] = 0, -- [0][0][2][0][RTW89_WW][117] = 0, -- [0][0][2][0][RTW89_WW][119] = 0, -- [0][1][2][0][RTW89_WW][0] = -2, -- [0][1][2][0][RTW89_WW][2] = -4, -- [0][1][2][0][RTW89_WW][4] = -4, -- [0][1][2][0][RTW89_WW][6] = -4, -- [0][1][2][0][RTW89_WW][8] = -4, -- [0][1][2][0][RTW89_WW][10] = -4, -- [0][1][2][0][RTW89_WW][12] = -4, -- [0][1][2][0][RTW89_WW][14] = -4, -- [0][1][2][0][RTW89_WW][15] = -4, -- [0][1][2][0][RTW89_WW][17] = -4, -- [0][1][2][0][RTW89_WW][19] = -4, -- [0][1][2][0][RTW89_WW][21] = -4, -- [0][1][2][0][RTW89_WW][23] = -4, -- [0][1][2][0][RTW89_WW][25] = -4, -- [0][1][2][0][RTW89_WW][27] = -4, -- [0][1][2][0][RTW89_WW][29] = -4, -- [0][1][2][0][RTW89_WW][30] = -4, -- [0][1][2][0][RTW89_WW][32] = -4, -- [0][1][2][0][RTW89_WW][34] = -4, -- [0][1][2][0][RTW89_WW][36] = -4, -- [0][1][2][0][RTW89_WW][38] = -4, -- [0][1][2][0][RTW89_WW][40] = -4, -- [0][1][2][0][RTW89_WW][42] = -4, -- [0][1][2][0][RTW89_WW][44] = -2, -- [0][1][2][0][RTW89_WW][45] = -2, -- [0][1][2][0][RTW89_WW][47] = -2, -- [0][1][2][0][RTW89_WW][49] = -2, -- [0][1][2][0][RTW89_WW][51] = -2, -- [0][1][2][0][RTW89_WW][53] = -2, -- [0][1][2][0][RTW89_WW][55] = -2, -- [0][1][2][0][RTW89_WW][57] = -2, -- [0][1][2][0][RTW89_WW][59] = -2, -- [0][1][2][0][RTW89_WW][60] = -2, -- [0][1][2][0][RTW89_WW][62] = -2, -- [0][1][2][0][RTW89_WW][64] = -2, -- [0][1][2][0][RTW89_WW][66] = -2, -- [0][1][2][0][RTW89_WW][68] = -2, -- [0][1][2][0][RTW89_WW][70] = -2, -- [0][1][2][0][RTW89_WW][72] = -2, -- [0][1][2][0][RTW89_WW][74] = -2, -- [0][1][2][0][RTW89_WW][75] = -2, -- [0][1][2][0][RTW89_WW][77] = -2, -- [0][1][2][0][RTW89_WW][79] = -2, -- [0][1][2][0][RTW89_WW][81] = -2, -- [0][1][2][0][RTW89_WW][83] = -2, -- [0][1][2][0][RTW89_WW][85] = -2, -- [0][1][2][0][RTW89_WW][87] = -2, -- [0][1][2][0][RTW89_WW][89] = -2, -- [0][1][2][0][RTW89_WW][90] = -2, -- [0][1][2][0][RTW89_WW][92] = -2, -- [0][1][2][0][RTW89_WW][94] = -2, -- [0][1][2][0][RTW89_WW][96] = -2, -- [0][1][2][0][RTW89_WW][98] = -2, -- [0][1][2][0][RTW89_WW][100] = -2, -- [0][1][2][0][RTW89_WW][102] = -2, -- [0][1][2][0][RTW89_WW][104] = -2, -- [0][1][2][0][RTW89_WW][105] = -2, -- [0][1][2][0][RTW89_WW][107] = 1, -- [0][1][2][0][RTW89_WW][109] = 1, -- [0][1][2][0][RTW89_WW][111] = 0, -- [0][1][2][0][RTW89_WW][113] = 0, -- [0][1][2][0][RTW89_WW][115] = 0, -- [0][1][2][0][RTW89_WW][117] = 0, -- [0][1][2][0][RTW89_WW][119] = 0, -- [0][1][2][1][RTW89_WW][0] = -2, -- [0][1][2][1][RTW89_WW][2] = -4, -- [0][1][2][1][RTW89_WW][4] = -4, -- [0][1][2][1][RTW89_WW][6] = -4, -- [0][1][2][1][RTW89_WW][8] = -4, -- [0][1][2][1][RTW89_WW][10] = -4, -- [0][1][2][1][RTW89_WW][12] = -4, -- [0][1][2][1][RTW89_WW][14] = -4, -- [0][1][2][1][RTW89_WW][15] = -4, -- [0][1][2][1][RTW89_WW][17] = -4, -- [0][1][2][1][RTW89_WW][19] = -4, -- [0][1][2][1][RTW89_WW][21] = -4, -- [0][1][2][1][RTW89_WW][23] = -4, -- [0][1][2][1][RTW89_WW][25] = -4, -- [0][1][2][1][RTW89_WW][27] = -4, -- [0][1][2][1][RTW89_WW][29] = -4, -- [0][1][2][1][RTW89_WW][30] = -4, -- [0][1][2][1][RTW89_WW][32] = -4, -- [0][1][2][1][RTW89_WW][34] = -4, -- [0][1][2][1][RTW89_WW][36] = -4, -- [0][1][2][1][RTW89_WW][38] = -4, -- [0][1][2][1][RTW89_WW][40] = -4, -- [0][1][2][1][RTW89_WW][42] = -4, -- [0][1][2][1][RTW89_WW][44] = -2, -- [0][1][2][1][RTW89_WW][45] = -2, -- [0][1][2][1][RTW89_WW][47] = -2, -- [0][1][2][1][RTW89_WW][49] = -2, -- [0][1][2][1][RTW89_WW][51] = -2, -- [0][1][2][1][RTW89_WW][53] = -2, -- [0][1][2][1][RTW89_WW][55] = -2, -- [0][1][2][1][RTW89_WW][57] = -2, -- [0][1][2][1][RTW89_WW][59] = -2, -- [0][1][2][1][RTW89_WW][60] = -2, -- [0][1][2][1][RTW89_WW][62] = -2, -- [0][1][2][1][RTW89_WW][64] = -2, -- [0][1][2][1][RTW89_WW][66] = -2, -- [0][1][2][1][RTW89_WW][68] = -2, -- [0][1][2][1][RTW89_WW][70] = -2, -- [0][1][2][1][RTW89_WW][72] = -2, -- [0][1][2][1][RTW89_WW][74] = -2, -- [0][1][2][1][RTW89_WW][75] = -2, -- [0][1][2][1][RTW89_WW][77] = -2, -- [0][1][2][1][RTW89_WW][79] = -2, -- [0][1][2][1][RTW89_WW][81] = -2, -- [0][1][2][1][RTW89_WW][83] = -2, -- [0][1][2][1][RTW89_WW][85] = -2, -- [0][1][2][1][RTW89_WW][87] = -2, -- [0][1][2][1][RTW89_WW][89] = -2, -- [0][1][2][1][RTW89_WW][90] = -2, -- [0][1][2][1][RTW89_WW][92] = -2, -- [0][1][2][1][RTW89_WW][94] = -2, -- [0][1][2][1][RTW89_WW][96] = -2, -- [0][1][2][1][RTW89_WW][98] = -2, -- [0][1][2][1][RTW89_WW][100] = -2, -- [0][1][2][1][RTW89_WW][102] = -2, -- [0][1][2][1][RTW89_WW][104] = -2, -- [0][1][2][1][RTW89_WW][105] = -2, -- [0][1][2][1][RTW89_WW][107] = 1, -- [0][1][2][1][RTW89_WW][109] = 1, -- [0][1][2][1][RTW89_WW][111] = 0, -- [0][1][2][1][RTW89_WW][113] = 0, -- [0][1][2][1][RTW89_WW][115] = 0, -- [0][1][2][1][RTW89_WW][117] = 0, -- [0][1][2][1][RTW89_WW][119] = 0, -- [1][0][2][0][RTW89_WW][1] = 34, -- [1][0][2][0][RTW89_WW][5] = 34, -- [1][0][2][0][RTW89_WW][9] = 34, -- [1][0][2][0][RTW89_WW][13] = 34, -- [1][0][2][0][RTW89_WW][16] = 34, -- [1][0][2][0][RTW89_WW][20] = 34, -- [1][0][2][0][RTW89_WW][24] = 36, -- [1][0][2][0][RTW89_WW][28] = 34, -- [1][0][2][0][RTW89_WW][31] = 34, -- [1][0][2][0][RTW89_WW][35] = 34, -- [1][0][2][0][RTW89_WW][39] = 34, -- [1][0][2][0][RTW89_WW][43] = 34, -- [1][0][2][0][RTW89_WW][46] = 34, -- [1][0][2][0][RTW89_WW][50] = 34, -- [1][0][2][0][RTW89_WW][54] = 36, -- [1][0][2][0][RTW89_WW][58] = 36, -- [1][0][2][0][RTW89_WW][61] = 34, -- [1][0][2][0][RTW89_WW][65] = 34, -- [1][0][2][0][RTW89_WW][69] = 34, -- [1][0][2][0][RTW89_WW][73] = 34, -- [1][0][2][0][RTW89_WW][76] = 34, -- [1][0][2][0][RTW89_WW][80] = 34, -- [1][0][2][0][RTW89_WW][84] = 34, -- [1][0][2][0][RTW89_WW][88] = 34, -- [1][0][2][0][RTW89_WW][91] = 36, -- [1][0][2][0][RTW89_WW][95] = 34, -- [1][0][2][0][RTW89_WW][99] = 34, -- [1][0][2][0][RTW89_WW][103] = 34, -- [1][0][2][0][RTW89_WW][106] = 36, -- [1][0][2][0][RTW89_WW][110] = 0, -- [1][0][2][0][RTW89_WW][114] = 0, -- [1][0][2][0][RTW89_WW][118] = 0, -- [1][1][2][0][RTW89_WW][1] = 10, -- [1][1][2][0][RTW89_WW][5] = 10, -- [1][1][2][0][RTW89_WW][9] = 10, -- [1][1][2][0][RTW89_WW][13] = 10, -- [1][1][2][0][RTW89_WW][16] = 10, -- [1][1][2][0][RTW89_WW][20] = 10, -- [1][1][2][0][RTW89_WW][24] = 10, -- [1][1][2][0][RTW89_WW][28] = 10, -- [1][1][2][0][RTW89_WW][31] = 10, -- [1][1][2][0][RTW89_WW][35] = 10, -- [1][1][2][0][RTW89_WW][39] = 10, -- [1][1][2][0][RTW89_WW][43] = 10, -- [1][1][2][0][RTW89_WW][46] = 12, -- [1][1][2][0][RTW89_WW][50] = 12, -- [1][1][2][0][RTW89_WW][54] = 10, -- [1][1][2][0][RTW89_WW][58] = 10, -- [1][1][2][0][RTW89_WW][61] = 10, -- [1][1][2][0][RTW89_WW][65] = 10, -- [1][1][2][0][RTW89_WW][69] = 10, -- [1][1][2][0][RTW89_WW][73] = 10, -- [1][1][2][0][RTW89_WW][76] = 10, -- [1][1][2][0][RTW89_WW][80] = 10, -- [1][1][2][0][RTW89_WW][84] = 10, -- [1][1][2][0][RTW89_WW][88] = 10, -- [1][1][2][0][RTW89_WW][91] = 12, -- [1][1][2][0][RTW89_WW][95] = 10, -- [1][1][2][0][RTW89_WW][99] = 10, -- [1][1][2][0][RTW89_WW][103] = 10, -- [1][1][2][0][RTW89_WW][106] = 12, -- [1][1][2][0][RTW89_WW][110] = 0, -- [1][1][2][0][RTW89_WW][114] = 0, -- [1][1][2][0][RTW89_WW][118] = 0, -- [1][1][2][1][RTW89_WW][1] = 10, -- [1][1][2][1][RTW89_WW][5] = 10, -- [1][1][2][1][RTW89_WW][9] = 10, -- [1][1][2][1][RTW89_WW][13] = 10, -- [1][1][2][1][RTW89_WW][16] = 10, -- [1][1][2][1][RTW89_WW][20] = 10, -- [1][1][2][1][RTW89_WW][24] = 10, -- [1][1][2][1][RTW89_WW][28] = 10, -- [1][1][2][1][RTW89_WW][31] = 10, -- [1][1][2][1][RTW89_WW][35] = 10, -- [1][1][2][1][RTW89_WW][39] = 10, -- [1][1][2][1][RTW89_WW][43] = 10, -- [1][1][2][1][RTW89_WW][46] = 12, -- [1][1][2][1][RTW89_WW][50] = 12, -- [1][1][2][1][RTW89_WW][54] = 10, -- [1][1][2][1][RTW89_WW][58] = 10, -- [1][1][2][1][RTW89_WW][61] = 10, -- [1][1][2][1][RTW89_WW][65] = 10, -- [1][1][2][1][RTW89_WW][69] = 10, -- [1][1][2][1][RTW89_WW][73] = 10, -- [1][1][2][1][RTW89_WW][76] = 10, -- [1][1][2][1][RTW89_WW][80] = 10, -- [1][1][2][1][RTW89_WW][84] = 10, -- [1][1][2][1][RTW89_WW][88] = 10, -- [1][1][2][1][RTW89_WW][91] = 12, -- [1][1][2][1][RTW89_WW][95] = 10, -- [1][1][2][1][RTW89_WW][99] = 10, -- [1][1][2][1][RTW89_WW][103] = 10, -- [1][1][2][1][RTW89_WW][106] = 12, -- [1][1][2][1][RTW89_WW][110] = 0, -- [1][1][2][1][RTW89_WW][114] = 0, -- [1][1][2][1][RTW89_WW][118] = 0, -- [2][0][2][0][RTW89_WW][3] = 46, -- [2][0][2][0][RTW89_WW][11] = 46, -- [2][0][2][0][RTW89_WW][18] = 46, -- [2][0][2][0][RTW89_WW][26] = 46, -- [2][0][2][0][RTW89_WW][33] = 46, -- [2][0][2][0][RTW89_WW][41] = 46, -- [2][0][2][0][RTW89_WW][48] = 46, -- [2][0][2][0][RTW89_WW][56] = 46, -- [2][0][2][0][RTW89_WW][63] = 46, -- [2][0][2][0][RTW89_WW][71] = 46, -- [2][0][2][0][RTW89_WW][78] = 46, -- [2][0][2][0][RTW89_WW][86] = 46, -- [2][0][2][0][RTW89_WW][93] = 46, -- [2][0][2][0][RTW89_WW][101] = 44, -- [2][0][2][0][RTW89_WW][108] = 0, -- [2][0][2][0][RTW89_WW][116] = 0, -- [2][1][2][0][RTW89_WW][3] = 22, -- [2][1][2][0][RTW89_WW][11] = 20, -- [2][1][2][0][RTW89_WW][18] = 20, -- [2][1][2][0][RTW89_WW][26] = 20, -- [2][1][2][0][RTW89_WW][33] = 20, -- [2][1][2][0][RTW89_WW][41] = 22, -- [2][1][2][0][RTW89_WW][48] = 22, -- [2][1][2][0][RTW89_WW][56] = 20, -- [2][1][2][0][RTW89_WW][63] = 22, -- [2][1][2][0][RTW89_WW][71] = 20, -- [2][1][2][0][RTW89_WW][78] = 20, -- [2][1][2][0][RTW89_WW][86] = 20, -- [2][1][2][0][RTW89_WW][93] = 22, -- [2][1][2][0][RTW89_WW][101] = 22, -- [2][1][2][0][RTW89_WW][108] = 0, -- [2][1][2][0][RTW89_WW][116] = 0, -- [2][1][2][1][RTW89_WW][3] = 22, -- [2][1][2][1][RTW89_WW][11] = 20, -- [2][1][2][1][RTW89_WW][18] = 20, -- [2][1][2][1][RTW89_WW][26] = 20, -- [2][1][2][1][RTW89_WW][33] = 20, -- [2][1][2][1][RTW89_WW][41] = 22, -- [2][1][2][1][RTW89_WW][48] = 22, -- [2][1][2][1][RTW89_WW][56] = 20, -- [2][1][2][1][RTW89_WW][63] = 22, -- [2][1][2][1][RTW89_WW][71] = 20, -- [2][1][2][1][RTW89_WW][78] = 20, -- [2][1][2][1][RTW89_WW][86] = 20, -- [2][1][2][1][RTW89_WW][93] = 22, -- [2][1][2][1][RTW89_WW][101] = 22, -- [2][1][2][1][RTW89_WW][108] = 0, -- [2][1][2][1][RTW89_WW][116] = 0, -- [3][0][2][0][RTW89_WW][7] = 38, -- [3][0][2][0][RTW89_WW][22] = 38, -- [3][0][2][0][RTW89_WW][37] = 38, -- [3][0][2][0][RTW89_WW][52] = 54, -- [3][0][2][0][RTW89_WW][67] = 54, -- [3][0][2][0][RTW89_WW][82] = 26, -- [3][0][2][0][RTW89_WW][97] = 26, -- [3][0][2][0][RTW89_WW][112] = 0, -- [3][1][2][0][RTW89_WW][7] = 32, -- [3][1][2][0][RTW89_WW][22] = 30, -- [3][1][2][0][RTW89_WW][37] = 30, -- [3][1][2][0][RTW89_WW][52] = 30, -- [3][1][2][0][RTW89_WW][67] = 32, -- [3][1][2][0][RTW89_WW][82] = 24, -- [3][1][2][0][RTW89_WW][97] = 14, -- [3][1][2][0][RTW89_WW][112] = 0, -- [3][1][2][1][RTW89_WW][7] = 32, -- [3][1][2][1][RTW89_WW][22] = 30, -- [3][1][2][1][RTW89_WW][37] = 30, -- [3][1][2][1][RTW89_WW][52] = 30, -- [3][1][2][1][RTW89_WW][67] = 32, -- [3][1][2][1][RTW89_WW][82] = 24, -- [3][1][2][1][RTW89_WW][97] = 14, -- [3][1][2][1][RTW89_WW][112] = 0, -- [0][0][1][0][RTW89_FCC][0] = 24, -- [0][0][1][0][RTW89_ETSI][0] = 66, -- [0][0][1][0][RTW89_KCC][0] = 24, -- [0][0][1][0][RTW89_FCC][2] = 22, -- [0][0][1][0][RTW89_ETSI][2] = 66, -- [0][0][1][0][RTW89_KCC][2] = 24, -- [0][0][1][0][RTW89_FCC][4] = 22, -- [0][0][1][0][RTW89_ETSI][4] = 66, -- [0][0][1][0][RTW89_KCC][4] = 24, -- [0][0][1][0][RTW89_FCC][6] = 22, -- [0][0][1][0][RTW89_ETSI][6] = 66, -- [0][0][1][0][RTW89_KCC][6] = 24, -- [0][0][1][0][RTW89_FCC][8] = 22, -- [0][0][1][0][RTW89_ETSI][8] = 66, -- [0][0][1][0][RTW89_KCC][8] = 24, -- [0][0][1][0][RTW89_FCC][10] = 22, -- [0][0][1][0][RTW89_ETSI][10] = 66, -- [0][0][1][0][RTW89_KCC][10] = 24, -- [0][0][1][0][RTW89_FCC][12] = 22, -- [0][0][1][0][RTW89_ETSI][12] = 66, -- [0][0][1][0][RTW89_KCC][12] = 24, -- [0][0][1][0][RTW89_FCC][14] = 22, -- [0][0][1][0][RTW89_ETSI][14] = 66, -- [0][0][1][0][RTW89_KCC][14] = 24, -- [0][0][1][0][RTW89_FCC][15] = 22, -- [0][0][1][0][RTW89_ETSI][15] = 66, -- [0][0][1][0][RTW89_KCC][15] = 24, -- [0][0][1][0][RTW89_FCC][17] = 22, -- [0][0][1][0][RTW89_ETSI][17] = 66, -- [0][0][1][0][RTW89_KCC][17] = 24, -- [0][0][1][0][RTW89_FCC][19] = 22, -- [0][0][1][0][RTW89_ETSI][19] = 66, -- [0][0][1][0][RTW89_KCC][19] = 24, -- [0][0][1][0][RTW89_FCC][21] = 22, -- [0][0][1][0][RTW89_ETSI][21] = 66, -- [0][0][1][0][RTW89_KCC][21] = 24, -- [0][0][1][0][RTW89_FCC][23] = 22, -- [0][0][1][0][RTW89_ETSI][23] = 66, -- [0][0][1][0][RTW89_KCC][23] = 24, -- [0][0][1][0][RTW89_FCC][25] = 22, -- [0][0][1][0][RTW89_ETSI][25] = 66, -- [0][0][1][0][RTW89_KCC][25] = 24, -- [0][0][1][0][RTW89_FCC][27] = 22, -- [0][0][1][0][RTW89_ETSI][27] = 66, -- [0][0][1][0][RTW89_KCC][27] = 24, -- [0][0][1][0][RTW89_FCC][29] = 22, -- [0][0][1][0][RTW89_ETSI][29] = 66, -- [0][0][1][0][RTW89_KCC][29] = 24, -- [0][0][1][0][RTW89_FCC][30] = 22, -- [0][0][1][0][RTW89_ETSI][30] = 66, -- [0][0][1][0][RTW89_KCC][30] = 24, -- [0][0][1][0][RTW89_FCC][32] = 22, -- [0][0][1][0][RTW89_ETSI][32] = 66, -- [0][0][1][0][RTW89_KCC][32] = 24, -- [0][0][1][0][RTW89_FCC][34] = 22, -- [0][0][1][0][RTW89_ETSI][34] = 66, -- [0][0][1][0][RTW89_KCC][34] = 24, -- [0][0][1][0][RTW89_FCC][36] = 22, -- [0][0][1][0][RTW89_ETSI][36] = 66, -- [0][0][1][0][RTW89_KCC][36] = 24, -- [0][0][1][0][RTW89_FCC][38] = 22, -- [0][0][1][0][RTW89_ETSI][38] = 66, -- [0][0][1][0][RTW89_KCC][38] = 24, -- [0][0][1][0][RTW89_FCC][40] = 22, -- [0][0][1][0][RTW89_ETSI][40] = 66, -- [0][0][1][0][RTW89_KCC][40] = 24, -- [0][0][1][0][RTW89_FCC][42] = 22, -- [0][0][1][0][RTW89_ETSI][42] = 66, -- [0][0][1][0][RTW89_KCC][42] = 24, -- [0][0][1][0][RTW89_FCC][44] = 22, -- [0][0][1][0][RTW89_ETSI][44] = 66, -- [0][0][1][0][RTW89_KCC][44] = 24, -- [0][0][1][0][RTW89_FCC][45] = 22, -- [0][0][1][0][RTW89_ETSI][45] = 127, -- [0][0][1][0][RTW89_KCC][45] = 24, -- [0][0][1][0][RTW89_FCC][47] = 22, -- [0][0][1][0][RTW89_ETSI][47] = 127, -- [0][0][1][0][RTW89_KCC][47] = 24, -- [0][0][1][0][RTW89_FCC][49] = 24, -- [0][0][1][0][RTW89_ETSI][49] = 127, -- [0][0][1][0][RTW89_KCC][49] = 24, -- [0][0][1][0][RTW89_FCC][51] = 22, -- [0][0][1][0][RTW89_ETSI][51] = 127, -- [0][0][1][0][RTW89_KCC][51] = 24, -- [0][0][1][0][RTW89_FCC][53] = 22, -- [0][0][1][0][RTW89_ETSI][53] = 127, -- [0][0][1][0][RTW89_KCC][53] = 24, -- [0][0][1][0][RTW89_FCC][55] = 22, -- [0][0][1][0][RTW89_ETSI][55] = 127, -- [0][0][1][0][RTW89_KCC][55] = 26, -- [0][0][1][0][RTW89_FCC][57] = 22, -- [0][0][1][0][RTW89_ETSI][57] = 127, -- [0][0][1][0][RTW89_KCC][57] = 26, -- [0][0][1][0][RTW89_FCC][59] = 22, -- [0][0][1][0][RTW89_ETSI][59] = 127, -- [0][0][1][0][RTW89_KCC][59] = 26, -- [0][0][1][0][RTW89_FCC][60] = 22, -- [0][0][1][0][RTW89_ETSI][60] = 127, -- [0][0][1][0][RTW89_KCC][60] = 26, -- [0][0][1][0][RTW89_FCC][62] = 22, -- [0][0][1][0][RTW89_ETSI][62] = 127, -- [0][0][1][0][RTW89_KCC][62] = 26, -- [0][0][1][0][RTW89_FCC][64] = 22, -- [0][0][1][0][RTW89_ETSI][64] = 127, -- [0][0][1][0][RTW89_KCC][64] = 26, -- [0][0][1][0][RTW89_FCC][66] = 22, -- [0][0][1][0][RTW89_ETSI][66] = 127, -- [0][0][1][0][RTW89_KCC][66] = 26, -- [0][0][1][0][RTW89_FCC][68] = 22, -- [0][0][1][0][RTW89_ETSI][68] = 127, -- [0][0][1][0][RTW89_KCC][68] = 26, -- [0][0][1][0][RTW89_FCC][70] = 24, -- [0][0][1][0][RTW89_ETSI][70] = 127, -- [0][0][1][0][RTW89_KCC][70] = 26, -- [0][0][1][0][RTW89_FCC][72] = 22, -- [0][0][1][0][RTW89_ETSI][72] = 127, -- [0][0][1][0][RTW89_KCC][72] = 26, -- [0][0][1][0][RTW89_FCC][74] = 22, -- [0][0][1][0][RTW89_ETSI][74] = 127, -- [0][0][1][0][RTW89_KCC][74] = 26, -- [0][0][1][0][RTW89_FCC][75] = 22, -- [0][0][1][0][RTW89_ETSI][75] = 127, -- [0][0][1][0][RTW89_KCC][75] = 26, -- [0][0][1][0][RTW89_FCC][77] = 22, -- [0][0][1][0][RTW89_ETSI][77] = 127, -- [0][0][1][0][RTW89_KCC][77] = 26, -- [0][0][1][0][RTW89_FCC][79] = 22, -- [0][0][1][0][RTW89_ETSI][79] = 127, -- [0][0][1][0][RTW89_KCC][79] = 26, -- [0][0][1][0][RTW89_FCC][81] = 22, -- [0][0][1][0][RTW89_ETSI][81] = 127, -- [0][0][1][0][RTW89_KCC][81] = 26, -- [0][0][1][0][RTW89_FCC][83] = 22, -- [0][0][1][0][RTW89_ETSI][83] = 127, -- [0][0][1][0][RTW89_KCC][83] = 32, -- [0][0][1][0][RTW89_FCC][85] = 22, -- [0][0][1][0][RTW89_ETSI][85] = 127, -- [0][0][1][0][RTW89_KCC][85] = 32, -- [0][0][1][0][RTW89_FCC][87] = 22, -- [0][0][1][0][RTW89_ETSI][87] = 127, -- [0][0][1][0][RTW89_KCC][87] = 32, -- [0][0][1][0][RTW89_FCC][89] = 22, -- [0][0][1][0][RTW89_ETSI][89] = 127, -- [0][0][1][0][RTW89_KCC][89] = 32, -- [0][0][1][0][RTW89_FCC][90] = 22, -- [0][0][1][0][RTW89_ETSI][90] = 127, -- [0][0][1][0][RTW89_KCC][90] = 32, -- [0][0][1][0][RTW89_FCC][92] = 22, -- [0][0][1][0][RTW89_ETSI][92] = 127, -- [0][0][1][0][RTW89_KCC][92] = 32, -- [0][0][1][0][RTW89_FCC][94] = 22, -- [0][0][1][0][RTW89_ETSI][94] = 127, -- [0][0][1][0][RTW89_KCC][94] = 32, -- [0][0][1][0][RTW89_FCC][96] = 22, -- [0][0][1][0][RTW89_ETSI][96] = 127, -- [0][0][1][0][RTW89_KCC][96] = 32, -- [0][0][1][0][RTW89_FCC][98] = 22, -- [0][0][1][0][RTW89_ETSI][98] = 127, -- [0][0][1][0][RTW89_KCC][98] = 32, -- [0][0][1][0][RTW89_FCC][100] = 22, -- [0][0][1][0][RTW89_ETSI][100] = 127, -- [0][0][1][0][RTW89_KCC][100] = 32, -- [0][0][1][0][RTW89_FCC][102] = 22, -- [0][0][1][0][RTW89_ETSI][102] = 127, -- [0][0][1][0][RTW89_KCC][102] = 32, -- [0][0][1][0][RTW89_FCC][104] = 22, -- [0][0][1][0][RTW89_ETSI][104] = 127, -- [0][0][1][0][RTW89_KCC][104] = 32, -- [0][0][1][0][RTW89_FCC][105] = 22, -- [0][0][1][0][RTW89_ETSI][105] = 127, -- [0][0][1][0][RTW89_KCC][105] = 32, -- [0][0][1][0][RTW89_FCC][107] = 24, -- [0][0][1][0][RTW89_ETSI][107] = 127, -- [0][0][1][0][RTW89_KCC][107] = 32, -- [0][0][1][0][RTW89_FCC][109] = 24, -- [0][0][1][0][RTW89_ETSI][109] = 127, -- [0][0][1][0][RTW89_KCC][109] = 32, -- [0][0][1][0][RTW89_FCC][111] = 127, -- [0][0][1][0][RTW89_ETSI][111] = 127, -- [0][0][1][0][RTW89_KCC][111] = 127, -- [0][0][1][0][RTW89_FCC][113] = 127, -- [0][0][1][0][RTW89_ETSI][113] = 127, -- [0][0][1][0][RTW89_KCC][113] = 127, -- [0][0][1][0][RTW89_FCC][115] = 127, -- [0][0][1][0][RTW89_ETSI][115] = 127, -- [0][0][1][0][RTW89_KCC][115] = 127, -- [0][0][1][0][RTW89_FCC][117] = 127, -- [0][0][1][0][RTW89_ETSI][117] = 127, -- [0][0][1][0][RTW89_KCC][117] = 127, -- [0][0][1][0][RTW89_FCC][119] = 127, -- [0][0][1][0][RTW89_ETSI][119] = 127, -- [0][0][1][0][RTW89_KCC][119] = 127, -- [0][1][1][0][RTW89_FCC][0] = -2, -- [0][1][1][0][RTW89_ETSI][0] = 54, -- [0][1][1][0][RTW89_KCC][0] = 12, -- [0][1][1][0][RTW89_FCC][2] = -4, -- [0][1][1][0][RTW89_ETSI][2] = 54, -- [0][1][1][0][RTW89_KCC][2] = 12, -- [0][1][1][0][RTW89_FCC][4] = -4, -- [0][1][1][0][RTW89_ETSI][4] = 54, -- [0][1][1][0][RTW89_KCC][4] = 12, -- [0][1][1][0][RTW89_FCC][6] = -4, -- [0][1][1][0][RTW89_ETSI][6] = 54, -- [0][1][1][0][RTW89_KCC][6] = 12, -- [0][1][1][0][RTW89_FCC][8] = -4, -- [0][1][1][0][RTW89_ETSI][8] = 54, -- [0][1][1][0][RTW89_KCC][8] = 12, -- [0][1][1][0][RTW89_FCC][10] = -4, -- [0][1][1][0][RTW89_ETSI][10] = 54, -- [0][1][1][0][RTW89_KCC][10] = 12, -- [0][1][1][0][RTW89_FCC][12] = -4, -- [0][1][1][0][RTW89_ETSI][12] = 54, -- [0][1][1][0][RTW89_KCC][12] = 12, -- [0][1][1][0][RTW89_FCC][14] = -4, -- [0][1][1][0][RTW89_ETSI][14] = 54, -- [0][1][1][0][RTW89_KCC][14] = 12, -- [0][1][1][0][RTW89_FCC][15] = -4, -- [0][1][1][0][RTW89_ETSI][15] = 54, -- [0][1][1][0][RTW89_KCC][15] = 12, -- [0][1][1][0][RTW89_FCC][17] = -4, -- [0][1][1][0][RTW89_ETSI][17] = 54, -- [0][1][1][0][RTW89_KCC][17] = 12, -- [0][1][1][0][RTW89_FCC][19] = -4, -- [0][1][1][0][RTW89_ETSI][19] = 54, -- [0][1][1][0][RTW89_KCC][19] = 12, -- [0][1][1][0][RTW89_FCC][21] = -4, -- [0][1][1][0][RTW89_ETSI][21] = 54, -- [0][1][1][0][RTW89_KCC][21] = 12, -- [0][1][1][0][RTW89_FCC][23] = -4, -- [0][1][1][0][RTW89_ETSI][23] = 54, -- [0][1][1][0][RTW89_KCC][23] = 12, -- [0][1][1][0][RTW89_FCC][25] = -4, -- [0][1][1][0][RTW89_ETSI][25] = 54, -- [0][1][1][0][RTW89_KCC][25] = 12, -- [0][1][1][0][RTW89_FCC][27] = -4, -- [0][1][1][0][RTW89_ETSI][27] = 54, -- [0][1][1][0][RTW89_KCC][27] = 12, -- [0][1][1][0][RTW89_FCC][29] = -4, -- [0][1][1][0][RTW89_ETSI][29] = 54, -- [0][1][1][0][RTW89_KCC][29] = 12, -- [0][1][1][0][RTW89_FCC][30] = -4, -- [0][1][1][0][RTW89_ETSI][30] = 54, -- [0][1][1][0][RTW89_KCC][30] = 12, -- [0][1][1][0][RTW89_FCC][32] = -4, -- [0][1][1][0][RTW89_ETSI][32] = 54, -- [0][1][1][0][RTW89_KCC][32] = 12, -- [0][1][1][0][RTW89_FCC][34] = -4, -- [0][1][1][0][RTW89_ETSI][34] = 54, -- [0][1][1][0][RTW89_KCC][34] = 12, -- [0][1][1][0][RTW89_FCC][36] = -4, -- [0][1][1][0][RTW89_ETSI][36] = 54, -- [0][1][1][0][RTW89_KCC][36] = 12, -- [0][1][1][0][RTW89_FCC][38] = -4, -- [0][1][1][0][RTW89_ETSI][38] = 54, -- [0][1][1][0][RTW89_KCC][38] = 12, -- [0][1][1][0][RTW89_FCC][40] = -4, -- [0][1][1][0][RTW89_ETSI][40] = 54, -- [0][1][1][0][RTW89_KCC][40] = 12, -- [0][1][1][0][RTW89_FCC][42] = -4, -- [0][1][1][0][RTW89_ETSI][42] = 54, -- [0][1][1][0][RTW89_KCC][42] = 12, -- [0][1][1][0][RTW89_FCC][44] = -2, -- [0][1][1][0][RTW89_ETSI][44] = 54, -- [0][1][1][0][RTW89_KCC][44] = 12, -- [0][1][1][0][RTW89_FCC][45] = -2, -- [0][1][1][0][RTW89_ETSI][45] = 127, -- [0][1][1][0][RTW89_KCC][45] = 12, -- [0][1][1][0][RTW89_FCC][47] = -2, -- [0][1][1][0][RTW89_ETSI][47] = 127, -- [0][1][1][0][RTW89_KCC][47] = 12, -- [0][1][1][0][RTW89_FCC][49] = -2, -- [0][1][1][0][RTW89_ETSI][49] = 127, -- [0][1][1][0][RTW89_KCC][49] = 12, -- [0][1][1][0][RTW89_FCC][51] = -2, -- [0][1][1][0][RTW89_ETSI][51] = 127, -- [0][1][1][0][RTW89_KCC][51] = 12, -- [0][1][1][0][RTW89_FCC][53] = -2, -- [0][1][1][0][RTW89_ETSI][53] = 127, -- [0][1][1][0][RTW89_KCC][53] = 12, -- [0][1][1][0][RTW89_FCC][55] = -2, -- [0][1][1][0][RTW89_ETSI][55] = 127, -- [0][1][1][0][RTW89_KCC][55] = 12, -- [0][1][1][0][RTW89_FCC][57] = -2, -- [0][1][1][0][RTW89_ETSI][57] = 127, -- [0][1][1][0][RTW89_KCC][57] = 12, -- [0][1][1][0][RTW89_FCC][59] = -2, -- [0][1][1][0][RTW89_ETSI][59] = 127, -- [0][1][1][0][RTW89_KCC][59] = 12, -- [0][1][1][0][RTW89_FCC][60] = -2, -- [0][1][1][0][RTW89_ETSI][60] = 127, -- [0][1][1][0][RTW89_KCC][60] = 12, -- [0][1][1][0][RTW89_FCC][62] = -2, -- [0][1][1][0][RTW89_ETSI][62] = 127, -- [0][1][1][0][RTW89_KCC][62] = 12, -- [0][1][1][0][RTW89_FCC][64] = -2, -- [0][1][1][0][RTW89_ETSI][64] = 127, -- [0][1][1][0][RTW89_KCC][64] = 12, -- [0][1][1][0][RTW89_FCC][66] = -2, -- [0][1][1][0][RTW89_ETSI][66] = 127, -- [0][1][1][0][RTW89_KCC][66] = 12, -- [0][1][1][0][RTW89_FCC][68] = -2, -- [0][1][1][0][RTW89_ETSI][68] = 127, -- [0][1][1][0][RTW89_KCC][68] = 12, -- [0][1][1][0][RTW89_FCC][70] = -2, -- [0][1][1][0][RTW89_ETSI][70] = 127, -- [0][1][1][0][RTW89_KCC][70] = 12, -- [0][1][1][0][RTW89_FCC][72] = -2, -- [0][1][1][0][RTW89_ETSI][72] = 127, -- [0][1][1][0][RTW89_KCC][72] = 12, -- [0][1][1][0][RTW89_FCC][74] = -2, -- [0][1][1][0][RTW89_ETSI][74] = 127, -- [0][1][1][0][RTW89_KCC][74] = 12, -- [0][1][1][0][RTW89_FCC][75] = -2, -- [0][1][1][0][RTW89_ETSI][75] = 127, -- [0][1][1][0][RTW89_KCC][75] = 12, -- [0][1][1][0][RTW89_FCC][77] = -2, -- [0][1][1][0][RTW89_ETSI][77] = 127, -- [0][1][1][0][RTW89_KCC][77] = 12, -- [0][1][1][0][RTW89_FCC][79] = -2, -- [0][1][1][0][RTW89_ETSI][79] = 127, -- [0][1][1][0][RTW89_KCC][79] = 12, -- [0][1][1][0][RTW89_FCC][81] = -2, -- [0][1][1][0][RTW89_ETSI][81] = 127, -- [0][1][1][0][RTW89_KCC][81] = 12, -- [0][1][1][0][RTW89_FCC][83] = -2, -- [0][1][1][0][RTW89_ETSI][83] = 127, -- [0][1][1][0][RTW89_KCC][83] = 20, -- [0][1][1][0][RTW89_FCC][85] = -2, -- [0][1][1][0][RTW89_ETSI][85] = 127, -- [0][1][1][0][RTW89_KCC][85] = 20, -- [0][1][1][0][RTW89_FCC][87] = -2, -- [0][1][1][0][RTW89_ETSI][87] = 127, -- [0][1][1][0][RTW89_KCC][87] = 20, -- [0][1][1][0][RTW89_FCC][89] = -2, -- [0][1][1][0][RTW89_ETSI][89] = 127, -- [0][1][1][0][RTW89_KCC][89] = 20, -- [0][1][1][0][RTW89_FCC][90] = -2, -- [0][1][1][0][RTW89_ETSI][90] = 127, -- [0][1][1][0][RTW89_KCC][90] = 20, -- [0][1][1][0][RTW89_FCC][92] = -2, -- [0][1][1][0][RTW89_ETSI][92] = 127, -- [0][1][1][0][RTW89_KCC][92] = 20, -- [0][1][1][0][RTW89_FCC][94] = -2, -- [0][1][1][0][RTW89_ETSI][94] = 127, -- [0][1][1][0][RTW89_KCC][94] = 20, -- [0][1][1][0][RTW89_FCC][96] = -2, -- [0][1][1][0][RTW89_ETSI][96] = 127, -- [0][1][1][0][RTW89_KCC][96] = 20, -- [0][1][1][0][RTW89_FCC][98] = -2, -- [0][1][1][0][RTW89_ETSI][98] = 127, -- [0][1][1][0][RTW89_KCC][98] = 20, -- [0][1][1][0][RTW89_FCC][100] = -2, -- [0][1][1][0][RTW89_ETSI][100] = 127, -- [0][1][1][0][RTW89_KCC][100] = 20, -- [0][1][1][0][RTW89_FCC][102] = -2, -- [0][1][1][0][RTW89_ETSI][102] = 127, -- [0][1][1][0][RTW89_KCC][102] = 20, -- [0][1][1][0][RTW89_FCC][104] = -2, -- [0][1][1][0][RTW89_ETSI][104] = 127, -- [0][1][1][0][RTW89_KCC][104] = 20, -- [0][1][1][0][RTW89_FCC][105] = -2, -- [0][1][1][0][RTW89_ETSI][105] = 127, -- [0][1][1][0][RTW89_KCC][105] = 20, -- [0][1][1][0][RTW89_FCC][107] = 0, -- [0][1][1][0][RTW89_ETSI][107] = 127, -- [0][1][1][0][RTW89_KCC][107] = 20, -- [0][1][1][0][RTW89_FCC][109] = 0, -- [0][1][1][0][RTW89_ETSI][109] = 127, -- [0][1][1][0][RTW89_KCC][109] = 20, -- [0][1][1][0][RTW89_FCC][111] = 127, -- [0][1][1][0][RTW89_ETSI][111] = 127, -- [0][1][1][0][RTW89_KCC][111] = 127, -- [0][1][1][0][RTW89_FCC][113] = 127, -- [0][1][1][0][RTW89_ETSI][113] = 127, -- [0][1][1][0][RTW89_KCC][113] = 127, -- [0][1][1][0][RTW89_FCC][115] = 127, -- [0][1][1][0][RTW89_ETSI][115] = 127, -- [0][1][1][0][RTW89_KCC][115] = 127, -- [0][1][1][0][RTW89_FCC][117] = 127, -- [0][1][1][0][RTW89_ETSI][117] = 127, -- [0][1][1][0][RTW89_KCC][117] = 127, -- [0][1][1][0][RTW89_FCC][119] = 127, -- [0][1][1][0][RTW89_ETSI][119] = 127, -- [0][1][1][0][RTW89_KCC][119] = 127, -- [0][0][2][0][RTW89_FCC][0] = 24, -- [0][0][2][0][RTW89_ETSI][0] = 66, -- [0][0][2][0][RTW89_KCC][0] = 24, -- [0][0][2][0][RTW89_FCC][2] = 22, -- [0][0][2][0][RTW89_ETSI][2] = 66, -- [0][0][2][0][RTW89_KCC][2] = 24, -- [0][0][2][0][RTW89_FCC][4] = 22, -- [0][0][2][0][RTW89_ETSI][4] = 66, -- [0][0][2][0][RTW89_KCC][4] = 24, -- [0][0][2][0][RTW89_FCC][6] = 22, -- [0][0][2][0][RTW89_ETSI][6] = 66, -- [0][0][2][0][RTW89_KCC][6] = 24, -- [0][0][2][0][RTW89_FCC][8] = 22, -- [0][0][2][0][RTW89_ETSI][8] = 66, -- [0][0][2][0][RTW89_KCC][8] = 24, -- [0][0][2][0][RTW89_FCC][10] = 22, -- [0][0][2][0][RTW89_ETSI][10] = 66, -- [0][0][2][0][RTW89_KCC][10] = 24, -- [0][0][2][0][RTW89_FCC][12] = 22, -- [0][0][2][0][RTW89_ETSI][12] = 66, -- [0][0][2][0][RTW89_KCC][12] = 24, -- [0][0][2][0][RTW89_FCC][14] = 22, -- [0][0][2][0][RTW89_ETSI][14] = 66, -- [0][0][2][0][RTW89_KCC][14] = 24, -- [0][0][2][0][RTW89_FCC][15] = 22, -- [0][0][2][0][RTW89_ETSI][15] = 66, -- [0][0][2][0][RTW89_KCC][15] = 24, -- [0][0][2][0][RTW89_FCC][17] = 22, -- [0][0][2][0][RTW89_ETSI][17] = 66, -- [0][0][2][0][RTW89_KCC][17] = 24, -- [0][0][2][0][RTW89_FCC][19] = 22, -- [0][0][2][0][RTW89_ETSI][19] = 66, -- [0][0][2][0][RTW89_KCC][19] = 24, -- [0][0][2][0][RTW89_FCC][21] = 22, -- [0][0][2][0][RTW89_ETSI][21] = 66, -- [0][0][2][0][RTW89_KCC][21] = 24, -- [0][0][2][0][RTW89_FCC][23] = 22, -- [0][0][2][0][RTW89_ETSI][23] = 66, -- [0][0][2][0][RTW89_KCC][23] = 24, -- [0][0][2][0][RTW89_FCC][25] = 22, -- [0][0][2][0][RTW89_ETSI][25] = 66, -- [0][0][2][0][RTW89_KCC][25] = 24, -- [0][0][2][0][RTW89_FCC][27] = 22, -- [0][0][2][0][RTW89_ETSI][27] = 66, -- [0][0][2][0][RTW89_KCC][27] = 24, -- [0][0][2][0][RTW89_FCC][29] = 22, -- [0][0][2][0][RTW89_ETSI][29] = 66, -- [0][0][2][0][RTW89_KCC][29] = 24, -- [0][0][2][0][RTW89_FCC][30] = 22, -- [0][0][2][0][RTW89_ETSI][30] = 66, -- [0][0][2][0][RTW89_KCC][30] = 24, -- [0][0][2][0][RTW89_FCC][32] = 22, -- [0][0][2][0][RTW89_ETSI][32] = 66, -- [0][0][2][0][RTW89_KCC][32] = 24, -- [0][0][2][0][RTW89_FCC][34] = 22, -- [0][0][2][0][RTW89_ETSI][34] = 66, -- [0][0][2][0][RTW89_KCC][34] = 24, -- [0][0][2][0][RTW89_FCC][36] = 22, -- [0][0][2][0][RTW89_ETSI][36] = 66, -- [0][0][2][0][RTW89_KCC][36] = 24, -- [0][0][2][0][RTW89_FCC][38] = 22, -- [0][0][2][0][RTW89_ETSI][38] = 66, -- [0][0][2][0][RTW89_KCC][38] = 24, -- [0][0][2][0][RTW89_FCC][40] = 22, -- [0][0][2][0][RTW89_ETSI][40] = 66, -- [0][0][2][0][RTW89_KCC][40] = 24, -- [0][0][2][0][RTW89_FCC][42] = 22, -- [0][0][2][0][RTW89_ETSI][42] = 66, -- [0][0][2][0][RTW89_KCC][42] = 24, -- [0][0][2][0][RTW89_FCC][44] = 22, -- [0][0][2][0][RTW89_ETSI][44] = 66, -- [0][0][2][0][RTW89_KCC][44] = 24, -- [0][0][2][0][RTW89_FCC][45] = 22, -- [0][0][2][0][RTW89_ETSI][45] = 127, -- [0][0][2][0][RTW89_KCC][45] = 24, -- [0][0][2][0][RTW89_FCC][47] = 22, -- [0][0][2][0][RTW89_ETSI][47] = 127, -- [0][0][2][0][RTW89_KCC][47] = 24, -- [0][0][2][0][RTW89_FCC][49] = 24, -- [0][0][2][0][RTW89_ETSI][49] = 127, -- [0][0][2][0][RTW89_KCC][49] = 24, -- [0][0][2][0][RTW89_FCC][51] = 22, -- [0][0][2][0][RTW89_ETSI][51] = 127, -- [0][0][2][0][RTW89_KCC][51] = 24, -- [0][0][2][0][RTW89_FCC][53] = 22, -- [0][0][2][0][RTW89_ETSI][53] = 127, -- [0][0][2][0][RTW89_KCC][53] = 24, -- [0][0][2][0][RTW89_FCC][55] = 22, -- [0][0][2][0][RTW89_ETSI][55] = 127, -- [0][0][2][0][RTW89_KCC][55] = 26, -- [0][0][2][0][RTW89_FCC][57] = 22, -- [0][0][2][0][RTW89_ETSI][57] = 127, -- [0][0][2][0][RTW89_KCC][57] = 26, -- [0][0][2][0][RTW89_FCC][59] = 22, -- [0][0][2][0][RTW89_ETSI][59] = 127, -- [0][0][2][0][RTW89_KCC][59] = 26, -- [0][0][2][0][RTW89_FCC][60] = 22, -- [0][0][2][0][RTW89_ETSI][60] = 127, -- [0][0][2][0][RTW89_KCC][60] = 26, -- [0][0][2][0][RTW89_FCC][62] = 22, -- [0][0][2][0][RTW89_ETSI][62] = 127, -- [0][0][2][0][RTW89_KCC][62] = 26, -- [0][0][2][0][RTW89_FCC][64] = 22, -- [0][0][2][0][RTW89_ETSI][64] = 127, -- [0][0][2][0][RTW89_KCC][64] = 26, -- [0][0][2][0][RTW89_FCC][66] = 22, -- [0][0][2][0][RTW89_ETSI][66] = 127, -- [0][0][2][0][RTW89_KCC][66] = 26, -- [0][0][2][0][RTW89_FCC][68] = 22, -- [0][0][2][0][RTW89_ETSI][68] = 127, -- [0][0][2][0][RTW89_KCC][68] = 26, -- [0][0][2][0][RTW89_FCC][70] = 24, -- [0][0][2][0][RTW89_ETSI][70] = 127, -- [0][0][2][0][RTW89_KCC][70] = 26, -- [0][0][2][0][RTW89_FCC][72] = 22, -- [0][0][2][0][RTW89_ETSI][72] = 127, -- [0][0][2][0][RTW89_KCC][72] = 26, -- [0][0][2][0][RTW89_FCC][74] = 22, -- [0][0][2][0][RTW89_ETSI][74] = 127, -- [0][0][2][0][RTW89_KCC][74] = 26, -- [0][0][2][0][RTW89_FCC][75] = 22, -- [0][0][2][0][RTW89_ETSI][75] = 127, -- [0][0][2][0][RTW89_KCC][75] = 26, -- [0][0][2][0][RTW89_FCC][77] = 22, -- [0][0][2][0][RTW89_ETSI][77] = 127, -- [0][0][2][0][RTW89_KCC][77] = 26, -- [0][0][2][0][RTW89_FCC][79] = 22, -- [0][0][2][0][RTW89_ETSI][79] = 127, -- [0][0][2][0][RTW89_KCC][79] = 26, -- [0][0][2][0][RTW89_FCC][81] = 22, -- [0][0][2][0][RTW89_ETSI][81] = 127, -- [0][0][2][0][RTW89_KCC][81] = 26, -- [0][0][2][0][RTW89_FCC][83] = 22, -- [0][0][2][0][RTW89_ETSI][83] = 127, -- [0][0][2][0][RTW89_KCC][83] = 32, -- [0][0][2][0][RTW89_FCC][85] = 22, -- [0][0][2][0][RTW89_ETSI][85] = 127, -- [0][0][2][0][RTW89_KCC][85] = 32, -- [0][0][2][0][RTW89_FCC][87] = 22, -- [0][0][2][0][RTW89_ETSI][87] = 127, -- [0][0][2][0][RTW89_KCC][87] = 32, -- [0][0][2][0][RTW89_FCC][89] = 22, -- [0][0][2][0][RTW89_ETSI][89] = 127, -- [0][0][2][0][RTW89_KCC][89] = 32, -- [0][0][2][0][RTW89_FCC][90] = 22, -- [0][0][2][0][RTW89_ETSI][90] = 127, -- [0][0][2][0][RTW89_KCC][90] = 32, -- [0][0][2][0][RTW89_FCC][92] = 22, -- [0][0][2][0][RTW89_ETSI][92] = 127, -- [0][0][2][0][RTW89_KCC][92] = 32, -- [0][0][2][0][RTW89_FCC][94] = 22, -- [0][0][2][0][RTW89_ETSI][94] = 127, -- [0][0][2][0][RTW89_KCC][94] = 32, -- [0][0][2][0][RTW89_FCC][96] = 22, -- [0][0][2][0][RTW89_ETSI][96] = 127, -- [0][0][2][0][RTW89_KCC][96] = 32, -- [0][0][2][0][RTW89_FCC][98] = 22, -- [0][0][2][0][RTW89_ETSI][98] = 127, -- [0][0][2][0][RTW89_KCC][98] = 32, -- [0][0][2][0][RTW89_FCC][100] = 22, -- [0][0][2][0][RTW89_ETSI][100] = 127, -- [0][0][2][0][RTW89_KCC][100] = 32, -- [0][0][2][0][RTW89_FCC][102] = 22, -- [0][0][2][0][RTW89_ETSI][102] = 127, -- [0][0][2][0][RTW89_KCC][102] = 32, -- [0][0][2][0][RTW89_FCC][104] = 22, -- [0][0][2][0][RTW89_ETSI][104] = 127, -- [0][0][2][0][RTW89_KCC][104] = 32, -- [0][0][2][0][RTW89_FCC][105] = 22, -- [0][0][2][0][RTW89_ETSI][105] = 127, -- [0][0][2][0][RTW89_KCC][105] = 32, -- [0][0][2][0][RTW89_FCC][107] = 24, -- [0][0][2][0][RTW89_ETSI][107] = 127, -- [0][0][2][0][RTW89_KCC][107] = 32, -- [0][0][2][0][RTW89_FCC][109] = 24, -- [0][0][2][0][RTW89_ETSI][109] = 127, -- [0][0][2][0][RTW89_KCC][109] = 32, -- [0][0][2][0][RTW89_FCC][111] = 127, -- [0][0][2][0][RTW89_ETSI][111] = 127, -- [0][0][2][0][RTW89_KCC][111] = 127, -- [0][0][2][0][RTW89_FCC][113] = 127, -- [0][0][2][0][RTW89_ETSI][113] = 127, -- [0][0][2][0][RTW89_KCC][113] = 127, -- [0][0][2][0][RTW89_FCC][115] = 127, -- [0][0][2][0][RTW89_ETSI][115] = 127, -- [0][0][2][0][RTW89_KCC][115] = 127, -- [0][0][2][0][RTW89_FCC][117] = 127, -- [0][0][2][0][RTW89_ETSI][117] = 127, -- [0][0][2][0][RTW89_KCC][117] = 127, -- [0][0][2][0][RTW89_FCC][119] = 127, -- [0][0][2][0][RTW89_ETSI][119] = 127, -- [0][0][2][0][RTW89_KCC][119] = 127, -- [0][1][2][0][RTW89_FCC][0] = -2, -- [0][1][2][0][RTW89_ETSI][0] = 54, -- [0][1][2][0][RTW89_KCC][0] = 12, -- [0][1][2][0][RTW89_FCC][2] = -4, -- [0][1][2][0][RTW89_ETSI][2] = 54, -- [0][1][2][0][RTW89_KCC][2] = 12, -- [0][1][2][0][RTW89_FCC][4] = -4, -- [0][1][2][0][RTW89_ETSI][4] = 54, -- [0][1][2][0][RTW89_KCC][4] = 12, -- [0][1][2][0][RTW89_FCC][6] = -4, -- [0][1][2][0][RTW89_ETSI][6] = 54, -- [0][1][2][0][RTW89_KCC][6] = 12, -- [0][1][2][0][RTW89_FCC][8] = -4, -- [0][1][2][0][RTW89_ETSI][8] = 54, -- [0][1][2][0][RTW89_KCC][8] = 12, -- [0][1][2][0][RTW89_FCC][10] = -4, -- [0][1][2][0][RTW89_ETSI][10] = 54, -- [0][1][2][0][RTW89_KCC][10] = 12, -- [0][1][2][0][RTW89_FCC][12] = -4, -- [0][1][2][0][RTW89_ETSI][12] = 54, -- [0][1][2][0][RTW89_KCC][12] = 12, -- [0][1][2][0][RTW89_FCC][14] = -4, -- [0][1][2][0][RTW89_ETSI][14] = 54, -- [0][1][2][0][RTW89_KCC][14] = 12, -- [0][1][2][0][RTW89_FCC][15] = -4, -- [0][1][2][0][RTW89_ETSI][15] = 54, -- [0][1][2][0][RTW89_KCC][15] = 12, -- [0][1][2][0][RTW89_FCC][17] = -4, -- [0][1][2][0][RTW89_ETSI][17] = 54, -- [0][1][2][0][RTW89_KCC][17] = 12, -- [0][1][2][0][RTW89_FCC][19] = -4, -- [0][1][2][0][RTW89_ETSI][19] = 54, -- [0][1][2][0][RTW89_KCC][19] = 12, -- [0][1][2][0][RTW89_FCC][21] = -4, -- [0][1][2][0][RTW89_ETSI][21] = 54, -- [0][1][2][0][RTW89_KCC][21] = 12, -- [0][1][2][0][RTW89_FCC][23] = -4, -- [0][1][2][0][RTW89_ETSI][23] = 54, -- [0][1][2][0][RTW89_KCC][23] = 12, -- [0][1][2][0][RTW89_FCC][25] = -4, -- [0][1][2][0][RTW89_ETSI][25] = 54, -- [0][1][2][0][RTW89_KCC][25] = 12, -- [0][1][2][0][RTW89_FCC][27] = -4, -- [0][1][2][0][RTW89_ETSI][27] = 54, -- [0][1][2][0][RTW89_KCC][27] = 12, -- [0][1][2][0][RTW89_FCC][29] = -4, -- [0][1][2][0][RTW89_ETSI][29] = 54, -- [0][1][2][0][RTW89_KCC][29] = 12, -- [0][1][2][0][RTW89_FCC][30] = -4, -- [0][1][2][0][RTW89_ETSI][30] = 54, -- [0][1][2][0][RTW89_KCC][30] = 12, -- [0][1][2][0][RTW89_FCC][32] = -4, -- [0][1][2][0][RTW89_ETSI][32] = 54, -- [0][1][2][0][RTW89_KCC][32] = 12, -- [0][1][2][0][RTW89_FCC][34] = -4, -- [0][1][2][0][RTW89_ETSI][34] = 54, -- [0][1][2][0][RTW89_KCC][34] = 12, -- [0][1][2][0][RTW89_FCC][36] = -4, -- [0][1][2][0][RTW89_ETSI][36] = 54, -- [0][1][2][0][RTW89_KCC][36] = 12, -- [0][1][2][0][RTW89_FCC][38] = -4, -- [0][1][2][0][RTW89_ETSI][38] = 54, -- [0][1][2][0][RTW89_KCC][38] = 12, -- [0][1][2][0][RTW89_FCC][40] = -4, -- [0][1][2][0][RTW89_ETSI][40] = 54, -- [0][1][2][0][RTW89_KCC][40] = 12, -- [0][1][2][0][RTW89_FCC][42] = -4, -- [0][1][2][0][RTW89_ETSI][42] = 54, -- [0][1][2][0][RTW89_KCC][42] = 12, -- [0][1][2][0][RTW89_FCC][44] = -2, -- [0][1][2][0][RTW89_ETSI][44] = 54, -- [0][1][2][0][RTW89_KCC][44] = 12, -- [0][1][2][0][RTW89_FCC][45] = -2, -- [0][1][2][0][RTW89_ETSI][45] = 127, -- [0][1][2][0][RTW89_KCC][45] = 12, -- [0][1][2][0][RTW89_FCC][47] = -2, -- [0][1][2][0][RTW89_ETSI][47] = 127, -- [0][1][2][0][RTW89_KCC][47] = 12, -- [0][1][2][0][RTW89_FCC][49] = -2, -- [0][1][2][0][RTW89_ETSI][49] = 127, -- [0][1][2][0][RTW89_KCC][49] = 12, -- [0][1][2][0][RTW89_FCC][51] = -2, -- [0][1][2][0][RTW89_ETSI][51] = 127, -- [0][1][2][0][RTW89_KCC][51] = 12, -- [0][1][2][0][RTW89_FCC][53] = -2, -- [0][1][2][0][RTW89_ETSI][53] = 127, -- [0][1][2][0][RTW89_KCC][53] = 12, -- [0][1][2][0][RTW89_FCC][55] = -2, -- [0][1][2][0][RTW89_ETSI][55] = 127, -- [0][1][2][0][RTW89_KCC][55] = 12, -- [0][1][2][0][RTW89_FCC][57] = -2, -- [0][1][2][0][RTW89_ETSI][57] = 127, -- [0][1][2][0][RTW89_KCC][57] = 12, -- [0][1][2][0][RTW89_FCC][59] = -2, -- [0][1][2][0][RTW89_ETSI][59] = 127, -- [0][1][2][0][RTW89_KCC][59] = 12, -- [0][1][2][0][RTW89_FCC][60] = -2, -- [0][1][2][0][RTW89_ETSI][60] = 127, -- [0][1][2][0][RTW89_KCC][60] = 12, -- [0][1][2][0][RTW89_FCC][62] = -2, -- [0][1][2][0][RTW89_ETSI][62] = 127, -- [0][1][2][0][RTW89_KCC][62] = 12, -- [0][1][2][0][RTW89_FCC][64] = -2, -- [0][1][2][0][RTW89_ETSI][64] = 127, -- [0][1][2][0][RTW89_KCC][64] = 12, -- [0][1][2][0][RTW89_FCC][66] = -2, -- [0][1][2][0][RTW89_ETSI][66] = 127, -- [0][1][2][0][RTW89_KCC][66] = 12, -- [0][1][2][0][RTW89_FCC][68] = -2, -- [0][1][2][0][RTW89_ETSI][68] = 127, -- [0][1][2][0][RTW89_KCC][68] = 12, -- [0][1][2][0][RTW89_FCC][70] = -2, -- [0][1][2][0][RTW89_ETSI][70] = 127, -- [0][1][2][0][RTW89_KCC][70] = 12, -- [0][1][2][0][RTW89_FCC][72] = -2, -- [0][1][2][0][RTW89_ETSI][72] = 127, -- [0][1][2][0][RTW89_KCC][72] = 12, -- [0][1][2][0][RTW89_FCC][74] = -2, -- [0][1][2][0][RTW89_ETSI][74] = 127, -- [0][1][2][0][RTW89_KCC][74] = 12, -- [0][1][2][0][RTW89_FCC][75] = -2, -- [0][1][2][0][RTW89_ETSI][75] = 127, -- [0][1][2][0][RTW89_KCC][75] = 12, -- [0][1][2][0][RTW89_FCC][77] = -2, -- [0][1][2][0][RTW89_ETSI][77] = 127, -- [0][1][2][0][RTW89_KCC][77] = 12, -- [0][1][2][0][RTW89_FCC][79] = -2, -- [0][1][2][0][RTW89_ETSI][79] = 127, -- [0][1][2][0][RTW89_KCC][79] = 12, -- [0][1][2][0][RTW89_FCC][81] = -2, -- [0][1][2][0][RTW89_ETSI][81] = 127, -- [0][1][2][0][RTW89_KCC][81] = 12, -- [0][1][2][0][RTW89_FCC][83] = -2, -- [0][1][2][0][RTW89_ETSI][83] = 127, -- [0][1][2][0][RTW89_KCC][83] = 20, -- [0][1][2][0][RTW89_FCC][85] = -2, -- [0][1][2][0][RTW89_ETSI][85] = 127, -- [0][1][2][0][RTW89_KCC][85] = 20, -- [0][1][2][0][RTW89_FCC][87] = -2, -- [0][1][2][0][RTW89_ETSI][87] = 127, -- [0][1][2][0][RTW89_KCC][87] = 20, -- [0][1][2][0][RTW89_FCC][89] = -2, -- [0][1][2][0][RTW89_ETSI][89] = 127, -- [0][1][2][0][RTW89_KCC][89] = 20, -- [0][1][2][0][RTW89_FCC][90] = -2, -- [0][1][2][0][RTW89_ETSI][90] = 127, -- [0][1][2][0][RTW89_KCC][90] = 20, -- [0][1][2][0][RTW89_FCC][92] = -2, -- [0][1][2][0][RTW89_ETSI][92] = 127, -- [0][1][2][0][RTW89_KCC][92] = 20, -- [0][1][2][0][RTW89_FCC][94] = -2, -- [0][1][2][0][RTW89_ETSI][94] = 127, -- [0][1][2][0][RTW89_KCC][94] = 20, -- [0][1][2][0][RTW89_FCC][96] = -2, -- [0][1][2][0][RTW89_ETSI][96] = 127, -- [0][1][2][0][RTW89_KCC][96] = 20, -- [0][1][2][0][RTW89_FCC][98] = -2, -- [0][1][2][0][RTW89_ETSI][98] = 127, -- [0][1][2][0][RTW89_KCC][98] = 20, -- [0][1][2][0][RTW89_FCC][100] = -2, -- [0][1][2][0][RTW89_ETSI][100] = 127, -- [0][1][2][0][RTW89_KCC][100] = 20, -- [0][1][2][0][RTW89_FCC][102] = -2, -- [0][1][2][0][RTW89_ETSI][102] = 127, -- [0][1][2][0][RTW89_KCC][102] = 20, -- [0][1][2][0][RTW89_FCC][104] = -2, -- [0][1][2][0][RTW89_ETSI][104] = 127, -- [0][1][2][0][RTW89_KCC][104] = 20, -- [0][1][2][0][RTW89_FCC][105] = -2, -- [0][1][2][0][RTW89_ETSI][105] = 127, -- [0][1][2][0][RTW89_KCC][105] = 20, -- [0][1][2][0][RTW89_FCC][107] = 0, -- [0][1][2][0][RTW89_ETSI][107] = 127, -- [0][1][2][0][RTW89_KCC][107] = 20, -- [0][1][2][0][RTW89_FCC][109] = 0, -- [0][1][2][0][RTW89_ETSI][109] = 127, -- [0][1][2][0][RTW89_KCC][109] = 20, -- [0][1][2][0][RTW89_FCC][111] = 127, -- [0][1][2][0][RTW89_ETSI][111] = 127, -- [0][1][2][0][RTW89_KCC][111] = 127, -- [0][1][2][0][RTW89_FCC][113] = 127, -- [0][1][2][0][RTW89_ETSI][113] = 127, -- [0][1][2][0][RTW89_KCC][113] = 127, -- [0][1][2][0][RTW89_FCC][115] = 127, -- [0][1][2][0][RTW89_ETSI][115] = 127, -- [0][1][2][0][RTW89_KCC][115] = 127, -- [0][1][2][0][RTW89_FCC][117] = 127, -- [0][1][2][0][RTW89_ETSI][117] = 127, -- [0][1][2][0][RTW89_KCC][117] = 127, -- [0][1][2][0][RTW89_FCC][119] = 127, -- [0][1][2][0][RTW89_ETSI][119] = 127, -- [0][1][2][0][RTW89_KCC][119] = 127, -- [0][1][2][1][RTW89_FCC][0] = -2, -- [0][1][2][1][RTW89_ETSI][0] = 42, -- [0][1][2][1][RTW89_KCC][0] = 12, -- [0][1][2][1][RTW89_FCC][2] = -4, -- [0][1][2][1][RTW89_ETSI][2] = 42, -- [0][1][2][1][RTW89_KCC][2] = 12, -- [0][1][2][1][RTW89_FCC][4] = -4, -- [0][1][2][1][RTW89_ETSI][4] = 42, -- [0][1][2][1][RTW89_KCC][4] = 12, -- [0][1][2][1][RTW89_FCC][6] = -4, -- [0][1][2][1][RTW89_ETSI][6] = 42, -- [0][1][2][1][RTW89_KCC][6] = 12, -- [0][1][2][1][RTW89_FCC][8] = -4, -- [0][1][2][1][RTW89_ETSI][8] = 42, -- [0][1][2][1][RTW89_KCC][8] = 12, -- [0][1][2][1][RTW89_FCC][10] = -4, -- [0][1][2][1][RTW89_ETSI][10] = 42, -- [0][1][2][1][RTW89_KCC][10] = 12, -- [0][1][2][1][RTW89_FCC][12] = -4, -- [0][1][2][1][RTW89_ETSI][12] = 42, -- [0][1][2][1][RTW89_KCC][12] = 12, -- [0][1][2][1][RTW89_FCC][14] = -4, -- [0][1][2][1][RTW89_ETSI][14] = 42, -- [0][1][2][1][RTW89_KCC][14] = 12, -- [0][1][2][1][RTW89_FCC][15] = -4, -- [0][1][2][1][RTW89_ETSI][15] = 42, -- [0][1][2][1][RTW89_KCC][15] = 12, -- [0][1][2][1][RTW89_FCC][17] = -4, -- [0][1][2][1][RTW89_ETSI][17] = 42, -- [0][1][2][1][RTW89_KCC][17] = 12, -- [0][1][2][1][RTW89_FCC][19] = -4, -- [0][1][2][1][RTW89_ETSI][19] = 42, -- [0][1][2][1][RTW89_KCC][19] = 12, -- [0][1][2][1][RTW89_FCC][21] = -4, -- [0][1][2][1][RTW89_ETSI][21] = 42, -- [0][1][2][1][RTW89_KCC][21] = 12, -- [0][1][2][1][RTW89_FCC][23] = -4, -- [0][1][2][1][RTW89_ETSI][23] = 42, -- [0][1][2][1][RTW89_KCC][23] = 12, -- [0][1][2][1][RTW89_FCC][25] = -4, -- [0][1][2][1][RTW89_ETSI][25] = 42, -- [0][1][2][1][RTW89_KCC][25] = 12, -- [0][1][2][1][RTW89_FCC][27] = -4, -- [0][1][2][1][RTW89_ETSI][27] = 42, -- [0][1][2][1][RTW89_KCC][27] = 12, -- [0][1][2][1][RTW89_FCC][29] = -4, -- [0][1][2][1][RTW89_ETSI][29] = 42, -- [0][1][2][1][RTW89_KCC][29] = 12, -- [0][1][2][1][RTW89_FCC][30] = -4, -- [0][1][2][1][RTW89_ETSI][30] = 42, -- [0][1][2][1][RTW89_KCC][30] = 12, -- [0][1][2][1][RTW89_FCC][32] = -4, -- [0][1][2][1][RTW89_ETSI][32] = 42, -- [0][1][2][1][RTW89_KCC][32] = 12, -- [0][1][2][1][RTW89_FCC][34] = -4, -- [0][1][2][1][RTW89_ETSI][34] = 42, -- [0][1][2][1][RTW89_KCC][34] = 12, -- [0][1][2][1][RTW89_FCC][36] = -4, -- [0][1][2][1][RTW89_ETSI][36] = 42, -- [0][1][2][1][RTW89_KCC][36] = 12, -- [0][1][2][1][RTW89_FCC][38] = -4, -- [0][1][2][1][RTW89_ETSI][38] = 42, -- [0][1][2][1][RTW89_KCC][38] = 12, -- [0][1][2][1][RTW89_FCC][40] = -4, -- [0][1][2][1][RTW89_ETSI][40] = 42, -- [0][1][2][1][RTW89_KCC][40] = 12, -- [0][1][2][1][RTW89_FCC][42] = -4, -- [0][1][2][1][RTW89_ETSI][42] = 42, -- [0][1][2][1][RTW89_KCC][42] = 12, -- [0][1][2][1][RTW89_FCC][44] = -2, -- [0][1][2][1][RTW89_ETSI][44] = 42, -- [0][1][2][1][RTW89_KCC][44] = 12, -- [0][1][2][1][RTW89_FCC][45] = -2, -- [0][1][2][1][RTW89_ETSI][45] = 127, -- [0][1][2][1][RTW89_KCC][45] = 12, -- [0][1][2][1][RTW89_FCC][47] = -2, -- [0][1][2][1][RTW89_ETSI][47] = 127, -- [0][1][2][1][RTW89_KCC][47] = 12, -- [0][1][2][1][RTW89_FCC][49] = -2, -- [0][1][2][1][RTW89_ETSI][49] = 127, -- [0][1][2][1][RTW89_KCC][49] = 12, -- [0][1][2][1][RTW89_FCC][51] = -2, -- [0][1][2][1][RTW89_ETSI][51] = 127, -- [0][1][2][1][RTW89_KCC][51] = 12, -- [0][1][2][1][RTW89_FCC][53] = -2, -- [0][1][2][1][RTW89_ETSI][53] = 127, -- [0][1][2][1][RTW89_KCC][53] = 12, -- [0][1][2][1][RTW89_FCC][55] = -2, -- [0][1][2][1][RTW89_ETSI][55] = 127, -- [0][1][2][1][RTW89_KCC][55] = 12, -- [0][1][2][1][RTW89_FCC][57] = -2, -- [0][1][2][1][RTW89_ETSI][57] = 127, -- [0][1][2][1][RTW89_KCC][57] = 12, -- [0][1][2][1][RTW89_FCC][59] = -2, -- [0][1][2][1][RTW89_ETSI][59] = 127, -- [0][1][2][1][RTW89_KCC][59] = 12, -- [0][1][2][1][RTW89_FCC][60] = -2, -- [0][1][2][1][RTW89_ETSI][60] = 127, -- [0][1][2][1][RTW89_KCC][60] = 12, -- [0][1][2][1][RTW89_FCC][62] = -2, -- [0][1][2][1][RTW89_ETSI][62] = 127, -- [0][1][2][1][RTW89_KCC][62] = 12, -- [0][1][2][1][RTW89_FCC][64] = -2, -- [0][1][2][1][RTW89_ETSI][64] = 127, -- [0][1][2][1][RTW89_KCC][64] = 12, -- [0][1][2][1][RTW89_FCC][66] = -2, -- [0][1][2][1][RTW89_ETSI][66] = 127, -- [0][1][2][1][RTW89_KCC][66] = 12, -- [0][1][2][1][RTW89_FCC][68] = -2, -- [0][1][2][1][RTW89_ETSI][68] = 127, -- [0][1][2][1][RTW89_KCC][68] = 12, -- [0][1][2][1][RTW89_FCC][70] = -2, -- [0][1][2][1][RTW89_ETSI][70] = 127, -- [0][1][2][1][RTW89_KCC][70] = 12, -- [0][1][2][1][RTW89_FCC][72] = -2, -- [0][1][2][1][RTW89_ETSI][72] = 127, -- [0][1][2][1][RTW89_KCC][72] = 12, -- [0][1][2][1][RTW89_FCC][74] = -2, -- [0][1][2][1][RTW89_ETSI][74] = 127, -- [0][1][2][1][RTW89_KCC][74] = 12, -- [0][1][2][1][RTW89_FCC][75] = -2, -- [0][1][2][1][RTW89_ETSI][75] = 127, -- [0][1][2][1][RTW89_KCC][75] = 12, -- [0][1][2][1][RTW89_FCC][77] = -2, -- [0][1][2][1][RTW89_ETSI][77] = 127, -- [0][1][2][1][RTW89_KCC][77] = 12, -- [0][1][2][1][RTW89_FCC][79] = -2, -- [0][1][2][1][RTW89_ETSI][79] = 127, -- [0][1][2][1][RTW89_KCC][79] = 12, -- [0][1][2][1][RTW89_FCC][81] = -2, -- [0][1][2][1][RTW89_ETSI][81] = 127, -- [0][1][2][1][RTW89_KCC][81] = 12, -- [0][1][2][1][RTW89_FCC][83] = -2, -- [0][1][2][1][RTW89_ETSI][83] = 127, -- [0][1][2][1][RTW89_KCC][83] = 20, -- [0][1][2][1][RTW89_FCC][85] = -2, -- [0][1][2][1][RTW89_ETSI][85] = 127, -- [0][1][2][1][RTW89_KCC][85] = 20, -- [0][1][2][1][RTW89_FCC][87] = -2, -- [0][1][2][1][RTW89_ETSI][87] = 127, -- [0][1][2][1][RTW89_KCC][87] = 20, -- [0][1][2][1][RTW89_FCC][89] = -2, -- [0][1][2][1][RTW89_ETSI][89] = 127, -- [0][1][2][1][RTW89_KCC][89] = 20, -- [0][1][2][1][RTW89_FCC][90] = -2, -- [0][1][2][1][RTW89_ETSI][90] = 127, -- [0][1][2][1][RTW89_KCC][90] = 20, -- [0][1][2][1][RTW89_FCC][92] = -2, -- [0][1][2][1][RTW89_ETSI][92] = 127, -- [0][1][2][1][RTW89_KCC][92] = 20, -- [0][1][2][1][RTW89_FCC][94] = -2, -- [0][1][2][1][RTW89_ETSI][94] = 127, -- [0][1][2][1][RTW89_KCC][94] = 20, -- [0][1][2][1][RTW89_FCC][96] = -2, -- [0][1][2][1][RTW89_ETSI][96] = 127, -- [0][1][2][1][RTW89_KCC][96] = 20, -- [0][1][2][1][RTW89_FCC][98] = -2, -- [0][1][2][1][RTW89_ETSI][98] = 127, -- [0][1][2][1][RTW89_KCC][98] = 20, -- [0][1][2][1][RTW89_FCC][100] = -2, -- [0][1][2][1][RTW89_ETSI][100] = 127, -- [0][1][2][1][RTW89_KCC][100] = 20, -- [0][1][2][1][RTW89_FCC][102] = -2, -- [0][1][2][1][RTW89_ETSI][102] = 127, -- [0][1][2][1][RTW89_KCC][102] = 20, -- [0][1][2][1][RTW89_FCC][104] = -2, -- [0][1][2][1][RTW89_ETSI][104] = 127, -- [0][1][2][1][RTW89_KCC][104] = 20, -- [0][1][2][1][RTW89_FCC][105] = -2, -- [0][1][2][1][RTW89_ETSI][105] = 127, -- [0][1][2][1][RTW89_KCC][105] = 20, -- [0][1][2][1][RTW89_FCC][107] = 0, -- [0][1][2][1][RTW89_ETSI][107] = 127, -- [0][1][2][1][RTW89_KCC][107] = 20, -- [0][1][2][1][RTW89_FCC][109] = 0, -- [0][1][2][1][RTW89_ETSI][109] = 127, -- [0][1][2][1][RTW89_KCC][109] = 20, -- [0][1][2][1][RTW89_FCC][111] = 127, -- [0][1][2][1][RTW89_ETSI][111] = 127, -- [0][1][2][1][RTW89_KCC][111] = 127, -- [0][1][2][1][RTW89_FCC][113] = 127, -- [0][1][2][1][RTW89_ETSI][113] = 127, -- [0][1][2][1][RTW89_KCC][113] = 127, -- [0][1][2][1][RTW89_FCC][115] = 127, -- [0][1][2][1][RTW89_ETSI][115] = 127, -- [0][1][2][1][RTW89_KCC][115] = 127, -- [0][1][2][1][RTW89_FCC][117] = 127, -- [0][1][2][1][RTW89_ETSI][117] = 127, -- [0][1][2][1][RTW89_KCC][117] = 127, -- [0][1][2][1][RTW89_FCC][119] = 127, -- [0][1][2][1][RTW89_ETSI][119] = 127, -- [0][1][2][1][RTW89_KCC][119] = 127, -- [1][0][2][0][RTW89_FCC][1] = 34, -- [1][0][2][0][RTW89_ETSI][1] = 66, -- [1][0][2][0][RTW89_KCC][1] = 40, -- [1][0][2][0][RTW89_FCC][5] = 34, -- [1][0][2][0][RTW89_ETSI][5] = 66, -- [1][0][2][0][RTW89_KCC][5] = 40, -- [1][0][2][0][RTW89_FCC][9] = 34, -- [1][0][2][0][RTW89_ETSI][9] = 66, -- [1][0][2][0][RTW89_KCC][9] = 40, -- [1][0][2][0][RTW89_FCC][13] = 34, -- [1][0][2][0][RTW89_ETSI][13] = 66, -- [1][0][2][0][RTW89_KCC][13] = 40, -- [1][0][2][0][RTW89_FCC][16] = 34, -- [1][0][2][0][RTW89_ETSI][16] = 66, -- [1][0][2][0][RTW89_KCC][16] = 40, -- [1][0][2][0][RTW89_FCC][20] = 34, -- [1][0][2][0][RTW89_ETSI][20] = 66, -- [1][0][2][0][RTW89_KCC][20] = 40, -- [1][0][2][0][RTW89_FCC][24] = 36, -- [1][0][2][0][RTW89_ETSI][24] = 66, -- [1][0][2][0][RTW89_KCC][24] = 40, -- [1][0][2][0][RTW89_FCC][28] = 34, -- [1][0][2][0][RTW89_ETSI][28] = 66, -- [1][0][2][0][RTW89_KCC][28] = 40, -- [1][0][2][0][RTW89_FCC][31] = 34, -- [1][0][2][0][RTW89_ETSI][31] = 66, -- [1][0][2][0][RTW89_KCC][31] = 40, -- [1][0][2][0][RTW89_FCC][35] = 34, -- [1][0][2][0][RTW89_ETSI][35] = 66, -- [1][0][2][0][RTW89_KCC][35] = 40, -- [1][0][2][0][RTW89_FCC][39] = 34, -- [1][0][2][0][RTW89_ETSI][39] = 66, -- [1][0][2][0][RTW89_KCC][39] = 40, -- [1][0][2][0][RTW89_FCC][43] = 34, -- [1][0][2][0][RTW89_ETSI][43] = 66, -- [1][0][2][0][RTW89_KCC][43] = 40, -- [1][0][2][0][RTW89_FCC][46] = 34, -- [1][0][2][0][RTW89_ETSI][46] = 127, -- [1][0][2][0][RTW89_KCC][46] = 40, -- [1][0][2][0][RTW89_FCC][50] = 34, -- [1][0][2][0][RTW89_ETSI][50] = 127, -- [1][0][2][0][RTW89_KCC][50] = 40, -- [1][0][2][0][RTW89_FCC][54] = 36, -- [1][0][2][0][RTW89_ETSI][54] = 127, -- [1][0][2][0][RTW89_KCC][54] = 40, -- [1][0][2][0][RTW89_FCC][58] = 36, -- [1][0][2][0][RTW89_ETSI][58] = 127, -- [1][0][2][0][RTW89_KCC][58] = 40, -- [1][0][2][0][RTW89_FCC][61] = 34, -- [1][0][2][0][RTW89_ETSI][61] = 127, -- [1][0][2][0][RTW89_KCC][61] = 40, -- [1][0][2][0][RTW89_FCC][65] = 34, -- [1][0][2][0][RTW89_ETSI][65] = 127, -- [1][0][2][0][RTW89_KCC][65] = 40, -- [1][0][2][0][RTW89_FCC][69] = 34, -- [1][0][2][0][RTW89_ETSI][69] = 127, -- [1][0][2][0][RTW89_KCC][69] = 40, -- [1][0][2][0][RTW89_FCC][73] = 34, -- [1][0][2][0][RTW89_ETSI][73] = 127, -- [1][0][2][0][RTW89_KCC][73] = 40, -- [1][0][2][0][RTW89_FCC][76] = 34, -- [1][0][2][0][RTW89_ETSI][76] = 127, -- [1][0][2][0][RTW89_KCC][76] = 40, -- [1][0][2][0][RTW89_FCC][80] = 34, -- [1][0][2][0][RTW89_ETSI][80] = 127, -- [1][0][2][0][RTW89_KCC][80] = 42, -- [1][0][2][0][RTW89_FCC][84] = 34, -- [1][0][2][0][RTW89_ETSI][84] = 127, -- [1][0][2][0][RTW89_KCC][84] = 42, -- [1][0][2][0][RTW89_FCC][88] = 34, -- [1][0][2][0][RTW89_ETSI][88] = 127, -- [1][0][2][0][RTW89_KCC][88] = 42, -- [1][0][2][0][RTW89_FCC][91] = 36, -- [1][0][2][0][RTW89_ETSI][91] = 127, -- [1][0][2][0][RTW89_KCC][91] = 42, -- [1][0][2][0][RTW89_FCC][95] = 34, -- [1][0][2][0][RTW89_ETSI][95] = 127, -- [1][0][2][0][RTW89_KCC][95] = 42, -- [1][0][2][0][RTW89_FCC][99] = 34, -- [1][0][2][0][RTW89_ETSI][99] = 127, -- [1][0][2][0][RTW89_KCC][99] = 42, -- [1][0][2][0][RTW89_FCC][103] = 34, -- [1][0][2][0][RTW89_ETSI][103] = 127, -- [1][0][2][0][RTW89_KCC][103] = 42, -- [1][0][2][0][RTW89_FCC][106] = 36, -- [1][0][2][0][RTW89_ETSI][106] = 127, -- [1][0][2][0][RTW89_KCC][106] = 42, -- [1][0][2][0][RTW89_FCC][110] = 127, -- [1][0][2][0][RTW89_ETSI][110] = 127, -- [1][0][2][0][RTW89_KCC][110] = 127, -- [1][0][2][0][RTW89_FCC][114] = 127, -- [1][0][2][0][RTW89_ETSI][114] = 127, -- [1][0][2][0][RTW89_KCC][114] = 127, -- [1][0][2][0][RTW89_FCC][118] = 127, -- [1][0][2][0][RTW89_ETSI][118] = 127, -- [1][0][2][0][RTW89_KCC][118] = 127, -- [1][1][2][0][RTW89_FCC][1] = 10, -- [1][1][2][0][RTW89_ETSI][1] = 54, -- [1][1][2][0][RTW89_KCC][1] = 28, -- [1][1][2][0][RTW89_FCC][5] = 10, -- [1][1][2][0][RTW89_ETSI][5] = 54, -- [1][1][2][0][RTW89_KCC][5] = 28, -- [1][1][2][0][RTW89_FCC][9] = 10, -- [1][1][2][0][RTW89_ETSI][9] = 54, -- [1][1][2][0][RTW89_KCC][9] = 28, -- [1][1][2][0][RTW89_FCC][13] = 10, -- [1][1][2][0][RTW89_ETSI][13] = 54, -- [1][1][2][0][RTW89_KCC][13] = 28, -- [1][1][2][0][RTW89_FCC][16] = 10, -- [1][1][2][0][RTW89_ETSI][16] = 54, -- [1][1][2][0][RTW89_KCC][16] = 28, -- [1][1][2][0][RTW89_FCC][20] = 10, -- [1][1][2][0][RTW89_ETSI][20] = 54, -- [1][1][2][0][RTW89_KCC][20] = 28, -- [1][1][2][0][RTW89_FCC][24] = 10, -- [1][1][2][0][RTW89_ETSI][24] = 54, -- [1][1][2][0][RTW89_KCC][24] = 28, -- [1][1][2][0][RTW89_FCC][28] = 10, -- [1][1][2][0][RTW89_ETSI][28] = 54, -- [1][1][2][0][RTW89_KCC][28] = 28, -- [1][1][2][0][RTW89_FCC][31] = 10, -- [1][1][2][0][RTW89_ETSI][31] = 54, -- [1][1][2][0][RTW89_KCC][31] = 28, -- [1][1][2][0][RTW89_FCC][35] = 10, -- [1][1][2][0][RTW89_ETSI][35] = 54, -- [1][1][2][0][RTW89_KCC][35] = 28, -- [1][1][2][0][RTW89_FCC][39] = 10, -- [1][1][2][0][RTW89_ETSI][39] = 54, -- [1][1][2][0][RTW89_KCC][39] = 28, -- [1][1][2][0][RTW89_FCC][43] = 10, -- [1][1][2][0][RTW89_ETSI][43] = 54, -- [1][1][2][0][RTW89_KCC][43] = 28, -- [1][1][2][0][RTW89_FCC][46] = 12, -- [1][1][2][0][RTW89_ETSI][46] = 127, -- [1][1][2][0][RTW89_KCC][46] = 28, -- [1][1][2][0][RTW89_FCC][50] = 12, -- [1][1][2][0][RTW89_ETSI][50] = 127, -- [1][1][2][0][RTW89_KCC][50] = 28, -- [1][1][2][0][RTW89_FCC][54] = 10, -- [1][1][2][0][RTW89_ETSI][54] = 127, -- [1][1][2][0][RTW89_KCC][54] = 28, -- [1][1][2][0][RTW89_FCC][58] = 10, -- [1][1][2][0][RTW89_ETSI][58] = 127, -- [1][1][2][0][RTW89_KCC][58] = 28, -- [1][1][2][0][RTW89_FCC][61] = 10, -- [1][1][2][0][RTW89_ETSI][61] = 127, -- [1][1][2][0][RTW89_KCC][61] = 28, -- [1][1][2][0][RTW89_FCC][65] = 10, -- [1][1][2][0][RTW89_ETSI][65] = 127, -- [1][1][2][0][RTW89_KCC][65] = 28, -- [1][1][2][0][RTW89_FCC][69] = 10, -- [1][1][2][0][RTW89_ETSI][69] = 127, -- [1][1][2][0][RTW89_KCC][69] = 28, -- [1][1][2][0][RTW89_FCC][73] = 10, -- [1][1][2][0][RTW89_ETSI][73] = 127, -- [1][1][2][0][RTW89_KCC][73] = 28, -- [1][1][2][0][RTW89_FCC][76] = 10, -- [1][1][2][0][RTW89_ETSI][76] = 127, -- [1][1][2][0][RTW89_KCC][76] = 28, -- [1][1][2][0][RTW89_FCC][80] = 10, -- [1][1][2][0][RTW89_ETSI][80] = 127, -- [1][1][2][0][RTW89_KCC][80] = 32, -- [1][1][2][0][RTW89_FCC][84] = 10, -- [1][1][2][0][RTW89_ETSI][84] = 127, -- [1][1][2][0][RTW89_KCC][84] = 32, -- [1][1][2][0][RTW89_FCC][88] = 10, -- [1][1][2][0][RTW89_ETSI][88] = 127, -- [1][1][2][0][RTW89_KCC][88] = 32, -- [1][1][2][0][RTW89_FCC][91] = 12, -- [1][1][2][0][RTW89_ETSI][91] = 127, -- [1][1][2][0][RTW89_KCC][91] = 32, -- [1][1][2][0][RTW89_FCC][95] = 10, -- [1][1][2][0][RTW89_ETSI][95] = 127, -- [1][1][2][0][RTW89_KCC][95] = 32, -- [1][1][2][0][RTW89_FCC][99] = 10, -- [1][1][2][0][RTW89_ETSI][99] = 127, -- [1][1][2][0][RTW89_KCC][99] = 32, -- [1][1][2][0][RTW89_FCC][103] = 10, -- [1][1][2][0][RTW89_ETSI][103] = 127, -- [1][1][2][0][RTW89_KCC][103] = 32, -- [1][1][2][0][RTW89_FCC][106] = 12, -- [1][1][2][0][RTW89_ETSI][106] = 127, -- [1][1][2][0][RTW89_KCC][106] = 32, -- [1][1][2][0][RTW89_FCC][110] = 127, -- [1][1][2][0][RTW89_ETSI][110] = 127, -- [1][1][2][0][RTW89_KCC][110] = 127, -- [1][1][2][0][RTW89_FCC][114] = 127, -- [1][1][2][0][RTW89_ETSI][114] = 127, -- [1][1][2][0][RTW89_KCC][114] = 127, -- [1][1][2][0][RTW89_FCC][118] = 127, -- [1][1][2][0][RTW89_ETSI][118] = 127, -- [1][1][2][0][RTW89_KCC][118] = 127, -- [1][1][2][1][RTW89_FCC][1] = 10, -- [1][1][2][1][RTW89_ETSI][1] = 42, -- [1][1][2][1][RTW89_KCC][1] = 28, -- [1][1][2][1][RTW89_FCC][5] = 10, -- [1][1][2][1][RTW89_ETSI][5] = 42, -- [1][1][2][1][RTW89_KCC][5] = 28, -- [1][1][2][1][RTW89_FCC][9] = 10, -- [1][1][2][1][RTW89_ETSI][9] = 42, -- [1][1][2][1][RTW89_KCC][9] = 28, -- [1][1][2][1][RTW89_FCC][13] = 10, -- [1][1][2][1][RTW89_ETSI][13] = 42, -- [1][1][2][1][RTW89_KCC][13] = 28, -- [1][1][2][1][RTW89_FCC][16] = 10, -- [1][1][2][1][RTW89_ETSI][16] = 42, -- [1][1][2][1][RTW89_KCC][16] = 28, -- [1][1][2][1][RTW89_FCC][20] = 10, -- [1][1][2][1][RTW89_ETSI][20] = 42, -- [1][1][2][1][RTW89_KCC][20] = 28, -- [1][1][2][1][RTW89_FCC][24] = 10, -- [1][1][2][1][RTW89_ETSI][24] = 42, -- [1][1][2][1][RTW89_KCC][24] = 28, -- [1][1][2][1][RTW89_FCC][28] = 10, -- [1][1][2][1][RTW89_ETSI][28] = 42, -- [1][1][2][1][RTW89_KCC][28] = 28, -- [1][1][2][1][RTW89_FCC][31] = 10, -- [1][1][2][1][RTW89_ETSI][31] = 42, -- [1][1][2][1][RTW89_KCC][31] = 28, -- [1][1][2][1][RTW89_FCC][35] = 10, -- [1][1][2][1][RTW89_ETSI][35] = 42, -- [1][1][2][1][RTW89_KCC][35] = 28, -- [1][1][2][1][RTW89_FCC][39] = 10, -- [1][1][2][1][RTW89_ETSI][39] = 42, -- [1][1][2][1][RTW89_KCC][39] = 28, -- [1][1][2][1][RTW89_FCC][43] = 10, -- [1][1][2][1][RTW89_ETSI][43] = 42, -- [1][1][2][1][RTW89_KCC][43] = 28, -- [1][1][2][1][RTW89_FCC][46] = 12, -- [1][1][2][1][RTW89_ETSI][46] = 127, -- [1][1][2][1][RTW89_KCC][46] = 28, -- [1][1][2][1][RTW89_FCC][50] = 12, -- [1][1][2][1][RTW89_ETSI][50] = 127, -- [1][1][2][1][RTW89_KCC][50] = 28, -- [1][1][2][1][RTW89_FCC][54] = 10, -- [1][1][2][1][RTW89_ETSI][54] = 127, -- [1][1][2][1][RTW89_KCC][54] = 28, -- [1][1][2][1][RTW89_FCC][58] = 10, -- [1][1][2][1][RTW89_ETSI][58] = 127, -- [1][1][2][1][RTW89_KCC][58] = 28, -- [1][1][2][1][RTW89_FCC][61] = 10, -- [1][1][2][1][RTW89_ETSI][61] = 127, -- [1][1][2][1][RTW89_KCC][61] = 28, -- [1][1][2][1][RTW89_FCC][65] = 10, -- [1][1][2][1][RTW89_ETSI][65] = 127, -- [1][1][2][1][RTW89_KCC][65] = 28, -- [1][1][2][1][RTW89_FCC][69] = 10, -- [1][1][2][1][RTW89_ETSI][69] = 127, -- [1][1][2][1][RTW89_KCC][69] = 28, -- [1][1][2][1][RTW89_FCC][73] = 10, -- [1][1][2][1][RTW89_ETSI][73] = 127, -- [1][1][2][1][RTW89_KCC][73] = 28, -- [1][1][2][1][RTW89_FCC][76] = 10, -- [1][1][2][1][RTW89_ETSI][76] = 127, -- [1][1][2][1][RTW89_KCC][76] = 28, -- [1][1][2][1][RTW89_FCC][80] = 10, -- [1][1][2][1][RTW89_ETSI][80] = 127, -- [1][1][2][1][RTW89_KCC][80] = 32, -- [1][1][2][1][RTW89_FCC][84] = 10, -- [1][1][2][1][RTW89_ETSI][84] = 127, -- [1][1][2][1][RTW89_KCC][84] = 32, -- [1][1][2][1][RTW89_FCC][88] = 10, -- [1][1][2][1][RTW89_ETSI][88] = 127, -- [1][1][2][1][RTW89_KCC][88] = 32, -- [1][1][2][1][RTW89_FCC][91] = 12, -- [1][1][2][1][RTW89_ETSI][91] = 127, -- [1][1][2][1][RTW89_KCC][91] = 32, -- [1][1][2][1][RTW89_FCC][95] = 10, -- [1][1][2][1][RTW89_ETSI][95] = 127, -- [1][1][2][1][RTW89_KCC][95] = 32, -- [1][1][2][1][RTW89_FCC][99] = 10, -- [1][1][2][1][RTW89_ETSI][99] = 127, -- [1][1][2][1][RTW89_KCC][99] = 32, -- [1][1][2][1][RTW89_FCC][103] = 10, -- [1][1][2][1][RTW89_ETSI][103] = 127, -- [1][1][2][1][RTW89_KCC][103] = 32, -- [1][1][2][1][RTW89_FCC][106] = 12, -- [1][1][2][1][RTW89_ETSI][106] = 127, -- [1][1][2][1][RTW89_KCC][106] = 32, -- [1][1][2][1][RTW89_FCC][110] = 127, -- [1][1][2][1][RTW89_ETSI][110] = 127, -- [1][1][2][1][RTW89_KCC][110] = 127, -- [1][1][2][1][RTW89_FCC][114] = 127, -- [1][1][2][1][RTW89_ETSI][114] = 127, -- [1][1][2][1][RTW89_KCC][114] = 127, -- [1][1][2][1][RTW89_FCC][118] = 127, -- [1][1][2][1][RTW89_ETSI][118] = 127, -- [1][1][2][1][RTW89_KCC][118] = 127, -- [2][0][2][0][RTW89_FCC][3] = 46, -- [2][0][2][0][RTW89_ETSI][3] = 48, -- [2][0][2][0][RTW89_KCC][3] = 50, -- [2][0][2][0][RTW89_FCC][11] = 46, -- [2][0][2][0][RTW89_ETSI][11] = 48, -- [2][0][2][0][RTW89_KCC][11] = 50, -- [2][0][2][0][RTW89_FCC][18] = 46, -- [2][0][2][0][RTW89_ETSI][18] = 48, -- [2][0][2][0][RTW89_KCC][18] = 50, -- [2][0][2][0][RTW89_FCC][26] = 46, -- [2][0][2][0][RTW89_ETSI][26] = 48, -- [2][0][2][0][RTW89_KCC][26] = 50, -- [2][0][2][0][RTW89_FCC][33] = 46, -- [2][0][2][0][RTW89_ETSI][33] = 48, -- [2][0][2][0][RTW89_KCC][33] = 50, -- [2][0][2][0][RTW89_FCC][41] = 46, -- [2][0][2][0][RTW89_ETSI][41] = 48, -- [2][0][2][0][RTW89_KCC][41] = 50, -- [2][0][2][0][RTW89_FCC][48] = 46, -- [2][0][2][0][RTW89_ETSI][48] = 127, -- [2][0][2][0][RTW89_KCC][48] = 48, -- [2][0][2][0][RTW89_FCC][56] = 46, -- [2][0][2][0][RTW89_ETSI][56] = 127, -- [2][0][2][0][RTW89_KCC][56] = 48, -- [2][0][2][0][RTW89_FCC][63] = 46, -- [2][0][2][0][RTW89_ETSI][63] = 127, -- [2][0][2][0][RTW89_KCC][63] = 48, -- [2][0][2][0][RTW89_FCC][71] = 46, -- [2][0][2][0][RTW89_ETSI][71] = 127, -- [2][0][2][0][RTW89_KCC][71] = 48, -- [2][0][2][0][RTW89_FCC][78] = 46, -- [2][0][2][0][RTW89_ETSI][78] = 127, -- [2][0][2][0][RTW89_KCC][78] = 52, -- [2][0][2][0][RTW89_FCC][86] = 46, -- [2][0][2][0][RTW89_ETSI][86] = 127, -- [2][0][2][0][RTW89_KCC][86] = 52, -- [2][0][2][0][RTW89_FCC][93] = 46, -- [2][0][2][0][RTW89_ETSI][93] = 127, -- [2][0][2][0][RTW89_KCC][93] = 50, -- [2][0][2][0][RTW89_FCC][101] = 44, -- [2][0][2][0][RTW89_ETSI][101] = 127, -- [2][0][2][0][RTW89_KCC][101] = 50, -- [2][0][2][0][RTW89_FCC][108] = 127, -- [2][0][2][0][RTW89_ETSI][108] = 127, -- [2][0][2][0][RTW89_KCC][108] = 127, -- [2][0][2][0][RTW89_FCC][116] = 127, -- [2][0][2][0][RTW89_ETSI][116] = 127, -- [2][0][2][0][RTW89_KCC][116] = 127, -- [2][1][2][0][RTW89_FCC][3] = 22, -- [2][1][2][0][RTW89_ETSI][3] = 48, -- [2][1][2][0][RTW89_KCC][3] = 38, -- [2][1][2][0][RTW89_FCC][11] = 20, -- [2][1][2][0][RTW89_ETSI][11] = 48, -- [2][1][2][0][RTW89_KCC][11] = 38, -- [2][1][2][0][RTW89_FCC][18] = 20, -- [2][1][2][0][RTW89_ETSI][18] = 48, -- [2][1][2][0][RTW89_KCC][18] = 38, -- [2][1][2][0][RTW89_FCC][26] = 20, -- [2][1][2][0][RTW89_ETSI][26] = 48, -- [2][1][2][0][RTW89_KCC][26] = 38, -- [2][1][2][0][RTW89_FCC][33] = 20, -- [2][1][2][0][RTW89_ETSI][33] = 48, -- [2][1][2][0][RTW89_KCC][33] = 38, -- [2][1][2][0][RTW89_FCC][41] = 22, -- [2][1][2][0][RTW89_ETSI][41] = 48, -- [2][1][2][0][RTW89_KCC][41] = 38, -- [2][1][2][0][RTW89_FCC][48] = 22, -- [2][1][2][0][RTW89_ETSI][48] = 127, -- [2][1][2][0][RTW89_KCC][48] = 38, -- [2][1][2][0][RTW89_FCC][56] = 20, -- [2][1][2][0][RTW89_ETSI][56] = 127, -- [2][1][2][0][RTW89_KCC][56] = 38, -- [2][1][2][0][RTW89_FCC][63] = 22, -- [2][1][2][0][RTW89_ETSI][63] = 127, -- [2][1][2][0][RTW89_KCC][63] = 38, -- [2][1][2][0][RTW89_FCC][71] = 20, -- [2][1][2][0][RTW89_ETSI][71] = 127, -- [2][1][2][0][RTW89_KCC][71] = 38, -- [2][1][2][0][RTW89_FCC][78] = 20, -- [2][1][2][0][RTW89_ETSI][78] = 127, -- [2][1][2][0][RTW89_KCC][78] = 38, -- [2][1][2][0][RTW89_FCC][86] = 20, -- [2][1][2][0][RTW89_ETSI][86] = 127, -- [2][1][2][0][RTW89_KCC][86] = 38, -- [2][1][2][0][RTW89_FCC][93] = 22, -- [2][1][2][0][RTW89_ETSI][93] = 127, -- [2][1][2][0][RTW89_KCC][93] = 38, -- [2][1][2][0][RTW89_FCC][101] = 22, -- [2][1][2][0][RTW89_ETSI][101] = 127, -- [2][1][2][0][RTW89_KCC][101] = 38, -- [2][1][2][0][RTW89_FCC][108] = 127, -- [2][1][2][0][RTW89_ETSI][108] = 127, -- [2][1][2][0][RTW89_KCC][108] = 127, -- [2][1][2][0][RTW89_FCC][116] = 127, -- [2][1][2][0][RTW89_ETSI][116] = 127, -- [2][1][2][0][RTW89_KCC][116] = 127, -- [2][1][2][1][RTW89_FCC][3] = 22, -- [2][1][2][1][RTW89_ETSI][3] = 42, -- [2][1][2][1][RTW89_KCC][3] = 38, -- [2][1][2][1][RTW89_FCC][11] = 20, -- [2][1][2][1][RTW89_ETSI][11] = 42, -- [2][1][2][1][RTW89_KCC][11] = 38, -- [2][1][2][1][RTW89_FCC][18] = 20, -- [2][1][2][1][RTW89_ETSI][18] = 42, -- [2][1][2][1][RTW89_KCC][18] = 38, -- [2][1][2][1][RTW89_FCC][26] = 20, -- [2][1][2][1][RTW89_ETSI][26] = 42, -- [2][1][2][1][RTW89_KCC][26] = 38, -- [2][1][2][1][RTW89_FCC][33] = 20, -- [2][1][2][1][RTW89_ETSI][33] = 42, -- [2][1][2][1][RTW89_KCC][33] = 38, -- [2][1][2][1][RTW89_FCC][41] = 22, -- [2][1][2][1][RTW89_ETSI][41] = 42, -- [2][1][2][1][RTW89_KCC][41] = 38, -- [2][1][2][1][RTW89_FCC][48] = 22, -- [2][1][2][1][RTW89_ETSI][48] = 127, -- [2][1][2][1][RTW89_KCC][48] = 38, -- [2][1][2][1][RTW89_FCC][56] = 20, -- [2][1][2][1][RTW89_ETSI][56] = 127, -- [2][1][2][1][RTW89_KCC][56] = 38, -- [2][1][2][1][RTW89_FCC][63] = 22, -- [2][1][2][1][RTW89_ETSI][63] = 127, -- [2][1][2][1][RTW89_KCC][63] = 38, -- [2][1][2][1][RTW89_FCC][71] = 20, -- [2][1][2][1][RTW89_ETSI][71] = 127, -- [2][1][2][1][RTW89_KCC][71] = 38, -- [2][1][2][1][RTW89_FCC][78] = 20, -- [2][1][2][1][RTW89_ETSI][78] = 127, -- [2][1][2][1][RTW89_KCC][78] = 38, -- [2][1][2][1][RTW89_FCC][86] = 20, -- [2][1][2][1][RTW89_ETSI][86] = 127, -- [2][1][2][1][RTW89_KCC][86] = 38, -- [2][1][2][1][RTW89_FCC][93] = 22, -- [2][1][2][1][RTW89_ETSI][93] = 127, -- [2][1][2][1][RTW89_KCC][93] = 38, -- [2][1][2][1][RTW89_FCC][101] = 22, -- [2][1][2][1][RTW89_ETSI][101] = 127, -- [2][1][2][1][RTW89_KCC][101] = 38, -- [2][1][2][1][RTW89_FCC][108] = 127, -- [2][1][2][1][RTW89_ETSI][108] = 127, -- [2][1][2][1][RTW89_KCC][108] = 127, -- [2][1][2][1][RTW89_FCC][116] = 127, -- [2][1][2][1][RTW89_ETSI][116] = 127, -- [2][1][2][1][RTW89_KCC][116] = 127, -- [3][0][2][0][RTW89_FCC][7] = 52, -- [3][0][2][0][RTW89_ETSI][7] = 38, -- [3][0][2][0][RTW89_KCC][7] = 42, -- [3][0][2][0][RTW89_FCC][22] = 52, -- [3][0][2][0][RTW89_ETSI][22] = 38, -- [3][0][2][0][RTW89_KCC][22] = 42, -- [3][0][2][0][RTW89_FCC][37] = 52, -- [3][0][2][0][RTW89_ETSI][37] = 38, -- [3][0][2][0][RTW89_KCC][37] = 42, -- [3][0][2][0][RTW89_FCC][52] = 54, -- [3][0][2][0][RTW89_ETSI][52] = 127, -- [3][0][2][0][RTW89_KCC][52] = 56, -- [3][0][2][0][RTW89_FCC][67] = 54, -- [3][0][2][0][RTW89_ETSI][67] = 127, -- [3][0][2][0][RTW89_KCC][67] = 54, -- [3][0][2][0][RTW89_FCC][82] = 54, -- [3][0][2][0][RTW89_ETSI][82] = 127, -- [3][0][2][0][RTW89_KCC][82] = 26, -- [3][0][2][0][RTW89_FCC][97] = 40, -- [3][0][2][0][RTW89_ETSI][97] = 127, -- [3][0][2][0][RTW89_KCC][97] = 26, -- [3][0][2][0][RTW89_FCC][112] = 127, -- [3][0][2][0][RTW89_ETSI][112] = 127, -- [3][0][2][0][RTW89_KCC][112] = 127, -- [3][1][2][0][RTW89_FCC][7] = 32, -- [3][1][2][0][RTW89_ETSI][7] = 38, -- [3][1][2][0][RTW89_KCC][7] = 40, -- [3][1][2][0][RTW89_FCC][22] = 30, -- [3][1][2][0][RTW89_ETSI][22] = 38, -- [3][1][2][0][RTW89_KCC][22] = 40, -- [3][1][2][0][RTW89_FCC][37] = 30, -- [3][1][2][0][RTW89_ETSI][37] = 38, -- [3][1][2][0][RTW89_KCC][37] = 40, -- [3][1][2][0][RTW89_FCC][52] = 30, -- [3][1][2][0][RTW89_ETSI][52] = 127, -- [3][1][2][0][RTW89_KCC][52] = 48, -- [3][1][2][0][RTW89_FCC][67] = 32, -- [3][1][2][0][RTW89_ETSI][67] = 127, -- [3][1][2][0][RTW89_KCC][67] = 48, -- [3][1][2][0][RTW89_FCC][82] = 32, -- [3][1][2][0][RTW89_ETSI][82] = 127, -- [3][1][2][0][RTW89_KCC][82] = 24, -- [3][1][2][0][RTW89_FCC][97] = 14, -- [3][1][2][0][RTW89_ETSI][97] = 127, -- [3][1][2][0][RTW89_KCC][97] = 24, -- [3][1][2][0][RTW89_FCC][112] = 127, -- [3][1][2][0][RTW89_ETSI][112] = 127, -- [3][1][2][0][RTW89_KCC][112] = 127, -- [3][1][2][1][RTW89_FCC][7] = 32, -- [3][1][2][1][RTW89_ETSI][7] = 38, -- [3][1][2][1][RTW89_KCC][7] = 40, -- [3][1][2][1][RTW89_FCC][22] = 30, -- [3][1][2][1][RTW89_ETSI][22] = 38, -- [3][1][2][1][RTW89_KCC][22] = 40, -- [3][1][2][1][RTW89_FCC][37] = 30, -- [3][1][2][1][RTW89_ETSI][37] = 38, -- [3][1][2][1][RTW89_KCC][37] = 40, -- [3][1][2][1][RTW89_FCC][52] = 30, -- [3][1][2][1][RTW89_ETSI][52] = 127, -- [3][1][2][1][RTW89_KCC][52] = 48, -- [3][1][2][1][RTW89_FCC][67] = 32, -- [3][1][2][1][RTW89_ETSI][67] = 127, -- [3][1][2][1][RTW89_KCC][67] = 48, -- [3][1][2][1][RTW89_FCC][82] = 32, -- [3][1][2][1][RTW89_ETSI][82] = 127, -- [3][1][2][1][RTW89_KCC][82] = 24, -- [3][1][2][1][RTW89_FCC][97] = 14, -- [3][1][2][1][RTW89_ETSI][97] = 127, -- [3][1][2][1][RTW89_KCC][97] = 24, -- [3][1][2][1][RTW89_FCC][112] = 127, -- [3][1][2][1][RTW89_ETSI][112] = 127, -- [3][1][2][1][RTW89_KCC][112] = 127, -+ [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] -+ [RTW89_6G_CH_NUM] = { -+ [0][0][1][0][RTW89_WW][0][0] = 24, -+ [0][0][1][0][RTW89_WW][1][0] = 24, -+ [0][0][1][0][RTW89_WW][2][0] = 56, -+ [0][0][1][0][RTW89_WW][0][2] = 22, -+ [0][0][1][0][RTW89_WW][1][2] = 22, -+ [0][0][1][0][RTW89_WW][2][2] = 56, -+ [0][0][1][0][RTW89_WW][0][4] = 22, -+ [0][0][1][0][RTW89_WW][1][4] = 22, -+ [0][0][1][0][RTW89_WW][2][4] = 56, -+ [0][0][1][0][RTW89_WW][0][6] = 22, -+ [0][0][1][0][RTW89_WW][1][6] = 22, -+ [0][0][1][0][RTW89_WW][2][6] = 56, -+ [0][0][1][0][RTW89_WW][0][8] = 22, -+ [0][0][1][0][RTW89_WW][1][8] = 22, -+ [0][0][1][0][RTW89_WW][2][8] = 56, -+ [0][0][1][0][RTW89_WW][0][10] = 22, -+ [0][0][1][0][RTW89_WW][1][10] = 22, -+ [0][0][1][0][RTW89_WW][2][10] = 56, -+ [0][0][1][0][RTW89_WW][0][12] = 22, -+ [0][0][1][0][RTW89_WW][1][12] = 22, -+ [0][0][1][0][RTW89_WW][2][12] = 56, -+ [0][0][1][0][RTW89_WW][0][14] = 22, -+ [0][0][1][0][RTW89_WW][1][14] = 22, -+ [0][0][1][0][RTW89_WW][2][14] = 56, -+ [0][0][1][0][RTW89_WW][0][15] = 22, -+ [0][0][1][0][RTW89_WW][1][15] = 22, -+ [0][0][1][0][RTW89_WW][2][15] = 56, -+ [0][0][1][0][RTW89_WW][0][17] = 22, -+ [0][0][1][0][RTW89_WW][1][17] = 22, -+ [0][0][1][0][RTW89_WW][2][17] = 56, -+ [0][0][1][0][RTW89_WW][0][19] = 22, -+ [0][0][1][0][RTW89_WW][1][19] = 22, -+ [0][0][1][0][RTW89_WW][2][19] = 56, -+ [0][0][1][0][RTW89_WW][0][21] = 22, -+ [0][0][1][0][RTW89_WW][1][21] = 22, -+ [0][0][1][0][RTW89_WW][2][21] = 56, -+ [0][0][1][0][RTW89_WW][0][23] = 22, -+ [0][0][1][0][RTW89_WW][1][23] = 22, -+ [0][0][1][0][RTW89_WW][2][23] = 70, -+ [0][0][1][0][RTW89_WW][0][25] = 22, -+ [0][0][1][0][RTW89_WW][1][25] = 22, -+ [0][0][1][0][RTW89_WW][2][25] = 70, -+ [0][0][1][0][RTW89_WW][0][27] = 22, -+ [0][0][1][0][RTW89_WW][1][27] = 22, -+ [0][0][1][0][RTW89_WW][2][27] = 70, -+ [0][0][1][0][RTW89_WW][0][29] = 22, -+ [0][0][1][0][RTW89_WW][1][29] = 22, -+ [0][0][1][0][RTW89_WW][2][29] = 70, -+ [0][0][1][0][RTW89_WW][0][30] = 22, -+ [0][0][1][0][RTW89_WW][1][30] = 22, -+ [0][0][1][0][RTW89_WW][2][30] = 70, -+ [0][0][1][0][RTW89_WW][0][32] = 22, -+ [0][0][1][0][RTW89_WW][1][32] = 22, -+ [0][0][1][0][RTW89_WW][2][32] = 70, -+ [0][0][1][0][RTW89_WW][0][34] = 22, -+ [0][0][1][0][RTW89_WW][1][34] = 22, -+ [0][0][1][0][RTW89_WW][2][34] = 70, -+ [0][0][1][0][RTW89_WW][0][36] = 22, -+ [0][0][1][0][RTW89_WW][1][36] = 22, -+ [0][0][1][0][RTW89_WW][2][36] = 70, -+ [0][0][1][0][RTW89_WW][0][38] = 22, -+ [0][0][1][0][RTW89_WW][1][38] = 22, -+ [0][0][1][0][RTW89_WW][2][38] = 70, -+ [0][0][1][0][RTW89_WW][0][40] = 22, -+ [0][0][1][0][RTW89_WW][1][40] = 22, -+ [0][0][1][0][RTW89_WW][2][40] = 70, -+ [0][0][1][0][RTW89_WW][0][42] = 22, -+ [0][0][1][0][RTW89_WW][1][42] = 22, -+ [0][0][1][0][RTW89_WW][2][42] = 70, -+ [0][0][1][0][RTW89_WW][0][44] = 22, -+ [0][0][1][0][RTW89_WW][1][44] = 22, -+ [0][0][1][0][RTW89_WW][2][44] = 70, -+ [0][0][1][0][RTW89_WW][0][45] = 22, -+ [0][0][1][0][RTW89_WW][1][45] = 22, -+ [0][0][1][0][RTW89_WW][2][45] = 0, -+ [0][0][1][0][RTW89_WW][0][47] = 22, -+ [0][0][1][0][RTW89_WW][1][47] = 22, -+ [0][0][1][0][RTW89_WW][2][47] = 0, -+ [0][0][1][0][RTW89_WW][0][49] = 24, -+ [0][0][1][0][RTW89_WW][1][49] = 24, -+ [0][0][1][0][RTW89_WW][2][49] = 0, -+ [0][0][1][0][RTW89_WW][0][51] = 22, -+ [0][0][1][0][RTW89_WW][1][51] = 22, -+ [0][0][1][0][RTW89_WW][2][51] = 0, -+ [0][0][1][0][RTW89_WW][0][53] = 22, -+ [0][0][1][0][RTW89_WW][1][53] = 22, -+ [0][0][1][0][RTW89_WW][2][53] = 0, -+ [0][0][1][0][RTW89_WW][0][55] = 22, -+ [0][0][1][0][RTW89_WW][1][55] = 22, -+ [0][0][1][0][RTW89_WW][2][55] = 68, -+ [0][0][1][0][RTW89_WW][0][57] = 22, -+ [0][0][1][0][RTW89_WW][1][57] = 22, -+ [0][0][1][0][RTW89_WW][2][57] = 68, -+ [0][0][1][0][RTW89_WW][0][59] = 22, -+ [0][0][1][0][RTW89_WW][1][59] = 22, -+ [0][0][1][0][RTW89_WW][2][59] = 68, -+ [0][0][1][0][RTW89_WW][0][60] = 22, -+ [0][0][1][0][RTW89_WW][1][60] = 22, -+ [0][0][1][0][RTW89_WW][2][60] = 68, -+ [0][0][1][0][RTW89_WW][0][62] = 22, -+ [0][0][1][0][RTW89_WW][1][62] = 22, -+ [0][0][1][0][RTW89_WW][2][62] = 68, -+ [0][0][1][0][RTW89_WW][0][64] = 22, -+ [0][0][1][0][RTW89_WW][1][64] = 22, -+ [0][0][1][0][RTW89_WW][2][64] = 68, -+ [0][0][1][0][RTW89_WW][0][66] = 22, -+ [0][0][1][0][RTW89_WW][1][66] = 22, -+ [0][0][1][0][RTW89_WW][2][66] = 68, -+ [0][0][1][0][RTW89_WW][0][68] = 22, -+ [0][0][1][0][RTW89_WW][1][68] = 22, -+ [0][0][1][0][RTW89_WW][2][68] = 68, -+ [0][0][1][0][RTW89_WW][0][70] = 24, -+ [0][0][1][0][RTW89_WW][1][70] = 24, -+ [0][0][1][0][RTW89_WW][2][70] = 68, -+ [0][0][1][0][RTW89_WW][0][72] = 22, -+ [0][0][1][0][RTW89_WW][1][72] = 22, -+ [0][0][1][0][RTW89_WW][2][72] = 68, -+ [0][0][1][0][RTW89_WW][0][74] = 22, -+ [0][0][1][0][RTW89_WW][1][74] = 22, -+ [0][0][1][0][RTW89_WW][2][74] = 68, -+ [0][0][1][0][RTW89_WW][0][75] = 22, -+ [0][0][1][0][RTW89_WW][1][75] = 22, -+ [0][0][1][0][RTW89_WW][2][75] = 68, -+ [0][0][1][0][RTW89_WW][0][77] = 22, -+ [0][0][1][0][RTW89_WW][1][77] = 22, -+ [0][0][1][0][RTW89_WW][2][77] = 68, -+ [0][0][1][0][RTW89_WW][0][79] = 22, -+ [0][0][1][0][RTW89_WW][1][79] = 22, -+ [0][0][1][0][RTW89_WW][2][79] = 68, -+ [0][0][1][0][RTW89_WW][0][81] = 22, -+ [0][0][1][0][RTW89_WW][1][81] = 22, -+ [0][0][1][0][RTW89_WW][2][81] = 68, -+ [0][0][1][0][RTW89_WW][0][83] = 22, -+ [0][0][1][0][RTW89_WW][1][83] = 22, -+ [0][0][1][0][RTW89_WW][2][83] = 68, -+ [0][0][1][0][RTW89_WW][0][85] = 22, -+ [0][0][1][0][RTW89_WW][1][85] = 22, -+ [0][0][1][0][RTW89_WW][2][85] = 68, -+ [0][0][1][0][RTW89_WW][0][87] = 22, -+ [0][0][1][0][RTW89_WW][1][87] = 22, -+ [0][0][1][0][RTW89_WW][2][87] = 0, -+ [0][0][1][0][RTW89_WW][0][89] = 22, -+ [0][0][1][0][RTW89_WW][1][89] = 22, -+ [0][0][1][0][RTW89_WW][2][89] = 0, -+ [0][0][1][0][RTW89_WW][0][90] = 22, -+ [0][0][1][0][RTW89_WW][1][90] = 22, -+ [0][0][1][0][RTW89_WW][2][90] = 0, -+ [0][0][1][0][RTW89_WW][0][92] = 22, -+ [0][0][1][0][RTW89_WW][1][92] = 22, -+ [0][0][1][0][RTW89_WW][2][92] = 0, -+ [0][0][1][0][RTW89_WW][0][94] = 22, -+ [0][0][1][0][RTW89_WW][1][94] = 22, -+ [0][0][1][0][RTW89_WW][2][94] = 0, -+ [0][0][1][0][RTW89_WW][0][96] = 22, -+ [0][0][1][0][RTW89_WW][1][96] = 22, -+ [0][0][1][0][RTW89_WW][2][96] = 0, -+ [0][0][1][0][RTW89_WW][0][98] = 22, -+ [0][0][1][0][RTW89_WW][1][98] = 22, -+ [0][0][1][0][RTW89_WW][2][98] = 0, -+ [0][0][1][0][RTW89_WW][0][100] = 22, -+ [0][0][1][0][RTW89_WW][1][100] = 22, -+ [0][0][1][0][RTW89_WW][2][100] = 0, -+ [0][0][1][0][RTW89_WW][0][102] = 22, -+ [0][0][1][0][RTW89_WW][1][102] = 22, -+ [0][0][1][0][RTW89_WW][2][102] = 0, -+ [0][0][1][0][RTW89_WW][0][104] = 22, -+ [0][0][1][0][RTW89_WW][1][104] = 22, -+ [0][0][1][0][RTW89_WW][2][104] = 0, -+ [0][0][1][0][RTW89_WW][0][105] = 22, -+ [0][0][1][0][RTW89_WW][1][105] = 22, -+ [0][0][1][0][RTW89_WW][2][105] = 0, -+ [0][0][1][0][RTW89_WW][0][107] = 24, -+ [0][0][1][0][RTW89_WW][1][107] = 24, -+ [0][0][1][0][RTW89_WW][2][107] = 0, -+ [0][0][1][0][RTW89_WW][0][109] = 24, -+ [0][0][1][0][RTW89_WW][1][109] = 24, -+ [0][0][1][0][RTW89_WW][2][109] = 0, -+ [0][0][1][0][RTW89_WW][0][111] = 0, -+ [0][0][1][0][RTW89_WW][1][111] = 0, -+ [0][0][1][0][RTW89_WW][2][111] = 0, -+ [0][0][1][0][RTW89_WW][0][113] = 0, -+ [0][0][1][0][RTW89_WW][1][113] = 0, -+ [0][0][1][0][RTW89_WW][2][113] = 0, -+ [0][0][1][0][RTW89_WW][0][115] = 0, -+ [0][0][1][0][RTW89_WW][1][115] = 0, -+ [0][0][1][0][RTW89_WW][2][115] = 0, -+ [0][0][1][0][RTW89_WW][0][117] = 0, -+ [0][0][1][0][RTW89_WW][1][117] = 0, -+ [0][0][1][0][RTW89_WW][2][117] = 0, -+ [0][0][1][0][RTW89_WW][0][119] = 0, -+ [0][0][1][0][RTW89_WW][1][119] = 0, -+ [0][0][1][0][RTW89_WW][2][119] = 0, -+ [0][1][1][0][RTW89_WW][0][0] = -2, -+ [0][1][1][0][RTW89_WW][1][0] = -2, -+ [0][1][1][0][RTW89_WW][2][0] = 54, -+ [0][1][1][0][RTW89_WW][0][2] = -4, -+ [0][1][1][0][RTW89_WW][1][2] = -4, -+ [0][1][1][0][RTW89_WW][2][2] = 54, -+ [0][1][1][0][RTW89_WW][0][4] = -4, -+ [0][1][1][0][RTW89_WW][1][4] = -4, -+ [0][1][1][0][RTW89_WW][2][4] = 54, -+ [0][1][1][0][RTW89_WW][0][6] = -4, -+ [0][1][1][0][RTW89_WW][1][6] = -4, -+ [0][1][1][0][RTW89_WW][2][6] = 54, -+ [0][1][1][0][RTW89_WW][0][8] = -4, -+ [0][1][1][0][RTW89_WW][1][8] = -4, -+ [0][1][1][0][RTW89_WW][2][8] = 54, -+ [0][1][1][0][RTW89_WW][0][10] = -4, -+ [0][1][1][0][RTW89_WW][1][10] = -4, -+ [0][1][1][0][RTW89_WW][2][10] = 54, -+ [0][1][1][0][RTW89_WW][0][12] = -4, -+ [0][1][1][0][RTW89_WW][1][12] = -4, -+ [0][1][1][0][RTW89_WW][2][12] = 54, -+ [0][1][1][0][RTW89_WW][0][14] = -4, -+ [0][1][1][0][RTW89_WW][1][14] = -4, -+ [0][1][1][0][RTW89_WW][2][14] = 54, -+ [0][1][1][0][RTW89_WW][0][15] = -4, -+ [0][1][1][0][RTW89_WW][1][15] = -4, -+ [0][1][1][0][RTW89_WW][2][15] = 54, -+ [0][1][1][0][RTW89_WW][0][17] = -4, -+ [0][1][1][0][RTW89_WW][1][17] = -4, -+ [0][1][1][0][RTW89_WW][2][17] = 54, -+ [0][1][1][0][RTW89_WW][0][19] = -4, -+ [0][1][1][0][RTW89_WW][1][19] = -4, -+ [0][1][1][0][RTW89_WW][2][19] = 54, -+ [0][1][1][0][RTW89_WW][0][21] = -4, -+ [0][1][1][0][RTW89_WW][1][21] = -4, -+ [0][1][1][0][RTW89_WW][2][21] = 54, -+ [0][1][1][0][RTW89_WW][0][23] = -4, -+ [0][1][1][0][RTW89_WW][1][23] = -4, -+ [0][1][1][0][RTW89_WW][2][23] = 68, -+ [0][1][1][0][RTW89_WW][0][25] = -4, -+ [0][1][1][0][RTW89_WW][1][25] = -4, -+ [0][1][1][0][RTW89_WW][2][25] = 68, -+ [0][1][1][0][RTW89_WW][0][27] = -4, -+ [0][1][1][0][RTW89_WW][1][27] = -4, -+ [0][1][1][0][RTW89_WW][2][27] = 68, -+ [0][1][1][0][RTW89_WW][0][29] = -4, -+ [0][1][1][0][RTW89_WW][1][29] = -4, -+ [0][1][1][0][RTW89_WW][2][29] = 68, -+ [0][1][1][0][RTW89_WW][0][30] = -4, -+ [0][1][1][0][RTW89_WW][1][30] = -4, -+ [0][1][1][0][RTW89_WW][2][30] = 68, -+ [0][1][1][0][RTW89_WW][0][32] = -4, -+ [0][1][1][0][RTW89_WW][1][32] = -4, -+ [0][1][1][0][RTW89_WW][2][32] = 68, -+ [0][1][1][0][RTW89_WW][0][34] = -4, -+ [0][1][1][0][RTW89_WW][1][34] = -4, -+ [0][1][1][0][RTW89_WW][2][34] = 68, -+ [0][1][1][0][RTW89_WW][0][36] = -4, -+ [0][1][1][0][RTW89_WW][1][36] = -4, -+ [0][1][1][0][RTW89_WW][2][36] = 68, -+ [0][1][1][0][RTW89_WW][0][38] = -4, -+ [0][1][1][0][RTW89_WW][1][38] = -4, -+ [0][1][1][0][RTW89_WW][2][38] = 68, -+ [0][1][1][0][RTW89_WW][0][40] = -4, -+ [0][1][1][0][RTW89_WW][1][40] = -4, -+ [0][1][1][0][RTW89_WW][2][40] = 68, -+ [0][1][1][0][RTW89_WW][0][42] = -4, -+ [0][1][1][0][RTW89_WW][1][42] = -4, -+ [0][1][1][0][RTW89_WW][2][42] = 68, -+ [0][1][1][0][RTW89_WW][0][44] = -2, -+ [0][1][1][0][RTW89_WW][1][44] = -2, -+ [0][1][1][0][RTW89_WW][2][44] = 68, -+ [0][1][1][0][RTW89_WW][0][45] = -2, -+ [0][1][1][0][RTW89_WW][1][45] = -2, -+ [0][1][1][0][RTW89_WW][2][45] = 0, -+ [0][1][1][0][RTW89_WW][0][47] = -2, -+ [0][1][1][0][RTW89_WW][1][47] = -2, -+ [0][1][1][0][RTW89_WW][2][47] = 0, -+ [0][1][1][0][RTW89_WW][0][49] = -2, -+ [0][1][1][0][RTW89_WW][1][49] = -2, -+ [0][1][1][0][RTW89_WW][2][49] = 0, -+ [0][1][1][0][RTW89_WW][0][51] = -2, -+ [0][1][1][0][RTW89_WW][1][51] = -2, -+ [0][1][1][0][RTW89_WW][2][51] = 0, -+ [0][1][1][0][RTW89_WW][0][53] = -2, -+ [0][1][1][0][RTW89_WW][1][53] = -2, -+ [0][1][1][0][RTW89_WW][2][53] = 0, -+ [0][1][1][0][RTW89_WW][0][55] = -2, -+ [0][1][1][0][RTW89_WW][1][55] = -2, -+ [0][1][1][0][RTW89_WW][2][55] = 68, -+ [0][1][1][0][RTW89_WW][0][57] = -2, -+ [0][1][1][0][RTW89_WW][1][57] = -2, -+ [0][1][1][0][RTW89_WW][2][57] = 68, -+ [0][1][1][0][RTW89_WW][0][59] = -2, -+ [0][1][1][0][RTW89_WW][1][59] = -2, -+ [0][1][1][0][RTW89_WW][2][59] = 68, -+ [0][1][1][0][RTW89_WW][0][60] = -2, -+ [0][1][1][0][RTW89_WW][1][60] = -2, -+ [0][1][1][0][RTW89_WW][2][60] = 68, -+ [0][1][1][0][RTW89_WW][0][62] = -2, -+ [0][1][1][0][RTW89_WW][1][62] = -2, -+ [0][1][1][0][RTW89_WW][2][62] = 68, -+ [0][1][1][0][RTW89_WW][0][64] = -2, -+ [0][1][1][0][RTW89_WW][1][64] = -2, -+ [0][1][1][0][RTW89_WW][2][64] = 68, -+ [0][1][1][0][RTW89_WW][0][66] = -2, -+ [0][1][1][0][RTW89_WW][1][66] = -2, -+ [0][1][1][0][RTW89_WW][2][66] = 68, -+ [0][1][1][0][RTW89_WW][0][68] = -2, -+ [0][1][1][0][RTW89_WW][1][68] = -2, -+ [0][1][1][0][RTW89_WW][2][68] = 68, -+ [0][1][1][0][RTW89_WW][0][70] = -2, -+ [0][1][1][0][RTW89_WW][1][70] = -2, -+ [0][1][1][0][RTW89_WW][2][70] = 68, -+ [0][1][1][0][RTW89_WW][0][72] = -2, -+ [0][1][1][0][RTW89_WW][1][72] = -2, -+ [0][1][1][0][RTW89_WW][2][72] = 68, -+ [0][1][1][0][RTW89_WW][0][74] = -2, -+ [0][1][1][0][RTW89_WW][1][74] = -2, -+ [0][1][1][0][RTW89_WW][2][74] = 68, -+ [0][1][1][0][RTW89_WW][0][75] = -2, -+ [0][1][1][0][RTW89_WW][1][75] = -2, -+ [0][1][1][0][RTW89_WW][2][75] = 68, -+ [0][1][1][0][RTW89_WW][0][77] = -2, -+ [0][1][1][0][RTW89_WW][1][77] = -2, -+ [0][1][1][0][RTW89_WW][2][77] = 68, -+ [0][1][1][0][RTW89_WW][0][79] = -2, -+ [0][1][1][0][RTW89_WW][1][79] = -2, -+ [0][1][1][0][RTW89_WW][2][79] = 68, -+ [0][1][1][0][RTW89_WW][0][81] = -2, -+ [0][1][1][0][RTW89_WW][1][81] = -2, -+ [0][1][1][0][RTW89_WW][2][81] = 68, -+ [0][1][1][0][RTW89_WW][0][83] = -2, -+ [0][1][1][0][RTW89_WW][1][83] = -2, -+ [0][1][1][0][RTW89_WW][2][83] = 68, -+ [0][1][1][0][RTW89_WW][0][85] = -2, -+ [0][1][1][0][RTW89_WW][1][85] = -2, -+ [0][1][1][0][RTW89_WW][2][85] = 68, -+ [0][1][1][0][RTW89_WW][0][87] = -2, -+ [0][1][1][0][RTW89_WW][1][87] = -2, -+ [0][1][1][0][RTW89_WW][2][87] = 0, -+ [0][1][1][0][RTW89_WW][0][89] = -2, -+ [0][1][1][0][RTW89_WW][1][89] = -2, -+ [0][1][1][0][RTW89_WW][2][89] = 0, -+ [0][1][1][0][RTW89_WW][0][90] = -2, -+ [0][1][1][0][RTW89_WW][1][90] = -2, -+ [0][1][1][0][RTW89_WW][2][90] = 0, -+ [0][1][1][0][RTW89_WW][0][92] = -2, -+ [0][1][1][0][RTW89_WW][1][92] = -2, -+ [0][1][1][0][RTW89_WW][2][92] = 0, -+ [0][1][1][0][RTW89_WW][0][94] = -2, -+ [0][1][1][0][RTW89_WW][1][94] = -2, -+ [0][1][1][0][RTW89_WW][2][94] = 0, -+ [0][1][1][0][RTW89_WW][0][96] = -2, -+ [0][1][1][0][RTW89_WW][1][96] = -2, -+ [0][1][1][0][RTW89_WW][2][96] = 0, -+ [0][1][1][0][RTW89_WW][0][98] = -2, -+ [0][1][1][0][RTW89_WW][1][98] = -2, -+ [0][1][1][0][RTW89_WW][2][98] = 0, -+ [0][1][1][0][RTW89_WW][0][100] = -2, -+ [0][1][1][0][RTW89_WW][1][100] = -2, -+ [0][1][1][0][RTW89_WW][2][100] = 0, -+ [0][1][1][0][RTW89_WW][0][102] = -2, -+ [0][1][1][0][RTW89_WW][1][102] = -2, -+ [0][1][1][0][RTW89_WW][2][102] = 0, -+ [0][1][1][0][RTW89_WW][0][104] = -2, -+ [0][1][1][0][RTW89_WW][1][104] = -2, -+ [0][1][1][0][RTW89_WW][2][104] = 0, -+ [0][1][1][0][RTW89_WW][0][105] = -2, -+ [0][1][1][0][RTW89_WW][1][105] = -2, -+ [0][1][1][0][RTW89_WW][2][105] = 0, -+ [0][1][1][0][RTW89_WW][0][107] = 1, -+ [0][1][1][0][RTW89_WW][1][107] = 1, -+ [0][1][1][0][RTW89_WW][2][107] = 0, -+ [0][1][1][0][RTW89_WW][0][109] = 1, -+ [0][1][1][0][RTW89_WW][1][109] = 1, -+ [0][1][1][0][RTW89_WW][2][109] = 0, -+ [0][1][1][0][RTW89_WW][0][111] = 0, -+ [0][1][1][0][RTW89_WW][1][111] = 0, -+ [0][1][1][0][RTW89_WW][2][111] = 0, -+ [0][1][1][0][RTW89_WW][0][113] = 0, -+ [0][1][1][0][RTW89_WW][1][113] = 0, -+ [0][1][1][0][RTW89_WW][2][113] = 0, -+ [0][1][1][0][RTW89_WW][0][115] = 0, -+ [0][1][1][0][RTW89_WW][1][115] = 0, -+ [0][1][1][0][RTW89_WW][2][115] = 0, -+ [0][1][1][0][RTW89_WW][0][117] = 0, -+ [0][1][1][0][RTW89_WW][1][117] = 0, -+ [0][1][1][0][RTW89_WW][2][117] = 0, -+ [0][1][1][0][RTW89_WW][0][119] = 0, -+ [0][1][1][0][RTW89_WW][1][119] = 0, -+ [0][1][1][0][RTW89_WW][2][119] = 0, -+ [0][0][2][0][RTW89_WW][0][0] = 24, -+ [0][0][2][0][RTW89_WW][1][0] = 24, -+ [0][0][2][0][RTW89_WW][2][0] = 56, -+ [0][0][2][0][RTW89_WW][0][2] = 22, -+ [0][0][2][0][RTW89_WW][1][2] = 22, -+ [0][0][2][0][RTW89_WW][2][2] = 56, -+ [0][0][2][0][RTW89_WW][0][4] = 22, -+ [0][0][2][0][RTW89_WW][1][4] = 22, -+ [0][0][2][0][RTW89_WW][2][4] = 56, -+ [0][0][2][0][RTW89_WW][0][6] = 22, -+ [0][0][2][0][RTW89_WW][1][6] = 22, -+ [0][0][2][0][RTW89_WW][2][6] = 56, -+ [0][0][2][0][RTW89_WW][0][8] = 22, -+ [0][0][2][0][RTW89_WW][1][8] = 22, -+ [0][0][2][0][RTW89_WW][2][8] = 56, -+ [0][0][2][0][RTW89_WW][0][10] = 22, -+ [0][0][2][0][RTW89_WW][1][10] = 22, -+ [0][0][2][0][RTW89_WW][2][10] = 56, -+ [0][0][2][0][RTW89_WW][0][12] = 22, -+ [0][0][2][0][RTW89_WW][1][12] = 22, -+ [0][0][2][0][RTW89_WW][2][12] = 56, -+ [0][0][2][0][RTW89_WW][0][14] = 22, -+ [0][0][2][0][RTW89_WW][1][14] = 22, -+ [0][0][2][0][RTW89_WW][2][14] = 56, -+ [0][0][2][0][RTW89_WW][0][15] = 22, -+ [0][0][2][0][RTW89_WW][1][15] = 22, -+ [0][0][2][0][RTW89_WW][2][15] = 56, -+ [0][0][2][0][RTW89_WW][0][17] = 22, -+ [0][0][2][0][RTW89_WW][1][17] = 22, -+ [0][0][2][0][RTW89_WW][2][17] = 56, -+ [0][0][2][0][RTW89_WW][0][19] = 22, -+ [0][0][2][0][RTW89_WW][1][19] = 22, -+ [0][0][2][0][RTW89_WW][2][19] = 56, -+ [0][0][2][0][RTW89_WW][0][21] = 22, -+ [0][0][2][0][RTW89_WW][1][21] = 22, -+ [0][0][2][0][RTW89_WW][2][21] = 56, -+ [0][0][2][0][RTW89_WW][0][23] = 22, -+ [0][0][2][0][RTW89_WW][1][23] = 22, -+ [0][0][2][0][RTW89_WW][2][23] = 70, -+ [0][0][2][0][RTW89_WW][0][25] = 22, -+ [0][0][2][0][RTW89_WW][1][25] = 22, -+ [0][0][2][0][RTW89_WW][2][25] = 70, -+ [0][0][2][0][RTW89_WW][0][27] = 22, -+ [0][0][2][0][RTW89_WW][1][27] = 22, -+ [0][0][2][0][RTW89_WW][2][27] = 70, -+ [0][0][2][0][RTW89_WW][0][29] = 22, -+ [0][0][2][0][RTW89_WW][1][29] = 22, -+ [0][0][2][0][RTW89_WW][2][29] = 70, -+ [0][0][2][0][RTW89_WW][0][30] = 22, -+ [0][0][2][0][RTW89_WW][1][30] = 22, -+ [0][0][2][0][RTW89_WW][2][30] = 70, -+ [0][0][2][0][RTW89_WW][0][32] = 22, -+ [0][0][2][0][RTW89_WW][1][32] = 22, -+ [0][0][2][0][RTW89_WW][2][32] = 70, -+ [0][0][2][0][RTW89_WW][0][34] = 22, -+ [0][0][2][0][RTW89_WW][1][34] = 22, -+ [0][0][2][0][RTW89_WW][2][34] = 70, -+ [0][0][2][0][RTW89_WW][0][36] = 22, -+ [0][0][2][0][RTW89_WW][1][36] = 22, -+ [0][0][2][0][RTW89_WW][2][36] = 70, -+ [0][0][2][0][RTW89_WW][0][38] = 22, -+ [0][0][2][0][RTW89_WW][1][38] = 22, -+ [0][0][2][0][RTW89_WW][2][38] = 70, -+ [0][0][2][0][RTW89_WW][0][40] = 22, -+ [0][0][2][0][RTW89_WW][1][40] = 22, -+ [0][0][2][0][RTW89_WW][2][40] = 70, -+ [0][0][2][0][RTW89_WW][0][42] = 22, -+ [0][0][2][0][RTW89_WW][1][42] = 22, -+ [0][0][2][0][RTW89_WW][2][42] = 70, -+ [0][0][2][0][RTW89_WW][0][44] = 22, -+ [0][0][2][0][RTW89_WW][1][44] = 22, -+ [0][0][2][0][RTW89_WW][2][44] = 70, -+ [0][0][2][0][RTW89_WW][0][45] = 22, -+ [0][0][2][0][RTW89_WW][1][45] = 22, -+ [0][0][2][0][RTW89_WW][2][45] = 0, -+ [0][0][2][0][RTW89_WW][0][47] = 22, -+ [0][0][2][0][RTW89_WW][1][47] = 22, -+ [0][0][2][0][RTW89_WW][2][47] = 0, -+ [0][0][2][0][RTW89_WW][0][49] = 24, -+ [0][0][2][0][RTW89_WW][1][49] = 24, -+ [0][0][2][0][RTW89_WW][2][49] = 0, -+ [0][0][2][0][RTW89_WW][0][51] = 22, -+ [0][0][2][0][RTW89_WW][1][51] = 22, -+ [0][0][2][0][RTW89_WW][2][51] = 0, -+ [0][0][2][0][RTW89_WW][0][53] = 22, -+ [0][0][2][0][RTW89_WW][1][53] = 22, -+ [0][0][2][0][RTW89_WW][2][53] = 0, -+ [0][0][2][0][RTW89_WW][0][55] = 22, -+ [0][0][2][0][RTW89_WW][1][55] = 22, -+ [0][0][2][0][RTW89_WW][2][55] = 68, -+ [0][0][2][0][RTW89_WW][0][57] = 22, -+ [0][0][2][0][RTW89_WW][1][57] = 22, -+ [0][0][2][0][RTW89_WW][2][57] = 68, -+ [0][0][2][0][RTW89_WW][0][59] = 22, -+ [0][0][2][0][RTW89_WW][1][59] = 22, -+ [0][0][2][0][RTW89_WW][2][59] = 68, -+ [0][0][2][0][RTW89_WW][0][60] = 22, -+ [0][0][2][0][RTW89_WW][1][60] = 22, -+ [0][0][2][0][RTW89_WW][2][60] = 68, -+ [0][0][2][0][RTW89_WW][0][62] = 22, -+ [0][0][2][0][RTW89_WW][1][62] = 22, -+ [0][0][2][0][RTW89_WW][2][62] = 68, -+ [0][0][2][0][RTW89_WW][0][64] = 22, -+ [0][0][2][0][RTW89_WW][1][64] = 22, -+ [0][0][2][0][RTW89_WW][2][64] = 68, -+ [0][0][2][0][RTW89_WW][0][66] = 22, -+ [0][0][2][0][RTW89_WW][1][66] = 22, -+ [0][0][2][0][RTW89_WW][2][66] = 68, -+ [0][0][2][0][RTW89_WW][0][68] = 22, -+ [0][0][2][0][RTW89_WW][1][68] = 22, -+ [0][0][2][0][RTW89_WW][2][68] = 68, -+ [0][0][2][0][RTW89_WW][0][70] = 24, -+ [0][0][2][0][RTW89_WW][1][70] = 24, -+ [0][0][2][0][RTW89_WW][2][70] = 68, -+ [0][0][2][0][RTW89_WW][0][72] = 22, -+ [0][0][2][0][RTW89_WW][1][72] = 22, -+ [0][0][2][0][RTW89_WW][2][72] = 68, -+ [0][0][2][0][RTW89_WW][0][74] = 22, -+ [0][0][2][0][RTW89_WW][1][74] = 22, -+ [0][0][2][0][RTW89_WW][2][74] = 68, -+ [0][0][2][0][RTW89_WW][0][75] = 22, -+ [0][0][2][0][RTW89_WW][1][75] = 22, -+ [0][0][2][0][RTW89_WW][2][75] = 68, -+ [0][0][2][0][RTW89_WW][0][77] = 22, -+ [0][0][2][0][RTW89_WW][1][77] = 22, -+ [0][0][2][0][RTW89_WW][2][77] = 68, -+ [0][0][2][0][RTW89_WW][0][79] = 22, -+ [0][0][2][0][RTW89_WW][1][79] = 22, -+ [0][0][2][0][RTW89_WW][2][79] = 68, -+ [0][0][2][0][RTW89_WW][0][81] = 22, -+ [0][0][2][0][RTW89_WW][1][81] = 22, -+ [0][0][2][0][RTW89_WW][2][81] = 68, -+ [0][0][2][0][RTW89_WW][0][83] = 22, -+ [0][0][2][0][RTW89_WW][1][83] = 22, -+ [0][0][2][0][RTW89_WW][2][83] = 68, -+ [0][0][2][0][RTW89_WW][0][85] = 22, -+ [0][0][2][0][RTW89_WW][1][85] = 22, -+ [0][0][2][0][RTW89_WW][2][85] = 68, -+ [0][0][2][0][RTW89_WW][0][87] = 22, -+ [0][0][2][0][RTW89_WW][1][87] = 22, -+ [0][0][2][0][RTW89_WW][2][87] = 0, -+ [0][0][2][0][RTW89_WW][0][89] = 22, -+ [0][0][2][0][RTW89_WW][1][89] = 22, -+ [0][0][2][0][RTW89_WW][2][89] = 0, -+ [0][0][2][0][RTW89_WW][0][90] = 22, -+ [0][0][2][0][RTW89_WW][1][90] = 22, -+ [0][0][2][0][RTW89_WW][2][90] = 0, -+ [0][0][2][0][RTW89_WW][0][92] = 22, -+ [0][0][2][0][RTW89_WW][1][92] = 22, -+ [0][0][2][0][RTW89_WW][2][92] = 0, -+ [0][0][2][0][RTW89_WW][0][94] = 22, -+ [0][0][2][0][RTW89_WW][1][94] = 22, -+ [0][0][2][0][RTW89_WW][2][94] = 0, -+ [0][0][2][0][RTW89_WW][0][96] = 22, -+ [0][0][2][0][RTW89_WW][1][96] = 22, -+ [0][0][2][0][RTW89_WW][2][96] = 0, -+ [0][0][2][0][RTW89_WW][0][98] = 22, -+ [0][0][2][0][RTW89_WW][1][98] = 22, -+ [0][0][2][0][RTW89_WW][2][98] = 0, -+ [0][0][2][0][RTW89_WW][0][100] = 22, -+ [0][0][2][0][RTW89_WW][1][100] = 22, -+ [0][0][2][0][RTW89_WW][2][100] = 0, -+ [0][0][2][0][RTW89_WW][0][102] = 22, -+ [0][0][2][0][RTW89_WW][1][102] = 22, -+ [0][0][2][0][RTW89_WW][2][102] = 0, -+ [0][0][2][0][RTW89_WW][0][104] = 22, -+ [0][0][2][0][RTW89_WW][1][104] = 22, -+ [0][0][2][0][RTW89_WW][2][104] = 0, -+ [0][0][2][0][RTW89_WW][0][105] = 22, -+ [0][0][2][0][RTW89_WW][1][105] = 22, -+ [0][0][2][0][RTW89_WW][2][105] = 0, -+ [0][0][2][0][RTW89_WW][0][107] = 24, -+ [0][0][2][0][RTW89_WW][1][107] = 24, -+ [0][0][2][0][RTW89_WW][2][107] = 0, -+ [0][0][2][0][RTW89_WW][0][109] = 24, -+ [0][0][2][0][RTW89_WW][1][109] = 24, -+ [0][0][2][0][RTW89_WW][2][109] = 0, -+ [0][0][2][0][RTW89_WW][0][111] = 0, -+ [0][0][2][0][RTW89_WW][1][111] = 0, -+ [0][0][2][0][RTW89_WW][2][111] = 0, -+ [0][0][2][0][RTW89_WW][0][113] = 0, -+ [0][0][2][0][RTW89_WW][1][113] = 0, -+ [0][0][2][0][RTW89_WW][2][113] = 0, -+ [0][0][2][0][RTW89_WW][0][115] = 0, -+ [0][0][2][0][RTW89_WW][1][115] = 0, -+ [0][0][2][0][RTW89_WW][2][115] = 0, -+ [0][0][2][0][RTW89_WW][0][117] = 0, -+ [0][0][2][0][RTW89_WW][1][117] = 0, -+ [0][0][2][0][RTW89_WW][2][117] = 0, -+ [0][0][2][0][RTW89_WW][0][119] = 0, -+ [0][0][2][0][RTW89_WW][1][119] = 0, -+ [0][0][2][0][RTW89_WW][2][119] = 0, -+ [0][1][2][0][RTW89_WW][0][0] = -2, -+ [0][1][2][0][RTW89_WW][1][0] = -2, -+ [0][1][2][0][RTW89_WW][2][0] = 54, -+ [0][1][2][0][RTW89_WW][0][2] = -4, -+ [0][1][2][0][RTW89_WW][1][2] = -4, -+ [0][1][2][0][RTW89_WW][2][2] = 54, -+ [0][1][2][0][RTW89_WW][0][4] = -4, -+ [0][1][2][0][RTW89_WW][1][4] = -4, -+ [0][1][2][0][RTW89_WW][2][4] = 54, -+ [0][1][2][0][RTW89_WW][0][6] = -4, -+ [0][1][2][0][RTW89_WW][1][6] = -4, -+ [0][1][2][0][RTW89_WW][2][6] = 54, -+ [0][1][2][0][RTW89_WW][0][8] = -4, -+ [0][1][2][0][RTW89_WW][1][8] = -4, -+ [0][1][2][0][RTW89_WW][2][8] = 54, -+ [0][1][2][0][RTW89_WW][0][10] = -4, -+ [0][1][2][0][RTW89_WW][1][10] = -4, -+ [0][1][2][0][RTW89_WW][2][10] = 54, -+ [0][1][2][0][RTW89_WW][0][12] = -4, -+ [0][1][2][0][RTW89_WW][1][12] = -4, -+ [0][1][2][0][RTW89_WW][2][12] = 54, -+ [0][1][2][0][RTW89_WW][0][14] = -4, -+ [0][1][2][0][RTW89_WW][1][14] = -4, -+ [0][1][2][0][RTW89_WW][2][14] = 54, -+ [0][1][2][0][RTW89_WW][0][15] = -4, -+ [0][1][2][0][RTW89_WW][1][15] = -4, -+ [0][1][2][0][RTW89_WW][2][15] = 54, -+ [0][1][2][0][RTW89_WW][0][17] = -4, -+ [0][1][2][0][RTW89_WW][1][17] = -4, -+ [0][1][2][0][RTW89_WW][2][17] = 54, -+ [0][1][2][0][RTW89_WW][0][19] = -4, -+ [0][1][2][0][RTW89_WW][1][19] = -4, -+ [0][1][2][0][RTW89_WW][2][19] = 54, -+ [0][1][2][0][RTW89_WW][0][21] = -4, -+ [0][1][2][0][RTW89_WW][1][21] = -4, -+ [0][1][2][0][RTW89_WW][2][21] = 54, -+ [0][1][2][0][RTW89_WW][0][23] = -4, -+ [0][1][2][0][RTW89_WW][1][23] = -4, -+ [0][1][2][0][RTW89_WW][2][23] = 68, -+ [0][1][2][0][RTW89_WW][0][25] = -4, -+ [0][1][2][0][RTW89_WW][1][25] = -4, -+ [0][1][2][0][RTW89_WW][2][25] = 68, -+ [0][1][2][0][RTW89_WW][0][27] = -4, -+ [0][1][2][0][RTW89_WW][1][27] = -4, -+ [0][1][2][0][RTW89_WW][2][27] = 68, -+ [0][1][2][0][RTW89_WW][0][29] = -4, -+ [0][1][2][0][RTW89_WW][1][29] = -4, -+ [0][1][2][0][RTW89_WW][2][29] = 68, -+ [0][1][2][0][RTW89_WW][0][30] = -4, -+ [0][1][2][0][RTW89_WW][1][30] = -4, -+ [0][1][2][0][RTW89_WW][2][30] = 68, -+ [0][1][2][0][RTW89_WW][0][32] = -4, -+ [0][1][2][0][RTW89_WW][1][32] = -4, -+ [0][1][2][0][RTW89_WW][2][32] = 68, -+ [0][1][2][0][RTW89_WW][0][34] = -4, -+ [0][1][2][0][RTW89_WW][1][34] = -4, -+ [0][1][2][0][RTW89_WW][2][34] = 68, -+ [0][1][2][0][RTW89_WW][0][36] = -4, -+ [0][1][2][0][RTW89_WW][1][36] = -4, -+ [0][1][2][0][RTW89_WW][2][36] = 68, -+ [0][1][2][0][RTW89_WW][0][38] = -4, -+ [0][1][2][0][RTW89_WW][1][38] = -4, -+ [0][1][2][0][RTW89_WW][2][38] = 68, -+ [0][1][2][0][RTW89_WW][0][40] = -4, -+ [0][1][2][0][RTW89_WW][1][40] = -4, -+ [0][1][2][0][RTW89_WW][2][40] = 68, -+ [0][1][2][0][RTW89_WW][0][42] = -4, -+ [0][1][2][0][RTW89_WW][1][42] = -4, -+ [0][1][2][0][RTW89_WW][2][42] = 68, -+ [0][1][2][0][RTW89_WW][0][44] = -2, -+ [0][1][2][0][RTW89_WW][1][44] = -2, -+ [0][1][2][0][RTW89_WW][2][44] = 68, -+ [0][1][2][0][RTW89_WW][0][45] = -2, -+ [0][1][2][0][RTW89_WW][1][45] = -2, -+ [0][1][2][0][RTW89_WW][2][45] = 0, -+ [0][1][2][0][RTW89_WW][0][47] = -2, -+ [0][1][2][0][RTW89_WW][1][47] = -2, -+ [0][1][2][0][RTW89_WW][2][47] = 0, -+ [0][1][2][0][RTW89_WW][0][49] = -2, -+ [0][1][2][0][RTW89_WW][1][49] = -2, -+ [0][1][2][0][RTW89_WW][2][49] = 0, -+ [0][1][2][0][RTW89_WW][0][51] = -2, -+ [0][1][2][0][RTW89_WW][1][51] = -2, -+ [0][1][2][0][RTW89_WW][2][51] = 0, -+ [0][1][2][0][RTW89_WW][0][53] = -2, -+ [0][1][2][0][RTW89_WW][1][53] = -2, -+ [0][1][2][0][RTW89_WW][2][53] = 0, -+ [0][1][2][0][RTW89_WW][0][55] = -2, -+ [0][1][2][0][RTW89_WW][1][55] = -2, -+ [0][1][2][0][RTW89_WW][2][55] = 68, -+ [0][1][2][0][RTW89_WW][0][57] = -2, -+ [0][1][2][0][RTW89_WW][1][57] = -2, -+ [0][1][2][0][RTW89_WW][2][57] = 68, -+ [0][1][2][0][RTW89_WW][0][59] = -2, -+ [0][1][2][0][RTW89_WW][1][59] = -2, -+ [0][1][2][0][RTW89_WW][2][59] = 68, -+ [0][1][2][0][RTW89_WW][0][60] = -2, -+ [0][1][2][0][RTW89_WW][1][60] = -2, -+ [0][1][2][0][RTW89_WW][2][60] = 68, -+ [0][1][2][0][RTW89_WW][0][62] = -2, -+ [0][1][2][0][RTW89_WW][1][62] = -2, -+ [0][1][2][0][RTW89_WW][2][62] = 68, -+ [0][1][2][0][RTW89_WW][0][64] = -2, -+ [0][1][2][0][RTW89_WW][1][64] = -2, -+ [0][1][2][0][RTW89_WW][2][64] = 68, -+ [0][1][2][0][RTW89_WW][0][66] = -2, -+ [0][1][2][0][RTW89_WW][1][66] = -2, -+ [0][1][2][0][RTW89_WW][2][66] = 68, -+ [0][1][2][0][RTW89_WW][0][68] = -2, -+ [0][1][2][0][RTW89_WW][1][68] = -2, -+ [0][1][2][0][RTW89_WW][2][68] = 68, -+ [0][1][2][0][RTW89_WW][0][70] = -2, -+ [0][1][2][0][RTW89_WW][1][70] = -2, -+ [0][1][2][0][RTW89_WW][2][70] = 68, -+ [0][1][2][0][RTW89_WW][0][72] = -2, -+ [0][1][2][0][RTW89_WW][1][72] = -2, -+ [0][1][2][0][RTW89_WW][2][72] = 68, -+ [0][1][2][0][RTW89_WW][0][74] = -2, -+ [0][1][2][0][RTW89_WW][1][74] = -2, -+ [0][1][2][0][RTW89_WW][2][74] = 68, -+ [0][1][2][0][RTW89_WW][0][75] = -2, -+ [0][1][2][0][RTW89_WW][1][75] = -2, -+ [0][1][2][0][RTW89_WW][2][75] = 68, -+ [0][1][2][0][RTW89_WW][0][77] = -2, -+ [0][1][2][0][RTW89_WW][1][77] = -2, -+ [0][1][2][0][RTW89_WW][2][77] = 68, -+ [0][1][2][0][RTW89_WW][0][79] = -2, -+ [0][1][2][0][RTW89_WW][1][79] = -2, -+ [0][1][2][0][RTW89_WW][2][79] = 68, -+ [0][1][2][0][RTW89_WW][0][81] = -2, -+ [0][1][2][0][RTW89_WW][1][81] = -2, -+ [0][1][2][0][RTW89_WW][2][81] = 68, -+ [0][1][2][0][RTW89_WW][0][83] = -2, -+ [0][1][2][0][RTW89_WW][1][83] = -2, -+ [0][1][2][0][RTW89_WW][2][83] = 68, -+ [0][1][2][0][RTW89_WW][0][85] = -2, -+ [0][1][2][0][RTW89_WW][1][85] = -2, -+ [0][1][2][0][RTW89_WW][2][85] = 68, -+ [0][1][2][0][RTW89_WW][0][87] = -2, -+ [0][1][2][0][RTW89_WW][1][87] = -2, -+ [0][1][2][0][RTW89_WW][2][87] = 0, -+ [0][1][2][0][RTW89_WW][0][89] = -2, -+ [0][1][2][0][RTW89_WW][1][89] = -2, -+ [0][1][2][0][RTW89_WW][2][89] = 0, -+ [0][1][2][0][RTW89_WW][0][90] = -2, -+ [0][1][2][0][RTW89_WW][1][90] = -2, -+ [0][1][2][0][RTW89_WW][2][90] = 0, -+ [0][1][2][0][RTW89_WW][0][92] = -2, -+ [0][1][2][0][RTW89_WW][1][92] = -2, -+ [0][1][2][0][RTW89_WW][2][92] = 0, -+ [0][1][2][0][RTW89_WW][0][94] = -2, -+ [0][1][2][0][RTW89_WW][1][94] = -2, -+ [0][1][2][0][RTW89_WW][2][94] = 0, -+ [0][1][2][0][RTW89_WW][0][96] = -2, -+ [0][1][2][0][RTW89_WW][1][96] = -2, -+ [0][1][2][0][RTW89_WW][2][96] = 0, -+ [0][1][2][0][RTW89_WW][0][98] = -2, -+ [0][1][2][0][RTW89_WW][1][98] = -2, -+ [0][1][2][0][RTW89_WW][2][98] = 0, -+ [0][1][2][0][RTW89_WW][0][100] = -2, -+ [0][1][2][0][RTW89_WW][1][100] = -2, -+ [0][1][2][0][RTW89_WW][2][100] = 0, -+ [0][1][2][0][RTW89_WW][0][102] = -2, -+ [0][1][2][0][RTW89_WW][1][102] = -2, -+ [0][1][2][0][RTW89_WW][2][102] = 0, -+ [0][1][2][0][RTW89_WW][0][104] = -2, -+ [0][1][2][0][RTW89_WW][1][104] = -2, -+ [0][1][2][0][RTW89_WW][2][104] = 0, -+ [0][1][2][0][RTW89_WW][0][105] = -2, -+ [0][1][2][0][RTW89_WW][1][105] = -2, -+ [0][1][2][0][RTW89_WW][2][105] = 0, -+ [0][1][2][0][RTW89_WW][0][107] = 1, -+ [0][1][2][0][RTW89_WW][1][107] = 1, -+ [0][1][2][0][RTW89_WW][2][107] = 0, -+ [0][1][2][0][RTW89_WW][0][109] = 1, -+ [0][1][2][0][RTW89_WW][1][109] = 1, -+ [0][1][2][0][RTW89_WW][2][109] = 0, -+ [0][1][2][0][RTW89_WW][0][111] = 0, -+ [0][1][2][0][RTW89_WW][1][111] = 0, -+ [0][1][2][0][RTW89_WW][2][111] = 0, -+ [0][1][2][0][RTW89_WW][0][113] = 0, -+ [0][1][2][0][RTW89_WW][1][113] = 0, -+ [0][1][2][0][RTW89_WW][2][113] = 0, -+ [0][1][2][0][RTW89_WW][0][115] = 0, -+ [0][1][2][0][RTW89_WW][1][115] = 0, -+ [0][1][2][0][RTW89_WW][2][115] = 0, -+ [0][1][2][0][RTW89_WW][0][117] = 0, -+ [0][1][2][0][RTW89_WW][1][117] = 0, -+ [0][1][2][0][RTW89_WW][2][117] = 0, -+ [0][1][2][0][RTW89_WW][0][119] = 0, -+ [0][1][2][0][RTW89_WW][1][119] = 0, -+ [0][1][2][0][RTW89_WW][2][119] = 0, -+ [0][1][2][1][RTW89_WW][0][0] = -2, -+ [0][1][2][1][RTW89_WW][1][0] = -2, -+ [0][1][2][1][RTW89_WW][2][0] = 54, -+ [0][1][2][1][RTW89_WW][0][2] = -4, -+ [0][1][2][1][RTW89_WW][1][2] = -4, -+ [0][1][2][1][RTW89_WW][2][2] = 54, -+ [0][1][2][1][RTW89_WW][0][4] = -4, -+ [0][1][2][1][RTW89_WW][1][4] = -4, -+ [0][1][2][1][RTW89_WW][2][4] = 54, -+ [0][1][2][1][RTW89_WW][0][6] = -4, -+ [0][1][2][1][RTW89_WW][1][6] = -4, -+ [0][1][2][1][RTW89_WW][2][6] = 54, -+ [0][1][2][1][RTW89_WW][0][8] = -4, -+ [0][1][2][1][RTW89_WW][1][8] = -4, -+ [0][1][2][1][RTW89_WW][2][8] = 54, -+ [0][1][2][1][RTW89_WW][0][10] = -4, -+ [0][1][2][1][RTW89_WW][1][10] = -4, -+ [0][1][2][1][RTW89_WW][2][10] = 54, -+ [0][1][2][1][RTW89_WW][0][12] = -4, -+ [0][1][2][1][RTW89_WW][1][12] = -4, -+ [0][1][2][1][RTW89_WW][2][12] = 54, -+ [0][1][2][1][RTW89_WW][0][14] = -4, -+ [0][1][2][1][RTW89_WW][1][14] = -4, -+ [0][1][2][1][RTW89_WW][2][14] = 54, -+ [0][1][2][1][RTW89_WW][0][15] = -4, -+ [0][1][2][1][RTW89_WW][1][15] = -4, -+ [0][1][2][1][RTW89_WW][2][15] = 54, -+ [0][1][2][1][RTW89_WW][0][17] = -4, -+ [0][1][2][1][RTW89_WW][1][17] = -4, -+ [0][1][2][1][RTW89_WW][2][17] = 54, -+ [0][1][2][1][RTW89_WW][0][19] = -4, -+ [0][1][2][1][RTW89_WW][1][19] = -4, -+ [0][1][2][1][RTW89_WW][2][19] = 54, -+ [0][1][2][1][RTW89_WW][0][21] = -4, -+ [0][1][2][1][RTW89_WW][1][21] = -4, -+ [0][1][2][1][RTW89_WW][2][21] = 54, -+ [0][1][2][1][RTW89_WW][0][23] = -4, -+ [0][1][2][1][RTW89_WW][1][23] = -4, -+ [0][1][2][1][RTW89_WW][2][23] = 68, -+ [0][1][2][1][RTW89_WW][0][25] = -4, -+ [0][1][2][1][RTW89_WW][1][25] = -4, -+ [0][1][2][1][RTW89_WW][2][25] = 68, -+ [0][1][2][1][RTW89_WW][0][27] = -4, -+ [0][1][2][1][RTW89_WW][1][27] = -4, -+ [0][1][2][1][RTW89_WW][2][27] = 68, -+ [0][1][2][1][RTW89_WW][0][29] = -4, -+ [0][1][2][1][RTW89_WW][1][29] = -4, -+ [0][1][2][1][RTW89_WW][2][29] = 68, -+ [0][1][2][1][RTW89_WW][0][30] = -4, -+ [0][1][2][1][RTW89_WW][1][30] = -4, -+ [0][1][2][1][RTW89_WW][2][30] = 68, -+ [0][1][2][1][RTW89_WW][0][32] = -4, -+ [0][1][2][1][RTW89_WW][1][32] = -4, -+ [0][1][2][1][RTW89_WW][2][32] = 68, -+ [0][1][2][1][RTW89_WW][0][34] = -4, -+ [0][1][2][1][RTW89_WW][1][34] = -4, -+ [0][1][2][1][RTW89_WW][2][34] = 68, -+ [0][1][2][1][RTW89_WW][0][36] = -4, -+ [0][1][2][1][RTW89_WW][1][36] = -4, -+ [0][1][2][1][RTW89_WW][2][36] = 68, -+ [0][1][2][1][RTW89_WW][0][38] = -4, -+ [0][1][2][1][RTW89_WW][1][38] = -4, -+ [0][1][2][1][RTW89_WW][2][38] = 68, -+ [0][1][2][1][RTW89_WW][0][40] = -4, -+ [0][1][2][1][RTW89_WW][1][40] = -4, -+ [0][1][2][1][RTW89_WW][2][40] = 68, -+ [0][1][2][1][RTW89_WW][0][42] = -4, -+ [0][1][2][1][RTW89_WW][1][42] = -4, -+ [0][1][2][1][RTW89_WW][2][42] = 68, -+ [0][1][2][1][RTW89_WW][0][44] = -2, -+ [0][1][2][1][RTW89_WW][1][44] = -2, -+ [0][1][2][1][RTW89_WW][2][44] = 68, -+ [0][1][2][1][RTW89_WW][0][45] = -2, -+ [0][1][2][1][RTW89_WW][1][45] = -2, -+ [0][1][2][1][RTW89_WW][2][45] = 0, -+ [0][1][2][1][RTW89_WW][0][47] = -2, -+ [0][1][2][1][RTW89_WW][1][47] = -2, -+ [0][1][2][1][RTW89_WW][2][47] = 0, -+ [0][1][2][1][RTW89_WW][0][49] = -2, -+ [0][1][2][1][RTW89_WW][1][49] = -2, -+ [0][1][2][1][RTW89_WW][2][49] = 0, -+ [0][1][2][1][RTW89_WW][0][51] = -2, -+ [0][1][2][1][RTW89_WW][1][51] = -2, -+ [0][1][2][1][RTW89_WW][2][51] = 0, -+ [0][1][2][1][RTW89_WW][0][53] = -2, -+ [0][1][2][1][RTW89_WW][1][53] = -2, -+ [0][1][2][1][RTW89_WW][2][53] = 0, -+ [0][1][2][1][RTW89_WW][0][55] = -2, -+ [0][1][2][1][RTW89_WW][1][55] = -2, -+ [0][1][2][1][RTW89_WW][2][55] = 68, -+ [0][1][2][1][RTW89_WW][0][57] = -2, -+ [0][1][2][1][RTW89_WW][1][57] = -2, -+ [0][1][2][1][RTW89_WW][2][57] = 68, -+ [0][1][2][1][RTW89_WW][0][59] = -2, -+ [0][1][2][1][RTW89_WW][1][59] = -2, -+ [0][1][2][1][RTW89_WW][2][59] = 68, -+ [0][1][2][1][RTW89_WW][0][60] = -2, -+ [0][1][2][1][RTW89_WW][1][60] = -2, -+ [0][1][2][1][RTW89_WW][2][60] = 68, -+ [0][1][2][1][RTW89_WW][0][62] = -2, -+ [0][1][2][1][RTW89_WW][1][62] = -2, -+ [0][1][2][1][RTW89_WW][2][62] = 68, -+ [0][1][2][1][RTW89_WW][0][64] = -2, -+ [0][1][2][1][RTW89_WW][1][64] = -2, -+ [0][1][2][1][RTW89_WW][2][64] = 68, -+ [0][1][2][1][RTW89_WW][0][66] = -2, -+ [0][1][2][1][RTW89_WW][1][66] = -2, -+ [0][1][2][1][RTW89_WW][2][66] = 68, -+ [0][1][2][1][RTW89_WW][0][68] = -2, -+ [0][1][2][1][RTW89_WW][1][68] = -2, -+ [0][1][2][1][RTW89_WW][2][68] = 68, -+ [0][1][2][1][RTW89_WW][0][70] = -2, -+ [0][1][2][1][RTW89_WW][1][70] = -2, -+ [0][1][2][1][RTW89_WW][2][70] = 68, -+ [0][1][2][1][RTW89_WW][0][72] = -2, -+ [0][1][2][1][RTW89_WW][1][72] = -2, -+ [0][1][2][1][RTW89_WW][2][72] = 68, -+ [0][1][2][1][RTW89_WW][0][74] = -2, -+ [0][1][2][1][RTW89_WW][1][74] = -2, -+ [0][1][2][1][RTW89_WW][2][74] = 68, -+ [0][1][2][1][RTW89_WW][0][75] = -2, -+ [0][1][2][1][RTW89_WW][1][75] = -2, -+ [0][1][2][1][RTW89_WW][2][75] = 68, -+ [0][1][2][1][RTW89_WW][0][77] = -2, -+ [0][1][2][1][RTW89_WW][1][77] = -2, -+ [0][1][2][1][RTW89_WW][2][77] = 68, -+ [0][1][2][1][RTW89_WW][0][79] = -2, -+ [0][1][2][1][RTW89_WW][1][79] = -2, -+ [0][1][2][1][RTW89_WW][2][79] = 68, -+ [0][1][2][1][RTW89_WW][0][81] = -2, -+ [0][1][2][1][RTW89_WW][1][81] = -2, -+ [0][1][2][1][RTW89_WW][2][81] = 68, -+ [0][1][2][1][RTW89_WW][0][83] = -2, -+ [0][1][2][1][RTW89_WW][1][83] = -2, -+ [0][1][2][1][RTW89_WW][2][83] = 68, -+ [0][1][2][1][RTW89_WW][0][85] = -2, -+ [0][1][2][1][RTW89_WW][1][85] = -2, -+ [0][1][2][1][RTW89_WW][2][85] = 68, -+ [0][1][2][1][RTW89_WW][0][87] = -2, -+ [0][1][2][1][RTW89_WW][1][87] = -2, -+ [0][1][2][1][RTW89_WW][2][87] = 0, -+ [0][1][2][1][RTW89_WW][0][89] = -2, -+ [0][1][2][1][RTW89_WW][1][89] = -2, -+ [0][1][2][1][RTW89_WW][2][89] = 0, -+ [0][1][2][1][RTW89_WW][0][90] = -2, -+ [0][1][2][1][RTW89_WW][1][90] = -2, -+ [0][1][2][1][RTW89_WW][2][90] = 0, -+ [0][1][2][1][RTW89_WW][0][92] = -2, -+ [0][1][2][1][RTW89_WW][1][92] = -2, -+ [0][1][2][1][RTW89_WW][2][92] = 0, -+ [0][1][2][1][RTW89_WW][0][94] = -2, -+ [0][1][2][1][RTW89_WW][1][94] = -2, -+ [0][1][2][1][RTW89_WW][2][94] = 0, -+ [0][1][2][1][RTW89_WW][0][96] = -2, -+ [0][1][2][1][RTW89_WW][1][96] = -2, -+ [0][1][2][1][RTW89_WW][2][96] = 0, -+ [0][1][2][1][RTW89_WW][0][98] = -2, -+ [0][1][2][1][RTW89_WW][1][98] = -2, -+ [0][1][2][1][RTW89_WW][2][98] = 0, -+ [0][1][2][1][RTW89_WW][0][100] = -2, -+ [0][1][2][1][RTW89_WW][1][100] = -2, -+ [0][1][2][1][RTW89_WW][2][100] = 0, -+ [0][1][2][1][RTW89_WW][0][102] = -2, -+ [0][1][2][1][RTW89_WW][1][102] = -2, -+ [0][1][2][1][RTW89_WW][2][102] = 0, -+ [0][1][2][1][RTW89_WW][0][104] = -2, -+ [0][1][2][1][RTW89_WW][1][104] = -2, -+ [0][1][2][1][RTW89_WW][2][104] = 0, -+ [0][1][2][1][RTW89_WW][0][105] = -2, -+ [0][1][2][1][RTW89_WW][1][105] = -2, -+ [0][1][2][1][RTW89_WW][2][105] = 0, -+ [0][1][2][1][RTW89_WW][0][107] = 1, -+ [0][1][2][1][RTW89_WW][1][107] = 1, -+ [0][1][2][1][RTW89_WW][2][107] = 0, -+ [0][1][2][1][RTW89_WW][0][109] = 1, -+ [0][1][2][1][RTW89_WW][1][109] = 1, -+ [0][1][2][1][RTW89_WW][2][109] = 0, -+ [0][1][2][1][RTW89_WW][0][111] = 0, -+ [0][1][2][1][RTW89_WW][1][111] = 0, -+ [0][1][2][1][RTW89_WW][2][111] = 0, -+ [0][1][2][1][RTW89_WW][0][113] = 0, -+ [0][1][2][1][RTW89_WW][1][113] = 0, -+ [0][1][2][1][RTW89_WW][2][113] = 0, -+ [0][1][2][1][RTW89_WW][0][115] = 0, -+ [0][1][2][1][RTW89_WW][1][115] = 0, -+ [0][1][2][1][RTW89_WW][2][115] = 0, -+ [0][1][2][1][RTW89_WW][0][117] = 0, -+ [0][1][2][1][RTW89_WW][1][117] = 0, -+ [0][1][2][1][RTW89_WW][2][117] = 0, -+ [0][1][2][1][RTW89_WW][0][119] = 0, -+ [0][1][2][1][RTW89_WW][1][119] = 0, -+ [0][1][2][1][RTW89_WW][2][119] = 0, -+ [1][0][2][0][RTW89_WW][0][1] = 24, -+ [1][0][2][0][RTW89_WW][1][1] = 34, -+ [1][0][2][0][RTW89_WW][2][1] = 70, -+ [1][0][2][0][RTW89_WW][0][5] = 24, -+ [1][0][2][0][RTW89_WW][1][5] = 34, -+ [1][0][2][0][RTW89_WW][2][5] = 70, -+ [1][0][2][0][RTW89_WW][0][9] = 24, -+ [1][0][2][0][RTW89_WW][1][9] = 34, -+ [1][0][2][0][RTW89_WW][2][9] = 70, -+ [1][0][2][0][RTW89_WW][0][13] = 24, -+ [1][0][2][0][RTW89_WW][1][13] = 34, -+ [1][0][2][0][RTW89_WW][2][13] = 70, -+ [1][0][2][0][RTW89_WW][0][16] = 24, -+ [1][0][2][0][RTW89_WW][1][16] = 34, -+ [1][0][2][0][RTW89_WW][2][16] = 70, -+ [1][0][2][0][RTW89_WW][0][20] = 24, -+ [1][0][2][0][RTW89_WW][1][20] = 34, -+ [1][0][2][0][RTW89_WW][2][20] = 70, -+ [1][0][2][0][RTW89_WW][0][24] = 26, -+ [1][0][2][0][RTW89_WW][1][24] = 36, -+ [1][0][2][0][RTW89_WW][2][24] = 70, -+ [1][0][2][0][RTW89_WW][0][28] = 26, -+ [1][0][2][0][RTW89_WW][1][28] = 34, -+ [1][0][2][0][RTW89_WW][2][28] = 70, -+ [1][0][2][0][RTW89_WW][0][31] = 26, -+ [1][0][2][0][RTW89_WW][1][31] = 34, -+ [1][0][2][0][RTW89_WW][2][31] = 70, -+ [1][0][2][0][RTW89_WW][0][35] = 26, -+ [1][0][2][0][RTW89_WW][1][35] = 34, -+ [1][0][2][0][RTW89_WW][2][35] = 70, -+ [1][0][2][0][RTW89_WW][0][39] = 26, -+ [1][0][2][0][RTW89_WW][1][39] = 34, -+ [1][0][2][0][RTW89_WW][2][39] = 70, -+ [1][0][2][0][RTW89_WW][0][43] = 26, -+ [1][0][2][0][RTW89_WW][1][43] = 34, -+ [1][0][2][0][RTW89_WW][2][43] = 70, -+ [1][0][2][0][RTW89_WW][0][46] = 34, -+ [1][0][2][0][RTW89_WW][1][46] = 34, -+ [1][0][2][0][RTW89_WW][2][46] = 0, -+ [1][0][2][0][RTW89_WW][0][50] = 34, -+ [1][0][2][0][RTW89_WW][1][50] = 34, -+ [1][0][2][0][RTW89_WW][2][50] = 0, -+ [1][0][2][0][RTW89_WW][0][54] = 36, -+ [1][0][2][0][RTW89_WW][1][54] = 36, -+ [1][0][2][0][RTW89_WW][2][54] = 0, -+ [1][0][2][0][RTW89_WW][0][58] = 36, -+ [1][0][2][0][RTW89_WW][1][58] = 36, -+ [1][0][2][0][RTW89_WW][2][58] = 66, -+ [1][0][2][0][RTW89_WW][0][61] = 34, -+ [1][0][2][0][RTW89_WW][1][61] = 34, -+ [1][0][2][0][RTW89_WW][2][61] = 66, -+ [1][0][2][0][RTW89_WW][0][65] = 34, -+ [1][0][2][0][RTW89_WW][1][65] = 34, -+ [1][0][2][0][RTW89_WW][2][65] = 66, -+ [1][0][2][0][RTW89_WW][0][69] = 34, -+ [1][0][2][0][RTW89_WW][1][69] = 34, -+ [1][0][2][0][RTW89_WW][2][69] = 66, -+ [1][0][2][0][RTW89_WW][0][73] = 34, -+ [1][0][2][0][RTW89_WW][1][73] = 34, -+ [1][0][2][0][RTW89_WW][2][73] = 66, -+ [1][0][2][0][RTW89_WW][0][76] = 34, -+ [1][0][2][0][RTW89_WW][1][76] = 34, -+ [1][0][2][0][RTW89_WW][2][76] = 66, -+ [1][0][2][0][RTW89_WW][0][80] = 34, -+ [1][0][2][0][RTW89_WW][1][80] = 34, -+ [1][0][2][0][RTW89_WW][2][80] = 66, -+ [1][0][2][0][RTW89_WW][0][84] = 34, -+ [1][0][2][0][RTW89_WW][1][84] = 34, -+ [1][0][2][0][RTW89_WW][2][84] = 66, -+ [1][0][2][0][RTW89_WW][0][88] = 34, -+ [1][0][2][0][RTW89_WW][1][88] = 34, -+ [1][0][2][0][RTW89_WW][2][88] = 0, -+ [1][0][2][0][RTW89_WW][0][91] = 36, -+ [1][0][2][0][RTW89_WW][1][91] = 36, -+ [1][0][2][0][RTW89_WW][2][91] = 0, -+ [1][0][2][0][RTW89_WW][0][95] = 34, -+ [1][0][2][0][RTW89_WW][1][95] = 34, -+ [1][0][2][0][RTW89_WW][2][95] = 0, -+ [1][0][2][0][RTW89_WW][0][99] = 34, -+ [1][0][2][0][RTW89_WW][1][99] = 34, -+ [1][0][2][0][RTW89_WW][2][99] = 0, -+ [1][0][2][0][RTW89_WW][0][103] = 34, -+ [1][0][2][0][RTW89_WW][1][103] = 34, -+ [1][0][2][0][RTW89_WW][2][103] = 0, -+ [1][0][2][0][RTW89_WW][0][106] = 36, -+ [1][0][2][0][RTW89_WW][1][106] = 36, -+ [1][0][2][0][RTW89_WW][2][106] = 0, -+ [1][0][2][0][RTW89_WW][0][110] = 0, -+ [1][0][2][0][RTW89_WW][1][110] = 0, -+ [1][0][2][0][RTW89_WW][2][110] = 0, -+ [1][0][2][0][RTW89_WW][0][114] = 0, -+ [1][0][2][0][RTW89_WW][1][114] = 0, -+ [1][0][2][0][RTW89_WW][2][114] = 0, -+ [1][0][2][0][RTW89_WW][0][118] = 0, -+ [1][0][2][0][RTW89_WW][1][118] = 0, -+ [1][0][2][0][RTW89_WW][2][118] = 0, -+ [1][1][2][0][RTW89_WW][0][1] = 10, -+ [1][1][2][0][RTW89_WW][1][1] = 10, -+ [1][1][2][0][RTW89_WW][2][1] = 58, -+ [1][1][2][0][RTW89_WW][0][5] = 10, -+ [1][1][2][0][RTW89_WW][1][5] = 10, -+ [1][1][2][0][RTW89_WW][2][5] = 58, -+ [1][1][2][0][RTW89_WW][0][9] = 10, -+ [1][1][2][0][RTW89_WW][1][9] = 10, -+ [1][1][2][0][RTW89_WW][2][9] = 58, -+ [1][1][2][0][RTW89_WW][0][13] = 10, -+ [1][1][2][0][RTW89_WW][1][13] = 10, -+ [1][1][2][0][RTW89_WW][2][13] = 58, -+ [1][1][2][0][RTW89_WW][0][16] = 10, -+ [1][1][2][0][RTW89_WW][1][16] = 10, -+ [1][1][2][0][RTW89_WW][2][16] = 58, -+ [1][1][2][0][RTW89_WW][0][20] = 10, -+ [1][1][2][0][RTW89_WW][1][20] = 10, -+ [1][1][2][0][RTW89_WW][2][20] = 58, -+ [1][1][2][0][RTW89_WW][0][24] = 10, -+ [1][1][2][0][RTW89_WW][1][24] = 10, -+ [1][1][2][0][RTW89_WW][2][24] = 70, -+ [1][1][2][0][RTW89_WW][0][28] = 10, -+ [1][1][2][0][RTW89_WW][1][28] = 10, -+ [1][1][2][0][RTW89_WW][2][28] = 70, -+ [1][1][2][0][RTW89_WW][0][31] = 10, -+ [1][1][2][0][RTW89_WW][1][31] = 10, -+ [1][1][2][0][RTW89_WW][2][31] = 70, -+ [1][1][2][0][RTW89_WW][0][35] = 10, -+ [1][1][2][0][RTW89_WW][1][35] = 10, -+ [1][1][2][0][RTW89_WW][2][35] = 70, -+ [1][1][2][0][RTW89_WW][0][39] = 10, -+ [1][1][2][0][RTW89_WW][1][39] = 10, -+ [1][1][2][0][RTW89_WW][2][39] = 70, -+ [1][1][2][0][RTW89_WW][0][43] = 10, -+ [1][1][2][0][RTW89_WW][1][43] = 10, -+ [1][1][2][0][RTW89_WW][2][43] = 70, -+ [1][1][2][0][RTW89_WW][0][46] = 12, -+ [1][1][2][0][RTW89_WW][1][46] = 12, -+ [1][1][2][0][RTW89_WW][2][46] = 0, -+ [1][1][2][0][RTW89_WW][0][50] = 12, -+ [1][1][2][0][RTW89_WW][1][50] = 12, -+ [1][1][2][0][RTW89_WW][2][50] = 0, -+ [1][1][2][0][RTW89_WW][0][54] = 10, -+ [1][1][2][0][RTW89_WW][1][54] = 10, -+ [1][1][2][0][RTW89_WW][2][54] = 0, -+ [1][1][2][0][RTW89_WW][0][58] = 10, -+ [1][1][2][0][RTW89_WW][1][58] = 10, -+ [1][1][2][0][RTW89_WW][2][58] = 66, -+ [1][1][2][0][RTW89_WW][0][61] = 10, -+ [1][1][2][0][RTW89_WW][1][61] = 10, -+ [1][1][2][0][RTW89_WW][2][61] = 66, -+ [1][1][2][0][RTW89_WW][0][65] = 10, -+ [1][1][2][0][RTW89_WW][1][65] = 10, -+ [1][1][2][0][RTW89_WW][2][65] = 66, -+ [1][1][2][0][RTW89_WW][0][69] = 10, -+ [1][1][2][0][RTW89_WW][1][69] = 10, -+ [1][1][2][0][RTW89_WW][2][69] = 66, -+ [1][1][2][0][RTW89_WW][0][73] = 10, -+ [1][1][2][0][RTW89_WW][1][73] = 10, -+ [1][1][2][0][RTW89_WW][2][73] = 66, -+ [1][1][2][0][RTW89_WW][0][76] = 10, -+ [1][1][2][0][RTW89_WW][1][76] = 10, -+ [1][1][2][0][RTW89_WW][2][76] = 66, -+ [1][1][2][0][RTW89_WW][0][80] = 10, -+ [1][1][2][0][RTW89_WW][1][80] = 10, -+ [1][1][2][0][RTW89_WW][2][80] = 66, -+ [1][1][2][0][RTW89_WW][0][84] = 10, -+ [1][1][2][0][RTW89_WW][1][84] = 10, -+ [1][1][2][0][RTW89_WW][2][84] = 66, -+ [1][1][2][0][RTW89_WW][0][88] = 10, -+ [1][1][2][0][RTW89_WW][1][88] = 10, -+ [1][1][2][0][RTW89_WW][2][88] = 0, -+ [1][1][2][0][RTW89_WW][0][91] = 12, -+ [1][1][2][0][RTW89_WW][1][91] = 12, -+ [1][1][2][0][RTW89_WW][2][91] = 0, -+ [1][1][2][0][RTW89_WW][0][95] = 10, -+ [1][1][2][0][RTW89_WW][1][95] = 10, -+ [1][1][2][0][RTW89_WW][2][95] = 0, -+ [1][1][2][0][RTW89_WW][0][99] = 10, -+ [1][1][2][0][RTW89_WW][1][99] = 10, -+ [1][1][2][0][RTW89_WW][2][99] = 0, -+ [1][1][2][0][RTW89_WW][0][103] = 10, -+ [1][1][2][0][RTW89_WW][1][103] = 10, -+ [1][1][2][0][RTW89_WW][2][103] = 0, -+ [1][1][2][0][RTW89_WW][0][106] = 12, -+ [1][1][2][0][RTW89_WW][1][106] = 12, -+ [1][1][2][0][RTW89_WW][2][106] = 0, -+ [1][1][2][0][RTW89_WW][0][110] = 0, -+ [1][1][2][0][RTW89_WW][1][110] = 0, -+ [1][1][2][0][RTW89_WW][2][110] = 0, -+ [1][1][2][0][RTW89_WW][0][114] = 0, -+ [1][1][2][0][RTW89_WW][1][114] = 0, -+ [1][1][2][0][RTW89_WW][2][114] = 0, -+ [1][1][2][0][RTW89_WW][0][118] = 0, -+ [1][1][2][0][RTW89_WW][1][118] = 0, -+ [1][1][2][0][RTW89_WW][2][118] = 0, -+ [1][1][2][1][RTW89_WW][0][1] = 6, -+ [1][1][2][1][RTW89_WW][1][1] = 10, -+ [1][1][2][1][RTW89_WW][2][1] = 58, -+ [1][1][2][1][RTW89_WW][0][5] = 6, -+ [1][1][2][1][RTW89_WW][1][5] = 10, -+ [1][1][2][1][RTW89_WW][2][5] = 58, -+ [1][1][2][1][RTW89_WW][0][9] = 6, -+ [1][1][2][1][RTW89_WW][1][9] = 10, -+ [1][1][2][1][RTW89_WW][2][9] = 58, -+ [1][1][2][1][RTW89_WW][0][13] = 6, -+ [1][1][2][1][RTW89_WW][1][13] = 10, -+ [1][1][2][1][RTW89_WW][2][13] = 58, -+ [1][1][2][1][RTW89_WW][0][16] = 6, -+ [1][1][2][1][RTW89_WW][1][16] = 10, -+ [1][1][2][1][RTW89_WW][2][16] = 58, -+ [1][1][2][1][RTW89_WW][0][20] = 6, -+ [1][1][2][1][RTW89_WW][1][20] = 10, -+ [1][1][2][1][RTW89_WW][2][20] = 58, -+ [1][1][2][1][RTW89_WW][0][24] = 6, -+ [1][1][2][1][RTW89_WW][1][24] = 10, -+ [1][1][2][1][RTW89_WW][2][24] = 70, -+ [1][1][2][1][RTW89_WW][0][28] = 6, -+ [1][1][2][1][RTW89_WW][1][28] = 10, -+ [1][1][2][1][RTW89_WW][2][28] = 70, -+ [1][1][2][1][RTW89_WW][0][31] = 6, -+ [1][1][2][1][RTW89_WW][1][31] = 10, -+ [1][1][2][1][RTW89_WW][2][31] = 70, -+ [1][1][2][1][RTW89_WW][0][35] = 6, -+ [1][1][2][1][RTW89_WW][1][35] = 10, -+ [1][1][2][1][RTW89_WW][2][35] = 70, -+ [1][1][2][1][RTW89_WW][0][39] = 6, -+ [1][1][2][1][RTW89_WW][1][39] = 10, -+ [1][1][2][1][RTW89_WW][2][39] = 70, -+ [1][1][2][1][RTW89_WW][0][43] = 6, -+ [1][1][2][1][RTW89_WW][1][43] = 10, -+ [1][1][2][1][RTW89_WW][2][43] = 70, -+ [1][1][2][1][RTW89_WW][0][46] = 12, -+ [1][1][2][1][RTW89_WW][1][46] = 12, -+ [1][1][2][1][RTW89_WW][2][46] = 0, -+ [1][1][2][1][RTW89_WW][0][50] = 12, -+ [1][1][2][1][RTW89_WW][1][50] = 12, -+ [1][1][2][1][RTW89_WW][2][50] = 0, -+ [1][1][2][1][RTW89_WW][0][54] = 10, -+ [1][1][2][1][RTW89_WW][1][54] = 10, -+ [1][1][2][1][RTW89_WW][2][54] = 0, -+ [1][1][2][1][RTW89_WW][0][58] = 10, -+ [1][1][2][1][RTW89_WW][1][58] = 10, -+ [1][1][2][1][RTW89_WW][2][58] = 66, -+ [1][1][2][1][RTW89_WW][0][61] = 10, -+ [1][1][2][1][RTW89_WW][1][61] = 10, -+ [1][1][2][1][RTW89_WW][2][61] = 66, -+ [1][1][2][1][RTW89_WW][0][65] = 10, -+ [1][1][2][1][RTW89_WW][1][65] = 10, -+ [1][1][2][1][RTW89_WW][2][65] = 66, -+ [1][1][2][1][RTW89_WW][0][69] = 10, -+ [1][1][2][1][RTW89_WW][1][69] = 10, -+ [1][1][2][1][RTW89_WW][2][69] = 66, -+ [1][1][2][1][RTW89_WW][0][73] = 10, -+ [1][1][2][1][RTW89_WW][1][73] = 10, -+ [1][1][2][1][RTW89_WW][2][73] = 66, -+ [1][1][2][1][RTW89_WW][0][76] = 10, -+ [1][1][2][1][RTW89_WW][1][76] = 10, -+ [1][1][2][1][RTW89_WW][2][76] = 66, -+ [1][1][2][1][RTW89_WW][0][80] = 10, -+ [1][1][2][1][RTW89_WW][1][80] = 10, -+ [1][1][2][1][RTW89_WW][2][80] = 66, -+ [1][1][2][1][RTW89_WW][0][84] = 10, -+ [1][1][2][1][RTW89_WW][1][84] = 10, -+ [1][1][2][1][RTW89_WW][2][84] = 66, -+ [1][1][2][1][RTW89_WW][0][88] = 10, -+ [1][1][2][1][RTW89_WW][1][88] = 10, -+ [1][1][2][1][RTW89_WW][2][88] = 0, -+ [1][1][2][1][RTW89_WW][0][91] = 12, -+ [1][1][2][1][RTW89_WW][1][91] = 12, -+ [1][1][2][1][RTW89_WW][2][91] = 0, -+ [1][1][2][1][RTW89_WW][0][95] = 10, -+ [1][1][2][1][RTW89_WW][1][95] = 10, -+ [1][1][2][1][RTW89_WW][2][95] = 0, -+ [1][1][2][1][RTW89_WW][0][99] = 10, -+ [1][1][2][1][RTW89_WW][1][99] = 10, -+ [1][1][2][1][RTW89_WW][2][99] = 0, -+ [1][1][2][1][RTW89_WW][0][103] = 10, -+ [1][1][2][1][RTW89_WW][1][103] = 10, -+ [1][1][2][1][RTW89_WW][2][103] = 0, -+ [1][1][2][1][RTW89_WW][0][106] = 12, -+ [1][1][2][1][RTW89_WW][1][106] = 12, -+ [1][1][2][1][RTW89_WW][2][106] = 0, -+ [1][1][2][1][RTW89_WW][0][110] = 0, -+ [1][1][2][1][RTW89_WW][1][110] = 0, -+ [1][1][2][1][RTW89_WW][2][110] = 0, -+ [1][1][2][1][RTW89_WW][0][114] = 0, -+ [1][1][2][1][RTW89_WW][1][114] = 0, -+ [1][1][2][1][RTW89_WW][2][114] = 0, -+ [1][1][2][1][RTW89_WW][0][118] = 0, -+ [1][1][2][1][RTW89_WW][1][118] = 0, -+ [1][1][2][1][RTW89_WW][2][118] = 0, -+ [2][0][2][0][RTW89_WW][0][3] = 24, -+ [2][0][2][0][RTW89_WW][1][3] = 46, -+ [2][0][2][0][RTW89_WW][2][3] = 60, -+ [2][0][2][0][RTW89_WW][0][11] = 24, -+ [2][0][2][0][RTW89_WW][1][11] = 46, -+ [2][0][2][0][RTW89_WW][2][11] = 60, -+ [2][0][2][0][RTW89_WW][0][18] = 24, -+ [2][0][2][0][RTW89_WW][1][18] = 46, -+ [2][0][2][0][RTW89_WW][2][18] = 60, -+ [2][0][2][0][RTW89_WW][0][26] = 24, -+ [2][0][2][0][RTW89_WW][1][26] = 46, -+ [2][0][2][0][RTW89_WW][2][26] = 60, -+ [2][0][2][0][RTW89_WW][0][33] = 24, -+ [2][0][2][0][RTW89_WW][1][33] = 46, -+ [2][0][2][0][RTW89_WW][2][33] = 60, -+ [2][0][2][0][RTW89_WW][0][41] = 24, -+ [2][0][2][0][RTW89_WW][1][41] = 46, -+ [2][0][2][0][RTW89_WW][2][41] = 60, -+ [2][0][2][0][RTW89_WW][0][48] = 46, -+ [2][0][2][0][RTW89_WW][1][48] = 46, -+ [2][0][2][0][RTW89_WW][2][48] = 0, -+ [2][0][2][0][RTW89_WW][0][56] = 46, -+ [2][0][2][0][RTW89_WW][1][56] = 46, -+ [2][0][2][0][RTW89_WW][2][56] = 0, -+ [2][0][2][0][RTW89_WW][0][63] = 46, -+ [2][0][2][0][RTW89_WW][1][63] = 46, -+ [2][0][2][0][RTW89_WW][2][63] = 58, -+ [2][0][2][0][RTW89_WW][0][71] = 46, -+ [2][0][2][0][RTW89_WW][1][71] = 46, -+ [2][0][2][0][RTW89_WW][2][71] = 58, -+ [2][0][2][0][RTW89_WW][0][78] = 46, -+ [2][0][2][0][RTW89_WW][1][78] = 46, -+ [2][0][2][0][RTW89_WW][2][78] = 58, -+ [2][0][2][0][RTW89_WW][0][86] = 46, -+ [2][0][2][0][RTW89_WW][1][86] = 46, -+ [2][0][2][0][RTW89_WW][2][86] = 0, -+ [2][0][2][0][RTW89_WW][0][93] = 46, -+ [2][0][2][0][RTW89_WW][1][93] = 46, -+ [2][0][2][0][RTW89_WW][2][93] = 0, -+ [2][0][2][0][RTW89_WW][0][101] = 44, -+ [2][0][2][0][RTW89_WW][1][101] = 44, -+ [2][0][2][0][RTW89_WW][2][101] = 0, -+ [2][0][2][0][RTW89_WW][0][108] = 0, -+ [2][0][2][0][RTW89_WW][1][108] = 0, -+ [2][0][2][0][RTW89_WW][2][108] = 0, -+ [2][0][2][0][RTW89_WW][0][116] = 0, -+ [2][0][2][0][RTW89_WW][1][116] = 0, -+ [2][0][2][0][RTW89_WW][2][116] = 0, -+ [2][1][2][0][RTW89_WW][0][3] = 12, -+ [2][1][2][0][RTW89_WW][1][3] = 22, -+ [2][1][2][0][RTW89_WW][2][3] = 50, -+ [2][1][2][0][RTW89_WW][0][11] = 12, -+ [2][1][2][0][RTW89_WW][1][11] = 20, -+ [2][1][2][0][RTW89_WW][2][11] = 50, -+ [2][1][2][0][RTW89_WW][0][18] = 12, -+ [2][1][2][0][RTW89_WW][1][18] = 20, -+ [2][1][2][0][RTW89_WW][2][18] = 50, -+ [2][1][2][0][RTW89_WW][0][26] = 12, -+ [2][1][2][0][RTW89_WW][1][26] = 20, -+ [2][1][2][0][RTW89_WW][2][26] = 60, -+ [2][1][2][0][RTW89_WW][0][33] = 12, -+ [2][1][2][0][RTW89_WW][1][33] = 20, -+ [2][1][2][0][RTW89_WW][2][33] = 60, -+ [2][1][2][0][RTW89_WW][0][41] = 12, -+ [2][1][2][0][RTW89_WW][1][41] = 22, -+ [2][1][2][0][RTW89_WW][2][41] = 60, -+ [2][1][2][0][RTW89_WW][0][48] = 22, -+ [2][1][2][0][RTW89_WW][1][48] = 22, -+ [2][1][2][0][RTW89_WW][2][48] = 0, -+ [2][1][2][0][RTW89_WW][0][56] = 20, -+ [2][1][2][0][RTW89_WW][1][56] = 20, -+ [2][1][2][0][RTW89_WW][2][56] = 0, -+ [2][1][2][0][RTW89_WW][0][63] = 22, -+ [2][1][2][0][RTW89_WW][1][63] = 22, -+ [2][1][2][0][RTW89_WW][2][63] = 58, -+ [2][1][2][0][RTW89_WW][0][71] = 20, -+ [2][1][2][0][RTW89_WW][1][71] = 20, -+ [2][1][2][0][RTW89_WW][2][71] = 58, -+ [2][1][2][0][RTW89_WW][0][78] = 20, -+ [2][1][2][0][RTW89_WW][1][78] = 20, -+ [2][1][2][0][RTW89_WW][2][78] = 58, -+ [2][1][2][0][RTW89_WW][0][86] = 20, -+ [2][1][2][0][RTW89_WW][1][86] = 20, -+ [2][1][2][0][RTW89_WW][2][86] = 0, -+ [2][1][2][0][RTW89_WW][0][93] = 22, -+ [2][1][2][0][RTW89_WW][1][93] = 22, -+ [2][1][2][0][RTW89_WW][2][93] = 0, -+ [2][1][2][0][RTW89_WW][0][101] = 22, -+ [2][1][2][0][RTW89_WW][1][101] = 22, -+ [2][1][2][0][RTW89_WW][2][101] = 0, -+ [2][1][2][0][RTW89_WW][0][108] = 0, -+ [2][1][2][0][RTW89_WW][1][108] = 0, -+ [2][1][2][0][RTW89_WW][2][108] = 0, -+ [2][1][2][0][RTW89_WW][0][116] = 0, -+ [2][1][2][0][RTW89_WW][1][116] = 0, -+ [2][1][2][0][RTW89_WW][2][116] = 0, -+ [2][1][2][1][RTW89_WW][0][3] = 6, -+ [2][1][2][1][RTW89_WW][1][3] = 22, -+ [2][1][2][1][RTW89_WW][2][3] = 50, -+ [2][1][2][1][RTW89_WW][0][11] = 6, -+ [2][1][2][1][RTW89_WW][1][11] = 20, -+ [2][1][2][1][RTW89_WW][2][11] = 50, -+ [2][1][2][1][RTW89_WW][0][18] = 6, -+ [2][1][2][1][RTW89_WW][1][18] = 20, -+ [2][1][2][1][RTW89_WW][2][18] = 50, -+ [2][1][2][1][RTW89_WW][0][26] = 6, -+ [2][1][2][1][RTW89_WW][1][26] = 20, -+ [2][1][2][1][RTW89_WW][2][26] = 60, -+ [2][1][2][1][RTW89_WW][0][33] = 6, -+ [2][1][2][1][RTW89_WW][1][33] = 20, -+ [2][1][2][1][RTW89_WW][2][33] = 60, -+ [2][1][2][1][RTW89_WW][0][41] = 6, -+ [2][1][2][1][RTW89_WW][1][41] = 22, -+ [2][1][2][1][RTW89_WW][2][41] = 60, -+ [2][1][2][1][RTW89_WW][0][48] = 22, -+ [2][1][2][1][RTW89_WW][1][48] = 22, -+ [2][1][2][1][RTW89_WW][2][48] = 0, -+ [2][1][2][1][RTW89_WW][0][56] = 20, -+ [2][1][2][1][RTW89_WW][1][56] = 20, -+ [2][1][2][1][RTW89_WW][2][56] = 0, -+ [2][1][2][1][RTW89_WW][0][63] = 22, -+ [2][1][2][1][RTW89_WW][1][63] = 22, -+ [2][1][2][1][RTW89_WW][2][63] = 58, -+ [2][1][2][1][RTW89_WW][0][71] = 20, -+ [2][1][2][1][RTW89_WW][1][71] = 20, -+ [2][1][2][1][RTW89_WW][2][71] = 58, -+ [2][1][2][1][RTW89_WW][0][78] = 20, -+ [2][1][2][1][RTW89_WW][1][78] = 20, -+ [2][1][2][1][RTW89_WW][2][78] = 58, -+ [2][1][2][1][RTW89_WW][0][86] = 20, -+ [2][1][2][1][RTW89_WW][1][86] = 20, -+ [2][1][2][1][RTW89_WW][2][86] = 0, -+ [2][1][2][1][RTW89_WW][0][93] = 22, -+ [2][1][2][1][RTW89_WW][1][93] = 22, -+ [2][1][2][1][RTW89_WW][2][93] = 0, -+ [2][1][2][1][RTW89_WW][0][101] = 22, -+ [2][1][2][1][RTW89_WW][1][101] = 22, -+ [2][1][2][1][RTW89_WW][2][101] = 0, -+ [2][1][2][1][RTW89_WW][0][108] = 0, -+ [2][1][2][1][RTW89_WW][1][108] = 0, -+ [2][1][2][1][RTW89_WW][2][108] = 0, -+ [2][1][2][1][RTW89_WW][0][116] = 0, -+ [2][1][2][1][RTW89_WW][1][116] = 0, -+ [2][1][2][1][RTW89_WW][2][116] = 0, -+ [3][0][2][0][RTW89_WW][0][7] = 22, -+ [3][0][2][0][RTW89_WW][1][7] = 42, -+ [3][0][2][0][RTW89_WW][2][7] = 52, -+ [3][0][2][0][RTW89_WW][0][22] = 20, -+ [3][0][2][0][RTW89_WW][1][22] = 42, -+ [3][0][2][0][RTW89_WW][2][22] = 52, -+ [3][0][2][0][RTW89_WW][0][37] = 20, -+ [3][0][2][0][RTW89_WW][1][37] = 42, -+ [3][0][2][0][RTW89_WW][2][37] = 52, -+ [3][0][2][0][RTW89_WW][0][52] = 54, -+ [3][0][2][0][RTW89_WW][1][52] = 54, -+ [3][0][2][0][RTW89_WW][2][52] = 0, -+ [3][0][2][0][RTW89_WW][0][67] = 54, -+ [3][0][2][0][RTW89_WW][1][67] = 54, -+ [3][0][2][0][RTW89_WW][2][67] = 54, -+ [3][0][2][0][RTW89_WW][0][82] = 26, -+ [3][0][2][0][RTW89_WW][1][82] = 26, -+ [3][0][2][0][RTW89_WW][2][82] = 0, -+ [3][0][2][0][RTW89_WW][0][97] = 26, -+ [3][0][2][0][RTW89_WW][1][97] = 26, -+ [3][0][2][0][RTW89_WW][2][97] = 0, -+ [3][0][2][0][RTW89_WW][0][112] = 0, -+ [3][0][2][0][RTW89_WW][1][112] = 0, -+ [3][0][2][0][RTW89_WW][2][112] = 0, -+ [3][1][2][0][RTW89_WW][0][7] = 10, -+ [3][1][2][0][RTW89_WW][1][7] = 32, -+ [3][1][2][0][RTW89_WW][2][7] = 46, -+ [3][1][2][0][RTW89_WW][0][22] = 8, -+ [3][1][2][0][RTW89_WW][1][22] = 30, -+ [3][1][2][0][RTW89_WW][2][22] = 52, -+ [3][1][2][0][RTW89_WW][0][37] = 8, -+ [3][1][2][0][RTW89_WW][1][37] = 30, -+ [3][1][2][0][RTW89_WW][2][37] = 52, -+ [3][1][2][0][RTW89_WW][0][52] = 30, -+ [3][1][2][0][RTW89_WW][1][52] = 30, -+ [3][1][2][0][RTW89_WW][2][52] = 0, -+ [3][1][2][0][RTW89_WW][0][67] = 32, -+ [3][1][2][0][RTW89_WW][1][67] = 32, -+ [3][1][2][0][RTW89_WW][2][67] = 54, -+ [3][1][2][0][RTW89_WW][0][82] = 24, -+ [3][1][2][0][RTW89_WW][1][82] = 24, -+ [3][1][2][0][RTW89_WW][2][82] = 0, -+ [3][1][2][0][RTW89_WW][0][97] = 24, -+ [3][1][2][0][RTW89_WW][1][97] = 24, -+ [3][1][2][0][RTW89_WW][2][97] = 0, -+ [3][1][2][0][RTW89_WW][0][112] = 0, -+ [3][1][2][0][RTW89_WW][1][112] = 0, -+ [3][1][2][0][RTW89_WW][2][112] = 0, -+ [3][1][2][1][RTW89_WW][0][7] = 6, -+ [3][1][2][1][RTW89_WW][1][7] = 32, -+ [3][1][2][1][RTW89_WW][2][7] = 46, -+ [3][1][2][1][RTW89_WW][0][22] = 6, -+ [3][1][2][1][RTW89_WW][1][22] = 30, -+ [3][1][2][1][RTW89_WW][2][22] = 52, -+ [3][1][2][1][RTW89_WW][0][37] = 6, -+ [3][1][2][1][RTW89_WW][1][37] = 30, -+ [3][1][2][1][RTW89_WW][2][37] = 52, -+ [3][1][2][1][RTW89_WW][0][52] = 30, -+ [3][1][2][1][RTW89_WW][1][52] = 30, -+ [3][1][2][1][RTW89_WW][2][52] = 0, -+ [3][1][2][1][RTW89_WW][0][67] = 32, -+ [3][1][2][1][RTW89_WW][1][67] = 32, -+ [3][1][2][1][RTW89_WW][2][67] = 54, -+ [3][1][2][1][RTW89_WW][0][82] = 24, -+ [3][1][2][1][RTW89_WW][1][82] = 24, -+ [3][1][2][1][RTW89_WW][2][82] = 0, -+ [3][1][2][1][RTW89_WW][0][97] = 24, -+ [3][1][2][1][RTW89_WW][1][97] = 24, -+ [3][1][2][1][RTW89_WW][2][97] = 0, -+ [3][1][2][1][RTW89_WW][0][112] = 0, -+ [3][1][2][1][RTW89_WW][1][112] = 0, -+ [3][1][2][1][RTW89_WW][2][112] = 0, -+ [0][0][1][0][RTW89_FCC][1][0] = 24, -+ [0][0][1][0][RTW89_FCC][2][0] = 56, -+ [0][0][1][0][RTW89_ETSI][1][0] = 66, -+ [0][0][1][0][RTW89_ETSI][0][0] = 28, -+ [0][0][1][0][RTW89_MKK][1][0] = 66, -+ [0][0][1][0][RTW89_MKK][0][0] = 26, -+ [0][0][1][0][RTW89_IC][1][0] = 24, -+ [0][0][1][0][RTW89_KCC][1][0] = 24, -+ [0][0][1][0][RTW89_KCC][0][0] = 24, -+ [0][0][1][0][RTW89_ACMA][1][0] = 66, -+ [0][0][1][0][RTW89_ACMA][0][0] = 28, -+ [0][0][1][0][RTW89_CHILE][1][0] = 24, -+ [0][0][1][0][RTW89_QATAR][1][0] = 66, -+ [0][0][1][0][RTW89_QATAR][0][0] = 28, -+ [0][0][1][0][RTW89_UK][1][0] = 66, -+ [0][0][1][0][RTW89_UK][0][0] = 28, -+ [0][0][1][0][RTW89_FCC][1][2] = 22, -+ [0][0][1][0][RTW89_FCC][2][2] = 56, -+ [0][0][1][0][RTW89_ETSI][1][2] = 66, -+ [0][0][1][0][RTW89_ETSI][0][2] = 28, -+ [0][0][1][0][RTW89_MKK][1][2] = 66, -+ [0][0][1][0][RTW89_MKK][0][2] = 26, -+ [0][0][1][0][RTW89_IC][1][2] = 22, -+ [0][0][1][0][RTW89_KCC][1][2] = 24, -+ [0][0][1][0][RTW89_KCC][0][2] = 24, -+ [0][0][1][0][RTW89_ACMA][1][2] = 66, -+ [0][0][1][0][RTW89_ACMA][0][2] = 28, -+ [0][0][1][0][RTW89_CHILE][1][2] = 22, -+ [0][0][1][0][RTW89_QATAR][1][2] = 66, -+ [0][0][1][0][RTW89_QATAR][0][2] = 28, -+ [0][0][1][0][RTW89_UK][1][2] = 66, -+ [0][0][1][0][RTW89_UK][0][2] = 28, -+ [0][0][1][0][RTW89_FCC][1][4] = 22, -+ [0][0][1][0][RTW89_FCC][2][4] = 56, -+ [0][0][1][0][RTW89_ETSI][1][4] = 66, -+ [0][0][1][0][RTW89_ETSI][0][4] = 28, -+ [0][0][1][0][RTW89_MKK][1][4] = 66, -+ [0][0][1][0][RTW89_MKK][0][4] = 26, -+ [0][0][1][0][RTW89_IC][1][4] = 22, -+ [0][0][1][0][RTW89_KCC][1][4] = 24, -+ [0][0][1][0][RTW89_KCC][0][4] = 24, -+ [0][0][1][0][RTW89_ACMA][1][4] = 66, -+ [0][0][1][0][RTW89_ACMA][0][4] = 28, -+ [0][0][1][0][RTW89_CHILE][1][4] = 22, -+ [0][0][1][0][RTW89_QATAR][1][4] = 66, -+ [0][0][1][0][RTW89_QATAR][0][4] = 28, -+ [0][0][1][0][RTW89_UK][1][4] = 66, -+ [0][0][1][0][RTW89_UK][0][4] = 28, -+ [0][0][1][0][RTW89_FCC][1][6] = 22, -+ [0][0][1][0][RTW89_FCC][2][6] = 56, -+ [0][0][1][0][RTW89_ETSI][1][6] = 66, -+ [0][0][1][0][RTW89_ETSI][0][6] = 28, -+ [0][0][1][0][RTW89_MKK][1][6] = 66, -+ [0][0][1][0][RTW89_MKK][0][6] = 26, -+ [0][0][1][0][RTW89_IC][1][6] = 22, -+ [0][0][1][0][RTW89_KCC][1][6] = 24, -+ [0][0][1][0][RTW89_KCC][0][6] = 24, -+ [0][0][1][0][RTW89_ACMA][1][6] = 66, -+ [0][0][1][0][RTW89_ACMA][0][6] = 28, -+ [0][0][1][0][RTW89_CHILE][1][6] = 22, -+ [0][0][1][0][RTW89_QATAR][1][6] = 66, -+ [0][0][1][0][RTW89_QATAR][0][6] = 28, -+ [0][0][1][0][RTW89_UK][1][6] = 66, -+ [0][0][1][0][RTW89_UK][0][6] = 28, -+ [0][0][1][0][RTW89_FCC][1][8] = 22, -+ [0][0][1][0][RTW89_FCC][2][8] = 56, -+ [0][0][1][0][RTW89_ETSI][1][8] = 66, -+ [0][0][1][0][RTW89_ETSI][0][8] = 28, -+ [0][0][1][0][RTW89_MKK][1][8] = 66, -+ [0][0][1][0][RTW89_MKK][0][8] = 26, -+ [0][0][1][0][RTW89_IC][1][8] = 22, -+ [0][0][1][0][RTW89_KCC][1][8] = 24, -+ [0][0][1][0][RTW89_KCC][0][8] = 24, -+ [0][0][1][0][RTW89_ACMA][1][8] = 66, -+ [0][0][1][0][RTW89_ACMA][0][8] = 28, -+ [0][0][1][0][RTW89_CHILE][1][8] = 22, -+ [0][0][1][0][RTW89_QATAR][1][8] = 66, -+ [0][0][1][0][RTW89_QATAR][0][8] = 28, -+ [0][0][1][0][RTW89_UK][1][8] = 66, -+ [0][0][1][0][RTW89_UK][0][8] = 28, -+ [0][0][1][0][RTW89_FCC][1][10] = 22, -+ [0][0][1][0][RTW89_FCC][2][10] = 56, -+ [0][0][1][0][RTW89_ETSI][1][10] = 66, -+ [0][0][1][0][RTW89_ETSI][0][10] = 28, -+ [0][0][1][0][RTW89_MKK][1][10] = 66, -+ [0][0][1][0][RTW89_MKK][0][10] = 26, -+ [0][0][1][0][RTW89_IC][1][10] = 22, -+ [0][0][1][0][RTW89_KCC][1][10] = 24, -+ [0][0][1][0][RTW89_KCC][0][10] = 24, -+ [0][0][1][0][RTW89_ACMA][1][10] = 66, -+ [0][0][1][0][RTW89_ACMA][0][10] = 28, -+ [0][0][1][0][RTW89_CHILE][1][10] = 22, -+ [0][0][1][0][RTW89_QATAR][1][10] = 66, -+ [0][0][1][0][RTW89_QATAR][0][10] = 28, -+ [0][0][1][0][RTW89_UK][1][10] = 66, -+ [0][0][1][0][RTW89_UK][0][10] = 28, -+ [0][0][1][0][RTW89_FCC][1][12] = 22, -+ [0][0][1][0][RTW89_FCC][2][12] = 56, -+ [0][0][1][0][RTW89_ETSI][1][12] = 66, -+ [0][0][1][0][RTW89_ETSI][0][12] = 28, -+ [0][0][1][0][RTW89_MKK][1][12] = 66, -+ [0][0][1][0][RTW89_MKK][0][12] = 26, -+ [0][0][1][0][RTW89_IC][1][12] = 22, -+ [0][0][1][0][RTW89_KCC][1][12] = 24, -+ [0][0][1][0][RTW89_KCC][0][12] = 24, -+ [0][0][1][0][RTW89_ACMA][1][12] = 66, -+ [0][0][1][0][RTW89_ACMA][0][12] = 28, -+ [0][0][1][0][RTW89_CHILE][1][12] = 22, -+ [0][0][1][0][RTW89_QATAR][1][12] = 66, -+ [0][0][1][0][RTW89_QATAR][0][12] = 28, -+ [0][0][1][0][RTW89_UK][1][12] = 66, -+ [0][0][1][0][RTW89_UK][0][12] = 28, -+ [0][0][1][0][RTW89_FCC][1][14] = 22, -+ [0][0][1][0][RTW89_FCC][2][14] = 56, -+ [0][0][1][0][RTW89_ETSI][1][14] = 66, -+ [0][0][1][0][RTW89_ETSI][0][14] = 28, -+ [0][0][1][0][RTW89_MKK][1][14] = 66, -+ [0][0][1][0][RTW89_MKK][0][14] = 26, -+ [0][0][1][0][RTW89_IC][1][14] = 22, -+ [0][0][1][0][RTW89_KCC][1][14] = 24, -+ [0][0][1][0][RTW89_KCC][0][14] = 24, -+ [0][0][1][0][RTW89_ACMA][1][14] = 66, -+ [0][0][1][0][RTW89_ACMA][0][14] = 28, -+ [0][0][1][0][RTW89_CHILE][1][14] = 22, -+ [0][0][1][0][RTW89_QATAR][1][14] = 66, -+ [0][0][1][0][RTW89_QATAR][0][14] = 28, -+ [0][0][1][0][RTW89_UK][1][14] = 66, -+ [0][0][1][0][RTW89_UK][0][14] = 28, -+ [0][0][1][0][RTW89_FCC][1][15] = 22, -+ [0][0][1][0][RTW89_FCC][2][15] = 56, -+ [0][0][1][0][RTW89_ETSI][1][15] = 66, -+ [0][0][1][0][RTW89_ETSI][0][15] = 28, -+ [0][0][1][0][RTW89_MKK][1][15] = 66, -+ [0][0][1][0][RTW89_MKK][0][15] = 26, -+ [0][0][1][0][RTW89_IC][1][15] = 22, -+ [0][0][1][0][RTW89_KCC][1][15] = 24, -+ [0][0][1][0][RTW89_KCC][0][15] = 24, -+ [0][0][1][0][RTW89_ACMA][1][15] = 66, -+ [0][0][1][0][RTW89_ACMA][0][15] = 28, -+ [0][0][1][0][RTW89_CHILE][1][15] = 22, -+ [0][0][1][0][RTW89_QATAR][1][15] = 66, -+ [0][0][1][0][RTW89_QATAR][0][15] = 28, -+ [0][0][1][0][RTW89_UK][1][15] = 66, -+ [0][0][1][0][RTW89_UK][0][15] = 28, -+ [0][0][1][0][RTW89_FCC][1][17] = 22, -+ [0][0][1][0][RTW89_FCC][2][17] = 56, -+ [0][0][1][0][RTW89_ETSI][1][17] = 66, -+ [0][0][1][0][RTW89_ETSI][0][17] = 28, -+ [0][0][1][0][RTW89_MKK][1][17] = 66, -+ [0][0][1][0][RTW89_MKK][0][17] = 26, -+ [0][0][1][0][RTW89_IC][1][17] = 22, -+ [0][0][1][0][RTW89_KCC][1][17] = 24, -+ [0][0][1][0][RTW89_KCC][0][17] = 24, -+ [0][0][1][0][RTW89_ACMA][1][17] = 66, -+ [0][0][1][0][RTW89_ACMA][0][17] = 28, -+ [0][0][1][0][RTW89_CHILE][1][17] = 22, -+ [0][0][1][0][RTW89_QATAR][1][17] = 66, -+ [0][0][1][0][RTW89_QATAR][0][17] = 28, -+ [0][0][1][0][RTW89_UK][1][17] = 66, -+ [0][0][1][0][RTW89_UK][0][17] = 28, -+ [0][0][1][0][RTW89_FCC][1][19] = 22, -+ [0][0][1][0][RTW89_FCC][2][19] = 56, -+ [0][0][1][0][RTW89_ETSI][1][19] = 66, -+ [0][0][1][0][RTW89_ETSI][0][19] = 28, -+ [0][0][1][0][RTW89_MKK][1][19] = 66, -+ [0][0][1][0][RTW89_MKK][0][19] = 26, -+ [0][0][1][0][RTW89_IC][1][19] = 22, -+ [0][0][1][0][RTW89_KCC][1][19] = 24, -+ [0][0][1][0][RTW89_KCC][0][19] = 24, -+ [0][0][1][0][RTW89_ACMA][1][19] = 66, -+ [0][0][1][0][RTW89_ACMA][0][19] = 28, -+ [0][0][1][0][RTW89_CHILE][1][19] = 22, -+ [0][0][1][0][RTW89_QATAR][1][19] = 66, -+ [0][0][1][0][RTW89_QATAR][0][19] = 28, -+ [0][0][1][0][RTW89_UK][1][19] = 66, -+ [0][0][1][0][RTW89_UK][0][19] = 28, -+ [0][0][1][0][RTW89_FCC][1][21] = 22, -+ [0][0][1][0][RTW89_FCC][2][21] = 56, -+ [0][0][1][0][RTW89_ETSI][1][21] = 66, -+ [0][0][1][0][RTW89_ETSI][0][21] = 28, -+ [0][0][1][0][RTW89_MKK][1][21] = 66, -+ [0][0][1][0][RTW89_MKK][0][21] = 26, -+ [0][0][1][0][RTW89_IC][1][21] = 22, -+ [0][0][1][0][RTW89_KCC][1][21] = 24, -+ [0][0][1][0][RTW89_KCC][0][21] = 24, -+ [0][0][1][0][RTW89_ACMA][1][21] = 66, -+ [0][0][1][0][RTW89_ACMA][0][21] = 28, -+ [0][0][1][0][RTW89_CHILE][1][21] = 22, -+ [0][0][1][0][RTW89_QATAR][1][21] = 66, -+ [0][0][1][0][RTW89_QATAR][0][21] = 28, -+ [0][0][1][0][RTW89_UK][1][21] = 66, -+ [0][0][1][0][RTW89_UK][0][21] = 28, -+ [0][0][1][0][RTW89_FCC][1][23] = 22, -+ [0][0][1][0][RTW89_FCC][2][23] = 70, -+ [0][0][1][0][RTW89_ETSI][1][23] = 66, -+ [0][0][1][0][RTW89_ETSI][0][23] = 28, -+ [0][0][1][0][RTW89_MKK][1][23] = 66, -+ [0][0][1][0][RTW89_MKK][0][23] = 26, -+ [0][0][1][0][RTW89_IC][1][23] = 22, -+ [0][0][1][0][RTW89_KCC][1][23] = 24, -+ [0][0][1][0][RTW89_KCC][0][23] = 26, -+ [0][0][1][0][RTW89_ACMA][1][23] = 66, -+ [0][0][1][0][RTW89_ACMA][0][23] = 28, -+ [0][0][1][0][RTW89_CHILE][1][23] = 22, -+ [0][0][1][0][RTW89_QATAR][1][23] = 66, -+ [0][0][1][0][RTW89_QATAR][0][23] = 28, -+ [0][0][1][0][RTW89_UK][1][23] = 66, -+ [0][0][1][0][RTW89_UK][0][23] = 28, -+ [0][0][1][0][RTW89_FCC][1][25] = 22, -+ [0][0][1][0][RTW89_FCC][2][25] = 70, -+ [0][0][1][0][RTW89_ETSI][1][25] = 66, -+ [0][0][1][0][RTW89_ETSI][0][25] = 28, -+ [0][0][1][0][RTW89_MKK][1][25] = 66, -+ [0][0][1][0][RTW89_MKK][0][25] = 26, -+ [0][0][1][0][RTW89_IC][1][25] = 22, -+ [0][0][1][0][RTW89_KCC][1][25] = 24, -+ [0][0][1][0][RTW89_KCC][0][25] = 26, -+ [0][0][1][0][RTW89_ACMA][1][25] = 66, -+ [0][0][1][0][RTW89_ACMA][0][25] = 28, -+ [0][0][1][0][RTW89_CHILE][1][25] = 22, -+ [0][0][1][0][RTW89_QATAR][1][25] = 66, -+ [0][0][1][0][RTW89_QATAR][0][25] = 28, -+ [0][0][1][0][RTW89_UK][1][25] = 66, -+ [0][0][1][0][RTW89_UK][0][25] = 28, -+ [0][0][1][0][RTW89_FCC][1][27] = 22, -+ [0][0][1][0][RTW89_FCC][2][27] = 70, -+ [0][0][1][0][RTW89_ETSI][1][27] = 66, -+ [0][0][1][0][RTW89_ETSI][0][27] = 28, -+ [0][0][1][0][RTW89_MKK][1][27] = 66, -+ [0][0][1][0][RTW89_MKK][0][27] = 26, -+ [0][0][1][0][RTW89_IC][1][27] = 22, -+ [0][0][1][0][RTW89_KCC][1][27] = 24, -+ [0][0][1][0][RTW89_KCC][0][27] = 26, -+ [0][0][1][0][RTW89_ACMA][1][27] = 66, -+ [0][0][1][0][RTW89_ACMA][0][27] = 28, -+ [0][0][1][0][RTW89_CHILE][1][27] = 22, -+ [0][0][1][0][RTW89_QATAR][1][27] = 66, -+ [0][0][1][0][RTW89_QATAR][0][27] = 28, -+ [0][0][1][0][RTW89_UK][1][27] = 66, -+ [0][0][1][0][RTW89_UK][0][27] = 28, -+ [0][0][1][0][RTW89_FCC][1][29] = 22, -+ [0][0][1][0][RTW89_FCC][2][29] = 70, -+ [0][0][1][0][RTW89_ETSI][1][29] = 66, -+ [0][0][1][0][RTW89_ETSI][0][29] = 28, -+ [0][0][1][0][RTW89_MKK][1][29] = 66, -+ [0][0][1][0][RTW89_MKK][0][29] = 26, -+ [0][0][1][0][RTW89_IC][1][29] = 22, -+ [0][0][1][0][RTW89_KCC][1][29] = 24, -+ [0][0][1][0][RTW89_KCC][0][29] = 26, -+ [0][0][1][0][RTW89_ACMA][1][29] = 66, -+ [0][0][1][0][RTW89_ACMA][0][29] = 28, -+ [0][0][1][0][RTW89_CHILE][1][29] = 22, -+ [0][0][1][0][RTW89_QATAR][1][29] = 66, -+ [0][0][1][0][RTW89_QATAR][0][29] = 28, -+ [0][0][1][0][RTW89_UK][1][29] = 66, -+ [0][0][1][0][RTW89_UK][0][29] = 28, -+ [0][0][1][0][RTW89_FCC][1][30] = 22, -+ [0][0][1][0][RTW89_FCC][2][30] = 70, -+ [0][0][1][0][RTW89_ETSI][1][30] = 66, -+ [0][0][1][0][RTW89_ETSI][0][30] = 28, -+ [0][0][1][0][RTW89_MKK][1][30] = 66, -+ [0][0][1][0][RTW89_MKK][0][30] = 26, -+ [0][0][1][0][RTW89_IC][1][30] = 22, -+ [0][0][1][0][RTW89_KCC][1][30] = 24, -+ [0][0][1][0][RTW89_KCC][0][30] = 26, -+ [0][0][1][0][RTW89_ACMA][1][30] = 66, -+ [0][0][1][0][RTW89_ACMA][0][30] = 28, -+ [0][0][1][0][RTW89_CHILE][1][30] = 22, -+ [0][0][1][0][RTW89_QATAR][1][30] = 66, -+ [0][0][1][0][RTW89_QATAR][0][30] = 28, -+ [0][0][1][0][RTW89_UK][1][30] = 66, -+ [0][0][1][0][RTW89_UK][0][30] = 28, -+ [0][0][1][0][RTW89_FCC][1][32] = 22, -+ [0][0][1][0][RTW89_FCC][2][32] = 70, -+ [0][0][1][0][RTW89_ETSI][1][32] = 66, -+ [0][0][1][0][RTW89_ETSI][0][32] = 28, -+ [0][0][1][0][RTW89_MKK][1][32] = 66, -+ [0][0][1][0][RTW89_MKK][0][32] = 26, -+ [0][0][1][0][RTW89_IC][1][32] = 22, -+ [0][0][1][0][RTW89_KCC][1][32] = 24, -+ [0][0][1][0][RTW89_KCC][0][32] = 26, -+ [0][0][1][0][RTW89_ACMA][1][32] = 66, -+ [0][0][1][0][RTW89_ACMA][0][32] = 28, -+ [0][0][1][0][RTW89_CHILE][1][32] = 22, -+ [0][0][1][0][RTW89_QATAR][1][32] = 66, -+ [0][0][1][0][RTW89_QATAR][0][32] = 28, -+ [0][0][1][0][RTW89_UK][1][32] = 66, -+ [0][0][1][0][RTW89_UK][0][32] = 28, -+ [0][0][1][0][RTW89_FCC][1][34] = 22, -+ [0][0][1][0][RTW89_FCC][2][34] = 70, -+ [0][0][1][0][RTW89_ETSI][1][34] = 66, -+ [0][0][1][0][RTW89_ETSI][0][34] = 28, -+ [0][0][1][0][RTW89_MKK][1][34] = 66, -+ [0][0][1][0][RTW89_MKK][0][34] = 26, -+ [0][0][1][0][RTW89_IC][1][34] = 22, -+ [0][0][1][0][RTW89_KCC][1][34] = 24, -+ [0][0][1][0][RTW89_KCC][0][34] = 26, -+ [0][0][1][0][RTW89_ACMA][1][34] = 66, -+ [0][0][1][0][RTW89_ACMA][0][34] = 28, -+ [0][0][1][0][RTW89_CHILE][1][34] = 22, -+ [0][0][1][0][RTW89_QATAR][1][34] = 66, -+ [0][0][1][0][RTW89_QATAR][0][34] = 28, -+ [0][0][1][0][RTW89_UK][1][34] = 66, -+ [0][0][1][0][RTW89_UK][0][34] = 28, -+ [0][0][1][0][RTW89_FCC][1][36] = 22, -+ [0][0][1][0][RTW89_FCC][2][36] = 70, -+ [0][0][1][0][RTW89_ETSI][1][36] = 66, -+ [0][0][1][0][RTW89_ETSI][0][36] = 28, -+ [0][0][1][0][RTW89_MKK][1][36] = 66, -+ [0][0][1][0][RTW89_MKK][0][36] = 26, -+ [0][0][1][0][RTW89_IC][1][36] = 22, -+ [0][0][1][0][RTW89_KCC][1][36] = 24, -+ [0][0][1][0][RTW89_KCC][0][36] = 26, -+ [0][0][1][0][RTW89_ACMA][1][36] = 66, -+ [0][0][1][0][RTW89_ACMA][0][36] = 28, -+ [0][0][1][0][RTW89_CHILE][1][36] = 22, -+ [0][0][1][0][RTW89_QATAR][1][36] = 66, -+ [0][0][1][0][RTW89_QATAR][0][36] = 28, -+ [0][0][1][0][RTW89_UK][1][36] = 66, -+ [0][0][1][0][RTW89_UK][0][36] = 28, -+ [0][0][1][0][RTW89_FCC][1][38] = 22, -+ [0][0][1][0][RTW89_FCC][2][38] = 70, -+ [0][0][1][0][RTW89_ETSI][1][38] = 66, -+ [0][0][1][0][RTW89_ETSI][0][38] = 28, -+ [0][0][1][0][RTW89_MKK][1][38] = 66, -+ [0][0][1][0][RTW89_MKK][0][38] = 26, -+ [0][0][1][0][RTW89_IC][1][38] = 22, -+ [0][0][1][0][RTW89_KCC][1][38] = 24, -+ [0][0][1][0][RTW89_KCC][0][38] = 26, -+ [0][0][1][0][RTW89_ACMA][1][38] = 66, -+ [0][0][1][0][RTW89_ACMA][0][38] = 28, -+ [0][0][1][0][RTW89_CHILE][1][38] = 22, -+ [0][0][1][0][RTW89_QATAR][1][38] = 66, -+ [0][0][1][0][RTW89_QATAR][0][38] = 28, -+ [0][0][1][0][RTW89_UK][1][38] = 66, -+ [0][0][1][0][RTW89_UK][0][38] = 28, -+ [0][0][1][0][RTW89_FCC][1][40] = 22, -+ [0][0][1][0][RTW89_FCC][2][40] = 70, -+ [0][0][1][0][RTW89_ETSI][1][40] = 66, -+ [0][0][1][0][RTW89_ETSI][0][40] = 28, -+ [0][0][1][0][RTW89_MKK][1][40] = 66, -+ [0][0][1][0][RTW89_MKK][0][40] = 26, -+ [0][0][1][0][RTW89_IC][1][40] = 22, -+ [0][0][1][0][RTW89_KCC][1][40] = 24, -+ [0][0][1][0][RTW89_KCC][0][40] = 26, -+ [0][0][1][0][RTW89_ACMA][1][40] = 66, -+ [0][0][1][0][RTW89_ACMA][0][40] = 28, -+ [0][0][1][0][RTW89_CHILE][1][40] = 22, -+ [0][0][1][0][RTW89_QATAR][1][40] = 66, -+ [0][0][1][0][RTW89_QATAR][0][40] = 28, -+ [0][0][1][0][RTW89_UK][1][40] = 66, -+ [0][0][1][0][RTW89_UK][0][40] = 28, -+ [0][0][1][0][RTW89_FCC][1][42] = 22, -+ [0][0][1][0][RTW89_FCC][2][42] = 70, -+ [0][0][1][0][RTW89_ETSI][1][42] = 66, -+ [0][0][1][0][RTW89_ETSI][0][42] = 28, -+ [0][0][1][0][RTW89_MKK][1][42] = 66, -+ [0][0][1][0][RTW89_MKK][0][42] = 26, -+ [0][0][1][0][RTW89_IC][1][42] = 22, -+ [0][0][1][0][RTW89_KCC][1][42] = 24, -+ [0][0][1][0][RTW89_KCC][0][42] = 26, -+ [0][0][1][0][RTW89_ACMA][1][42] = 66, -+ [0][0][1][0][RTW89_ACMA][0][42] = 28, -+ [0][0][1][0][RTW89_CHILE][1][42] = 22, -+ [0][0][1][0][RTW89_QATAR][1][42] = 66, -+ [0][0][1][0][RTW89_QATAR][0][42] = 28, -+ [0][0][1][0][RTW89_UK][1][42] = 66, -+ [0][0][1][0][RTW89_UK][0][42] = 28, -+ [0][0][1][0][RTW89_FCC][1][44] = 22, -+ [0][0][1][0][RTW89_FCC][2][44] = 70, -+ [0][0][1][0][RTW89_ETSI][1][44] = 66, -+ [0][0][1][0][RTW89_ETSI][0][44] = 30, -+ [0][0][1][0][RTW89_MKK][1][44] = 44, -+ [0][0][1][0][RTW89_MKK][0][44] = 28, -+ [0][0][1][0][RTW89_IC][1][44] = 22, -+ [0][0][1][0][RTW89_KCC][1][44] = 24, -+ [0][0][1][0][RTW89_KCC][0][44] = 26, -+ [0][0][1][0][RTW89_ACMA][1][44] = 66, -+ [0][0][1][0][RTW89_ACMA][0][44] = 30, -+ [0][0][1][0][RTW89_CHILE][1][44] = 22, -+ [0][0][1][0][RTW89_QATAR][1][44] = 66, -+ [0][0][1][0][RTW89_QATAR][0][44] = 30, -+ [0][0][1][0][RTW89_UK][1][44] = 66, -+ [0][0][1][0][RTW89_UK][0][44] = 30, -+ [0][0][1][0][RTW89_FCC][1][45] = 22, -+ [0][0][1][0][RTW89_FCC][2][45] = 127, -+ [0][0][1][0][RTW89_ETSI][1][45] = 127, -+ [0][0][1][0][RTW89_ETSI][0][45] = 127, -+ [0][0][1][0][RTW89_MKK][1][45] = 127, -+ [0][0][1][0][RTW89_MKK][0][45] = 127, -+ [0][0][1][0][RTW89_IC][1][45] = 22, -+ [0][0][1][0][RTW89_KCC][1][45] = 24, -+ [0][0][1][0][RTW89_KCC][0][45] = 127, -+ [0][0][1][0][RTW89_ACMA][1][45] = 127, -+ [0][0][1][0][RTW89_ACMA][0][45] = 127, -+ [0][0][1][0][RTW89_CHILE][1][45] = 22, -+ [0][0][1][0][RTW89_QATAR][1][45] = 127, -+ [0][0][1][0][RTW89_QATAR][0][45] = 127, -+ [0][0][1][0][RTW89_UK][1][45] = 127, -+ [0][0][1][0][RTW89_UK][0][45] = 127, -+ [0][0][1][0][RTW89_FCC][1][47] = 22, -+ [0][0][1][0][RTW89_FCC][2][47] = 127, -+ [0][0][1][0][RTW89_ETSI][1][47] = 127, -+ [0][0][1][0][RTW89_ETSI][0][47] = 127, -+ [0][0][1][0][RTW89_MKK][1][47] = 127, -+ [0][0][1][0][RTW89_MKK][0][47] = 127, -+ [0][0][1][0][RTW89_IC][1][47] = 22, -+ [0][0][1][0][RTW89_KCC][1][47] = 24, -+ [0][0][1][0][RTW89_KCC][0][47] = 127, -+ [0][0][1][0][RTW89_ACMA][1][47] = 127, -+ [0][0][1][0][RTW89_ACMA][0][47] = 127, -+ [0][0][1][0][RTW89_CHILE][1][47] = 22, -+ [0][0][1][0][RTW89_QATAR][1][47] = 127, -+ [0][0][1][0][RTW89_QATAR][0][47] = 127, -+ [0][0][1][0][RTW89_UK][1][47] = 127, -+ [0][0][1][0][RTW89_UK][0][47] = 127, -+ [0][0][1][0][RTW89_FCC][1][49] = 24, -+ [0][0][1][0][RTW89_FCC][2][49] = 127, -+ [0][0][1][0][RTW89_ETSI][1][49] = 127, -+ [0][0][1][0][RTW89_ETSI][0][49] = 127, -+ [0][0][1][0][RTW89_MKK][1][49] = 127, -+ [0][0][1][0][RTW89_MKK][0][49] = 127, -+ [0][0][1][0][RTW89_IC][1][49] = 24, -+ [0][0][1][0][RTW89_KCC][1][49] = 24, -+ [0][0][1][0][RTW89_KCC][0][49] = 127, -+ [0][0][1][0][RTW89_ACMA][1][49] = 127, -+ [0][0][1][0][RTW89_ACMA][0][49] = 127, -+ [0][0][1][0][RTW89_CHILE][1][49] = 24, -+ [0][0][1][0][RTW89_QATAR][1][49] = 127, -+ [0][0][1][0][RTW89_QATAR][0][49] = 127, -+ [0][0][1][0][RTW89_UK][1][49] = 127, -+ [0][0][1][0][RTW89_UK][0][49] = 127, -+ [0][0][1][0][RTW89_FCC][1][51] = 22, -+ [0][0][1][0][RTW89_FCC][2][51] = 127, -+ [0][0][1][0][RTW89_ETSI][1][51] = 127, -+ [0][0][1][0][RTW89_ETSI][0][51] = 127, -+ [0][0][1][0][RTW89_MKK][1][51] = 127, -+ [0][0][1][0][RTW89_MKK][0][51] = 127, -+ [0][0][1][0][RTW89_IC][1][51] = 22, -+ [0][0][1][0][RTW89_KCC][1][51] = 24, -+ [0][0][1][0][RTW89_KCC][0][51] = 127, -+ [0][0][1][0][RTW89_ACMA][1][51] = 127, -+ [0][0][1][0][RTW89_ACMA][0][51] = 127, -+ [0][0][1][0][RTW89_CHILE][1][51] = 22, -+ [0][0][1][0][RTW89_QATAR][1][51] = 127, -+ [0][0][1][0][RTW89_QATAR][0][51] = 127, -+ [0][0][1][0][RTW89_UK][1][51] = 127, -+ [0][0][1][0][RTW89_UK][0][51] = 127, -+ [0][0][1][0][RTW89_FCC][1][53] = 22, -+ [0][0][1][0][RTW89_FCC][2][53] = 127, -+ [0][0][1][0][RTW89_ETSI][1][53] = 127, -+ [0][0][1][0][RTW89_ETSI][0][53] = 127, -+ [0][0][1][0][RTW89_MKK][1][53] = 127, -+ [0][0][1][0][RTW89_MKK][0][53] = 127, -+ [0][0][1][0][RTW89_IC][1][53] = 22, -+ [0][0][1][0][RTW89_KCC][1][53] = 24, -+ [0][0][1][0][RTW89_KCC][0][53] = 127, -+ [0][0][1][0][RTW89_ACMA][1][53] = 127, -+ [0][0][1][0][RTW89_ACMA][0][53] = 127, -+ [0][0][1][0][RTW89_CHILE][1][53] = 22, -+ [0][0][1][0][RTW89_QATAR][1][53] = 127, -+ [0][0][1][0][RTW89_QATAR][0][53] = 127, -+ [0][0][1][0][RTW89_UK][1][53] = 127, -+ [0][0][1][0][RTW89_UK][0][53] = 127, -+ [0][0][1][0][RTW89_FCC][1][55] = 22, -+ [0][0][1][0][RTW89_FCC][2][55] = 68, -+ [0][0][1][0][RTW89_ETSI][1][55] = 127, -+ [0][0][1][0][RTW89_ETSI][0][55] = 127, -+ [0][0][1][0][RTW89_MKK][1][55] = 127, -+ [0][0][1][0][RTW89_MKK][0][55] = 127, -+ [0][0][1][0][RTW89_IC][1][55] = 22, -+ [0][0][1][0][RTW89_KCC][1][55] = 26, -+ [0][0][1][0][RTW89_KCC][0][55] = 127, -+ [0][0][1][0][RTW89_ACMA][1][55] = 127, -+ [0][0][1][0][RTW89_ACMA][0][55] = 127, -+ [0][0][1][0][RTW89_CHILE][1][55] = 22, -+ [0][0][1][0][RTW89_QATAR][1][55] = 127, -+ [0][0][1][0][RTW89_QATAR][0][55] = 127, -+ [0][0][1][0][RTW89_UK][1][55] = 127, -+ [0][0][1][0][RTW89_UK][0][55] = 127, -+ [0][0][1][0][RTW89_FCC][1][57] = 22, -+ [0][0][1][0][RTW89_FCC][2][57] = 68, -+ [0][0][1][0][RTW89_ETSI][1][57] = 127, -+ [0][0][1][0][RTW89_ETSI][0][57] = 127, -+ [0][0][1][0][RTW89_MKK][1][57] = 127, -+ [0][0][1][0][RTW89_MKK][0][57] = 127, -+ [0][0][1][0][RTW89_IC][1][57] = 22, -+ [0][0][1][0][RTW89_KCC][1][57] = 26, -+ [0][0][1][0][RTW89_KCC][0][57] = 127, -+ [0][0][1][0][RTW89_ACMA][1][57] = 127, -+ [0][0][1][0][RTW89_ACMA][0][57] = 127, -+ [0][0][1][0][RTW89_CHILE][1][57] = 22, -+ [0][0][1][0][RTW89_QATAR][1][57] = 127, -+ [0][0][1][0][RTW89_QATAR][0][57] = 127, -+ [0][0][1][0][RTW89_UK][1][57] = 127, -+ [0][0][1][0][RTW89_UK][0][57] = 127, -+ [0][0][1][0][RTW89_FCC][1][59] = 22, -+ [0][0][1][0][RTW89_FCC][2][59] = 68, -+ [0][0][1][0][RTW89_ETSI][1][59] = 127, -+ [0][0][1][0][RTW89_ETSI][0][59] = 127, -+ [0][0][1][0][RTW89_MKK][1][59] = 127, -+ [0][0][1][0][RTW89_MKK][0][59] = 127, -+ [0][0][1][0][RTW89_IC][1][59] = 22, -+ [0][0][1][0][RTW89_KCC][1][59] = 26, -+ [0][0][1][0][RTW89_KCC][0][59] = 127, -+ [0][0][1][0][RTW89_ACMA][1][59] = 127, -+ [0][0][1][0][RTW89_ACMA][0][59] = 127, -+ [0][0][1][0][RTW89_CHILE][1][59] = 22, -+ [0][0][1][0][RTW89_QATAR][1][59] = 127, -+ [0][0][1][0][RTW89_QATAR][0][59] = 127, -+ [0][0][1][0][RTW89_UK][1][59] = 127, -+ [0][0][1][0][RTW89_UK][0][59] = 127, -+ [0][0][1][0][RTW89_FCC][1][60] = 22, -+ [0][0][1][0][RTW89_FCC][2][60] = 68, -+ [0][0][1][0][RTW89_ETSI][1][60] = 127, -+ [0][0][1][0][RTW89_ETSI][0][60] = 127, -+ [0][0][1][0][RTW89_MKK][1][60] = 127, -+ [0][0][1][0][RTW89_MKK][0][60] = 127, -+ [0][0][1][0][RTW89_IC][1][60] = 22, -+ [0][0][1][0][RTW89_KCC][1][60] = 26, -+ [0][0][1][0][RTW89_KCC][0][60] = 127, -+ [0][0][1][0][RTW89_ACMA][1][60] = 127, -+ [0][0][1][0][RTW89_ACMA][0][60] = 127, -+ [0][0][1][0][RTW89_CHILE][1][60] = 22, -+ [0][0][1][0][RTW89_QATAR][1][60] = 127, -+ [0][0][1][0][RTW89_QATAR][0][60] = 127, -+ [0][0][1][0][RTW89_UK][1][60] = 127, -+ [0][0][1][0][RTW89_UK][0][60] = 127, -+ [0][0][1][0][RTW89_FCC][1][62] = 22, -+ [0][0][1][0][RTW89_FCC][2][62] = 68, -+ [0][0][1][0][RTW89_ETSI][1][62] = 127, -+ [0][0][1][0][RTW89_ETSI][0][62] = 127, -+ [0][0][1][0][RTW89_MKK][1][62] = 127, -+ [0][0][1][0][RTW89_MKK][0][62] = 127, -+ [0][0][1][0][RTW89_IC][1][62] = 22, -+ [0][0][1][0][RTW89_KCC][1][62] = 26, -+ [0][0][1][0][RTW89_KCC][0][62] = 127, -+ [0][0][1][0][RTW89_ACMA][1][62] = 127, -+ [0][0][1][0][RTW89_ACMA][0][62] = 127, -+ [0][0][1][0][RTW89_CHILE][1][62] = 22, -+ [0][0][1][0][RTW89_QATAR][1][62] = 127, -+ [0][0][1][0][RTW89_QATAR][0][62] = 127, -+ [0][0][1][0][RTW89_UK][1][62] = 127, -+ [0][0][1][0][RTW89_UK][0][62] = 127, -+ [0][0][1][0][RTW89_FCC][1][64] = 22, -+ [0][0][1][0][RTW89_FCC][2][64] = 68, -+ [0][0][1][0][RTW89_ETSI][1][64] = 127, -+ [0][0][1][0][RTW89_ETSI][0][64] = 127, -+ [0][0][1][0][RTW89_MKK][1][64] = 127, -+ [0][0][1][0][RTW89_MKK][0][64] = 127, -+ [0][0][1][0][RTW89_IC][1][64] = 22, -+ [0][0][1][0][RTW89_KCC][1][64] = 26, -+ [0][0][1][0][RTW89_KCC][0][64] = 127, -+ [0][0][1][0][RTW89_ACMA][1][64] = 127, -+ [0][0][1][0][RTW89_ACMA][0][64] = 127, -+ [0][0][1][0][RTW89_CHILE][1][64] = 22, -+ [0][0][1][0][RTW89_QATAR][1][64] = 127, -+ [0][0][1][0][RTW89_QATAR][0][64] = 127, -+ [0][0][1][0][RTW89_UK][1][64] = 127, -+ [0][0][1][0][RTW89_UK][0][64] = 127, -+ [0][0][1][0][RTW89_FCC][1][66] = 22, -+ [0][0][1][0][RTW89_FCC][2][66] = 68, -+ [0][0][1][0][RTW89_ETSI][1][66] = 127, -+ [0][0][1][0][RTW89_ETSI][0][66] = 127, -+ [0][0][1][0][RTW89_MKK][1][66] = 127, -+ [0][0][1][0][RTW89_MKK][0][66] = 127, -+ [0][0][1][0][RTW89_IC][1][66] = 22, -+ [0][0][1][0][RTW89_KCC][1][66] = 26, -+ [0][0][1][0][RTW89_KCC][0][66] = 127, -+ [0][0][1][0][RTW89_ACMA][1][66] = 127, -+ [0][0][1][0][RTW89_ACMA][0][66] = 127, -+ [0][0][1][0][RTW89_CHILE][1][66] = 22, -+ [0][0][1][0][RTW89_QATAR][1][66] = 127, -+ [0][0][1][0][RTW89_QATAR][0][66] = 127, -+ [0][0][1][0][RTW89_UK][1][66] = 127, -+ [0][0][1][0][RTW89_UK][0][66] = 127, -+ [0][0][1][0][RTW89_FCC][1][68] = 22, -+ [0][0][1][0][RTW89_FCC][2][68] = 68, -+ [0][0][1][0][RTW89_ETSI][1][68] = 127, -+ [0][0][1][0][RTW89_ETSI][0][68] = 127, -+ [0][0][1][0][RTW89_MKK][1][68] = 127, -+ [0][0][1][0][RTW89_MKK][0][68] = 127, -+ [0][0][1][0][RTW89_IC][1][68] = 22, -+ [0][0][1][0][RTW89_KCC][1][68] = 26, -+ [0][0][1][0][RTW89_KCC][0][68] = 127, -+ [0][0][1][0][RTW89_ACMA][1][68] = 127, -+ [0][0][1][0][RTW89_ACMA][0][68] = 127, -+ [0][0][1][0][RTW89_CHILE][1][68] = 22, -+ [0][0][1][0][RTW89_QATAR][1][68] = 127, -+ [0][0][1][0][RTW89_QATAR][0][68] = 127, -+ [0][0][1][0][RTW89_UK][1][68] = 127, -+ [0][0][1][0][RTW89_UK][0][68] = 127, -+ [0][0][1][0][RTW89_FCC][1][70] = 24, -+ [0][0][1][0][RTW89_FCC][2][70] = 68, -+ [0][0][1][0][RTW89_ETSI][1][70] = 127, -+ [0][0][1][0][RTW89_ETSI][0][70] = 127, -+ [0][0][1][0][RTW89_MKK][1][70] = 127, -+ [0][0][1][0][RTW89_MKK][0][70] = 127, -+ [0][0][1][0][RTW89_IC][1][70] = 24, -+ [0][0][1][0][RTW89_KCC][1][70] = 26, -+ [0][0][1][0][RTW89_KCC][0][70] = 127, -+ [0][0][1][0][RTW89_ACMA][1][70] = 127, -+ [0][0][1][0][RTW89_ACMA][0][70] = 127, -+ [0][0][1][0][RTW89_CHILE][1][70] = 24, -+ [0][0][1][0][RTW89_QATAR][1][70] = 127, -+ [0][0][1][0][RTW89_QATAR][0][70] = 127, -+ [0][0][1][0][RTW89_UK][1][70] = 127, -+ [0][0][1][0][RTW89_UK][0][70] = 127, -+ [0][0][1][0][RTW89_FCC][1][72] = 22, -+ [0][0][1][0][RTW89_FCC][2][72] = 68, -+ [0][0][1][0][RTW89_ETSI][1][72] = 127, -+ [0][0][1][0][RTW89_ETSI][0][72] = 127, -+ [0][0][1][0][RTW89_MKK][1][72] = 127, -+ [0][0][1][0][RTW89_MKK][0][72] = 127, -+ [0][0][1][0][RTW89_IC][1][72] = 22, -+ [0][0][1][0][RTW89_KCC][1][72] = 26, -+ [0][0][1][0][RTW89_KCC][0][72] = 127, -+ [0][0][1][0][RTW89_ACMA][1][72] = 127, -+ [0][0][1][0][RTW89_ACMA][0][72] = 127, -+ [0][0][1][0][RTW89_CHILE][1][72] = 22, -+ [0][0][1][0][RTW89_QATAR][1][72] = 127, -+ [0][0][1][0][RTW89_QATAR][0][72] = 127, -+ [0][0][1][0][RTW89_UK][1][72] = 127, -+ [0][0][1][0][RTW89_UK][0][72] = 127, -+ [0][0][1][0][RTW89_FCC][1][74] = 22, -+ [0][0][1][0][RTW89_FCC][2][74] = 68, -+ [0][0][1][0][RTW89_ETSI][1][74] = 127, -+ [0][0][1][0][RTW89_ETSI][0][74] = 127, -+ [0][0][1][0][RTW89_MKK][1][74] = 127, -+ [0][0][1][0][RTW89_MKK][0][74] = 127, -+ [0][0][1][0][RTW89_IC][1][74] = 22, -+ [0][0][1][0][RTW89_KCC][1][74] = 26, -+ [0][0][1][0][RTW89_KCC][0][74] = 127, -+ [0][0][1][0][RTW89_ACMA][1][74] = 127, -+ [0][0][1][0][RTW89_ACMA][0][74] = 127, -+ [0][0][1][0][RTW89_CHILE][1][74] = 22, -+ [0][0][1][0][RTW89_QATAR][1][74] = 127, -+ [0][0][1][0][RTW89_QATAR][0][74] = 127, -+ [0][0][1][0][RTW89_UK][1][74] = 127, -+ [0][0][1][0][RTW89_UK][0][74] = 127, -+ [0][0][1][0][RTW89_FCC][1][75] = 22, -+ [0][0][1][0][RTW89_FCC][2][75] = 68, -+ [0][0][1][0][RTW89_ETSI][1][75] = 127, -+ [0][0][1][0][RTW89_ETSI][0][75] = 127, -+ [0][0][1][0][RTW89_MKK][1][75] = 127, -+ [0][0][1][0][RTW89_MKK][0][75] = 127, -+ [0][0][1][0][RTW89_IC][1][75] = 22, -+ [0][0][1][0][RTW89_KCC][1][75] = 26, -+ [0][0][1][0][RTW89_KCC][0][75] = 127, -+ [0][0][1][0][RTW89_ACMA][1][75] = 127, -+ [0][0][1][0][RTW89_ACMA][0][75] = 127, -+ [0][0][1][0][RTW89_CHILE][1][75] = 22, -+ [0][0][1][0][RTW89_QATAR][1][75] = 127, -+ [0][0][1][0][RTW89_QATAR][0][75] = 127, -+ [0][0][1][0][RTW89_UK][1][75] = 127, -+ [0][0][1][0][RTW89_UK][0][75] = 127, -+ [0][0][1][0][RTW89_FCC][1][77] = 22, -+ [0][0][1][0][RTW89_FCC][2][77] = 68, -+ [0][0][1][0][RTW89_ETSI][1][77] = 127, -+ [0][0][1][0][RTW89_ETSI][0][77] = 127, -+ [0][0][1][0][RTW89_MKK][1][77] = 127, -+ [0][0][1][0][RTW89_MKK][0][77] = 127, -+ [0][0][1][0][RTW89_IC][1][77] = 22, -+ [0][0][1][0][RTW89_KCC][1][77] = 26, -+ [0][0][1][0][RTW89_KCC][0][77] = 127, -+ [0][0][1][0][RTW89_ACMA][1][77] = 127, -+ [0][0][1][0][RTW89_ACMA][0][77] = 127, -+ [0][0][1][0][RTW89_CHILE][1][77] = 22, -+ [0][0][1][0][RTW89_QATAR][1][77] = 127, -+ [0][0][1][0][RTW89_QATAR][0][77] = 127, -+ [0][0][1][0][RTW89_UK][1][77] = 127, -+ [0][0][1][0][RTW89_UK][0][77] = 127, -+ [0][0][1][0][RTW89_FCC][1][79] = 22, -+ [0][0][1][0][RTW89_FCC][2][79] = 68, -+ [0][0][1][0][RTW89_ETSI][1][79] = 127, -+ [0][0][1][0][RTW89_ETSI][0][79] = 127, -+ [0][0][1][0][RTW89_MKK][1][79] = 127, -+ [0][0][1][0][RTW89_MKK][0][79] = 127, -+ [0][0][1][0][RTW89_IC][1][79] = 22, -+ [0][0][1][0][RTW89_KCC][1][79] = 26, -+ [0][0][1][0][RTW89_KCC][0][79] = 127, -+ [0][0][1][0][RTW89_ACMA][1][79] = 127, -+ [0][0][1][0][RTW89_ACMA][0][79] = 127, -+ [0][0][1][0][RTW89_CHILE][1][79] = 22, -+ [0][0][1][0][RTW89_QATAR][1][79] = 127, -+ [0][0][1][0][RTW89_QATAR][0][79] = 127, -+ [0][0][1][0][RTW89_UK][1][79] = 127, -+ [0][0][1][0][RTW89_UK][0][79] = 127, -+ [0][0][1][0][RTW89_FCC][1][81] = 22, -+ [0][0][1][0][RTW89_FCC][2][81] = 68, -+ [0][0][1][0][RTW89_ETSI][1][81] = 127, -+ [0][0][1][0][RTW89_ETSI][0][81] = 127, -+ [0][0][1][0][RTW89_MKK][1][81] = 127, -+ [0][0][1][0][RTW89_MKK][0][81] = 127, -+ [0][0][1][0][RTW89_IC][1][81] = 22, -+ [0][0][1][0][RTW89_KCC][1][81] = 26, -+ [0][0][1][0][RTW89_KCC][0][81] = 127, -+ [0][0][1][0][RTW89_ACMA][1][81] = 127, -+ [0][0][1][0][RTW89_ACMA][0][81] = 127, -+ [0][0][1][0][RTW89_CHILE][1][81] = 22, -+ [0][0][1][0][RTW89_QATAR][1][81] = 127, -+ [0][0][1][0][RTW89_QATAR][0][81] = 127, -+ [0][0][1][0][RTW89_UK][1][81] = 127, -+ [0][0][1][0][RTW89_UK][0][81] = 127, -+ [0][0][1][0][RTW89_FCC][1][83] = 22, -+ [0][0][1][0][RTW89_FCC][2][83] = 68, -+ [0][0][1][0][RTW89_ETSI][1][83] = 127, -+ [0][0][1][0][RTW89_ETSI][0][83] = 127, -+ [0][0][1][0][RTW89_MKK][1][83] = 127, -+ [0][0][1][0][RTW89_MKK][0][83] = 127, -+ [0][0][1][0][RTW89_IC][1][83] = 22, -+ [0][0][1][0][RTW89_KCC][1][83] = 32, -+ [0][0][1][0][RTW89_KCC][0][83] = 127, -+ [0][0][1][0][RTW89_ACMA][1][83] = 127, -+ [0][0][1][0][RTW89_ACMA][0][83] = 127, -+ [0][0][1][0][RTW89_CHILE][1][83] = 22, -+ [0][0][1][0][RTW89_QATAR][1][83] = 127, -+ [0][0][1][0][RTW89_QATAR][0][83] = 127, -+ [0][0][1][0][RTW89_UK][1][83] = 127, -+ [0][0][1][0][RTW89_UK][0][83] = 127, -+ [0][0][1][0][RTW89_FCC][1][85] = 22, -+ [0][0][1][0][RTW89_FCC][2][85] = 68, -+ [0][0][1][0][RTW89_ETSI][1][85] = 127, -+ [0][0][1][0][RTW89_ETSI][0][85] = 127, -+ [0][0][1][0][RTW89_MKK][1][85] = 127, -+ [0][0][1][0][RTW89_MKK][0][85] = 127, -+ [0][0][1][0][RTW89_IC][1][85] = 22, -+ [0][0][1][0][RTW89_KCC][1][85] = 32, -+ [0][0][1][0][RTW89_KCC][0][85] = 127, -+ [0][0][1][0][RTW89_ACMA][1][85] = 127, -+ [0][0][1][0][RTW89_ACMA][0][85] = 127, -+ [0][0][1][0][RTW89_CHILE][1][85] = 22, -+ [0][0][1][0][RTW89_QATAR][1][85] = 127, -+ [0][0][1][0][RTW89_QATAR][0][85] = 127, -+ [0][0][1][0][RTW89_UK][1][85] = 127, -+ [0][0][1][0][RTW89_UK][0][85] = 127, -+ [0][0][1][0][RTW89_FCC][1][87] = 22, -+ [0][0][1][0][RTW89_FCC][2][87] = 127, -+ [0][0][1][0][RTW89_ETSI][1][87] = 127, -+ [0][0][1][0][RTW89_ETSI][0][87] = 127, -+ [0][0][1][0][RTW89_MKK][1][87] = 127, -+ [0][0][1][0][RTW89_MKK][0][87] = 127, -+ [0][0][1][0][RTW89_IC][1][87] = 22, -+ [0][0][1][0][RTW89_KCC][1][87] = 32, -+ [0][0][1][0][RTW89_KCC][0][87] = 127, -+ [0][0][1][0][RTW89_ACMA][1][87] = 127, -+ [0][0][1][0][RTW89_ACMA][0][87] = 127, -+ [0][0][1][0][RTW89_CHILE][1][87] = 22, -+ [0][0][1][0][RTW89_QATAR][1][87] = 127, -+ [0][0][1][0][RTW89_QATAR][0][87] = 127, -+ [0][0][1][0][RTW89_UK][1][87] = 127, -+ [0][0][1][0][RTW89_UK][0][87] = 127, -+ [0][0][1][0][RTW89_FCC][1][89] = 22, -+ [0][0][1][0][RTW89_FCC][2][89] = 127, -+ [0][0][1][0][RTW89_ETSI][1][89] = 127, -+ [0][0][1][0][RTW89_ETSI][0][89] = 127, -+ [0][0][1][0][RTW89_MKK][1][89] = 127, -+ [0][0][1][0][RTW89_MKK][0][89] = 127, -+ [0][0][1][0][RTW89_IC][1][89] = 22, -+ [0][0][1][0][RTW89_KCC][1][89] = 32, -+ [0][0][1][0][RTW89_KCC][0][89] = 127, -+ [0][0][1][0][RTW89_ACMA][1][89] = 127, -+ [0][0][1][0][RTW89_ACMA][0][89] = 127, -+ [0][0][1][0][RTW89_CHILE][1][89] = 22, -+ [0][0][1][0][RTW89_QATAR][1][89] = 127, -+ [0][0][1][0][RTW89_QATAR][0][89] = 127, -+ [0][0][1][0][RTW89_UK][1][89] = 127, -+ [0][0][1][0][RTW89_UK][0][89] = 127, -+ [0][0][1][0][RTW89_FCC][1][90] = 22, -+ [0][0][1][0][RTW89_FCC][2][90] = 127, -+ [0][0][1][0][RTW89_ETSI][1][90] = 127, -+ [0][0][1][0][RTW89_ETSI][0][90] = 127, -+ [0][0][1][0][RTW89_MKK][1][90] = 127, -+ [0][0][1][0][RTW89_MKK][0][90] = 127, -+ [0][0][1][0][RTW89_IC][1][90] = 22, -+ [0][0][1][0][RTW89_KCC][1][90] = 32, -+ [0][0][1][0][RTW89_KCC][0][90] = 127, -+ [0][0][1][0][RTW89_ACMA][1][90] = 127, -+ [0][0][1][0][RTW89_ACMA][0][90] = 127, -+ [0][0][1][0][RTW89_CHILE][1][90] = 22, -+ [0][0][1][0][RTW89_QATAR][1][90] = 127, -+ [0][0][1][0][RTW89_QATAR][0][90] = 127, -+ [0][0][1][0][RTW89_UK][1][90] = 127, -+ [0][0][1][0][RTW89_UK][0][90] = 127, -+ [0][0][1][0][RTW89_FCC][1][92] = 22, -+ [0][0][1][0][RTW89_FCC][2][92] = 127, -+ [0][0][1][0][RTW89_ETSI][1][92] = 127, -+ [0][0][1][0][RTW89_ETSI][0][92] = 127, -+ [0][0][1][0][RTW89_MKK][1][92] = 127, -+ [0][0][1][0][RTW89_MKK][0][92] = 127, -+ [0][0][1][0][RTW89_IC][1][92] = 22, -+ [0][0][1][0][RTW89_KCC][1][92] = 32, -+ [0][0][1][0][RTW89_KCC][0][92] = 127, -+ [0][0][1][0][RTW89_ACMA][1][92] = 127, -+ [0][0][1][0][RTW89_ACMA][0][92] = 127, -+ [0][0][1][0][RTW89_CHILE][1][92] = 22, -+ [0][0][1][0][RTW89_QATAR][1][92] = 127, -+ [0][0][1][0][RTW89_QATAR][0][92] = 127, -+ [0][0][1][0][RTW89_UK][1][92] = 127, -+ [0][0][1][0][RTW89_UK][0][92] = 127, -+ [0][0][1][0][RTW89_FCC][1][94] = 22, -+ [0][0][1][0][RTW89_FCC][2][94] = 127, -+ [0][0][1][0][RTW89_ETSI][1][94] = 127, -+ [0][0][1][0][RTW89_ETSI][0][94] = 127, -+ [0][0][1][0][RTW89_MKK][1][94] = 127, -+ [0][0][1][0][RTW89_MKK][0][94] = 127, -+ [0][0][1][0][RTW89_IC][1][94] = 22, -+ [0][0][1][0][RTW89_KCC][1][94] = 32, -+ [0][0][1][0][RTW89_KCC][0][94] = 127, -+ [0][0][1][0][RTW89_ACMA][1][94] = 127, -+ [0][0][1][0][RTW89_ACMA][0][94] = 127, -+ [0][0][1][0][RTW89_CHILE][1][94] = 22, -+ [0][0][1][0][RTW89_QATAR][1][94] = 127, -+ [0][0][1][0][RTW89_QATAR][0][94] = 127, -+ [0][0][1][0][RTW89_UK][1][94] = 127, -+ [0][0][1][0][RTW89_UK][0][94] = 127, -+ [0][0][1][0][RTW89_FCC][1][96] = 22, -+ [0][0][1][0][RTW89_FCC][2][96] = 127, -+ [0][0][1][0][RTW89_ETSI][1][96] = 127, -+ [0][0][1][0][RTW89_ETSI][0][96] = 127, -+ [0][0][1][0][RTW89_MKK][1][96] = 127, -+ [0][0][1][0][RTW89_MKK][0][96] = 127, -+ [0][0][1][0][RTW89_IC][1][96] = 22, -+ [0][0][1][0][RTW89_KCC][1][96] = 32, -+ [0][0][1][0][RTW89_KCC][0][96] = 127, -+ [0][0][1][0][RTW89_ACMA][1][96] = 127, -+ [0][0][1][0][RTW89_ACMA][0][96] = 127, -+ [0][0][1][0][RTW89_CHILE][1][96] = 22, -+ [0][0][1][0][RTW89_QATAR][1][96] = 127, -+ [0][0][1][0][RTW89_QATAR][0][96] = 127, -+ [0][0][1][0][RTW89_UK][1][96] = 127, -+ [0][0][1][0][RTW89_UK][0][96] = 127, -+ [0][0][1][0][RTW89_FCC][1][98] = 22, -+ [0][0][1][0][RTW89_FCC][2][98] = 127, -+ [0][0][1][0][RTW89_ETSI][1][98] = 127, -+ [0][0][1][0][RTW89_ETSI][0][98] = 127, -+ [0][0][1][0][RTW89_MKK][1][98] = 127, -+ [0][0][1][0][RTW89_MKK][0][98] = 127, -+ [0][0][1][0][RTW89_IC][1][98] = 22, -+ [0][0][1][0][RTW89_KCC][1][98] = 32, -+ [0][0][1][0][RTW89_KCC][0][98] = 127, -+ [0][0][1][0][RTW89_ACMA][1][98] = 127, -+ [0][0][1][0][RTW89_ACMA][0][98] = 127, -+ [0][0][1][0][RTW89_CHILE][1][98] = 22, -+ [0][0][1][0][RTW89_QATAR][1][98] = 127, -+ [0][0][1][0][RTW89_QATAR][0][98] = 127, -+ [0][0][1][0][RTW89_UK][1][98] = 127, -+ [0][0][1][0][RTW89_UK][0][98] = 127, -+ [0][0][1][0][RTW89_FCC][1][100] = 22, -+ [0][0][1][0][RTW89_FCC][2][100] = 127, -+ [0][0][1][0][RTW89_ETSI][1][100] = 127, -+ [0][0][1][0][RTW89_ETSI][0][100] = 127, -+ [0][0][1][0][RTW89_MKK][1][100] = 127, -+ [0][0][1][0][RTW89_MKK][0][100] = 127, -+ [0][0][1][0][RTW89_IC][1][100] = 22, -+ [0][0][1][0][RTW89_KCC][1][100] = 32, -+ [0][0][1][0][RTW89_KCC][0][100] = 127, -+ [0][0][1][0][RTW89_ACMA][1][100] = 127, -+ [0][0][1][0][RTW89_ACMA][0][100] = 127, -+ [0][0][1][0][RTW89_CHILE][1][100] = 22, -+ [0][0][1][0][RTW89_QATAR][1][100] = 127, -+ [0][0][1][0][RTW89_QATAR][0][100] = 127, -+ [0][0][1][0][RTW89_UK][1][100] = 127, -+ [0][0][1][0][RTW89_UK][0][100] = 127, -+ [0][0][1][0][RTW89_FCC][1][102] = 22, -+ [0][0][1][0][RTW89_FCC][2][102] = 127, -+ [0][0][1][0][RTW89_ETSI][1][102] = 127, -+ [0][0][1][0][RTW89_ETSI][0][102] = 127, -+ [0][0][1][0][RTW89_MKK][1][102] = 127, -+ [0][0][1][0][RTW89_MKK][0][102] = 127, -+ [0][0][1][0][RTW89_IC][1][102] = 22, -+ [0][0][1][0][RTW89_KCC][1][102] = 32, -+ [0][0][1][0][RTW89_KCC][0][102] = 127, -+ [0][0][1][0][RTW89_ACMA][1][102] = 127, -+ [0][0][1][0][RTW89_ACMA][0][102] = 127, -+ [0][0][1][0][RTW89_CHILE][1][102] = 22, -+ [0][0][1][0][RTW89_QATAR][1][102] = 127, -+ [0][0][1][0][RTW89_QATAR][0][102] = 127, -+ [0][0][1][0][RTW89_UK][1][102] = 127, -+ [0][0][1][0][RTW89_UK][0][102] = 127, -+ [0][0][1][0][RTW89_FCC][1][104] = 22, -+ [0][0][1][0][RTW89_FCC][2][104] = 127, -+ [0][0][1][0][RTW89_ETSI][1][104] = 127, -+ [0][0][1][0][RTW89_ETSI][0][104] = 127, -+ [0][0][1][0][RTW89_MKK][1][104] = 127, -+ [0][0][1][0][RTW89_MKK][0][104] = 127, -+ [0][0][1][0][RTW89_IC][1][104] = 22, -+ [0][0][1][0][RTW89_KCC][1][104] = 32, -+ [0][0][1][0][RTW89_KCC][0][104] = 127, -+ [0][0][1][0][RTW89_ACMA][1][104] = 127, -+ [0][0][1][0][RTW89_ACMA][0][104] = 127, -+ [0][0][1][0][RTW89_CHILE][1][104] = 22, -+ [0][0][1][0][RTW89_QATAR][1][104] = 127, -+ [0][0][1][0][RTW89_QATAR][0][104] = 127, -+ [0][0][1][0][RTW89_UK][1][104] = 127, -+ [0][0][1][0][RTW89_UK][0][104] = 127, -+ [0][0][1][0][RTW89_FCC][1][105] = 22, -+ [0][0][1][0][RTW89_FCC][2][105] = 127, -+ [0][0][1][0][RTW89_ETSI][1][105] = 127, -+ [0][0][1][0][RTW89_ETSI][0][105] = 127, -+ [0][0][1][0][RTW89_MKK][1][105] = 127, -+ [0][0][1][0][RTW89_MKK][0][105] = 127, -+ [0][0][1][0][RTW89_IC][1][105] = 22, -+ [0][0][1][0][RTW89_KCC][1][105] = 32, -+ [0][0][1][0][RTW89_KCC][0][105] = 127, -+ [0][0][1][0][RTW89_ACMA][1][105] = 127, -+ [0][0][1][0][RTW89_ACMA][0][105] = 127, -+ [0][0][1][0][RTW89_CHILE][1][105] = 22, -+ [0][0][1][0][RTW89_QATAR][1][105] = 127, -+ [0][0][1][0][RTW89_QATAR][0][105] = 127, -+ [0][0][1][0][RTW89_UK][1][105] = 127, -+ [0][0][1][0][RTW89_UK][0][105] = 127, -+ [0][0][1][0][RTW89_FCC][1][107] = 24, -+ [0][0][1][0][RTW89_FCC][2][107] = 127, -+ [0][0][1][0][RTW89_ETSI][1][107] = 127, -+ [0][0][1][0][RTW89_ETSI][0][107] = 127, -+ [0][0][1][0][RTW89_MKK][1][107] = 127, -+ [0][0][1][0][RTW89_MKK][0][107] = 127, -+ [0][0][1][0][RTW89_IC][1][107] = 24, -+ [0][0][1][0][RTW89_KCC][1][107] = 32, -+ [0][0][1][0][RTW89_KCC][0][107] = 127, -+ [0][0][1][0][RTW89_ACMA][1][107] = 127, -+ [0][0][1][0][RTW89_ACMA][0][107] = 127, -+ [0][0][1][0][RTW89_CHILE][1][107] = 24, -+ [0][0][1][0][RTW89_QATAR][1][107] = 127, -+ [0][0][1][0][RTW89_QATAR][0][107] = 127, -+ [0][0][1][0][RTW89_UK][1][107] = 127, -+ [0][0][1][0][RTW89_UK][0][107] = 127, -+ [0][0][1][0][RTW89_FCC][1][109] = 24, -+ [0][0][1][0][RTW89_FCC][2][109] = 127, -+ [0][0][1][0][RTW89_ETSI][1][109] = 127, -+ [0][0][1][0][RTW89_ETSI][0][109] = 127, -+ [0][0][1][0][RTW89_MKK][1][109] = 127, -+ [0][0][1][0][RTW89_MKK][0][109] = 127, -+ [0][0][1][0][RTW89_IC][1][109] = 24, -+ [0][0][1][0][RTW89_KCC][1][109] = 32, -+ [0][0][1][0][RTW89_KCC][0][109] = 127, -+ [0][0][1][0][RTW89_ACMA][1][109] = 127, -+ [0][0][1][0][RTW89_ACMA][0][109] = 127, -+ [0][0][1][0][RTW89_CHILE][1][109] = 24, -+ [0][0][1][0][RTW89_QATAR][1][109] = 127, -+ [0][0][1][0][RTW89_QATAR][0][109] = 127, -+ [0][0][1][0][RTW89_UK][1][109] = 127, -+ [0][0][1][0][RTW89_UK][0][109] = 127, -+ [0][0][1][0][RTW89_FCC][1][111] = 127, -+ [0][0][1][0][RTW89_FCC][2][111] = 127, -+ [0][0][1][0][RTW89_ETSI][1][111] = 127, -+ [0][0][1][0][RTW89_ETSI][0][111] = 127, -+ [0][0][1][0][RTW89_MKK][1][111] = 127, -+ [0][0][1][0][RTW89_MKK][0][111] = 127, -+ [0][0][1][0][RTW89_IC][1][111] = 127, -+ [0][0][1][0][RTW89_KCC][1][111] = 127, -+ [0][0][1][0][RTW89_KCC][0][111] = 127, -+ [0][0][1][0][RTW89_ACMA][1][111] = 127, -+ [0][0][1][0][RTW89_ACMA][0][111] = 127, -+ [0][0][1][0][RTW89_CHILE][1][111] = 127, -+ [0][0][1][0][RTW89_QATAR][1][111] = 127, -+ [0][0][1][0][RTW89_QATAR][0][111] = 127, -+ [0][0][1][0][RTW89_UK][1][111] = 127, -+ [0][0][1][0][RTW89_UK][0][111] = 127, -+ [0][0][1][0][RTW89_FCC][1][113] = 127, -+ [0][0][1][0][RTW89_FCC][2][113] = 127, -+ [0][0][1][0][RTW89_ETSI][1][113] = 127, -+ [0][0][1][0][RTW89_ETSI][0][113] = 127, -+ [0][0][1][0][RTW89_MKK][1][113] = 127, -+ [0][0][1][0][RTW89_MKK][0][113] = 127, -+ [0][0][1][0][RTW89_IC][1][113] = 127, -+ [0][0][1][0][RTW89_KCC][1][113] = 127, -+ [0][0][1][0][RTW89_KCC][0][113] = 127, -+ [0][0][1][0][RTW89_ACMA][1][113] = 127, -+ [0][0][1][0][RTW89_ACMA][0][113] = 127, -+ [0][0][1][0][RTW89_CHILE][1][113] = 127, -+ [0][0][1][0][RTW89_QATAR][1][113] = 127, -+ [0][0][1][0][RTW89_QATAR][0][113] = 127, -+ [0][0][1][0][RTW89_UK][1][113] = 127, -+ [0][0][1][0][RTW89_UK][0][113] = 127, -+ [0][0][1][0][RTW89_FCC][1][115] = 127, -+ [0][0][1][0][RTW89_FCC][2][115] = 127, -+ [0][0][1][0][RTW89_ETSI][1][115] = 127, -+ [0][0][1][0][RTW89_ETSI][0][115] = 127, -+ [0][0][1][0][RTW89_MKK][1][115] = 127, -+ [0][0][1][0][RTW89_MKK][0][115] = 127, -+ [0][0][1][0][RTW89_IC][1][115] = 127, -+ [0][0][1][0][RTW89_KCC][1][115] = 127, -+ [0][0][1][0][RTW89_KCC][0][115] = 127, -+ [0][0][1][0][RTW89_ACMA][1][115] = 127, -+ [0][0][1][0][RTW89_ACMA][0][115] = 127, -+ [0][0][1][0][RTW89_CHILE][1][115] = 127, -+ [0][0][1][0][RTW89_QATAR][1][115] = 127, -+ [0][0][1][0][RTW89_QATAR][0][115] = 127, -+ [0][0][1][0][RTW89_UK][1][115] = 127, -+ [0][0][1][0][RTW89_UK][0][115] = 127, -+ [0][0][1][0][RTW89_FCC][1][117] = 127, -+ [0][0][1][0][RTW89_FCC][2][117] = 127, -+ [0][0][1][0][RTW89_ETSI][1][117] = 127, -+ [0][0][1][0][RTW89_ETSI][0][117] = 127, -+ [0][0][1][0][RTW89_MKK][1][117] = 127, -+ [0][0][1][0][RTW89_MKK][0][117] = 127, -+ [0][0][1][0][RTW89_IC][1][117] = 127, -+ [0][0][1][0][RTW89_KCC][1][117] = 127, -+ [0][0][1][0][RTW89_KCC][0][117] = 127, -+ [0][0][1][0][RTW89_ACMA][1][117] = 127, -+ [0][0][1][0][RTW89_ACMA][0][117] = 127, -+ [0][0][1][0][RTW89_CHILE][1][117] = 127, -+ [0][0][1][0][RTW89_QATAR][1][117] = 127, -+ [0][0][1][0][RTW89_QATAR][0][117] = 127, -+ [0][0][1][0][RTW89_UK][1][117] = 127, -+ [0][0][1][0][RTW89_UK][0][117] = 127, -+ [0][0][1][0][RTW89_FCC][1][119] = 127, -+ [0][0][1][0][RTW89_FCC][2][119] = 127, -+ [0][0][1][0][RTW89_ETSI][1][119] = 127, -+ [0][0][1][0][RTW89_ETSI][0][119] = 127, -+ [0][0][1][0][RTW89_MKK][1][119] = 127, -+ [0][0][1][0][RTW89_MKK][0][119] = 127, -+ [0][0][1][0][RTW89_IC][1][119] = 127, -+ [0][0][1][0][RTW89_KCC][1][119] = 127, -+ [0][0][1][0][RTW89_KCC][0][119] = 127, -+ [0][0][1][0][RTW89_ACMA][1][119] = 127, -+ [0][0][1][0][RTW89_ACMA][0][119] = 127, -+ [0][0][1][0][RTW89_CHILE][1][119] = 127, -+ [0][0][1][0][RTW89_QATAR][1][119] = 127, -+ [0][0][1][0][RTW89_QATAR][0][119] = 127, -+ [0][0][1][0][RTW89_UK][1][119] = 127, -+ [0][0][1][0][RTW89_UK][0][119] = 127, -+ [0][1][1][0][RTW89_FCC][1][0] = -2, -+ [0][1][1][0][RTW89_FCC][2][0] = 54, -+ [0][1][1][0][RTW89_ETSI][1][0] = 54, -+ [0][1][1][0][RTW89_ETSI][0][0] = 18, -+ [0][1][1][0][RTW89_MKK][1][0] = 56, -+ [0][1][1][0][RTW89_MKK][0][0] = 16, -+ [0][1][1][0][RTW89_IC][1][0] = -2, -+ [0][1][1][0][RTW89_KCC][1][0] = 12, -+ [0][1][1][0][RTW89_KCC][0][0] = 10, -+ [0][1][1][0][RTW89_ACMA][1][0] = 54, -+ [0][1][1][0][RTW89_ACMA][0][0] = 18, -+ [0][1][1][0][RTW89_CHILE][1][0] = -2, -+ [0][1][1][0][RTW89_QATAR][1][0] = 54, -+ [0][1][1][0][RTW89_QATAR][0][0] = 18, -+ [0][1][1][0][RTW89_UK][1][0] = 54, -+ [0][1][1][0][RTW89_UK][0][0] = 18, -+ [0][1][1][0][RTW89_FCC][1][2] = -4, -+ [0][1][1][0][RTW89_FCC][2][2] = 54, -+ [0][1][1][0][RTW89_ETSI][1][2] = 54, -+ [0][1][1][0][RTW89_ETSI][0][2] = 18, -+ [0][1][1][0][RTW89_MKK][1][2] = 54, -+ [0][1][1][0][RTW89_MKK][0][2] = 16, -+ [0][1][1][0][RTW89_IC][1][2] = -4, -+ [0][1][1][0][RTW89_KCC][1][2] = 12, -+ [0][1][1][0][RTW89_KCC][0][2] = 12, -+ [0][1][1][0][RTW89_ACMA][1][2] = 54, -+ [0][1][1][0][RTW89_ACMA][0][2] = 18, -+ [0][1][1][0][RTW89_CHILE][1][2] = -4, -+ [0][1][1][0][RTW89_QATAR][1][2] = 54, -+ [0][1][1][0][RTW89_QATAR][0][2] = 18, -+ [0][1][1][0][RTW89_UK][1][2] = 54, -+ [0][1][1][0][RTW89_UK][0][2] = 18, -+ [0][1][1][0][RTW89_FCC][1][4] = -4, -+ [0][1][1][0][RTW89_FCC][2][4] = 54, -+ [0][1][1][0][RTW89_ETSI][1][4] = 54, -+ [0][1][1][0][RTW89_ETSI][0][4] = 18, -+ [0][1][1][0][RTW89_MKK][1][4] = 54, -+ [0][1][1][0][RTW89_MKK][0][4] = 16, -+ [0][1][1][0][RTW89_IC][1][4] = -4, -+ [0][1][1][0][RTW89_KCC][1][4] = 12, -+ [0][1][1][0][RTW89_KCC][0][4] = 12, -+ [0][1][1][0][RTW89_ACMA][1][4] = 54, -+ [0][1][1][0][RTW89_ACMA][0][4] = 18, -+ [0][1][1][0][RTW89_CHILE][1][4] = -4, -+ [0][1][1][0][RTW89_QATAR][1][4] = 54, -+ [0][1][1][0][RTW89_QATAR][0][4] = 18, -+ [0][1][1][0][RTW89_UK][1][4] = 54, -+ [0][1][1][0][RTW89_UK][0][4] = 18, -+ [0][1][1][0][RTW89_FCC][1][6] = -4, -+ [0][1][1][0][RTW89_FCC][2][6] = 54, -+ [0][1][1][0][RTW89_ETSI][1][6] = 54, -+ [0][1][1][0][RTW89_ETSI][0][6] = 18, -+ [0][1][1][0][RTW89_MKK][1][6] = 54, -+ [0][1][1][0][RTW89_MKK][0][6] = 16, -+ [0][1][1][0][RTW89_IC][1][6] = -4, -+ [0][1][1][0][RTW89_KCC][1][6] = 12, -+ [0][1][1][0][RTW89_KCC][0][6] = 12, -+ [0][1][1][0][RTW89_ACMA][1][6] = 54, -+ [0][1][1][0][RTW89_ACMA][0][6] = 18, -+ [0][1][1][0][RTW89_CHILE][1][6] = -4, -+ [0][1][1][0][RTW89_QATAR][1][6] = 54, -+ [0][1][1][0][RTW89_QATAR][0][6] = 18, -+ [0][1][1][0][RTW89_UK][1][6] = 54, -+ [0][1][1][0][RTW89_UK][0][6] = 18, -+ [0][1][1][0][RTW89_FCC][1][8] = -4, -+ [0][1][1][0][RTW89_FCC][2][8] = 54, -+ [0][1][1][0][RTW89_ETSI][1][8] = 54, -+ [0][1][1][0][RTW89_ETSI][0][8] = 18, -+ [0][1][1][0][RTW89_MKK][1][8] = 54, -+ [0][1][1][0][RTW89_MKK][0][8] = 16, -+ [0][1][1][0][RTW89_IC][1][8] = -4, -+ [0][1][1][0][RTW89_KCC][1][8] = 12, -+ [0][1][1][0][RTW89_KCC][0][8] = 12, -+ [0][1][1][0][RTW89_ACMA][1][8] = 54, -+ [0][1][1][0][RTW89_ACMA][0][8] = 18, -+ [0][1][1][0][RTW89_CHILE][1][8] = -4, -+ [0][1][1][0][RTW89_QATAR][1][8] = 54, -+ [0][1][1][0][RTW89_QATAR][0][8] = 18, -+ [0][1][1][0][RTW89_UK][1][8] = 54, -+ [0][1][1][0][RTW89_UK][0][8] = 18, -+ [0][1][1][0][RTW89_FCC][1][10] = -4, -+ [0][1][1][0][RTW89_FCC][2][10] = 54, -+ [0][1][1][0][RTW89_ETSI][1][10] = 54, -+ [0][1][1][0][RTW89_ETSI][0][10] = 18, -+ [0][1][1][0][RTW89_MKK][1][10] = 54, -+ [0][1][1][0][RTW89_MKK][0][10] = 16, -+ [0][1][1][0][RTW89_IC][1][10] = -4, -+ [0][1][1][0][RTW89_KCC][1][10] = 12, -+ [0][1][1][0][RTW89_KCC][0][10] = 12, -+ [0][1][1][0][RTW89_ACMA][1][10] = 54, -+ [0][1][1][0][RTW89_ACMA][0][10] = 18, -+ [0][1][1][0][RTW89_CHILE][1][10] = -4, -+ [0][1][1][0][RTW89_QATAR][1][10] = 54, -+ [0][1][1][0][RTW89_QATAR][0][10] = 18, -+ [0][1][1][0][RTW89_UK][1][10] = 54, -+ [0][1][1][0][RTW89_UK][0][10] = 18, -+ [0][1][1][0][RTW89_FCC][1][12] = -4, -+ [0][1][1][0][RTW89_FCC][2][12] = 54, -+ [0][1][1][0][RTW89_ETSI][1][12] = 54, -+ [0][1][1][0][RTW89_ETSI][0][12] = 18, -+ [0][1][1][0][RTW89_MKK][1][12] = 54, -+ [0][1][1][0][RTW89_MKK][0][12] = 16, -+ [0][1][1][0][RTW89_IC][1][12] = -4, -+ [0][1][1][0][RTW89_KCC][1][12] = 12, -+ [0][1][1][0][RTW89_KCC][0][12] = 12, -+ [0][1][1][0][RTW89_ACMA][1][12] = 54, -+ [0][1][1][0][RTW89_ACMA][0][12] = 18, -+ [0][1][1][0][RTW89_CHILE][1][12] = -4, -+ [0][1][1][0][RTW89_QATAR][1][12] = 54, -+ [0][1][1][0][RTW89_QATAR][0][12] = 18, -+ [0][1][1][0][RTW89_UK][1][12] = 54, -+ [0][1][1][0][RTW89_UK][0][12] = 18, -+ [0][1][1][0][RTW89_FCC][1][14] = -4, -+ [0][1][1][0][RTW89_FCC][2][14] = 54, -+ [0][1][1][0][RTW89_ETSI][1][14] = 54, -+ [0][1][1][0][RTW89_ETSI][0][14] = 18, -+ [0][1][1][0][RTW89_MKK][1][14] = 54, -+ [0][1][1][0][RTW89_MKK][0][14] = 16, -+ [0][1][1][0][RTW89_IC][1][14] = -4, -+ [0][1][1][0][RTW89_KCC][1][14] = 12, -+ [0][1][1][0][RTW89_KCC][0][14] = 12, -+ [0][1][1][0][RTW89_ACMA][1][14] = 54, -+ [0][1][1][0][RTW89_ACMA][0][14] = 18, -+ [0][1][1][0][RTW89_CHILE][1][14] = -4, -+ [0][1][1][0][RTW89_QATAR][1][14] = 54, -+ [0][1][1][0][RTW89_QATAR][0][14] = 18, -+ [0][1][1][0][RTW89_UK][1][14] = 54, -+ [0][1][1][0][RTW89_UK][0][14] = 18, -+ [0][1][1][0][RTW89_FCC][1][15] = -4, -+ [0][1][1][0][RTW89_FCC][2][15] = 54, -+ [0][1][1][0][RTW89_ETSI][1][15] = 54, -+ [0][1][1][0][RTW89_ETSI][0][15] = 18, -+ [0][1][1][0][RTW89_MKK][1][15] = 54, -+ [0][1][1][0][RTW89_MKK][0][15] = 16, -+ [0][1][1][0][RTW89_IC][1][15] = -4, -+ [0][1][1][0][RTW89_KCC][1][15] = 12, -+ [0][1][1][0][RTW89_KCC][0][15] = 12, -+ [0][1][1][0][RTW89_ACMA][1][15] = 54, -+ [0][1][1][0][RTW89_ACMA][0][15] = 18, -+ [0][1][1][0][RTW89_CHILE][1][15] = -4, -+ [0][1][1][0][RTW89_QATAR][1][15] = 54, -+ [0][1][1][0][RTW89_QATAR][0][15] = 18, -+ [0][1][1][0][RTW89_UK][1][15] = 54, -+ [0][1][1][0][RTW89_UK][0][15] = 18, -+ [0][1][1][0][RTW89_FCC][1][17] = -4, -+ [0][1][1][0][RTW89_FCC][2][17] = 54, -+ [0][1][1][0][RTW89_ETSI][1][17] = 54, -+ [0][1][1][0][RTW89_ETSI][0][17] = 18, -+ [0][1][1][0][RTW89_MKK][1][17] = 54, -+ [0][1][1][0][RTW89_MKK][0][17] = 16, -+ [0][1][1][0][RTW89_IC][1][17] = -4, -+ [0][1][1][0][RTW89_KCC][1][17] = 12, -+ [0][1][1][0][RTW89_KCC][0][17] = 12, -+ [0][1][1][0][RTW89_ACMA][1][17] = 54, -+ [0][1][1][0][RTW89_ACMA][0][17] = 18, -+ [0][1][1][0][RTW89_CHILE][1][17] = -4, -+ [0][1][1][0][RTW89_QATAR][1][17] = 54, -+ [0][1][1][0][RTW89_QATAR][0][17] = 18, -+ [0][1][1][0][RTW89_UK][1][17] = 54, -+ [0][1][1][0][RTW89_UK][0][17] = 18, -+ [0][1][1][0][RTW89_FCC][1][19] = -4, -+ [0][1][1][0][RTW89_FCC][2][19] = 54, -+ [0][1][1][0][RTW89_ETSI][1][19] = 54, -+ [0][1][1][0][RTW89_ETSI][0][19] = 18, -+ [0][1][1][0][RTW89_MKK][1][19] = 54, -+ [0][1][1][0][RTW89_MKK][0][19] = 16, -+ [0][1][1][0][RTW89_IC][1][19] = -4, -+ [0][1][1][0][RTW89_KCC][1][19] = 12, -+ [0][1][1][0][RTW89_KCC][0][19] = 12, -+ [0][1][1][0][RTW89_ACMA][1][19] = 54, -+ [0][1][1][0][RTW89_ACMA][0][19] = 18, -+ [0][1][1][0][RTW89_CHILE][1][19] = -4, -+ [0][1][1][0][RTW89_QATAR][1][19] = 54, -+ [0][1][1][0][RTW89_QATAR][0][19] = 18, -+ [0][1][1][0][RTW89_UK][1][19] = 54, -+ [0][1][1][0][RTW89_UK][0][19] = 18, -+ [0][1][1][0][RTW89_FCC][1][21] = -4, -+ [0][1][1][0][RTW89_FCC][2][21] = 54, -+ [0][1][1][0][RTW89_ETSI][1][21] = 54, -+ [0][1][1][0][RTW89_ETSI][0][21] = 18, -+ [0][1][1][0][RTW89_MKK][1][21] = 54, -+ [0][1][1][0][RTW89_MKK][0][21] = 16, -+ [0][1][1][0][RTW89_IC][1][21] = -4, -+ [0][1][1][0][RTW89_KCC][1][21] = 12, -+ [0][1][1][0][RTW89_KCC][0][21] = 12, -+ [0][1][1][0][RTW89_ACMA][1][21] = 54, -+ [0][1][1][0][RTW89_ACMA][0][21] = 18, -+ [0][1][1][0][RTW89_CHILE][1][21] = -4, -+ [0][1][1][0][RTW89_QATAR][1][21] = 54, -+ [0][1][1][0][RTW89_QATAR][0][21] = 18, -+ [0][1][1][0][RTW89_UK][1][21] = 54, -+ [0][1][1][0][RTW89_UK][0][21] = 18, -+ [0][1][1][0][RTW89_FCC][1][23] = -4, -+ [0][1][1][0][RTW89_FCC][2][23] = 68, -+ [0][1][1][0][RTW89_ETSI][1][23] = 54, -+ [0][1][1][0][RTW89_ETSI][0][23] = 18, -+ [0][1][1][0][RTW89_MKK][1][23] = 54, -+ [0][1][1][0][RTW89_MKK][0][23] = 16, -+ [0][1][1][0][RTW89_IC][1][23] = -4, -+ [0][1][1][0][RTW89_KCC][1][23] = 12, -+ [0][1][1][0][RTW89_KCC][0][23] = 10, -+ [0][1][1][0][RTW89_ACMA][1][23] = 54, -+ [0][1][1][0][RTW89_ACMA][0][23] = 18, -+ [0][1][1][0][RTW89_CHILE][1][23] = -4, -+ [0][1][1][0][RTW89_QATAR][1][23] = 54, -+ [0][1][1][0][RTW89_QATAR][0][23] = 18, -+ [0][1][1][0][RTW89_UK][1][23] = 54, -+ [0][1][1][0][RTW89_UK][0][23] = 18, -+ [0][1][1][0][RTW89_FCC][1][25] = -4, -+ [0][1][1][0][RTW89_FCC][2][25] = 68, -+ [0][1][1][0][RTW89_ETSI][1][25] = 54, -+ [0][1][1][0][RTW89_ETSI][0][25] = 18, -+ [0][1][1][0][RTW89_MKK][1][25] = 54, -+ [0][1][1][0][RTW89_MKK][0][25] = 16, -+ [0][1][1][0][RTW89_IC][1][25] = -4, -+ [0][1][1][0][RTW89_KCC][1][25] = 12, -+ [0][1][1][0][RTW89_KCC][0][25] = 14, -+ [0][1][1][0][RTW89_ACMA][1][25] = 54, -+ [0][1][1][0][RTW89_ACMA][0][25] = 18, -+ [0][1][1][0][RTW89_CHILE][1][25] = -4, -+ [0][1][1][0][RTW89_QATAR][1][25] = 54, -+ [0][1][1][0][RTW89_QATAR][0][25] = 18, -+ [0][1][1][0][RTW89_UK][1][25] = 54, -+ [0][1][1][0][RTW89_UK][0][25] = 18, -+ [0][1][1][0][RTW89_FCC][1][27] = -4, -+ [0][1][1][0][RTW89_FCC][2][27] = 68, -+ [0][1][1][0][RTW89_ETSI][1][27] = 54, -+ [0][1][1][0][RTW89_ETSI][0][27] = 18, -+ [0][1][1][0][RTW89_MKK][1][27] = 54, -+ [0][1][1][0][RTW89_MKK][0][27] = 16, -+ [0][1][1][0][RTW89_IC][1][27] = -4, -+ [0][1][1][0][RTW89_KCC][1][27] = 12, -+ [0][1][1][0][RTW89_KCC][0][27] = 14, -+ [0][1][1][0][RTW89_ACMA][1][27] = 54, -+ [0][1][1][0][RTW89_ACMA][0][27] = 18, -+ [0][1][1][0][RTW89_CHILE][1][27] = -4, -+ [0][1][1][0][RTW89_QATAR][1][27] = 54, -+ [0][1][1][0][RTW89_QATAR][0][27] = 18, -+ [0][1][1][0][RTW89_UK][1][27] = 54, -+ [0][1][1][0][RTW89_UK][0][27] = 18, -+ [0][1][1][0][RTW89_FCC][1][29] = -4, -+ [0][1][1][0][RTW89_FCC][2][29] = 68, -+ [0][1][1][0][RTW89_ETSI][1][29] = 54, -+ [0][1][1][0][RTW89_ETSI][0][29] = 18, -+ [0][1][1][0][RTW89_MKK][1][29] = 54, -+ [0][1][1][0][RTW89_MKK][0][29] = 16, -+ [0][1][1][0][RTW89_IC][1][29] = -4, -+ [0][1][1][0][RTW89_KCC][1][29] = 12, -+ [0][1][1][0][RTW89_KCC][0][29] = 14, -+ [0][1][1][0][RTW89_ACMA][1][29] = 54, -+ [0][1][1][0][RTW89_ACMA][0][29] = 18, -+ [0][1][1][0][RTW89_CHILE][1][29] = -4, -+ [0][1][1][0][RTW89_QATAR][1][29] = 54, -+ [0][1][1][0][RTW89_QATAR][0][29] = 18, -+ [0][1][1][0][RTW89_UK][1][29] = 54, -+ [0][1][1][0][RTW89_UK][0][29] = 18, -+ [0][1][1][0][RTW89_FCC][1][30] = -4, -+ [0][1][1][0][RTW89_FCC][2][30] = 68, -+ [0][1][1][0][RTW89_ETSI][1][30] = 54, -+ [0][1][1][0][RTW89_ETSI][0][30] = 18, -+ [0][1][1][0][RTW89_MKK][1][30] = 54, -+ [0][1][1][0][RTW89_MKK][0][30] = 16, -+ [0][1][1][0][RTW89_IC][1][30] = -4, -+ [0][1][1][0][RTW89_KCC][1][30] = 12, -+ [0][1][1][0][RTW89_KCC][0][30] = 14, -+ [0][1][1][0][RTW89_ACMA][1][30] = 54, -+ [0][1][1][0][RTW89_ACMA][0][30] = 18, -+ [0][1][1][0][RTW89_CHILE][1][30] = -4, -+ [0][1][1][0][RTW89_QATAR][1][30] = 54, -+ [0][1][1][0][RTW89_QATAR][0][30] = 18, -+ [0][1][1][0][RTW89_UK][1][30] = 54, -+ [0][1][1][0][RTW89_UK][0][30] = 18, -+ [0][1][1][0][RTW89_FCC][1][32] = -4, -+ [0][1][1][0][RTW89_FCC][2][32] = 68, -+ [0][1][1][0][RTW89_ETSI][1][32] = 54, -+ [0][1][1][0][RTW89_ETSI][0][32] = 18, -+ [0][1][1][0][RTW89_MKK][1][32] = 54, -+ [0][1][1][0][RTW89_MKK][0][32] = 16, -+ [0][1][1][0][RTW89_IC][1][32] = -4, -+ [0][1][1][0][RTW89_KCC][1][32] = 12, -+ [0][1][1][0][RTW89_KCC][0][32] = 14, -+ [0][1][1][0][RTW89_ACMA][1][32] = 54, -+ [0][1][1][0][RTW89_ACMA][0][32] = 18, -+ [0][1][1][0][RTW89_CHILE][1][32] = -4, -+ [0][1][1][0][RTW89_QATAR][1][32] = 54, -+ [0][1][1][0][RTW89_QATAR][0][32] = 18, -+ [0][1][1][0][RTW89_UK][1][32] = 54, -+ [0][1][1][0][RTW89_UK][0][32] = 18, -+ [0][1][1][0][RTW89_FCC][1][34] = -4, -+ [0][1][1][0][RTW89_FCC][2][34] = 68, -+ [0][1][1][0][RTW89_ETSI][1][34] = 54, -+ [0][1][1][0][RTW89_ETSI][0][34] = 18, -+ [0][1][1][0][RTW89_MKK][1][34] = 54, -+ [0][1][1][0][RTW89_MKK][0][34] = 16, -+ [0][1][1][0][RTW89_IC][1][34] = -4, -+ [0][1][1][0][RTW89_KCC][1][34] = 12, -+ [0][1][1][0][RTW89_KCC][0][34] = 14, -+ [0][1][1][0][RTW89_ACMA][1][34] = 54, -+ [0][1][1][0][RTW89_ACMA][0][34] = 18, -+ [0][1][1][0][RTW89_CHILE][1][34] = -4, -+ [0][1][1][0][RTW89_QATAR][1][34] = 54, -+ [0][1][1][0][RTW89_QATAR][0][34] = 18, -+ [0][1][1][0][RTW89_UK][1][34] = 54, -+ [0][1][1][0][RTW89_UK][0][34] = 18, -+ [0][1][1][0][RTW89_FCC][1][36] = -4, -+ [0][1][1][0][RTW89_FCC][2][36] = 68, -+ [0][1][1][0][RTW89_ETSI][1][36] = 54, -+ [0][1][1][0][RTW89_ETSI][0][36] = 18, -+ [0][1][1][0][RTW89_MKK][1][36] = 54, -+ [0][1][1][0][RTW89_MKK][0][36] = 16, -+ [0][1][1][0][RTW89_IC][1][36] = -4, -+ [0][1][1][0][RTW89_KCC][1][36] = 12, -+ [0][1][1][0][RTW89_KCC][0][36] = 14, -+ [0][1][1][0][RTW89_ACMA][1][36] = 54, -+ [0][1][1][0][RTW89_ACMA][0][36] = 18, -+ [0][1][1][0][RTW89_CHILE][1][36] = -4, -+ [0][1][1][0][RTW89_QATAR][1][36] = 54, -+ [0][1][1][0][RTW89_QATAR][0][36] = 18, -+ [0][1][1][0][RTW89_UK][1][36] = 54, -+ [0][1][1][0][RTW89_UK][0][36] = 18, -+ [0][1][1][0][RTW89_FCC][1][38] = -4, -+ [0][1][1][0][RTW89_FCC][2][38] = 68, -+ [0][1][1][0][RTW89_ETSI][1][38] = 54, -+ [0][1][1][0][RTW89_ETSI][0][38] = 18, -+ [0][1][1][0][RTW89_MKK][1][38] = 54, -+ [0][1][1][0][RTW89_MKK][0][38] = 16, -+ [0][1][1][0][RTW89_IC][1][38] = -4, -+ [0][1][1][0][RTW89_KCC][1][38] = 12, -+ [0][1][1][0][RTW89_KCC][0][38] = 14, -+ [0][1][1][0][RTW89_ACMA][1][38] = 54, -+ [0][1][1][0][RTW89_ACMA][0][38] = 18, -+ [0][1][1][0][RTW89_CHILE][1][38] = -4, -+ [0][1][1][0][RTW89_QATAR][1][38] = 54, -+ [0][1][1][0][RTW89_QATAR][0][38] = 18, -+ [0][1][1][0][RTW89_UK][1][38] = 54, -+ [0][1][1][0][RTW89_UK][0][38] = 18, -+ [0][1][1][0][RTW89_FCC][1][40] = -4, -+ [0][1][1][0][RTW89_FCC][2][40] = 68, -+ [0][1][1][0][RTW89_ETSI][1][40] = 54, -+ [0][1][1][0][RTW89_ETSI][0][40] = 18, -+ [0][1][1][0][RTW89_MKK][1][40] = 54, -+ [0][1][1][0][RTW89_MKK][0][40] = 16, -+ [0][1][1][0][RTW89_IC][1][40] = -4, -+ [0][1][1][0][RTW89_KCC][1][40] = 12, -+ [0][1][1][0][RTW89_KCC][0][40] = 14, -+ [0][1][1][0][RTW89_ACMA][1][40] = 54, -+ [0][1][1][0][RTW89_ACMA][0][40] = 18, -+ [0][1][1][0][RTW89_CHILE][1][40] = -4, -+ [0][1][1][0][RTW89_QATAR][1][40] = 54, -+ [0][1][1][0][RTW89_QATAR][0][40] = 18, -+ [0][1][1][0][RTW89_UK][1][40] = 54, -+ [0][1][1][0][RTW89_UK][0][40] = 18, -+ [0][1][1][0][RTW89_FCC][1][42] = -4, -+ [0][1][1][0][RTW89_FCC][2][42] = 68, -+ [0][1][1][0][RTW89_ETSI][1][42] = 54, -+ [0][1][1][0][RTW89_ETSI][0][42] = 18, -+ [0][1][1][0][RTW89_MKK][1][42] = 54, -+ [0][1][1][0][RTW89_MKK][0][42] = 16, -+ [0][1][1][0][RTW89_IC][1][42] = -4, -+ [0][1][1][0][RTW89_KCC][1][42] = 12, -+ [0][1][1][0][RTW89_KCC][0][42] = 14, -+ [0][1][1][0][RTW89_ACMA][1][42] = 54, -+ [0][1][1][0][RTW89_ACMA][0][42] = 18, -+ [0][1][1][0][RTW89_CHILE][1][42] = -4, -+ [0][1][1][0][RTW89_QATAR][1][42] = 54, -+ [0][1][1][0][RTW89_QATAR][0][42] = 18, -+ [0][1][1][0][RTW89_UK][1][42] = 54, -+ [0][1][1][0][RTW89_UK][0][42] = 18, -+ [0][1][1][0][RTW89_FCC][1][44] = -2, -+ [0][1][1][0][RTW89_FCC][2][44] = 68, -+ [0][1][1][0][RTW89_ETSI][1][44] = 54, -+ [0][1][1][0][RTW89_ETSI][0][44] = 18, -+ [0][1][1][0][RTW89_MKK][1][44] = 34, -+ [0][1][1][0][RTW89_MKK][0][44] = 16, -+ [0][1][1][0][RTW89_IC][1][44] = -2, -+ [0][1][1][0][RTW89_KCC][1][44] = 12, -+ [0][1][1][0][RTW89_KCC][0][44] = 12, -+ [0][1][1][0][RTW89_ACMA][1][44] = 54, -+ [0][1][1][0][RTW89_ACMA][0][44] = 18, -+ [0][1][1][0][RTW89_CHILE][1][44] = -2, -+ [0][1][1][0][RTW89_QATAR][1][44] = 54, -+ [0][1][1][0][RTW89_QATAR][0][44] = 18, -+ [0][1][1][0][RTW89_UK][1][44] = 54, -+ [0][1][1][0][RTW89_UK][0][44] = 18, -+ [0][1][1][0][RTW89_FCC][1][45] = -2, -+ [0][1][1][0][RTW89_FCC][2][45] = 127, -+ [0][1][1][0][RTW89_ETSI][1][45] = 127, -+ [0][1][1][0][RTW89_ETSI][0][45] = 127, -+ [0][1][1][0][RTW89_MKK][1][45] = 127, -+ [0][1][1][0][RTW89_MKK][0][45] = 127, -+ [0][1][1][0][RTW89_IC][1][45] = -2, -+ [0][1][1][0][RTW89_KCC][1][45] = 12, -+ [0][1][1][0][RTW89_KCC][0][45] = 127, -+ [0][1][1][0][RTW89_ACMA][1][45] = 127, -+ [0][1][1][0][RTW89_ACMA][0][45] = 127, -+ [0][1][1][0][RTW89_CHILE][1][45] = -2, -+ [0][1][1][0][RTW89_QATAR][1][45] = 127, -+ [0][1][1][0][RTW89_QATAR][0][45] = 127, -+ [0][1][1][0][RTW89_UK][1][45] = 127, -+ [0][1][1][0][RTW89_UK][0][45] = 127, -+ [0][1][1][0][RTW89_FCC][1][47] = -2, -+ [0][1][1][0][RTW89_FCC][2][47] = 127, -+ [0][1][1][0][RTW89_ETSI][1][47] = 127, -+ [0][1][1][0][RTW89_ETSI][0][47] = 127, -+ [0][1][1][0][RTW89_MKK][1][47] = 127, -+ [0][1][1][0][RTW89_MKK][0][47] = 127, -+ [0][1][1][0][RTW89_IC][1][47] = -2, -+ [0][1][1][0][RTW89_KCC][1][47] = 12, -+ [0][1][1][0][RTW89_KCC][0][47] = 127, -+ [0][1][1][0][RTW89_ACMA][1][47] = 127, -+ [0][1][1][0][RTW89_ACMA][0][47] = 127, -+ [0][1][1][0][RTW89_CHILE][1][47] = -2, -+ [0][1][1][0][RTW89_QATAR][1][47] = 127, -+ [0][1][1][0][RTW89_QATAR][0][47] = 127, -+ [0][1][1][0][RTW89_UK][1][47] = 127, -+ [0][1][1][0][RTW89_UK][0][47] = 127, -+ [0][1][1][0][RTW89_FCC][1][49] = -2, -+ [0][1][1][0][RTW89_FCC][2][49] = 127, -+ [0][1][1][0][RTW89_ETSI][1][49] = 127, -+ [0][1][1][0][RTW89_ETSI][0][49] = 127, -+ [0][1][1][0][RTW89_MKK][1][49] = 127, -+ [0][1][1][0][RTW89_MKK][0][49] = 127, -+ [0][1][1][0][RTW89_IC][1][49] = -2, -+ [0][1][1][0][RTW89_KCC][1][49] = 12, -+ [0][1][1][0][RTW89_KCC][0][49] = 127, -+ [0][1][1][0][RTW89_ACMA][1][49] = 127, -+ [0][1][1][0][RTW89_ACMA][0][49] = 127, -+ [0][1][1][0][RTW89_CHILE][1][49] = -2, -+ [0][1][1][0][RTW89_QATAR][1][49] = 127, -+ [0][1][1][0][RTW89_QATAR][0][49] = 127, -+ [0][1][1][0][RTW89_UK][1][49] = 127, -+ [0][1][1][0][RTW89_UK][0][49] = 127, -+ [0][1][1][0][RTW89_FCC][1][51] = -2, -+ [0][1][1][0][RTW89_FCC][2][51] = 127, -+ [0][1][1][0][RTW89_ETSI][1][51] = 127, -+ [0][1][1][0][RTW89_ETSI][0][51] = 127, -+ [0][1][1][0][RTW89_MKK][1][51] = 127, -+ [0][1][1][0][RTW89_MKK][0][51] = 127, -+ [0][1][1][0][RTW89_IC][1][51] = -2, -+ [0][1][1][0][RTW89_KCC][1][51] = 12, -+ [0][1][1][0][RTW89_KCC][0][51] = 127, -+ [0][1][1][0][RTW89_ACMA][1][51] = 127, -+ [0][1][1][0][RTW89_ACMA][0][51] = 127, -+ [0][1][1][0][RTW89_CHILE][1][51] = -2, -+ [0][1][1][0][RTW89_QATAR][1][51] = 127, -+ [0][1][1][0][RTW89_QATAR][0][51] = 127, -+ [0][1][1][0][RTW89_UK][1][51] = 127, -+ [0][1][1][0][RTW89_UK][0][51] = 127, -+ [0][1][1][0][RTW89_FCC][1][53] = -2, -+ [0][1][1][0][RTW89_FCC][2][53] = 127, -+ [0][1][1][0][RTW89_ETSI][1][53] = 127, -+ [0][1][1][0][RTW89_ETSI][0][53] = 127, -+ [0][1][1][0][RTW89_MKK][1][53] = 127, -+ [0][1][1][0][RTW89_MKK][0][53] = 127, -+ [0][1][1][0][RTW89_IC][1][53] = -2, -+ [0][1][1][0][RTW89_KCC][1][53] = 12, -+ [0][1][1][0][RTW89_KCC][0][53] = 127, -+ [0][1][1][0][RTW89_ACMA][1][53] = 127, -+ [0][1][1][0][RTW89_ACMA][0][53] = 127, -+ [0][1][1][0][RTW89_CHILE][1][53] = -2, -+ [0][1][1][0][RTW89_QATAR][1][53] = 127, -+ [0][1][1][0][RTW89_QATAR][0][53] = 127, -+ [0][1][1][0][RTW89_UK][1][53] = 127, -+ [0][1][1][0][RTW89_UK][0][53] = 127, -+ [0][1][1][0][RTW89_FCC][1][55] = -2, -+ [0][1][1][0][RTW89_FCC][2][55] = 68, -+ [0][1][1][0][RTW89_ETSI][1][55] = 127, -+ [0][1][1][0][RTW89_ETSI][0][55] = 127, -+ [0][1][1][0][RTW89_MKK][1][55] = 127, -+ [0][1][1][0][RTW89_MKK][0][55] = 127, -+ [0][1][1][0][RTW89_IC][1][55] = -2, -+ [0][1][1][0][RTW89_KCC][1][55] = 12, -+ [0][1][1][0][RTW89_KCC][0][55] = 127, -+ [0][1][1][0][RTW89_ACMA][1][55] = 127, -+ [0][1][1][0][RTW89_ACMA][0][55] = 127, -+ [0][1][1][0][RTW89_CHILE][1][55] = -2, -+ [0][1][1][0][RTW89_QATAR][1][55] = 127, -+ [0][1][1][0][RTW89_QATAR][0][55] = 127, -+ [0][1][1][0][RTW89_UK][1][55] = 127, -+ [0][1][1][0][RTW89_UK][0][55] = 127, -+ [0][1][1][0][RTW89_FCC][1][57] = -2, -+ [0][1][1][0][RTW89_FCC][2][57] = 68, -+ [0][1][1][0][RTW89_ETSI][1][57] = 127, -+ [0][1][1][0][RTW89_ETSI][0][57] = 127, -+ [0][1][1][0][RTW89_MKK][1][57] = 127, -+ [0][1][1][0][RTW89_MKK][0][57] = 127, -+ [0][1][1][0][RTW89_IC][1][57] = -2, -+ [0][1][1][0][RTW89_KCC][1][57] = 12, -+ [0][1][1][0][RTW89_KCC][0][57] = 127, -+ [0][1][1][0][RTW89_ACMA][1][57] = 127, -+ [0][1][1][0][RTW89_ACMA][0][57] = 127, -+ [0][1][1][0][RTW89_CHILE][1][57] = -2, -+ [0][1][1][0][RTW89_QATAR][1][57] = 127, -+ [0][1][1][0][RTW89_QATAR][0][57] = 127, -+ [0][1][1][0][RTW89_UK][1][57] = 127, -+ [0][1][1][0][RTW89_UK][0][57] = 127, -+ [0][1][1][0][RTW89_FCC][1][59] = -2, -+ [0][1][1][0][RTW89_FCC][2][59] = 68, -+ [0][1][1][0][RTW89_ETSI][1][59] = 127, -+ [0][1][1][0][RTW89_ETSI][0][59] = 127, -+ [0][1][1][0][RTW89_MKK][1][59] = 127, -+ [0][1][1][0][RTW89_MKK][0][59] = 127, -+ [0][1][1][0][RTW89_IC][1][59] = -2, -+ [0][1][1][0][RTW89_KCC][1][59] = 12, -+ [0][1][1][0][RTW89_KCC][0][59] = 127, -+ [0][1][1][0][RTW89_ACMA][1][59] = 127, -+ [0][1][1][0][RTW89_ACMA][0][59] = 127, -+ [0][1][1][0][RTW89_CHILE][1][59] = -2, -+ [0][1][1][0][RTW89_QATAR][1][59] = 127, -+ [0][1][1][0][RTW89_QATAR][0][59] = 127, -+ [0][1][1][0][RTW89_UK][1][59] = 127, -+ [0][1][1][0][RTW89_UK][0][59] = 127, -+ [0][1][1][0][RTW89_FCC][1][60] = -2, -+ [0][1][1][0][RTW89_FCC][2][60] = 68, -+ [0][1][1][0][RTW89_ETSI][1][60] = 127, -+ [0][1][1][0][RTW89_ETSI][0][60] = 127, -+ [0][1][1][0][RTW89_MKK][1][60] = 127, -+ [0][1][1][0][RTW89_MKK][0][60] = 127, -+ [0][1][1][0][RTW89_IC][1][60] = -2, -+ [0][1][1][0][RTW89_KCC][1][60] = 12, -+ [0][1][1][0][RTW89_KCC][0][60] = 127, -+ [0][1][1][0][RTW89_ACMA][1][60] = 127, -+ [0][1][1][0][RTW89_ACMA][0][60] = 127, -+ [0][1][1][0][RTW89_CHILE][1][60] = -2, -+ [0][1][1][0][RTW89_QATAR][1][60] = 127, -+ [0][1][1][0][RTW89_QATAR][0][60] = 127, -+ [0][1][1][0][RTW89_UK][1][60] = 127, -+ [0][1][1][0][RTW89_UK][0][60] = 127, -+ [0][1][1][0][RTW89_FCC][1][62] = -2, -+ [0][1][1][0][RTW89_FCC][2][62] = 68, -+ [0][1][1][0][RTW89_ETSI][1][62] = 127, -+ [0][1][1][0][RTW89_ETSI][0][62] = 127, -+ [0][1][1][0][RTW89_MKK][1][62] = 127, -+ [0][1][1][0][RTW89_MKK][0][62] = 127, -+ [0][1][1][0][RTW89_IC][1][62] = -2, -+ [0][1][1][0][RTW89_KCC][1][62] = 12, -+ [0][1][1][0][RTW89_KCC][0][62] = 127, -+ [0][1][1][0][RTW89_ACMA][1][62] = 127, -+ [0][1][1][0][RTW89_ACMA][0][62] = 127, -+ [0][1][1][0][RTW89_CHILE][1][62] = -2, -+ [0][1][1][0][RTW89_QATAR][1][62] = 127, -+ [0][1][1][0][RTW89_QATAR][0][62] = 127, -+ [0][1][1][0][RTW89_UK][1][62] = 127, -+ [0][1][1][0][RTW89_UK][0][62] = 127, -+ [0][1][1][0][RTW89_FCC][1][64] = -2, -+ [0][1][1][0][RTW89_FCC][2][64] = 68, -+ [0][1][1][0][RTW89_ETSI][1][64] = 127, -+ [0][1][1][0][RTW89_ETSI][0][64] = 127, -+ [0][1][1][0][RTW89_MKK][1][64] = 127, -+ [0][1][1][0][RTW89_MKK][0][64] = 127, -+ [0][1][1][0][RTW89_IC][1][64] = -2, -+ [0][1][1][0][RTW89_KCC][1][64] = 12, -+ [0][1][1][0][RTW89_KCC][0][64] = 127, -+ [0][1][1][0][RTW89_ACMA][1][64] = 127, -+ [0][1][1][0][RTW89_ACMA][0][64] = 127, -+ [0][1][1][0][RTW89_CHILE][1][64] = -2, -+ [0][1][1][0][RTW89_QATAR][1][64] = 127, -+ [0][1][1][0][RTW89_QATAR][0][64] = 127, -+ [0][1][1][0][RTW89_UK][1][64] = 127, -+ [0][1][1][0][RTW89_UK][0][64] = 127, -+ [0][1][1][0][RTW89_FCC][1][66] = -2, -+ [0][1][1][0][RTW89_FCC][2][66] = 68, -+ [0][1][1][0][RTW89_ETSI][1][66] = 127, -+ [0][1][1][0][RTW89_ETSI][0][66] = 127, -+ [0][1][1][0][RTW89_MKK][1][66] = 127, -+ [0][1][1][0][RTW89_MKK][0][66] = 127, -+ [0][1][1][0][RTW89_IC][1][66] = -2, -+ [0][1][1][0][RTW89_KCC][1][66] = 12, -+ [0][1][1][0][RTW89_KCC][0][66] = 127, -+ [0][1][1][0][RTW89_ACMA][1][66] = 127, -+ [0][1][1][0][RTW89_ACMA][0][66] = 127, -+ [0][1][1][0][RTW89_CHILE][1][66] = -2, -+ [0][1][1][0][RTW89_QATAR][1][66] = 127, -+ [0][1][1][0][RTW89_QATAR][0][66] = 127, -+ [0][1][1][0][RTW89_UK][1][66] = 127, -+ [0][1][1][0][RTW89_UK][0][66] = 127, -+ [0][1][1][0][RTW89_FCC][1][68] = -2, -+ [0][1][1][0][RTW89_FCC][2][68] = 68, -+ [0][1][1][0][RTW89_ETSI][1][68] = 127, -+ [0][1][1][0][RTW89_ETSI][0][68] = 127, -+ [0][1][1][0][RTW89_MKK][1][68] = 127, -+ [0][1][1][0][RTW89_MKK][0][68] = 127, -+ [0][1][1][0][RTW89_IC][1][68] = -2, -+ [0][1][1][0][RTW89_KCC][1][68] = 12, -+ [0][1][1][0][RTW89_KCC][0][68] = 127, -+ [0][1][1][0][RTW89_ACMA][1][68] = 127, -+ [0][1][1][0][RTW89_ACMA][0][68] = 127, -+ [0][1][1][0][RTW89_CHILE][1][68] = -2, -+ [0][1][1][0][RTW89_QATAR][1][68] = 127, -+ [0][1][1][0][RTW89_QATAR][0][68] = 127, -+ [0][1][1][0][RTW89_UK][1][68] = 127, -+ [0][1][1][0][RTW89_UK][0][68] = 127, -+ [0][1][1][0][RTW89_FCC][1][70] = -2, -+ [0][1][1][0][RTW89_FCC][2][70] = 68, -+ [0][1][1][0][RTW89_ETSI][1][70] = 127, -+ [0][1][1][0][RTW89_ETSI][0][70] = 127, -+ [0][1][1][0][RTW89_MKK][1][70] = 127, -+ [0][1][1][0][RTW89_MKK][0][70] = 127, -+ [0][1][1][0][RTW89_IC][1][70] = -2, -+ [0][1][1][0][RTW89_KCC][1][70] = 12, -+ [0][1][1][0][RTW89_KCC][0][70] = 127, -+ [0][1][1][0][RTW89_ACMA][1][70] = 127, -+ [0][1][1][0][RTW89_ACMA][0][70] = 127, -+ [0][1][1][0][RTW89_CHILE][1][70] = -2, -+ [0][1][1][0][RTW89_QATAR][1][70] = 127, -+ [0][1][1][0][RTW89_QATAR][0][70] = 127, -+ [0][1][1][0][RTW89_UK][1][70] = 127, -+ [0][1][1][0][RTW89_UK][0][70] = 127, -+ [0][1][1][0][RTW89_FCC][1][72] = -2, -+ [0][1][1][0][RTW89_FCC][2][72] = 68, -+ [0][1][1][0][RTW89_ETSI][1][72] = 127, -+ [0][1][1][0][RTW89_ETSI][0][72] = 127, -+ [0][1][1][0][RTW89_MKK][1][72] = 127, -+ [0][1][1][0][RTW89_MKK][0][72] = 127, -+ [0][1][1][0][RTW89_IC][1][72] = -2, -+ [0][1][1][0][RTW89_KCC][1][72] = 12, -+ [0][1][1][0][RTW89_KCC][0][72] = 127, -+ [0][1][1][0][RTW89_ACMA][1][72] = 127, -+ [0][1][1][0][RTW89_ACMA][0][72] = 127, -+ [0][1][1][0][RTW89_CHILE][1][72] = -2, -+ [0][1][1][0][RTW89_QATAR][1][72] = 127, -+ [0][1][1][0][RTW89_QATAR][0][72] = 127, -+ [0][1][1][0][RTW89_UK][1][72] = 127, -+ [0][1][1][0][RTW89_UK][0][72] = 127, -+ [0][1][1][0][RTW89_FCC][1][74] = -2, -+ [0][1][1][0][RTW89_FCC][2][74] = 68, -+ [0][1][1][0][RTW89_ETSI][1][74] = 127, -+ [0][1][1][0][RTW89_ETSI][0][74] = 127, -+ [0][1][1][0][RTW89_MKK][1][74] = 127, -+ [0][1][1][0][RTW89_MKK][0][74] = 127, -+ [0][1][1][0][RTW89_IC][1][74] = -2, -+ [0][1][1][0][RTW89_KCC][1][74] = 12, -+ [0][1][1][0][RTW89_KCC][0][74] = 127, -+ [0][1][1][0][RTW89_ACMA][1][74] = 127, -+ [0][1][1][0][RTW89_ACMA][0][74] = 127, -+ [0][1][1][0][RTW89_CHILE][1][74] = -2, -+ [0][1][1][0][RTW89_QATAR][1][74] = 127, -+ [0][1][1][0][RTW89_QATAR][0][74] = 127, -+ [0][1][1][0][RTW89_UK][1][74] = 127, -+ [0][1][1][0][RTW89_UK][0][74] = 127, -+ [0][1][1][0][RTW89_FCC][1][75] = -2, -+ [0][1][1][0][RTW89_FCC][2][75] = 68, -+ [0][1][1][0][RTW89_ETSI][1][75] = 127, -+ [0][1][1][0][RTW89_ETSI][0][75] = 127, -+ [0][1][1][0][RTW89_MKK][1][75] = 127, -+ [0][1][1][0][RTW89_MKK][0][75] = 127, -+ [0][1][1][0][RTW89_IC][1][75] = -2, -+ [0][1][1][0][RTW89_KCC][1][75] = 12, -+ [0][1][1][0][RTW89_KCC][0][75] = 127, -+ [0][1][1][0][RTW89_ACMA][1][75] = 127, -+ [0][1][1][0][RTW89_ACMA][0][75] = 127, -+ [0][1][1][0][RTW89_CHILE][1][75] = -2, -+ [0][1][1][0][RTW89_QATAR][1][75] = 127, -+ [0][1][1][0][RTW89_QATAR][0][75] = 127, -+ [0][1][1][0][RTW89_UK][1][75] = 127, -+ [0][1][1][0][RTW89_UK][0][75] = 127, -+ [0][1][1][0][RTW89_FCC][1][77] = -2, -+ [0][1][1][0][RTW89_FCC][2][77] = 68, -+ [0][1][1][0][RTW89_ETSI][1][77] = 127, -+ [0][1][1][0][RTW89_ETSI][0][77] = 127, -+ [0][1][1][0][RTW89_MKK][1][77] = 127, -+ [0][1][1][0][RTW89_MKK][0][77] = 127, -+ [0][1][1][0][RTW89_IC][1][77] = -2, -+ [0][1][1][0][RTW89_KCC][1][77] = 12, -+ [0][1][1][0][RTW89_KCC][0][77] = 127, -+ [0][1][1][0][RTW89_ACMA][1][77] = 127, -+ [0][1][1][0][RTW89_ACMA][0][77] = 127, -+ [0][1][1][0][RTW89_CHILE][1][77] = -2, -+ [0][1][1][0][RTW89_QATAR][1][77] = 127, -+ [0][1][1][0][RTW89_QATAR][0][77] = 127, -+ [0][1][1][0][RTW89_UK][1][77] = 127, -+ [0][1][1][0][RTW89_UK][0][77] = 127, -+ [0][1][1][0][RTW89_FCC][1][79] = -2, -+ [0][1][1][0][RTW89_FCC][2][79] = 68, -+ [0][1][1][0][RTW89_ETSI][1][79] = 127, -+ [0][1][1][0][RTW89_ETSI][0][79] = 127, -+ [0][1][1][0][RTW89_MKK][1][79] = 127, -+ [0][1][1][0][RTW89_MKK][0][79] = 127, -+ [0][1][1][0][RTW89_IC][1][79] = -2, -+ [0][1][1][0][RTW89_KCC][1][79] = 12, -+ [0][1][1][0][RTW89_KCC][0][79] = 127, -+ [0][1][1][0][RTW89_ACMA][1][79] = 127, -+ [0][1][1][0][RTW89_ACMA][0][79] = 127, -+ [0][1][1][0][RTW89_CHILE][1][79] = -2, -+ [0][1][1][0][RTW89_QATAR][1][79] = 127, -+ [0][1][1][0][RTW89_QATAR][0][79] = 127, -+ [0][1][1][0][RTW89_UK][1][79] = 127, -+ [0][1][1][0][RTW89_UK][0][79] = 127, -+ [0][1][1][0][RTW89_FCC][1][81] = -2, -+ [0][1][1][0][RTW89_FCC][2][81] = 68, -+ [0][1][1][0][RTW89_ETSI][1][81] = 127, -+ [0][1][1][0][RTW89_ETSI][0][81] = 127, -+ [0][1][1][0][RTW89_MKK][1][81] = 127, -+ [0][1][1][0][RTW89_MKK][0][81] = 127, -+ [0][1][1][0][RTW89_IC][1][81] = -2, -+ [0][1][1][0][RTW89_KCC][1][81] = 12, -+ [0][1][1][0][RTW89_KCC][0][81] = 127, -+ [0][1][1][0][RTW89_ACMA][1][81] = 127, -+ [0][1][1][0][RTW89_ACMA][0][81] = 127, -+ [0][1][1][0][RTW89_CHILE][1][81] = -2, -+ [0][1][1][0][RTW89_QATAR][1][81] = 127, -+ [0][1][1][0][RTW89_QATAR][0][81] = 127, -+ [0][1][1][0][RTW89_UK][1][81] = 127, -+ [0][1][1][0][RTW89_UK][0][81] = 127, -+ [0][1][1][0][RTW89_FCC][1][83] = -2, -+ [0][1][1][0][RTW89_FCC][2][83] = 68, -+ [0][1][1][0][RTW89_ETSI][1][83] = 127, -+ [0][1][1][0][RTW89_ETSI][0][83] = 127, -+ [0][1][1][0][RTW89_MKK][1][83] = 127, -+ [0][1][1][0][RTW89_MKK][0][83] = 127, -+ [0][1][1][0][RTW89_IC][1][83] = -2, -+ [0][1][1][0][RTW89_KCC][1][83] = 20, -+ [0][1][1][0][RTW89_KCC][0][83] = 127, -+ [0][1][1][0][RTW89_ACMA][1][83] = 127, -+ [0][1][1][0][RTW89_ACMA][0][83] = 127, -+ [0][1][1][0][RTW89_CHILE][1][83] = -2, -+ [0][1][1][0][RTW89_QATAR][1][83] = 127, -+ [0][1][1][0][RTW89_QATAR][0][83] = 127, -+ [0][1][1][0][RTW89_UK][1][83] = 127, -+ [0][1][1][0][RTW89_UK][0][83] = 127, -+ [0][1][1][0][RTW89_FCC][1][85] = -2, -+ [0][1][1][0][RTW89_FCC][2][85] = 68, -+ [0][1][1][0][RTW89_ETSI][1][85] = 127, -+ [0][1][1][0][RTW89_ETSI][0][85] = 127, -+ [0][1][1][0][RTW89_MKK][1][85] = 127, -+ [0][1][1][0][RTW89_MKK][0][85] = 127, -+ [0][1][1][0][RTW89_IC][1][85] = -2, -+ [0][1][1][0][RTW89_KCC][1][85] = 20, -+ [0][1][1][0][RTW89_KCC][0][85] = 127, -+ [0][1][1][0][RTW89_ACMA][1][85] = 127, -+ [0][1][1][0][RTW89_ACMA][0][85] = 127, -+ [0][1][1][0][RTW89_CHILE][1][85] = -2, -+ [0][1][1][0][RTW89_QATAR][1][85] = 127, -+ [0][1][1][0][RTW89_QATAR][0][85] = 127, -+ [0][1][1][0][RTW89_UK][1][85] = 127, -+ [0][1][1][0][RTW89_UK][0][85] = 127, -+ [0][1][1][0][RTW89_FCC][1][87] = -2, -+ [0][1][1][0][RTW89_FCC][2][87] = 127, -+ [0][1][1][0][RTW89_ETSI][1][87] = 127, -+ [0][1][1][0][RTW89_ETSI][0][87] = 127, -+ [0][1][1][0][RTW89_MKK][1][87] = 127, -+ [0][1][1][0][RTW89_MKK][0][87] = 127, -+ [0][1][1][0][RTW89_IC][1][87] = -2, -+ [0][1][1][0][RTW89_KCC][1][87] = 20, -+ [0][1][1][0][RTW89_KCC][0][87] = 127, -+ [0][1][1][0][RTW89_ACMA][1][87] = 127, -+ [0][1][1][0][RTW89_ACMA][0][87] = 127, -+ [0][1][1][0][RTW89_CHILE][1][87] = -2, -+ [0][1][1][0][RTW89_QATAR][1][87] = 127, -+ [0][1][1][0][RTW89_QATAR][0][87] = 127, -+ [0][1][1][0][RTW89_UK][1][87] = 127, -+ [0][1][1][0][RTW89_UK][0][87] = 127, -+ [0][1][1][0][RTW89_FCC][1][89] = -2, -+ [0][1][1][0][RTW89_FCC][2][89] = 127, -+ [0][1][1][0][RTW89_ETSI][1][89] = 127, -+ [0][1][1][0][RTW89_ETSI][0][89] = 127, -+ [0][1][1][0][RTW89_MKK][1][89] = 127, -+ [0][1][1][0][RTW89_MKK][0][89] = 127, -+ [0][1][1][0][RTW89_IC][1][89] = -2, -+ [0][1][1][0][RTW89_KCC][1][89] = 20, -+ [0][1][1][0][RTW89_KCC][0][89] = 127, -+ [0][1][1][0][RTW89_ACMA][1][89] = 127, -+ [0][1][1][0][RTW89_ACMA][0][89] = 127, -+ [0][1][1][0][RTW89_CHILE][1][89] = -2, -+ [0][1][1][0][RTW89_QATAR][1][89] = 127, -+ [0][1][1][0][RTW89_QATAR][0][89] = 127, -+ [0][1][1][0][RTW89_UK][1][89] = 127, -+ [0][1][1][0][RTW89_UK][0][89] = 127, -+ [0][1][1][0][RTW89_FCC][1][90] = -2, -+ [0][1][1][0][RTW89_FCC][2][90] = 127, -+ [0][1][1][0][RTW89_ETSI][1][90] = 127, -+ [0][1][1][0][RTW89_ETSI][0][90] = 127, -+ [0][1][1][0][RTW89_MKK][1][90] = 127, -+ [0][1][1][0][RTW89_MKK][0][90] = 127, -+ [0][1][1][0][RTW89_IC][1][90] = -2, -+ [0][1][1][0][RTW89_KCC][1][90] = 20, -+ [0][1][1][0][RTW89_KCC][0][90] = 127, -+ [0][1][1][0][RTW89_ACMA][1][90] = 127, -+ [0][1][1][0][RTW89_ACMA][0][90] = 127, -+ [0][1][1][0][RTW89_CHILE][1][90] = -2, -+ [0][1][1][0][RTW89_QATAR][1][90] = 127, -+ [0][1][1][0][RTW89_QATAR][0][90] = 127, -+ [0][1][1][0][RTW89_UK][1][90] = 127, -+ [0][1][1][0][RTW89_UK][0][90] = 127, -+ [0][1][1][0][RTW89_FCC][1][92] = -2, -+ [0][1][1][0][RTW89_FCC][2][92] = 127, -+ [0][1][1][0][RTW89_ETSI][1][92] = 127, -+ [0][1][1][0][RTW89_ETSI][0][92] = 127, -+ [0][1][1][0][RTW89_MKK][1][92] = 127, -+ [0][1][1][0][RTW89_MKK][0][92] = 127, -+ [0][1][1][0][RTW89_IC][1][92] = -2, -+ [0][1][1][0][RTW89_KCC][1][92] = 20, -+ [0][1][1][0][RTW89_KCC][0][92] = 127, -+ [0][1][1][0][RTW89_ACMA][1][92] = 127, -+ [0][1][1][0][RTW89_ACMA][0][92] = 127, -+ [0][1][1][0][RTW89_CHILE][1][92] = -2, -+ [0][1][1][0][RTW89_QATAR][1][92] = 127, -+ [0][1][1][0][RTW89_QATAR][0][92] = 127, -+ [0][1][1][0][RTW89_UK][1][92] = 127, -+ [0][1][1][0][RTW89_UK][0][92] = 127, -+ [0][1][1][0][RTW89_FCC][1][94] = -2, -+ [0][1][1][0][RTW89_FCC][2][94] = 127, -+ [0][1][1][0][RTW89_ETSI][1][94] = 127, -+ [0][1][1][0][RTW89_ETSI][0][94] = 127, -+ [0][1][1][0][RTW89_MKK][1][94] = 127, -+ [0][1][1][0][RTW89_MKK][0][94] = 127, -+ [0][1][1][0][RTW89_IC][1][94] = -2, -+ [0][1][1][0][RTW89_KCC][1][94] = 20, -+ [0][1][1][0][RTW89_KCC][0][94] = 127, -+ [0][1][1][0][RTW89_ACMA][1][94] = 127, -+ [0][1][1][0][RTW89_ACMA][0][94] = 127, -+ [0][1][1][0][RTW89_CHILE][1][94] = -2, -+ [0][1][1][0][RTW89_QATAR][1][94] = 127, -+ [0][1][1][0][RTW89_QATAR][0][94] = 127, -+ [0][1][1][0][RTW89_UK][1][94] = 127, -+ [0][1][1][0][RTW89_UK][0][94] = 127, -+ [0][1][1][0][RTW89_FCC][1][96] = -2, -+ [0][1][1][0][RTW89_FCC][2][96] = 127, -+ [0][1][1][0][RTW89_ETSI][1][96] = 127, -+ [0][1][1][0][RTW89_ETSI][0][96] = 127, -+ [0][1][1][0][RTW89_MKK][1][96] = 127, -+ [0][1][1][0][RTW89_MKK][0][96] = 127, -+ [0][1][1][0][RTW89_IC][1][96] = -2, -+ [0][1][1][0][RTW89_KCC][1][96] = 20, -+ [0][1][1][0][RTW89_KCC][0][96] = 127, -+ [0][1][1][0][RTW89_ACMA][1][96] = 127, -+ [0][1][1][0][RTW89_ACMA][0][96] = 127, -+ [0][1][1][0][RTW89_CHILE][1][96] = -2, -+ [0][1][1][0][RTW89_QATAR][1][96] = 127, -+ [0][1][1][0][RTW89_QATAR][0][96] = 127, -+ [0][1][1][0][RTW89_UK][1][96] = 127, -+ [0][1][1][0][RTW89_UK][0][96] = 127, -+ [0][1][1][0][RTW89_FCC][1][98] = -2, -+ [0][1][1][0][RTW89_FCC][2][98] = 127, -+ [0][1][1][0][RTW89_ETSI][1][98] = 127, -+ [0][1][1][0][RTW89_ETSI][0][98] = 127, -+ [0][1][1][0][RTW89_MKK][1][98] = 127, -+ [0][1][1][0][RTW89_MKK][0][98] = 127, -+ [0][1][1][0][RTW89_IC][1][98] = -2, -+ [0][1][1][0][RTW89_KCC][1][98] = 20, -+ [0][1][1][0][RTW89_KCC][0][98] = 127, -+ [0][1][1][0][RTW89_ACMA][1][98] = 127, -+ [0][1][1][0][RTW89_ACMA][0][98] = 127, -+ [0][1][1][0][RTW89_CHILE][1][98] = -2, -+ [0][1][1][0][RTW89_QATAR][1][98] = 127, -+ [0][1][1][0][RTW89_QATAR][0][98] = 127, -+ [0][1][1][0][RTW89_UK][1][98] = 127, -+ [0][1][1][0][RTW89_UK][0][98] = 127, -+ [0][1][1][0][RTW89_FCC][1][100] = -2, -+ [0][1][1][0][RTW89_FCC][2][100] = 127, -+ [0][1][1][0][RTW89_ETSI][1][100] = 127, -+ [0][1][1][0][RTW89_ETSI][0][100] = 127, -+ [0][1][1][0][RTW89_MKK][1][100] = 127, -+ [0][1][1][0][RTW89_MKK][0][100] = 127, -+ [0][1][1][0][RTW89_IC][1][100] = -2, -+ [0][1][1][0][RTW89_KCC][1][100] = 20, -+ [0][1][1][0][RTW89_KCC][0][100] = 127, -+ [0][1][1][0][RTW89_ACMA][1][100] = 127, -+ [0][1][1][0][RTW89_ACMA][0][100] = 127, -+ [0][1][1][0][RTW89_CHILE][1][100] = -2, -+ [0][1][1][0][RTW89_QATAR][1][100] = 127, -+ [0][1][1][0][RTW89_QATAR][0][100] = 127, -+ [0][1][1][0][RTW89_UK][1][100] = 127, -+ [0][1][1][0][RTW89_UK][0][100] = 127, -+ [0][1][1][0][RTW89_FCC][1][102] = -2, -+ [0][1][1][0][RTW89_FCC][2][102] = 127, -+ [0][1][1][0][RTW89_ETSI][1][102] = 127, -+ [0][1][1][0][RTW89_ETSI][0][102] = 127, -+ [0][1][1][0][RTW89_MKK][1][102] = 127, -+ [0][1][1][0][RTW89_MKK][0][102] = 127, -+ [0][1][1][0][RTW89_IC][1][102] = -2, -+ [0][1][1][0][RTW89_KCC][1][102] = 20, -+ [0][1][1][0][RTW89_KCC][0][102] = 127, -+ [0][1][1][0][RTW89_ACMA][1][102] = 127, -+ [0][1][1][0][RTW89_ACMA][0][102] = 127, -+ [0][1][1][0][RTW89_CHILE][1][102] = -2, -+ [0][1][1][0][RTW89_QATAR][1][102] = 127, -+ [0][1][1][0][RTW89_QATAR][0][102] = 127, -+ [0][1][1][0][RTW89_UK][1][102] = 127, -+ [0][1][1][0][RTW89_UK][0][102] = 127, -+ [0][1][1][0][RTW89_FCC][1][104] = -2, -+ [0][1][1][0][RTW89_FCC][2][104] = 127, -+ [0][1][1][0][RTW89_ETSI][1][104] = 127, -+ [0][1][1][0][RTW89_ETSI][0][104] = 127, -+ [0][1][1][0][RTW89_MKK][1][104] = 127, -+ [0][1][1][0][RTW89_MKK][0][104] = 127, -+ [0][1][1][0][RTW89_IC][1][104] = -2, -+ [0][1][1][0][RTW89_KCC][1][104] = 20, -+ [0][1][1][0][RTW89_KCC][0][104] = 127, -+ [0][1][1][0][RTW89_ACMA][1][104] = 127, -+ [0][1][1][0][RTW89_ACMA][0][104] = 127, -+ [0][1][1][0][RTW89_CHILE][1][104] = -2, -+ [0][1][1][0][RTW89_QATAR][1][104] = 127, -+ [0][1][1][0][RTW89_QATAR][0][104] = 127, -+ [0][1][1][0][RTW89_UK][1][104] = 127, -+ [0][1][1][0][RTW89_UK][0][104] = 127, -+ [0][1][1][0][RTW89_FCC][1][105] = -2, -+ [0][1][1][0][RTW89_FCC][2][105] = 127, -+ [0][1][1][0][RTW89_ETSI][1][105] = 127, -+ [0][1][1][0][RTW89_ETSI][0][105] = 127, -+ [0][1][1][0][RTW89_MKK][1][105] = 127, -+ [0][1][1][0][RTW89_MKK][0][105] = 127, -+ [0][1][1][0][RTW89_IC][1][105] = -2, -+ [0][1][1][0][RTW89_KCC][1][105] = 20, -+ [0][1][1][0][RTW89_KCC][0][105] = 127, -+ [0][1][1][0][RTW89_ACMA][1][105] = 127, -+ [0][1][1][0][RTW89_ACMA][0][105] = 127, -+ [0][1][1][0][RTW89_CHILE][1][105] = -2, -+ [0][1][1][0][RTW89_QATAR][1][105] = 127, -+ [0][1][1][0][RTW89_QATAR][0][105] = 127, -+ [0][1][1][0][RTW89_UK][1][105] = 127, -+ [0][1][1][0][RTW89_UK][0][105] = 127, -+ [0][1][1][0][RTW89_FCC][1][107] = 1, -+ [0][1][1][0][RTW89_FCC][2][107] = 127, -+ [0][1][1][0][RTW89_ETSI][1][107] = 127, -+ [0][1][1][0][RTW89_ETSI][0][107] = 127, -+ [0][1][1][0][RTW89_MKK][1][107] = 127, -+ [0][1][1][0][RTW89_MKK][0][107] = 127, -+ [0][1][1][0][RTW89_IC][1][107] = 1, -+ [0][1][1][0][RTW89_KCC][1][107] = 20, -+ [0][1][1][0][RTW89_KCC][0][107] = 127, -+ [0][1][1][0][RTW89_ACMA][1][107] = 127, -+ [0][1][1][0][RTW89_ACMA][0][107] = 127, -+ [0][1][1][0][RTW89_CHILE][1][107] = 1, -+ [0][1][1][0][RTW89_QATAR][1][107] = 127, -+ [0][1][1][0][RTW89_QATAR][0][107] = 127, -+ [0][1][1][0][RTW89_UK][1][107] = 127, -+ [0][1][1][0][RTW89_UK][0][107] = 127, -+ [0][1][1][0][RTW89_FCC][1][109] = 1, -+ [0][1][1][0][RTW89_FCC][2][109] = 127, -+ [0][1][1][0][RTW89_ETSI][1][109] = 127, -+ [0][1][1][0][RTW89_ETSI][0][109] = 127, -+ [0][1][1][0][RTW89_MKK][1][109] = 127, -+ [0][1][1][0][RTW89_MKK][0][109] = 127, -+ [0][1][1][0][RTW89_IC][1][109] = 1, -+ [0][1][1][0][RTW89_KCC][1][109] = 20, -+ [0][1][1][0][RTW89_KCC][0][109] = 127, -+ [0][1][1][0][RTW89_ACMA][1][109] = 127, -+ [0][1][1][0][RTW89_ACMA][0][109] = 127, -+ [0][1][1][0][RTW89_CHILE][1][109] = 1, -+ [0][1][1][0][RTW89_QATAR][1][109] = 127, -+ [0][1][1][0][RTW89_QATAR][0][109] = 127, -+ [0][1][1][0][RTW89_UK][1][109] = 127, -+ [0][1][1][0][RTW89_UK][0][109] = 127, -+ [0][1][1][0][RTW89_FCC][1][111] = 127, -+ [0][1][1][0][RTW89_FCC][2][111] = 127, -+ [0][1][1][0][RTW89_ETSI][1][111] = 127, -+ [0][1][1][0][RTW89_ETSI][0][111] = 127, -+ [0][1][1][0][RTW89_MKK][1][111] = 127, -+ [0][1][1][0][RTW89_MKK][0][111] = 127, -+ [0][1][1][0][RTW89_IC][1][111] = 127, -+ [0][1][1][0][RTW89_KCC][1][111] = 127, -+ [0][1][1][0][RTW89_KCC][0][111] = 127, -+ [0][1][1][0][RTW89_ACMA][1][111] = 127, -+ [0][1][1][0][RTW89_ACMA][0][111] = 127, -+ [0][1][1][0][RTW89_CHILE][1][111] = 127, -+ [0][1][1][0][RTW89_QATAR][1][111] = 127, -+ [0][1][1][0][RTW89_QATAR][0][111] = 127, -+ [0][1][1][0][RTW89_UK][1][111] = 127, -+ [0][1][1][0][RTW89_UK][0][111] = 127, -+ [0][1][1][0][RTW89_FCC][1][113] = 127, -+ [0][1][1][0][RTW89_FCC][2][113] = 127, -+ [0][1][1][0][RTW89_ETSI][1][113] = 127, -+ [0][1][1][0][RTW89_ETSI][0][113] = 127, -+ [0][1][1][0][RTW89_MKK][1][113] = 127, -+ [0][1][1][0][RTW89_MKK][0][113] = 127, -+ [0][1][1][0][RTW89_IC][1][113] = 127, -+ [0][1][1][0][RTW89_KCC][1][113] = 127, -+ [0][1][1][0][RTW89_KCC][0][113] = 127, -+ [0][1][1][0][RTW89_ACMA][1][113] = 127, -+ [0][1][1][0][RTW89_ACMA][0][113] = 127, -+ [0][1][1][0][RTW89_CHILE][1][113] = 127, -+ [0][1][1][0][RTW89_QATAR][1][113] = 127, -+ [0][1][1][0][RTW89_QATAR][0][113] = 127, -+ [0][1][1][0][RTW89_UK][1][113] = 127, -+ [0][1][1][0][RTW89_UK][0][113] = 127, -+ [0][1][1][0][RTW89_FCC][1][115] = 127, -+ [0][1][1][0][RTW89_FCC][2][115] = 127, -+ [0][1][1][0][RTW89_ETSI][1][115] = 127, -+ [0][1][1][0][RTW89_ETSI][0][115] = 127, -+ [0][1][1][0][RTW89_MKK][1][115] = 127, -+ [0][1][1][0][RTW89_MKK][0][115] = 127, -+ [0][1][1][0][RTW89_IC][1][115] = 127, -+ [0][1][1][0][RTW89_KCC][1][115] = 127, -+ [0][1][1][0][RTW89_KCC][0][115] = 127, -+ [0][1][1][0][RTW89_ACMA][1][115] = 127, -+ [0][1][1][0][RTW89_ACMA][0][115] = 127, -+ [0][1][1][0][RTW89_CHILE][1][115] = 127, -+ [0][1][1][0][RTW89_QATAR][1][115] = 127, -+ [0][1][1][0][RTW89_QATAR][0][115] = 127, -+ [0][1][1][0][RTW89_UK][1][115] = 127, -+ [0][1][1][0][RTW89_UK][0][115] = 127, -+ [0][1][1][0][RTW89_FCC][1][117] = 127, -+ [0][1][1][0][RTW89_FCC][2][117] = 127, -+ [0][1][1][0][RTW89_ETSI][1][117] = 127, -+ [0][1][1][0][RTW89_ETSI][0][117] = 127, -+ [0][1][1][0][RTW89_MKK][1][117] = 127, -+ [0][1][1][0][RTW89_MKK][0][117] = 127, -+ [0][1][1][0][RTW89_IC][1][117] = 127, -+ [0][1][1][0][RTW89_KCC][1][117] = 127, -+ [0][1][1][0][RTW89_KCC][0][117] = 127, -+ [0][1][1][0][RTW89_ACMA][1][117] = 127, -+ [0][1][1][0][RTW89_ACMA][0][117] = 127, -+ [0][1][1][0][RTW89_CHILE][1][117] = 127, -+ [0][1][1][0][RTW89_QATAR][1][117] = 127, -+ [0][1][1][0][RTW89_QATAR][0][117] = 127, -+ [0][1][1][0][RTW89_UK][1][117] = 127, -+ [0][1][1][0][RTW89_UK][0][117] = 127, -+ [0][1][1][0][RTW89_FCC][1][119] = 127, -+ [0][1][1][0][RTW89_FCC][2][119] = 127, -+ [0][1][1][0][RTW89_ETSI][1][119] = 127, -+ [0][1][1][0][RTW89_ETSI][0][119] = 127, -+ [0][1][1][0][RTW89_MKK][1][119] = 127, -+ [0][1][1][0][RTW89_MKK][0][119] = 127, -+ [0][1][1][0][RTW89_IC][1][119] = 127, -+ [0][1][1][0][RTW89_KCC][1][119] = 127, -+ [0][1][1][0][RTW89_KCC][0][119] = 127, -+ [0][1][1][0][RTW89_ACMA][1][119] = 127, -+ [0][1][1][0][RTW89_ACMA][0][119] = 127, -+ [0][1][1][0][RTW89_CHILE][1][119] = 127, -+ [0][1][1][0][RTW89_QATAR][1][119] = 127, -+ [0][1][1][0][RTW89_QATAR][0][119] = 127, -+ [0][1][1][0][RTW89_UK][1][119] = 127, -+ [0][1][1][0][RTW89_UK][0][119] = 127, -+ [0][0][2][0][RTW89_FCC][1][0] = 24, -+ [0][0][2][0][RTW89_FCC][2][0] = 56, -+ [0][0][2][0][RTW89_ETSI][1][0] = 66, -+ [0][0][2][0][RTW89_ETSI][0][0] = 28, -+ [0][0][2][0][RTW89_MKK][1][0] = 66, -+ [0][0][2][0][RTW89_MKK][0][0] = 26, -+ [0][0][2][0][RTW89_IC][1][0] = 24, -+ [0][0][2][0][RTW89_KCC][1][0] = 24, -+ [0][0][2][0][RTW89_KCC][0][0] = 24, -+ [0][0][2][0][RTW89_ACMA][1][0] = 66, -+ [0][0][2][0][RTW89_ACMA][0][0] = 28, -+ [0][0][2][0][RTW89_CHILE][1][0] = 24, -+ [0][0][2][0][RTW89_QATAR][1][0] = 66, -+ [0][0][2][0][RTW89_QATAR][0][0] = 28, -+ [0][0][2][0][RTW89_UK][1][0] = 66, -+ [0][0][2][0][RTW89_UK][0][0] = 28, -+ [0][0][2][0][RTW89_FCC][1][2] = 22, -+ [0][0][2][0][RTW89_FCC][2][2] = 56, -+ [0][0][2][0][RTW89_ETSI][1][2] = 66, -+ [0][0][2][0][RTW89_ETSI][0][2] = 28, -+ [0][0][2][0][RTW89_MKK][1][2] = 66, -+ [0][0][2][0][RTW89_MKK][0][2] = 26, -+ [0][0][2][0][RTW89_IC][1][2] = 22, -+ [0][0][2][0][RTW89_KCC][1][2] = 24, -+ [0][0][2][0][RTW89_KCC][0][2] = 24, -+ [0][0][2][0][RTW89_ACMA][1][2] = 66, -+ [0][0][2][0][RTW89_ACMA][0][2] = 28, -+ [0][0][2][0][RTW89_CHILE][1][2] = 22, -+ [0][0][2][0][RTW89_QATAR][1][2] = 66, -+ [0][0][2][0][RTW89_QATAR][0][2] = 28, -+ [0][0][2][0][RTW89_UK][1][2] = 66, -+ [0][0][2][0][RTW89_UK][0][2] = 28, -+ [0][0][2][0][RTW89_FCC][1][4] = 22, -+ [0][0][2][0][RTW89_FCC][2][4] = 56, -+ [0][0][2][0][RTW89_ETSI][1][4] = 66, -+ [0][0][2][0][RTW89_ETSI][0][4] = 28, -+ [0][0][2][0][RTW89_MKK][1][4] = 66, -+ [0][0][2][0][RTW89_MKK][0][4] = 26, -+ [0][0][2][0][RTW89_IC][1][4] = 22, -+ [0][0][2][0][RTW89_KCC][1][4] = 24, -+ [0][0][2][0][RTW89_KCC][0][4] = 24, -+ [0][0][2][0][RTW89_ACMA][1][4] = 66, -+ [0][0][2][0][RTW89_ACMA][0][4] = 28, -+ [0][0][2][0][RTW89_CHILE][1][4] = 22, -+ [0][0][2][0][RTW89_QATAR][1][4] = 66, -+ [0][0][2][0][RTW89_QATAR][0][4] = 28, -+ [0][0][2][0][RTW89_UK][1][4] = 66, -+ [0][0][2][0][RTW89_UK][0][4] = 28, -+ [0][0][2][0][RTW89_FCC][1][6] = 22, -+ [0][0][2][0][RTW89_FCC][2][6] = 56, -+ [0][0][2][0][RTW89_ETSI][1][6] = 66, -+ [0][0][2][0][RTW89_ETSI][0][6] = 28, -+ [0][0][2][0][RTW89_MKK][1][6] = 66, -+ [0][0][2][0][RTW89_MKK][0][6] = 26, -+ [0][0][2][0][RTW89_IC][1][6] = 22, -+ [0][0][2][0][RTW89_KCC][1][6] = 24, -+ [0][0][2][0][RTW89_KCC][0][6] = 24, -+ [0][0][2][0][RTW89_ACMA][1][6] = 66, -+ [0][0][2][0][RTW89_ACMA][0][6] = 28, -+ [0][0][2][0][RTW89_CHILE][1][6] = 22, -+ [0][0][2][0][RTW89_QATAR][1][6] = 66, -+ [0][0][2][0][RTW89_QATAR][0][6] = 28, -+ [0][0][2][0][RTW89_UK][1][6] = 66, -+ [0][0][2][0][RTW89_UK][0][6] = 28, -+ [0][0][2][0][RTW89_FCC][1][8] = 22, -+ [0][0][2][0][RTW89_FCC][2][8] = 56, -+ [0][0][2][0][RTW89_ETSI][1][8] = 66, -+ [0][0][2][0][RTW89_ETSI][0][8] = 28, -+ [0][0][2][0][RTW89_MKK][1][8] = 66, -+ [0][0][2][0][RTW89_MKK][0][8] = 26, -+ [0][0][2][0][RTW89_IC][1][8] = 22, -+ [0][0][2][0][RTW89_KCC][1][8] = 24, -+ [0][0][2][0][RTW89_KCC][0][8] = 24, -+ [0][0][2][0][RTW89_ACMA][1][8] = 66, -+ [0][0][2][0][RTW89_ACMA][0][8] = 28, -+ [0][0][2][0][RTW89_CHILE][1][8] = 22, -+ [0][0][2][0][RTW89_QATAR][1][8] = 66, -+ [0][0][2][0][RTW89_QATAR][0][8] = 28, -+ [0][0][2][0][RTW89_UK][1][8] = 66, -+ [0][0][2][0][RTW89_UK][0][8] = 28, -+ [0][0][2][0][RTW89_FCC][1][10] = 22, -+ [0][0][2][0][RTW89_FCC][2][10] = 56, -+ [0][0][2][0][RTW89_ETSI][1][10] = 66, -+ [0][0][2][0][RTW89_ETSI][0][10] = 28, -+ [0][0][2][0][RTW89_MKK][1][10] = 66, -+ [0][0][2][0][RTW89_MKK][0][10] = 26, -+ [0][0][2][0][RTW89_IC][1][10] = 22, -+ [0][0][2][0][RTW89_KCC][1][10] = 24, -+ [0][0][2][0][RTW89_KCC][0][10] = 24, -+ [0][0][2][0][RTW89_ACMA][1][10] = 66, -+ [0][0][2][0][RTW89_ACMA][0][10] = 28, -+ [0][0][2][0][RTW89_CHILE][1][10] = 22, -+ [0][0][2][0][RTW89_QATAR][1][10] = 66, -+ [0][0][2][0][RTW89_QATAR][0][10] = 28, -+ [0][0][2][0][RTW89_UK][1][10] = 66, -+ [0][0][2][0][RTW89_UK][0][10] = 28, -+ [0][0][2][0][RTW89_FCC][1][12] = 22, -+ [0][0][2][0][RTW89_FCC][2][12] = 56, -+ [0][0][2][0][RTW89_ETSI][1][12] = 66, -+ [0][0][2][0][RTW89_ETSI][0][12] = 28, -+ [0][0][2][0][RTW89_MKK][1][12] = 66, -+ [0][0][2][0][RTW89_MKK][0][12] = 26, -+ [0][0][2][0][RTW89_IC][1][12] = 22, -+ [0][0][2][0][RTW89_KCC][1][12] = 24, -+ [0][0][2][0][RTW89_KCC][0][12] = 24, -+ [0][0][2][0][RTW89_ACMA][1][12] = 66, -+ [0][0][2][0][RTW89_ACMA][0][12] = 28, -+ [0][0][2][0][RTW89_CHILE][1][12] = 22, -+ [0][0][2][0][RTW89_QATAR][1][12] = 66, -+ [0][0][2][0][RTW89_QATAR][0][12] = 28, -+ [0][0][2][0][RTW89_UK][1][12] = 66, -+ [0][0][2][0][RTW89_UK][0][12] = 28, -+ [0][0][2][0][RTW89_FCC][1][14] = 22, -+ [0][0][2][0][RTW89_FCC][2][14] = 56, -+ [0][0][2][0][RTW89_ETSI][1][14] = 66, -+ [0][0][2][0][RTW89_ETSI][0][14] = 28, -+ [0][0][2][0][RTW89_MKK][1][14] = 66, -+ [0][0][2][0][RTW89_MKK][0][14] = 26, -+ [0][0][2][0][RTW89_IC][1][14] = 22, -+ [0][0][2][0][RTW89_KCC][1][14] = 24, -+ [0][0][2][0][RTW89_KCC][0][14] = 24, -+ [0][0][2][0][RTW89_ACMA][1][14] = 66, -+ [0][0][2][0][RTW89_ACMA][0][14] = 28, -+ [0][0][2][0][RTW89_CHILE][1][14] = 22, -+ [0][0][2][0][RTW89_QATAR][1][14] = 66, -+ [0][0][2][0][RTW89_QATAR][0][14] = 28, -+ [0][0][2][0][RTW89_UK][1][14] = 66, -+ [0][0][2][0][RTW89_UK][0][14] = 28, -+ [0][0][2][0][RTW89_FCC][1][15] = 22, -+ [0][0][2][0][RTW89_FCC][2][15] = 56, -+ [0][0][2][0][RTW89_ETSI][1][15] = 66, -+ [0][0][2][0][RTW89_ETSI][0][15] = 28, -+ [0][0][2][0][RTW89_MKK][1][15] = 66, -+ [0][0][2][0][RTW89_MKK][0][15] = 26, -+ [0][0][2][0][RTW89_IC][1][15] = 22, -+ [0][0][2][0][RTW89_KCC][1][15] = 24, -+ [0][0][2][0][RTW89_KCC][0][15] = 24, -+ [0][0][2][0][RTW89_ACMA][1][15] = 66, -+ [0][0][2][0][RTW89_ACMA][0][15] = 28, -+ [0][0][2][0][RTW89_CHILE][1][15] = 22, -+ [0][0][2][0][RTW89_QATAR][1][15] = 66, -+ [0][0][2][0][RTW89_QATAR][0][15] = 28, -+ [0][0][2][0][RTW89_UK][1][15] = 66, -+ [0][0][2][0][RTW89_UK][0][15] = 28, -+ [0][0][2][0][RTW89_FCC][1][17] = 22, -+ [0][0][2][0][RTW89_FCC][2][17] = 56, -+ [0][0][2][0][RTW89_ETSI][1][17] = 66, -+ [0][0][2][0][RTW89_ETSI][0][17] = 28, -+ [0][0][2][0][RTW89_MKK][1][17] = 66, -+ [0][0][2][0][RTW89_MKK][0][17] = 26, -+ [0][0][2][0][RTW89_IC][1][17] = 22, -+ [0][0][2][0][RTW89_KCC][1][17] = 24, -+ [0][0][2][0][RTW89_KCC][0][17] = 24, -+ [0][0][2][0][RTW89_ACMA][1][17] = 66, -+ [0][0][2][0][RTW89_ACMA][0][17] = 28, -+ [0][0][2][0][RTW89_CHILE][1][17] = 22, -+ [0][0][2][0][RTW89_QATAR][1][17] = 66, -+ [0][0][2][0][RTW89_QATAR][0][17] = 28, -+ [0][0][2][0][RTW89_UK][1][17] = 66, -+ [0][0][2][0][RTW89_UK][0][17] = 28, -+ [0][0][2][0][RTW89_FCC][1][19] = 22, -+ [0][0][2][0][RTW89_FCC][2][19] = 56, -+ [0][0][2][0][RTW89_ETSI][1][19] = 66, -+ [0][0][2][0][RTW89_ETSI][0][19] = 28, -+ [0][0][2][0][RTW89_MKK][1][19] = 66, -+ [0][0][2][0][RTW89_MKK][0][19] = 26, -+ [0][0][2][0][RTW89_IC][1][19] = 22, -+ [0][0][2][0][RTW89_KCC][1][19] = 24, -+ [0][0][2][0][RTW89_KCC][0][19] = 24, -+ [0][0][2][0][RTW89_ACMA][1][19] = 66, -+ [0][0][2][0][RTW89_ACMA][0][19] = 28, -+ [0][0][2][0][RTW89_CHILE][1][19] = 22, -+ [0][0][2][0][RTW89_QATAR][1][19] = 66, -+ [0][0][2][0][RTW89_QATAR][0][19] = 28, -+ [0][0][2][0][RTW89_UK][1][19] = 66, -+ [0][0][2][0][RTW89_UK][0][19] = 28, -+ [0][0][2][0][RTW89_FCC][1][21] = 22, -+ [0][0][2][0][RTW89_FCC][2][21] = 56, -+ [0][0][2][0][RTW89_ETSI][1][21] = 66, -+ [0][0][2][0][RTW89_ETSI][0][21] = 28, -+ [0][0][2][0][RTW89_MKK][1][21] = 66, -+ [0][0][2][0][RTW89_MKK][0][21] = 26, -+ [0][0][2][0][RTW89_IC][1][21] = 22, -+ [0][0][2][0][RTW89_KCC][1][21] = 24, -+ [0][0][2][0][RTW89_KCC][0][21] = 24, -+ [0][0][2][0][RTW89_ACMA][1][21] = 66, -+ [0][0][2][0][RTW89_ACMA][0][21] = 28, -+ [0][0][2][0][RTW89_CHILE][1][21] = 22, -+ [0][0][2][0][RTW89_QATAR][1][21] = 66, -+ [0][0][2][0][RTW89_QATAR][0][21] = 28, -+ [0][0][2][0][RTW89_UK][1][21] = 66, -+ [0][0][2][0][RTW89_UK][0][21] = 28, -+ [0][0][2][0][RTW89_FCC][1][23] = 22, -+ [0][0][2][0][RTW89_FCC][2][23] = 70, -+ [0][0][2][0][RTW89_ETSI][1][23] = 66, -+ [0][0][2][0][RTW89_ETSI][0][23] = 28, -+ [0][0][2][0][RTW89_MKK][1][23] = 66, -+ [0][0][2][0][RTW89_MKK][0][23] = 26, -+ [0][0][2][0][RTW89_IC][1][23] = 22, -+ [0][0][2][0][RTW89_KCC][1][23] = 24, -+ [0][0][2][0][RTW89_KCC][0][23] = 26, -+ [0][0][2][0][RTW89_ACMA][1][23] = 66, -+ [0][0][2][0][RTW89_ACMA][0][23] = 28, -+ [0][0][2][0][RTW89_CHILE][1][23] = 22, -+ [0][0][2][0][RTW89_QATAR][1][23] = 66, -+ [0][0][2][0][RTW89_QATAR][0][23] = 28, -+ [0][0][2][0][RTW89_UK][1][23] = 66, -+ [0][0][2][0][RTW89_UK][0][23] = 28, -+ [0][0][2][0][RTW89_FCC][1][25] = 22, -+ [0][0][2][0][RTW89_FCC][2][25] = 70, -+ [0][0][2][0][RTW89_ETSI][1][25] = 66, -+ [0][0][2][0][RTW89_ETSI][0][25] = 28, -+ [0][0][2][0][RTW89_MKK][1][25] = 66, -+ [0][0][2][0][RTW89_MKK][0][25] = 26, -+ [0][0][2][0][RTW89_IC][1][25] = 22, -+ [0][0][2][0][RTW89_KCC][1][25] = 24, -+ [0][0][2][0][RTW89_KCC][0][25] = 26, -+ [0][0][2][0][RTW89_ACMA][1][25] = 66, -+ [0][0][2][0][RTW89_ACMA][0][25] = 28, -+ [0][0][2][0][RTW89_CHILE][1][25] = 22, -+ [0][0][2][0][RTW89_QATAR][1][25] = 66, -+ [0][0][2][0][RTW89_QATAR][0][25] = 28, -+ [0][0][2][0][RTW89_UK][1][25] = 66, -+ [0][0][2][0][RTW89_UK][0][25] = 28, -+ [0][0][2][0][RTW89_FCC][1][27] = 22, -+ [0][0][2][0][RTW89_FCC][2][27] = 70, -+ [0][0][2][0][RTW89_ETSI][1][27] = 66, -+ [0][0][2][0][RTW89_ETSI][0][27] = 28, -+ [0][0][2][0][RTW89_MKK][1][27] = 66, -+ [0][0][2][0][RTW89_MKK][0][27] = 26, -+ [0][0][2][0][RTW89_IC][1][27] = 22, -+ [0][0][2][0][RTW89_KCC][1][27] = 24, -+ [0][0][2][0][RTW89_KCC][0][27] = 26, -+ [0][0][2][0][RTW89_ACMA][1][27] = 66, -+ [0][0][2][0][RTW89_ACMA][0][27] = 28, -+ [0][0][2][0][RTW89_CHILE][1][27] = 22, -+ [0][0][2][0][RTW89_QATAR][1][27] = 66, -+ [0][0][2][0][RTW89_QATAR][0][27] = 28, -+ [0][0][2][0][RTW89_UK][1][27] = 66, -+ [0][0][2][0][RTW89_UK][0][27] = 28, -+ [0][0][2][0][RTW89_FCC][1][29] = 22, -+ [0][0][2][0][RTW89_FCC][2][29] = 70, -+ [0][0][2][0][RTW89_ETSI][1][29] = 66, -+ [0][0][2][0][RTW89_ETSI][0][29] = 28, -+ [0][0][2][0][RTW89_MKK][1][29] = 66, -+ [0][0][2][0][RTW89_MKK][0][29] = 26, -+ [0][0][2][0][RTW89_IC][1][29] = 22, -+ [0][0][2][0][RTW89_KCC][1][29] = 24, -+ [0][0][2][0][RTW89_KCC][0][29] = 26, -+ [0][0][2][0][RTW89_ACMA][1][29] = 66, -+ [0][0][2][0][RTW89_ACMA][0][29] = 28, -+ [0][0][2][0][RTW89_CHILE][1][29] = 22, -+ [0][0][2][0][RTW89_QATAR][1][29] = 66, -+ [0][0][2][0][RTW89_QATAR][0][29] = 28, -+ [0][0][2][0][RTW89_UK][1][29] = 66, -+ [0][0][2][0][RTW89_UK][0][29] = 28, -+ [0][0][2][0][RTW89_FCC][1][30] = 22, -+ [0][0][2][0][RTW89_FCC][2][30] = 70, -+ [0][0][2][0][RTW89_ETSI][1][30] = 66, -+ [0][0][2][0][RTW89_ETSI][0][30] = 28, -+ [0][0][2][0][RTW89_MKK][1][30] = 66, -+ [0][0][2][0][RTW89_MKK][0][30] = 26, -+ [0][0][2][0][RTW89_IC][1][30] = 22, -+ [0][0][2][0][RTW89_KCC][1][30] = 24, -+ [0][0][2][0][RTW89_KCC][0][30] = 26, -+ [0][0][2][0][RTW89_ACMA][1][30] = 66, -+ [0][0][2][0][RTW89_ACMA][0][30] = 28, -+ [0][0][2][0][RTW89_CHILE][1][30] = 22, -+ [0][0][2][0][RTW89_QATAR][1][30] = 66, -+ [0][0][2][0][RTW89_QATAR][0][30] = 28, -+ [0][0][2][0][RTW89_UK][1][30] = 66, -+ [0][0][2][0][RTW89_UK][0][30] = 28, -+ [0][0][2][0][RTW89_FCC][1][32] = 22, -+ [0][0][2][0][RTW89_FCC][2][32] = 70, -+ [0][0][2][0][RTW89_ETSI][1][32] = 66, -+ [0][0][2][0][RTW89_ETSI][0][32] = 28, -+ [0][0][2][0][RTW89_MKK][1][32] = 66, -+ [0][0][2][0][RTW89_MKK][0][32] = 26, -+ [0][0][2][0][RTW89_IC][1][32] = 22, -+ [0][0][2][0][RTW89_KCC][1][32] = 24, -+ [0][0][2][0][RTW89_KCC][0][32] = 26, -+ [0][0][2][0][RTW89_ACMA][1][32] = 66, -+ [0][0][2][0][RTW89_ACMA][0][32] = 28, -+ [0][0][2][0][RTW89_CHILE][1][32] = 22, -+ [0][0][2][0][RTW89_QATAR][1][32] = 66, -+ [0][0][2][0][RTW89_QATAR][0][32] = 28, -+ [0][0][2][0][RTW89_UK][1][32] = 66, -+ [0][0][2][0][RTW89_UK][0][32] = 28, -+ [0][0][2][0][RTW89_FCC][1][34] = 22, -+ [0][0][2][0][RTW89_FCC][2][34] = 70, -+ [0][0][2][0][RTW89_ETSI][1][34] = 66, -+ [0][0][2][0][RTW89_ETSI][0][34] = 28, -+ [0][0][2][0][RTW89_MKK][1][34] = 66, -+ [0][0][2][0][RTW89_MKK][0][34] = 26, -+ [0][0][2][0][RTW89_IC][1][34] = 22, -+ [0][0][2][0][RTW89_KCC][1][34] = 24, -+ [0][0][2][0][RTW89_KCC][0][34] = 26, -+ [0][0][2][0][RTW89_ACMA][1][34] = 66, -+ [0][0][2][0][RTW89_ACMA][0][34] = 28, -+ [0][0][2][0][RTW89_CHILE][1][34] = 22, -+ [0][0][2][0][RTW89_QATAR][1][34] = 66, -+ [0][0][2][0][RTW89_QATAR][0][34] = 28, -+ [0][0][2][0][RTW89_UK][1][34] = 66, -+ [0][0][2][0][RTW89_UK][0][34] = 28, -+ [0][0][2][0][RTW89_FCC][1][36] = 22, -+ [0][0][2][0][RTW89_FCC][2][36] = 70, -+ [0][0][2][0][RTW89_ETSI][1][36] = 66, -+ [0][0][2][0][RTW89_ETSI][0][36] = 28, -+ [0][0][2][0][RTW89_MKK][1][36] = 66, -+ [0][0][2][0][RTW89_MKK][0][36] = 26, -+ [0][0][2][0][RTW89_IC][1][36] = 22, -+ [0][0][2][0][RTW89_KCC][1][36] = 24, -+ [0][0][2][0][RTW89_KCC][0][36] = 26, -+ [0][0][2][0][RTW89_ACMA][1][36] = 66, -+ [0][0][2][0][RTW89_ACMA][0][36] = 28, -+ [0][0][2][0][RTW89_CHILE][1][36] = 22, -+ [0][0][2][0][RTW89_QATAR][1][36] = 66, -+ [0][0][2][0][RTW89_QATAR][0][36] = 28, -+ [0][0][2][0][RTW89_UK][1][36] = 66, -+ [0][0][2][0][RTW89_UK][0][36] = 28, -+ [0][0][2][0][RTW89_FCC][1][38] = 22, -+ [0][0][2][0][RTW89_FCC][2][38] = 70, -+ [0][0][2][0][RTW89_ETSI][1][38] = 66, -+ [0][0][2][0][RTW89_ETSI][0][38] = 28, -+ [0][0][2][0][RTW89_MKK][1][38] = 66, -+ [0][0][2][0][RTW89_MKK][0][38] = 26, -+ [0][0][2][0][RTW89_IC][1][38] = 22, -+ [0][0][2][0][RTW89_KCC][1][38] = 24, -+ [0][0][2][0][RTW89_KCC][0][38] = 26, -+ [0][0][2][0][RTW89_ACMA][1][38] = 66, -+ [0][0][2][0][RTW89_ACMA][0][38] = 28, -+ [0][0][2][0][RTW89_CHILE][1][38] = 22, -+ [0][0][2][0][RTW89_QATAR][1][38] = 66, -+ [0][0][2][0][RTW89_QATAR][0][38] = 28, -+ [0][0][2][0][RTW89_UK][1][38] = 66, -+ [0][0][2][0][RTW89_UK][0][38] = 28, -+ [0][0][2][0][RTW89_FCC][1][40] = 22, -+ [0][0][2][0][RTW89_FCC][2][40] = 70, -+ [0][0][2][0][RTW89_ETSI][1][40] = 66, -+ [0][0][2][0][RTW89_ETSI][0][40] = 28, -+ [0][0][2][0][RTW89_MKK][1][40] = 66, -+ [0][0][2][0][RTW89_MKK][0][40] = 26, -+ [0][0][2][0][RTW89_IC][1][40] = 22, -+ [0][0][2][0][RTW89_KCC][1][40] = 24, -+ [0][0][2][0][RTW89_KCC][0][40] = 26, -+ [0][0][2][0][RTW89_ACMA][1][40] = 66, -+ [0][0][2][0][RTW89_ACMA][0][40] = 28, -+ [0][0][2][0][RTW89_CHILE][1][40] = 22, -+ [0][0][2][0][RTW89_QATAR][1][40] = 66, -+ [0][0][2][0][RTW89_QATAR][0][40] = 28, -+ [0][0][2][0][RTW89_UK][1][40] = 66, -+ [0][0][2][0][RTW89_UK][0][40] = 28, -+ [0][0][2][0][RTW89_FCC][1][42] = 22, -+ [0][0][2][0][RTW89_FCC][2][42] = 70, -+ [0][0][2][0][RTW89_ETSI][1][42] = 66, -+ [0][0][2][0][RTW89_ETSI][0][42] = 28, -+ [0][0][2][0][RTW89_MKK][1][42] = 66, -+ [0][0][2][0][RTW89_MKK][0][42] = 26, -+ [0][0][2][0][RTW89_IC][1][42] = 22, -+ [0][0][2][0][RTW89_KCC][1][42] = 24, -+ [0][0][2][0][RTW89_KCC][0][42] = 26, -+ [0][0][2][0][RTW89_ACMA][1][42] = 66, -+ [0][0][2][0][RTW89_ACMA][0][42] = 28, -+ [0][0][2][0][RTW89_CHILE][1][42] = 22, -+ [0][0][2][0][RTW89_QATAR][1][42] = 66, -+ [0][0][2][0][RTW89_QATAR][0][42] = 28, -+ [0][0][2][0][RTW89_UK][1][42] = 66, -+ [0][0][2][0][RTW89_UK][0][42] = 28, -+ [0][0][2][0][RTW89_FCC][1][44] = 22, -+ [0][0][2][0][RTW89_FCC][2][44] = 70, -+ [0][0][2][0][RTW89_ETSI][1][44] = 66, -+ [0][0][2][0][RTW89_ETSI][0][44] = 30, -+ [0][0][2][0][RTW89_MKK][1][44] = 44, -+ [0][0][2][0][RTW89_MKK][0][44] = 28, -+ [0][0][2][0][RTW89_IC][1][44] = 22, -+ [0][0][2][0][RTW89_KCC][1][44] = 24, -+ [0][0][2][0][RTW89_KCC][0][44] = 26, -+ [0][0][2][0][RTW89_ACMA][1][44] = 66, -+ [0][0][2][0][RTW89_ACMA][0][44] = 30, -+ [0][0][2][0][RTW89_CHILE][1][44] = 22, -+ [0][0][2][0][RTW89_QATAR][1][44] = 66, -+ [0][0][2][0][RTW89_QATAR][0][44] = 30, -+ [0][0][2][0][RTW89_UK][1][44] = 66, -+ [0][0][2][0][RTW89_UK][0][44] = 30, -+ [0][0][2][0][RTW89_FCC][1][45] = 22, -+ [0][0][2][0][RTW89_FCC][2][45] = 127, -+ [0][0][2][0][RTW89_ETSI][1][45] = 127, -+ [0][0][2][0][RTW89_ETSI][0][45] = 127, -+ [0][0][2][0][RTW89_MKK][1][45] = 127, -+ [0][0][2][0][RTW89_MKK][0][45] = 127, -+ [0][0][2][0][RTW89_IC][1][45] = 22, -+ [0][0][2][0][RTW89_KCC][1][45] = 24, -+ [0][0][2][0][RTW89_KCC][0][45] = 127, -+ [0][0][2][0][RTW89_ACMA][1][45] = 127, -+ [0][0][2][0][RTW89_ACMA][0][45] = 127, -+ [0][0][2][0][RTW89_CHILE][1][45] = 22, -+ [0][0][2][0][RTW89_QATAR][1][45] = 127, -+ [0][0][2][0][RTW89_QATAR][0][45] = 127, -+ [0][0][2][0][RTW89_UK][1][45] = 127, -+ [0][0][2][0][RTW89_UK][0][45] = 127, -+ [0][0][2][0][RTW89_FCC][1][47] = 22, -+ [0][0][2][0][RTW89_FCC][2][47] = 127, -+ [0][0][2][0][RTW89_ETSI][1][47] = 127, -+ [0][0][2][0][RTW89_ETSI][0][47] = 127, -+ [0][0][2][0][RTW89_MKK][1][47] = 127, -+ [0][0][2][0][RTW89_MKK][0][47] = 127, -+ [0][0][2][0][RTW89_IC][1][47] = 22, -+ [0][0][2][0][RTW89_KCC][1][47] = 24, -+ [0][0][2][0][RTW89_KCC][0][47] = 127, -+ [0][0][2][0][RTW89_ACMA][1][47] = 127, -+ [0][0][2][0][RTW89_ACMA][0][47] = 127, -+ [0][0][2][0][RTW89_CHILE][1][47] = 22, -+ [0][0][2][0][RTW89_QATAR][1][47] = 127, -+ [0][0][2][0][RTW89_QATAR][0][47] = 127, -+ [0][0][2][0][RTW89_UK][1][47] = 127, -+ [0][0][2][0][RTW89_UK][0][47] = 127, -+ [0][0][2][0][RTW89_FCC][1][49] = 24, -+ [0][0][2][0][RTW89_FCC][2][49] = 127, -+ [0][0][2][0][RTW89_ETSI][1][49] = 127, -+ [0][0][2][0][RTW89_ETSI][0][49] = 127, -+ [0][0][2][0][RTW89_MKK][1][49] = 127, -+ [0][0][2][0][RTW89_MKK][0][49] = 127, -+ [0][0][2][0][RTW89_IC][1][49] = 24, -+ [0][0][2][0][RTW89_KCC][1][49] = 24, -+ [0][0][2][0][RTW89_KCC][0][49] = 127, -+ [0][0][2][0][RTW89_ACMA][1][49] = 127, -+ [0][0][2][0][RTW89_ACMA][0][49] = 127, -+ [0][0][2][0][RTW89_CHILE][1][49] = 24, -+ [0][0][2][0][RTW89_QATAR][1][49] = 127, -+ [0][0][2][0][RTW89_QATAR][0][49] = 127, -+ [0][0][2][0][RTW89_UK][1][49] = 127, -+ [0][0][2][0][RTW89_UK][0][49] = 127, -+ [0][0][2][0][RTW89_FCC][1][51] = 22, -+ [0][0][2][0][RTW89_FCC][2][51] = 127, -+ [0][0][2][0][RTW89_ETSI][1][51] = 127, -+ [0][0][2][0][RTW89_ETSI][0][51] = 127, -+ [0][0][2][0][RTW89_MKK][1][51] = 127, -+ [0][0][2][0][RTW89_MKK][0][51] = 127, -+ [0][0][2][0][RTW89_IC][1][51] = 22, -+ [0][0][2][0][RTW89_KCC][1][51] = 24, -+ [0][0][2][0][RTW89_KCC][0][51] = 127, -+ [0][0][2][0][RTW89_ACMA][1][51] = 127, -+ [0][0][2][0][RTW89_ACMA][0][51] = 127, -+ [0][0][2][0][RTW89_CHILE][1][51] = 22, -+ [0][0][2][0][RTW89_QATAR][1][51] = 127, -+ [0][0][2][0][RTW89_QATAR][0][51] = 127, -+ [0][0][2][0][RTW89_UK][1][51] = 127, -+ [0][0][2][0][RTW89_UK][0][51] = 127, -+ [0][0][2][0][RTW89_FCC][1][53] = 22, -+ [0][0][2][0][RTW89_FCC][2][53] = 127, -+ [0][0][2][0][RTW89_ETSI][1][53] = 127, -+ [0][0][2][0][RTW89_ETSI][0][53] = 127, -+ [0][0][2][0][RTW89_MKK][1][53] = 127, -+ [0][0][2][0][RTW89_MKK][0][53] = 127, -+ [0][0][2][0][RTW89_IC][1][53] = 22, -+ [0][0][2][0][RTW89_KCC][1][53] = 24, -+ [0][0][2][0][RTW89_KCC][0][53] = 127, -+ [0][0][2][0][RTW89_ACMA][1][53] = 127, -+ [0][0][2][0][RTW89_ACMA][0][53] = 127, -+ [0][0][2][0][RTW89_CHILE][1][53] = 22, -+ [0][0][2][0][RTW89_QATAR][1][53] = 127, -+ [0][0][2][0][RTW89_QATAR][0][53] = 127, -+ [0][0][2][0][RTW89_UK][1][53] = 127, -+ [0][0][2][0][RTW89_UK][0][53] = 127, -+ [0][0][2][0][RTW89_FCC][1][55] = 22, -+ [0][0][2][0][RTW89_FCC][2][55] = 68, -+ [0][0][2][0][RTW89_ETSI][1][55] = 127, -+ [0][0][2][0][RTW89_ETSI][0][55] = 127, -+ [0][0][2][0][RTW89_MKK][1][55] = 127, -+ [0][0][2][0][RTW89_MKK][0][55] = 127, -+ [0][0][2][0][RTW89_IC][1][55] = 22, -+ [0][0][2][0][RTW89_KCC][1][55] = 26, -+ [0][0][2][0][RTW89_KCC][0][55] = 127, -+ [0][0][2][0][RTW89_ACMA][1][55] = 127, -+ [0][0][2][0][RTW89_ACMA][0][55] = 127, -+ [0][0][2][0][RTW89_CHILE][1][55] = 22, -+ [0][0][2][0][RTW89_QATAR][1][55] = 127, -+ [0][0][2][0][RTW89_QATAR][0][55] = 127, -+ [0][0][2][0][RTW89_UK][1][55] = 127, -+ [0][0][2][0][RTW89_UK][0][55] = 127, -+ [0][0][2][0][RTW89_FCC][1][57] = 22, -+ [0][0][2][0][RTW89_FCC][2][57] = 68, -+ [0][0][2][0][RTW89_ETSI][1][57] = 127, -+ [0][0][2][0][RTW89_ETSI][0][57] = 127, -+ [0][0][2][0][RTW89_MKK][1][57] = 127, -+ [0][0][2][0][RTW89_MKK][0][57] = 127, -+ [0][0][2][0][RTW89_IC][1][57] = 22, -+ [0][0][2][0][RTW89_KCC][1][57] = 26, -+ [0][0][2][0][RTW89_KCC][0][57] = 127, -+ [0][0][2][0][RTW89_ACMA][1][57] = 127, -+ [0][0][2][0][RTW89_ACMA][0][57] = 127, -+ [0][0][2][0][RTW89_CHILE][1][57] = 22, -+ [0][0][2][0][RTW89_QATAR][1][57] = 127, -+ [0][0][2][0][RTW89_QATAR][0][57] = 127, -+ [0][0][2][0][RTW89_UK][1][57] = 127, -+ [0][0][2][0][RTW89_UK][0][57] = 127, -+ [0][0][2][0][RTW89_FCC][1][59] = 22, -+ [0][0][2][0][RTW89_FCC][2][59] = 68, -+ [0][0][2][0][RTW89_ETSI][1][59] = 127, -+ [0][0][2][0][RTW89_ETSI][0][59] = 127, -+ [0][0][2][0][RTW89_MKK][1][59] = 127, -+ [0][0][2][0][RTW89_MKK][0][59] = 127, -+ [0][0][2][0][RTW89_IC][1][59] = 22, -+ [0][0][2][0][RTW89_KCC][1][59] = 26, -+ [0][0][2][0][RTW89_KCC][0][59] = 127, -+ [0][0][2][0][RTW89_ACMA][1][59] = 127, -+ [0][0][2][0][RTW89_ACMA][0][59] = 127, -+ [0][0][2][0][RTW89_CHILE][1][59] = 22, -+ [0][0][2][0][RTW89_QATAR][1][59] = 127, -+ [0][0][2][0][RTW89_QATAR][0][59] = 127, -+ [0][0][2][0][RTW89_UK][1][59] = 127, -+ [0][0][2][0][RTW89_UK][0][59] = 127, -+ [0][0][2][0][RTW89_FCC][1][60] = 22, -+ [0][0][2][0][RTW89_FCC][2][60] = 68, -+ [0][0][2][0][RTW89_ETSI][1][60] = 127, -+ [0][0][2][0][RTW89_ETSI][0][60] = 127, -+ [0][0][2][0][RTW89_MKK][1][60] = 127, -+ [0][0][2][0][RTW89_MKK][0][60] = 127, -+ [0][0][2][0][RTW89_IC][1][60] = 22, -+ [0][0][2][0][RTW89_KCC][1][60] = 26, -+ [0][0][2][0][RTW89_KCC][0][60] = 127, -+ [0][0][2][0][RTW89_ACMA][1][60] = 127, -+ [0][0][2][0][RTW89_ACMA][0][60] = 127, -+ [0][0][2][0][RTW89_CHILE][1][60] = 22, -+ [0][0][2][0][RTW89_QATAR][1][60] = 127, -+ [0][0][2][0][RTW89_QATAR][0][60] = 127, -+ [0][0][2][0][RTW89_UK][1][60] = 127, -+ [0][0][2][0][RTW89_UK][0][60] = 127, -+ [0][0][2][0][RTW89_FCC][1][62] = 22, -+ [0][0][2][0][RTW89_FCC][2][62] = 68, -+ [0][0][2][0][RTW89_ETSI][1][62] = 127, -+ [0][0][2][0][RTW89_ETSI][0][62] = 127, -+ [0][0][2][0][RTW89_MKK][1][62] = 127, -+ [0][0][2][0][RTW89_MKK][0][62] = 127, -+ [0][0][2][0][RTW89_IC][1][62] = 22, -+ [0][0][2][0][RTW89_KCC][1][62] = 26, -+ [0][0][2][0][RTW89_KCC][0][62] = 127, -+ [0][0][2][0][RTW89_ACMA][1][62] = 127, -+ [0][0][2][0][RTW89_ACMA][0][62] = 127, -+ [0][0][2][0][RTW89_CHILE][1][62] = 22, -+ [0][0][2][0][RTW89_QATAR][1][62] = 127, -+ [0][0][2][0][RTW89_QATAR][0][62] = 127, -+ [0][0][2][0][RTW89_UK][1][62] = 127, -+ [0][0][2][0][RTW89_UK][0][62] = 127, -+ [0][0][2][0][RTW89_FCC][1][64] = 22, -+ [0][0][2][0][RTW89_FCC][2][64] = 68, -+ [0][0][2][0][RTW89_ETSI][1][64] = 127, -+ [0][0][2][0][RTW89_ETSI][0][64] = 127, -+ [0][0][2][0][RTW89_MKK][1][64] = 127, -+ [0][0][2][0][RTW89_MKK][0][64] = 127, -+ [0][0][2][0][RTW89_IC][1][64] = 22, -+ [0][0][2][0][RTW89_KCC][1][64] = 26, -+ [0][0][2][0][RTW89_KCC][0][64] = 127, -+ [0][0][2][0][RTW89_ACMA][1][64] = 127, -+ [0][0][2][0][RTW89_ACMA][0][64] = 127, -+ [0][0][2][0][RTW89_CHILE][1][64] = 22, -+ [0][0][2][0][RTW89_QATAR][1][64] = 127, -+ [0][0][2][0][RTW89_QATAR][0][64] = 127, -+ [0][0][2][0][RTW89_UK][1][64] = 127, -+ [0][0][2][0][RTW89_UK][0][64] = 127, -+ [0][0][2][0][RTW89_FCC][1][66] = 22, -+ [0][0][2][0][RTW89_FCC][2][66] = 68, -+ [0][0][2][0][RTW89_ETSI][1][66] = 127, -+ [0][0][2][0][RTW89_ETSI][0][66] = 127, -+ [0][0][2][0][RTW89_MKK][1][66] = 127, -+ [0][0][2][0][RTW89_MKK][0][66] = 127, -+ [0][0][2][0][RTW89_IC][1][66] = 22, -+ [0][0][2][0][RTW89_KCC][1][66] = 26, -+ [0][0][2][0][RTW89_KCC][0][66] = 127, -+ [0][0][2][0][RTW89_ACMA][1][66] = 127, -+ [0][0][2][0][RTW89_ACMA][0][66] = 127, -+ [0][0][2][0][RTW89_CHILE][1][66] = 22, -+ [0][0][2][0][RTW89_QATAR][1][66] = 127, -+ [0][0][2][0][RTW89_QATAR][0][66] = 127, -+ [0][0][2][0][RTW89_UK][1][66] = 127, -+ [0][0][2][0][RTW89_UK][0][66] = 127, -+ [0][0][2][0][RTW89_FCC][1][68] = 22, -+ [0][0][2][0][RTW89_FCC][2][68] = 68, -+ [0][0][2][0][RTW89_ETSI][1][68] = 127, -+ [0][0][2][0][RTW89_ETSI][0][68] = 127, -+ [0][0][2][0][RTW89_MKK][1][68] = 127, -+ [0][0][2][0][RTW89_MKK][0][68] = 127, -+ [0][0][2][0][RTW89_IC][1][68] = 22, -+ [0][0][2][0][RTW89_KCC][1][68] = 26, -+ [0][0][2][0][RTW89_KCC][0][68] = 127, -+ [0][0][2][0][RTW89_ACMA][1][68] = 127, -+ [0][0][2][0][RTW89_ACMA][0][68] = 127, -+ [0][0][2][0][RTW89_CHILE][1][68] = 22, -+ [0][0][2][0][RTW89_QATAR][1][68] = 127, -+ [0][0][2][0][RTW89_QATAR][0][68] = 127, -+ [0][0][2][0][RTW89_UK][1][68] = 127, -+ [0][0][2][0][RTW89_UK][0][68] = 127, -+ [0][0][2][0][RTW89_FCC][1][70] = 24, -+ [0][0][2][0][RTW89_FCC][2][70] = 68, -+ [0][0][2][0][RTW89_ETSI][1][70] = 127, -+ [0][0][2][0][RTW89_ETSI][0][70] = 127, -+ [0][0][2][0][RTW89_MKK][1][70] = 127, -+ [0][0][2][0][RTW89_MKK][0][70] = 127, -+ [0][0][2][0][RTW89_IC][1][70] = 24, -+ [0][0][2][0][RTW89_KCC][1][70] = 26, -+ [0][0][2][0][RTW89_KCC][0][70] = 127, -+ [0][0][2][0][RTW89_ACMA][1][70] = 127, -+ [0][0][2][0][RTW89_ACMA][0][70] = 127, -+ [0][0][2][0][RTW89_CHILE][1][70] = 24, -+ [0][0][2][0][RTW89_QATAR][1][70] = 127, -+ [0][0][2][0][RTW89_QATAR][0][70] = 127, -+ [0][0][2][0][RTW89_UK][1][70] = 127, -+ [0][0][2][0][RTW89_UK][0][70] = 127, -+ [0][0][2][0][RTW89_FCC][1][72] = 22, -+ [0][0][2][0][RTW89_FCC][2][72] = 68, -+ [0][0][2][0][RTW89_ETSI][1][72] = 127, -+ [0][0][2][0][RTW89_ETSI][0][72] = 127, -+ [0][0][2][0][RTW89_MKK][1][72] = 127, -+ [0][0][2][0][RTW89_MKK][0][72] = 127, -+ [0][0][2][0][RTW89_IC][1][72] = 22, -+ [0][0][2][0][RTW89_KCC][1][72] = 26, -+ [0][0][2][0][RTW89_KCC][0][72] = 127, -+ [0][0][2][0][RTW89_ACMA][1][72] = 127, -+ [0][0][2][0][RTW89_ACMA][0][72] = 127, -+ [0][0][2][0][RTW89_CHILE][1][72] = 22, -+ [0][0][2][0][RTW89_QATAR][1][72] = 127, -+ [0][0][2][0][RTW89_QATAR][0][72] = 127, -+ [0][0][2][0][RTW89_UK][1][72] = 127, -+ [0][0][2][0][RTW89_UK][0][72] = 127, -+ [0][0][2][0][RTW89_FCC][1][74] = 22, -+ [0][0][2][0][RTW89_FCC][2][74] = 68, -+ [0][0][2][0][RTW89_ETSI][1][74] = 127, -+ [0][0][2][0][RTW89_ETSI][0][74] = 127, -+ [0][0][2][0][RTW89_MKK][1][74] = 127, -+ [0][0][2][0][RTW89_MKK][0][74] = 127, -+ [0][0][2][0][RTW89_IC][1][74] = 22, -+ [0][0][2][0][RTW89_KCC][1][74] = 26, -+ [0][0][2][0][RTW89_KCC][0][74] = 127, -+ [0][0][2][0][RTW89_ACMA][1][74] = 127, -+ [0][0][2][0][RTW89_ACMA][0][74] = 127, -+ [0][0][2][0][RTW89_CHILE][1][74] = 22, -+ [0][0][2][0][RTW89_QATAR][1][74] = 127, -+ [0][0][2][0][RTW89_QATAR][0][74] = 127, -+ [0][0][2][0][RTW89_UK][1][74] = 127, -+ [0][0][2][0][RTW89_UK][0][74] = 127, -+ [0][0][2][0][RTW89_FCC][1][75] = 22, -+ [0][0][2][0][RTW89_FCC][2][75] = 68, -+ [0][0][2][0][RTW89_ETSI][1][75] = 127, -+ [0][0][2][0][RTW89_ETSI][0][75] = 127, -+ [0][0][2][0][RTW89_MKK][1][75] = 127, -+ [0][0][2][0][RTW89_MKK][0][75] = 127, -+ [0][0][2][0][RTW89_IC][1][75] = 22, -+ [0][0][2][0][RTW89_KCC][1][75] = 26, -+ [0][0][2][0][RTW89_KCC][0][75] = 127, -+ [0][0][2][0][RTW89_ACMA][1][75] = 127, -+ [0][0][2][0][RTW89_ACMA][0][75] = 127, -+ [0][0][2][0][RTW89_CHILE][1][75] = 22, -+ [0][0][2][0][RTW89_QATAR][1][75] = 127, -+ [0][0][2][0][RTW89_QATAR][0][75] = 127, -+ [0][0][2][0][RTW89_UK][1][75] = 127, -+ [0][0][2][0][RTW89_UK][0][75] = 127, -+ [0][0][2][0][RTW89_FCC][1][77] = 22, -+ [0][0][2][0][RTW89_FCC][2][77] = 68, -+ [0][0][2][0][RTW89_ETSI][1][77] = 127, -+ [0][0][2][0][RTW89_ETSI][0][77] = 127, -+ [0][0][2][0][RTW89_MKK][1][77] = 127, -+ [0][0][2][0][RTW89_MKK][0][77] = 127, -+ [0][0][2][0][RTW89_IC][1][77] = 22, -+ [0][0][2][0][RTW89_KCC][1][77] = 26, -+ [0][0][2][0][RTW89_KCC][0][77] = 127, -+ [0][0][2][0][RTW89_ACMA][1][77] = 127, -+ [0][0][2][0][RTW89_ACMA][0][77] = 127, -+ [0][0][2][0][RTW89_CHILE][1][77] = 22, -+ [0][0][2][0][RTW89_QATAR][1][77] = 127, -+ [0][0][2][0][RTW89_QATAR][0][77] = 127, -+ [0][0][2][0][RTW89_UK][1][77] = 127, -+ [0][0][2][0][RTW89_UK][0][77] = 127, -+ [0][0][2][0][RTW89_FCC][1][79] = 22, -+ [0][0][2][0][RTW89_FCC][2][79] = 68, -+ [0][0][2][0][RTW89_ETSI][1][79] = 127, -+ [0][0][2][0][RTW89_ETSI][0][79] = 127, -+ [0][0][2][0][RTW89_MKK][1][79] = 127, -+ [0][0][2][0][RTW89_MKK][0][79] = 127, -+ [0][0][2][0][RTW89_IC][1][79] = 22, -+ [0][0][2][0][RTW89_KCC][1][79] = 26, -+ [0][0][2][0][RTW89_KCC][0][79] = 127, -+ [0][0][2][0][RTW89_ACMA][1][79] = 127, -+ [0][0][2][0][RTW89_ACMA][0][79] = 127, -+ [0][0][2][0][RTW89_CHILE][1][79] = 22, -+ [0][0][2][0][RTW89_QATAR][1][79] = 127, -+ [0][0][2][0][RTW89_QATAR][0][79] = 127, -+ [0][0][2][0][RTW89_UK][1][79] = 127, -+ [0][0][2][0][RTW89_UK][0][79] = 127, -+ [0][0][2][0][RTW89_FCC][1][81] = 22, -+ [0][0][2][0][RTW89_FCC][2][81] = 68, -+ [0][0][2][0][RTW89_ETSI][1][81] = 127, -+ [0][0][2][0][RTW89_ETSI][0][81] = 127, -+ [0][0][2][0][RTW89_MKK][1][81] = 127, -+ [0][0][2][0][RTW89_MKK][0][81] = 127, -+ [0][0][2][0][RTW89_IC][1][81] = 22, -+ [0][0][2][0][RTW89_KCC][1][81] = 26, -+ [0][0][2][0][RTW89_KCC][0][81] = 127, -+ [0][0][2][0][RTW89_ACMA][1][81] = 127, -+ [0][0][2][0][RTW89_ACMA][0][81] = 127, -+ [0][0][2][0][RTW89_CHILE][1][81] = 22, -+ [0][0][2][0][RTW89_QATAR][1][81] = 127, -+ [0][0][2][0][RTW89_QATAR][0][81] = 127, -+ [0][0][2][0][RTW89_UK][1][81] = 127, -+ [0][0][2][0][RTW89_UK][0][81] = 127, -+ [0][0][2][0][RTW89_FCC][1][83] = 22, -+ [0][0][2][0][RTW89_FCC][2][83] = 68, -+ [0][0][2][0][RTW89_ETSI][1][83] = 127, -+ [0][0][2][0][RTW89_ETSI][0][83] = 127, -+ [0][0][2][0][RTW89_MKK][1][83] = 127, -+ [0][0][2][0][RTW89_MKK][0][83] = 127, -+ [0][0][2][0][RTW89_IC][1][83] = 22, -+ [0][0][2][0][RTW89_KCC][1][83] = 32, -+ [0][0][2][0][RTW89_KCC][0][83] = 127, -+ [0][0][2][0][RTW89_ACMA][1][83] = 127, -+ [0][0][2][0][RTW89_ACMA][0][83] = 127, -+ [0][0][2][0][RTW89_CHILE][1][83] = 22, -+ [0][0][2][0][RTW89_QATAR][1][83] = 127, -+ [0][0][2][0][RTW89_QATAR][0][83] = 127, -+ [0][0][2][0][RTW89_UK][1][83] = 127, -+ [0][0][2][0][RTW89_UK][0][83] = 127, -+ [0][0][2][0][RTW89_FCC][1][85] = 22, -+ [0][0][2][0][RTW89_FCC][2][85] = 68, -+ [0][0][2][0][RTW89_ETSI][1][85] = 127, -+ [0][0][2][0][RTW89_ETSI][0][85] = 127, -+ [0][0][2][0][RTW89_MKK][1][85] = 127, -+ [0][0][2][0][RTW89_MKK][0][85] = 127, -+ [0][0][2][0][RTW89_IC][1][85] = 22, -+ [0][0][2][0][RTW89_KCC][1][85] = 32, -+ [0][0][2][0][RTW89_KCC][0][85] = 127, -+ [0][0][2][0][RTW89_ACMA][1][85] = 127, -+ [0][0][2][0][RTW89_ACMA][0][85] = 127, -+ [0][0][2][0][RTW89_CHILE][1][85] = 22, -+ [0][0][2][0][RTW89_QATAR][1][85] = 127, -+ [0][0][2][0][RTW89_QATAR][0][85] = 127, -+ [0][0][2][0][RTW89_UK][1][85] = 127, -+ [0][0][2][0][RTW89_UK][0][85] = 127, -+ [0][0][2][0][RTW89_FCC][1][87] = 22, -+ [0][0][2][0][RTW89_FCC][2][87] = 127, -+ [0][0][2][0][RTW89_ETSI][1][87] = 127, -+ [0][0][2][0][RTW89_ETSI][0][87] = 127, -+ [0][0][2][0][RTW89_MKK][1][87] = 127, -+ [0][0][2][0][RTW89_MKK][0][87] = 127, -+ [0][0][2][0][RTW89_IC][1][87] = 22, -+ [0][0][2][0][RTW89_KCC][1][87] = 32, -+ [0][0][2][0][RTW89_KCC][0][87] = 127, -+ [0][0][2][0][RTW89_ACMA][1][87] = 127, -+ [0][0][2][0][RTW89_ACMA][0][87] = 127, -+ [0][0][2][0][RTW89_CHILE][1][87] = 22, -+ [0][0][2][0][RTW89_QATAR][1][87] = 127, -+ [0][0][2][0][RTW89_QATAR][0][87] = 127, -+ [0][0][2][0][RTW89_UK][1][87] = 127, -+ [0][0][2][0][RTW89_UK][0][87] = 127, -+ [0][0][2][0][RTW89_FCC][1][89] = 22, -+ [0][0][2][0][RTW89_FCC][2][89] = 127, -+ [0][0][2][0][RTW89_ETSI][1][89] = 127, -+ [0][0][2][0][RTW89_ETSI][0][89] = 127, -+ [0][0][2][0][RTW89_MKK][1][89] = 127, -+ [0][0][2][0][RTW89_MKK][0][89] = 127, -+ [0][0][2][0][RTW89_IC][1][89] = 22, -+ [0][0][2][0][RTW89_KCC][1][89] = 32, -+ [0][0][2][0][RTW89_KCC][0][89] = 127, -+ [0][0][2][0][RTW89_ACMA][1][89] = 127, -+ [0][0][2][0][RTW89_ACMA][0][89] = 127, -+ [0][0][2][0][RTW89_CHILE][1][89] = 22, -+ [0][0][2][0][RTW89_QATAR][1][89] = 127, -+ [0][0][2][0][RTW89_QATAR][0][89] = 127, -+ [0][0][2][0][RTW89_UK][1][89] = 127, -+ [0][0][2][0][RTW89_UK][0][89] = 127, -+ [0][0][2][0][RTW89_FCC][1][90] = 22, -+ [0][0][2][0][RTW89_FCC][2][90] = 127, -+ [0][0][2][0][RTW89_ETSI][1][90] = 127, -+ [0][0][2][0][RTW89_ETSI][0][90] = 127, -+ [0][0][2][0][RTW89_MKK][1][90] = 127, -+ [0][0][2][0][RTW89_MKK][0][90] = 127, -+ [0][0][2][0][RTW89_IC][1][90] = 22, -+ [0][0][2][0][RTW89_KCC][1][90] = 32, -+ [0][0][2][0][RTW89_KCC][0][90] = 127, -+ [0][0][2][0][RTW89_ACMA][1][90] = 127, -+ [0][0][2][0][RTW89_ACMA][0][90] = 127, -+ [0][0][2][0][RTW89_CHILE][1][90] = 22, -+ [0][0][2][0][RTW89_QATAR][1][90] = 127, -+ [0][0][2][0][RTW89_QATAR][0][90] = 127, -+ [0][0][2][0][RTW89_UK][1][90] = 127, -+ [0][0][2][0][RTW89_UK][0][90] = 127, -+ [0][0][2][0][RTW89_FCC][1][92] = 22, -+ [0][0][2][0][RTW89_FCC][2][92] = 127, -+ [0][0][2][0][RTW89_ETSI][1][92] = 127, -+ [0][0][2][0][RTW89_ETSI][0][92] = 127, -+ [0][0][2][0][RTW89_MKK][1][92] = 127, -+ [0][0][2][0][RTW89_MKK][0][92] = 127, -+ [0][0][2][0][RTW89_IC][1][92] = 22, -+ [0][0][2][0][RTW89_KCC][1][92] = 32, -+ [0][0][2][0][RTW89_KCC][0][92] = 127, -+ [0][0][2][0][RTW89_ACMA][1][92] = 127, -+ [0][0][2][0][RTW89_ACMA][0][92] = 127, -+ [0][0][2][0][RTW89_CHILE][1][92] = 22, -+ [0][0][2][0][RTW89_QATAR][1][92] = 127, -+ [0][0][2][0][RTW89_QATAR][0][92] = 127, -+ [0][0][2][0][RTW89_UK][1][92] = 127, -+ [0][0][2][0][RTW89_UK][0][92] = 127, -+ [0][0][2][0][RTW89_FCC][1][94] = 22, -+ [0][0][2][0][RTW89_FCC][2][94] = 127, -+ [0][0][2][0][RTW89_ETSI][1][94] = 127, -+ [0][0][2][0][RTW89_ETSI][0][94] = 127, -+ [0][0][2][0][RTW89_MKK][1][94] = 127, -+ [0][0][2][0][RTW89_MKK][0][94] = 127, -+ [0][0][2][0][RTW89_IC][1][94] = 22, -+ [0][0][2][0][RTW89_KCC][1][94] = 32, -+ [0][0][2][0][RTW89_KCC][0][94] = 127, -+ [0][0][2][0][RTW89_ACMA][1][94] = 127, -+ [0][0][2][0][RTW89_ACMA][0][94] = 127, -+ [0][0][2][0][RTW89_CHILE][1][94] = 22, -+ [0][0][2][0][RTW89_QATAR][1][94] = 127, -+ [0][0][2][0][RTW89_QATAR][0][94] = 127, -+ [0][0][2][0][RTW89_UK][1][94] = 127, -+ [0][0][2][0][RTW89_UK][0][94] = 127, -+ [0][0][2][0][RTW89_FCC][1][96] = 22, -+ [0][0][2][0][RTW89_FCC][2][96] = 127, -+ [0][0][2][0][RTW89_ETSI][1][96] = 127, -+ [0][0][2][0][RTW89_ETSI][0][96] = 127, -+ [0][0][2][0][RTW89_MKK][1][96] = 127, -+ [0][0][2][0][RTW89_MKK][0][96] = 127, -+ [0][0][2][0][RTW89_IC][1][96] = 22, -+ [0][0][2][0][RTW89_KCC][1][96] = 32, -+ [0][0][2][0][RTW89_KCC][0][96] = 127, -+ [0][0][2][0][RTW89_ACMA][1][96] = 127, -+ [0][0][2][0][RTW89_ACMA][0][96] = 127, -+ [0][0][2][0][RTW89_CHILE][1][96] = 22, -+ [0][0][2][0][RTW89_QATAR][1][96] = 127, -+ [0][0][2][0][RTW89_QATAR][0][96] = 127, -+ [0][0][2][0][RTW89_UK][1][96] = 127, -+ [0][0][2][0][RTW89_UK][0][96] = 127, -+ [0][0][2][0][RTW89_FCC][1][98] = 22, -+ [0][0][2][0][RTW89_FCC][2][98] = 127, -+ [0][0][2][0][RTW89_ETSI][1][98] = 127, -+ [0][0][2][0][RTW89_ETSI][0][98] = 127, -+ [0][0][2][0][RTW89_MKK][1][98] = 127, -+ [0][0][2][0][RTW89_MKK][0][98] = 127, -+ [0][0][2][0][RTW89_IC][1][98] = 22, -+ [0][0][2][0][RTW89_KCC][1][98] = 32, -+ [0][0][2][0][RTW89_KCC][0][98] = 127, -+ [0][0][2][0][RTW89_ACMA][1][98] = 127, -+ [0][0][2][0][RTW89_ACMA][0][98] = 127, -+ [0][0][2][0][RTW89_CHILE][1][98] = 22, -+ [0][0][2][0][RTW89_QATAR][1][98] = 127, -+ [0][0][2][0][RTW89_QATAR][0][98] = 127, -+ [0][0][2][0][RTW89_UK][1][98] = 127, -+ [0][0][2][0][RTW89_UK][0][98] = 127, -+ [0][0][2][0][RTW89_FCC][1][100] = 22, -+ [0][0][2][0][RTW89_FCC][2][100] = 127, -+ [0][0][2][0][RTW89_ETSI][1][100] = 127, -+ [0][0][2][0][RTW89_ETSI][0][100] = 127, -+ [0][0][2][0][RTW89_MKK][1][100] = 127, -+ [0][0][2][0][RTW89_MKK][0][100] = 127, -+ [0][0][2][0][RTW89_IC][1][100] = 22, -+ [0][0][2][0][RTW89_KCC][1][100] = 32, -+ [0][0][2][0][RTW89_KCC][0][100] = 127, -+ [0][0][2][0][RTW89_ACMA][1][100] = 127, -+ [0][0][2][0][RTW89_ACMA][0][100] = 127, -+ [0][0][2][0][RTW89_CHILE][1][100] = 22, -+ [0][0][2][0][RTW89_QATAR][1][100] = 127, -+ [0][0][2][0][RTW89_QATAR][0][100] = 127, -+ [0][0][2][0][RTW89_UK][1][100] = 127, -+ [0][0][2][0][RTW89_UK][0][100] = 127, -+ [0][0][2][0][RTW89_FCC][1][102] = 22, -+ [0][0][2][0][RTW89_FCC][2][102] = 127, -+ [0][0][2][0][RTW89_ETSI][1][102] = 127, -+ [0][0][2][0][RTW89_ETSI][0][102] = 127, -+ [0][0][2][0][RTW89_MKK][1][102] = 127, -+ [0][0][2][0][RTW89_MKK][0][102] = 127, -+ [0][0][2][0][RTW89_IC][1][102] = 22, -+ [0][0][2][0][RTW89_KCC][1][102] = 32, -+ [0][0][2][0][RTW89_KCC][0][102] = 127, -+ [0][0][2][0][RTW89_ACMA][1][102] = 127, -+ [0][0][2][0][RTW89_ACMA][0][102] = 127, -+ [0][0][2][0][RTW89_CHILE][1][102] = 22, -+ [0][0][2][0][RTW89_QATAR][1][102] = 127, -+ [0][0][2][0][RTW89_QATAR][0][102] = 127, -+ [0][0][2][0][RTW89_UK][1][102] = 127, -+ [0][0][2][0][RTW89_UK][0][102] = 127, -+ [0][0][2][0][RTW89_FCC][1][104] = 22, -+ [0][0][2][0][RTW89_FCC][2][104] = 127, -+ [0][0][2][0][RTW89_ETSI][1][104] = 127, -+ [0][0][2][0][RTW89_ETSI][0][104] = 127, -+ [0][0][2][0][RTW89_MKK][1][104] = 127, -+ [0][0][2][0][RTW89_MKK][0][104] = 127, -+ [0][0][2][0][RTW89_IC][1][104] = 22, -+ [0][0][2][0][RTW89_KCC][1][104] = 32, -+ [0][0][2][0][RTW89_KCC][0][104] = 127, -+ [0][0][2][0][RTW89_ACMA][1][104] = 127, -+ [0][0][2][0][RTW89_ACMA][0][104] = 127, -+ [0][0][2][0][RTW89_CHILE][1][104] = 22, -+ [0][0][2][0][RTW89_QATAR][1][104] = 127, -+ [0][0][2][0][RTW89_QATAR][0][104] = 127, -+ [0][0][2][0][RTW89_UK][1][104] = 127, -+ [0][0][2][0][RTW89_UK][0][104] = 127, -+ [0][0][2][0][RTW89_FCC][1][105] = 22, -+ [0][0][2][0][RTW89_FCC][2][105] = 127, -+ [0][0][2][0][RTW89_ETSI][1][105] = 127, -+ [0][0][2][0][RTW89_ETSI][0][105] = 127, -+ [0][0][2][0][RTW89_MKK][1][105] = 127, -+ [0][0][2][0][RTW89_MKK][0][105] = 127, -+ [0][0][2][0][RTW89_IC][1][105] = 22, -+ [0][0][2][0][RTW89_KCC][1][105] = 32, -+ [0][0][2][0][RTW89_KCC][0][105] = 127, -+ [0][0][2][0][RTW89_ACMA][1][105] = 127, -+ [0][0][2][0][RTW89_ACMA][0][105] = 127, -+ [0][0][2][0][RTW89_CHILE][1][105] = 22, -+ [0][0][2][0][RTW89_QATAR][1][105] = 127, -+ [0][0][2][0][RTW89_QATAR][0][105] = 127, -+ [0][0][2][0][RTW89_UK][1][105] = 127, -+ [0][0][2][0][RTW89_UK][0][105] = 127, -+ [0][0][2][0][RTW89_FCC][1][107] = 24, -+ [0][0][2][0][RTW89_FCC][2][107] = 127, -+ [0][0][2][0][RTW89_ETSI][1][107] = 127, -+ [0][0][2][0][RTW89_ETSI][0][107] = 127, -+ [0][0][2][0][RTW89_MKK][1][107] = 127, -+ [0][0][2][0][RTW89_MKK][0][107] = 127, -+ [0][0][2][0][RTW89_IC][1][107] = 24, -+ [0][0][2][0][RTW89_KCC][1][107] = 32, -+ [0][0][2][0][RTW89_KCC][0][107] = 127, -+ [0][0][2][0][RTW89_ACMA][1][107] = 127, -+ [0][0][2][0][RTW89_ACMA][0][107] = 127, -+ [0][0][2][0][RTW89_CHILE][1][107] = 24, -+ [0][0][2][0][RTW89_QATAR][1][107] = 127, -+ [0][0][2][0][RTW89_QATAR][0][107] = 127, -+ [0][0][2][0][RTW89_UK][1][107] = 127, -+ [0][0][2][0][RTW89_UK][0][107] = 127, -+ [0][0][2][0][RTW89_FCC][1][109] = 24, -+ [0][0][2][0][RTW89_FCC][2][109] = 127, -+ [0][0][2][0][RTW89_ETSI][1][109] = 127, -+ [0][0][2][0][RTW89_ETSI][0][109] = 127, -+ [0][0][2][0][RTW89_MKK][1][109] = 127, -+ [0][0][2][0][RTW89_MKK][0][109] = 127, -+ [0][0][2][0][RTW89_IC][1][109] = 24, -+ [0][0][2][0][RTW89_KCC][1][109] = 32, -+ [0][0][2][0][RTW89_KCC][0][109] = 127, -+ [0][0][2][0][RTW89_ACMA][1][109] = 127, -+ [0][0][2][0][RTW89_ACMA][0][109] = 127, -+ [0][0][2][0][RTW89_CHILE][1][109] = 24, -+ [0][0][2][0][RTW89_QATAR][1][109] = 127, -+ [0][0][2][0][RTW89_QATAR][0][109] = 127, -+ [0][0][2][0][RTW89_UK][1][109] = 127, -+ [0][0][2][0][RTW89_UK][0][109] = 127, -+ [0][0][2][0][RTW89_FCC][1][111] = 127, -+ [0][0][2][0][RTW89_FCC][2][111] = 127, -+ [0][0][2][0][RTW89_ETSI][1][111] = 127, -+ [0][0][2][0][RTW89_ETSI][0][111] = 127, -+ [0][0][2][0][RTW89_MKK][1][111] = 127, -+ [0][0][2][0][RTW89_MKK][0][111] = 127, -+ [0][0][2][0][RTW89_IC][1][111] = 127, -+ [0][0][2][0][RTW89_KCC][1][111] = 127, -+ [0][0][2][0][RTW89_KCC][0][111] = 127, -+ [0][0][2][0][RTW89_ACMA][1][111] = 127, -+ [0][0][2][0][RTW89_ACMA][0][111] = 127, -+ [0][0][2][0][RTW89_CHILE][1][111] = 127, -+ [0][0][2][0][RTW89_QATAR][1][111] = 127, -+ [0][0][2][0][RTW89_QATAR][0][111] = 127, -+ [0][0][2][0][RTW89_UK][1][111] = 127, -+ [0][0][2][0][RTW89_UK][0][111] = 127, -+ [0][0][2][0][RTW89_FCC][1][113] = 127, -+ [0][0][2][0][RTW89_FCC][2][113] = 127, -+ [0][0][2][0][RTW89_ETSI][1][113] = 127, -+ [0][0][2][0][RTW89_ETSI][0][113] = 127, -+ [0][0][2][0][RTW89_MKK][1][113] = 127, -+ [0][0][2][0][RTW89_MKK][0][113] = 127, -+ [0][0][2][0][RTW89_IC][1][113] = 127, -+ [0][0][2][0][RTW89_KCC][1][113] = 127, -+ [0][0][2][0][RTW89_KCC][0][113] = 127, -+ [0][0][2][0][RTW89_ACMA][1][113] = 127, -+ [0][0][2][0][RTW89_ACMA][0][113] = 127, -+ [0][0][2][0][RTW89_CHILE][1][113] = 127, -+ [0][0][2][0][RTW89_QATAR][1][113] = 127, -+ [0][0][2][0][RTW89_QATAR][0][113] = 127, -+ [0][0][2][0][RTW89_UK][1][113] = 127, -+ [0][0][2][0][RTW89_UK][0][113] = 127, -+ [0][0][2][0][RTW89_FCC][1][115] = 127, -+ [0][0][2][0][RTW89_FCC][2][115] = 127, -+ [0][0][2][0][RTW89_ETSI][1][115] = 127, -+ [0][0][2][0][RTW89_ETSI][0][115] = 127, -+ [0][0][2][0][RTW89_MKK][1][115] = 127, -+ [0][0][2][0][RTW89_MKK][0][115] = 127, -+ [0][0][2][0][RTW89_IC][1][115] = 127, -+ [0][0][2][0][RTW89_KCC][1][115] = 127, -+ [0][0][2][0][RTW89_KCC][0][115] = 127, -+ [0][0][2][0][RTW89_ACMA][1][115] = 127, -+ [0][0][2][0][RTW89_ACMA][0][115] = 127, -+ [0][0][2][0][RTW89_CHILE][1][115] = 127, -+ [0][0][2][0][RTW89_QATAR][1][115] = 127, -+ [0][0][2][0][RTW89_QATAR][0][115] = 127, -+ [0][0][2][0][RTW89_UK][1][115] = 127, -+ [0][0][2][0][RTW89_UK][0][115] = 127, -+ [0][0][2][0][RTW89_FCC][1][117] = 127, -+ [0][0][2][0][RTW89_FCC][2][117] = 127, -+ [0][0][2][0][RTW89_ETSI][1][117] = 127, -+ [0][0][2][0][RTW89_ETSI][0][117] = 127, -+ [0][0][2][0][RTW89_MKK][1][117] = 127, -+ [0][0][2][0][RTW89_MKK][0][117] = 127, -+ [0][0][2][0][RTW89_IC][1][117] = 127, -+ [0][0][2][0][RTW89_KCC][1][117] = 127, -+ [0][0][2][0][RTW89_KCC][0][117] = 127, -+ [0][0][2][0][RTW89_ACMA][1][117] = 127, -+ [0][0][2][0][RTW89_ACMA][0][117] = 127, -+ [0][0][2][0][RTW89_CHILE][1][117] = 127, -+ [0][0][2][0][RTW89_QATAR][1][117] = 127, -+ [0][0][2][0][RTW89_QATAR][0][117] = 127, -+ [0][0][2][0][RTW89_UK][1][117] = 127, -+ [0][0][2][0][RTW89_UK][0][117] = 127, -+ [0][0][2][0][RTW89_FCC][1][119] = 127, -+ [0][0][2][0][RTW89_FCC][2][119] = 127, -+ [0][0][2][0][RTW89_ETSI][1][119] = 127, -+ [0][0][2][0][RTW89_ETSI][0][119] = 127, -+ [0][0][2][0][RTW89_MKK][1][119] = 127, -+ [0][0][2][0][RTW89_MKK][0][119] = 127, -+ [0][0][2][0][RTW89_IC][1][119] = 127, -+ [0][0][2][0][RTW89_KCC][1][119] = 127, -+ [0][0][2][0][RTW89_KCC][0][119] = 127, -+ [0][0][2][0][RTW89_ACMA][1][119] = 127, -+ [0][0][2][0][RTW89_ACMA][0][119] = 127, -+ [0][0][2][0][RTW89_CHILE][1][119] = 127, -+ [0][0][2][0][RTW89_QATAR][1][119] = 127, -+ [0][0][2][0][RTW89_QATAR][0][119] = 127, -+ [0][0][2][0][RTW89_UK][1][119] = 127, -+ [0][0][2][0][RTW89_UK][0][119] = 127, -+ [0][1][2][0][RTW89_FCC][1][0] = -2, -+ [0][1][2][0][RTW89_FCC][2][0] = 54, -+ [0][1][2][0][RTW89_ETSI][1][0] = 54, -+ [0][1][2][0][RTW89_ETSI][0][0] = 18, -+ [0][1][2][0][RTW89_MKK][1][0] = 56, -+ [0][1][2][0][RTW89_MKK][0][0] = 16, -+ [0][1][2][0][RTW89_IC][1][0] = -2, -+ [0][1][2][0][RTW89_KCC][1][0] = 12, -+ [0][1][2][0][RTW89_KCC][0][0] = 10, -+ [0][1][2][0][RTW89_ACMA][1][0] = 54, -+ [0][1][2][0][RTW89_ACMA][0][0] = 18, -+ [0][1][2][0][RTW89_CHILE][1][0] = -2, -+ [0][1][2][0][RTW89_QATAR][1][0] = 54, -+ [0][1][2][0][RTW89_QATAR][0][0] = 18, -+ [0][1][2][0][RTW89_UK][1][0] = 54, -+ [0][1][2][0][RTW89_UK][0][0] = 18, -+ [0][1][2][0][RTW89_FCC][1][2] = -4, -+ [0][1][2][0][RTW89_FCC][2][2] = 54, -+ [0][1][2][0][RTW89_ETSI][1][2] = 54, -+ [0][1][2][0][RTW89_ETSI][0][2] = 18, -+ [0][1][2][0][RTW89_MKK][1][2] = 54, -+ [0][1][2][0][RTW89_MKK][0][2] = 16, -+ [0][1][2][0][RTW89_IC][1][2] = -4, -+ [0][1][2][0][RTW89_KCC][1][2] = 12, -+ [0][1][2][0][RTW89_KCC][0][2] = 12, -+ [0][1][2][0][RTW89_ACMA][1][2] = 54, -+ [0][1][2][0][RTW89_ACMA][0][2] = 18, -+ [0][1][2][0][RTW89_CHILE][1][2] = -4, -+ [0][1][2][0][RTW89_QATAR][1][2] = 54, -+ [0][1][2][0][RTW89_QATAR][0][2] = 18, -+ [0][1][2][0][RTW89_UK][1][2] = 54, -+ [0][1][2][0][RTW89_UK][0][2] = 18, -+ [0][1][2][0][RTW89_FCC][1][4] = -4, -+ [0][1][2][0][RTW89_FCC][2][4] = 54, -+ [0][1][2][0][RTW89_ETSI][1][4] = 54, -+ [0][1][2][0][RTW89_ETSI][0][4] = 18, -+ [0][1][2][0][RTW89_MKK][1][4] = 54, -+ [0][1][2][0][RTW89_MKK][0][4] = 16, -+ [0][1][2][0][RTW89_IC][1][4] = -4, -+ [0][1][2][0][RTW89_KCC][1][4] = 12, -+ [0][1][2][0][RTW89_KCC][0][4] = 12, -+ [0][1][2][0][RTW89_ACMA][1][4] = 54, -+ [0][1][2][0][RTW89_ACMA][0][4] = 18, -+ [0][1][2][0][RTW89_CHILE][1][4] = -4, -+ [0][1][2][0][RTW89_QATAR][1][4] = 54, -+ [0][1][2][0][RTW89_QATAR][0][4] = 18, -+ [0][1][2][0][RTW89_UK][1][4] = 54, -+ [0][1][2][0][RTW89_UK][0][4] = 18, -+ [0][1][2][0][RTW89_FCC][1][6] = -4, -+ [0][1][2][0][RTW89_FCC][2][6] = 54, -+ [0][1][2][0][RTW89_ETSI][1][6] = 54, -+ [0][1][2][0][RTW89_ETSI][0][6] = 18, -+ [0][1][2][0][RTW89_MKK][1][6] = 54, -+ [0][1][2][0][RTW89_MKK][0][6] = 16, -+ [0][1][2][0][RTW89_IC][1][6] = -4, -+ [0][1][2][0][RTW89_KCC][1][6] = 12, -+ [0][1][2][0][RTW89_KCC][0][6] = 12, -+ [0][1][2][0][RTW89_ACMA][1][6] = 54, -+ [0][1][2][0][RTW89_ACMA][0][6] = 18, -+ [0][1][2][0][RTW89_CHILE][1][6] = -4, -+ [0][1][2][0][RTW89_QATAR][1][6] = 54, -+ [0][1][2][0][RTW89_QATAR][0][6] = 18, -+ [0][1][2][0][RTW89_UK][1][6] = 54, -+ [0][1][2][0][RTW89_UK][0][6] = 18, -+ [0][1][2][0][RTW89_FCC][1][8] = -4, -+ [0][1][2][0][RTW89_FCC][2][8] = 54, -+ [0][1][2][0][RTW89_ETSI][1][8] = 54, -+ [0][1][2][0][RTW89_ETSI][0][8] = 18, -+ [0][1][2][0][RTW89_MKK][1][8] = 54, -+ [0][1][2][0][RTW89_MKK][0][8] = 16, -+ [0][1][2][0][RTW89_IC][1][8] = -4, -+ [0][1][2][0][RTW89_KCC][1][8] = 12, -+ [0][1][2][0][RTW89_KCC][0][8] = 12, -+ [0][1][2][0][RTW89_ACMA][1][8] = 54, -+ [0][1][2][0][RTW89_ACMA][0][8] = 18, -+ [0][1][2][0][RTW89_CHILE][1][8] = -4, -+ [0][1][2][0][RTW89_QATAR][1][8] = 54, -+ [0][1][2][0][RTW89_QATAR][0][8] = 18, -+ [0][1][2][0][RTW89_UK][1][8] = 54, -+ [0][1][2][0][RTW89_UK][0][8] = 18, -+ [0][1][2][0][RTW89_FCC][1][10] = -4, -+ [0][1][2][0][RTW89_FCC][2][10] = 54, -+ [0][1][2][0][RTW89_ETSI][1][10] = 54, -+ [0][1][2][0][RTW89_ETSI][0][10] = 18, -+ [0][1][2][0][RTW89_MKK][1][10] = 54, -+ [0][1][2][0][RTW89_MKK][0][10] = 16, -+ [0][1][2][0][RTW89_IC][1][10] = -4, -+ [0][1][2][0][RTW89_KCC][1][10] = 12, -+ [0][1][2][0][RTW89_KCC][0][10] = 12, -+ [0][1][2][0][RTW89_ACMA][1][10] = 54, -+ [0][1][2][0][RTW89_ACMA][0][10] = 18, -+ [0][1][2][0][RTW89_CHILE][1][10] = -4, -+ [0][1][2][0][RTW89_QATAR][1][10] = 54, -+ [0][1][2][0][RTW89_QATAR][0][10] = 18, -+ [0][1][2][0][RTW89_UK][1][10] = 54, -+ [0][1][2][0][RTW89_UK][0][10] = 18, -+ [0][1][2][0][RTW89_FCC][1][12] = -4, -+ [0][1][2][0][RTW89_FCC][2][12] = 54, -+ [0][1][2][0][RTW89_ETSI][1][12] = 54, -+ [0][1][2][0][RTW89_ETSI][0][12] = 18, -+ [0][1][2][0][RTW89_MKK][1][12] = 54, -+ [0][1][2][0][RTW89_MKK][0][12] = 16, -+ [0][1][2][0][RTW89_IC][1][12] = -4, -+ [0][1][2][0][RTW89_KCC][1][12] = 12, -+ [0][1][2][0][RTW89_KCC][0][12] = 12, -+ [0][1][2][0][RTW89_ACMA][1][12] = 54, -+ [0][1][2][0][RTW89_ACMA][0][12] = 18, -+ [0][1][2][0][RTW89_CHILE][1][12] = -4, -+ [0][1][2][0][RTW89_QATAR][1][12] = 54, -+ [0][1][2][0][RTW89_QATAR][0][12] = 18, -+ [0][1][2][0][RTW89_UK][1][12] = 54, -+ [0][1][2][0][RTW89_UK][0][12] = 18, -+ [0][1][2][0][RTW89_FCC][1][14] = -4, -+ [0][1][2][0][RTW89_FCC][2][14] = 54, -+ [0][1][2][0][RTW89_ETSI][1][14] = 54, -+ [0][1][2][0][RTW89_ETSI][0][14] = 18, -+ [0][1][2][0][RTW89_MKK][1][14] = 54, -+ [0][1][2][0][RTW89_MKK][0][14] = 16, -+ [0][1][2][0][RTW89_IC][1][14] = -4, -+ [0][1][2][0][RTW89_KCC][1][14] = 12, -+ [0][1][2][0][RTW89_KCC][0][14] = 12, -+ [0][1][2][0][RTW89_ACMA][1][14] = 54, -+ [0][1][2][0][RTW89_ACMA][0][14] = 18, -+ [0][1][2][0][RTW89_CHILE][1][14] = -4, -+ [0][1][2][0][RTW89_QATAR][1][14] = 54, -+ [0][1][2][0][RTW89_QATAR][0][14] = 18, -+ [0][1][2][0][RTW89_UK][1][14] = 54, -+ [0][1][2][0][RTW89_UK][0][14] = 18, -+ [0][1][2][0][RTW89_FCC][1][15] = -4, -+ [0][1][2][0][RTW89_FCC][2][15] = 54, -+ [0][1][2][0][RTW89_ETSI][1][15] = 54, -+ [0][1][2][0][RTW89_ETSI][0][15] = 18, -+ [0][1][2][0][RTW89_MKK][1][15] = 54, -+ [0][1][2][0][RTW89_MKK][0][15] = 16, -+ [0][1][2][0][RTW89_IC][1][15] = -4, -+ [0][1][2][0][RTW89_KCC][1][15] = 12, -+ [0][1][2][0][RTW89_KCC][0][15] = 12, -+ [0][1][2][0][RTW89_ACMA][1][15] = 54, -+ [0][1][2][0][RTW89_ACMA][0][15] = 18, -+ [0][1][2][0][RTW89_CHILE][1][15] = -4, -+ [0][1][2][0][RTW89_QATAR][1][15] = 54, -+ [0][1][2][0][RTW89_QATAR][0][15] = 18, -+ [0][1][2][0][RTW89_UK][1][15] = 54, -+ [0][1][2][0][RTW89_UK][0][15] = 18, -+ [0][1][2][0][RTW89_FCC][1][17] = -4, -+ [0][1][2][0][RTW89_FCC][2][17] = 54, -+ [0][1][2][0][RTW89_ETSI][1][17] = 54, -+ [0][1][2][0][RTW89_ETSI][0][17] = 18, -+ [0][1][2][0][RTW89_MKK][1][17] = 54, -+ [0][1][2][0][RTW89_MKK][0][17] = 16, -+ [0][1][2][0][RTW89_IC][1][17] = -4, -+ [0][1][2][0][RTW89_KCC][1][17] = 12, -+ [0][1][2][0][RTW89_KCC][0][17] = 12, -+ [0][1][2][0][RTW89_ACMA][1][17] = 54, -+ [0][1][2][0][RTW89_ACMA][0][17] = 18, -+ [0][1][2][0][RTW89_CHILE][1][17] = -4, -+ [0][1][2][0][RTW89_QATAR][1][17] = 54, -+ [0][1][2][0][RTW89_QATAR][0][17] = 18, -+ [0][1][2][0][RTW89_UK][1][17] = 54, -+ [0][1][2][0][RTW89_UK][0][17] = 18, -+ [0][1][2][0][RTW89_FCC][1][19] = -4, -+ [0][1][2][0][RTW89_FCC][2][19] = 54, -+ [0][1][2][0][RTW89_ETSI][1][19] = 54, -+ [0][1][2][0][RTW89_ETSI][0][19] = 18, -+ [0][1][2][0][RTW89_MKK][1][19] = 54, -+ [0][1][2][0][RTW89_MKK][0][19] = 16, -+ [0][1][2][0][RTW89_IC][1][19] = -4, -+ [0][1][2][0][RTW89_KCC][1][19] = 12, -+ [0][1][2][0][RTW89_KCC][0][19] = 12, -+ [0][1][2][0][RTW89_ACMA][1][19] = 54, -+ [0][1][2][0][RTW89_ACMA][0][19] = 18, -+ [0][1][2][0][RTW89_CHILE][1][19] = -4, -+ [0][1][2][0][RTW89_QATAR][1][19] = 54, -+ [0][1][2][0][RTW89_QATAR][0][19] = 18, -+ [0][1][2][0][RTW89_UK][1][19] = 54, -+ [0][1][2][0][RTW89_UK][0][19] = 18, -+ [0][1][2][0][RTW89_FCC][1][21] = -4, -+ [0][1][2][0][RTW89_FCC][2][21] = 54, -+ [0][1][2][0][RTW89_ETSI][1][21] = 54, -+ [0][1][2][0][RTW89_ETSI][0][21] = 18, -+ [0][1][2][0][RTW89_MKK][1][21] = 54, -+ [0][1][2][0][RTW89_MKK][0][21] = 16, -+ [0][1][2][0][RTW89_IC][1][21] = -4, -+ [0][1][2][0][RTW89_KCC][1][21] = 12, -+ [0][1][2][0][RTW89_KCC][0][21] = 12, -+ [0][1][2][0][RTW89_ACMA][1][21] = 54, -+ [0][1][2][0][RTW89_ACMA][0][21] = 18, -+ [0][1][2][0][RTW89_CHILE][1][21] = -4, -+ [0][1][2][0][RTW89_QATAR][1][21] = 54, -+ [0][1][2][0][RTW89_QATAR][0][21] = 18, -+ [0][1][2][0][RTW89_UK][1][21] = 54, -+ [0][1][2][0][RTW89_UK][0][21] = 18, -+ [0][1][2][0][RTW89_FCC][1][23] = -4, -+ [0][1][2][0][RTW89_FCC][2][23] = 68, -+ [0][1][2][0][RTW89_ETSI][1][23] = 54, -+ [0][1][2][0][RTW89_ETSI][0][23] = 18, -+ [0][1][2][0][RTW89_MKK][1][23] = 54, -+ [0][1][2][0][RTW89_MKK][0][23] = 16, -+ [0][1][2][0][RTW89_IC][1][23] = -4, -+ [0][1][2][0][RTW89_KCC][1][23] = 12, -+ [0][1][2][0][RTW89_KCC][0][23] = 10, -+ [0][1][2][0][RTW89_ACMA][1][23] = 54, -+ [0][1][2][0][RTW89_ACMA][0][23] = 18, -+ [0][1][2][0][RTW89_CHILE][1][23] = -4, -+ [0][1][2][0][RTW89_QATAR][1][23] = 54, -+ [0][1][2][0][RTW89_QATAR][0][23] = 18, -+ [0][1][2][0][RTW89_UK][1][23] = 54, -+ [0][1][2][0][RTW89_UK][0][23] = 18, -+ [0][1][2][0][RTW89_FCC][1][25] = -4, -+ [0][1][2][0][RTW89_FCC][2][25] = 68, -+ [0][1][2][0][RTW89_ETSI][1][25] = 54, -+ [0][1][2][0][RTW89_ETSI][0][25] = 18, -+ [0][1][2][0][RTW89_MKK][1][25] = 54, -+ [0][1][2][0][RTW89_MKK][0][25] = 16, -+ [0][1][2][0][RTW89_IC][1][25] = -4, -+ [0][1][2][0][RTW89_KCC][1][25] = 12, -+ [0][1][2][0][RTW89_KCC][0][25] = 14, -+ [0][1][2][0][RTW89_ACMA][1][25] = 54, -+ [0][1][2][0][RTW89_ACMA][0][25] = 18, -+ [0][1][2][0][RTW89_CHILE][1][25] = -4, -+ [0][1][2][0][RTW89_QATAR][1][25] = 54, -+ [0][1][2][0][RTW89_QATAR][0][25] = 18, -+ [0][1][2][0][RTW89_UK][1][25] = 54, -+ [0][1][2][0][RTW89_UK][0][25] = 18, -+ [0][1][2][0][RTW89_FCC][1][27] = -4, -+ [0][1][2][0][RTW89_FCC][2][27] = 68, -+ [0][1][2][0][RTW89_ETSI][1][27] = 54, -+ [0][1][2][0][RTW89_ETSI][0][27] = 18, -+ [0][1][2][0][RTW89_MKK][1][27] = 54, -+ [0][1][2][0][RTW89_MKK][0][27] = 16, -+ [0][1][2][0][RTW89_IC][1][27] = -4, -+ [0][1][2][0][RTW89_KCC][1][27] = 12, -+ [0][1][2][0][RTW89_KCC][0][27] = 14, -+ [0][1][2][0][RTW89_ACMA][1][27] = 54, -+ [0][1][2][0][RTW89_ACMA][0][27] = 18, -+ [0][1][2][0][RTW89_CHILE][1][27] = -4, -+ [0][1][2][0][RTW89_QATAR][1][27] = 54, -+ [0][1][2][0][RTW89_QATAR][0][27] = 18, -+ [0][1][2][0][RTW89_UK][1][27] = 54, -+ [0][1][2][0][RTW89_UK][0][27] = 18, -+ [0][1][2][0][RTW89_FCC][1][29] = -4, -+ [0][1][2][0][RTW89_FCC][2][29] = 68, -+ [0][1][2][0][RTW89_ETSI][1][29] = 54, -+ [0][1][2][0][RTW89_ETSI][0][29] = 18, -+ [0][1][2][0][RTW89_MKK][1][29] = 54, -+ [0][1][2][0][RTW89_MKK][0][29] = 16, -+ [0][1][2][0][RTW89_IC][1][29] = -4, -+ [0][1][2][0][RTW89_KCC][1][29] = 12, -+ [0][1][2][0][RTW89_KCC][0][29] = 14, -+ [0][1][2][0][RTW89_ACMA][1][29] = 54, -+ [0][1][2][0][RTW89_ACMA][0][29] = 18, -+ [0][1][2][0][RTW89_CHILE][1][29] = -4, -+ [0][1][2][0][RTW89_QATAR][1][29] = 54, -+ [0][1][2][0][RTW89_QATAR][0][29] = 18, -+ [0][1][2][0][RTW89_UK][1][29] = 54, -+ [0][1][2][0][RTW89_UK][0][29] = 18, -+ [0][1][2][0][RTW89_FCC][1][30] = -4, -+ [0][1][2][0][RTW89_FCC][2][30] = 68, -+ [0][1][2][0][RTW89_ETSI][1][30] = 54, -+ [0][1][2][0][RTW89_ETSI][0][30] = 18, -+ [0][1][2][0][RTW89_MKK][1][30] = 54, -+ [0][1][2][0][RTW89_MKK][0][30] = 16, -+ [0][1][2][0][RTW89_IC][1][30] = -4, -+ [0][1][2][0][RTW89_KCC][1][30] = 12, -+ [0][1][2][0][RTW89_KCC][0][30] = 14, -+ [0][1][2][0][RTW89_ACMA][1][30] = 54, -+ [0][1][2][0][RTW89_ACMA][0][30] = 18, -+ [0][1][2][0][RTW89_CHILE][1][30] = -4, -+ [0][1][2][0][RTW89_QATAR][1][30] = 54, -+ [0][1][2][0][RTW89_QATAR][0][30] = 18, -+ [0][1][2][0][RTW89_UK][1][30] = 54, -+ [0][1][2][0][RTW89_UK][0][30] = 18, -+ [0][1][2][0][RTW89_FCC][1][32] = -4, -+ [0][1][2][0][RTW89_FCC][2][32] = 68, -+ [0][1][2][0][RTW89_ETSI][1][32] = 54, -+ [0][1][2][0][RTW89_ETSI][0][32] = 18, -+ [0][1][2][0][RTW89_MKK][1][32] = 54, -+ [0][1][2][0][RTW89_MKK][0][32] = 16, -+ [0][1][2][0][RTW89_IC][1][32] = -4, -+ [0][1][2][0][RTW89_KCC][1][32] = 12, -+ [0][1][2][0][RTW89_KCC][0][32] = 14, -+ [0][1][2][0][RTW89_ACMA][1][32] = 54, -+ [0][1][2][0][RTW89_ACMA][0][32] = 18, -+ [0][1][2][0][RTW89_CHILE][1][32] = -4, -+ [0][1][2][0][RTW89_QATAR][1][32] = 54, -+ [0][1][2][0][RTW89_QATAR][0][32] = 18, -+ [0][1][2][0][RTW89_UK][1][32] = 54, -+ [0][1][2][0][RTW89_UK][0][32] = 18, -+ [0][1][2][0][RTW89_FCC][1][34] = -4, -+ [0][1][2][0][RTW89_FCC][2][34] = 68, -+ [0][1][2][0][RTW89_ETSI][1][34] = 54, -+ [0][1][2][0][RTW89_ETSI][0][34] = 18, -+ [0][1][2][0][RTW89_MKK][1][34] = 54, -+ [0][1][2][0][RTW89_MKK][0][34] = 16, -+ [0][1][2][0][RTW89_IC][1][34] = -4, -+ [0][1][2][0][RTW89_KCC][1][34] = 12, -+ [0][1][2][0][RTW89_KCC][0][34] = 14, -+ [0][1][2][0][RTW89_ACMA][1][34] = 54, -+ [0][1][2][0][RTW89_ACMA][0][34] = 18, -+ [0][1][2][0][RTW89_CHILE][1][34] = -4, -+ [0][1][2][0][RTW89_QATAR][1][34] = 54, -+ [0][1][2][0][RTW89_QATAR][0][34] = 18, -+ [0][1][2][0][RTW89_UK][1][34] = 54, -+ [0][1][2][0][RTW89_UK][0][34] = 18, -+ [0][1][2][0][RTW89_FCC][1][36] = -4, -+ [0][1][2][0][RTW89_FCC][2][36] = 68, -+ [0][1][2][0][RTW89_ETSI][1][36] = 54, -+ [0][1][2][0][RTW89_ETSI][0][36] = 18, -+ [0][1][2][0][RTW89_MKK][1][36] = 54, -+ [0][1][2][0][RTW89_MKK][0][36] = 16, -+ [0][1][2][0][RTW89_IC][1][36] = -4, -+ [0][1][2][0][RTW89_KCC][1][36] = 12, -+ [0][1][2][0][RTW89_KCC][0][36] = 14, -+ [0][1][2][0][RTW89_ACMA][1][36] = 54, -+ [0][1][2][0][RTW89_ACMA][0][36] = 18, -+ [0][1][2][0][RTW89_CHILE][1][36] = -4, -+ [0][1][2][0][RTW89_QATAR][1][36] = 54, -+ [0][1][2][0][RTW89_QATAR][0][36] = 18, -+ [0][1][2][0][RTW89_UK][1][36] = 54, -+ [0][1][2][0][RTW89_UK][0][36] = 18, -+ [0][1][2][0][RTW89_FCC][1][38] = -4, -+ [0][1][2][0][RTW89_FCC][2][38] = 68, -+ [0][1][2][0][RTW89_ETSI][1][38] = 54, -+ [0][1][2][0][RTW89_ETSI][0][38] = 18, -+ [0][1][2][0][RTW89_MKK][1][38] = 54, -+ [0][1][2][0][RTW89_MKK][0][38] = 16, -+ [0][1][2][0][RTW89_IC][1][38] = -4, -+ [0][1][2][0][RTW89_KCC][1][38] = 12, -+ [0][1][2][0][RTW89_KCC][0][38] = 14, -+ [0][1][2][0][RTW89_ACMA][1][38] = 54, -+ [0][1][2][0][RTW89_ACMA][0][38] = 18, -+ [0][1][2][0][RTW89_CHILE][1][38] = -4, -+ [0][1][2][0][RTW89_QATAR][1][38] = 54, -+ [0][1][2][0][RTW89_QATAR][0][38] = 18, -+ [0][1][2][0][RTW89_UK][1][38] = 54, -+ [0][1][2][0][RTW89_UK][0][38] = 18, -+ [0][1][2][0][RTW89_FCC][1][40] = -4, -+ [0][1][2][0][RTW89_FCC][2][40] = 68, -+ [0][1][2][0][RTW89_ETSI][1][40] = 54, -+ [0][1][2][0][RTW89_ETSI][0][40] = 18, -+ [0][1][2][0][RTW89_MKK][1][40] = 54, -+ [0][1][2][0][RTW89_MKK][0][40] = 16, -+ [0][1][2][0][RTW89_IC][1][40] = -4, -+ [0][1][2][0][RTW89_KCC][1][40] = 12, -+ [0][1][2][0][RTW89_KCC][0][40] = 14, -+ [0][1][2][0][RTW89_ACMA][1][40] = 54, -+ [0][1][2][0][RTW89_ACMA][0][40] = 18, -+ [0][1][2][0][RTW89_CHILE][1][40] = -4, -+ [0][1][2][0][RTW89_QATAR][1][40] = 54, -+ [0][1][2][0][RTW89_QATAR][0][40] = 18, -+ [0][1][2][0][RTW89_UK][1][40] = 54, -+ [0][1][2][0][RTW89_UK][0][40] = 18, -+ [0][1][2][0][RTW89_FCC][1][42] = -4, -+ [0][1][2][0][RTW89_FCC][2][42] = 68, -+ [0][1][2][0][RTW89_ETSI][1][42] = 54, -+ [0][1][2][0][RTW89_ETSI][0][42] = 18, -+ [0][1][2][0][RTW89_MKK][1][42] = 54, -+ [0][1][2][0][RTW89_MKK][0][42] = 16, -+ [0][1][2][0][RTW89_IC][1][42] = -4, -+ [0][1][2][0][RTW89_KCC][1][42] = 12, -+ [0][1][2][0][RTW89_KCC][0][42] = 14, -+ [0][1][2][0][RTW89_ACMA][1][42] = 54, -+ [0][1][2][0][RTW89_ACMA][0][42] = 18, -+ [0][1][2][0][RTW89_CHILE][1][42] = -4, -+ [0][1][2][0][RTW89_QATAR][1][42] = 54, -+ [0][1][2][0][RTW89_QATAR][0][42] = 18, -+ [0][1][2][0][RTW89_UK][1][42] = 54, -+ [0][1][2][0][RTW89_UK][0][42] = 18, -+ [0][1][2][0][RTW89_FCC][1][44] = -2, -+ [0][1][2][0][RTW89_FCC][2][44] = 68, -+ [0][1][2][0][RTW89_ETSI][1][44] = 54, -+ [0][1][2][0][RTW89_ETSI][0][44] = 18, -+ [0][1][2][0][RTW89_MKK][1][44] = 34, -+ [0][1][2][0][RTW89_MKK][0][44] = 16, -+ [0][1][2][0][RTW89_IC][1][44] = -2, -+ [0][1][2][0][RTW89_KCC][1][44] = 12, -+ [0][1][2][0][RTW89_KCC][0][44] = 12, -+ [0][1][2][0][RTW89_ACMA][1][44] = 54, -+ [0][1][2][0][RTW89_ACMA][0][44] = 18, -+ [0][1][2][0][RTW89_CHILE][1][44] = -2, -+ [0][1][2][0][RTW89_QATAR][1][44] = 54, -+ [0][1][2][0][RTW89_QATAR][0][44] = 18, -+ [0][1][2][0][RTW89_UK][1][44] = 54, -+ [0][1][2][0][RTW89_UK][0][44] = 18, -+ [0][1][2][0][RTW89_FCC][1][45] = -2, -+ [0][1][2][0][RTW89_FCC][2][45] = 127, -+ [0][1][2][0][RTW89_ETSI][1][45] = 127, -+ [0][1][2][0][RTW89_ETSI][0][45] = 127, -+ [0][1][2][0][RTW89_MKK][1][45] = 127, -+ [0][1][2][0][RTW89_MKK][0][45] = 127, -+ [0][1][2][0][RTW89_IC][1][45] = -2, -+ [0][1][2][0][RTW89_KCC][1][45] = 12, -+ [0][1][2][0][RTW89_KCC][0][45] = 127, -+ [0][1][2][0][RTW89_ACMA][1][45] = 127, -+ [0][1][2][0][RTW89_ACMA][0][45] = 127, -+ [0][1][2][0][RTW89_CHILE][1][45] = -2, -+ [0][1][2][0][RTW89_QATAR][1][45] = 127, -+ [0][1][2][0][RTW89_QATAR][0][45] = 127, -+ [0][1][2][0][RTW89_UK][1][45] = 127, -+ [0][1][2][0][RTW89_UK][0][45] = 127, -+ [0][1][2][0][RTW89_FCC][1][47] = -2, -+ [0][1][2][0][RTW89_FCC][2][47] = 127, -+ [0][1][2][0][RTW89_ETSI][1][47] = 127, -+ [0][1][2][0][RTW89_ETSI][0][47] = 127, -+ [0][1][2][0][RTW89_MKK][1][47] = 127, -+ [0][1][2][0][RTW89_MKK][0][47] = 127, -+ [0][1][2][0][RTW89_IC][1][47] = -2, -+ [0][1][2][0][RTW89_KCC][1][47] = 12, -+ [0][1][2][0][RTW89_KCC][0][47] = 127, -+ [0][1][2][0][RTW89_ACMA][1][47] = 127, -+ [0][1][2][0][RTW89_ACMA][0][47] = 127, -+ [0][1][2][0][RTW89_CHILE][1][47] = -2, -+ [0][1][2][0][RTW89_QATAR][1][47] = 127, -+ [0][1][2][0][RTW89_QATAR][0][47] = 127, -+ [0][1][2][0][RTW89_UK][1][47] = 127, -+ [0][1][2][0][RTW89_UK][0][47] = 127, -+ [0][1][2][0][RTW89_FCC][1][49] = -2, -+ [0][1][2][0][RTW89_FCC][2][49] = 127, -+ [0][1][2][0][RTW89_ETSI][1][49] = 127, -+ [0][1][2][0][RTW89_ETSI][0][49] = 127, -+ [0][1][2][0][RTW89_MKK][1][49] = 127, -+ [0][1][2][0][RTW89_MKK][0][49] = 127, -+ [0][1][2][0][RTW89_IC][1][49] = -2, -+ [0][1][2][0][RTW89_KCC][1][49] = 12, -+ [0][1][2][0][RTW89_KCC][0][49] = 127, -+ [0][1][2][0][RTW89_ACMA][1][49] = 127, -+ [0][1][2][0][RTW89_ACMA][0][49] = 127, -+ [0][1][2][0][RTW89_CHILE][1][49] = -2, -+ [0][1][2][0][RTW89_QATAR][1][49] = 127, -+ [0][1][2][0][RTW89_QATAR][0][49] = 127, -+ [0][1][2][0][RTW89_UK][1][49] = 127, -+ [0][1][2][0][RTW89_UK][0][49] = 127, -+ [0][1][2][0][RTW89_FCC][1][51] = -2, -+ [0][1][2][0][RTW89_FCC][2][51] = 127, -+ [0][1][2][0][RTW89_ETSI][1][51] = 127, -+ [0][1][2][0][RTW89_ETSI][0][51] = 127, -+ [0][1][2][0][RTW89_MKK][1][51] = 127, -+ [0][1][2][0][RTW89_MKK][0][51] = 127, -+ [0][1][2][0][RTW89_IC][1][51] = -2, -+ [0][1][2][0][RTW89_KCC][1][51] = 12, -+ [0][1][2][0][RTW89_KCC][0][51] = 127, -+ [0][1][2][0][RTW89_ACMA][1][51] = 127, -+ [0][1][2][0][RTW89_ACMA][0][51] = 127, -+ [0][1][2][0][RTW89_CHILE][1][51] = -2, -+ [0][1][2][0][RTW89_QATAR][1][51] = 127, -+ [0][1][2][0][RTW89_QATAR][0][51] = 127, -+ [0][1][2][0][RTW89_UK][1][51] = 127, -+ [0][1][2][0][RTW89_UK][0][51] = 127, -+ [0][1][2][0][RTW89_FCC][1][53] = -2, -+ [0][1][2][0][RTW89_FCC][2][53] = 127, -+ [0][1][2][0][RTW89_ETSI][1][53] = 127, -+ [0][1][2][0][RTW89_ETSI][0][53] = 127, -+ [0][1][2][0][RTW89_MKK][1][53] = 127, -+ [0][1][2][0][RTW89_MKK][0][53] = 127, -+ [0][1][2][0][RTW89_IC][1][53] = -2, -+ [0][1][2][0][RTW89_KCC][1][53] = 12, -+ [0][1][2][0][RTW89_KCC][0][53] = 127, -+ [0][1][2][0][RTW89_ACMA][1][53] = 127, -+ [0][1][2][0][RTW89_ACMA][0][53] = 127, -+ [0][1][2][0][RTW89_CHILE][1][53] = -2, -+ [0][1][2][0][RTW89_QATAR][1][53] = 127, -+ [0][1][2][0][RTW89_QATAR][0][53] = 127, -+ [0][1][2][0][RTW89_UK][1][53] = 127, -+ [0][1][2][0][RTW89_UK][0][53] = 127, -+ [0][1][2][0][RTW89_FCC][1][55] = -2, -+ [0][1][2][0][RTW89_FCC][2][55] = 68, -+ [0][1][2][0][RTW89_ETSI][1][55] = 127, -+ [0][1][2][0][RTW89_ETSI][0][55] = 127, -+ [0][1][2][0][RTW89_MKK][1][55] = 127, -+ [0][1][2][0][RTW89_MKK][0][55] = 127, -+ [0][1][2][0][RTW89_IC][1][55] = -2, -+ [0][1][2][0][RTW89_KCC][1][55] = 12, -+ [0][1][2][0][RTW89_KCC][0][55] = 127, -+ [0][1][2][0][RTW89_ACMA][1][55] = 127, -+ [0][1][2][0][RTW89_ACMA][0][55] = 127, -+ [0][1][2][0][RTW89_CHILE][1][55] = -2, -+ [0][1][2][0][RTW89_QATAR][1][55] = 127, -+ [0][1][2][0][RTW89_QATAR][0][55] = 127, -+ [0][1][2][0][RTW89_UK][1][55] = 127, -+ [0][1][2][0][RTW89_UK][0][55] = 127, -+ [0][1][2][0][RTW89_FCC][1][57] = -2, -+ [0][1][2][0][RTW89_FCC][2][57] = 68, -+ [0][1][2][0][RTW89_ETSI][1][57] = 127, -+ [0][1][2][0][RTW89_ETSI][0][57] = 127, -+ [0][1][2][0][RTW89_MKK][1][57] = 127, -+ [0][1][2][0][RTW89_MKK][0][57] = 127, -+ [0][1][2][0][RTW89_IC][1][57] = -2, -+ [0][1][2][0][RTW89_KCC][1][57] = 12, -+ [0][1][2][0][RTW89_KCC][0][57] = 127, -+ [0][1][2][0][RTW89_ACMA][1][57] = 127, -+ [0][1][2][0][RTW89_ACMA][0][57] = 127, -+ [0][1][2][0][RTW89_CHILE][1][57] = -2, -+ [0][1][2][0][RTW89_QATAR][1][57] = 127, -+ [0][1][2][0][RTW89_QATAR][0][57] = 127, -+ [0][1][2][0][RTW89_UK][1][57] = 127, -+ [0][1][2][0][RTW89_UK][0][57] = 127, -+ [0][1][2][0][RTW89_FCC][1][59] = -2, -+ [0][1][2][0][RTW89_FCC][2][59] = 68, -+ [0][1][2][0][RTW89_ETSI][1][59] = 127, -+ [0][1][2][0][RTW89_ETSI][0][59] = 127, -+ [0][1][2][0][RTW89_MKK][1][59] = 127, -+ [0][1][2][0][RTW89_MKK][0][59] = 127, -+ [0][1][2][0][RTW89_IC][1][59] = -2, -+ [0][1][2][0][RTW89_KCC][1][59] = 12, -+ [0][1][2][0][RTW89_KCC][0][59] = 127, -+ [0][1][2][0][RTW89_ACMA][1][59] = 127, -+ [0][1][2][0][RTW89_ACMA][0][59] = 127, -+ [0][1][2][0][RTW89_CHILE][1][59] = -2, -+ [0][1][2][0][RTW89_QATAR][1][59] = 127, -+ [0][1][2][0][RTW89_QATAR][0][59] = 127, -+ [0][1][2][0][RTW89_UK][1][59] = 127, -+ [0][1][2][0][RTW89_UK][0][59] = 127, -+ [0][1][2][0][RTW89_FCC][1][60] = -2, -+ [0][1][2][0][RTW89_FCC][2][60] = 68, -+ [0][1][2][0][RTW89_ETSI][1][60] = 127, -+ [0][1][2][0][RTW89_ETSI][0][60] = 127, -+ [0][1][2][0][RTW89_MKK][1][60] = 127, -+ [0][1][2][0][RTW89_MKK][0][60] = 127, -+ [0][1][2][0][RTW89_IC][1][60] = -2, -+ [0][1][2][0][RTW89_KCC][1][60] = 12, -+ [0][1][2][0][RTW89_KCC][0][60] = 127, -+ [0][1][2][0][RTW89_ACMA][1][60] = 127, -+ [0][1][2][0][RTW89_ACMA][0][60] = 127, -+ [0][1][2][0][RTW89_CHILE][1][60] = -2, -+ [0][1][2][0][RTW89_QATAR][1][60] = 127, -+ [0][1][2][0][RTW89_QATAR][0][60] = 127, -+ [0][1][2][0][RTW89_UK][1][60] = 127, -+ [0][1][2][0][RTW89_UK][0][60] = 127, -+ [0][1][2][0][RTW89_FCC][1][62] = -2, -+ [0][1][2][0][RTW89_FCC][2][62] = 68, -+ [0][1][2][0][RTW89_ETSI][1][62] = 127, -+ [0][1][2][0][RTW89_ETSI][0][62] = 127, -+ [0][1][2][0][RTW89_MKK][1][62] = 127, -+ [0][1][2][0][RTW89_MKK][0][62] = 127, -+ [0][1][2][0][RTW89_IC][1][62] = -2, -+ [0][1][2][0][RTW89_KCC][1][62] = 12, -+ [0][1][2][0][RTW89_KCC][0][62] = 127, -+ [0][1][2][0][RTW89_ACMA][1][62] = 127, -+ [0][1][2][0][RTW89_ACMA][0][62] = 127, -+ [0][1][2][0][RTW89_CHILE][1][62] = -2, -+ [0][1][2][0][RTW89_QATAR][1][62] = 127, -+ [0][1][2][0][RTW89_QATAR][0][62] = 127, -+ [0][1][2][0][RTW89_UK][1][62] = 127, -+ [0][1][2][0][RTW89_UK][0][62] = 127, -+ [0][1][2][0][RTW89_FCC][1][64] = -2, -+ [0][1][2][0][RTW89_FCC][2][64] = 68, -+ [0][1][2][0][RTW89_ETSI][1][64] = 127, -+ [0][1][2][0][RTW89_ETSI][0][64] = 127, -+ [0][1][2][0][RTW89_MKK][1][64] = 127, -+ [0][1][2][0][RTW89_MKK][0][64] = 127, -+ [0][1][2][0][RTW89_IC][1][64] = -2, -+ [0][1][2][0][RTW89_KCC][1][64] = 12, -+ [0][1][2][0][RTW89_KCC][0][64] = 127, -+ [0][1][2][0][RTW89_ACMA][1][64] = 127, -+ [0][1][2][0][RTW89_ACMA][0][64] = 127, -+ [0][1][2][0][RTW89_CHILE][1][64] = -2, -+ [0][1][2][0][RTW89_QATAR][1][64] = 127, -+ [0][1][2][0][RTW89_QATAR][0][64] = 127, -+ [0][1][2][0][RTW89_UK][1][64] = 127, -+ [0][1][2][0][RTW89_UK][0][64] = 127, -+ [0][1][2][0][RTW89_FCC][1][66] = -2, -+ [0][1][2][0][RTW89_FCC][2][66] = 68, -+ [0][1][2][0][RTW89_ETSI][1][66] = 127, -+ [0][1][2][0][RTW89_ETSI][0][66] = 127, -+ [0][1][2][0][RTW89_MKK][1][66] = 127, -+ [0][1][2][0][RTW89_MKK][0][66] = 127, -+ [0][1][2][0][RTW89_IC][1][66] = -2, -+ [0][1][2][0][RTW89_KCC][1][66] = 12, -+ [0][1][2][0][RTW89_KCC][0][66] = 127, -+ [0][1][2][0][RTW89_ACMA][1][66] = 127, -+ [0][1][2][0][RTW89_ACMA][0][66] = 127, -+ [0][1][2][0][RTW89_CHILE][1][66] = -2, -+ [0][1][2][0][RTW89_QATAR][1][66] = 127, -+ [0][1][2][0][RTW89_QATAR][0][66] = 127, -+ [0][1][2][0][RTW89_UK][1][66] = 127, -+ [0][1][2][0][RTW89_UK][0][66] = 127, -+ [0][1][2][0][RTW89_FCC][1][68] = -2, -+ [0][1][2][0][RTW89_FCC][2][68] = 68, -+ [0][1][2][0][RTW89_ETSI][1][68] = 127, -+ [0][1][2][0][RTW89_ETSI][0][68] = 127, -+ [0][1][2][0][RTW89_MKK][1][68] = 127, -+ [0][1][2][0][RTW89_MKK][0][68] = 127, -+ [0][1][2][0][RTW89_IC][1][68] = -2, -+ [0][1][2][0][RTW89_KCC][1][68] = 12, -+ [0][1][2][0][RTW89_KCC][0][68] = 127, -+ [0][1][2][0][RTW89_ACMA][1][68] = 127, -+ [0][1][2][0][RTW89_ACMA][0][68] = 127, -+ [0][1][2][0][RTW89_CHILE][1][68] = -2, -+ [0][1][2][0][RTW89_QATAR][1][68] = 127, -+ [0][1][2][0][RTW89_QATAR][0][68] = 127, -+ [0][1][2][0][RTW89_UK][1][68] = 127, -+ [0][1][2][0][RTW89_UK][0][68] = 127, -+ [0][1][2][0][RTW89_FCC][1][70] = -2, -+ [0][1][2][0][RTW89_FCC][2][70] = 68, -+ [0][1][2][0][RTW89_ETSI][1][70] = 127, -+ [0][1][2][0][RTW89_ETSI][0][70] = 127, -+ [0][1][2][0][RTW89_MKK][1][70] = 127, -+ [0][1][2][0][RTW89_MKK][0][70] = 127, -+ [0][1][2][0][RTW89_IC][1][70] = -2, -+ [0][1][2][0][RTW89_KCC][1][70] = 12, -+ [0][1][2][0][RTW89_KCC][0][70] = 127, -+ [0][1][2][0][RTW89_ACMA][1][70] = 127, -+ [0][1][2][0][RTW89_ACMA][0][70] = 127, -+ [0][1][2][0][RTW89_CHILE][1][70] = -2, -+ [0][1][2][0][RTW89_QATAR][1][70] = 127, -+ [0][1][2][0][RTW89_QATAR][0][70] = 127, -+ [0][1][2][0][RTW89_UK][1][70] = 127, -+ [0][1][2][0][RTW89_UK][0][70] = 127, -+ [0][1][2][0][RTW89_FCC][1][72] = -2, -+ [0][1][2][0][RTW89_FCC][2][72] = 68, -+ [0][1][2][0][RTW89_ETSI][1][72] = 127, -+ [0][1][2][0][RTW89_ETSI][0][72] = 127, -+ [0][1][2][0][RTW89_MKK][1][72] = 127, -+ [0][1][2][0][RTW89_MKK][0][72] = 127, -+ [0][1][2][0][RTW89_IC][1][72] = -2, -+ [0][1][2][0][RTW89_KCC][1][72] = 12, -+ [0][1][2][0][RTW89_KCC][0][72] = 127, -+ [0][1][2][0][RTW89_ACMA][1][72] = 127, -+ [0][1][2][0][RTW89_ACMA][0][72] = 127, -+ [0][1][2][0][RTW89_CHILE][1][72] = -2, -+ [0][1][2][0][RTW89_QATAR][1][72] = 127, -+ [0][1][2][0][RTW89_QATAR][0][72] = 127, -+ [0][1][2][0][RTW89_UK][1][72] = 127, -+ [0][1][2][0][RTW89_UK][0][72] = 127, -+ [0][1][2][0][RTW89_FCC][1][74] = -2, -+ [0][1][2][0][RTW89_FCC][2][74] = 68, -+ [0][1][2][0][RTW89_ETSI][1][74] = 127, -+ [0][1][2][0][RTW89_ETSI][0][74] = 127, -+ [0][1][2][0][RTW89_MKK][1][74] = 127, -+ [0][1][2][0][RTW89_MKK][0][74] = 127, -+ [0][1][2][0][RTW89_IC][1][74] = -2, -+ [0][1][2][0][RTW89_KCC][1][74] = 12, -+ [0][1][2][0][RTW89_KCC][0][74] = 127, -+ [0][1][2][0][RTW89_ACMA][1][74] = 127, -+ [0][1][2][0][RTW89_ACMA][0][74] = 127, -+ [0][1][2][0][RTW89_CHILE][1][74] = -2, -+ [0][1][2][0][RTW89_QATAR][1][74] = 127, -+ [0][1][2][0][RTW89_QATAR][0][74] = 127, -+ [0][1][2][0][RTW89_UK][1][74] = 127, -+ [0][1][2][0][RTW89_UK][0][74] = 127, -+ [0][1][2][0][RTW89_FCC][1][75] = -2, -+ [0][1][2][0][RTW89_FCC][2][75] = 68, -+ [0][1][2][0][RTW89_ETSI][1][75] = 127, -+ [0][1][2][0][RTW89_ETSI][0][75] = 127, -+ [0][1][2][0][RTW89_MKK][1][75] = 127, -+ [0][1][2][0][RTW89_MKK][0][75] = 127, -+ [0][1][2][0][RTW89_IC][1][75] = -2, -+ [0][1][2][0][RTW89_KCC][1][75] = 12, -+ [0][1][2][0][RTW89_KCC][0][75] = 127, -+ [0][1][2][0][RTW89_ACMA][1][75] = 127, -+ [0][1][2][0][RTW89_ACMA][0][75] = 127, -+ [0][1][2][0][RTW89_CHILE][1][75] = -2, -+ [0][1][2][0][RTW89_QATAR][1][75] = 127, -+ [0][1][2][0][RTW89_QATAR][0][75] = 127, -+ [0][1][2][0][RTW89_UK][1][75] = 127, -+ [0][1][2][0][RTW89_UK][0][75] = 127, -+ [0][1][2][0][RTW89_FCC][1][77] = -2, -+ [0][1][2][0][RTW89_FCC][2][77] = 68, -+ [0][1][2][0][RTW89_ETSI][1][77] = 127, -+ [0][1][2][0][RTW89_ETSI][0][77] = 127, -+ [0][1][2][0][RTW89_MKK][1][77] = 127, -+ [0][1][2][0][RTW89_MKK][0][77] = 127, -+ [0][1][2][0][RTW89_IC][1][77] = -2, -+ [0][1][2][0][RTW89_KCC][1][77] = 12, -+ [0][1][2][0][RTW89_KCC][0][77] = 127, -+ [0][1][2][0][RTW89_ACMA][1][77] = 127, -+ [0][1][2][0][RTW89_ACMA][0][77] = 127, -+ [0][1][2][0][RTW89_CHILE][1][77] = -2, -+ [0][1][2][0][RTW89_QATAR][1][77] = 127, -+ [0][1][2][0][RTW89_QATAR][0][77] = 127, -+ [0][1][2][0][RTW89_UK][1][77] = 127, -+ [0][1][2][0][RTW89_UK][0][77] = 127, -+ [0][1][2][0][RTW89_FCC][1][79] = -2, -+ [0][1][2][0][RTW89_FCC][2][79] = 68, -+ [0][1][2][0][RTW89_ETSI][1][79] = 127, -+ [0][1][2][0][RTW89_ETSI][0][79] = 127, -+ [0][1][2][0][RTW89_MKK][1][79] = 127, -+ [0][1][2][0][RTW89_MKK][0][79] = 127, -+ [0][1][2][0][RTW89_IC][1][79] = -2, -+ [0][1][2][0][RTW89_KCC][1][79] = 12, -+ [0][1][2][0][RTW89_KCC][0][79] = 127, -+ [0][1][2][0][RTW89_ACMA][1][79] = 127, -+ [0][1][2][0][RTW89_ACMA][0][79] = 127, -+ [0][1][2][0][RTW89_CHILE][1][79] = -2, -+ [0][1][2][0][RTW89_QATAR][1][79] = 127, -+ [0][1][2][0][RTW89_QATAR][0][79] = 127, -+ [0][1][2][0][RTW89_UK][1][79] = 127, -+ [0][1][2][0][RTW89_UK][0][79] = 127, -+ [0][1][2][0][RTW89_FCC][1][81] = -2, -+ [0][1][2][0][RTW89_FCC][2][81] = 68, -+ [0][1][2][0][RTW89_ETSI][1][81] = 127, -+ [0][1][2][0][RTW89_ETSI][0][81] = 127, -+ [0][1][2][0][RTW89_MKK][1][81] = 127, -+ [0][1][2][0][RTW89_MKK][0][81] = 127, -+ [0][1][2][0][RTW89_IC][1][81] = -2, -+ [0][1][2][0][RTW89_KCC][1][81] = 12, -+ [0][1][2][0][RTW89_KCC][0][81] = 127, -+ [0][1][2][0][RTW89_ACMA][1][81] = 127, -+ [0][1][2][0][RTW89_ACMA][0][81] = 127, -+ [0][1][2][0][RTW89_CHILE][1][81] = -2, -+ [0][1][2][0][RTW89_QATAR][1][81] = 127, -+ [0][1][2][0][RTW89_QATAR][0][81] = 127, -+ [0][1][2][0][RTW89_UK][1][81] = 127, -+ [0][1][2][0][RTW89_UK][0][81] = 127, -+ [0][1][2][0][RTW89_FCC][1][83] = -2, -+ [0][1][2][0][RTW89_FCC][2][83] = 68, -+ [0][1][2][0][RTW89_ETSI][1][83] = 127, -+ [0][1][2][0][RTW89_ETSI][0][83] = 127, -+ [0][1][2][0][RTW89_MKK][1][83] = 127, -+ [0][1][2][0][RTW89_MKK][0][83] = 127, -+ [0][1][2][0][RTW89_IC][1][83] = -2, -+ [0][1][2][0][RTW89_KCC][1][83] = 20, -+ [0][1][2][0][RTW89_KCC][0][83] = 127, -+ [0][1][2][0][RTW89_ACMA][1][83] = 127, -+ [0][1][2][0][RTW89_ACMA][0][83] = 127, -+ [0][1][2][0][RTW89_CHILE][1][83] = -2, -+ [0][1][2][0][RTW89_QATAR][1][83] = 127, -+ [0][1][2][0][RTW89_QATAR][0][83] = 127, -+ [0][1][2][0][RTW89_UK][1][83] = 127, -+ [0][1][2][0][RTW89_UK][0][83] = 127, -+ [0][1][2][0][RTW89_FCC][1][85] = -2, -+ [0][1][2][0][RTW89_FCC][2][85] = 68, -+ [0][1][2][0][RTW89_ETSI][1][85] = 127, -+ [0][1][2][0][RTW89_ETSI][0][85] = 127, -+ [0][1][2][0][RTW89_MKK][1][85] = 127, -+ [0][1][2][0][RTW89_MKK][0][85] = 127, -+ [0][1][2][0][RTW89_IC][1][85] = -2, -+ [0][1][2][0][RTW89_KCC][1][85] = 20, -+ [0][1][2][0][RTW89_KCC][0][85] = 127, -+ [0][1][2][0][RTW89_ACMA][1][85] = 127, -+ [0][1][2][0][RTW89_ACMA][0][85] = 127, -+ [0][1][2][0][RTW89_CHILE][1][85] = -2, -+ [0][1][2][0][RTW89_QATAR][1][85] = 127, -+ [0][1][2][0][RTW89_QATAR][0][85] = 127, -+ [0][1][2][0][RTW89_UK][1][85] = 127, -+ [0][1][2][0][RTW89_UK][0][85] = 127, -+ [0][1][2][0][RTW89_FCC][1][87] = -2, -+ [0][1][2][0][RTW89_FCC][2][87] = 127, -+ [0][1][2][0][RTW89_ETSI][1][87] = 127, -+ [0][1][2][0][RTW89_ETSI][0][87] = 127, -+ [0][1][2][0][RTW89_MKK][1][87] = 127, -+ [0][1][2][0][RTW89_MKK][0][87] = 127, -+ [0][1][2][0][RTW89_IC][1][87] = -2, -+ [0][1][2][0][RTW89_KCC][1][87] = 20, -+ [0][1][2][0][RTW89_KCC][0][87] = 127, -+ [0][1][2][0][RTW89_ACMA][1][87] = 127, -+ [0][1][2][0][RTW89_ACMA][0][87] = 127, -+ [0][1][2][0][RTW89_CHILE][1][87] = -2, -+ [0][1][2][0][RTW89_QATAR][1][87] = 127, -+ [0][1][2][0][RTW89_QATAR][0][87] = 127, -+ [0][1][2][0][RTW89_UK][1][87] = 127, -+ [0][1][2][0][RTW89_UK][0][87] = 127, -+ [0][1][2][0][RTW89_FCC][1][89] = -2, -+ [0][1][2][0][RTW89_FCC][2][89] = 127, -+ [0][1][2][0][RTW89_ETSI][1][89] = 127, -+ [0][1][2][0][RTW89_ETSI][0][89] = 127, -+ [0][1][2][0][RTW89_MKK][1][89] = 127, -+ [0][1][2][0][RTW89_MKK][0][89] = 127, -+ [0][1][2][0][RTW89_IC][1][89] = -2, -+ [0][1][2][0][RTW89_KCC][1][89] = 20, -+ [0][1][2][0][RTW89_KCC][0][89] = 127, -+ [0][1][2][0][RTW89_ACMA][1][89] = 127, -+ [0][1][2][0][RTW89_ACMA][0][89] = 127, -+ [0][1][2][0][RTW89_CHILE][1][89] = -2, -+ [0][1][2][0][RTW89_QATAR][1][89] = 127, -+ [0][1][2][0][RTW89_QATAR][0][89] = 127, -+ [0][1][2][0][RTW89_UK][1][89] = 127, -+ [0][1][2][0][RTW89_UK][0][89] = 127, -+ [0][1][2][0][RTW89_FCC][1][90] = -2, -+ [0][1][2][0][RTW89_FCC][2][90] = 127, -+ [0][1][2][0][RTW89_ETSI][1][90] = 127, -+ [0][1][2][0][RTW89_ETSI][0][90] = 127, -+ [0][1][2][0][RTW89_MKK][1][90] = 127, -+ [0][1][2][0][RTW89_MKK][0][90] = 127, -+ [0][1][2][0][RTW89_IC][1][90] = -2, -+ [0][1][2][0][RTW89_KCC][1][90] = 20, -+ [0][1][2][0][RTW89_KCC][0][90] = 127, -+ [0][1][2][0][RTW89_ACMA][1][90] = 127, -+ [0][1][2][0][RTW89_ACMA][0][90] = 127, -+ [0][1][2][0][RTW89_CHILE][1][90] = -2, -+ [0][1][2][0][RTW89_QATAR][1][90] = 127, -+ [0][1][2][0][RTW89_QATAR][0][90] = 127, -+ [0][1][2][0][RTW89_UK][1][90] = 127, -+ [0][1][2][0][RTW89_UK][0][90] = 127, -+ [0][1][2][0][RTW89_FCC][1][92] = -2, -+ [0][1][2][0][RTW89_FCC][2][92] = 127, -+ [0][1][2][0][RTW89_ETSI][1][92] = 127, -+ [0][1][2][0][RTW89_ETSI][0][92] = 127, -+ [0][1][2][0][RTW89_MKK][1][92] = 127, -+ [0][1][2][0][RTW89_MKK][0][92] = 127, -+ [0][1][2][0][RTW89_IC][1][92] = -2, -+ [0][1][2][0][RTW89_KCC][1][92] = 20, -+ [0][1][2][0][RTW89_KCC][0][92] = 127, -+ [0][1][2][0][RTW89_ACMA][1][92] = 127, -+ [0][1][2][0][RTW89_ACMA][0][92] = 127, -+ [0][1][2][0][RTW89_CHILE][1][92] = -2, -+ [0][1][2][0][RTW89_QATAR][1][92] = 127, -+ [0][1][2][0][RTW89_QATAR][0][92] = 127, -+ [0][1][2][0][RTW89_UK][1][92] = 127, -+ [0][1][2][0][RTW89_UK][0][92] = 127, -+ [0][1][2][0][RTW89_FCC][1][94] = -2, -+ [0][1][2][0][RTW89_FCC][2][94] = 127, -+ [0][1][2][0][RTW89_ETSI][1][94] = 127, -+ [0][1][2][0][RTW89_ETSI][0][94] = 127, -+ [0][1][2][0][RTW89_MKK][1][94] = 127, -+ [0][1][2][0][RTW89_MKK][0][94] = 127, -+ [0][1][2][0][RTW89_IC][1][94] = -2, -+ [0][1][2][0][RTW89_KCC][1][94] = 20, -+ [0][1][2][0][RTW89_KCC][0][94] = 127, -+ [0][1][2][0][RTW89_ACMA][1][94] = 127, -+ [0][1][2][0][RTW89_ACMA][0][94] = 127, -+ [0][1][2][0][RTW89_CHILE][1][94] = -2, -+ [0][1][2][0][RTW89_QATAR][1][94] = 127, -+ [0][1][2][0][RTW89_QATAR][0][94] = 127, -+ [0][1][2][0][RTW89_UK][1][94] = 127, -+ [0][1][2][0][RTW89_UK][0][94] = 127, -+ [0][1][2][0][RTW89_FCC][1][96] = -2, -+ [0][1][2][0][RTW89_FCC][2][96] = 127, -+ [0][1][2][0][RTW89_ETSI][1][96] = 127, -+ [0][1][2][0][RTW89_ETSI][0][96] = 127, -+ [0][1][2][0][RTW89_MKK][1][96] = 127, -+ [0][1][2][0][RTW89_MKK][0][96] = 127, -+ [0][1][2][0][RTW89_IC][1][96] = -2, -+ [0][1][2][0][RTW89_KCC][1][96] = 20, -+ [0][1][2][0][RTW89_KCC][0][96] = 127, -+ [0][1][2][0][RTW89_ACMA][1][96] = 127, -+ [0][1][2][0][RTW89_ACMA][0][96] = 127, -+ [0][1][2][0][RTW89_CHILE][1][96] = -2, -+ [0][1][2][0][RTW89_QATAR][1][96] = 127, -+ [0][1][2][0][RTW89_QATAR][0][96] = 127, -+ [0][1][2][0][RTW89_UK][1][96] = 127, -+ [0][1][2][0][RTW89_UK][0][96] = 127, -+ [0][1][2][0][RTW89_FCC][1][98] = -2, -+ [0][1][2][0][RTW89_FCC][2][98] = 127, -+ [0][1][2][0][RTW89_ETSI][1][98] = 127, -+ [0][1][2][0][RTW89_ETSI][0][98] = 127, -+ [0][1][2][0][RTW89_MKK][1][98] = 127, -+ [0][1][2][0][RTW89_MKK][0][98] = 127, -+ [0][1][2][0][RTW89_IC][1][98] = -2, -+ [0][1][2][0][RTW89_KCC][1][98] = 20, -+ [0][1][2][0][RTW89_KCC][0][98] = 127, -+ [0][1][2][0][RTW89_ACMA][1][98] = 127, -+ [0][1][2][0][RTW89_ACMA][0][98] = 127, -+ [0][1][2][0][RTW89_CHILE][1][98] = -2, -+ [0][1][2][0][RTW89_QATAR][1][98] = 127, -+ [0][1][2][0][RTW89_QATAR][0][98] = 127, -+ [0][1][2][0][RTW89_UK][1][98] = 127, -+ [0][1][2][0][RTW89_UK][0][98] = 127, -+ [0][1][2][0][RTW89_FCC][1][100] = -2, -+ [0][1][2][0][RTW89_FCC][2][100] = 127, -+ [0][1][2][0][RTW89_ETSI][1][100] = 127, -+ [0][1][2][0][RTW89_ETSI][0][100] = 127, -+ [0][1][2][0][RTW89_MKK][1][100] = 127, -+ [0][1][2][0][RTW89_MKK][0][100] = 127, -+ [0][1][2][0][RTW89_IC][1][100] = -2, -+ [0][1][2][0][RTW89_KCC][1][100] = 20, -+ [0][1][2][0][RTW89_KCC][0][100] = 127, -+ [0][1][2][0][RTW89_ACMA][1][100] = 127, -+ [0][1][2][0][RTW89_ACMA][0][100] = 127, -+ [0][1][2][0][RTW89_CHILE][1][100] = -2, -+ [0][1][2][0][RTW89_QATAR][1][100] = 127, -+ [0][1][2][0][RTW89_QATAR][0][100] = 127, -+ [0][1][2][0][RTW89_UK][1][100] = 127, -+ [0][1][2][0][RTW89_UK][0][100] = 127, -+ [0][1][2][0][RTW89_FCC][1][102] = -2, -+ [0][1][2][0][RTW89_FCC][2][102] = 127, -+ [0][1][2][0][RTW89_ETSI][1][102] = 127, -+ [0][1][2][0][RTW89_ETSI][0][102] = 127, -+ [0][1][2][0][RTW89_MKK][1][102] = 127, -+ [0][1][2][0][RTW89_MKK][0][102] = 127, -+ [0][1][2][0][RTW89_IC][1][102] = -2, -+ [0][1][2][0][RTW89_KCC][1][102] = 20, -+ [0][1][2][0][RTW89_KCC][0][102] = 127, -+ [0][1][2][0][RTW89_ACMA][1][102] = 127, -+ [0][1][2][0][RTW89_ACMA][0][102] = 127, -+ [0][1][2][0][RTW89_CHILE][1][102] = -2, -+ [0][1][2][0][RTW89_QATAR][1][102] = 127, -+ [0][1][2][0][RTW89_QATAR][0][102] = 127, -+ [0][1][2][0][RTW89_UK][1][102] = 127, -+ [0][1][2][0][RTW89_UK][0][102] = 127, -+ [0][1][2][0][RTW89_FCC][1][104] = -2, -+ [0][1][2][0][RTW89_FCC][2][104] = 127, -+ [0][1][2][0][RTW89_ETSI][1][104] = 127, -+ [0][1][2][0][RTW89_ETSI][0][104] = 127, -+ [0][1][2][0][RTW89_MKK][1][104] = 127, -+ [0][1][2][0][RTW89_MKK][0][104] = 127, -+ [0][1][2][0][RTW89_IC][1][104] = -2, -+ [0][1][2][0][RTW89_KCC][1][104] = 20, -+ [0][1][2][0][RTW89_KCC][0][104] = 127, -+ [0][1][2][0][RTW89_ACMA][1][104] = 127, -+ [0][1][2][0][RTW89_ACMA][0][104] = 127, -+ [0][1][2][0][RTW89_CHILE][1][104] = -2, -+ [0][1][2][0][RTW89_QATAR][1][104] = 127, -+ [0][1][2][0][RTW89_QATAR][0][104] = 127, -+ [0][1][2][0][RTW89_UK][1][104] = 127, -+ [0][1][2][0][RTW89_UK][0][104] = 127, -+ [0][1][2][0][RTW89_FCC][1][105] = -2, -+ [0][1][2][0][RTW89_FCC][2][105] = 127, -+ [0][1][2][0][RTW89_ETSI][1][105] = 127, -+ [0][1][2][0][RTW89_ETSI][0][105] = 127, -+ [0][1][2][0][RTW89_MKK][1][105] = 127, -+ [0][1][2][0][RTW89_MKK][0][105] = 127, -+ [0][1][2][0][RTW89_IC][1][105] = -2, -+ [0][1][2][0][RTW89_KCC][1][105] = 20, -+ [0][1][2][0][RTW89_KCC][0][105] = 127, -+ [0][1][2][0][RTW89_ACMA][1][105] = 127, -+ [0][1][2][0][RTW89_ACMA][0][105] = 127, -+ [0][1][2][0][RTW89_CHILE][1][105] = -2, -+ [0][1][2][0][RTW89_QATAR][1][105] = 127, -+ [0][1][2][0][RTW89_QATAR][0][105] = 127, -+ [0][1][2][0][RTW89_UK][1][105] = 127, -+ [0][1][2][0][RTW89_UK][0][105] = 127, -+ [0][1][2][0][RTW89_FCC][1][107] = 1, -+ [0][1][2][0][RTW89_FCC][2][107] = 127, -+ [0][1][2][0][RTW89_ETSI][1][107] = 127, -+ [0][1][2][0][RTW89_ETSI][0][107] = 127, -+ [0][1][2][0][RTW89_MKK][1][107] = 127, -+ [0][1][2][0][RTW89_MKK][0][107] = 127, -+ [0][1][2][0][RTW89_IC][1][107] = 1, -+ [0][1][2][0][RTW89_KCC][1][107] = 20, -+ [0][1][2][0][RTW89_KCC][0][107] = 127, -+ [0][1][2][0][RTW89_ACMA][1][107] = 127, -+ [0][1][2][0][RTW89_ACMA][0][107] = 127, -+ [0][1][2][0][RTW89_CHILE][1][107] = 1, -+ [0][1][2][0][RTW89_QATAR][1][107] = 127, -+ [0][1][2][0][RTW89_QATAR][0][107] = 127, -+ [0][1][2][0][RTW89_UK][1][107] = 127, -+ [0][1][2][0][RTW89_UK][0][107] = 127, -+ [0][1][2][0][RTW89_FCC][1][109] = 1, -+ [0][1][2][0][RTW89_FCC][2][109] = 127, -+ [0][1][2][0][RTW89_ETSI][1][109] = 127, -+ [0][1][2][0][RTW89_ETSI][0][109] = 127, -+ [0][1][2][0][RTW89_MKK][1][109] = 127, -+ [0][1][2][0][RTW89_MKK][0][109] = 127, -+ [0][1][2][0][RTW89_IC][1][109] = 1, -+ [0][1][2][0][RTW89_KCC][1][109] = 20, -+ [0][1][2][0][RTW89_KCC][0][109] = 127, -+ [0][1][2][0][RTW89_ACMA][1][109] = 127, -+ [0][1][2][0][RTW89_ACMA][0][109] = 127, -+ [0][1][2][0][RTW89_CHILE][1][109] = 1, -+ [0][1][2][0][RTW89_QATAR][1][109] = 127, -+ [0][1][2][0][RTW89_QATAR][0][109] = 127, -+ [0][1][2][0][RTW89_UK][1][109] = 127, -+ [0][1][2][0][RTW89_UK][0][109] = 127, -+ [0][1][2][0][RTW89_FCC][1][111] = 127, -+ [0][1][2][0][RTW89_FCC][2][111] = 127, -+ [0][1][2][0][RTW89_ETSI][1][111] = 127, -+ [0][1][2][0][RTW89_ETSI][0][111] = 127, -+ [0][1][2][0][RTW89_MKK][1][111] = 127, -+ [0][1][2][0][RTW89_MKK][0][111] = 127, -+ [0][1][2][0][RTW89_IC][1][111] = 127, -+ [0][1][2][0][RTW89_KCC][1][111] = 127, -+ [0][1][2][0][RTW89_KCC][0][111] = 127, -+ [0][1][2][0][RTW89_ACMA][1][111] = 127, -+ [0][1][2][0][RTW89_ACMA][0][111] = 127, -+ [0][1][2][0][RTW89_CHILE][1][111] = 127, -+ [0][1][2][0][RTW89_QATAR][1][111] = 127, -+ [0][1][2][0][RTW89_QATAR][0][111] = 127, -+ [0][1][2][0][RTW89_UK][1][111] = 127, -+ [0][1][2][0][RTW89_UK][0][111] = 127, -+ [0][1][2][0][RTW89_FCC][1][113] = 127, -+ [0][1][2][0][RTW89_FCC][2][113] = 127, -+ [0][1][2][0][RTW89_ETSI][1][113] = 127, -+ [0][1][2][0][RTW89_ETSI][0][113] = 127, -+ [0][1][2][0][RTW89_MKK][1][113] = 127, -+ [0][1][2][0][RTW89_MKK][0][113] = 127, -+ [0][1][2][0][RTW89_IC][1][113] = 127, -+ [0][1][2][0][RTW89_KCC][1][113] = 127, -+ [0][1][2][0][RTW89_KCC][0][113] = 127, -+ [0][1][2][0][RTW89_ACMA][1][113] = 127, -+ [0][1][2][0][RTW89_ACMA][0][113] = 127, -+ [0][1][2][0][RTW89_CHILE][1][113] = 127, -+ [0][1][2][0][RTW89_QATAR][1][113] = 127, -+ [0][1][2][0][RTW89_QATAR][0][113] = 127, -+ [0][1][2][0][RTW89_UK][1][113] = 127, -+ [0][1][2][0][RTW89_UK][0][113] = 127, -+ [0][1][2][0][RTW89_FCC][1][115] = 127, -+ [0][1][2][0][RTW89_FCC][2][115] = 127, -+ [0][1][2][0][RTW89_ETSI][1][115] = 127, -+ [0][1][2][0][RTW89_ETSI][0][115] = 127, -+ [0][1][2][0][RTW89_MKK][1][115] = 127, -+ [0][1][2][0][RTW89_MKK][0][115] = 127, -+ [0][1][2][0][RTW89_IC][1][115] = 127, -+ [0][1][2][0][RTW89_KCC][1][115] = 127, -+ [0][1][2][0][RTW89_KCC][0][115] = 127, -+ [0][1][2][0][RTW89_ACMA][1][115] = 127, -+ [0][1][2][0][RTW89_ACMA][0][115] = 127, -+ [0][1][2][0][RTW89_CHILE][1][115] = 127, -+ [0][1][2][0][RTW89_QATAR][1][115] = 127, -+ [0][1][2][0][RTW89_QATAR][0][115] = 127, -+ [0][1][2][0][RTW89_UK][1][115] = 127, -+ [0][1][2][0][RTW89_UK][0][115] = 127, -+ [0][1][2][0][RTW89_FCC][1][117] = 127, -+ [0][1][2][0][RTW89_FCC][2][117] = 127, -+ [0][1][2][0][RTW89_ETSI][1][117] = 127, -+ [0][1][2][0][RTW89_ETSI][0][117] = 127, -+ [0][1][2][0][RTW89_MKK][1][117] = 127, -+ [0][1][2][0][RTW89_MKK][0][117] = 127, -+ [0][1][2][0][RTW89_IC][1][117] = 127, -+ [0][1][2][0][RTW89_KCC][1][117] = 127, -+ [0][1][2][0][RTW89_KCC][0][117] = 127, -+ [0][1][2][0][RTW89_ACMA][1][117] = 127, -+ [0][1][2][0][RTW89_ACMA][0][117] = 127, -+ [0][1][2][0][RTW89_CHILE][1][117] = 127, -+ [0][1][2][0][RTW89_QATAR][1][117] = 127, -+ [0][1][2][0][RTW89_QATAR][0][117] = 127, -+ [0][1][2][0][RTW89_UK][1][117] = 127, -+ [0][1][2][0][RTW89_UK][0][117] = 127, -+ [0][1][2][0][RTW89_FCC][1][119] = 127, -+ [0][1][2][0][RTW89_FCC][2][119] = 127, -+ [0][1][2][0][RTW89_ETSI][1][119] = 127, -+ [0][1][2][0][RTW89_ETSI][0][119] = 127, -+ [0][1][2][0][RTW89_MKK][1][119] = 127, -+ [0][1][2][0][RTW89_MKK][0][119] = 127, -+ [0][1][2][0][RTW89_IC][1][119] = 127, -+ [0][1][2][0][RTW89_KCC][1][119] = 127, -+ [0][1][2][0][RTW89_KCC][0][119] = 127, -+ [0][1][2][0][RTW89_ACMA][1][119] = 127, -+ [0][1][2][0][RTW89_ACMA][0][119] = 127, -+ [0][1][2][0][RTW89_CHILE][1][119] = 127, -+ [0][1][2][0][RTW89_QATAR][1][119] = 127, -+ [0][1][2][0][RTW89_QATAR][0][119] = 127, -+ [0][1][2][0][RTW89_UK][1][119] = 127, -+ [0][1][2][0][RTW89_UK][0][119] = 127, -+ [0][1][2][1][RTW89_FCC][1][0] = -2, -+ [0][1][2][1][RTW89_FCC][2][0] = 54, -+ [0][1][2][1][RTW89_ETSI][1][0] = 42, -+ [0][1][2][1][RTW89_ETSI][0][0] = 6, -+ [0][1][2][1][RTW89_MKK][1][0] = 56, -+ [0][1][2][1][RTW89_MKK][0][0] = 16, -+ [0][1][2][1][RTW89_IC][1][0] = -2, -+ [0][1][2][1][RTW89_KCC][1][0] = 12, -+ [0][1][2][1][RTW89_KCC][0][0] = 10, -+ [0][1][2][1][RTW89_ACMA][1][0] = 42, -+ [0][1][2][1][RTW89_ACMA][0][0] = 6, -+ [0][1][2][1][RTW89_CHILE][1][0] = -2, -+ [0][1][2][1][RTW89_QATAR][1][0] = 42, -+ [0][1][2][1][RTW89_QATAR][0][0] = 6, -+ [0][1][2][1][RTW89_UK][1][0] = 42, -+ [0][1][2][1][RTW89_UK][0][0] = 6, -+ [0][1][2][1][RTW89_FCC][1][2] = -4, -+ [0][1][2][1][RTW89_FCC][2][2] = 54, -+ [0][1][2][1][RTW89_ETSI][1][2] = 42, -+ [0][1][2][1][RTW89_ETSI][0][2] = 6, -+ [0][1][2][1][RTW89_MKK][1][2] = 54, -+ [0][1][2][1][RTW89_MKK][0][2] = 16, -+ [0][1][2][1][RTW89_IC][1][2] = -4, -+ [0][1][2][1][RTW89_KCC][1][2] = 12, -+ [0][1][2][1][RTW89_KCC][0][2] = 12, -+ [0][1][2][1][RTW89_ACMA][1][2] = 42, -+ [0][1][2][1][RTW89_ACMA][0][2] = 6, -+ [0][1][2][1][RTW89_CHILE][1][2] = -4, -+ [0][1][2][1][RTW89_QATAR][1][2] = 42, -+ [0][1][2][1][RTW89_QATAR][0][2] = 6, -+ [0][1][2][1][RTW89_UK][1][2] = 42, -+ [0][1][2][1][RTW89_UK][0][2] = 6, -+ [0][1][2][1][RTW89_FCC][1][4] = -4, -+ [0][1][2][1][RTW89_FCC][2][4] = 54, -+ [0][1][2][1][RTW89_ETSI][1][4] = 42, -+ [0][1][2][1][RTW89_ETSI][0][4] = 6, -+ [0][1][2][1][RTW89_MKK][1][4] = 54, -+ [0][1][2][1][RTW89_MKK][0][4] = 16, -+ [0][1][2][1][RTW89_IC][1][4] = -4, -+ [0][1][2][1][RTW89_KCC][1][4] = 12, -+ [0][1][2][1][RTW89_KCC][0][4] = 12, -+ [0][1][2][1][RTW89_ACMA][1][4] = 42, -+ [0][1][2][1][RTW89_ACMA][0][4] = 6, -+ [0][1][2][1][RTW89_CHILE][1][4] = -4, -+ [0][1][2][1][RTW89_QATAR][1][4] = 42, -+ [0][1][2][1][RTW89_QATAR][0][4] = 6, -+ [0][1][2][1][RTW89_UK][1][4] = 42, -+ [0][1][2][1][RTW89_UK][0][4] = 6, -+ [0][1][2][1][RTW89_FCC][1][6] = -4, -+ [0][1][2][1][RTW89_FCC][2][6] = 54, -+ [0][1][2][1][RTW89_ETSI][1][6] = 42, -+ [0][1][2][1][RTW89_ETSI][0][6] = 6, -+ [0][1][2][1][RTW89_MKK][1][6] = 54, -+ [0][1][2][1][RTW89_MKK][0][6] = 16, -+ [0][1][2][1][RTW89_IC][1][6] = -4, -+ [0][1][2][1][RTW89_KCC][1][6] = 12, -+ [0][1][2][1][RTW89_KCC][0][6] = 12, -+ [0][1][2][1][RTW89_ACMA][1][6] = 42, -+ [0][1][2][1][RTW89_ACMA][0][6] = 6, -+ [0][1][2][1][RTW89_CHILE][1][6] = -4, -+ [0][1][2][1][RTW89_QATAR][1][6] = 42, -+ [0][1][2][1][RTW89_QATAR][0][6] = 6, -+ [0][1][2][1][RTW89_UK][1][6] = 42, -+ [0][1][2][1][RTW89_UK][0][6] = 6, -+ [0][1][2][1][RTW89_FCC][1][8] = -4, -+ [0][1][2][1][RTW89_FCC][2][8] = 54, -+ [0][1][2][1][RTW89_ETSI][1][8] = 42, -+ [0][1][2][1][RTW89_ETSI][0][8] = 6, -+ [0][1][2][1][RTW89_MKK][1][8] = 54, -+ [0][1][2][1][RTW89_MKK][0][8] = 16, -+ [0][1][2][1][RTW89_IC][1][8] = -4, -+ [0][1][2][1][RTW89_KCC][1][8] = 12, -+ [0][1][2][1][RTW89_KCC][0][8] = 12, -+ [0][1][2][1][RTW89_ACMA][1][8] = 42, -+ [0][1][2][1][RTW89_ACMA][0][8] = 6, -+ [0][1][2][1][RTW89_CHILE][1][8] = -4, -+ [0][1][2][1][RTW89_QATAR][1][8] = 42, -+ [0][1][2][1][RTW89_QATAR][0][8] = 6, -+ [0][1][2][1][RTW89_UK][1][8] = 42, -+ [0][1][2][1][RTW89_UK][0][8] = 6, -+ [0][1][2][1][RTW89_FCC][1][10] = -4, -+ [0][1][2][1][RTW89_FCC][2][10] = 54, -+ [0][1][2][1][RTW89_ETSI][1][10] = 42, -+ [0][1][2][1][RTW89_ETSI][0][10] = 6, -+ [0][1][2][1][RTW89_MKK][1][10] = 54, -+ [0][1][2][1][RTW89_MKK][0][10] = 16, -+ [0][1][2][1][RTW89_IC][1][10] = -4, -+ [0][1][2][1][RTW89_KCC][1][10] = 12, -+ [0][1][2][1][RTW89_KCC][0][10] = 12, -+ [0][1][2][1][RTW89_ACMA][1][10] = 42, -+ [0][1][2][1][RTW89_ACMA][0][10] = 6, -+ [0][1][2][1][RTW89_CHILE][1][10] = -4, -+ [0][1][2][1][RTW89_QATAR][1][10] = 42, -+ [0][1][2][1][RTW89_QATAR][0][10] = 6, -+ [0][1][2][1][RTW89_UK][1][10] = 42, -+ [0][1][2][1][RTW89_UK][0][10] = 6, -+ [0][1][2][1][RTW89_FCC][1][12] = -4, -+ [0][1][2][1][RTW89_FCC][2][12] = 54, -+ [0][1][2][1][RTW89_ETSI][1][12] = 42, -+ [0][1][2][1][RTW89_ETSI][0][12] = 6, -+ [0][1][2][1][RTW89_MKK][1][12] = 54, -+ [0][1][2][1][RTW89_MKK][0][12] = 16, -+ [0][1][2][1][RTW89_IC][1][12] = -4, -+ [0][1][2][1][RTW89_KCC][1][12] = 12, -+ [0][1][2][1][RTW89_KCC][0][12] = 12, -+ [0][1][2][1][RTW89_ACMA][1][12] = 42, -+ [0][1][2][1][RTW89_ACMA][0][12] = 6, -+ [0][1][2][1][RTW89_CHILE][1][12] = -4, -+ [0][1][2][1][RTW89_QATAR][1][12] = 42, -+ [0][1][2][1][RTW89_QATAR][0][12] = 6, -+ [0][1][2][1][RTW89_UK][1][12] = 42, -+ [0][1][2][1][RTW89_UK][0][12] = 6, -+ [0][1][2][1][RTW89_FCC][1][14] = -4, -+ [0][1][2][1][RTW89_FCC][2][14] = 54, -+ [0][1][2][1][RTW89_ETSI][1][14] = 42, -+ [0][1][2][1][RTW89_ETSI][0][14] = 6, -+ [0][1][2][1][RTW89_MKK][1][14] = 54, -+ [0][1][2][1][RTW89_MKK][0][14] = 16, -+ [0][1][2][1][RTW89_IC][1][14] = -4, -+ [0][1][2][1][RTW89_KCC][1][14] = 12, -+ [0][1][2][1][RTW89_KCC][0][14] = 12, -+ [0][1][2][1][RTW89_ACMA][1][14] = 42, -+ [0][1][2][1][RTW89_ACMA][0][14] = 6, -+ [0][1][2][1][RTW89_CHILE][1][14] = -4, -+ [0][1][2][1][RTW89_QATAR][1][14] = 42, -+ [0][1][2][1][RTW89_QATAR][0][14] = 6, -+ [0][1][2][1][RTW89_UK][1][14] = 42, -+ [0][1][2][1][RTW89_UK][0][14] = 6, -+ [0][1][2][1][RTW89_FCC][1][15] = -4, -+ [0][1][2][1][RTW89_FCC][2][15] = 54, -+ [0][1][2][1][RTW89_ETSI][1][15] = 42, -+ [0][1][2][1][RTW89_ETSI][0][15] = 6, -+ [0][1][2][1][RTW89_MKK][1][15] = 54, -+ [0][1][2][1][RTW89_MKK][0][15] = 16, -+ [0][1][2][1][RTW89_IC][1][15] = -4, -+ [0][1][2][1][RTW89_KCC][1][15] = 12, -+ [0][1][2][1][RTW89_KCC][0][15] = 12, -+ [0][1][2][1][RTW89_ACMA][1][15] = 42, -+ [0][1][2][1][RTW89_ACMA][0][15] = 6, -+ [0][1][2][1][RTW89_CHILE][1][15] = -4, -+ [0][1][2][1][RTW89_QATAR][1][15] = 42, -+ [0][1][2][1][RTW89_QATAR][0][15] = 6, -+ [0][1][2][1][RTW89_UK][1][15] = 42, -+ [0][1][2][1][RTW89_UK][0][15] = 6, -+ [0][1][2][1][RTW89_FCC][1][17] = -4, -+ [0][1][2][1][RTW89_FCC][2][17] = 54, -+ [0][1][2][1][RTW89_ETSI][1][17] = 42, -+ [0][1][2][1][RTW89_ETSI][0][17] = 6, -+ [0][1][2][1][RTW89_MKK][1][17] = 54, -+ [0][1][2][1][RTW89_MKK][0][17] = 16, -+ [0][1][2][1][RTW89_IC][1][17] = -4, -+ [0][1][2][1][RTW89_KCC][1][17] = 12, -+ [0][1][2][1][RTW89_KCC][0][17] = 12, -+ [0][1][2][1][RTW89_ACMA][1][17] = 42, -+ [0][1][2][1][RTW89_ACMA][0][17] = 6, -+ [0][1][2][1][RTW89_CHILE][1][17] = -4, -+ [0][1][2][1][RTW89_QATAR][1][17] = 42, -+ [0][1][2][1][RTW89_QATAR][0][17] = 6, -+ [0][1][2][1][RTW89_UK][1][17] = 42, -+ [0][1][2][1][RTW89_UK][0][17] = 6, -+ [0][1][2][1][RTW89_FCC][1][19] = -4, -+ [0][1][2][1][RTW89_FCC][2][19] = 54, -+ [0][1][2][1][RTW89_ETSI][1][19] = 42, -+ [0][1][2][1][RTW89_ETSI][0][19] = 6, -+ [0][1][2][1][RTW89_MKK][1][19] = 54, -+ [0][1][2][1][RTW89_MKK][0][19] = 16, -+ [0][1][2][1][RTW89_IC][1][19] = -4, -+ [0][1][2][1][RTW89_KCC][1][19] = 12, -+ [0][1][2][1][RTW89_KCC][0][19] = 12, -+ [0][1][2][1][RTW89_ACMA][1][19] = 42, -+ [0][1][2][1][RTW89_ACMA][0][19] = 6, -+ [0][1][2][1][RTW89_CHILE][1][19] = -4, -+ [0][1][2][1][RTW89_QATAR][1][19] = 42, -+ [0][1][2][1][RTW89_QATAR][0][19] = 6, -+ [0][1][2][1][RTW89_UK][1][19] = 42, -+ [0][1][2][1][RTW89_UK][0][19] = 6, -+ [0][1][2][1][RTW89_FCC][1][21] = -4, -+ [0][1][2][1][RTW89_FCC][2][21] = 54, -+ [0][1][2][1][RTW89_ETSI][1][21] = 42, -+ [0][1][2][1][RTW89_ETSI][0][21] = 6, -+ [0][1][2][1][RTW89_MKK][1][21] = 54, -+ [0][1][2][1][RTW89_MKK][0][21] = 16, -+ [0][1][2][1][RTW89_IC][1][21] = -4, -+ [0][1][2][1][RTW89_KCC][1][21] = 12, -+ [0][1][2][1][RTW89_KCC][0][21] = 12, -+ [0][1][2][1][RTW89_ACMA][1][21] = 42, -+ [0][1][2][1][RTW89_ACMA][0][21] = 6, -+ [0][1][2][1][RTW89_CHILE][1][21] = -4, -+ [0][1][2][1][RTW89_QATAR][1][21] = 42, -+ [0][1][2][1][RTW89_QATAR][0][21] = 6, -+ [0][1][2][1][RTW89_UK][1][21] = 42, -+ [0][1][2][1][RTW89_UK][0][21] = 6, -+ [0][1][2][1][RTW89_FCC][1][23] = -4, -+ [0][1][2][1][RTW89_FCC][2][23] = 68, -+ [0][1][2][1][RTW89_ETSI][1][23] = 42, -+ [0][1][2][1][RTW89_ETSI][0][23] = 6, -+ [0][1][2][1][RTW89_MKK][1][23] = 54, -+ [0][1][2][1][RTW89_MKK][0][23] = 16, -+ [0][1][2][1][RTW89_IC][1][23] = -4, -+ [0][1][2][1][RTW89_KCC][1][23] = 12, -+ [0][1][2][1][RTW89_KCC][0][23] = 10, -+ [0][1][2][1][RTW89_ACMA][1][23] = 42, -+ [0][1][2][1][RTW89_ACMA][0][23] = 6, -+ [0][1][2][1][RTW89_CHILE][1][23] = -4, -+ [0][1][2][1][RTW89_QATAR][1][23] = 42, -+ [0][1][2][1][RTW89_QATAR][0][23] = 6, -+ [0][1][2][1][RTW89_UK][1][23] = 42, -+ [0][1][2][1][RTW89_UK][0][23] = 6, -+ [0][1][2][1][RTW89_FCC][1][25] = -4, -+ [0][1][2][1][RTW89_FCC][2][25] = 68, -+ [0][1][2][1][RTW89_ETSI][1][25] = 42, -+ [0][1][2][1][RTW89_ETSI][0][25] = 6, -+ [0][1][2][1][RTW89_MKK][1][25] = 54, -+ [0][1][2][1][RTW89_MKK][0][25] = 16, -+ [0][1][2][1][RTW89_IC][1][25] = -4, -+ [0][1][2][1][RTW89_KCC][1][25] = 12, -+ [0][1][2][1][RTW89_KCC][0][25] = 14, -+ [0][1][2][1][RTW89_ACMA][1][25] = 42, -+ [0][1][2][1][RTW89_ACMA][0][25] = 6, -+ [0][1][2][1][RTW89_CHILE][1][25] = -4, -+ [0][1][2][1][RTW89_QATAR][1][25] = 42, -+ [0][1][2][1][RTW89_QATAR][0][25] = 6, -+ [0][1][2][1][RTW89_UK][1][25] = 42, -+ [0][1][2][1][RTW89_UK][0][25] = 6, -+ [0][1][2][1][RTW89_FCC][1][27] = -4, -+ [0][1][2][1][RTW89_FCC][2][27] = 68, -+ [0][1][2][1][RTW89_ETSI][1][27] = 42, -+ [0][1][2][1][RTW89_ETSI][0][27] = 6, -+ [0][1][2][1][RTW89_MKK][1][27] = 54, -+ [0][1][2][1][RTW89_MKK][0][27] = 16, -+ [0][1][2][1][RTW89_IC][1][27] = -4, -+ [0][1][2][1][RTW89_KCC][1][27] = 12, -+ [0][1][2][1][RTW89_KCC][0][27] = 14, -+ [0][1][2][1][RTW89_ACMA][1][27] = 42, -+ [0][1][2][1][RTW89_ACMA][0][27] = 6, -+ [0][1][2][1][RTW89_CHILE][1][27] = -4, -+ [0][1][2][1][RTW89_QATAR][1][27] = 42, -+ [0][1][2][1][RTW89_QATAR][0][27] = 6, -+ [0][1][2][1][RTW89_UK][1][27] = 42, -+ [0][1][2][1][RTW89_UK][0][27] = 6, -+ [0][1][2][1][RTW89_FCC][1][29] = -4, -+ [0][1][2][1][RTW89_FCC][2][29] = 68, -+ [0][1][2][1][RTW89_ETSI][1][29] = 42, -+ [0][1][2][1][RTW89_ETSI][0][29] = 6, -+ [0][1][2][1][RTW89_MKK][1][29] = 54, -+ [0][1][2][1][RTW89_MKK][0][29] = 16, -+ [0][1][2][1][RTW89_IC][1][29] = -4, -+ [0][1][2][1][RTW89_KCC][1][29] = 12, -+ [0][1][2][1][RTW89_KCC][0][29] = 14, -+ [0][1][2][1][RTW89_ACMA][1][29] = 42, -+ [0][1][2][1][RTW89_ACMA][0][29] = 6, -+ [0][1][2][1][RTW89_CHILE][1][29] = -4, -+ [0][1][2][1][RTW89_QATAR][1][29] = 42, -+ [0][1][2][1][RTW89_QATAR][0][29] = 6, -+ [0][1][2][1][RTW89_UK][1][29] = 42, -+ [0][1][2][1][RTW89_UK][0][29] = 6, -+ [0][1][2][1][RTW89_FCC][1][30] = -4, -+ [0][1][2][1][RTW89_FCC][2][30] = 68, -+ [0][1][2][1][RTW89_ETSI][1][30] = 42, -+ [0][1][2][1][RTW89_ETSI][0][30] = 6, -+ [0][1][2][1][RTW89_MKK][1][30] = 54, -+ [0][1][2][1][RTW89_MKK][0][30] = 16, -+ [0][1][2][1][RTW89_IC][1][30] = -4, -+ [0][1][2][1][RTW89_KCC][1][30] = 12, -+ [0][1][2][1][RTW89_KCC][0][30] = 14, -+ [0][1][2][1][RTW89_ACMA][1][30] = 42, -+ [0][1][2][1][RTW89_ACMA][0][30] = 6, -+ [0][1][2][1][RTW89_CHILE][1][30] = -4, -+ [0][1][2][1][RTW89_QATAR][1][30] = 42, -+ [0][1][2][1][RTW89_QATAR][0][30] = 6, -+ [0][1][2][1][RTW89_UK][1][30] = 42, -+ [0][1][2][1][RTW89_UK][0][30] = 6, -+ [0][1][2][1][RTW89_FCC][1][32] = -4, -+ [0][1][2][1][RTW89_FCC][2][32] = 68, -+ [0][1][2][1][RTW89_ETSI][1][32] = 42, -+ [0][1][2][1][RTW89_ETSI][0][32] = 6, -+ [0][1][2][1][RTW89_MKK][1][32] = 54, -+ [0][1][2][1][RTW89_MKK][0][32] = 16, -+ [0][1][2][1][RTW89_IC][1][32] = -4, -+ [0][1][2][1][RTW89_KCC][1][32] = 12, -+ [0][1][2][1][RTW89_KCC][0][32] = 14, -+ [0][1][2][1][RTW89_ACMA][1][32] = 42, -+ [0][1][2][1][RTW89_ACMA][0][32] = 6, -+ [0][1][2][1][RTW89_CHILE][1][32] = -4, -+ [0][1][2][1][RTW89_QATAR][1][32] = 42, -+ [0][1][2][1][RTW89_QATAR][0][32] = 6, -+ [0][1][2][1][RTW89_UK][1][32] = 42, -+ [0][1][2][1][RTW89_UK][0][32] = 6, -+ [0][1][2][1][RTW89_FCC][1][34] = -4, -+ [0][1][2][1][RTW89_FCC][2][34] = 68, -+ [0][1][2][1][RTW89_ETSI][1][34] = 42, -+ [0][1][2][1][RTW89_ETSI][0][34] = 6, -+ [0][1][2][1][RTW89_MKK][1][34] = 54, -+ [0][1][2][1][RTW89_MKK][0][34] = 16, -+ [0][1][2][1][RTW89_IC][1][34] = -4, -+ [0][1][2][1][RTW89_KCC][1][34] = 12, -+ [0][1][2][1][RTW89_KCC][0][34] = 14, -+ [0][1][2][1][RTW89_ACMA][1][34] = 42, -+ [0][1][2][1][RTW89_ACMA][0][34] = 6, -+ [0][1][2][1][RTW89_CHILE][1][34] = -4, -+ [0][1][2][1][RTW89_QATAR][1][34] = 42, -+ [0][1][2][1][RTW89_QATAR][0][34] = 6, -+ [0][1][2][1][RTW89_UK][1][34] = 42, -+ [0][1][2][1][RTW89_UK][0][34] = 6, -+ [0][1][2][1][RTW89_FCC][1][36] = -4, -+ [0][1][2][1][RTW89_FCC][2][36] = 68, -+ [0][1][2][1][RTW89_ETSI][1][36] = 42, -+ [0][1][2][1][RTW89_ETSI][0][36] = 6, -+ [0][1][2][1][RTW89_MKK][1][36] = 54, -+ [0][1][2][1][RTW89_MKK][0][36] = 16, -+ [0][1][2][1][RTW89_IC][1][36] = -4, -+ [0][1][2][1][RTW89_KCC][1][36] = 12, -+ [0][1][2][1][RTW89_KCC][0][36] = 14, -+ [0][1][2][1][RTW89_ACMA][1][36] = 42, -+ [0][1][2][1][RTW89_ACMA][0][36] = 6, -+ [0][1][2][1][RTW89_CHILE][1][36] = -4, -+ [0][1][2][1][RTW89_QATAR][1][36] = 42, -+ [0][1][2][1][RTW89_QATAR][0][36] = 6, -+ [0][1][2][1][RTW89_UK][1][36] = 42, -+ [0][1][2][1][RTW89_UK][0][36] = 6, -+ [0][1][2][1][RTW89_FCC][1][38] = -4, -+ [0][1][2][1][RTW89_FCC][2][38] = 68, -+ [0][1][2][1][RTW89_ETSI][1][38] = 42, -+ [0][1][2][1][RTW89_ETSI][0][38] = 6, -+ [0][1][2][1][RTW89_MKK][1][38] = 54, -+ [0][1][2][1][RTW89_MKK][0][38] = 16, -+ [0][1][2][1][RTW89_IC][1][38] = -4, -+ [0][1][2][1][RTW89_KCC][1][38] = 12, -+ [0][1][2][1][RTW89_KCC][0][38] = 14, -+ [0][1][2][1][RTW89_ACMA][1][38] = 42, -+ [0][1][2][1][RTW89_ACMA][0][38] = 6, -+ [0][1][2][1][RTW89_CHILE][1][38] = -4, -+ [0][1][2][1][RTW89_QATAR][1][38] = 42, -+ [0][1][2][1][RTW89_QATAR][0][38] = 6, -+ [0][1][2][1][RTW89_UK][1][38] = 42, -+ [0][1][2][1][RTW89_UK][0][38] = 6, -+ [0][1][2][1][RTW89_FCC][1][40] = -4, -+ [0][1][2][1][RTW89_FCC][2][40] = 68, -+ [0][1][2][1][RTW89_ETSI][1][40] = 42, -+ [0][1][2][1][RTW89_ETSI][0][40] = 6, -+ [0][1][2][1][RTW89_MKK][1][40] = 54, -+ [0][1][2][1][RTW89_MKK][0][40] = 16, -+ [0][1][2][1][RTW89_IC][1][40] = -4, -+ [0][1][2][1][RTW89_KCC][1][40] = 12, -+ [0][1][2][1][RTW89_KCC][0][40] = 14, -+ [0][1][2][1][RTW89_ACMA][1][40] = 42, -+ [0][1][2][1][RTW89_ACMA][0][40] = 6, -+ [0][1][2][1][RTW89_CHILE][1][40] = -4, -+ [0][1][2][1][RTW89_QATAR][1][40] = 42, -+ [0][1][2][1][RTW89_QATAR][0][40] = 6, -+ [0][1][2][1][RTW89_UK][1][40] = 42, -+ [0][1][2][1][RTW89_UK][0][40] = 6, -+ [0][1][2][1][RTW89_FCC][1][42] = -4, -+ [0][1][2][1][RTW89_FCC][2][42] = 68, -+ [0][1][2][1][RTW89_ETSI][1][42] = 42, -+ [0][1][2][1][RTW89_ETSI][0][42] = 6, -+ [0][1][2][1][RTW89_MKK][1][42] = 54, -+ [0][1][2][1][RTW89_MKK][0][42] = 16, -+ [0][1][2][1][RTW89_IC][1][42] = -4, -+ [0][1][2][1][RTW89_KCC][1][42] = 12, -+ [0][1][2][1][RTW89_KCC][0][42] = 14, -+ [0][1][2][1][RTW89_ACMA][1][42] = 42, -+ [0][1][2][1][RTW89_ACMA][0][42] = 6, -+ [0][1][2][1][RTW89_CHILE][1][42] = -4, -+ [0][1][2][1][RTW89_QATAR][1][42] = 42, -+ [0][1][2][1][RTW89_QATAR][0][42] = 6, -+ [0][1][2][1][RTW89_UK][1][42] = 42, -+ [0][1][2][1][RTW89_UK][0][42] = 6, -+ [0][1][2][1][RTW89_FCC][1][44] = -2, -+ [0][1][2][1][RTW89_FCC][2][44] = 68, -+ [0][1][2][1][RTW89_ETSI][1][44] = 42, -+ [0][1][2][1][RTW89_ETSI][0][44] = 6, -+ [0][1][2][1][RTW89_MKK][1][44] = 34, -+ [0][1][2][1][RTW89_MKK][0][44] = 16, -+ [0][1][2][1][RTW89_IC][1][44] = -2, -+ [0][1][2][1][RTW89_KCC][1][44] = 12, -+ [0][1][2][1][RTW89_KCC][0][44] = 12, -+ [0][1][2][1][RTW89_ACMA][1][44] = 42, -+ [0][1][2][1][RTW89_ACMA][0][44] = 6, -+ [0][1][2][1][RTW89_CHILE][1][44] = -2, -+ [0][1][2][1][RTW89_QATAR][1][44] = 42, -+ [0][1][2][1][RTW89_QATAR][0][44] = 6, -+ [0][1][2][1][RTW89_UK][1][44] = 42, -+ [0][1][2][1][RTW89_UK][0][44] = 6, -+ [0][1][2][1][RTW89_FCC][1][45] = -2, -+ [0][1][2][1][RTW89_FCC][2][45] = 127, -+ [0][1][2][1][RTW89_ETSI][1][45] = 127, -+ [0][1][2][1][RTW89_ETSI][0][45] = 127, -+ [0][1][2][1][RTW89_MKK][1][45] = 127, -+ [0][1][2][1][RTW89_MKK][0][45] = 127, -+ [0][1][2][1][RTW89_IC][1][45] = -2, -+ [0][1][2][1][RTW89_KCC][1][45] = 12, -+ [0][1][2][1][RTW89_KCC][0][45] = 127, -+ [0][1][2][1][RTW89_ACMA][1][45] = 127, -+ [0][1][2][1][RTW89_ACMA][0][45] = 127, -+ [0][1][2][1][RTW89_CHILE][1][45] = -2, -+ [0][1][2][1][RTW89_QATAR][1][45] = 127, -+ [0][1][2][1][RTW89_QATAR][0][45] = 127, -+ [0][1][2][1][RTW89_UK][1][45] = 127, -+ [0][1][2][1][RTW89_UK][0][45] = 127, -+ [0][1][2][1][RTW89_FCC][1][47] = -2, -+ [0][1][2][1][RTW89_FCC][2][47] = 127, -+ [0][1][2][1][RTW89_ETSI][1][47] = 127, -+ [0][1][2][1][RTW89_ETSI][0][47] = 127, -+ [0][1][2][1][RTW89_MKK][1][47] = 127, -+ [0][1][2][1][RTW89_MKK][0][47] = 127, -+ [0][1][2][1][RTW89_IC][1][47] = -2, -+ [0][1][2][1][RTW89_KCC][1][47] = 12, -+ [0][1][2][1][RTW89_KCC][0][47] = 127, -+ [0][1][2][1][RTW89_ACMA][1][47] = 127, -+ [0][1][2][1][RTW89_ACMA][0][47] = 127, -+ [0][1][2][1][RTW89_CHILE][1][47] = -2, -+ [0][1][2][1][RTW89_QATAR][1][47] = 127, -+ [0][1][2][1][RTW89_QATAR][0][47] = 127, -+ [0][1][2][1][RTW89_UK][1][47] = 127, -+ [0][1][2][1][RTW89_UK][0][47] = 127, -+ [0][1][2][1][RTW89_FCC][1][49] = -2, -+ [0][1][2][1][RTW89_FCC][2][49] = 127, -+ [0][1][2][1][RTW89_ETSI][1][49] = 127, -+ [0][1][2][1][RTW89_ETSI][0][49] = 127, -+ [0][1][2][1][RTW89_MKK][1][49] = 127, -+ [0][1][2][1][RTW89_MKK][0][49] = 127, -+ [0][1][2][1][RTW89_IC][1][49] = -2, -+ [0][1][2][1][RTW89_KCC][1][49] = 12, -+ [0][1][2][1][RTW89_KCC][0][49] = 127, -+ [0][1][2][1][RTW89_ACMA][1][49] = 127, -+ [0][1][2][1][RTW89_ACMA][0][49] = 127, -+ [0][1][2][1][RTW89_CHILE][1][49] = -2, -+ [0][1][2][1][RTW89_QATAR][1][49] = 127, -+ [0][1][2][1][RTW89_QATAR][0][49] = 127, -+ [0][1][2][1][RTW89_UK][1][49] = 127, -+ [0][1][2][1][RTW89_UK][0][49] = 127, -+ [0][1][2][1][RTW89_FCC][1][51] = -2, -+ [0][1][2][1][RTW89_FCC][2][51] = 127, -+ [0][1][2][1][RTW89_ETSI][1][51] = 127, -+ [0][1][2][1][RTW89_ETSI][0][51] = 127, -+ [0][1][2][1][RTW89_MKK][1][51] = 127, -+ [0][1][2][1][RTW89_MKK][0][51] = 127, -+ [0][1][2][1][RTW89_IC][1][51] = -2, -+ [0][1][2][1][RTW89_KCC][1][51] = 12, -+ [0][1][2][1][RTW89_KCC][0][51] = 127, -+ [0][1][2][1][RTW89_ACMA][1][51] = 127, -+ [0][1][2][1][RTW89_ACMA][0][51] = 127, -+ [0][1][2][1][RTW89_CHILE][1][51] = -2, -+ [0][1][2][1][RTW89_QATAR][1][51] = 127, -+ [0][1][2][1][RTW89_QATAR][0][51] = 127, -+ [0][1][2][1][RTW89_UK][1][51] = 127, -+ [0][1][2][1][RTW89_UK][0][51] = 127, -+ [0][1][2][1][RTW89_FCC][1][53] = -2, -+ [0][1][2][1][RTW89_FCC][2][53] = 127, -+ [0][1][2][1][RTW89_ETSI][1][53] = 127, -+ [0][1][2][1][RTW89_ETSI][0][53] = 127, -+ [0][1][2][1][RTW89_MKK][1][53] = 127, -+ [0][1][2][1][RTW89_MKK][0][53] = 127, -+ [0][1][2][1][RTW89_IC][1][53] = -2, -+ [0][1][2][1][RTW89_KCC][1][53] = 12, -+ [0][1][2][1][RTW89_KCC][0][53] = 127, -+ [0][1][2][1][RTW89_ACMA][1][53] = 127, -+ [0][1][2][1][RTW89_ACMA][0][53] = 127, -+ [0][1][2][1][RTW89_CHILE][1][53] = -2, -+ [0][1][2][1][RTW89_QATAR][1][53] = 127, -+ [0][1][2][1][RTW89_QATAR][0][53] = 127, -+ [0][1][2][1][RTW89_UK][1][53] = 127, -+ [0][1][2][1][RTW89_UK][0][53] = 127, -+ [0][1][2][1][RTW89_FCC][1][55] = -2, -+ [0][1][2][1][RTW89_FCC][2][55] = 68, -+ [0][1][2][1][RTW89_ETSI][1][55] = 127, -+ [0][1][2][1][RTW89_ETSI][0][55] = 127, -+ [0][1][2][1][RTW89_MKK][1][55] = 127, -+ [0][1][2][1][RTW89_MKK][0][55] = 127, -+ [0][1][2][1][RTW89_IC][1][55] = -2, -+ [0][1][2][1][RTW89_KCC][1][55] = 12, -+ [0][1][2][1][RTW89_KCC][0][55] = 127, -+ [0][1][2][1][RTW89_ACMA][1][55] = 127, -+ [0][1][2][1][RTW89_ACMA][0][55] = 127, -+ [0][1][2][1][RTW89_CHILE][1][55] = -2, -+ [0][1][2][1][RTW89_QATAR][1][55] = 127, -+ [0][1][2][1][RTW89_QATAR][0][55] = 127, -+ [0][1][2][1][RTW89_UK][1][55] = 127, -+ [0][1][2][1][RTW89_UK][0][55] = 127, -+ [0][1][2][1][RTW89_FCC][1][57] = -2, -+ [0][1][2][1][RTW89_FCC][2][57] = 68, -+ [0][1][2][1][RTW89_ETSI][1][57] = 127, -+ [0][1][2][1][RTW89_ETSI][0][57] = 127, -+ [0][1][2][1][RTW89_MKK][1][57] = 127, -+ [0][1][2][1][RTW89_MKK][0][57] = 127, -+ [0][1][2][1][RTW89_IC][1][57] = -2, -+ [0][1][2][1][RTW89_KCC][1][57] = 12, -+ [0][1][2][1][RTW89_KCC][0][57] = 127, -+ [0][1][2][1][RTW89_ACMA][1][57] = 127, -+ [0][1][2][1][RTW89_ACMA][0][57] = 127, -+ [0][1][2][1][RTW89_CHILE][1][57] = -2, -+ [0][1][2][1][RTW89_QATAR][1][57] = 127, -+ [0][1][2][1][RTW89_QATAR][0][57] = 127, -+ [0][1][2][1][RTW89_UK][1][57] = 127, -+ [0][1][2][1][RTW89_UK][0][57] = 127, -+ [0][1][2][1][RTW89_FCC][1][59] = -2, -+ [0][1][2][1][RTW89_FCC][2][59] = 68, -+ [0][1][2][1][RTW89_ETSI][1][59] = 127, -+ [0][1][2][1][RTW89_ETSI][0][59] = 127, -+ [0][1][2][1][RTW89_MKK][1][59] = 127, -+ [0][1][2][1][RTW89_MKK][0][59] = 127, -+ [0][1][2][1][RTW89_IC][1][59] = -2, -+ [0][1][2][1][RTW89_KCC][1][59] = 12, -+ [0][1][2][1][RTW89_KCC][0][59] = 127, -+ [0][1][2][1][RTW89_ACMA][1][59] = 127, -+ [0][1][2][1][RTW89_ACMA][0][59] = 127, -+ [0][1][2][1][RTW89_CHILE][1][59] = -2, -+ [0][1][2][1][RTW89_QATAR][1][59] = 127, -+ [0][1][2][1][RTW89_QATAR][0][59] = 127, -+ [0][1][2][1][RTW89_UK][1][59] = 127, -+ [0][1][2][1][RTW89_UK][0][59] = 127, -+ [0][1][2][1][RTW89_FCC][1][60] = -2, -+ [0][1][2][1][RTW89_FCC][2][60] = 68, -+ [0][1][2][1][RTW89_ETSI][1][60] = 127, -+ [0][1][2][1][RTW89_ETSI][0][60] = 127, -+ [0][1][2][1][RTW89_MKK][1][60] = 127, -+ [0][1][2][1][RTW89_MKK][0][60] = 127, -+ [0][1][2][1][RTW89_IC][1][60] = -2, -+ [0][1][2][1][RTW89_KCC][1][60] = 12, -+ [0][1][2][1][RTW89_KCC][0][60] = 127, -+ [0][1][2][1][RTW89_ACMA][1][60] = 127, -+ [0][1][2][1][RTW89_ACMA][0][60] = 127, -+ [0][1][2][1][RTW89_CHILE][1][60] = -2, -+ [0][1][2][1][RTW89_QATAR][1][60] = 127, -+ [0][1][2][1][RTW89_QATAR][0][60] = 127, -+ [0][1][2][1][RTW89_UK][1][60] = 127, -+ [0][1][2][1][RTW89_UK][0][60] = 127, -+ [0][1][2][1][RTW89_FCC][1][62] = -2, -+ [0][1][2][1][RTW89_FCC][2][62] = 68, -+ [0][1][2][1][RTW89_ETSI][1][62] = 127, -+ [0][1][2][1][RTW89_ETSI][0][62] = 127, -+ [0][1][2][1][RTW89_MKK][1][62] = 127, -+ [0][1][2][1][RTW89_MKK][0][62] = 127, -+ [0][1][2][1][RTW89_IC][1][62] = -2, -+ [0][1][2][1][RTW89_KCC][1][62] = 12, -+ [0][1][2][1][RTW89_KCC][0][62] = 127, -+ [0][1][2][1][RTW89_ACMA][1][62] = 127, -+ [0][1][2][1][RTW89_ACMA][0][62] = 127, -+ [0][1][2][1][RTW89_CHILE][1][62] = -2, -+ [0][1][2][1][RTW89_QATAR][1][62] = 127, -+ [0][1][2][1][RTW89_QATAR][0][62] = 127, -+ [0][1][2][1][RTW89_UK][1][62] = 127, -+ [0][1][2][1][RTW89_UK][0][62] = 127, -+ [0][1][2][1][RTW89_FCC][1][64] = -2, -+ [0][1][2][1][RTW89_FCC][2][64] = 68, -+ [0][1][2][1][RTW89_ETSI][1][64] = 127, -+ [0][1][2][1][RTW89_ETSI][0][64] = 127, -+ [0][1][2][1][RTW89_MKK][1][64] = 127, -+ [0][1][2][1][RTW89_MKK][0][64] = 127, -+ [0][1][2][1][RTW89_IC][1][64] = -2, -+ [0][1][2][1][RTW89_KCC][1][64] = 12, -+ [0][1][2][1][RTW89_KCC][0][64] = 127, -+ [0][1][2][1][RTW89_ACMA][1][64] = 127, -+ [0][1][2][1][RTW89_ACMA][0][64] = 127, -+ [0][1][2][1][RTW89_CHILE][1][64] = -2, -+ [0][1][2][1][RTW89_QATAR][1][64] = 127, -+ [0][1][2][1][RTW89_QATAR][0][64] = 127, -+ [0][1][2][1][RTW89_UK][1][64] = 127, -+ [0][1][2][1][RTW89_UK][0][64] = 127, -+ [0][1][2][1][RTW89_FCC][1][66] = -2, -+ [0][1][2][1][RTW89_FCC][2][66] = 68, -+ [0][1][2][1][RTW89_ETSI][1][66] = 127, -+ [0][1][2][1][RTW89_ETSI][0][66] = 127, -+ [0][1][2][1][RTW89_MKK][1][66] = 127, -+ [0][1][2][1][RTW89_MKK][0][66] = 127, -+ [0][1][2][1][RTW89_IC][1][66] = -2, -+ [0][1][2][1][RTW89_KCC][1][66] = 12, -+ [0][1][2][1][RTW89_KCC][0][66] = 127, -+ [0][1][2][1][RTW89_ACMA][1][66] = 127, -+ [0][1][2][1][RTW89_ACMA][0][66] = 127, -+ [0][1][2][1][RTW89_CHILE][1][66] = -2, -+ [0][1][2][1][RTW89_QATAR][1][66] = 127, -+ [0][1][2][1][RTW89_QATAR][0][66] = 127, -+ [0][1][2][1][RTW89_UK][1][66] = 127, -+ [0][1][2][1][RTW89_UK][0][66] = 127, -+ [0][1][2][1][RTW89_FCC][1][68] = -2, -+ [0][1][2][1][RTW89_FCC][2][68] = 68, -+ [0][1][2][1][RTW89_ETSI][1][68] = 127, -+ [0][1][2][1][RTW89_ETSI][0][68] = 127, -+ [0][1][2][1][RTW89_MKK][1][68] = 127, -+ [0][1][2][1][RTW89_MKK][0][68] = 127, -+ [0][1][2][1][RTW89_IC][1][68] = -2, -+ [0][1][2][1][RTW89_KCC][1][68] = 12, -+ [0][1][2][1][RTW89_KCC][0][68] = 127, -+ [0][1][2][1][RTW89_ACMA][1][68] = 127, -+ [0][1][2][1][RTW89_ACMA][0][68] = 127, -+ [0][1][2][1][RTW89_CHILE][1][68] = -2, -+ [0][1][2][1][RTW89_QATAR][1][68] = 127, -+ [0][1][2][1][RTW89_QATAR][0][68] = 127, -+ [0][1][2][1][RTW89_UK][1][68] = 127, -+ [0][1][2][1][RTW89_UK][0][68] = 127, -+ [0][1][2][1][RTW89_FCC][1][70] = -2, -+ [0][1][2][1][RTW89_FCC][2][70] = 68, -+ [0][1][2][1][RTW89_ETSI][1][70] = 127, -+ [0][1][2][1][RTW89_ETSI][0][70] = 127, -+ [0][1][2][1][RTW89_MKK][1][70] = 127, -+ [0][1][2][1][RTW89_MKK][0][70] = 127, -+ [0][1][2][1][RTW89_IC][1][70] = -2, -+ [0][1][2][1][RTW89_KCC][1][70] = 12, -+ [0][1][2][1][RTW89_KCC][0][70] = 127, -+ [0][1][2][1][RTW89_ACMA][1][70] = 127, -+ [0][1][2][1][RTW89_ACMA][0][70] = 127, -+ [0][1][2][1][RTW89_CHILE][1][70] = -2, -+ [0][1][2][1][RTW89_QATAR][1][70] = 127, -+ [0][1][2][1][RTW89_QATAR][0][70] = 127, -+ [0][1][2][1][RTW89_UK][1][70] = 127, -+ [0][1][2][1][RTW89_UK][0][70] = 127, -+ [0][1][2][1][RTW89_FCC][1][72] = -2, -+ [0][1][2][1][RTW89_FCC][2][72] = 68, -+ [0][1][2][1][RTW89_ETSI][1][72] = 127, -+ [0][1][2][1][RTW89_ETSI][0][72] = 127, -+ [0][1][2][1][RTW89_MKK][1][72] = 127, -+ [0][1][2][1][RTW89_MKK][0][72] = 127, -+ [0][1][2][1][RTW89_IC][1][72] = -2, -+ [0][1][2][1][RTW89_KCC][1][72] = 12, -+ [0][1][2][1][RTW89_KCC][0][72] = 127, -+ [0][1][2][1][RTW89_ACMA][1][72] = 127, -+ [0][1][2][1][RTW89_ACMA][0][72] = 127, -+ [0][1][2][1][RTW89_CHILE][1][72] = -2, -+ [0][1][2][1][RTW89_QATAR][1][72] = 127, -+ [0][1][2][1][RTW89_QATAR][0][72] = 127, -+ [0][1][2][1][RTW89_UK][1][72] = 127, -+ [0][1][2][1][RTW89_UK][0][72] = 127, -+ [0][1][2][1][RTW89_FCC][1][74] = -2, -+ [0][1][2][1][RTW89_FCC][2][74] = 68, -+ [0][1][2][1][RTW89_ETSI][1][74] = 127, -+ [0][1][2][1][RTW89_ETSI][0][74] = 127, -+ [0][1][2][1][RTW89_MKK][1][74] = 127, -+ [0][1][2][1][RTW89_MKK][0][74] = 127, -+ [0][1][2][1][RTW89_IC][1][74] = -2, -+ [0][1][2][1][RTW89_KCC][1][74] = 12, -+ [0][1][2][1][RTW89_KCC][0][74] = 127, -+ [0][1][2][1][RTW89_ACMA][1][74] = 127, -+ [0][1][2][1][RTW89_ACMA][0][74] = 127, -+ [0][1][2][1][RTW89_CHILE][1][74] = -2, -+ [0][1][2][1][RTW89_QATAR][1][74] = 127, -+ [0][1][2][1][RTW89_QATAR][0][74] = 127, -+ [0][1][2][1][RTW89_UK][1][74] = 127, -+ [0][1][2][1][RTW89_UK][0][74] = 127, -+ [0][1][2][1][RTW89_FCC][1][75] = -2, -+ [0][1][2][1][RTW89_FCC][2][75] = 68, -+ [0][1][2][1][RTW89_ETSI][1][75] = 127, -+ [0][1][2][1][RTW89_ETSI][0][75] = 127, -+ [0][1][2][1][RTW89_MKK][1][75] = 127, -+ [0][1][2][1][RTW89_MKK][0][75] = 127, -+ [0][1][2][1][RTW89_IC][1][75] = -2, -+ [0][1][2][1][RTW89_KCC][1][75] = 12, -+ [0][1][2][1][RTW89_KCC][0][75] = 127, -+ [0][1][2][1][RTW89_ACMA][1][75] = 127, -+ [0][1][2][1][RTW89_ACMA][0][75] = 127, -+ [0][1][2][1][RTW89_CHILE][1][75] = -2, -+ [0][1][2][1][RTW89_QATAR][1][75] = 127, -+ [0][1][2][1][RTW89_QATAR][0][75] = 127, -+ [0][1][2][1][RTW89_UK][1][75] = 127, -+ [0][1][2][1][RTW89_UK][0][75] = 127, -+ [0][1][2][1][RTW89_FCC][1][77] = -2, -+ [0][1][2][1][RTW89_FCC][2][77] = 68, -+ [0][1][2][1][RTW89_ETSI][1][77] = 127, -+ [0][1][2][1][RTW89_ETSI][0][77] = 127, -+ [0][1][2][1][RTW89_MKK][1][77] = 127, -+ [0][1][2][1][RTW89_MKK][0][77] = 127, -+ [0][1][2][1][RTW89_IC][1][77] = -2, -+ [0][1][2][1][RTW89_KCC][1][77] = 12, -+ [0][1][2][1][RTW89_KCC][0][77] = 127, -+ [0][1][2][1][RTW89_ACMA][1][77] = 127, -+ [0][1][2][1][RTW89_ACMA][0][77] = 127, -+ [0][1][2][1][RTW89_CHILE][1][77] = -2, -+ [0][1][2][1][RTW89_QATAR][1][77] = 127, -+ [0][1][2][1][RTW89_QATAR][0][77] = 127, -+ [0][1][2][1][RTW89_UK][1][77] = 127, -+ [0][1][2][1][RTW89_UK][0][77] = 127, -+ [0][1][2][1][RTW89_FCC][1][79] = -2, -+ [0][1][2][1][RTW89_FCC][2][79] = 68, -+ [0][1][2][1][RTW89_ETSI][1][79] = 127, -+ [0][1][2][1][RTW89_ETSI][0][79] = 127, -+ [0][1][2][1][RTW89_MKK][1][79] = 127, -+ [0][1][2][1][RTW89_MKK][0][79] = 127, -+ [0][1][2][1][RTW89_IC][1][79] = -2, -+ [0][1][2][1][RTW89_KCC][1][79] = 12, -+ [0][1][2][1][RTW89_KCC][0][79] = 127, -+ [0][1][2][1][RTW89_ACMA][1][79] = 127, -+ [0][1][2][1][RTW89_ACMA][0][79] = 127, -+ [0][1][2][1][RTW89_CHILE][1][79] = -2, -+ [0][1][2][1][RTW89_QATAR][1][79] = 127, -+ [0][1][2][1][RTW89_QATAR][0][79] = 127, -+ [0][1][2][1][RTW89_UK][1][79] = 127, -+ [0][1][2][1][RTW89_UK][0][79] = 127, -+ [0][1][2][1][RTW89_FCC][1][81] = -2, -+ [0][1][2][1][RTW89_FCC][2][81] = 68, -+ [0][1][2][1][RTW89_ETSI][1][81] = 127, -+ [0][1][2][1][RTW89_ETSI][0][81] = 127, -+ [0][1][2][1][RTW89_MKK][1][81] = 127, -+ [0][1][2][1][RTW89_MKK][0][81] = 127, -+ [0][1][2][1][RTW89_IC][1][81] = -2, -+ [0][1][2][1][RTW89_KCC][1][81] = 12, -+ [0][1][2][1][RTW89_KCC][0][81] = 127, -+ [0][1][2][1][RTW89_ACMA][1][81] = 127, -+ [0][1][2][1][RTW89_ACMA][0][81] = 127, -+ [0][1][2][1][RTW89_CHILE][1][81] = -2, -+ [0][1][2][1][RTW89_QATAR][1][81] = 127, -+ [0][1][2][1][RTW89_QATAR][0][81] = 127, -+ [0][1][2][1][RTW89_UK][1][81] = 127, -+ [0][1][2][1][RTW89_UK][0][81] = 127, -+ [0][1][2][1][RTW89_FCC][1][83] = -2, -+ [0][1][2][1][RTW89_FCC][2][83] = 68, -+ [0][1][2][1][RTW89_ETSI][1][83] = 127, -+ [0][1][2][1][RTW89_ETSI][0][83] = 127, -+ [0][1][2][1][RTW89_MKK][1][83] = 127, -+ [0][1][2][1][RTW89_MKK][0][83] = 127, -+ [0][1][2][1][RTW89_IC][1][83] = -2, -+ [0][1][2][1][RTW89_KCC][1][83] = 20, -+ [0][1][2][1][RTW89_KCC][0][83] = 127, -+ [0][1][2][1][RTW89_ACMA][1][83] = 127, -+ [0][1][2][1][RTW89_ACMA][0][83] = 127, -+ [0][1][2][1][RTW89_CHILE][1][83] = -2, -+ [0][1][2][1][RTW89_QATAR][1][83] = 127, -+ [0][1][2][1][RTW89_QATAR][0][83] = 127, -+ [0][1][2][1][RTW89_UK][1][83] = 127, -+ [0][1][2][1][RTW89_UK][0][83] = 127, -+ [0][1][2][1][RTW89_FCC][1][85] = -2, -+ [0][1][2][1][RTW89_FCC][2][85] = 68, -+ [0][1][2][1][RTW89_ETSI][1][85] = 127, -+ [0][1][2][1][RTW89_ETSI][0][85] = 127, -+ [0][1][2][1][RTW89_MKK][1][85] = 127, -+ [0][1][2][1][RTW89_MKK][0][85] = 127, -+ [0][1][2][1][RTW89_IC][1][85] = -2, -+ [0][1][2][1][RTW89_KCC][1][85] = 20, -+ [0][1][2][1][RTW89_KCC][0][85] = 127, -+ [0][1][2][1][RTW89_ACMA][1][85] = 127, -+ [0][1][2][1][RTW89_ACMA][0][85] = 127, -+ [0][1][2][1][RTW89_CHILE][1][85] = -2, -+ [0][1][2][1][RTW89_QATAR][1][85] = 127, -+ [0][1][2][1][RTW89_QATAR][0][85] = 127, -+ [0][1][2][1][RTW89_UK][1][85] = 127, -+ [0][1][2][1][RTW89_UK][0][85] = 127, -+ [0][1][2][1][RTW89_FCC][1][87] = -2, -+ [0][1][2][1][RTW89_FCC][2][87] = 127, -+ [0][1][2][1][RTW89_ETSI][1][87] = 127, -+ [0][1][2][1][RTW89_ETSI][0][87] = 127, -+ [0][1][2][1][RTW89_MKK][1][87] = 127, -+ [0][1][2][1][RTW89_MKK][0][87] = 127, -+ [0][1][2][1][RTW89_IC][1][87] = -2, -+ [0][1][2][1][RTW89_KCC][1][87] = 20, -+ [0][1][2][1][RTW89_KCC][0][87] = 127, -+ [0][1][2][1][RTW89_ACMA][1][87] = 127, -+ [0][1][2][1][RTW89_ACMA][0][87] = 127, -+ [0][1][2][1][RTW89_CHILE][1][87] = -2, -+ [0][1][2][1][RTW89_QATAR][1][87] = 127, -+ [0][1][2][1][RTW89_QATAR][0][87] = 127, -+ [0][1][2][1][RTW89_UK][1][87] = 127, -+ [0][1][2][1][RTW89_UK][0][87] = 127, -+ [0][1][2][1][RTW89_FCC][1][89] = -2, -+ [0][1][2][1][RTW89_FCC][2][89] = 127, -+ [0][1][2][1][RTW89_ETSI][1][89] = 127, -+ [0][1][2][1][RTW89_ETSI][0][89] = 127, -+ [0][1][2][1][RTW89_MKK][1][89] = 127, -+ [0][1][2][1][RTW89_MKK][0][89] = 127, -+ [0][1][2][1][RTW89_IC][1][89] = -2, -+ [0][1][2][1][RTW89_KCC][1][89] = 20, -+ [0][1][2][1][RTW89_KCC][0][89] = 127, -+ [0][1][2][1][RTW89_ACMA][1][89] = 127, -+ [0][1][2][1][RTW89_ACMA][0][89] = 127, -+ [0][1][2][1][RTW89_CHILE][1][89] = -2, -+ [0][1][2][1][RTW89_QATAR][1][89] = 127, -+ [0][1][2][1][RTW89_QATAR][0][89] = 127, -+ [0][1][2][1][RTW89_UK][1][89] = 127, -+ [0][1][2][1][RTW89_UK][0][89] = 127, -+ [0][1][2][1][RTW89_FCC][1][90] = -2, -+ [0][1][2][1][RTW89_FCC][2][90] = 127, -+ [0][1][2][1][RTW89_ETSI][1][90] = 127, -+ [0][1][2][1][RTW89_ETSI][0][90] = 127, -+ [0][1][2][1][RTW89_MKK][1][90] = 127, -+ [0][1][2][1][RTW89_MKK][0][90] = 127, -+ [0][1][2][1][RTW89_IC][1][90] = -2, -+ [0][1][2][1][RTW89_KCC][1][90] = 20, -+ [0][1][2][1][RTW89_KCC][0][90] = 127, -+ [0][1][2][1][RTW89_ACMA][1][90] = 127, -+ [0][1][2][1][RTW89_ACMA][0][90] = 127, -+ [0][1][2][1][RTW89_CHILE][1][90] = -2, -+ [0][1][2][1][RTW89_QATAR][1][90] = 127, -+ [0][1][2][1][RTW89_QATAR][0][90] = 127, -+ [0][1][2][1][RTW89_UK][1][90] = 127, -+ [0][1][2][1][RTW89_UK][0][90] = 127, -+ [0][1][2][1][RTW89_FCC][1][92] = -2, -+ [0][1][2][1][RTW89_FCC][2][92] = 127, -+ [0][1][2][1][RTW89_ETSI][1][92] = 127, -+ [0][1][2][1][RTW89_ETSI][0][92] = 127, -+ [0][1][2][1][RTW89_MKK][1][92] = 127, -+ [0][1][2][1][RTW89_MKK][0][92] = 127, -+ [0][1][2][1][RTW89_IC][1][92] = -2, -+ [0][1][2][1][RTW89_KCC][1][92] = 20, -+ [0][1][2][1][RTW89_KCC][0][92] = 127, -+ [0][1][2][1][RTW89_ACMA][1][92] = 127, -+ [0][1][2][1][RTW89_ACMA][0][92] = 127, -+ [0][1][2][1][RTW89_CHILE][1][92] = -2, -+ [0][1][2][1][RTW89_QATAR][1][92] = 127, -+ [0][1][2][1][RTW89_QATAR][0][92] = 127, -+ [0][1][2][1][RTW89_UK][1][92] = 127, -+ [0][1][2][1][RTW89_UK][0][92] = 127, -+ [0][1][2][1][RTW89_FCC][1][94] = -2, -+ [0][1][2][1][RTW89_FCC][2][94] = 127, -+ [0][1][2][1][RTW89_ETSI][1][94] = 127, -+ [0][1][2][1][RTW89_ETSI][0][94] = 127, -+ [0][1][2][1][RTW89_MKK][1][94] = 127, -+ [0][1][2][1][RTW89_MKK][0][94] = 127, -+ [0][1][2][1][RTW89_IC][1][94] = -2, -+ [0][1][2][1][RTW89_KCC][1][94] = 20, -+ [0][1][2][1][RTW89_KCC][0][94] = 127, -+ [0][1][2][1][RTW89_ACMA][1][94] = 127, -+ [0][1][2][1][RTW89_ACMA][0][94] = 127, -+ [0][1][2][1][RTW89_CHILE][1][94] = -2, -+ [0][1][2][1][RTW89_QATAR][1][94] = 127, -+ [0][1][2][1][RTW89_QATAR][0][94] = 127, -+ [0][1][2][1][RTW89_UK][1][94] = 127, -+ [0][1][2][1][RTW89_UK][0][94] = 127, -+ [0][1][2][1][RTW89_FCC][1][96] = -2, -+ [0][1][2][1][RTW89_FCC][2][96] = 127, -+ [0][1][2][1][RTW89_ETSI][1][96] = 127, -+ [0][1][2][1][RTW89_ETSI][0][96] = 127, -+ [0][1][2][1][RTW89_MKK][1][96] = 127, -+ [0][1][2][1][RTW89_MKK][0][96] = 127, -+ [0][1][2][1][RTW89_IC][1][96] = -2, -+ [0][1][2][1][RTW89_KCC][1][96] = 20, -+ [0][1][2][1][RTW89_KCC][0][96] = 127, -+ [0][1][2][1][RTW89_ACMA][1][96] = 127, -+ [0][1][2][1][RTW89_ACMA][0][96] = 127, -+ [0][1][2][1][RTW89_CHILE][1][96] = -2, -+ [0][1][2][1][RTW89_QATAR][1][96] = 127, -+ [0][1][2][1][RTW89_QATAR][0][96] = 127, -+ [0][1][2][1][RTW89_UK][1][96] = 127, -+ [0][1][2][1][RTW89_UK][0][96] = 127, -+ [0][1][2][1][RTW89_FCC][1][98] = -2, -+ [0][1][2][1][RTW89_FCC][2][98] = 127, -+ [0][1][2][1][RTW89_ETSI][1][98] = 127, -+ [0][1][2][1][RTW89_ETSI][0][98] = 127, -+ [0][1][2][1][RTW89_MKK][1][98] = 127, -+ [0][1][2][1][RTW89_MKK][0][98] = 127, -+ [0][1][2][1][RTW89_IC][1][98] = -2, -+ [0][1][2][1][RTW89_KCC][1][98] = 20, -+ [0][1][2][1][RTW89_KCC][0][98] = 127, -+ [0][1][2][1][RTW89_ACMA][1][98] = 127, -+ [0][1][2][1][RTW89_ACMA][0][98] = 127, -+ [0][1][2][1][RTW89_CHILE][1][98] = -2, -+ [0][1][2][1][RTW89_QATAR][1][98] = 127, -+ [0][1][2][1][RTW89_QATAR][0][98] = 127, -+ [0][1][2][1][RTW89_UK][1][98] = 127, -+ [0][1][2][1][RTW89_UK][0][98] = 127, -+ [0][1][2][1][RTW89_FCC][1][100] = -2, -+ [0][1][2][1][RTW89_FCC][2][100] = 127, -+ [0][1][2][1][RTW89_ETSI][1][100] = 127, -+ [0][1][2][1][RTW89_ETSI][0][100] = 127, -+ [0][1][2][1][RTW89_MKK][1][100] = 127, -+ [0][1][2][1][RTW89_MKK][0][100] = 127, -+ [0][1][2][1][RTW89_IC][1][100] = -2, -+ [0][1][2][1][RTW89_KCC][1][100] = 20, -+ [0][1][2][1][RTW89_KCC][0][100] = 127, -+ [0][1][2][1][RTW89_ACMA][1][100] = 127, -+ [0][1][2][1][RTW89_ACMA][0][100] = 127, -+ [0][1][2][1][RTW89_CHILE][1][100] = -2, -+ [0][1][2][1][RTW89_QATAR][1][100] = 127, -+ [0][1][2][1][RTW89_QATAR][0][100] = 127, -+ [0][1][2][1][RTW89_UK][1][100] = 127, -+ [0][1][2][1][RTW89_UK][0][100] = 127, -+ [0][1][2][1][RTW89_FCC][1][102] = -2, -+ [0][1][2][1][RTW89_FCC][2][102] = 127, -+ [0][1][2][1][RTW89_ETSI][1][102] = 127, -+ [0][1][2][1][RTW89_ETSI][0][102] = 127, -+ [0][1][2][1][RTW89_MKK][1][102] = 127, -+ [0][1][2][1][RTW89_MKK][0][102] = 127, -+ [0][1][2][1][RTW89_IC][1][102] = -2, -+ [0][1][2][1][RTW89_KCC][1][102] = 20, -+ [0][1][2][1][RTW89_KCC][0][102] = 127, -+ [0][1][2][1][RTW89_ACMA][1][102] = 127, -+ [0][1][2][1][RTW89_ACMA][0][102] = 127, -+ [0][1][2][1][RTW89_CHILE][1][102] = -2, -+ [0][1][2][1][RTW89_QATAR][1][102] = 127, -+ [0][1][2][1][RTW89_QATAR][0][102] = 127, -+ [0][1][2][1][RTW89_UK][1][102] = 127, -+ [0][1][2][1][RTW89_UK][0][102] = 127, -+ [0][1][2][1][RTW89_FCC][1][104] = -2, -+ [0][1][2][1][RTW89_FCC][2][104] = 127, -+ [0][1][2][1][RTW89_ETSI][1][104] = 127, -+ [0][1][2][1][RTW89_ETSI][0][104] = 127, -+ [0][1][2][1][RTW89_MKK][1][104] = 127, -+ [0][1][2][1][RTW89_MKK][0][104] = 127, -+ [0][1][2][1][RTW89_IC][1][104] = -2, -+ [0][1][2][1][RTW89_KCC][1][104] = 20, -+ [0][1][2][1][RTW89_KCC][0][104] = 127, -+ [0][1][2][1][RTW89_ACMA][1][104] = 127, -+ [0][1][2][1][RTW89_ACMA][0][104] = 127, -+ [0][1][2][1][RTW89_CHILE][1][104] = -2, -+ [0][1][2][1][RTW89_QATAR][1][104] = 127, -+ [0][1][2][1][RTW89_QATAR][0][104] = 127, -+ [0][1][2][1][RTW89_UK][1][104] = 127, -+ [0][1][2][1][RTW89_UK][0][104] = 127, -+ [0][1][2][1][RTW89_FCC][1][105] = -2, -+ [0][1][2][1][RTW89_FCC][2][105] = 127, -+ [0][1][2][1][RTW89_ETSI][1][105] = 127, -+ [0][1][2][1][RTW89_ETSI][0][105] = 127, -+ [0][1][2][1][RTW89_MKK][1][105] = 127, -+ [0][1][2][1][RTW89_MKK][0][105] = 127, -+ [0][1][2][1][RTW89_IC][1][105] = -2, -+ [0][1][2][1][RTW89_KCC][1][105] = 20, -+ [0][1][2][1][RTW89_KCC][0][105] = 127, -+ [0][1][2][1][RTW89_ACMA][1][105] = 127, -+ [0][1][2][1][RTW89_ACMA][0][105] = 127, -+ [0][1][2][1][RTW89_CHILE][1][105] = -2, -+ [0][1][2][1][RTW89_QATAR][1][105] = 127, -+ [0][1][2][1][RTW89_QATAR][0][105] = 127, -+ [0][1][2][1][RTW89_UK][1][105] = 127, -+ [0][1][2][1][RTW89_UK][0][105] = 127, -+ [0][1][2][1][RTW89_FCC][1][107] = 1, -+ [0][1][2][1][RTW89_FCC][2][107] = 127, -+ [0][1][2][1][RTW89_ETSI][1][107] = 127, -+ [0][1][2][1][RTW89_ETSI][0][107] = 127, -+ [0][1][2][1][RTW89_MKK][1][107] = 127, -+ [0][1][2][1][RTW89_MKK][0][107] = 127, -+ [0][1][2][1][RTW89_IC][1][107] = 1, -+ [0][1][2][1][RTW89_KCC][1][107] = 20, -+ [0][1][2][1][RTW89_KCC][0][107] = 127, -+ [0][1][2][1][RTW89_ACMA][1][107] = 127, -+ [0][1][2][1][RTW89_ACMA][0][107] = 127, -+ [0][1][2][1][RTW89_CHILE][1][107] = 1, -+ [0][1][2][1][RTW89_QATAR][1][107] = 127, -+ [0][1][2][1][RTW89_QATAR][0][107] = 127, -+ [0][1][2][1][RTW89_UK][1][107] = 127, -+ [0][1][2][1][RTW89_UK][0][107] = 127, -+ [0][1][2][1][RTW89_FCC][1][109] = 1, -+ [0][1][2][1][RTW89_FCC][2][109] = 127, -+ [0][1][2][1][RTW89_ETSI][1][109] = 127, -+ [0][1][2][1][RTW89_ETSI][0][109] = 127, -+ [0][1][2][1][RTW89_MKK][1][109] = 127, -+ [0][1][2][1][RTW89_MKK][0][109] = 127, -+ [0][1][2][1][RTW89_IC][1][109] = 1, -+ [0][1][2][1][RTW89_KCC][1][109] = 20, -+ [0][1][2][1][RTW89_KCC][0][109] = 127, -+ [0][1][2][1][RTW89_ACMA][1][109] = 127, -+ [0][1][2][1][RTW89_ACMA][0][109] = 127, -+ [0][1][2][1][RTW89_CHILE][1][109] = 1, -+ [0][1][2][1][RTW89_QATAR][1][109] = 127, -+ [0][1][2][1][RTW89_QATAR][0][109] = 127, -+ [0][1][2][1][RTW89_UK][1][109] = 127, -+ [0][1][2][1][RTW89_UK][0][109] = 127, -+ [0][1][2][1][RTW89_FCC][1][111] = 127, -+ [0][1][2][1][RTW89_FCC][2][111] = 127, -+ [0][1][2][1][RTW89_ETSI][1][111] = 127, -+ [0][1][2][1][RTW89_ETSI][0][111] = 127, -+ [0][1][2][1][RTW89_MKK][1][111] = 127, -+ [0][1][2][1][RTW89_MKK][0][111] = 127, -+ [0][1][2][1][RTW89_IC][1][111] = 127, -+ [0][1][2][1][RTW89_KCC][1][111] = 127, -+ [0][1][2][1][RTW89_KCC][0][111] = 127, -+ [0][1][2][1][RTW89_ACMA][1][111] = 127, -+ [0][1][2][1][RTW89_ACMA][0][111] = 127, -+ [0][1][2][1][RTW89_CHILE][1][111] = 127, -+ [0][1][2][1][RTW89_QATAR][1][111] = 127, -+ [0][1][2][1][RTW89_QATAR][0][111] = 127, -+ [0][1][2][1][RTW89_UK][1][111] = 127, -+ [0][1][2][1][RTW89_UK][0][111] = 127, -+ [0][1][2][1][RTW89_FCC][1][113] = 127, -+ [0][1][2][1][RTW89_FCC][2][113] = 127, -+ [0][1][2][1][RTW89_ETSI][1][113] = 127, -+ [0][1][2][1][RTW89_ETSI][0][113] = 127, -+ [0][1][2][1][RTW89_MKK][1][113] = 127, -+ [0][1][2][1][RTW89_MKK][0][113] = 127, -+ [0][1][2][1][RTW89_IC][1][113] = 127, -+ [0][1][2][1][RTW89_KCC][1][113] = 127, -+ [0][1][2][1][RTW89_KCC][0][113] = 127, -+ [0][1][2][1][RTW89_ACMA][1][113] = 127, -+ [0][1][2][1][RTW89_ACMA][0][113] = 127, -+ [0][1][2][1][RTW89_CHILE][1][113] = 127, -+ [0][1][2][1][RTW89_QATAR][1][113] = 127, -+ [0][1][2][1][RTW89_QATAR][0][113] = 127, -+ [0][1][2][1][RTW89_UK][1][113] = 127, -+ [0][1][2][1][RTW89_UK][0][113] = 127, -+ [0][1][2][1][RTW89_FCC][1][115] = 127, -+ [0][1][2][1][RTW89_FCC][2][115] = 127, -+ [0][1][2][1][RTW89_ETSI][1][115] = 127, -+ [0][1][2][1][RTW89_ETSI][0][115] = 127, -+ [0][1][2][1][RTW89_MKK][1][115] = 127, -+ [0][1][2][1][RTW89_MKK][0][115] = 127, -+ [0][1][2][1][RTW89_IC][1][115] = 127, -+ [0][1][2][1][RTW89_KCC][1][115] = 127, -+ [0][1][2][1][RTW89_KCC][0][115] = 127, -+ [0][1][2][1][RTW89_ACMA][1][115] = 127, -+ [0][1][2][1][RTW89_ACMA][0][115] = 127, -+ [0][1][2][1][RTW89_CHILE][1][115] = 127, -+ [0][1][2][1][RTW89_QATAR][1][115] = 127, -+ [0][1][2][1][RTW89_QATAR][0][115] = 127, -+ [0][1][2][1][RTW89_UK][1][115] = 127, -+ [0][1][2][1][RTW89_UK][0][115] = 127, -+ [0][1][2][1][RTW89_FCC][1][117] = 127, -+ [0][1][2][1][RTW89_FCC][2][117] = 127, -+ [0][1][2][1][RTW89_ETSI][1][117] = 127, -+ [0][1][2][1][RTW89_ETSI][0][117] = 127, -+ [0][1][2][1][RTW89_MKK][1][117] = 127, -+ [0][1][2][1][RTW89_MKK][0][117] = 127, -+ [0][1][2][1][RTW89_IC][1][117] = 127, -+ [0][1][2][1][RTW89_KCC][1][117] = 127, -+ [0][1][2][1][RTW89_KCC][0][117] = 127, -+ [0][1][2][1][RTW89_ACMA][1][117] = 127, -+ [0][1][2][1][RTW89_ACMA][0][117] = 127, -+ [0][1][2][1][RTW89_CHILE][1][117] = 127, -+ [0][1][2][1][RTW89_QATAR][1][117] = 127, -+ [0][1][2][1][RTW89_QATAR][0][117] = 127, -+ [0][1][2][1][RTW89_UK][1][117] = 127, -+ [0][1][2][1][RTW89_UK][0][117] = 127, -+ [0][1][2][1][RTW89_FCC][1][119] = 127, -+ [0][1][2][1][RTW89_FCC][2][119] = 127, -+ [0][1][2][1][RTW89_ETSI][1][119] = 127, -+ [0][1][2][1][RTW89_ETSI][0][119] = 127, -+ [0][1][2][1][RTW89_MKK][1][119] = 127, -+ [0][1][2][1][RTW89_MKK][0][119] = 127, -+ [0][1][2][1][RTW89_IC][1][119] = 127, -+ [0][1][2][1][RTW89_KCC][1][119] = 127, -+ [0][1][2][1][RTW89_KCC][0][119] = 127, -+ [0][1][2][1][RTW89_ACMA][1][119] = 127, -+ [0][1][2][1][RTW89_ACMA][0][119] = 127, -+ [0][1][2][1][RTW89_CHILE][1][119] = 127, -+ [0][1][2][1][RTW89_QATAR][1][119] = 127, -+ [0][1][2][1][RTW89_QATAR][0][119] = 127, -+ [0][1][2][1][RTW89_UK][1][119] = 127, -+ [0][1][2][1][RTW89_UK][0][119] = 127, -+ [1][0][2][0][RTW89_FCC][1][1] = 34, -+ [1][0][2][0][RTW89_FCC][2][1] = 70, -+ [1][0][2][0][RTW89_ETSI][1][1] = 66, -+ [1][0][2][0][RTW89_ETSI][0][1] = 30, -+ [1][0][2][0][RTW89_MKK][1][1] = 62, -+ [1][0][2][0][RTW89_MKK][0][1] = 26, -+ [1][0][2][0][RTW89_IC][1][1] = 34, -+ [1][0][2][0][RTW89_KCC][1][1] = 40, -+ [1][0][2][0][RTW89_KCC][0][1] = 24, -+ [1][0][2][0][RTW89_ACMA][1][1] = 66, -+ [1][0][2][0][RTW89_ACMA][0][1] = 30, -+ [1][0][2][0][RTW89_CHILE][1][1] = 34, -+ [1][0][2][0][RTW89_QATAR][1][1] = 66, -+ [1][0][2][0][RTW89_QATAR][0][1] = 30, -+ [1][0][2][0][RTW89_UK][1][1] = 66, -+ [1][0][2][0][RTW89_UK][0][1] = 30, -+ [1][0][2][0][RTW89_FCC][1][5] = 34, -+ [1][0][2][0][RTW89_FCC][2][5] = 70, -+ [1][0][2][0][RTW89_ETSI][1][5] = 66, -+ [1][0][2][0][RTW89_ETSI][0][5] = 30, -+ [1][0][2][0][RTW89_MKK][1][5] = 62, -+ [1][0][2][0][RTW89_MKK][0][5] = 26, -+ [1][0][2][0][RTW89_IC][1][5] = 34, -+ [1][0][2][0][RTW89_KCC][1][5] = 40, -+ [1][0][2][0][RTW89_KCC][0][5] = 24, -+ [1][0][2][0][RTW89_ACMA][1][5] = 66, -+ [1][0][2][0][RTW89_ACMA][0][5] = 30, -+ [1][0][2][0][RTW89_CHILE][1][5] = 34, -+ [1][0][2][0][RTW89_QATAR][1][5] = 66, -+ [1][0][2][0][RTW89_QATAR][0][5] = 30, -+ [1][0][2][0][RTW89_UK][1][5] = 66, -+ [1][0][2][0][RTW89_UK][0][5] = 30, -+ [1][0][2][0][RTW89_FCC][1][9] = 34, -+ [1][0][2][0][RTW89_FCC][2][9] = 70, -+ [1][0][2][0][RTW89_ETSI][1][9] = 66, -+ [1][0][2][0][RTW89_ETSI][0][9] = 30, -+ [1][0][2][0][RTW89_MKK][1][9] = 62, -+ [1][0][2][0][RTW89_MKK][0][9] = 26, -+ [1][0][2][0][RTW89_IC][1][9] = 34, -+ [1][0][2][0][RTW89_KCC][1][9] = 40, -+ [1][0][2][0][RTW89_KCC][0][9] = 24, -+ [1][0][2][0][RTW89_ACMA][1][9] = 66, -+ [1][0][2][0][RTW89_ACMA][0][9] = 30, -+ [1][0][2][0][RTW89_CHILE][1][9] = 34, -+ [1][0][2][0][RTW89_QATAR][1][9] = 66, -+ [1][0][2][0][RTW89_QATAR][0][9] = 30, -+ [1][0][2][0][RTW89_UK][1][9] = 66, -+ [1][0][2][0][RTW89_UK][0][9] = 30, -+ [1][0][2][0][RTW89_FCC][1][13] = 34, -+ [1][0][2][0][RTW89_FCC][2][13] = 70, -+ [1][0][2][0][RTW89_ETSI][1][13] = 66, -+ [1][0][2][0][RTW89_ETSI][0][13] = 30, -+ [1][0][2][0][RTW89_MKK][1][13] = 62, -+ [1][0][2][0][RTW89_MKK][0][13] = 26, -+ [1][0][2][0][RTW89_IC][1][13] = 34, -+ [1][0][2][0][RTW89_KCC][1][13] = 40, -+ [1][0][2][0][RTW89_KCC][0][13] = 24, -+ [1][0][2][0][RTW89_ACMA][1][13] = 66, -+ [1][0][2][0][RTW89_ACMA][0][13] = 30, -+ [1][0][2][0][RTW89_CHILE][1][13] = 34, -+ [1][0][2][0][RTW89_QATAR][1][13] = 66, -+ [1][0][2][0][RTW89_QATAR][0][13] = 30, -+ [1][0][2][0][RTW89_UK][1][13] = 66, -+ [1][0][2][0][RTW89_UK][0][13] = 30, -+ [1][0][2][0][RTW89_FCC][1][16] = 34, -+ [1][0][2][0][RTW89_FCC][2][16] = 70, -+ [1][0][2][0][RTW89_ETSI][1][16] = 66, -+ [1][0][2][0][RTW89_ETSI][0][16] = 30, -+ [1][0][2][0][RTW89_MKK][1][16] = 62, -+ [1][0][2][0][RTW89_MKK][0][16] = 26, -+ [1][0][2][0][RTW89_IC][1][16] = 34, -+ [1][0][2][0][RTW89_KCC][1][16] = 40, -+ [1][0][2][0][RTW89_KCC][0][16] = 24, -+ [1][0][2][0][RTW89_ACMA][1][16] = 66, -+ [1][0][2][0][RTW89_ACMA][0][16] = 30, -+ [1][0][2][0][RTW89_CHILE][1][16] = 34, -+ [1][0][2][0][RTW89_QATAR][1][16] = 66, -+ [1][0][2][0][RTW89_QATAR][0][16] = 30, -+ [1][0][2][0][RTW89_UK][1][16] = 66, -+ [1][0][2][0][RTW89_UK][0][16] = 30, -+ [1][0][2][0][RTW89_FCC][1][20] = 34, -+ [1][0][2][0][RTW89_FCC][2][20] = 70, -+ [1][0][2][0][RTW89_ETSI][1][20] = 66, -+ [1][0][2][0][RTW89_ETSI][0][20] = 30, -+ [1][0][2][0][RTW89_MKK][1][20] = 62, -+ [1][0][2][0][RTW89_MKK][0][20] = 26, -+ [1][0][2][0][RTW89_IC][1][20] = 34, -+ [1][0][2][0][RTW89_KCC][1][20] = 40, -+ [1][0][2][0][RTW89_KCC][0][20] = 24, -+ [1][0][2][0][RTW89_ACMA][1][20] = 66, -+ [1][0][2][0][RTW89_ACMA][0][20] = 30, -+ [1][0][2][0][RTW89_CHILE][1][20] = 34, -+ [1][0][2][0][RTW89_QATAR][1][20] = 66, -+ [1][0][2][0][RTW89_QATAR][0][20] = 30, -+ [1][0][2][0][RTW89_UK][1][20] = 66, -+ [1][0][2][0][RTW89_UK][0][20] = 30, -+ [1][0][2][0][RTW89_FCC][1][24] = 36, -+ [1][0][2][0][RTW89_FCC][2][24] = 70, -+ [1][0][2][0][RTW89_ETSI][1][24] = 66, -+ [1][0][2][0][RTW89_ETSI][0][24] = 30, -+ [1][0][2][0][RTW89_MKK][1][24] = 64, -+ [1][0][2][0][RTW89_MKK][0][24] = 28, -+ [1][0][2][0][RTW89_IC][1][24] = 36, -+ [1][0][2][0][RTW89_KCC][1][24] = 40, -+ [1][0][2][0][RTW89_KCC][0][24] = 26, -+ [1][0][2][0][RTW89_ACMA][1][24] = 66, -+ [1][0][2][0][RTW89_ACMA][0][24] = 30, -+ [1][0][2][0][RTW89_CHILE][1][24] = 36, -+ [1][0][2][0][RTW89_QATAR][1][24] = 66, -+ [1][0][2][0][RTW89_QATAR][0][24] = 30, -+ [1][0][2][0][RTW89_UK][1][24] = 66, -+ [1][0][2][0][RTW89_UK][0][24] = 30, -+ [1][0][2][0][RTW89_FCC][1][28] = 34, -+ [1][0][2][0][RTW89_FCC][2][28] = 70, -+ [1][0][2][0][RTW89_ETSI][1][28] = 66, -+ [1][0][2][0][RTW89_ETSI][0][28] = 30, -+ [1][0][2][0][RTW89_MKK][1][28] = 64, -+ [1][0][2][0][RTW89_MKK][0][28] = 26, -+ [1][0][2][0][RTW89_IC][1][28] = 34, -+ [1][0][2][0][RTW89_KCC][1][28] = 40, -+ [1][0][2][0][RTW89_KCC][0][28] = 26, -+ [1][0][2][0][RTW89_ACMA][1][28] = 66, -+ [1][0][2][0][RTW89_ACMA][0][28] = 30, -+ [1][0][2][0][RTW89_CHILE][1][28] = 34, -+ [1][0][2][0][RTW89_QATAR][1][28] = 66, -+ [1][0][2][0][RTW89_QATAR][0][28] = 30, -+ [1][0][2][0][RTW89_UK][1][28] = 66, -+ [1][0][2][0][RTW89_UK][0][28] = 30, -+ [1][0][2][0][RTW89_FCC][1][31] = 34, -+ [1][0][2][0][RTW89_FCC][2][31] = 70, -+ [1][0][2][0][RTW89_ETSI][1][31] = 66, -+ [1][0][2][0][RTW89_ETSI][0][31] = 30, -+ [1][0][2][0][RTW89_MKK][1][31] = 64, -+ [1][0][2][0][RTW89_MKK][0][31] = 26, -+ [1][0][2][0][RTW89_IC][1][31] = 34, -+ [1][0][2][0][RTW89_KCC][1][31] = 40, -+ [1][0][2][0][RTW89_KCC][0][31] = 26, -+ [1][0][2][0][RTW89_ACMA][1][31] = 66, -+ [1][0][2][0][RTW89_ACMA][0][31] = 30, -+ [1][0][2][0][RTW89_CHILE][1][31] = 34, -+ [1][0][2][0][RTW89_QATAR][1][31] = 66, -+ [1][0][2][0][RTW89_QATAR][0][31] = 30, -+ [1][0][2][0][RTW89_UK][1][31] = 66, -+ [1][0][2][0][RTW89_UK][0][31] = 30, -+ [1][0][2][0][RTW89_FCC][1][35] = 34, -+ [1][0][2][0][RTW89_FCC][2][35] = 70, -+ [1][0][2][0][RTW89_ETSI][1][35] = 66, -+ [1][0][2][0][RTW89_ETSI][0][35] = 30, -+ [1][0][2][0][RTW89_MKK][1][35] = 64, -+ [1][0][2][0][RTW89_MKK][0][35] = 26, -+ [1][0][2][0][RTW89_IC][1][35] = 34, -+ [1][0][2][0][RTW89_KCC][1][35] = 40, -+ [1][0][2][0][RTW89_KCC][0][35] = 26, -+ [1][0][2][0][RTW89_ACMA][1][35] = 66, -+ [1][0][2][0][RTW89_ACMA][0][35] = 30, -+ [1][0][2][0][RTW89_CHILE][1][35] = 34, -+ [1][0][2][0][RTW89_QATAR][1][35] = 66, -+ [1][0][2][0][RTW89_QATAR][0][35] = 30, -+ [1][0][2][0][RTW89_UK][1][35] = 66, -+ [1][0][2][0][RTW89_UK][0][35] = 30, -+ [1][0][2][0][RTW89_FCC][1][39] = 34, -+ [1][0][2][0][RTW89_FCC][2][39] = 70, -+ [1][0][2][0][RTW89_ETSI][1][39] = 66, -+ [1][0][2][0][RTW89_ETSI][0][39] = 30, -+ [1][0][2][0][RTW89_MKK][1][39] = 64, -+ [1][0][2][0][RTW89_MKK][0][39] = 26, -+ [1][0][2][0][RTW89_IC][1][39] = 34, -+ [1][0][2][0][RTW89_KCC][1][39] = 40, -+ [1][0][2][0][RTW89_KCC][0][39] = 26, -+ [1][0][2][0][RTW89_ACMA][1][39] = 66, -+ [1][0][2][0][RTW89_ACMA][0][39] = 30, -+ [1][0][2][0][RTW89_CHILE][1][39] = 34, -+ [1][0][2][0][RTW89_QATAR][1][39] = 66, -+ [1][0][2][0][RTW89_QATAR][0][39] = 30, -+ [1][0][2][0][RTW89_UK][1][39] = 66, -+ [1][0][2][0][RTW89_UK][0][39] = 30, -+ [1][0][2][0][RTW89_FCC][1][43] = 34, -+ [1][0][2][0][RTW89_FCC][2][43] = 70, -+ [1][0][2][0][RTW89_ETSI][1][43] = 66, -+ [1][0][2][0][RTW89_ETSI][0][43] = 30, -+ [1][0][2][0][RTW89_MKK][1][43] = 64, -+ [1][0][2][0][RTW89_MKK][0][43] = 26, -+ [1][0][2][0][RTW89_IC][1][43] = 34, -+ [1][0][2][0][RTW89_KCC][1][43] = 40, -+ [1][0][2][0][RTW89_KCC][0][43] = 26, -+ [1][0][2][0][RTW89_ACMA][1][43] = 66, -+ [1][0][2][0][RTW89_ACMA][0][43] = 30, -+ [1][0][2][0][RTW89_CHILE][1][43] = 34, -+ [1][0][2][0][RTW89_QATAR][1][43] = 66, -+ [1][0][2][0][RTW89_QATAR][0][43] = 30, -+ [1][0][2][0][RTW89_UK][1][43] = 66, -+ [1][0][2][0][RTW89_UK][0][43] = 30, -+ [1][0][2][0][RTW89_FCC][1][46] = 34, -+ [1][0][2][0][RTW89_FCC][2][46] = 127, -+ [1][0][2][0][RTW89_ETSI][1][46] = 127, -+ [1][0][2][0][RTW89_ETSI][0][46] = 127, -+ [1][0][2][0][RTW89_MKK][1][46] = 127, -+ [1][0][2][0][RTW89_MKK][0][46] = 127, -+ [1][0][2][0][RTW89_IC][1][46] = 34, -+ [1][0][2][0][RTW89_KCC][1][46] = 40, -+ [1][0][2][0][RTW89_KCC][0][46] = 127, -+ [1][0][2][0][RTW89_ACMA][1][46] = 127, -+ [1][0][2][0][RTW89_ACMA][0][46] = 127, -+ [1][0][2][0][RTW89_CHILE][1][46] = 34, -+ [1][0][2][0][RTW89_QATAR][1][46] = 127, -+ [1][0][2][0][RTW89_QATAR][0][46] = 127, -+ [1][0][2][0][RTW89_UK][1][46] = 127, -+ [1][0][2][0][RTW89_UK][0][46] = 127, -+ [1][0][2][0][RTW89_FCC][1][50] = 34, -+ [1][0][2][0][RTW89_FCC][2][50] = 127, -+ [1][0][2][0][RTW89_ETSI][1][50] = 127, -+ [1][0][2][0][RTW89_ETSI][0][50] = 127, -+ [1][0][2][0][RTW89_MKK][1][50] = 127, -+ [1][0][2][0][RTW89_MKK][0][50] = 127, -+ [1][0][2][0][RTW89_IC][1][50] = 34, -+ [1][0][2][0][RTW89_KCC][1][50] = 40, -+ [1][0][2][0][RTW89_KCC][0][50] = 127, -+ [1][0][2][0][RTW89_ACMA][1][50] = 127, -+ [1][0][2][0][RTW89_ACMA][0][50] = 127, -+ [1][0][2][0][RTW89_CHILE][1][50] = 34, -+ [1][0][2][0][RTW89_QATAR][1][50] = 127, -+ [1][0][2][0][RTW89_QATAR][0][50] = 127, -+ [1][0][2][0][RTW89_UK][1][50] = 127, -+ [1][0][2][0][RTW89_UK][0][50] = 127, -+ [1][0][2][0][RTW89_FCC][1][54] = 36, -+ [1][0][2][0][RTW89_FCC][2][54] = 127, -+ [1][0][2][0][RTW89_ETSI][1][54] = 127, -+ [1][0][2][0][RTW89_ETSI][0][54] = 127, -+ [1][0][2][0][RTW89_MKK][1][54] = 127, -+ [1][0][2][0][RTW89_MKK][0][54] = 127, -+ [1][0][2][0][RTW89_IC][1][54] = 36, -+ [1][0][2][0][RTW89_KCC][1][54] = 40, -+ [1][0][2][0][RTW89_KCC][0][54] = 127, -+ [1][0][2][0][RTW89_ACMA][1][54] = 127, -+ [1][0][2][0][RTW89_ACMA][0][54] = 127, -+ [1][0][2][0][RTW89_CHILE][1][54] = 36, -+ [1][0][2][0][RTW89_QATAR][1][54] = 127, -+ [1][0][2][0][RTW89_QATAR][0][54] = 127, -+ [1][0][2][0][RTW89_UK][1][54] = 127, -+ [1][0][2][0][RTW89_UK][0][54] = 127, -+ [1][0][2][0][RTW89_FCC][1][58] = 36, -+ [1][0][2][0][RTW89_FCC][2][58] = 66, -+ [1][0][2][0][RTW89_ETSI][1][58] = 127, -+ [1][0][2][0][RTW89_ETSI][0][58] = 127, -+ [1][0][2][0][RTW89_MKK][1][58] = 127, -+ [1][0][2][0][RTW89_MKK][0][58] = 127, -+ [1][0][2][0][RTW89_IC][1][58] = 36, -+ [1][0][2][0][RTW89_KCC][1][58] = 40, -+ [1][0][2][0][RTW89_KCC][0][58] = 127, -+ [1][0][2][0][RTW89_ACMA][1][58] = 127, -+ [1][0][2][0][RTW89_ACMA][0][58] = 127, -+ [1][0][2][0][RTW89_CHILE][1][58] = 36, -+ [1][0][2][0][RTW89_QATAR][1][58] = 127, -+ [1][0][2][0][RTW89_QATAR][0][58] = 127, -+ [1][0][2][0][RTW89_UK][1][58] = 127, -+ [1][0][2][0][RTW89_UK][0][58] = 127, -+ [1][0][2][0][RTW89_FCC][1][61] = 34, -+ [1][0][2][0][RTW89_FCC][2][61] = 66, -+ [1][0][2][0][RTW89_ETSI][1][61] = 127, -+ [1][0][2][0][RTW89_ETSI][0][61] = 127, -+ [1][0][2][0][RTW89_MKK][1][61] = 127, -+ [1][0][2][0][RTW89_MKK][0][61] = 127, -+ [1][0][2][0][RTW89_IC][1][61] = 34, -+ [1][0][2][0][RTW89_KCC][1][61] = 40, -+ [1][0][2][0][RTW89_KCC][0][61] = 127, -+ [1][0][2][0][RTW89_ACMA][1][61] = 127, -+ [1][0][2][0][RTW89_ACMA][0][61] = 127, -+ [1][0][2][0][RTW89_CHILE][1][61] = 34, -+ [1][0][2][0][RTW89_QATAR][1][61] = 127, -+ [1][0][2][0][RTW89_QATAR][0][61] = 127, -+ [1][0][2][0][RTW89_UK][1][61] = 127, -+ [1][0][2][0][RTW89_UK][0][61] = 127, -+ [1][0][2][0][RTW89_FCC][1][65] = 34, -+ [1][0][2][0][RTW89_FCC][2][65] = 66, -+ [1][0][2][0][RTW89_ETSI][1][65] = 127, -+ [1][0][2][0][RTW89_ETSI][0][65] = 127, -+ [1][0][2][0][RTW89_MKK][1][65] = 127, -+ [1][0][2][0][RTW89_MKK][0][65] = 127, -+ [1][0][2][0][RTW89_IC][1][65] = 34, -+ [1][0][2][0][RTW89_KCC][1][65] = 40, -+ [1][0][2][0][RTW89_KCC][0][65] = 127, -+ [1][0][2][0][RTW89_ACMA][1][65] = 127, -+ [1][0][2][0][RTW89_ACMA][0][65] = 127, -+ [1][0][2][0][RTW89_CHILE][1][65] = 34, -+ [1][0][2][0][RTW89_QATAR][1][65] = 127, -+ [1][0][2][0][RTW89_QATAR][0][65] = 127, -+ [1][0][2][0][RTW89_UK][1][65] = 127, -+ [1][0][2][0][RTW89_UK][0][65] = 127, -+ [1][0][2][0][RTW89_FCC][1][69] = 34, -+ [1][0][2][0][RTW89_FCC][2][69] = 66, -+ [1][0][2][0][RTW89_ETSI][1][69] = 127, -+ [1][0][2][0][RTW89_ETSI][0][69] = 127, -+ [1][0][2][0][RTW89_MKK][1][69] = 127, -+ [1][0][2][0][RTW89_MKK][0][69] = 127, -+ [1][0][2][0][RTW89_IC][1][69] = 34, -+ [1][0][2][0][RTW89_KCC][1][69] = 40, -+ [1][0][2][0][RTW89_KCC][0][69] = 127, -+ [1][0][2][0][RTW89_ACMA][1][69] = 127, -+ [1][0][2][0][RTW89_ACMA][0][69] = 127, -+ [1][0][2][0][RTW89_CHILE][1][69] = 34, -+ [1][0][2][0][RTW89_QATAR][1][69] = 127, -+ [1][0][2][0][RTW89_QATAR][0][69] = 127, -+ [1][0][2][0][RTW89_UK][1][69] = 127, -+ [1][0][2][0][RTW89_UK][0][69] = 127, -+ [1][0][2][0][RTW89_FCC][1][73] = 34, -+ [1][0][2][0][RTW89_FCC][2][73] = 66, -+ [1][0][2][0][RTW89_ETSI][1][73] = 127, -+ [1][0][2][0][RTW89_ETSI][0][73] = 127, -+ [1][0][2][0][RTW89_MKK][1][73] = 127, -+ [1][0][2][0][RTW89_MKK][0][73] = 127, -+ [1][0][2][0][RTW89_IC][1][73] = 34, -+ [1][0][2][0][RTW89_KCC][1][73] = 40, -+ [1][0][2][0][RTW89_KCC][0][73] = 127, -+ [1][0][2][0][RTW89_ACMA][1][73] = 127, -+ [1][0][2][0][RTW89_ACMA][0][73] = 127, -+ [1][0][2][0][RTW89_CHILE][1][73] = 34, -+ [1][0][2][0][RTW89_QATAR][1][73] = 127, -+ [1][0][2][0][RTW89_QATAR][0][73] = 127, -+ [1][0][2][0][RTW89_UK][1][73] = 127, -+ [1][0][2][0][RTW89_UK][0][73] = 127, -+ [1][0][2][0][RTW89_FCC][1][76] = 34, -+ [1][0][2][0][RTW89_FCC][2][76] = 66, -+ [1][0][2][0][RTW89_ETSI][1][76] = 127, -+ [1][0][2][0][RTW89_ETSI][0][76] = 127, -+ [1][0][2][0][RTW89_MKK][1][76] = 127, -+ [1][0][2][0][RTW89_MKK][0][76] = 127, -+ [1][0][2][0][RTW89_IC][1][76] = 34, -+ [1][0][2][0][RTW89_KCC][1][76] = 40, -+ [1][0][2][0][RTW89_KCC][0][76] = 127, -+ [1][0][2][0][RTW89_ACMA][1][76] = 127, -+ [1][0][2][0][RTW89_ACMA][0][76] = 127, -+ [1][0][2][0][RTW89_CHILE][1][76] = 34, -+ [1][0][2][0][RTW89_QATAR][1][76] = 127, -+ [1][0][2][0][RTW89_QATAR][0][76] = 127, -+ [1][0][2][0][RTW89_UK][1][76] = 127, -+ [1][0][2][0][RTW89_UK][0][76] = 127, -+ [1][0][2][0][RTW89_FCC][1][80] = 34, -+ [1][0][2][0][RTW89_FCC][2][80] = 66, -+ [1][0][2][0][RTW89_ETSI][1][80] = 127, -+ [1][0][2][0][RTW89_ETSI][0][80] = 127, -+ [1][0][2][0][RTW89_MKK][1][80] = 127, -+ [1][0][2][0][RTW89_MKK][0][80] = 127, -+ [1][0][2][0][RTW89_IC][1][80] = 34, -+ [1][0][2][0][RTW89_KCC][1][80] = 42, -+ [1][0][2][0][RTW89_KCC][0][80] = 127, -+ [1][0][2][0][RTW89_ACMA][1][80] = 127, -+ [1][0][2][0][RTW89_ACMA][0][80] = 127, -+ [1][0][2][0][RTW89_CHILE][1][80] = 34, -+ [1][0][2][0][RTW89_QATAR][1][80] = 127, -+ [1][0][2][0][RTW89_QATAR][0][80] = 127, -+ [1][0][2][0][RTW89_UK][1][80] = 127, -+ [1][0][2][0][RTW89_UK][0][80] = 127, -+ [1][0][2][0][RTW89_FCC][1][84] = 34, -+ [1][0][2][0][RTW89_FCC][2][84] = 66, -+ [1][0][2][0][RTW89_ETSI][1][84] = 127, -+ [1][0][2][0][RTW89_ETSI][0][84] = 127, -+ [1][0][2][0][RTW89_MKK][1][84] = 127, -+ [1][0][2][0][RTW89_MKK][0][84] = 127, -+ [1][0][2][0][RTW89_IC][1][84] = 34, -+ [1][0][2][0][RTW89_KCC][1][84] = 42, -+ [1][0][2][0][RTW89_KCC][0][84] = 127, -+ [1][0][2][0][RTW89_ACMA][1][84] = 127, -+ [1][0][2][0][RTW89_ACMA][0][84] = 127, -+ [1][0][2][0][RTW89_CHILE][1][84] = 34, -+ [1][0][2][0][RTW89_QATAR][1][84] = 127, -+ [1][0][2][0][RTW89_QATAR][0][84] = 127, -+ [1][0][2][0][RTW89_UK][1][84] = 127, -+ [1][0][2][0][RTW89_UK][0][84] = 127, -+ [1][0][2][0][RTW89_FCC][1][88] = 34, -+ [1][0][2][0][RTW89_FCC][2][88] = 127, -+ [1][0][2][0][RTW89_ETSI][1][88] = 127, -+ [1][0][2][0][RTW89_ETSI][0][88] = 127, -+ [1][0][2][0][RTW89_MKK][1][88] = 127, -+ [1][0][2][0][RTW89_MKK][0][88] = 127, -+ [1][0][2][0][RTW89_IC][1][88] = 34, -+ [1][0][2][0][RTW89_KCC][1][88] = 42, -+ [1][0][2][0][RTW89_KCC][0][88] = 127, -+ [1][0][2][0][RTW89_ACMA][1][88] = 127, -+ [1][0][2][0][RTW89_ACMA][0][88] = 127, -+ [1][0][2][0][RTW89_CHILE][1][88] = 34, -+ [1][0][2][0][RTW89_QATAR][1][88] = 127, -+ [1][0][2][0][RTW89_QATAR][0][88] = 127, -+ [1][0][2][0][RTW89_UK][1][88] = 127, -+ [1][0][2][0][RTW89_UK][0][88] = 127, -+ [1][0][2][0][RTW89_FCC][1][91] = 36, -+ [1][0][2][0][RTW89_FCC][2][91] = 127, -+ [1][0][2][0][RTW89_ETSI][1][91] = 127, -+ [1][0][2][0][RTW89_ETSI][0][91] = 127, -+ [1][0][2][0][RTW89_MKK][1][91] = 127, -+ [1][0][2][0][RTW89_MKK][0][91] = 127, -+ [1][0][2][0][RTW89_IC][1][91] = 36, -+ [1][0][2][0][RTW89_KCC][1][91] = 42, -+ [1][0][2][0][RTW89_KCC][0][91] = 127, -+ [1][0][2][0][RTW89_ACMA][1][91] = 127, -+ [1][0][2][0][RTW89_ACMA][0][91] = 127, -+ [1][0][2][0][RTW89_CHILE][1][91] = 36, -+ [1][0][2][0][RTW89_QATAR][1][91] = 127, -+ [1][0][2][0][RTW89_QATAR][0][91] = 127, -+ [1][0][2][0][RTW89_UK][1][91] = 127, -+ [1][0][2][0][RTW89_UK][0][91] = 127, -+ [1][0][2][0][RTW89_FCC][1][95] = 34, -+ [1][0][2][0][RTW89_FCC][2][95] = 127, -+ [1][0][2][0][RTW89_ETSI][1][95] = 127, -+ [1][0][2][0][RTW89_ETSI][0][95] = 127, -+ [1][0][2][0][RTW89_MKK][1][95] = 127, -+ [1][0][2][0][RTW89_MKK][0][95] = 127, -+ [1][0][2][0][RTW89_IC][1][95] = 34, -+ [1][0][2][0][RTW89_KCC][1][95] = 42, -+ [1][0][2][0][RTW89_KCC][0][95] = 127, -+ [1][0][2][0][RTW89_ACMA][1][95] = 127, -+ [1][0][2][0][RTW89_ACMA][0][95] = 127, -+ [1][0][2][0][RTW89_CHILE][1][95] = 34, -+ [1][0][2][0][RTW89_QATAR][1][95] = 127, -+ [1][0][2][0][RTW89_QATAR][0][95] = 127, -+ [1][0][2][0][RTW89_UK][1][95] = 127, -+ [1][0][2][0][RTW89_UK][0][95] = 127, -+ [1][0][2][0][RTW89_FCC][1][99] = 34, -+ [1][0][2][0][RTW89_FCC][2][99] = 127, -+ [1][0][2][0][RTW89_ETSI][1][99] = 127, -+ [1][0][2][0][RTW89_ETSI][0][99] = 127, -+ [1][0][2][0][RTW89_MKK][1][99] = 127, -+ [1][0][2][0][RTW89_MKK][0][99] = 127, -+ [1][0][2][0][RTW89_IC][1][99] = 34, -+ [1][0][2][0][RTW89_KCC][1][99] = 42, -+ [1][0][2][0][RTW89_KCC][0][99] = 127, -+ [1][0][2][0][RTW89_ACMA][1][99] = 127, -+ [1][0][2][0][RTW89_ACMA][0][99] = 127, -+ [1][0][2][0][RTW89_CHILE][1][99] = 34, -+ [1][0][2][0][RTW89_QATAR][1][99] = 127, -+ [1][0][2][0][RTW89_QATAR][0][99] = 127, -+ [1][0][2][0][RTW89_UK][1][99] = 127, -+ [1][0][2][0][RTW89_UK][0][99] = 127, -+ [1][0][2][0][RTW89_FCC][1][103] = 34, -+ [1][0][2][0][RTW89_FCC][2][103] = 127, -+ [1][0][2][0][RTW89_ETSI][1][103] = 127, -+ [1][0][2][0][RTW89_ETSI][0][103] = 127, -+ [1][0][2][0][RTW89_MKK][1][103] = 127, -+ [1][0][2][0][RTW89_MKK][0][103] = 127, -+ [1][0][2][0][RTW89_IC][1][103] = 34, -+ [1][0][2][0][RTW89_KCC][1][103] = 42, -+ [1][0][2][0][RTW89_KCC][0][103] = 127, -+ [1][0][2][0][RTW89_ACMA][1][103] = 127, -+ [1][0][2][0][RTW89_ACMA][0][103] = 127, -+ [1][0][2][0][RTW89_CHILE][1][103] = 34, -+ [1][0][2][0][RTW89_QATAR][1][103] = 127, -+ [1][0][2][0][RTW89_QATAR][0][103] = 127, -+ [1][0][2][0][RTW89_UK][1][103] = 127, -+ [1][0][2][0][RTW89_UK][0][103] = 127, -+ [1][0][2][0][RTW89_FCC][1][106] = 36, -+ [1][0][2][0][RTW89_FCC][2][106] = 127, -+ [1][0][2][0][RTW89_ETSI][1][106] = 127, -+ [1][0][2][0][RTW89_ETSI][0][106] = 127, -+ [1][0][2][0][RTW89_MKK][1][106] = 127, -+ [1][0][2][0][RTW89_MKK][0][106] = 127, -+ [1][0][2][0][RTW89_IC][1][106] = 36, -+ [1][0][2][0][RTW89_KCC][1][106] = 42, -+ [1][0][2][0][RTW89_KCC][0][106] = 127, -+ [1][0][2][0][RTW89_ACMA][1][106] = 127, -+ [1][0][2][0][RTW89_ACMA][0][106] = 127, -+ [1][0][2][0][RTW89_CHILE][1][106] = 36, -+ [1][0][2][0][RTW89_QATAR][1][106] = 127, -+ [1][0][2][0][RTW89_QATAR][0][106] = 127, -+ [1][0][2][0][RTW89_UK][1][106] = 127, -+ [1][0][2][0][RTW89_UK][0][106] = 127, -+ [1][0][2][0][RTW89_FCC][1][110] = 127, -+ [1][0][2][0][RTW89_FCC][2][110] = 127, -+ [1][0][2][0][RTW89_ETSI][1][110] = 127, -+ [1][0][2][0][RTW89_ETSI][0][110] = 127, -+ [1][0][2][0][RTW89_MKK][1][110] = 127, -+ [1][0][2][0][RTW89_MKK][0][110] = 127, -+ [1][0][2][0][RTW89_IC][1][110] = 127, -+ [1][0][2][0][RTW89_KCC][1][110] = 127, -+ [1][0][2][0][RTW89_KCC][0][110] = 127, -+ [1][0][2][0][RTW89_ACMA][1][110] = 127, -+ [1][0][2][0][RTW89_ACMA][0][110] = 127, -+ [1][0][2][0][RTW89_CHILE][1][110] = 127, -+ [1][0][2][0][RTW89_QATAR][1][110] = 127, -+ [1][0][2][0][RTW89_QATAR][0][110] = 127, -+ [1][0][2][0][RTW89_UK][1][110] = 127, -+ [1][0][2][0][RTW89_UK][0][110] = 127, -+ [1][0][2][0][RTW89_FCC][1][114] = 127, -+ [1][0][2][0][RTW89_FCC][2][114] = 127, -+ [1][0][2][0][RTW89_ETSI][1][114] = 127, -+ [1][0][2][0][RTW89_ETSI][0][114] = 127, -+ [1][0][2][0][RTW89_MKK][1][114] = 127, -+ [1][0][2][0][RTW89_MKK][0][114] = 127, -+ [1][0][2][0][RTW89_IC][1][114] = 127, -+ [1][0][2][0][RTW89_KCC][1][114] = 127, -+ [1][0][2][0][RTW89_KCC][0][114] = 127, -+ [1][0][2][0][RTW89_ACMA][1][114] = 127, -+ [1][0][2][0][RTW89_ACMA][0][114] = 127, -+ [1][0][2][0][RTW89_CHILE][1][114] = 127, -+ [1][0][2][0][RTW89_QATAR][1][114] = 127, -+ [1][0][2][0][RTW89_QATAR][0][114] = 127, -+ [1][0][2][0][RTW89_UK][1][114] = 127, -+ [1][0][2][0][RTW89_UK][0][114] = 127, -+ [1][0][2][0][RTW89_FCC][1][118] = 127, -+ [1][0][2][0][RTW89_FCC][2][118] = 127, -+ [1][0][2][0][RTW89_ETSI][1][118] = 127, -+ [1][0][2][0][RTW89_ETSI][0][118] = 127, -+ [1][0][2][0][RTW89_MKK][1][118] = 127, -+ [1][0][2][0][RTW89_MKK][0][118] = 127, -+ [1][0][2][0][RTW89_IC][1][118] = 127, -+ [1][0][2][0][RTW89_KCC][1][118] = 127, -+ [1][0][2][0][RTW89_KCC][0][118] = 127, -+ [1][0][2][0][RTW89_ACMA][1][118] = 127, -+ [1][0][2][0][RTW89_ACMA][0][118] = 127, -+ [1][0][2][0][RTW89_CHILE][1][118] = 127, -+ [1][0][2][0][RTW89_QATAR][1][118] = 127, -+ [1][0][2][0][RTW89_QATAR][0][118] = 127, -+ [1][0][2][0][RTW89_UK][1][118] = 127, -+ [1][0][2][0][RTW89_UK][0][118] = 127, -+ [1][1][2][0][RTW89_FCC][1][1] = 10, -+ [1][1][2][0][RTW89_FCC][2][1] = 58, -+ [1][1][2][0][RTW89_ETSI][1][1] = 54, -+ [1][1][2][0][RTW89_ETSI][0][1] = 18, -+ [1][1][2][0][RTW89_MKK][1][1] = 52, -+ [1][1][2][0][RTW89_MKK][0][1] = 12, -+ [1][1][2][0][RTW89_IC][1][1] = 10, -+ [1][1][2][0][RTW89_KCC][1][1] = 28, -+ [1][1][2][0][RTW89_KCC][0][1] = 12, -+ [1][1][2][0][RTW89_ACMA][1][1] = 54, -+ [1][1][2][0][RTW89_ACMA][0][1] = 18, -+ [1][1][2][0][RTW89_CHILE][1][1] = 10, -+ [1][1][2][0][RTW89_QATAR][1][1] = 54, -+ [1][1][2][0][RTW89_QATAR][0][1] = 18, -+ [1][1][2][0][RTW89_UK][1][1] = 54, -+ [1][1][2][0][RTW89_UK][0][1] = 18, -+ [1][1][2][0][RTW89_FCC][1][5] = 10, -+ [1][1][2][0][RTW89_FCC][2][5] = 58, -+ [1][1][2][0][RTW89_ETSI][1][5] = 54, -+ [1][1][2][0][RTW89_ETSI][0][5] = 16, -+ [1][1][2][0][RTW89_MKK][1][5] = 52, -+ [1][1][2][0][RTW89_MKK][0][5] = 12, -+ [1][1][2][0][RTW89_IC][1][5] = 10, -+ [1][1][2][0][RTW89_KCC][1][5] = 28, -+ [1][1][2][0][RTW89_KCC][0][5] = 12, -+ [1][1][2][0][RTW89_ACMA][1][5] = 54, -+ [1][1][2][0][RTW89_ACMA][0][5] = 16, -+ [1][1][2][0][RTW89_CHILE][1][5] = 10, -+ [1][1][2][0][RTW89_QATAR][1][5] = 54, -+ [1][1][2][0][RTW89_QATAR][0][5] = 16, -+ [1][1][2][0][RTW89_UK][1][5] = 54, -+ [1][1][2][0][RTW89_UK][0][5] = 16, -+ [1][1][2][0][RTW89_FCC][1][9] = 10, -+ [1][1][2][0][RTW89_FCC][2][9] = 58, -+ [1][1][2][0][RTW89_ETSI][1][9] = 54, -+ [1][1][2][0][RTW89_ETSI][0][9] = 16, -+ [1][1][2][0][RTW89_MKK][1][9] = 52, -+ [1][1][2][0][RTW89_MKK][0][9] = 12, -+ [1][1][2][0][RTW89_IC][1][9] = 10, -+ [1][1][2][0][RTW89_KCC][1][9] = 28, -+ [1][1][2][0][RTW89_KCC][0][9] = 12, -+ [1][1][2][0][RTW89_ACMA][1][9] = 54, -+ [1][1][2][0][RTW89_ACMA][0][9] = 16, -+ [1][1][2][0][RTW89_CHILE][1][9] = 10, -+ [1][1][2][0][RTW89_QATAR][1][9] = 54, -+ [1][1][2][0][RTW89_QATAR][0][9] = 16, -+ [1][1][2][0][RTW89_UK][1][9] = 54, -+ [1][1][2][0][RTW89_UK][0][9] = 16, -+ [1][1][2][0][RTW89_FCC][1][13] = 10, -+ [1][1][2][0][RTW89_FCC][2][13] = 58, -+ [1][1][2][0][RTW89_ETSI][1][13] = 54, -+ [1][1][2][0][RTW89_ETSI][0][13] = 16, -+ [1][1][2][0][RTW89_MKK][1][13] = 52, -+ [1][1][2][0][RTW89_MKK][0][13] = 12, -+ [1][1][2][0][RTW89_IC][1][13] = 10, -+ [1][1][2][0][RTW89_KCC][1][13] = 28, -+ [1][1][2][0][RTW89_KCC][0][13] = 12, -+ [1][1][2][0][RTW89_ACMA][1][13] = 54, -+ [1][1][2][0][RTW89_ACMA][0][13] = 16, -+ [1][1][2][0][RTW89_CHILE][1][13] = 10, -+ [1][1][2][0][RTW89_QATAR][1][13] = 54, -+ [1][1][2][0][RTW89_QATAR][0][13] = 16, -+ [1][1][2][0][RTW89_UK][1][13] = 54, -+ [1][1][2][0][RTW89_UK][0][13] = 16, -+ [1][1][2][0][RTW89_FCC][1][16] = 10, -+ [1][1][2][0][RTW89_FCC][2][16] = 58, -+ [1][1][2][0][RTW89_ETSI][1][16] = 54, -+ [1][1][2][0][RTW89_ETSI][0][16] = 16, -+ [1][1][2][0][RTW89_MKK][1][16] = 52, -+ [1][1][2][0][RTW89_MKK][0][16] = 12, -+ [1][1][2][0][RTW89_IC][1][16] = 10, -+ [1][1][2][0][RTW89_KCC][1][16] = 28, -+ [1][1][2][0][RTW89_KCC][0][16] = 12, -+ [1][1][2][0][RTW89_ACMA][1][16] = 54, -+ [1][1][2][0][RTW89_ACMA][0][16] = 16, -+ [1][1][2][0][RTW89_CHILE][1][16] = 10, -+ [1][1][2][0][RTW89_QATAR][1][16] = 54, -+ [1][1][2][0][RTW89_QATAR][0][16] = 16, -+ [1][1][2][0][RTW89_UK][1][16] = 54, -+ [1][1][2][0][RTW89_UK][0][16] = 16, -+ [1][1][2][0][RTW89_FCC][1][20] = 10, -+ [1][1][2][0][RTW89_FCC][2][20] = 58, -+ [1][1][2][0][RTW89_ETSI][1][20] = 54, -+ [1][1][2][0][RTW89_ETSI][0][20] = 16, -+ [1][1][2][0][RTW89_MKK][1][20] = 52, -+ [1][1][2][0][RTW89_MKK][0][20] = 12, -+ [1][1][2][0][RTW89_IC][1][20] = 10, -+ [1][1][2][0][RTW89_KCC][1][20] = 28, -+ [1][1][2][0][RTW89_KCC][0][20] = 12, -+ [1][1][2][0][RTW89_ACMA][1][20] = 54, -+ [1][1][2][0][RTW89_ACMA][0][20] = 16, -+ [1][1][2][0][RTW89_CHILE][1][20] = 10, -+ [1][1][2][0][RTW89_QATAR][1][20] = 54, -+ [1][1][2][0][RTW89_QATAR][0][20] = 16, -+ [1][1][2][0][RTW89_UK][1][20] = 54, -+ [1][1][2][0][RTW89_UK][0][20] = 16, -+ [1][1][2][0][RTW89_FCC][1][24] = 10, -+ [1][1][2][0][RTW89_FCC][2][24] = 70, -+ [1][1][2][0][RTW89_ETSI][1][24] = 54, -+ [1][1][2][0][RTW89_ETSI][0][24] = 16, -+ [1][1][2][0][RTW89_MKK][1][24] = 54, -+ [1][1][2][0][RTW89_MKK][0][24] = 14, -+ [1][1][2][0][RTW89_IC][1][24] = 10, -+ [1][1][2][0][RTW89_KCC][1][24] = 28, -+ [1][1][2][0][RTW89_KCC][0][24] = 12, -+ [1][1][2][0][RTW89_ACMA][1][24] = 54, -+ [1][1][2][0][RTW89_ACMA][0][24] = 16, -+ [1][1][2][0][RTW89_CHILE][1][24] = 10, -+ [1][1][2][0][RTW89_QATAR][1][24] = 54, -+ [1][1][2][0][RTW89_QATAR][0][24] = 16, -+ [1][1][2][0][RTW89_UK][1][24] = 54, -+ [1][1][2][0][RTW89_UK][0][24] = 16, -+ [1][1][2][0][RTW89_FCC][1][28] = 10, -+ [1][1][2][0][RTW89_FCC][2][28] = 70, -+ [1][1][2][0][RTW89_ETSI][1][28] = 54, -+ [1][1][2][0][RTW89_ETSI][0][28] = 16, -+ [1][1][2][0][RTW89_MKK][1][28] = 52, -+ [1][1][2][0][RTW89_MKK][0][28] = 14, -+ [1][1][2][0][RTW89_IC][1][28] = 10, -+ [1][1][2][0][RTW89_KCC][1][28] = 28, -+ [1][1][2][0][RTW89_KCC][0][28] = 14, -+ [1][1][2][0][RTW89_ACMA][1][28] = 54, -+ [1][1][2][0][RTW89_ACMA][0][28] = 16, -+ [1][1][2][0][RTW89_CHILE][1][28] = 10, -+ [1][1][2][0][RTW89_QATAR][1][28] = 54, -+ [1][1][2][0][RTW89_QATAR][0][28] = 16, -+ [1][1][2][0][RTW89_UK][1][28] = 54, -+ [1][1][2][0][RTW89_UK][0][28] = 16, -+ [1][1][2][0][RTW89_FCC][1][31] = 10, -+ [1][1][2][0][RTW89_FCC][2][31] = 70, -+ [1][1][2][0][RTW89_ETSI][1][31] = 54, -+ [1][1][2][0][RTW89_ETSI][0][31] = 16, -+ [1][1][2][0][RTW89_MKK][1][31] = 52, -+ [1][1][2][0][RTW89_MKK][0][31] = 14, -+ [1][1][2][0][RTW89_IC][1][31] = 10, -+ [1][1][2][0][RTW89_KCC][1][31] = 28, -+ [1][1][2][0][RTW89_KCC][0][31] = 14, -+ [1][1][2][0][RTW89_ACMA][1][31] = 54, -+ [1][1][2][0][RTW89_ACMA][0][31] = 16, -+ [1][1][2][0][RTW89_CHILE][1][31] = 10, -+ [1][1][2][0][RTW89_QATAR][1][31] = 54, -+ [1][1][2][0][RTW89_QATAR][0][31] = 16, -+ [1][1][2][0][RTW89_UK][1][31] = 54, -+ [1][1][2][0][RTW89_UK][0][31] = 16, -+ [1][1][2][0][RTW89_FCC][1][35] = 10, -+ [1][1][2][0][RTW89_FCC][2][35] = 70, -+ [1][1][2][0][RTW89_ETSI][1][35] = 54, -+ [1][1][2][0][RTW89_ETSI][0][35] = 16, -+ [1][1][2][0][RTW89_MKK][1][35] = 52, -+ [1][1][2][0][RTW89_MKK][0][35] = 14, -+ [1][1][2][0][RTW89_IC][1][35] = 10, -+ [1][1][2][0][RTW89_KCC][1][35] = 28, -+ [1][1][2][0][RTW89_KCC][0][35] = 14, -+ [1][1][2][0][RTW89_ACMA][1][35] = 54, -+ [1][1][2][0][RTW89_ACMA][0][35] = 16, -+ [1][1][2][0][RTW89_CHILE][1][35] = 10, -+ [1][1][2][0][RTW89_QATAR][1][35] = 54, -+ [1][1][2][0][RTW89_QATAR][0][35] = 16, -+ [1][1][2][0][RTW89_UK][1][35] = 54, -+ [1][1][2][0][RTW89_UK][0][35] = 16, -+ [1][1][2][0][RTW89_FCC][1][39] = 10, -+ [1][1][2][0][RTW89_FCC][2][39] = 70, -+ [1][1][2][0][RTW89_ETSI][1][39] = 54, -+ [1][1][2][0][RTW89_ETSI][0][39] = 16, -+ [1][1][2][0][RTW89_MKK][1][39] = 52, -+ [1][1][2][0][RTW89_MKK][0][39] = 14, -+ [1][1][2][0][RTW89_IC][1][39] = 10, -+ [1][1][2][0][RTW89_KCC][1][39] = 28, -+ [1][1][2][0][RTW89_KCC][0][39] = 14, -+ [1][1][2][0][RTW89_ACMA][1][39] = 54, -+ [1][1][2][0][RTW89_ACMA][0][39] = 16, -+ [1][1][2][0][RTW89_CHILE][1][39] = 10, -+ [1][1][2][0][RTW89_QATAR][1][39] = 54, -+ [1][1][2][0][RTW89_QATAR][0][39] = 16, -+ [1][1][2][0][RTW89_UK][1][39] = 54, -+ [1][1][2][0][RTW89_UK][0][39] = 16, -+ [1][1][2][0][RTW89_FCC][1][43] = 10, -+ [1][1][2][0][RTW89_FCC][2][43] = 70, -+ [1][1][2][0][RTW89_ETSI][1][43] = 54, -+ [1][1][2][0][RTW89_ETSI][0][43] = 16, -+ [1][1][2][0][RTW89_MKK][1][43] = 52, -+ [1][1][2][0][RTW89_MKK][0][43] = 14, -+ [1][1][2][0][RTW89_IC][1][43] = 10, -+ [1][1][2][0][RTW89_KCC][1][43] = 28, -+ [1][1][2][0][RTW89_KCC][0][43] = 14, -+ [1][1][2][0][RTW89_ACMA][1][43] = 54, -+ [1][1][2][0][RTW89_ACMA][0][43] = 16, -+ [1][1][2][0][RTW89_CHILE][1][43] = 10, -+ [1][1][2][0][RTW89_QATAR][1][43] = 54, -+ [1][1][2][0][RTW89_QATAR][0][43] = 16, -+ [1][1][2][0][RTW89_UK][1][43] = 54, -+ [1][1][2][0][RTW89_UK][0][43] = 16, -+ [1][1][2][0][RTW89_FCC][1][46] = 12, -+ [1][1][2][0][RTW89_FCC][2][46] = 127, -+ [1][1][2][0][RTW89_ETSI][1][46] = 127, -+ [1][1][2][0][RTW89_ETSI][0][46] = 127, -+ [1][1][2][0][RTW89_MKK][1][46] = 127, -+ [1][1][2][0][RTW89_MKK][0][46] = 127, -+ [1][1][2][0][RTW89_IC][1][46] = 12, -+ [1][1][2][0][RTW89_KCC][1][46] = 28, -+ [1][1][2][0][RTW89_KCC][0][46] = 127, -+ [1][1][2][0][RTW89_ACMA][1][46] = 127, -+ [1][1][2][0][RTW89_ACMA][0][46] = 127, -+ [1][1][2][0][RTW89_CHILE][1][46] = 12, -+ [1][1][2][0][RTW89_QATAR][1][46] = 127, -+ [1][1][2][0][RTW89_QATAR][0][46] = 127, -+ [1][1][2][0][RTW89_UK][1][46] = 127, -+ [1][1][2][0][RTW89_UK][0][46] = 127, -+ [1][1][2][0][RTW89_FCC][1][50] = 12, -+ [1][1][2][0][RTW89_FCC][2][50] = 127, -+ [1][1][2][0][RTW89_ETSI][1][50] = 127, -+ [1][1][2][0][RTW89_ETSI][0][50] = 127, -+ [1][1][2][0][RTW89_MKK][1][50] = 127, -+ [1][1][2][0][RTW89_MKK][0][50] = 127, -+ [1][1][2][0][RTW89_IC][1][50] = 12, -+ [1][1][2][0][RTW89_KCC][1][50] = 28, -+ [1][1][2][0][RTW89_KCC][0][50] = 127, -+ [1][1][2][0][RTW89_ACMA][1][50] = 127, -+ [1][1][2][0][RTW89_ACMA][0][50] = 127, -+ [1][1][2][0][RTW89_CHILE][1][50] = 12, -+ [1][1][2][0][RTW89_QATAR][1][50] = 127, -+ [1][1][2][0][RTW89_QATAR][0][50] = 127, -+ [1][1][2][0][RTW89_UK][1][50] = 127, -+ [1][1][2][0][RTW89_UK][0][50] = 127, -+ [1][1][2][0][RTW89_FCC][1][54] = 10, -+ [1][1][2][0][RTW89_FCC][2][54] = 127, -+ [1][1][2][0][RTW89_ETSI][1][54] = 127, -+ [1][1][2][0][RTW89_ETSI][0][54] = 127, -+ [1][1][2][0][RTW89_MKK][1][54] = 127, -+ [1][1][2][0][RTW89_MKK][0][54] = 127, -+ [1][1][2][0][RTW89_IC][1][54] = 10, -+ [1][1][2][0][RTW89_KCC][1][54] = 28, -+ [1][1][2][0][RTW89_KCC][0][54] = 127, -+ [1][1][2][0][RTW89_ACMA][1][54] = 127, -+ [1][1][2][0][RTW89_ACMA][0][54] = 127, -+ [1][1][2][0][RTW89_CHILE][1][54] = 10, -+ [1][1][2][0][RTW89_QATAR][1][54] = 127, -+ [1][1][2][0][RTW89_QATAR][0][54] = 127, -+ [1][1][2][0][RTW89_UK][1][54] = 127, -+ [1][1][2][0][RTW89_UK][0][54] = 127, -+ [1][1][2][0][RTW89_FCC][1][58] = 10, -+ [1][1][2][0][RTW89_FCC][2][58] = 66, -+ [1][1][2][0][RTW89_ETSI][1][58] = 127, -+ [1][1][2][0][RTW89_ETSI][0][58] = 127, -+ [1][1][2][0][RTW89_MKK][1][58] = 127, -+ [1][1][2][0][RTW89_MKK][0][58] = 127, -+ [1][1][2][0][RTW89_IC][1][58] = 10, -+ [1][1][2][0][RTW89_KCC][1][58] = 28, -+ [1][1][2][0][RTW89_KCC][0][58] = 127, -+ [1][1][2][0][RTW89_ACMA][1][58] = 127, -+ [1][1][2][0][RTW89_ACMA][0][58] = 127, -+ [1][1][2][0][RTW89_CHILE][1][58] = 10, -+ [1][1][2][0][RTW89_QATAR][1][58] = 127, -+ [1][1][2][0][RTW89_QATAR][0][58] = 127, -+ [1][1][2][0][RTW89_UK][1][58] = 127, -+ [1][1][2][0][RTW89_UK][0][58] = 127, -+ [1][1][2][0][RTW89_FCC][1][61] = 10, -+ [1][1][2][0][RTW89_FCC][2][61] = 66, -+ [1][1][2][0][RTW89_ETSI][1][61] = 127, -+ [1][1][2][0][RTW89_ETSI][0][61] = 127, -+ [1][1][2][0][RTW89_MKK][1][61] = 127, -+ [1][1][2][0][RTW89_MKK][0][61] = 127, -+ [1][1][2][0][RTW89_IC][1][61] = 10, -+ [1][1][2][0][RTW89_KCC][1][61] = 28, -+ [1][1][2][0][RTW89_KCC][0][61] = 127, -+ [1][1][2][0][RTW89_ACMA][1][61] = 127, -+ [1][1][2][0][RTW89_ACMA][0][61] = 127, -+ [1][1][2][0][RTW89_CHILE][1][61] = 10, -+ [1][1][2][0][RTW89_QATAR][1][61] = 127, -+ [1][1][2][0][RTW89_QATAR][0][61] = 127, -+ [1][1][2][0][RTW89_UK][1][61] = 127, -+ [1][1][2][0][RTW89_UK][0][61] = 127, -+ [1][1][2][0][RTW89_FCC][1][65] = 10, -+ [1][1][2][0][RTW89_FCC][2][65] = 66, -+ [1][1][2][0][RTW89_ETSI][1][65] = 127, -+ [1][1][2][0][RTW89_ETSI][0][65] = 127, -+ [1][1][2][0][RTW89_MKK][1][65] = 127, -+ [1][1][2][0][RTW89_MKK][0][65] = 127, -+ [1][1][2][0][RTW89_IC][1][65] = 10, -+ [1][1][2][0][RTW89_KCC][1][65] = 28, -+ [1][1][2][0][RTW89_KCC][0][65] = 127, -+ [1][1][2][0][RTW89_ACMA][1][65] = 127, -+ [1][1][2][0][RTW89_ACMA][0][65] = 127, -+ [1][1][2][0][RTW89_CHILE][1][65] = 10, -+ [1][1][2][0][RTW89_QATAR][1][65] = 127, -+ [1][1][2][0][RTW89_QATAR][0][65] = 127, -+ [1][1][2][0][RTW89_UK][1][65] = 127, -+ [1][1][2][0][RTW89_UK][0][65] = 127, -+ [1][1][2][0][RTW89_FCC][1][69] = 10, -+ [1][1][2][0][RTW89_FCC][2][69] = 66, -+ [1][1][2][0][RTW89_ETSI][1][69] = 127, -+ [1][1][2][0][RTW89_ETSI][0][69] = 127, -+ [1][1][2][0][RTW89_MKK][1][69] = 127, -+ [1][1][2][0][RTW89_MKK][0][69] = 127, -+ [1][1][2][0][RTW89_IC][1][69] = 10, -+ [1][1][2][0][RTW89_KCC][1][69] = 28, -+ [1][1][2][0][RTW89_KCC][0][69] = 127, -+ [1][1][2][0][RTW89_ACMA][1][69] = 127, -+ [1][1][2][0][RTW89_ACMA][0][69] = 127, -+ [1][1][2][0][RTW89_CHILE][1][69] = 10, -+ [1][1][2][0][RTW89_QATAR][1][69] = 127, -+ [1][1][2][0][RTW89_QATAR][0][69] = 127, -+ [1][1][2][0][RTW89_UK][1][69] = 127, -+ [1][1][2][0][RTW89_UK][0][69] = 127, -+ [1][1][2][0][RTW89_FCC][1][73] = 10, -+ [1][1][2][0][RTW89_FCC][2][73] = 66, -+ [1][1][2][0][RTW89_ETSI][1][73] = 127, -+ [1][1][2][0][RTW89_ETSI][0][73] = 127, -+ [1][1][2][0][RTW89_MKK][1][73] = 127, -+ [1][1][2][0][RTW89_MKK][0][73] = 127, -+ [1][1][2][0][RTW89_IC][1][73] = 10, -+ [1][1][2][0][RTW89_KCC][1][73] = 28, -+ [1][1][2][0][RTW89_KCC][0][73] = 127, -+ [1][1][2][0][RTW89_ACMA][1][73] = 127, -+ [1][1][2][0][RTW89_ACMA][0][73] = 127, -+ [1][1][2][0][RTW89_CHILE][1][73] = 10, -+ [1][1][2][0][RTW89_QATAR][1][73] = 127, -+ [1][1][2][0][RTW89_QATAR][0][73] = 127, -+ [1][1][2][0][RTW89_UK][1][73] = 127, -+ [1][1][2][0][RTW89_UK][0][73] = 127, -+ [1][1][2][0][RTW89_FCC][1][76] = 10, -+ [1][1][2][0][RTW89_FCC][2][76] = 66, -+ [1][1][2][0][RTW89_ETSI][1][76] = 127, -+ [1][1][2][0][RTW89_ETSI][0][76] = 127, -+ [1][1][2][0][RTW89_MKK][1][76] = 127, -+ [1][1][2][0][RTW89_MKK][0][76] = 127, -+ [1][1][2][0][RTW89_IC][1][76] = 10, -+ [1][1][2][0][RTW89_KCC][1][76] = 28, -+ [1][1][2][0][RTW89_KCC][0][76] = 127, -+ [1][1][2][0][RTW89_ACMA][1][76] = 127, -+ [1][1][2][0][RTW89_ACMA][0][76] = 127, -+ [1][1][2][0][RTW89_CHILE][1][76] = 10, -+ [1][1][2][0][RTW89_QATAR][1][76] = 127, -+ [1][1][2][0][RTW89_QATAR][0][76] = 127, -+ [1][1][2][0][RTW89_UK][1][76] = 127, -+ [1][1][2][0][RTW89_UK][0][76] = 127, -+ [1][1][2][0][RTW89_FCC][1][80] = 10, -+ [1][1][2][0][RTW89_FCC][2][80] = 66, -+ [1][1][2][0][RTW89_ETSI][1][80] = 127, -+ [1][1][2][0][RTW89_ETSI][0][80] = 127, -+ [1][1][2][0][RTW89_MKK][1][80] = 127, -+ [1][1][2][0][RTW89_MKK][0][80] = 127, -+ [1][1][2][0][RTW89_IC][1][80] = 10, -+ [1][1][2][0][RTW89_KCC][1][80] = 32, -+ [1][1][2][0][RTW89_KCC][0][80] = 127, -+ [1][1][2][0][RTW89_ACMA][1][80] = 127, -+ [1][1][2][0][RTW89_ACMA][0][80] = 127, -+ [1][1][2][0][RTW89_CHILE][1][80] = 10, -+ [1][1][2][0][RTW89_QATAR][1][80] = 127, -+ [1][1][2][0][RTW89_QATAR][0][80] = 127, -+ [1][1][2][0][RTW89_UK][1][80] = 127, -+ [1][1][2][0][RTW89_UK][0][80] = 127, -+ [1][1][2][0][RTW89_FCC][1][84] = 10, -+ [1][1][2][0][RTW89_FCC][2][84] = 66, -+ [1][1][2][0][RTW89_ETSI][1][84] = 127, -+ [1][1][2][0][RTW89_ETSI][0][84] = 127, -+ [1][1][2][0][RTW89_MKK][1][84] = 127, -+ [1][1][2][0][RTW89_MKK][0][84] = 127, -+ [1][1][2][0][RTW89_IC][1][84] = 10, -+ [1][1][2][0][RTW89_KCC][1][84] = 32, -+ [1][1][2][0][RTW89_KCC][0][84] = 127, -+ [1][1][2][0][RTW89_ACMA][1][84] = 127, -+ [1][1][2][0][RTW89_ACMA][0][84] = 127, -+ [1][1][2][0][RTW89_CHILE][1][84] = 10, -+ [1][1][2][0][RTW89_QATAR][1][84] = 127, -+ [1][1][2][0][RTW89_QATAR][0][84] = 127, -+ [1][1][2][0][RTW89_UK][1][84] = 127, -+ [1][1][2][0][RTW89_UK][0][84] = 127, -+ [1][1][2][0][RTW89_FCC][1][88] = 10, -+ [1][1][2][0][RTW89_FCC][2][88] = 127, -+ [1][1][2][0][RTW89_ETSI][1][88] = 127, -+ [1][1][2][0][RTW89_ETSI][0][88] = 127, -+ [1][1][2][0][RTW89_MKK][1][88] = 127, -+ [1][1][2][0][RTW89_MKK][0][88] = 127, -+ [1][1][2][0][RTW89_IC][1][88] = 10, -+ [1][1][2][0][RTW89_KCC][1][88] = 32, -+ [1][1][2][0][RTW89_KCC][0][88] = 127, -+ [1][1][2][0][RTW89_ACMA][1][88] = 127, -+ [1][1][2][0][RTW89_ACMA][0][88] = 127, -+ [1][1][2][0][RTW89_CHILE][1][88] = 10, -+ [1][1][2][0][RTW89_QATAR][1][88] = 127, -+ [1][1][2][0][RTW89_QATAR][0][88] = 127, -+ [1][1][2][0][RTW89_UK][1][88] = 127, -+ [1][1][2][0][RTW89_UK][0][88] = 127, -+ [1][1][2][0][RTW89_FCC][1][91] = 12, -+ [1][1][2][0][RTW89_FCC][2][91] = 127, -+ [1][1][2][0][RTW89_ETSI][1][91] = 127, -+ [1][1][2][0][RTW89_ETSI][0][91] = 127, -+ [1][1][2][0][RTW89_MKK][1][91] = 127, -+ [1][1][2][0][RTW89_MKK][0][91] = 127, -+ [1][1][2][0][RTW89_IC][1][91] = 12, -+ [1][1][2][0][RTW89_KCC][1][91] = 32, -+ [1][1][2][0][RTW89_KCC][0][91] = 127, -+ [1][1][2][0][RTW89_ACMA][1][91] = 127, -+ [1][1][2][0][RTW89_ACMA][0][91] = 127, -+ [1][1][2][0][RTW89_CHILE][1][91] = 12, -+ [1][1][2][0][RTW89_QATAR][1][91] = 127, -+ [1][1][2][0][RTW89_QATAR][0][91] = 127, -+ [1][1][2][0][RTW89_UK][1][91] = 127, -+ [1][1][2][0][RTW89_UK][0][91] = 127, -+ [1][1][2][0][RTW89_FCC][1][95] = 10, -+ [1][1][2][0][RTW89_FCC][2][95] = 127, -+ [1][1][2][0][RTW89_ETSI][1][95] = 127, -+ [1][1][2][0][RTW89_ETSI][0][95] = 127, -+ [1][1][2][0][RTW89_MKK][1][95] = 127, -+ [1][1][2][0][RTW89_MKK][0][95] = 127, -+ [1][1][2][0][RTW89_IC][1][95] = 10, -+ [1][1][2][0][RTW89_KCC][1][95] = 32, -+ [1][1][2][0][RTW89_KCC][0][95] = 127, -+ [1][1][2][0][RTW89_ACMA][1][95] = 127, -+ [1][1][2][0][RTW89_ACMA][0][95] = 127, -+ [1][1][2][0][RTW89_CHILE][1][95] = 10, -+ [1][1][2][0][RTW89_QATAR][1][95] = 127, -+ [1][1][2][0][RTW89_QATAR][0][95] = 127, -+ [1][1][2][0][RTW89_UK][1][95] = 127, -+ [1][1][2][0][RTW89_UK][0][95] = 127, -+ [1][1][2][0][RTW89_FCC][1][99] = 10, -+ [1][1][2][0][RTW89_FCC][2][99] = 127, -+ [1][1][2][0][RTW89_ETSI][1][99] = 127, -+ [1][1][2][0][RTW89_ETSI][0][99] = 127, -+ [1][1][2][0][RTW89_MKK][1][99] = 127, -+ [1][1][2][0][RTW89_MKK][0][99] = 127, -+ [1][1][2][0][RTW89_IC][1][99] = 10, -+ [1][1][2][0][RTW89_KCC][1][99] = 32, -+ [1][1][2][0][RTW89_KCC][0][99] = 127, -+ [1][1][2][0][RTW89_ACMA][1][99] = 127, -+ [1][1][2][0][RTW89_ACMA][0][99] = 127, -+ [1][1][2][0][RTW89_CHILE][1][99] = 10, -+ [1][1][2][0][RTW89_QATAR][1][99] = 127, -+ [1][1][2][0][RTW89_QATAR][0][99] = 127, -+ [1][1][2][0][RTW89_UK][1][99] = 127, -+ [1][1][2][0][RTW89_UK][0][99] = 127, -+ [1][1][2][0][RTW89_FCC][1][103] = 10, -+ [1][1][2][0][RTW89_FCC][2][103] = 127, -+ [1][1][2][0][RTW89_ETSI][1][103] = 127, -+ [1][1][2][0][RTW89_ETSI][0][103] = 127, -+ [1][1][2][0][RTW89_MKK][1][103] = 127, -+ [1][1][2][0][RTW89_MKK][0][103] = 127, -+ [1][1][2][0][RTW89_IC][1][103] = 10, -+ [1][1][2][0][RTW89_KCC][1][103] = 32, -+ [1][1][2][0][RTW89_KCC][0][103] = 127, -+ [1][1][2][0][RTW89_ACMA][1][103] = 127, -+ [1][1][2][0][RTW89_ACMA][0][103] = 127, -+ [1][1][2][0][RTW89_CHILE][1][103] = 10, -+ [1][1][2][0][RTW89_QATAR][1][103] = 127, -+ [1][1][2][0][RTW89_QATAR][0][103] = 127, -+ [1][1][2][0][RTW89_UK][1][103] = 127, -+ [1][1][2][0][RTW89_UK][0][103] = 127, -+ [1][1][2][0][RTW89_FCC][1][106] = 12, -+ [1][1][2][0][RTW89_FCC][2][106] = 127, -+ [1][1][2][0][RTW89_ETSI][1][106] = 127, -+ [1][1][2][0][RTW89_ETSI][0][106] = 127, -+ [1][1][2][0][RTW89_MKK][1][106] = 127, -+ [1][1][2][0][RTW89_MKK][0][106] = 127, -+ [1][1][2][0][RTW89_IC][1][106] = 12, -+ [1][1][2][0][RTW89_KCC][1][106] = 32, -+ [1][1][2][0][RTW89_KCC][0][106] = 127, -+ [1][1][2][0][RTW89_ACMA][1][106] = 127, -+ [1][1][2][0][RTW89_ACMA][0][106] = 127, -+ [1][1][2][0][RTW89_CHILE][1][106] = 12, -+ [1][1][2][0][RTW89_QATAR][1][106] = 127, -+ [1][1][2][0][RTW89_QATAR][0][106] = 127, -+ [1][1][2][0][RTW89_UK][1][106] = 127, -+ [1][1][2][0][RTW89_UK][0][106] = 127, -+ [1][1][2][0][RTW89_FCC][1][110] = 127, -+ [1][1][2][0][RTW89_FCC][2][110] = 127, -+ [1][1][2][0][RTW89_ETSI][1][110] = 127, -+ [1][1][2][0][RTW89_ETSI][0][110] = 127, -+ [1][1][2][0][RTW89_MKK][1][110] = 127, -+ [1][1][2][0][RTW89_MKK][0][110] = 127, -+ [1][1][2][0][RTW89_IC][1][110] = 127, -+ [1][1][2][0][RTW89_KCC][1][110] = 127, -+ [1][1][2][0][RTW89_KCC][0][110] = 127, -+ [1][1][2][0][RTW89_ACMA][1][110] = 127, -+ [1][1][2][0][RTW89_ACMA][0][110] = 127, -+ [1][1][2][0][RTW89_CHILE][1][110] = 127, -+ [1][1][2][0][RTW89_QATAR][1][110] = 127, -+ [1][1][2][0][RTW89_QATAR][0][110] = 127, -+ [1][1][2][0][RTW89_UK][1][110] = 127, -+ [1][1][2][0][RTW89_UK][0][110] = 127, -+ [1][1][2][0][RTW89_FCC][1][114] = 127, -+ [1][1][2][0][RTW89_FCC][2][114] = 127, -+ [1][1][2][0][RTW89_ETSI][1][114] = 127, -+ [1][1][2][0][RTW89_ETSI][0][114] = 127, -+ [1][1][2][0][RTW89_MKK][1][114] = 127, -+ [1][1][2][0][RTW89_MKK][0][114] = 127, -+ [1][1][2][0][RTW89_IC][1][114] = 127, -+ [1][1][2][0][RTW89_KCC][1][114] = 127, -+ [1][1][2][0][RTW89_KCC][0][114] = 127, -+ [1][1][2][0][RTW89_ACMA][1][114] = 127, -+ [1][1][2][0][RTW89_ACMA][0][114] = 127, -+ [1][1][2][0][RTW89_CHILE][1][114] = 127, -+ [1][1][2][0][RTW89_QATAR][1][114] = 127, -+ [1][1][2][0][RTW89_QATAR][0][114] = 127, -+ [1][1][2][0][RTW89_UK][1][114] = 127, -+ [1][1][2][0][RTW89_UK][0][114] = 127, -+ [1][1][2][0][RTW89_FCC][1][118] = 127, -+ [1][1][2][0][RTW89_FCC][2][118] = 127, -+ [1][1][2][0][RTW89_ETSI][1][118] = 127, -+ [1][1][2][0][RTW89_ETSI][0][118] = 127, -+ [1][1][2][0][RTW89_MKK][1][118] = 127, -+ [1][1][2][0][RTW89_MKK][0][118] = 127, -+ [1][1][2][0][RTW89_IC][1][118] = 127, -+ [1][1][2][0][RTW89_KCC][1][118] = 127, -+ [1][1][2][0][RTW89_KCC][0][118] = 127, -+ [1][1][2][0][RTW89_ACMA][1][118] = 127, -+ [1][1][2][0][RTW89_ACMA][0][118] = 127, -+ [1][1][2][0][RTW89_CHILE][1][118] = 127, -+ [1][1][2][0][RTW89_QATAR][1][118] = 127, -+ [1][1][2][0][RTW89_QATAR][0][118] = 127, -+ [1][1][2][0][RTW89_UK][1][118] = 127, -+ [1][1][2][0][RTW89_UK][0][118] = 127, -+ [1][1][2][1][RTW89_FCC][1][1] = 10, -+ [1][1][2][1][RTW89_FCC][2][1] = 58, -+ [1][1][2][1][RTW89_ETSI][1][1] = 42, -+ [1][1][2][1][RTW89_ETSI][0][1] = 6, -+ [1][1][2][1][RTW89_MKK][1][1] = 52, -+ [1][1][2][1][RTW89_MKK][0][1] = 12, -+ [1][1][2][1][RTW89_IC][1][1] = 10, -+ [1][1][2][1][RTW89_KCC][1][1] = 28, -+ [1][1][2][1][RTW89_KCC][0][1] = 12, -+ [1][1][2][1][RTW89_ACMA][1][1] = 42, -+ [1][1][2][1][RTW89_ACMA][0][1] = 6, -+ [1][1][2][1][RTW89_CHILE][1][1] = 10, -+ [1][1][2][1][RTW89_QATAR][1][1] = 42, -+ [1][1][2][1][RTW89_QATAR][0][1] = 6, -+ [1][1][2][1][RTW89_UK][1][1] = 42, -+ [1][1][2][1][RTW89_UK][0][1] = 6, -+ [1][1][2][1][RTW89_FCC][1][5] = 10, -+ [1][1][2][1][RTW89_FCC][2][5] = 58, -+ [1][1][2][1][RTW89_ETSI][1][5] = 42, -+ [1][1][2][1][RTW89_ETSI][0][5] = 6, -+ [1][1][2][1][RTW89_MKK][1][5] = 52, -+ [1][1][2][1][RTW89_MKK][0][5] = 12, -+ [1][1][2][1][RTW89_IC][1][5] = 10, -+ [1][1][2][1][RTW89_KCC][1][5] = 28, -+ [1][1][2][1][RTW89_KCC][0][5] = 12, -+ [1][1][2][1][RTW89_ACMA][1][5] = 42, -+ [1][1][2][1][RTW89_ACMA][0][5] = 6, -+ [1][1][2][1][RTW89_CHILE][1][5] = 10, -+ [1][1][2][1][RTW89_QATAR][1][5] = 42, -+ [1][1][2][1][RTW89_QATAR][0][5] = 6, -+ [1][1][2][1][RTW89_UK][1][5] = 42, -+ [1][1][2][1][RTW89_UK][0][5] = 6, -+ [1][1][2][1][RTW89_FCC][1][9] = 10, -+ [1][1][2][1][RTW89_FCC][2][9] = 58, -+ [1][1][2][1][RTW89_ETSI][1][9] = 42, -+ [1][1][2][1][RTW89_ETSI][0][9] = 6, -+ [1][1][2][1][RTW89_MKK][1][9] = 52, -+ [1][1][2][1][RTW89_MKK][0][9] = 12, -+ [1][1][2][1][RTW89_IC][1][9] = 10, -+ [1][1][2][1][RTW89_KCC][1][9] = 28, -+ [1][1][2][1][RTW89_KCC][0][9] = 12, -+ [1][1][2][1][RTW89_ACMA][1][9] = 42, -+ [1][1][2][1][RTW89_ACMA][0][9] = 6, -+ [1][1][2][1][RTW89_CHILE][1][9] = 10, -+ [1][1][2][1][RTW89_QATAR][1][9] = 42, -+ [1][1][2][1][RTW89_QATAR][0][9] = 6, -+ [1][1][2][1][RTW89_UK][1][9] = 42, -+ [1][1][2][1][RTW89_UK][0][9] = 6, -+ [1][1][2][1][RTW89_FCC][1][13] = 10, -+ [1][1][2][1][RTW89_FCC][2][13] = 58, -+ [1][1][2][1][RTW89_ETSI][1][13] = 42, -+ [1][1][2][1][RTW89_ETSI][0][13] = 6, -+ [1][1][2][1][RTW89_MKK][1][13] = 52, -+ [1][1][2][1][RTW89_MKK][0][13] = 12, -+ [1][1][2][1][RTW89_IC][1][13] = 10, -+ [1][1][2][1][RTW89_KCC][1][13] = 28, -+ [1][1][2][1][RTW89_KCC][0][13] = 12, -+ [1][1][2][1][RTW89_ACMA][1][13] = 42, -+ [1][1][2][1][RTW89_ACMA][0][13] = 6, -+ [1][1][2][1][RTW89_CHILE][1][13] = 10, -+ [1][1][2][1][RTW89_QATAR][1][13] = 42, -+ [1][1][2][1][RTW89_QATAR][0][13] = 6, -+ [1][1][2][1][RTW89_UK][1][13] = 42, -+ [1][1][2][1][RTW89_UK][0][13] = 6, -+ [1][1][2][1][RTW89_FCC][1][16] = 10, -+ [1][1][2][1][RTW89_FCC][2][16] = 58, -+ [1][1][2][1][RTW89_ETSI][1][16] = 42, -+ [1][1][2][1][RTW89_ETSI][0][16] = 6, -+ [1][1][2][1][RTW89_MKK][1][16] = 52, -+ [1][1][2][1][RTW89_MKK][0][16] = 12, -+ [1][1][2][1][RTW89_IC][1][16] = 10, -+ [1][1][2][1][RTW89_KCC][1][16] = 28, -+ [1][1][2][1][RTW89_KCC][0][16] = 12, -+ [1][1][2][1][RTW89_ACMA][1][16] = 42, -+ [1][1][2][1][RTW89_ACMA][0][16] = 6, -+ [1][1][2][1][RTW89_CHILE][1][16] = 10, -+ [1][1][2][1][RTW89_QATAR][1][16] = 42, -+ [1][1][2][1][RTW89_QATAR][0][16] = 6, -+ [1][1][2][1][RTW89_UK][1][16] = 42, -+ [1][1][2][1][RTW89_UK][0][16] = 6, -+ [1][1][2][1][RTW89_FCC][1][20] = 10, -+ [1][1][2][1][RTW89_FCC][2][20] = 58, -+ [1][1][2][1][RTW89_ETSI][1][20] = 42, -+ [1][1][2][1][RTW89_ETSI][0][20] = 6, -+ [1][1][2][1][RTW89_MKK][1][20] = 52, -+ [1][1][2][1][RTW89_MKK][0][20] = 12, -+ [1][1][2][1][RTW89_IC][1][20] = 10, -+ [1][1][2][1][RTW89_KCC][1][20] = 28, -+ [1][1][2][1][RTW89_KCC][0][20] = 12, -+ [1][1][2][1][RTW89_ACMA][1][20] = 42, -+ [1][1][2][1][RTW89_ACMA][0][20] = 6, -+ [1][1][2][1][RTW89_CHILE][1][20] = 10, -+ [1][1][2][1][RTW89_QATAR][1][20] = 42, -+ [1][1][2][1][RTW89_QATAR][0][20] = 6, -+ [1][1][2][1][RTW89_UK][1][20] = 42, -+ [1][1][2][1][RTW89_UK][0][20] = 6, -+ [1][1][2][1][RTW89_FCC][1][24] = 10, -+ [1][1][2][1][RTW89_FCC][2][24] = 70, -+ [1][1][2][1][RTW89_ETSI][1][24] = 42, -+ [1][1][2][1][RTW89_ETSI][0][24] = 6, -+ [1][1][2][1][RTW89_MKK][1][24] = 54, -+ [1][1][2][1][RTW89_MKK][0][24] = 14, -+ [1][1][2][1][RTW89_IC][1][24] = 10, -+ [1][1][2][1][RTW89_KCC][1][24] = 28, -+ [1][1][2][1][RTW89_KCC][0][24] = 12, -+ [1][1][2][1][RTW89_ACMA][1][24] = 42, -+ [1][1][2][1][RTW89_ACMA][0][24] = 6, -+ [1][1][2][1][RTW89_CHILE][1][24] = 10, -+ [1][1][2][1][RTW89_QATAR][1][24] = 42, -+ [1][1][2][1][RTW89_QATAR][0][24] = 6, -+ [1][1][2][1][RTW89_UK][1][24] = 42, -+ [1][1][2][1][RTW89_UK][0][24] = 6, -+ [1][1][2][1][RTW89_FCC][1][28] = 10, -+ [1][1][2][1][RTW89_FCC][2][28] = 70, -+ [1][1][2][1][RTW89_ETSI][1][28] = 42, -+ [1][1][2][1][RTW89_ETSI][0][28] = 6, -+ [1][1][2][1][RTW89_MKK][1][28] = 52, -+ [1][1][2][1][RTW89_MKK][0][28] = 14, -+ [1][1][2][1][RTW89_IC][1][28] = 10, -+ [1][1][2][1][RTW89_KCC][1][28] = 28, -+ [1][1][2][1][RTW89_KCC][0][28] = 14, -+ [1][1][2][1][RTW89_ACMA][1][28] = 42, -+ [1][1][2][1][RTW89_ACMA][0][28] = 6, -+ [1][1][2][1][RTW89_CHILE][1][28] = 10, -+ [1][1][2][1][RTW89_QATAR][1][28] = 42, -+ [1][1][2][1][RTW89_QATAR][0][28] = 6, -+ [1][1][2][1][RTW89_UK][1][28] = 42, -+ [1][1][2][1][RTW89_UK][0][28] = 6, -+ [1][1][2][1][RTW89_FCC][1][31] = 10, -+ [1][1][2][1][RTW89_FCC][2][31] = 70, -+ [1][1][2][1][RTW89_ETSI][1][31] = 42, -+ [1][1][2][1][RTW89_ETSI][0][31] = 6, -+ [1][1][2][1][RTW89_MKK][1][31] = 52, -+ [1][1][2][1][RTW89_MKK][0][31] = 14, -+ [1][1][2][1][RTW89_IC][1][31] = 10, -+ [1][1][2][1][RTW89_KCC][1][31] = 28, -+ [1][1][2][1][RTW89_KCC][0][31] = 14, -+ [1][1][2][1][RTW89_ACMA][1][31] = 42, -+ [1][1][2][1][RTW89_ACMA][0][31] = 6, -+ [1][1][2][1][RTW89_CHILE][1][31] = 10, -+ [1][1][2][1][RTW89_QATAR][1][31] = 42, -+ [1][1][2][1][RTW89_QATAR][0][31] = 6, -+ [1][1][2][1][RTW89_UK][1][31] = 42, -+ [1][1][2][1][RTW89_UK][0][31] = 6, -+ [1][1][2][1][RTW89_FCC][1][35] = 10, -+ [1][1][2][1][RTW89_FCC][2][35] = 70, -+ [1][1][2][1][RTW89_ETSI][1][35] = 42, -+ [1][1][2][1][RTW89_ETSI][0][35] = 6, -+ [1][1][2][1][RTW89_MKK][1][35] = 52, -+ [1][1][2][1][RTW89_MKK][0][35] = 14, -+ [1][1][2][1][RTW89_IC][1][35] = 10, -+ [1][1][2][1][RTW89_KCC][1][35] = 28, -+ [1][1][2][1][RTW89_KCC][0][35] = 14, -+ [1][1][2][1][RTW89_ACMA][1][35] = 42, -+ [1][1][2][1][RTW89_ACMA][0][35] = 6, -+ [1][1][2][1][RTW89_CHILE][1][35] = 10, -+ [1][1][2][1][RTW89_QATAR][1][35] = 42, -+ [1][1][2][1][RTW89_QATAR][0][35] = 6, -+ [1][1][2][1][RTW89_UK][1][35] = 42, -+ [1][1][2][1][RTW89_UK][0][35] = 6, -+ [1][1][2][1][RTW89_FCC][1][39] = 10, -+ [1][1][2][1][RTW89_FCC][2][39] = 70, -+ [1][1][2][1][RTW89_ETSI][1][39] = 42, -+ [1][1][2][1][RTW89_ETSI][0][39] = 6, -+ [1][1][2][1][RTW89_MKK][1][39] = 52, -+ [1][1][2][1][RTW89_MKK][0][39] = 14, -+ [1][1][2][1][RTW89_IC][1][39] = 10, -+ [1][1][2][1][RTW89_KCC][1][39] = 28, -+ [1][1][2][1][RTW89_KCC][0][39] = 14, -+ [1][1][2][1][RTW89_ACMA][1][39] = 42, -+ [1][1][2][1][RTW89_ACMA][0][39] = 6, -+ [1][1][2][1][RTW89_CHILE][1][39] = 10, -+ [1][1][2][1][RTW89_QATAR][1][39] = 42, -+ [1][1][2][1][RTW89_QATAR][0][39] = 6, -+ [1][1][2][1][RTW89_UK][1][39] = 42, -+ [1][1][2][1][RTW89_UK][0][39] = 6, -+ [1][1][2][1][RTW89_FCC][1][43] = 10, -+ [1][1][2][1][RTW89_FCC][2][43] = 70, -+ [1][1][2][1][RTW89_ETSI][1][43] = 42, -+ [1][1][2][1][RTW89_ETSI][0][43] = 6, -+ [1][1][2][1][RTW89_MKK][1][43] = 52, -+ [1][1][2][1][RTW89_MKK][0][43] = 14, -+ [1][1][2][1][RTW89_IC][1][43] = 10, -+ [1][1][2][1][RTW89_KCC][1][43] = 28, -+ [1][1][2][1][RTW89_KCC][0][43] = 14, -+ [1][1][2][1][RTW89_ACMA][1][43] = 42, -+ [1][1][2][1][RTW89_ACMA][0][43] = 6, -+ [1][1][2][1][RTW89_CHILE][1][43] = 10, -+ [1][1][2][1][RTW89_QATAR][1][43] = 42, -+ [1][1][2][1][RTW89_QATAR][0][43] = 6, -+ [1][1][2][1][RTW89_UK][1][43] = 42, -+ [1][1][2][1][RTW89_UK][0][43] = 6, -+ [1][1][2][1][RTW89_FCC][1][46] = 12, -+ [1][1][2][1][RTW89_FCC][2][46] = 127, -+ [1][1][2][1][RTW89_ETSI][1][46] = 127, -+ [1][1][2][1][RTW89_ETSI][0][46] = 127, -+ [1][1][2][1][RTW89_MKK][1][46] = 127, -+ [1][1][2][1][RTW89_MKK][0][46] = 127, -+ [1][1][2][1][RTW89_IC][1][46] = 12, -+ [1][1][2][1][RTW89_KCC][1][46] = 28, -+ [1][1][2][1][RTW89_KCC][0][46] = 127, -+ [1][1][2][1][RTW89_ACMA][1][46] = 127, -+ [1][1][2][1][RTW89_ACMA][0][46] = 127, -+ [1][1][2][1][RTW89_CHILE][1][46] = 12, -+ [1][1][2][1][RTW89_QATAR][1][46] = 127, -+ [1][1][2][1][RTW89_QATAR][0][46] = 127, -+ [1][1][2][1][RTW89_UK][1][46] = 127, -+ [1][1][2][1][RTW89_UK][0][46] = 127, -+ [1][1][2][1][RTW89_FCC][1][50] = 12, -+ [1][1][2][1][RTW89_FCC][2][50] = 127, -+ [1][1][2][1][RTW89_ETSI][1][50] = 127, -+ [1][1][2][1][RTW89_ETSI][0][50] = 127, -+ [1][1][2][1][RTW89_MKK][1][50] = 127, -+ [1][1][2][1][RTW89_MKK][0][50] = 127, -+ [1][1][2][1][RTW89_IC][1][50] = 12, -+ [1][1][2][1][RTW89_KCC][1][50] = 28, -+ [1][1][2][1][RTW89_KCC][0][50] = 127, -+ [1][1][2][1][RTW89_ACMA][1][50] = 127, -+ [1][1][2][1][RTW89_ACMA][0][50] = 127, -+ [1][1][2][1][RTW89_CHILE][1][50] = 12, -+ [1][1][2][1][RTW89_QATAR][1][50] = 127, -+ [1][1][2][1][RTW89_QATAR][0][50] = 127, -+ [1][1][2][1][RTW89_UK][1][50] = 127, -+ [1][1][2][1][RTW89_UK][0][50] = 127, -+ [1][1][2][1][RTW89_FCC][1][54] = 10, -+ [1][1][2][1][RTW89_FCC][2][54] = 127, -+ [1][1][2][1][RTW89_ETSI][1][54] = 127, -+ [1][1][2][1][RTW89_ETSI][0][54] = 127, -+ [1][1][2][1][RTW89_MKK][1][54] = 127, -+ [1][1][2][1][RTW89_MKK][0][54] = 127, -+ [1][1][2][1][RTW89_IC][1][54] = 10, -+ [1][1][2][1][RTW89_KCC][1][54] = 28, -+ [1][1][2][1][RTW89_KCC][0][54] = 127, -+ [1][1][2][1][RTW89_ACMA][1][54] = 127, -+ [1][1][2][1][RTW89_ACMA][0][54] = 127, -+ [1][1][2][1][RTW89_CHILE][1][54] = 10, -+ [1][1][2][1][RTW89_QATAR][1][54] = 127, -+ [1][1][2][1][RTW89_QATAR][0][54] = 127, -+ [1][1][2][1][RTW89_UK][1][54] = 127, -+ [1][1][2][1][RTW89_UK][0][54] = 127, -+ [1][1][2][1][RTW89_FCC][1][58] = 10, -+ [1][1][2][1][RTW89_FCC][2][58] = 66, -+ [1][1][2][1][RTW89_ETSI][1][58] = 127, -+ [1][1][2][1][RTW89_ETSI][0][58] = 127, -+ [1][1][2][1][RTW89_MKK][1][58] = 127, -+ [1][1][2][1][RTW89_MKK][0][58] = 127, -+ [1][1][2][1][RTW89_IC][1][58] = 10, -+ [1][1][2][1][RTW89_KCC][1][58] = 28, -+ [1][1][2][1][RTW89_KCC][0][58] = 127, -+ [1][1][2][1][RTW89_ACMA][1][58] = 127, -+ [1][1][2][1][RTW89_ACMA][0][58] = 127, -+ [1][1][2][1][RTW89_CHILE][1][58] = 10, -+ [1][1][2][1][RTW89_QATAR][1][58] = 127, -+ [1][1][2][1][RTW89_QATAR][0][58] = 127, -+ [1][1][2][1][RTW89_UK][1][58] = 127, -+ [1][1][2][1][RTW89_UK][0][58] = 127, -+ [1][1][2][1][RTW89_FCC][1][61] = 10, -+ [1][1][2][1][RTW89_FCC][2][61] = 66, -+ [1][1][2][1][RTW89_ETSI][1][61] = 127, -+ [1][1][2][1][RTW89_ETSI][0][61] = 127, -+ [1][1][2][1][RTW89_MKK][1][61] = 127, -+ [1][1][2][1][RTW89_MKK][0][61] = 127, -+ [1][1][2][1][RTW89_IC][1][61] = 10, -+ [1][1][2][1][RTW89_KCC][1][61] = 28, -+ [1][1][2][1][RTW89_KCC][0][61] = 127, -+ [1][1][2][1][RTW89_ACMA][1][61] = 127, -+ [1][1][2][1][RTW89_ACMA][0][61] = 127, -+ [1][1][2][1][RTW89_CHILE][1][61] = 10, -+ [1][1][2][1][RTW89_QATAR][1][61] = 127, -+ [1][1][2][1][RTW89_QATAR][0][61] = 127, -+ [1][1][2][1][RTW89_UK][1][61] = 127, -+ [1][1][2][1][RTW89_UK][0][61] = 127, -+ [1][1][2][1][RTW89_FCC][1][65] = 10, -+ [1][1][2][1][RTW89_FCC][2][65] = 66, -+ [1][1][2][1][RTW89_ETSI][1][65] = 127, -+ [1][1][2][1][RTW89_ETSI][0][65] = 127, -+ [1][1][2][1][RTW89_MKK][1][65] = 127, -+ [1][1][2][1][RTW89_MKK][0][65] = 127, -+ [1][1][2][1][RTW89_IC][1][65] = 10, -+ [1][1][2][1][RTW89_KCC][1][65] = 28, -+ [1][1][2][1][RTW89_KCC][0][65] = 127, -+ [1][1][2][1][RTW89_ACMA][1][65] = 127, -+ [1][1][2][1][RTW89_ACMA][0][65] = 127, -+ [1][1][2][1][RTW89_CHILE][1][65] = 10, -+ [1][1][2][1][RTW89_QATAR][1][65] = 127, -+ [1][1][2][1][RTW89_QATAR][0][65] = 127, -+ [1][1][2][1][RTW89_UK][1][65] = 127, -+ [1][1][2][1][RTW89_UK][0][65] = 127, -+ [1][1][2][1][RTW89_FCC][1][69] = 10, -+ [1][1][2][1][RTW89_FCC][2][69] = 66, -+ [1][1][2][1][RTW89_ETSI][1][69] = 127, -+ [1][1][2][1][RTW89_ETSI][0][69] = 127, -+ [1][1][2][1][RTW89_MKK][1][69] = 127, -+ [1][1][2][1][RTW89_MKK][0][69] = 127, -+ [1][1][2][1][RTW89_IC][1][69] = 10, -+ [1][1][2][1][RTW89_KCC][1][69] = 28, -+ [1][1][2][1][RTW89_KCC][0][69] = 127, -+ [1][1][2][1][RTW89_ACMA][1][69] = 127, -+ [1][1][2][1][RTW89_ACMA][0][69] = 127, -+ [1][1][2][1][RTW89_CHILE][1][69] = 10, -+ [1][1][2][1][RTW89_QATAR][1][69] = 127, -+ [1][1][2][1][RTW89_QATAR][0][69] = 127, -+ [1][1][2][1][RTW89_UK][1][69] = 127, -+ [1][1][2][1][RTW89_UK][0][69] = 127, -+ [1][1][2][1][RTW89_FCC][1][73] = 10, -+ [1][1][2][1][RTW89_FCC][2][73] = 66, -+ [1][1][2][1][RTW89_ETSI][1][73] = 127, -+ [1][1][2][1][RTW89_ETSI][0][73] = 127, -+ [1][1][2][1][RTW89_MKK][1][73] = 127, -+ [1][1][2][1][RTW89_MKK][0][73] = 127, -+ [1][1][2][1][RTW89_IC][1][73] = 10, -+ [1][1][2][1][RTW89_KCC][1][73] = 28, -+ [1][1][2][1][RTW89_KCC][0][73] = 127, -+ [1][1][2][1][RTW89_ACMA][1][73] = 127, -+ [1][1][2][1][RTW89_ACMA][0][73] = 127, -+ [1][1][2][1][RTW89_CHILE][1][73] = 10, -+ [1][1][2][1][RTW89_QATAR][1][73] = 127, -+ [1][1][2][1][RTW89_QATAR][0][73] = 127, -+ [1][1][2][1][RTW89_UK][1][73] = 127, -+ [1][1][2][1][RTW89_UK][0][73] = 127, -+ [1][1][2][1][RTW89_FCC][1][76] = 10, -+ [1][1][2][1][RTW89_FCC][2][76] = 66, -+ [1][1][2][1][RTW89_ETSI][1][76] = 127, -+ [1][1][2][1][RTW89_ETSI][0][76] = 127, -+ [1][1][2][1][RTW89_MKK][1][76] = 127, -+ [1][1][2][1][RTW89_MKK][0][76] = 127, -+ [1][1][2][1][RTW89_IC][1][76] = 10, -+ [1][1][2][1][RTW89_KCC][1][76] = 28, -+ [1][1][2][1][RTW89_KCC][0][76] = 127, -+ [1][1][2][1][RTW89_ACMA][1][76] = 127, -+ [1][1][2][1][RTW89_ACMA][0][76] = 127, -+ [1][1][2][1][RTW89_CHILE][1][76] = 10, -+ [1][1][2][1][RTW89_QATAR][1][76] = 127, -+ [1][1][2][1][RTW89_QATAR][0][76] = 127, -+ [1][1][2][1][RTW89_UK][1][76] = 127, -+ [1][1][2][1][RTW89_UK][0][76] = 127, -+ [1][1][2][1][RTW89_FCC][1][80] = 10, -+ [1][1][2][1][RTW89_FCC][2][80] = 66, -+ [1][1][2][1][RTW89_ETSI][1][80] = 127, -+ [1][1][2][1][RTW89_ETSI][0][80] = 127, -+ [1][1][2][1][RTW89_MKK][1][80] = 127, -+ [1][1][2][1][RTW89_MKK][0][80] = 127, -+ [1][1][2][1][RTW89_IC][1][80] = 10, -+ [1][1][2][1][RTW89_KCC][1][80] = 32, -+ [1][1][2][1][RTW89_KCC][0][80] = 127, -+ [1][1][2][1][RTW89_ACMA][1][80] = 127, -+ [1][1][2][1][RTW89_ACMA][0][80] = 127, -+ [1][1][2][1][RTW89_CHILE][1][80] = 10, -+ [1][1][2][1][RTW89_QATAR][1][80] = 127, -+ [1][1][2][1][RTW89_QATAR][0][80] = 127, -+ [1][1][2][1][RTW89_UK][1][80] = 127, -+ [1][1][2][1][RTW89_UK][0][80] = 127, -+ [1][1][2][1][RTW89_FCC][1][84] = 10, -+ [1][1][2][1][RTW89_FCC][2][84] = 66, -+ [1][1][2][1][RTW89_ETSI][1][84] = 127, -+ [1][1][2][1][RTW89_ETSI][0][84] = 127, -+ [1][1][2][1][RTW89_MKK][1][84] = 127, -+ [1][1][2][1][RTW89_MKK][0][84] = 127, -+ [1][1][2][1][RTW89_IC][1][84] = 10, -+ [1][1][2][1][RTW89_KCC][1][84] = 32, -+ [1][1][2][1][RTW89_KCC][0][84] = 127, -+ [1][1][2][1][RTW89_ACMA][1][84] = 127, -+ [1][1][2][1][RTW89_ACMA][0][84] = 127, -+ [1][1][2][1][RTW89_CHILE][1][84] = 10, -+ [1][1][2][1][RTW89_QATAR][1][84] = 127, -+ [1][1][2][1][RTW89_QATAR][0][84] = 127, -+ [1][1][2][1][RTW89_UK][1][84] = 127, -+ [1][1][2][1][RTW89_UK][0][84] = 127, -+ [1][1][2][1][RTW89_FCC][1][88] = 10, -+ [1][1][2][1][RTW89_FCC][2][88] = 127, -+ [1][1][2][1][RTW89_ETSI][1][88] = 127, -+ [1][1][2][1][RTW89_ETSI][0][88] = 127, -+ [1][1][2][1][RTW89_MKK][1][88] = 127, -+ [1][1][2][1][RTW89_MKK][0][88] = 127, -+ [1][1][2][1][RTW89_IC][1][88] = 10, -+ [1][1][2][1][RTW89_KCC][1][88] = 32, -+ [1][1][2][1][RTW89_KCC][0][88] = 127, -+ [1][1][2][1][RTW89_ACMA][1][88] = 127, -+ [1][1][2][1][RTW89_ACMA][0][88] = 127, -+ [1][1][2][1][RTW89_CHILE][1][88] = 10, -+ [1][1][2][1][RTW89_QATAR][1][88] = 127, -+ [1][1][2][1][RTW89_QATAR][0][88] = 127, -+ [1][1][2][1][RTW89_UK][1][88] = 127, -+ [1][1][2][1][RTW89_UK][0][88] = 127, -+ [1][1][2][1][RTW89_FCC][1][91] = 12, -+ [1][1][2][1][RTW89_FCC][2][91] = 127, -+ [1][1][2][1][RTW89_ETSI][1][91] = 127, -+ [1][1][2][1][RTW89_ETSI][0][91] = 127, -+ [1][1][2][1][RTW89_MKK][1][91] = 127, -+ [1][1][2][1][RTW89_MKK][0][91] = 127, -+ [1][1][2][1][RTW89_IC][1][91] = 12, -+ [1][1][2][1][RTW89_KCC][1][91] = 32, -+ [1][1][2][1][RTW89_KCC][0][91] = 127, -+ [1][1][2][1][RTW89_ACMA][1][91] = 127, -+ [1][1][2][1][RTW89_ACMA][0][91] = 127, -+ [1][1][2][1][RTW89_CHILE][1][91] = 12, -+ [1][1][2][1][RTW89_QATAR][1][91] = 127, -+ [1][1][2][1][RTW89_QATAR][0][91] = 127, -+ [1][1][2][1][RTW89_UK][1][91] = 127, -+ [1][1][2][1][RTW89_UK][0][91] = 127, -+ [1][1][2][1][RTW89_FCC][1][95] = 10, -+ [1][1][2][1][RTW89_FCC][2][95] = 127, -+ [1][1][2][1][RTW89_ETSI][1][95] = 127, -+ [1][1][2][1][RTW89_ETSI][0][95] = 127, -+ [1][1][2][1][RTW89_MKK][1][95] = 127, -+ [1][1][2][1][RTW89_MKK][0][95] = 127, -+ [1][1][2][1][RTW89_IC][1][95] = 10, -+ [1][1][2][1][RTW89_KCC][1][95] = 32, -+ [1][1][2][1][RTW89_KCC][0][95] = 127, -+ [1][1][2][1][RTW89_ACMA][1][95] = 127, -+ [1][1][2][1][RTW89_ACMA][0][95] = 127, -+ [1][1][2][1][RTW89_CHILE][1][95] = 10, -+ [1][1][2][1][RTW89_QATAR][1][95] = 127, -+ [1][1][2][1][RTW89_QATAR][0][95] = 127, -+ [1][1][2][1][RTW89_UK][1][95] = 127, -+ [1][1][2][1][RTW89_UK][0][95] = 127, -+ [1][1][2][1][RTW89_FCC][1][99] = 10, -+ [1][1][2][1][RTW89_FCC][2][99] = 127, -+ [1][1][2][1][RTW89_ETSI][1][99] = 127, -+ [1][1][2][1][RTW89_ETSI][0][99] = 127, -+ [1][1][2][1][RTW89_MKK][1][99] = 127, -+ [1][1][2][1][RTW89_MKK][0][99] = 127, -+ [1][1][2][1][RTW89_IC][1][99] = 10, -+ [1][1][2][1][RTW89_KCC][1][99] = 32, -+ [1][1][2][1][RTW89_KCC][0][99] = 127, -+ [1][1][2][1][RTW89_ACMA][1][99] = 127, -+ [1][1][2][1][RTW89_ACMA][0][99] = 127, -+ [1][1][2][1][RTW89_CHILE][1][99] = 10, -+ [1][1][2][1][RTW89_QATAR][1][99] = 127, -+ [1][1][2][1][RTW89_QATAR][0][99] = 127, -+ [1][1][2][1][RTW89_UK][1][99] = 127, -+ [1][1][2][1][RTW89_UK][0][99] = 127, -+ [1][1][2][1][RTW89_FCC][1][103] = 10, -+ [1][1][2][1][RTW89_FCC][2][103] = 127, -+ [1][1][2][1][RTW89_ETSI][1][103] = 127, -+ [1][1][2][1][RTW89_ETSI][0][103] = 127, -+ [1][1][2][1][RTW89_MKK][1][103] = 127, -+ [1][1][2][1][RTW89_MKK][0][103] = 127, -+ [1][1][2][1][RTW89_IC][1][103] = 10, -+ [1][1][2][1][RTW89_KCC][1][103] = 32, -+ [1][1][2][1][RTW89_KCC][0][103] = 127, -+ [1][1][2][1][RTW89_ACMA][1][103] = 127, -+ [1][1][2][1][RTW89_ACMA][0][103] = 127, -+ [1][1][2][1][RTW89_CHILE][1][103] = 10, -+ [1][1][2][1][RTW89_QATAR][1][103] = 127, -+ [1][1][2][1][RTW89_QATAR][0][103] = 127, -+ [1][1][2][1][RTW89_UK][1][103] = 127, -+ [1][1][2][1][RTW89_UK][0][103] = 127, -+ [1][1][2][1][RTW89_FCC][1][106] = 12, -+ [1][1][2][1][RTW89_FCC][2][106] = 127, -+ [1][1][2][1][RTW89_ETSI][1][106] = 127, -+ [1][1][2][1][RTW89_ETSI][0][106] = 127, -+ [1][1][2][1][RTW89_MKK][1][106] = 127, -+ [1][1][2][1][RTW89_MKK][0][106] = 127, -+ [1][1][2][1][RTW89_IC][1][106] = 12, -+ [1][1][2][1][RTW89_KCC][1][106] = 32, -+ [1][1][2][1][RTW89_KCC][0][106] = 127, -+ [1][1][2][1][RTW89_ACMA][1][106] = 127, -+ [1][1][2][1][RTW89_ACMA][0][106] = 127, -+ [1][1][2][1][RTW89_CHILE][1][106] = 12, -+ [1][1][2][1][RTW89_QATAR][1][106] = 127, -+ [1][1][2][1][RTW89_QATAR][0][106] = 127, -+ [1][1][2][1][RTW89_UK][1][106] = 127, -+ [1][1][2][1][RTW89_UK][0][106] = 127, -+ [1][1][2][1][RTW89_FCC][1][110] = 127, -+ [1][1][2][1][RTW89_FCC][2][110] = 127, -+ [1][1][2][1][RTW89_ETSI][1][110] = 127, -+ [1][1][2][1][RTW89_ETSI][0][110] = 127, -+ [1][1][2][1][RTW89_MKK][1][110] = 127, -+ [1][1][2][1][RTW89_MKK][0][110] = 127, -+ [1][1][2][1][RTW89_IC][1][110] = 127, -+ [1][1][2][1][RTW89_KCC][1][110] = 127, -+ [1][1][2][1][RTW89_KCC][0][110] = 127, -+ [1][1][2][1][RTW89_ACMA][1][110] = 127, -+ [1][1][2][1][RTW89_ACMA][0][110] = 127, -+ [1][1][2][1][RTW89_CHILE][1][110] = 127, -+ [1][1][2][1][RTW89_QATAR][1][110] = 127, -+ [1][1][2][1][RTW89_QATAR][0][110] = 127, -+ [1][1][2][1][RTW89_UK][1][110] = 127, -+ [1][1][2][1][RTW89_UK][0][110] = 127, -+ [1][1][2][1][RTW89_FCC][1][114] = 127, -+ [1][1][2][1][RTW89_FCC][2][114] = 127, -+ [1][1][2][1][RTW89_ETSI][1][114] = 127, -+ [1][1][2][1][RTW89_ETSI][0][114] = 127, -+ [1][1][2][1][RTW89_MKK][1][114] = 127, -+ [1][1][2][1][RTW89_MKK][0][114] = 127, -+ [1][1][2][1][RTW89_IC][1][114] = 127, -+ [1][1][2][1][RTW89_KCC][1][114] = 127, -+ [1][1][2][1][RTW89_KCC][0][114] = 127, -+ [1][1][2][1][RTW89_ACMA][1][114] = 127, -+ [1][1][2][1][RTW89_ACMA][0][114] = 127, -+ [1][1][2][1][RTW89_CHILE][1][114] = 127, -+ [1][1][2][1][RTW89_QATAR][1][114] = 127, -+ [1][1][2][1][RTW89_QATAR][0][114] = 127, -+ [1][1][2][1][RTW89_UK][1][114] = 127, -+ [1][1][2][1][RTW89_UK][0][114] = 127, -+ [1][1][2][1][RTW89_FCC][1][118] = 127, -+ [1][1][2][1][RTW89_FCC][2][118] = 127, -+ [1][1][2][1][RTW89_ETSI][1][118] = 127, -+ [1][1][2][1][RTW89_ETSI][0][118] = 127, -+ [1][1][2][1][RTW89_MKK][1][118] = 127, -+ [1][1][2][1][RTW89_MKK][0][118] = 127, -+ [1][1][2][1][RTW89_IC][1][118] = 127, -+ [1][1][2][1][RTW89_KCC][1][118] = 127, -+ [1][1][2][1][RTW89_KCC][0][118] = 127, -+ [1][1][2][1][RTW89_ACMA][1][118] = 127, -+ [1][1][2][1][RTW89_ACMA][0][118] = 127, -+ [1][1][2][1][RTW89_CHILE][1][118] = 127, -+ [1][1][2][1][RTW89_QATAR][1][118] = 127, -+ [1][1][2][1][RTW89_QATAR][0][118] = 127, -+ [1][1][2][1][RTW89_UK][1][118] = 127, -+ [1][1][2][1][RTW89_UK][0][118] = 127, -+ [2][0][2][0][RTW89_FCC][1][3] = 46, -+ [2][0][2][0][RTW89_FCC][2][3] = 60, -+ [2][0][2][0][RTW89_ETSI][1][3] = 58, -+ [2][0][2][0][RTW89_ETSI][0][3] = 30, -+ [2][0][2][0][RTW89_MKK][1][3] = 58, -+ [2][0][2][0][RTW89_MKK][0][3] = 26, -+ [2][0][2][0][RTW89_IC][1][3] = 46, -+ [2][0][2][0][RTW89_KCC][1][3] = 50, -+ [2][0][2][0][RTW89_KCC][0][3] = 24, -+ [2][0][2][0][RTW89_ACMA][1][3] = 58, -+ [2][0][2][0][RTW89_ACMA][0][3] = 30, -+ [2][0][2][0][RTW89_CHILE][1][3] = 46, -+ [2][0][2][0][RTW89_QATAR][1][3] = 58, -+ [2][0][2][0][RTW89_QATAR][0][3] = 30, -+ [2][0][2][0][RTW89_UK][1][3] = 58, -+ [2][0][2][0][RTW89_UK][0][3] = 30, -+ [2][0][2][0][RTW89_FCC][1][11] = 46, -+ [2][0][2][0][RTW89_FCC][2][11] = 60, -+ [2][0][2][0][RTW89_ETSI][1][11] = 58, -+ [2][0][2][0][RTW89_ETSI][0][11] = 30, -+ [2][0][2][0][RTW89_MKK][1][11] = 58, -+ [2][0][2][0][RTW89_MKK][0][11] = 24, -+ [2][0][2][0][RTW89_IC][1][11] = 46, -+ [2][0][2][0][RTW89_KCC][1][11] = 50, -+ [2][0][2][0][RTW89_KCC][0][11] = 24, -+ [2][0][2][0][RTW89_ACMA][1][11] = 58, -+ [2][0][2][0][RTW89_ACMA][0][11] = 30, -+ [2][0][2][0][RTW89_CHILE][1][11] = 46, -+ [2][0][2][0][RTW89_QATAR][1][11] = 58, -+ [2][0][2][0][RTW89_QATAR][0][11] = 30, -+ [2][0][2][0][RTW89_UK][1][11] = 58, -+ [2][0][2][0][RTW89_UK][0][11] = 30, -+ [2][0][2][0][RTW89_FCC][1][18] = 46, -+ [2][0][2][0][RTW89_FCC][2][18] = 60, -+ [2][0][2][0][RTW89_ETSI][1][18] = 58, -+ [2][0][2][0][RTW89_ETSI][0][18] = 30, -+ [2][0][2][0][RTW89_MKK][1][18] = 58, -+ [2][0][2][0][RTW89_MKK][0][18] = 24, -+ [2][0][2][0][RTW89_IC][1][18] = 46, -+ [2][0][2][0][RTW89_KCC][1][18] = 50, -+ [2][0][2][0][RTW89_KCC][0][18] = 24, -+ [2][0][2][0][RTW89_ACMA][1][18] = 58, -+ [2][0][2][0][RTW89_ACMA][0][18] = 30, -+ [2][0][2][0][RTW89_CHILE][1][18] = 46, -+ [2][0][2][0][RTW89_QATAR][1][18] = 58, -+ [2][0][2][0][RTW89_QATAR][0][18] = 30, -+ [2][0][2][0][RTW89_UK][1][18] = 58, -+ [2][0][2][0][RTW89_UK][0][18] = 30, -+ [2][0][2][0][RTW89_FCC][1][26] = 46, -+ [2][0][2][0][RTW89_FCC][2][26] = 60, -+ [2][0][2][0][RTW89_ETSI][1][26] = 58, -+ [2][0][2][0][RTW89_ETSI][0][26] = 30, -+ [2][0][2][0][RTW89_MKK][1][26] = 58, -+ [2][0][2][0][RTW89_MKK][0][26] = 24, -+ [2][0][2][0][RTW89_IC][1][26] = 46, -+ [2][0][2][0][RTW89_KCC][1][26] = 50, -+ [2][0][2][0][RTW89_KCC][0][26] = 26, -+ [2][0][2][0][RTW89_ACMA][1][26] = 58, -+ [2][0][2][0][RTW89_ACMA][0][26] = 30, -+ [2][0][2][0][RTW89_CHILE][1][26] = 46, -+ [2][0][2][0][RTW89_QATAR][1][26] = 58, -+ [2][0][2][0][RTW89_QATAR][0][26] = 30, -+ [2][0][2][0][RTW89_UK][1][26] = 58, -+ [2][0][2][0][RTW89_UK][0][26] = 30, -+ [2][0][2][0][RTW89_FCC][1][33] = 46, -+ [2][0][2][0][RTW89_FCC][2][33] = 60, -+ [2][0][2][0][RTW89_ETSI][1][33] = 58, -+ [2][0][2][0][RTW89_ETSI][0][33] = 30, -+ [2][0][2][0][RTW89_MKK][1][33] = 58, -+ [2][0][2][0][RTW89_MKK][0][33] = 24, -+ [2][0][2][0][RTW89_IC][1][33] = 46, -+ [2][0][2][0][RTW89_KCC][1][33] = 50, -+ [2][0][2][0][RTW89_KCC][0][33] = 24, -+ [2][0][2][0][RTW89_ACMA][1][33] = 58, -+ [2][0][2][0][RTW89_ACMA][0][33] = 30, -+ [2][0][2][0][RTW89_CHILE][1][33] = 46, -+ [2][0][2][0][RTW89_QATAR][1][33] = 58, -+ [2][0][2][0][RTW89_QATAR][0][33] = 30, -+ [2][0][2][0][RTW89_UK][1][33] = 58, -+ [2][0][2][0][RTW89_UK][0][33] = 30, -+ [2][0][2][0][RTW89_FCC][1][41] = 46, -+ [2][0][2][0][RTW89_FCC][2][41] = 60, -+ [2][0][2][0][RTW89_ETSI][1][41] = 58, -+ [2][0][2][0][RTW89_ETSI][0][41] = 30, -+ [2][0][2][0][RTW89_MKK][1][41] = 58, -+ [2][0][2][0][RTW89_MKK][0][41] = 24, -+ [2][0][2][0][RTW89_IC][1][41] = 46, -+ [2][0][2][0][RTW89_KCC][1][41] = 50, -+ [2][0][2][0][RTW89_KCC][0][41] = 24, -+ [2][0][2][0][RTW89_ACMA][1][41] = 58, -+ [2][0][2][0][RTW89_ACMA][0][41] = 30, -+ [2][0][2][0][RTW89_CHILE][1][41] = 46, -+ [2][0][2][0][RTW89_QATAR][1][41] = 58, -+ [2][0][2][0][RTW89_QATAR][0][41] = 30, -+ [2][0][2][0][RTW89_UK][1][41] = 58, -+ [2][0][2][0][RTW89_UK][0][41] = 30, -+ [2][0][2][0][RTW89_FCC][1][48] = 46, -+ [2][0][2][0][RTW89_FCC][2][48] = 127, -+ [2][0][2][0][RTW89_ETSI][1][48] = 127, -+ [2][0][2][0][RTW89_ETSI][0][48] = 127, -+ [2][0][2][0][RTW89_MKK][1][48] = 127, -+ [2][0][2][0][RTW89_MKK][0][48] = 127, -+ [2][0][2][0][RTW89_IC][1][48] = 46, -+ [2][0][2][0][RTW89_KCC][1][48] = 48, -+ [2][0][2][0][RTW89_KCC][0][48] = 127, -+ [2][0][2][0][RTW89_ACMA][1][48] = 127, -+ [2][0][2][0][RTW89_ACMA][0][48] = 127, -+ [2][0][2][0][RTW89_CHILE][1][48] = 46, -+ [2][0][2][0][RTW89_QATAR][1][48] = 127, -+ [2][0][2][0][RTW89_QATAR][0][48] = 127, -+ [2][0][2][0][RTW89_UK][1][48] = 127, -+ [2][0][2][0][RTW89_UK][0][48] = 127, -+ [2][0][2][0][RTW89_FCC][1][56] = 46, -+ [2][0][2][0][RTW89_FCC][2][56] = 127, -+ [2][0][2][0][RTW89_ETSI][1][56] = 127, -+ [2][0][2][0][RTW89_ETSI][0][56] = 127, -+ [2][0][2][0][RTW89_MKK][1][56] = 127, -+ [2][0][2][0][RTW89_MKK][0][56] = 127, -+ [2][0][2][0][RTW89_IC][1][56] = 46, -+ [2][0][2][0][RTW89_KCC][1][56] = 48, -+ [2][0][2][0][RTW89_KCC][0][56] = 127, -+ [2][0][2][0][RTW89_ACMA][1][56] = 127, -+ [2][0][2][0][RTW89_ACMA][0][56] = 127, -+ [2][0][2][0][RTW89_CHILE][1][56] = 46, -+ [2][0][2][0][RTW89_QATAR][1][56] = 127, -+ [2][0][2][0][RTW89_QATAR][0][56] = 127, -+ [2][0][2][0][RTW89_UK][1][56] = 127, -+ [2][0][2][0][RTW89_UK][0][56] = 127, -+ [2][0][2][0][RTW89_FCC][1][63] = 46, -+ [2][0][2][0][RTW89_FCC][2][63] = 58, -+ [2][0][2][0][RTW89_ETSI][1][63] = 127, -+ [2][0][2][0][RTW89_ETSI][0][63] = 127, -+ [2][0][2][0][RTW89_MKK][1][63] = 127, -+ [2][0][2][0][RTW89_MKK][0][63] = 127, -+ [2][0][2][0][RTW89_IC][1][63] = 46, -+ [2][0][2][0][RTW89_KCC][1][63] = 48, -+ [2][0][2][0][RTW89_KCC][0][63] = 127, -+ [2][0][2][0][RTW89_ACMA][1][63] = 127, -+ [2][0][2][0][RTW89_ACMA][0][63] = 127, -+ [2][0][2][0][RTW89_CHILE][1][63] = 46, -+ [2][0][2][0][RTW89_QATAR][1][63] = 127, -+ [2][0][2][0][RTW89_QATAR][0][63] = 127, -+ [2][0][2][0][RTW89_UK][1][63] = 127, -+ [2][0][2][0][RTW89_UK][0][63] = 127, -+ [2][0][2][0][RTW89_FCC][1][71] = 46, -+ [2][0][2][0][RTW89_FCC][2][71] = 58, -+ [2][0][2][0][RTW89_ETSI][1][71] = 127, -+ [2][0][2][0][RTW89_ETSI][0][71] = 127, -+ [2][0][2][0][RTW89_MKK][1][71] = 127, -+ [2][0][2][0][RTW89_MKK][0][71] = 127, -+ [2][0][2][0][RTW89_IC][1][71] = 46, -+ [2][0][2][0][RTW89_KCC][1][71] = 48, -+ [2][0][2][0][RTW89_KCC][0][71] = 127, -+ [2][0][2][0][RTW89_ACMA][1][71] = 127, -+ [2][0][2][0][RTW89_ACMA][0][71] = 127, -+ [2][0][2][0][RTW89_CHILE][1][71] = 46, -+ [2][0][2][0][RTW89_QATAR][1][71] = 127, -+ [2][0][2][0][RTW89_QATAR][0][71] = 127, -+ [2][0][2][0][RTW89_UK][1][71] = 127, -+ [2][0][2][0][RTW89_UK][0][71] = 127, -+ [2][0][2][0][RTW89_FCC][1][78] = 46, -+ [2][0][2][0][RTW89_FCC][2][78] = 58, -+ [2][0][2][0][RTW89_ETSI][1][78] = 127, -+ [2][0][2][0][RTW89_ETSI][0][78] = 127, -+ [2][0][2][0][RTW89_MKK][1][78] = 127, -+ [2][0][2][0][RTW89_MKK][0][78] = 127, -+ [2][0][2][0][RTW89_IC][1][78] = 46, -+ [2][0][2][0][RTW89_KCC][1][78] = 52, -+ [2][0][2][0][RTW89_KCC][0][78] = 127, -+ [2][0][2][0][RTW89_ACMA][1][78] = 127, -+ [2][0][2][0][RTW89_ACMA][0][78] = 127, -+ [2][0][2][0][RTW89_CHILE][1][78] = 46, -+ [2][0][2][0][RTW89_QATAR][1][78] = 127, -+ [2][0][2][0][RTW89_QATAR][0][78] = 127, -+ [2][0][2][0][RTW89_UK][1][78] = 127, -+ [2][0][2][0][RTW89_UK][0][78] = 127, -+ [2][0][2][0][RTW89_FCC][1][86] = 46, -+ [2][0][2][0][RTW89_FCC][2][86] = 127, -+ [2][0][2][0][RTW89_ETSI][1][86] = 127, -+ [2][0][2][0][RTW89_ETSI][0][86] = 127, -+ [2][0][2][0][RTW89_MKK][1][86] = 127, -+ [2][0][2][0][RTW89_MKK][0][86] = 127, -+ [2][0][2][0][RTW89_IC][1][86] = 46, -+ [2][0][2][0][RTW89_KCC][1][86] = 52, -+ [2][0][2][0][RTW89_KCC][0][86] = 127, -+ [2][0][2][0][RTW89_ACMA][1][86] = 127, -+ [2][0][2][0][RTW89_ACMA][0][86] = 127, -+ [2][0][2][0][RTW89_CHILE][1][86] = 46, -+ [2][0][2][0][RTW89_QATAR][1][86] = 127, -+ [2][0][2][0][RTW89_QATAR][0][86] = 127, -+ [2][0][2][0][RTW89_UK][1][86] = 127, -+ [2][0][2][0][RTW89_UK][0][86] = 127, -+ [2][0][2][0][RTW89_FCC][1][93] = 46, -+ [2][0][2][0][RTW89_FCC][2][93] = 127, -+ [2][0][2][0][RTW89_ETSI][1][93] = 127, -+ [2][0][2][0][RTW89_ETSI][0][93] = 127, -+ [2][0][2][0][RTW89_MKK][1][93] = 127, -+ [2][0][2][0][RTW89_MKK][0][93] = 127, -+ [2][0][2][0][RTW89_IC][1][93] = 46, -+ [2][0][2][0][RTW89_KCC][1][93] = 50, -+ [2][0][2][0][RTW89_KCC][0][93] = 127, -+ [2][0][2][0][RTW89_ACMA][1][93] = 127, -+ [2][0][2][0][RTW89_ACMA][0][93] = 127, -+ [2][0][2][0][RTW89_CHILE][1][93] = 46, -+ [2][0][2][0][RTW89_QATAR][1][93] = 127, -+ [2][0][2][0][RTW89_QATAR][0][93] = 127, -+ [2][0][2][0][RTW89_UK][1][93] = 127, -+ [2][0][2][0][RTW89_UK][0][93] = 127, -+ [2][0][2][0][RTW89_FCC][1][101] = 44, -+ [2][0][2][0][RTW89_FCC][2][101] = 127, -+ [2][0][2][0][RTW89_ETSI][1][101] = 127, -+ [2][0][2][0][RTW89_ETSI][0][101] = 127, -+ [2][0][2][0][RTW89_MKK][1][101] = 127, -+ [2][0][2][0][RTW89_MKK][0][101] = 127, -+ [2][0][2][0][RTW89_IC][1][101] = 44, -+ [2][0][2][0][RTW89_KCC][1][101] = 50, -+ [2][0][2][0][RTW89_KCC][0][101] = 127, -+ [2][0][2][0][RTW89_ACMA][1][101] = 127, -+ [2][0][2][0][RTW89_ACMA][0][101] = 127, -+ [2][0][2][0][RTW89_CHILE][1][101] = 44, -+ [2][0][2][0][RTW89_QATAR][1][101] = 127, -+ [2][0][2][0][RTW89_QATAR][0][101] = 127, -+ [2][0][2][0][RTW89_UK][1][101] = 127, -+ [2][0][2][0][RTW89_UK][0][101] = 127, -+ [2][0][2][0][RTW89_FCC][1][108] = 127, -+ [2][0][2][0][RTW89_FCC][2][108] = 127, -+ [2][0][2][0][RTW89_ETSI][1][108] = 127, -+ [2][0][2][0][RTW89_ETSI][0][108] = 127, -+ [2][0][2][0][RTW89_MKK][1][108] = 127, -+ [2][0][2][0][RTW89_MKK][0][108] = 127, -+ [2][0][2][0][RTW89_IC][1][108] = 127, -+ [2][0][2][0][RTW89_KCC][1][108] = 127, -+ [2][0][2][0][RTW89_KCC][0][108] = 127, -+ [2][0][2][0][RTW89_ACMA][1][108] = 127, -+ [2][0][2][0][RTW89_ACMA][0][108] = 127, -+ [2][0][2][0][RTW89_CHILE][1][108] = 127, -+ [2][0][2][0][RTW89_QATAR][1][108] = 127, -+ [2][0][2][0][RTW89_QATAR][0][108] = 127, -+ [2][0][2][0][RTW89_UK][1][108] = 127, -+ [2][0][2][0][RTW89_UK][0][108] = 127, -+ [2][0][2][0][RTW89_FCC][1][116] = 127, -+ [2][0][2][0][RTW89_FCC][2][116] = 127, -+ [2][0][2][0][RTW89_ETSI][1][116] = 127, -+ [2][0][2][0][RTW89_ETSI][0][116] = 127, -+ [2][0][2][0][RTW89_MKK][1][116] = 127, -+ [2][0][2][0][RTW89_MKK][0][116] = 127, -+ [2][0][2][0][RTW89_IC][1][116] = 127, -+ [2][0][2][0][RTW89_KCC][1][116] = 127, -+ [2][0][2][0][RTW89_KCC][0][116] = 127, -+ [2][0][2][0][RTW89_ACMA][1][116] = 127, -+ [2][0][2][0][RTW89_ACMA][0][116] = 127, -+ [2][0][2][0][RTW89_CHILE][1][116] = 127, -+ [2][0][2][0][RTW89_QATAR][1][116] = 127, -+ [2][0][2][0][RTW89_QATAR][0][116] = 127, -+ [2][0][2][0][RTW89_UK][1][116] = 127, -+ [2][0][2][0][RTW89_UK][0][116] = 127, -+ [2][1][2][0][RTW89_FCC][1][3] = 22, -+ [2][1][2][0][RTW89_FCC][2][3] = 50, -+ [2][1][2][0][RTW89_ETSI][1][3] = 54, -+ [2][1][2][0][RTW89_ETSI][0][3] = 16, -+ [2][1][2][0][RTW89_MKK][1][3] = 52, -+ [2][1][2][0][RTW89_MKK][0][3] = 14, -+ [2][1][2][0][RTW89_IC][1][3] = 22, -+ [2][1][2][0][RTW89_KCC][1][3] = 38, -+ [2][1][2][0][RTW89_KCC][0][3] = 12, -+ [2][1][2][0][RTW89_ACMA][1][3] = 54, -+ [2][1][2][0][RTW89_ACMA][0][3] = 16, -+ [2][1][2][0][RTW89_CHILE][1][3] = 22, -+ [2][1][2][0][RTW89_QATAR][1][3] = 54, -+ [2][1][2][0][RTW89_QATAR][0][3] = 16, -+ [2][1][2][0][RTW89_UK][1][3] = 54, -+ [2][1][2][0][RTW89_UK][0][3] = 16, -+ [2][1][2][0][RTW89_FCC][1][11] = 20, -+ [2][1][2][0][RTW89_FCC][2][11] = 50, -+ [2][1][2][0][RTW89_ETSI][1][11] = 54, -+ [2][1][2][0][RTW89_ETSI][0][11] = 16, -+ [2][1][2][0][RTW89_MKK][1][11] = 52, -+ [2][1][2][0][RTW89_MKK][0][11] = 12, -+ [2][1][2][0][RTW89_IC][1][11] = 20, -+ [2][1][2][0][RTW89_KCC][1][11] = 38, -+ [2][1][2][0][RTW89_KCC][0][11] = 12, -+ [2][1][2][0][RTW89_ACMA][1][11] = 54, -+ [2][1][2][0][RTW89_ACMA][0][11] = 16, -+ [2][1][2][0][RTW89_CHILE][1][11] = 20, -+ [2][1][2][0][RTW89_QATAR][1][11] = 54, -+ [2][1][2][0][RTW89_QATAR][0][11] = 16, -+ [2][1][2][0][RTW89_UK][1][11] = 54, -+ [2][1][2][0][RTW89_UK][0][11] = 16, -+ [2][1][2][0][RTW89_FCC][1][18] = 20, -+ [2][1][2][0][RTW89_FCC][2][18] = 50, -+ [2][1][2][0][RTW89_ETSI][1][18] = 54, -+ [2][1][2][0][RTW89_ETSI][0][18] = 16, -+ [2][1][2][0][RTW89_MKK][1][18] = 52, -+ [2][1][2][0][RTW89_MKK][0][18] = 12, -+ [2][1][2][0][RTW89_IC][1][18] = 20, -+ [2][1][2][0][RTW89_KCC][1][18] = 38, -+ [2][1][2][0][RTW89_KCC][0][18] = 12, -+ [2][1][2][0][RTW89_ACMA][1][18] = 54, -+ [2][1][2][0][RTW89_ACMA][0][18] = 16, -+ [2][1][2][0][RTW89_CHILE][1][18] = 20, -+ [2][1][2][0][RTW89_QATAR][1][18] = 54, -+ [2][1][2][0][RTW89_QATAR][0][18] = 16, -+ [2][1][2][0][RTW89_UK][1][18] = 54, -+ [2][1][2][0][RTW89_UK][0][18] = 16, -+ [2][1][2][0][RTW89_FCC][1][26] = 20, -+ [2][1][2][0][RTW89_FCC][2][26] = 60, -+ [2][1][2][0][RTW89_ETSI][1][26] = 54, -+ [2][1][2][0][RTW89_ETSI][0][26] = 16, -+ [2][1][2][0][RTW89_MKK][1][26] = 52, -+ [2][1][2][0][RTW89_MKK][0][26] = 12, -+ [2][1][2][0][RTW89_IC][1][26] = 20, -+ [2][1][2][0][RTW89_KCC][1][26] = 38, -+ [2][1][2][0][RTW89_KCC][0][26] = 12, -+ [2][1][2][0][RTW89_ACMA][1][26] = 54, -+ [2][1][2][0][RTW89_ACMA][0][26] = 16, -+ [2][1][2][0][RTW89_CHILE][1][26] = 20, -+ [2][1][2][0][RTW89_QATAR][1][26] = 54, -+ [2][1][2][0][RTW89_QATAR][0][26] = 16, -+ [2][1][2][0][RTW89_UK][1][26] = 54, -+ [2][1][2][0][RTW89_UK][0][26] = 16, -+ [2][1][2][0][RTW89_FCC][1][33] = 20, -+ [2][1][2][0][RTW89_FCC][2][33] = 60, -+ [2][1][2][0][RTW89_ETSI][1][33] = 54, -+ [2][1][2][0][RTW89_ETSI][0][33] = 16, -+ [2][1][2][0][RTW89_MKK][1][33] = 48, -+ [2][1][2][0][RTW89_MKK][0][33] = 12, -+ [2][1][2][0][RTW89_IC][1][33] = 20, -+ [2][1][2][0][RTW89_KCC][1][33] = 38, -+ [2][1][2][0][RTW89_KCC][0][33] = 12, -+ [2][1][2][0][RTW89_ACMA][1][33] = 54, -+ [2][1][2][0][RTW89_ACMA][0][33] = 16, -+ [2][1][2][0][RTW89_CHILE][1][33] = 20, -+ [2][1][2][0][RTW89_QATAR][1][33] = 54, -+ [2][1][2][0][RTW89_QATAR][0][33] = 16, -+ [2][1][2][0][RTW89_UK][1][33] = 54, -+ [2][1][2][0][RTW89_UK][0][33] = 16, -+ [2][1][2][0][RTW89_FCC][1][41] = 22, -+ [2][1][2][0][RTW89_FCC][2][41] = 60, -+ [2][1][2][0][RTW89_ETSI][1][41] = 54, -+ [2][1][2][0][RTW89_ETSI][0][41] = 18, -+ [2][1][2][0][RTW89_MKK][1][41] = 48, -+ [2][1][2][0][RTW89_MKK][0][41] = 12, -+ [2][1][2][0][RTW89_IC][1][41] = 22, -+ [2][1][2][0][RTW89_KCC][1][41] = 38, -+ [2][1][2][0][RTW89_KCC][0][41] = 12, -+ [2][1][2][0][RTW89_ACMA][1][41] = 54, -+ [2][1][2][0][RTW89_ACMA][0][41] = 18, -+ [2][1][2][0][RTW89_CHILE][1][41] = 22, -+ [2][1][2][0][RTW89_QATAR][1][41] = 54, -+ [2][1][2][0][RTW89_QATAR][0][41] = 18, -+ [2][1][2][0][RTW89_UK][1][41] = 54, -+ [2][1][2][0][RTW89_UK][0][41] = 18, -+ [2][1][2][0][RTW89_FCC][1][48] = 22, -+ [2][1][2][0][RTW89_FCC][2][48] = 127, -+ [2][1][2][0][RTW89_ETSI][1][48] = 127, -+ [2][1][2][0][RTW89_ETSI][0][48] = 127, -+ [2][1][2][0][RTW89_MKK][1][48] = 127, -+ [2][1][2][0][RTW89_MKK][0][48] = 127, -+ [2][1][2][0][RTW89_IC][1][48] = 22, -+ [2][1][2][0][RTW89_KCC][1][48] = 38, -+ [2][1][2][0][RTW89_KCC][0][48] = 127, -+ [2][1][2][0][RTW89_ACMA][1][48] = 127, -+ [2][1][2][0][RTW89_ACMA][0][48] = 127, -+ [2][1][2][0][RTW89_CHILE][1][48] = 22, -+ [2][1][2][0][RTW89_QATAR][1][48] = 127, -+ [2][1][2][0][RTW89_QATAR][0][48] = 127, -+ [2][1][2][0][RTW89_UK][1][48] = 127, -+ [2][1][2][0][RTW89_UK][0][48] = 127, -+ [2][1][2][0][RTW89_FCC][1][56] = 20, -+ [2][1][2][0][RTW89_FCC][2][56] = 127, -+ [2][1][2][0][RTW89_ETSI][1][56] = 127, -+ [2][1][2][0][RTW89_ETSI][0][56] = 127, -+ [2][1][2][0][RTW89_MKK][1][56] = 127, -+ [2][1][2][0][RTW89_MKK][0][56] = 127, -+ [2][1][2][0][RTW89_IC][1][56] = 20, -+ [2][1][2][0][RTW89_KCC][1][56] = 38, -+ [2][1][2][0][RTW89_KCC][0][56] = 127, -+ [2][1][2][0][RTW89_ACMA][1][56] = 127, -+ [2][1][2][0][RTW89_ACMA][0][56] = 127, -+ [2][1][2][0][RTW89_CHILE][1][56] = 20, -+ [2][1][2][0][RTW89_QATAR][1][56] = 127, -+ [2][1][2][0][RTW89_QATAR][0][56] = 127, -+ [2][1][2][0][RTW89_UK][1][56] = 127, -+ [2][1][2][0][RTW89_UK][0][56] = 127, -+ [2][1][2][0][RTW89_FCC][1][63] = 22, -+ [2][1][2][0][RTW89_FCC][2][63] = 58, -+ [2][1][2][0][RTW89_ETSI][1][63] = 127, -+ [2][1][2][0][RTW89_ETSI][0][63] = 127, -+ [2][1][2][0][RTW89_MKK][1][63] = 127, -+ [2][1][2][0][RTW89_MKK][0][63] = 127, -+ [2][1][2][0][RTW89_IC][1][63] = 22, -+ [2][1][2][0][RTW89_KCC][1][63] = 38, -+ [2][1][2][0][RTW89_KCC][0][63] = 127, -+ [2][1][2][0][RTW89_ACMA][1][63] = 127, -+ [2][1][2][0][RTW89_ACMA][0][63] = 127, -+ [2][1][2][0][RTW89_CHILE][1][63] = 22, -+ [2][1][2][0][RTW89_QATAR][1][63] = 127, -+ [2][1][2][0][RTW89_QATAR][0][63] = 127, -+ [2][1][2][0][RTW89_UK][1][63] = 127, -+ [2][1][2][0][RTW89_UK][0][63] = 127, -+ [2][1][2][0][RTW89_FCC][1][71] = 20, -+ [2][1][2][0][RTW89_FCC][2][71] = 58, -+ [2][1][2][0][RTW89_ETSI][1][71] = 127, -+ [2][1][2][0][RTW89_ETSI][0][71] = 127, -+ [2][1][2][0][RTW89_MKK][1][71] = 127, -+ [2][1][2][0][RTW89_MKK][0][71] = 127, -+ [2][1][2][0][RTW89_IC][1][71] = 20, -+ [2][1][2][0][RTW89_KCC][1][71] = 38, -+ [2][1][2][0][RTW89_KCC][0][71] = 127, -+ [2][1][2][0][RTW89_ACMA][1][71] = 127, -+ [2][1][2][0][RTW89_ACMA][0][71] = 127, -+ [2][1][2][0][RTW89_CHILE][1][71] = 20, -+ [2][1][2][0][RTW89_QATAR][1][71] = 127, -+ [2][1][2][0][RTW89_QATAR][0][71] = 127, -+ [2][1][2][0][RTW89_UK][1][71] = 127, -+ [2][1][2][0][RTW89_UK][0][71] = 127, -+ [2][1][2][0][RTW89_FCC][1][78] = 20, -+ [2][1][2][0][RTW89_FCC][2][78] = 58, -+ [2][1][2][0][RTW89_ETSI][1][78] = 127, -+ [2][1][2][0][RTW89_ETSI][0][78] = 127, -+ [2][1][2][0][RTW89_MKK][1][78] = 127, -+ [2][1][2][0][RTW89_MKK][0][78] = 127, -+ [2][1][2][0][RTW89_IC][1][78] = 20, -+ [2][1][2][0][RTW89_KCC][1][78] = 38, -+ [2][1][2][0][RTW89_KCC][0][78] = 127, -+ [2][1][2][0][RTW89_ACMA][1][78] = 127, -+ [2][1][2][0][RTW89_ACMA][0][78] = 127, -+ [2][1][2][0][RTW89_CHILE][1][78] = 20, -+ [2][1][2][0][RTW89_QATAR][1][78] = 127, -+ [2][1][2][0][RTW89_QATAR][0][78] = 127, -+ [2][1][2][0][RTW89_UK][1][78] = 127, -+ [2][1][2][0][RTW89_UK][0][78] = 127, -+ [2][1][2][0][RTW89_FCC][1][86] = 20, -+ [2][1][2][0][RTW89_FCC][2][86] = 127, -+ [2][1][2][0][RTW89_ETSI][1][86] = 127, -+ [2][1][2][0][RTW89_ETSI][0][86] = 127, -+ [2][1][2][0][RTW89_MKK][1][86] = 127, -+ [2][1][2][0][RTW89_MKK][0][86] = 127, -+ [2][1][2][0][RTW89_IC][1][86] = 20, -+ [2][1][2][0][RTW89_KCC][1][86] = 38, -+ [2][1][2][0][RTW89_KCC][0][86] = 127, -+ [2][1][2][0][RTW89_ACMA][1][86] = 127, -+ [2][1][2][0][RTW89_ACMA][0][86] = 127, -+ [2][1][2][0][RTW89_CHILE][1][86] = 20, -+ [2][1][2][0][RTW89_QATAR][1][86] = 127, -+ [2][1][2][0][RTW89_QATAR][0][86] = 127, -+ [2][1][2][0][RTW89_UK][1][86] = 127, -+ [2][1][2][0][RTW89_UK][0][86] = 127, -+ [2][1][2][0][RTW89_FCC][1][93] = 22, -+ [2][1][2][0][RTW89_FCC][2][93] = 127, -+ [2][1][2][0][RTW89_ETSI][1][93] = 127, -+ [2][1][2][0][RTW89_ETSI][0][93] = 127, -+ [2][1][2][0][RTW89_MKK][1][93] = 127, -+ [2][1][2][0][RTW89_MKK][0][93] = 127, -+ [2][1][2][0][RTW89_IC][1][93] = 22, -+ [2][1][2][0][RTW89_KCC][1][93] = 38, -+ [2][1][2][0][RTW89_KCC][0][93] = 127, -+ [2][1][2][0][RTW89_ACMA][1][93] = 127, -+ [2][1][2][0][RTW89_ACMA][0][93] = 127, -+ [2][1][2][0][RTW89_CHILE][1][93] = 22, -+ [2][1][2][0][RTW89_QATAR][1][93] = 127, -+ [2][1][2][0][RTW89_QATAR][0][93] = 127, -+ [2][1][2][0][RTW89_UK][1][93] = 127, -+ [2][1][2][0][RTW89_UK][0][93] = 127, -+ [2][1][2][0][RTW89_FCC][1][101] = 22, -+ [2][1][2][0][RTW89_FCC][2][101] = 127, -+ [2][1][2][0][RTW89_ETSI][1][101] = 127, -+ [2][1][2][0][RTW89_ETSI][0][101] = 127, -+ [2][1][2][0][RTW89_MKK][1][101] = 127, -+ [2][1][2][0][RTW89_MKK][0][101] = 127, -+ [2][1][2][0][RTW89_IC][1][101] = 22, -+ [2][1][2][0][RTW89_KCC][1][101] = 38, -+ [2][1][2][0][RTW89_KCC][0][101] = 127, -+ [2][1][2][0][RTW89_ACMA][1][101] = 127, -+ [2][1][2][0][RTW89_ACMA][0][101] = 127, -+ [2][1][2][0][RTW89_CHILE][1][101] = 22, -+ [2][1][2][0][RTW89_QATAR][1][101] = 127, -+ [2][1][2][0][RTW89_QATAR][0][101] = 127, -+ [2][1][2][0][RTW89_UK][1][101] = 127, -+ [2][1][2][0][RTW89_UK][0][101] = 127, -+ [2][1][2][0][RTW89_FCC][1][108] = 127, -+ [2][1][2][0][RTW89_FCC][2][108] = 127, -+ [2][1][2][0][RTW89_ETSI][1][108] = 127, -+ [2][1][2][0][RTW89_ETSI][0][108] = 127, -+ [2][1][2][0][RTW89_MKK][1][108] = 127, -+ [2][1][2][0][RTW89_MKK][0][108] = 127, -+ [2][1][2][0][RTW89_IC][1][108] = 127, -+ [2][1][2][0][RTW89_KCC][1][108] = 127, -+ [2][1][2][0][RTW89_KCC][0][108] = 127, -+ [2][1][2][0][RTW89_ACMA][1][108] = 127, -+ [2][1][2][0][RTW89_ACMA][0][108] = 127, -+ [2][1][2][0][RTW89_CHILE][1][108] = 127, -+ [2][1][2][0][RTW89_QATAR][1][108] = 127, -+ [2][1][2][0][RTW89_QATAR][0][108] = 127, -+ [2][1][2][0][RTW89_UK][1][108] = 127, -+ [2][1][2][0][RTW89_UK][0][108] = 127, -+ [2][1][2][0][RTW89_FCC][1][116] = 127, -+ [2][1][2][0][RTW89_FCC][2][116] = 127, -+ [2][1][2][0][RTW89_ETSI][1][116] = 127, -+ [2][1][2][0][RTW89_ETSI][0][116] = 127, -+ [2][1][2][0][RTW89_MKK][1][116] = 127, -+ [2][1][2][0][RTW89_MKK][0][116] = 127, -+ [2][1][2][0][RTW89_IC][1][116] = 127, -+ [2][1][2][0][RTW89_KCC][1][116] = 127, -+ [2][1][2][0][RTW89_KCC][0][116] = 127, -+ [2][1][2][0][RTW89_ACMA][1][116] = 127, -+ [2][1][2][0][RTW89_ACMA][0][116] = 127, -+ [2][1][2][0][RTW89_CHILE][1][116] = 127, -+ [2][1][2][0][RTW89_QATAR][1][116] = 127, -+ [2][1][2][0][RTW89_QATAR][0][116] = 127, -+ [2][1][2][0][RTW89_UK][1][116] = 127, -+ [2][1][2][0][RTW89_UK][0][116] = 127, -+ [2][1][2][1][RTW89_FCC][1][3] = 22, -+ [2][1][2][1][RTW89_FCC][2][3] = 50, -+ [2][1][2][1][RTW89_ETSI][1][3] = 42, -+ [2][1][2][1][RTW89_ETSI][0][3] = 6, -+ [2][1][2][1][RTW89_MKK][1][3] = 52, -+ [2][1][2][1][RTW89_MKK][0][3] = 14, -+ [2][1][2][1][RTW89_IC][1][3] = 22, -+ [2][1][2][1][RTW89_KCC][1][3] = 38, -+ [2][1][2][1][RTW89_KCC][0][3] = 12, -+ [2][1][2][1][RTW89_ACMA][1][3] = 42, -+ [2][1][2][1][RTW89_ACMA][0][3] = 6, -+ [2][1][2][1][RTW89_CHILE][1][3] = 22, -+ [2][1][2][1][RTW89_QATAR][1][3] = 42, -+ [2][1][2][1][RTW89_QATAR][0][3] = 6, -+ [2][1][2][1][RTW89_UK][1][3] = 42, -+ [2][1][2][1][RTW89_UK][0][3] = 6, -+ [2][1][2][1][RTW89_FCC][1][11] = 20, -+ [2][1][2][1][RTW89_FCC][2][11] = 50, -+ [2][1][2][1][RTW89_ETSI][1][11] = 42, -+ [2][1][2][1][RTW89_ETSI][0][11] = 6, -+ [2][1][2][1][RTW89_MKK][1][11] = 52, -+ [2][1][2][1][RTW89_MKK][0][11] = 12, -+ [2][1][2][1][RTW89_IC][1][11] = 20, -+ [2][1][2][1][RTW89_KCC][1][11] = 38, -+ [2][1][2][1][RTW89_KCC][0][11] = 12, -+ [2][1][2][1][RTW89_ACMA][1][11] = 42, -+ [2][1][2][1][RTW89_ACMA][0][11] = 6, -+ [2][1][2][1][RTW89_CHILE][1][11] = 20, -+ [2][1][2][1][RTW89_QATAR][1][11] = 42, -+ [2][1][2][1][RTW89_QATAR][0][11] = 6, -+ [2][1][2][1][RTW89_UK][1][11] = 42, -+ [2][1][2][1][RTW89_UK][0][11] = 6, -+ [2][1][2][1][RTW89_FCC][1][18] = 20, -+ [2][1][2][1][RTW89_FCC][2][18] = 50, -+ [2][1][2][1][RTW89_ETSI][1][18] = 42, -+ [2][1][2][1][RTW89_ETSI][0][18] = 6, -+ [2][1][2][1][RTW89_MKK][1][18] = 52, -+ [2][1][2][1][RTW89_MKK][0][18] = 12, -+ [2][1][2][1][RTW89_IC][1][18] = 20, -+ [2][1][2][1][RTW89_KCC][1][18] = 38, -+ [2][1][2][1][RTW89_KCC][0][18] = 12, -+ [2][1][2][1][RTW89_ACMA][1][18] = 42, -+ [2][1][2][1][RTW89_ACMA][0][18] = 6, -+ [2][1][2][1][RTW89_CHILE][1][18] = 20, -+ [2][1][2][1][RTW89_QATAR][1][18] = 42, -+ [2][1][2][1][RTW89_QATAR][0][18] = 6, -+ [2][1][2][1][RTW89_UK][1][18] = 42, -+ [2][1][2][1][RTW89_UK][0][18] = 6, -+ [2][1][2][1][RTW89_FCC][1][26] = 20, -+ [2][1][2][1][RTW89_FCC][2][26] = 60, -+ [2][1][2][1][RTW89_ETSI][1][26] = 42, -+ [2][1][2][1][RTW89_ETSI][0][26] = 6, -+ [2][1][2][1][RTW89_MKK][1][26] = 52, -+ [2][1][2][1][RTW89_MKK][0][26] = 12, -+ [2][1][2][1][RTW89_IC][1][26] = 20, -+ [2][1][2][1][RTW89_KCC][1][26] = 38, -+ [2][1][2][1][RTW89_KCC][0][26] = 12, -+ [2][1][2][1][RTW89_ACMA][1][26] = 42, -+ [2][1][2][1][RTW89_ACMA][0][26] = 6, -+ [2][1][2][1][RTW89_CHILE][1][26] = 20, -+ [2][1][2][1][RTW89_QATAR][1][26] = 42, -+ [2][1][2][1][RTW89_QATAR][0][26] = 6, -+ [2][1][2][1][RTW89_UK][1][26] = 42, -+ [2][1][2][1][RTW89_UK][0][26] = 6, -+ [2][1][2][1][RTW89_FCC][1][33] = 20, -+ [2][1][2][1][RTW89_FCC][2][33] = 60, -+ [2][1][2][1][RTW89_ETSI][1][33] = 42, -+ [2][1][2][1][RTW89_ETSI][0][33] = 6, -+ [2][1][2][1][RTW89_MKK][1][33] = 48, -+ [2][1][2][1][RTW89_MKK][0][33] = 12, -+ [2][1][2][1][RTW89_IC][1][33] = 20, -+ [2][1][2][1][RTW89_KCC][1][33] = 38, -+ [2][1][2][1][RTW89_KCC][0][33] = 12, -+ [2][1][2][1][RTW89_ACMA][1][33] = 42, -+ [2][1][2][1][RTW89_ACMA][0][33] = 6, -+ [2][1][2][1][RTW89_CHILE][1][33] = 20, -+ [2][1][2][1][RTW89_QATAR][1][33] = 42, -+ [2][1][2][1][RTW89_QATAR][0][33] = 6, -+ [2][1][2][1][RTW89_UK][1][33] = 42, -+ [2][1][2][1][RTW89_UK][0][33] = 6, -+ [2][1][2][1][RTW89_FCC][1][41] = 22, -+ [2][1][2][1][RTW89_FCC][2][41] = 60, -+ [2][1][2][1][RTW89_ETSI][1][41] = 42, -+ [2][1][2][1][RTW89_ETSI][0][41] = 6, -+ [2][1][2][1][RTW89_MKK][1][41] = 48, -+ [2][1][2][1][RTW89_MKK][0][41] = 12, -+ [2][1][2][1][RTW89_IC][1][41] = 22, -+ [2][1][2][1][RTW89_KCC][1][41] = 38, -+ [2][1][2][1][RTW89_KCC][0][41] = 12, -+ [2][1][2][1][RTW89_ACMA][1][41] = 42, -+ [2][1][2][1][RTW89_ACMA][0][41] = 6, -+ [2][1][2][1][RTW89_CHILE][1][41] = 22, -+ [2][1][2][1][RTW89_QATAR][1][41] = 42, -+ [2][1][2][1][RTW89_QATAR][0][41] = 6, -+ [2][1][2][1][RTW89_UK][1][41] = 42, -+ [2][1][2][1][RTW89_UK][0][41] = 6, -+ [2][1][2][1][RTW89_FCC][1][48] = 22, -+ [2][1][2][1][RTW89_FCC][2][48] = 127, -+ [2][1][2][1][RTW89_ETSI][1][48] = 127, -+ [2][1][2][1][RTW89_ETSI][0][48] = 127, -+ [2][1][2][1][RTW89_MKK][1][48] = 127, -+ [2][1][2][1][RTW89_MKK][0][48] = 127, -+ [2][1][2][1][RTW89_IC][1][48] = 22, -+ [2][1][2][1][RTW89_KCC][1][48] = 38, -+ [2][1][2][1][RTW89_KCC][0][48] = 127, -+ [2][1][2][1][RTW89_ACMA][1][48] = 127, -+ [2][1][2][1][RTW89_ACMA][0][48] = 127, -+ [2][1][2][1][RTW89_CHILE][1][48] = 22, -+ [2][1][2][1][RTW89_QATAR][1][48] = 127, -+ [2][1][2][1][RTW89_QATAR][0][48] = 127, -+ [2][1][2][1][RTW89_UK][1][48] = 127, -+ [2][1][2][1][RTW89_UK][0][48] = 127, -+ [2][1][2][1][RTW89_FCC][1][56] = 20, -+ [2][1][2][1][RTW89_FCC][2][56] = 127, -+ [2][1][2][1][RTW89_ETSI][1][56] = 127, -+ [2][1][2][1][RTW89_ETSI][0][56] = 127, -+ [2][1][2][1][RTW89_MKK][1][56] = 127, -+ [2][1][2][1][RTW89_MKK][0][56] = 127, -+ [2][1][2][1][RTW89_IC][1][56] = 20, -+ [2][1][2][1][RTW89_KCC][1][56] = 38, -+ [2][1][2][1][RTW89_KCC][0][56] = 127, -+ [2][1][2][1][RTW89_ACMA][1][56] = 127, -+ [2][1][2][1][RTW89_ACMA][0][56] = 127, -+ [2][1][2][1][RTW89_CHILE][1][56] = 20, -+ [2][1][2][1][RTW89_QATAR][1][56] = 127, -+ [2][1][2][1][RTW89_QATAR][0][56] = 127, -+ [2][1][2][1][RTW89_UK][1][56] = 127, -+ [2][1][2][1][RTW89_UK][0][56] = 127, -+ [2][1][2][1][RTW89_FCC][1][63] = 22, -+ [2][1][2][1][RTW89_FCC][2][63] = 58, -+ [2][1][2][1][RTW89_ETSI][1][63] = 127, -+ [2][1][2][1][RTW89_ETSI][0][63] = 127, -+ [2][1][2][1][RTW89_MKK][1][63] = 127, -+ [2][1][2][1][RTW89_MKK][0][63] = 127, -+ [2][1][2][1][RTW89_IC][1][63] = 22, -+ [2][1][2][1][RTW89_KCC][1][63] = 38, -+ [2][1][2][1][RTW89_KCC][0][63] = 127, -+ [2][1][2][1][RTW89_ACMA][1][63] = 127, -+ [2][1][2][1][RTW89_ACMA][0][63] = 127, -+ [2][1][2][1][RTW89_CHILE][1][63] = 22, -+ [2][1][2][1][RTW89_QATAR][1][63] = 127, -+ [2][1][2][1][RTW89_QATAR][0][63] = 127, -+ [2][1][2][1][RTW89_UK][1][63] = 127, -+ [2][1][2][1][RTW89_UK][0][63] = 127, -+ [2][1][2][1][RTW89_FCC][1][71] = 20, -+ [2][1][2][1][RTW89_FCC][2][71] = 58, -+ [2][1][2][1][RTW89_ETSI][1][71] = 127, -+ [2][1][2][1][RTW89_ETSI][0][71] = 127, -+ [2][1][2][1][RTW89_MKK][1][71] = 127, -+ [2][1][2][1][RTW89_MKK][0][71] = 127, -+ [2][1][2][1][RTW89_IC][1][71] = 20, -+ [2][1][2][1][RTW89_KCC][1][71] = 38, -+ [2][1][2][1][RTW89_KCC][0][71] = 127, -+ [2][1][2][1][RTW89_ACMA][1][71] = 127, -+ [2][1][2][1][RTW89_ACMA][0][71] = 127, -+ [2][1][2][1][RTW89_CHILE][1][71] = 20, -+ [2][1][2][1][RTW89_QATAR][1][71] = 127, -+ [2][1][2][1][RTW89_QATAR][0][71] = 127, -+ [2][1][2][1][RTW89_UK][1][71] = 127, -+ [2][1][2][1][RTW89_UK][0][71] = 127, -+ [2][1][2][1][RTW89_FCC][1][78] = 20, -+ [2][1][2][1][RTW89_FCC][2][78] = 58, -+ [2][1][2][1][RTW89_ETSI][1][78] = 127, -+ [2][1][2][1][RTW89_ETSI][0][78] = 127, -+ [2][1][2][1][RTW89_MKK][1][78] = 127, -+ [2][1][2][1][RTW89_MKK][0][78] = 127, -+ [2][1][2][1][RTW89_IC][1][78] = 20, -+ [2][1][2][1][RTW89_KCC][1][78] = 38, -+ [2][1][2][1][RTW89_KCC][0][78] = 127, -+ [2][1][2][1][RTW89_ACMA][1][78] = 127, -+ [2][1][2][1][RTW89_ACMA][0][78] = 127, -+ [2][1][2][1][RTW89_CHILE][1][78] = 20, -+ [2][1][2][1][RTW89_QATAR][1][78] = 127, -+ [2][1][2][1][RTW89_QATAR][0][78] = 127, -+ [2][1][2][1][RTW89_UK][1][78] = 127, -+ [2][1][2][1][RTW89_UK][0][78] = 127, -+ [2][1][2][1][RTW89_FCC][1][86] = 20, -+ [2][1][2][1][RTW89_FCC][2][86] = 127, -+ [2][1][2][1][RTW89_ETSI][1][86] = 127, -+ [2][1][2][1][RTW89_ETSI][0][86] = 127, -+ [2][1][2][1][RTW89_MKK][1][86] = 127, -+ [2][1][2][1][RTW89_MKK][0][86] = 127, -+ [2][1][2][1][RTW89_IC][1][86] = 20, -+ [2][1][2][1][RTW89_KCC][1][86] = 38, -+ [2][1][2][1][RTW89_KCC][0][86] = 127, -+ [2][1][2][1][RTW89_ACMA][1][86] = 127, -+ [2][1][2][1][RTW89_ACMA][0][86] = 127, -+ [2][1][2][1][RTW89_CHILE][1][86] = 20, -+ [2][1][2][1][RTW89_QATAR][1][86] = 127, -+ [2][1][2][1][RTW89_QATAR][0][86] = 127, -+ [2][1][2][1][RTW89_UK][1][86] = 127, -+ [2][1][2][1][RTW89_UK][0][86] = 127, -+ [2][1][2][1][RTW89_FCC][1][93] = 22, -+ [2][1][2][1][RTW89_FCC][2][93] = 127, -+ [2][1][2][1][RTW89_ETSI][1][93] = 127, -+ [2][1][2][1][RTW89_ETSI][0][93] = 127, -+ [2][1][2][1][RTW89_MKK][1][93] = 127, -+ [2][1][2][1][RTW89_MKK][0][93] = 127, -+ [2][1][2][1][RTW89_IC][1][93] = 22, -+ [2][1][2][1][RTW89_KCC][1][93] = 38, -+ [2][1][2][1][RTW89_KCC][0][93] = 127, -+ [2][1][2][1][RTW89_ACMA][1][93] = 127, -+ [2][1][2][1][RTW89_ACMA][0][93] = 127, -+ [2][1][2][1][RTW89_CHILE][1][93] = 22, -+ [2][1][2][1][RTW89_QATAR][1][93] = 127, -+ [2][1][2][1][RTW89_QATAR][0][93] = 127, -+ [2][1][2][1][RTW89_UK][1][93] = 127, -+ [2][1][2][1][RTW89_UK][0][93] = 127, -+ [2][1][2][1][RTW89_FCC][1][101] = 22, -+ [2][1][2][1][RTW89_FCC][2][101] = 127, -+ [2][1][2][1][RTW89_ETSI][1][101] = 127, -+ [2][1][2][1][RTW89_ETSI][0][101] = 127, -+ [2][1][2][1][RTW89_MKK][1][101] = 127, -+ [2][1][2][1][RTW89_MKK][0][101] = 127, -+ [2][1][2][1][RTW89_IC][1][101] = 22, -+ [2][1][2][1][RTW89_KCC][1][101] = 38, -+ [2][1][2][1][RTW89_KCC][0][101] = 127, -+ [2][1][2][1][RTW89_ACMA][1][101] = 127, -+ [2][1][2][1][RTW89_ACMA][0][101] = 127, -+ [2][1][2][1][RTW89_CHILE][1][101] = 22, -+ [2][1][2][1][RTW89_QATAR][1][101] = 127, -+ [2][1][2][1][RTW89_QATAR][0][101] = 127, -+ [2][1][2][1][RTW89_UK][1][101] = 127, -+ [2][1][2][1][RTW89_UK][0][101] = 127, -+ [2][1][2][1][RTW89_FCC][1][108] = 127, -+ [2][1][2][1][RTW89_FCC][2][108] = 127, -+ [2][1][2][1][RTW89_ETSI][1][108] = 127, -+ [2][1][2][1][RTW89_ETSI][0][108] = 127, -+ [2][1][2][1][RTW89_MKK][1][108] = 127, -+ [2][1][2][1][RTW89_MKK][0][108] = 127, -+ [2][1][2][1][RTW89_IC][1][108] = 127, -+ [2][1][2][1][RTW89_KCC][1][108] = 127, -+ [2][1][2][1][RTW89_KCC][0][108] = 127, -+ [2][1][2][1][RTW89_ACMA][1][108] = 127, -+ [2][1][2][1][RTW89_ACMA][0][108] = 127, -+ [2][1][2][1][RTW89_CHILE][1][108] = 127, -+ [2][1][2][1][RTW89_QATAR][1][108] = 127, -+ [2][1][2][1][RTW89_QATAR][0][108] = 127, -+ [2][1][2][1][RTW89_UK][1][108] = 127, -+ [2][1][2][1][RTW89_UK][0][108] = 127, -+ [2][1][2][1][RTW89_FCC][1][116] = 127, -+ [2][1][2][1][RTW89_FCC][2][116] = 127, -+ [2][1][2][1][RTW89_ETSI][1][116] = 127, -+ [2][1][2][1][RTW89_ETSI][0][116] = 127, -+ [2][1][2][1][RTW89_MKK][1][116] = 127, -+ [2][1][2][1][RTW89_MKK][0][116] = 127, -+ [2][1][2][1][RTW89_IC][1][116] = 127, -+ [2][1][2][1][RTW89_KCC][1][116] = 127, -+ [2][1][2][1][RTW89_KCC][0][116] = 127, -+ [2][1][2][1][RTW89_ACMA][1][116] = 127, -+ [2][1][2][1][RTW89_ACMA][0][116] = 127, -+ [2][1][2][1][RTW89_CHILE][1][116] = 127, -+ [2][1][2][1][RTW89_QATAR][1][116] = 127, -+ [2][1][2][1][RTW89_QATAR][0][116] = 127, -+ [2][1][2][1][RTW89_UK][1][116] = 127, -+ [2][1][2][1][RTW89_UK][0][116] = 127, -+ [3][0][2][0][RTW89_FCC][1][7] = 52, -+ [3][0][2][0][RTW89_FCC][2][7] = 52, -+ [3][0][2][0][RTW89_ETSI][1][7] = 50, -+ [3][0][2][0][RTW89_ETSI][0][7] = 30, -+ [3][0][2][0][RTW89_MKK][1][7] = 50, -+ [3][0][2][0][RTW89_MKK][0][7] = 22, -+ [3][0][2][0][RTW89_IC][1][7] = 52, -+ [3][0][2][0][RTW89_KCC][1][7] = 42, -+ [3][0][2][0][RTW89_KCC][0][7] = 24, -+ [3][0][2][0][RTW89_ACMA][1][7] = 50, -+ [3][0][2][0][RTW89_ACMA][0][7] = 30, -+ [3][0][2][0][RTW89_CHILE][1][7] = 52, -+ [3][0][2][0][RTW89_QATAR][1][7] = 50, -+ [3][0][2][0][RTW89_QATAR][0][7] = 30, -+ [3][0][2][0][RTW89_UK][1][7] = 50, -+ [3][0][2][0][RTW89_UK][0][7] = 30, -+ [3][0][2][0][RTW89_FCC][1][22] = 52, -+ [3][0][2][0][RTW89_FCC][2][22] = 52, -+ [3][0][2][0][RTW89_ETSI][1][22] = 50, -+ [3][0][2][0][RTW89_ETSI][0][22] = 30, -+ [3][0][2][0][RTW89_MKK][1][22] = 50, -+ [3][0][2][0][RTW89_MKK][0][22] = 20, -+ [3][0][2][0][RTW89_IC][1][22] = 52, -+ [3][0][2][0][RTW89_KCC][1][22] = 42, -+ [3][0][2][0][RTW89_KCC][0][22] = 24, -+ [3][0][2][0][RTW89_ACMA][1][22] = 50, -+ [3][0][2][0][RTW89_ACMA][0][22] = 30, -+ [3][0][2][0][RTW89_CHILE][1][22] = 52, -+ [3][0][2][0][RTW89_QATAR][1][22] = 50, -+ [3][0][2][0][RTW89_QATAR][0][22] = 30, -+ [3][0][2][0][RTW89_UK][1][22] = 50, -+ [3][0][2][0][RTW89_UK][0][22] = 30, -+ [3][0][2][0][RTW89_FCC][1][37] = 52, -+ [3][0][2][0][RTW89_FCC][2][37] = 52, -+ [3][0][2][0][RTW89_ETSI][1][37] = 50, -+ [3][0][2][0][RTW89_ETSI][0][37] = 30, -+ [3][0][2][0][RTW89_MKK][1][37] = 50, -+ [3][0][2][0][RTW89_MKK][0][37] = 20, -+ [3][0][2][0][RTW89_IC][1][37] = 52, -+ [3][0][2][0][RTW89_KCC][1][37] = 42, -+ [3][0][2][0][RTW89_KCC][0][37] = 24, -+ [3][0][2][0][RTW89_ACMA][1][37] = 50, -+ [3][0][2][0][RTW89_ACMA][0][37] = 30, -+ [3][0][2][0][RTW89_CHILE][1][37] = 52, -+ [3][0][2][0][RTW89_QATAR][1][37] = 50, -+ [3][0][2][0][RTW89_QATAR][0][37] = 30, -+ [3][0][2][0][RTW89_UK][1][37] = 50, -+ [3][0][2][0][RTW89_UK][0][37] = 30, -+ [3][0][2][0][RTW89_FCC][1][52] = 54, -+ [3][0][2][0][RTW89_FCC][2][52] = 127, -+ [3][0][2][0][RTW89_ETSI][1][52] = 127, -+ [3][0][2][0][RTW89_ETSI][0][52] = 127, -+ [3][0][2][0][RTW89_MKK][1][52] = 127, -+ [3][0][2][0][RTW89_MKK][0][52] = 127, -+ [3][0][2][0][RTW89_IC][1][52] = 54, -+ [3][0][2][0][RTW89_KCC][1][52] = 56, -+ [3][0][2][0][RTW89_KCC][0][52] = 127, -+ [3][0][2][0][RTW89_ACMA][1][52] = 127, -+ [3][0][2][0][RTW89_ACMA][0][52] = 127, -+ [3][0][2][0][RTW89_CHILE][1][52] = 54, -+ [3][0][2][0][RTW89_QATAR][1][52] = 127, -+ [3][0][2][0][RTW89_QATAR][0][52] = 127, -+ [3][0][2][0][RTW89_UK][1][52] = 127, -+ [3][0][2][0][RTW89_UK][0][52] = 127, -+ [3][0][2][0][RTW89_FCC][1][67] = 54, -+ [3][0][2][0][RTW89_FCC][2][67] = 54, -+ [3][0][2][0][RTW89_ETSI][1][67] = 127, -+ [3][0][2][0][RTW89_ETSI][0][67] = 127, -+ [3][0][2][0][RTW89_MKK][1][67] = 127, -+ [3][0][2][0][RTW89_MKK][0][67] = 127, -+ [3][0][2][0][RTW89_IC][1][67] = 54, -+ [3][0][2][0][RTW89_KCC][1][67] = 54, -+ [3][0][2][0][RTW89_KCC][0][67] = 127, -+ [3][0][2][0][RTW89_ACMA][1][67] = 127, -+ [3][0][2][0][RTW89_ACMA][0][67] = 127, -+ [3][0][2][0][RTW89_CHILE][1][67] = 54, -+ [3][0][2][0][RTW89_QATAR][1][67] = 127, -+ [3][0][2][0][RTW89_QATAR][0][67] = 127, -+ [3][0][2][0][RTW89_UK][1][67] = 127, -+ [3][0][2][0][RTW89_UK][0][67] = 127, -+ [3][0][2][0][RTW89_FCC][1][82] = 46, -+ [3][0][2][0][RTW89_FCC][2][82] = 127, -+ [3][0][2][0][RTW89_ETSI][1][82] = 127, -+ [3][0][2][0][RTW89_ETSI][0][82] = 127, -+ [3][0][2][0][RTW89_MKK][1][82] = 127, -+ [3][0][2][0][RTW89_MKK][0][82] = 127, -+ [3][0][2][0][RTW89_IC][1][82] = 46, -+ [3][0][2][0][RTW89_KCC][1][82] = 26, -+ [3][0][2][0][RTW89_KCC][0][82] = 127, -+ [3][0][2][0][RTW89_ACMA][1][82] = 127, -+ [3][0][2][0][RTW89_ACMA][0][82] = 127, -+ [3][0][2][0][RTW89_CHILE][1][82] = 46, -+ [3][0][2][0][RTW89_QATAR][1][82] = 127, -+ [3][0][2][0][RTW89_QATAR][0][82] = 127, -+ [3][0][2][0][RTW89_UK][1][82] = 127, -+ [3][0][2][0][RTW89_UK][0][82] = 127, -+ [3][0][2][0][RTW89_FCC][1][97] = 40, -+ [3][0][2][0][RTW89_FCC][2][97] = 127, -+ [3][0][2][0][RTW89_ETSI][1][97] = 127, -+ [3][0][2][0][RTW89_ETSI][0][97] = 127, -+ [3][0][2][0][RTW89_MKK][1][97] = 127, -+ [3][0][2][0][RTW89_MKK][0][97] = 127, -+ [3][0][2][0][RTW89_IC][1][97] = 40, -+ [3][0][2][0][RTW89_KCC][1][97] = 26, -+ [3][0][2][0][RTW89_KCC][0][97] = 127, -+ [3][0][2][0][RTW89_ACMA][1][97] = 127, -+ [3][0][2][0][RTW89_ACMA][0][97] = 127, -+ [3][0][2][0][RTW89_CHILE][1][97] = 40, -+ [3][0][2][0][RTW89_QATAR][1][97] = 127, -+ [3][0][2][0][RTW89_QATAR][0][97] = 127, -+ [3][0][2][0][RTW89_UK][1][97] = 127, -+ [3][0][2][0][RTW89_UK][0][97] = 127, -+ [3][0][2][0][RTW89_FCC][1][112] = 127, -+ [3][0][2][0][RTW89_FCC][2][112] = 127, -+ [3][0][2][0][RTW89_ETSI][1][112] = 127, -+ [3][0][2][0][RTW89_ETSI][0][112] = 127, -+ [3][0][2][0][RTW89_MKK][1][112] = 127, -+ [3][0][2][0][RTW89_MKK][0][112] = 127, -+ [3][0][2][0][RTW89_IC][1][112] = 127, -+ [3][0][2][0][RTW89_KCC][1][112] = 127, -+ [3][0][2][0][RTW89_KCC][0][112] = 127, -+ [3][0][2][0][RTW89_ACMA][1][112] = 127, -+ [3][0][2][0][RTW89_ACMA][0][112] = 127, -+ [3][0][2][0][RTW89_CHILE][1][112] = 127, -+ [3][0][2][0][RTW89_QATAR][1][112] = 127, -+ [3][0][2][0][RTW89_QATAR][0][112] = 127, -+ [3][0][2][0][RTW89_UK][1][112] = 127, -+ [3][0][2][0][RTW89_UK][0][112] = 127, -+ [3][1][2][0][RTW89_FCC][1][7] = 32, -+ [3][1][2][0][RTW89_FCC][2][7] = 46, -+ [3][1][2][0][RTW89_ETSI][1][7] = 50, -+ [3][1][2][0][RTW89_ETSI][0][7] = 18, -+ [3][1][2][0][RTW89_MKK][1][7] = 38, -+ [3][1][2][0][RTW89_MKK][0][7] = 10, -+ [3][1][2][0][RTW89_IC][1][7] = 32, -+ [3][1][2][0][RTW89_KCC][1][7] = 40, -+ [3][1][2][0][RTW89_KCC][0][7] = 12, -+ [3][1][2][0][RTW89_ACMA][1][7] = 50, -+ [3][1][2][0][RTW89_ACMA][0][7] = 18, -+ [3][1][2][0][RTW89_CHILE][1][7] = 32, -+ [3][1][2][0][RTW89_QATAR][1][7] = 50, -+ [3][1][2][0][RTW89_QATAR][0][7] = 18, -+ [3][1][2][0][RTW89_UK][1][7] = 50, -+ [3][1][2][0][RTW89_UK][0][7] = 18, -+ [3][1][2][0][RTW89_FCC][1][22] = 30, -+ [3][1][2][0][RTW89_FCC][2][22] = 52, -+ [3][1][2][0][RTW89_ETSI][1][22] = 46, -+ [3][1][2][0][RTW89_ETSI][0][22] = 16, -+ [3][1][2][0][RTW89_MKK][1][22] = 48, -+ [3][1][2][0][RTW89_MKK][0][22] = 8, -+ [3][1][2][0][RTW89_IC][1][22] = 30, -+ [3][1][2][0][RTW89_KCC][1][22] = 40, -+ [3][1][2][0][RTW89_KCC][0][22] = 12, -+ [3][1][2][0][RTW89_ACMA][1][22] = 46, -+ [3][1][2][0][RTW89_ACMA][0][22] = 16, -+ [3][1][2][0][RTW89_CHILE][1][22] = 30, -+ [3][1][2][0][RTW89_QATAR][1][22] = 46, -+ [3][1][2][0][RTW89_QATAR][0][22] = 16, -+ [3][1][2][0][RTW89_UK][1][22] = 46, -+ [3][1][2][0][RTW89_UK][0][22] = 16, -+ [3][1][2][0][RTW89_FCC][1][37] = 30, -+ [3][1][2][0][RTW89_FCC][2][37] = 52, -+ [3][1][2][0][RTW89_ETSI][1][37] = 46, -+ [3][1][2][0][RTW89_ETSI][0][37] = 16, -+ [3][1][2][0][RTW89_MKK][1][37] = 48, -+ [3][1][2][0][RTW89_MKK][0][37] = 8, -+ [3][1][2][0][RTW89_IC][1][37] = 30, -+ [3][1][2][0][RTW89_KCC][1][37] = 40, -+ [3][1][2][0][RTW89_KCC][0][37] = 12, -+ [3][1][2][0][RTW89_ACMA][1][37] = 46, -+ [3][1][2][0][RTW89_ACMA][0][37] = 16, -+ [3][1][2][0][RTW89_CHILE][1][37] = 30, -+ [3][1][2][0][RTW89_QATAR][1][37] = 46, -+ [3][1][2][0][RTW89_QATAR][0][37] = 16, -+ [3][1][2][0][RTW89_UK][1][37] = 46, -+ [3][1][2][0][RTW89_UK][0][37] = 16, -+ [3][1][2][0][RTW89_FCC][1][52] = 30, -+ [3][1][2][0][RTW89_FCC][2][52] = 127, -+ [3][1][2][0][RTW89_ETSI][1][52] = 127, -+ [3][1][2][0][RTW89_ETSI][0][52] = 127, -+ [3][1][2][0][RTW89_MKK][1][52] = 127, -+ [3][1][2][0][RTW89_MKK][0][52] = 127, -+ [3][1][2][0][RTW89_IC][1][52] = 30, -+ [3][1][2][0][RTW89_KCC][1][52] = 48, -+ [3][1][2][0][RTW89_KCC][0][52] = 127, -+ [3][1][2][0][RTW89_ACMA][1][52] = 127, -+ [3][1][2][0][RTW89_ACMA][0][52] = 127, -+ [3][1][2][0][RTW89_CHILE][1][52] = 30, -+ [3][1][2][0][RTW89_QATAR][1][52] = 127, -+ [3][1][2][0][RTW89_QATAR][0][52] = 127, -+ [3][1][2][0][RTW89_UK][1][52] = 127, -+ [3][1][2][0][RTW89_UK][0][52] = 127, -+ [3][1][2][0][RTW89_FCC][1][67] = 32, -+ [3][1][2][0][RTW89_FCC][2][67] = 54, -+ [3][1][2][0][RTW89_ETSI][1][67] = 127, -+ [3][1][2][0][RTW89_ETSI][0][67] = 127, -+ [3][1][2][0][RTW89_MKK][1][67] = 127, -+ [3][1][2][0][RTW89_MKK][0][67] = 127, -+ [3][1][2][0][RTW89_IC][1][67] = 32, -+ [3][1][2][0][RTW89_KCC][1][67] = 48, -+ [3][1][2][0][RTW89_KCC][0][67] = 127, -+ [3][1][2][0][RTW89_ACMA][1][67] = 127, -+ [3][1][2][0][RTW89_ACMA][0][67] = 127, -+ [3][1][2][0][RTW89_CHILE][1][67] = 32, -+ [3][1][2][0][RTW89_QATAR][1][67] = 127, -+ [3][1][2][0][RTW89_QATAR][0][67] = 127, -+ [3][1][2][0][RTW89_UK][1][67] = 127, -+ [3][1][2][0][RTW89_UK][0][67] = 127, -+ [3][1][2][0][RTW89_FCC][1][82] = 32, -+ [3][1][2][0][RTW89_FCC][2][82] = 127, -+ [3][1][2][0][RTW89_ETSI][1][82] = 127, -+ [3][1][2][0][RTW89_ETSI][0][82] = 127, -+ [3][1][2][0][RTW89_MKK][1][82] = 127, -+ [3][1][2][0][RTW89_MKK][0][82] = 127, -+ [3][1][2][0][RTW89_IC][1][82] = 32, -+ [3][1][2][0][RTW89_KCC][1][82] = 24, -+ [3][1][2][0][RTW89_KCC][0][82] = 127, -+ [3][1][2][0][RTW89_ACMA][1][82] = 127, -+ [3][1][2][0][RTW89_ACMA][0][82] = 127, -+ [3][1][2][0][RTW89_CHILE][1][82] = 32, -+ [3][1][2][0][RTW89_QATAR][1][82] = 127, -+ [3][1][2][0][RTW89_QATAR][0][82] = 127, -+ [3][1][2][0][RTW89_UK][1][82] = 127, -+ [3][1][2][0][RTW89_UK][0][82] = 127, -+ [3][1][2][0][RTW89_FCC][1][97] = 32, -+ [3][1][2][0][RTW89_FCC][2][97] = 127, -+ [3][1][2][0][RTW89_ETSI][1][97] = 127, -+ [3][1][2][0][RTW89_ETSI][0][97] = 127, -+ [3][1][2][0][RTW89_MKK][1][97] = 127, -+ [3][1][2][0][RTW89_MKK][0][97] = 127, -+ [3][1][2][0][RTW89_IC][1][97] = 32, -+ [3][1][2][0][RTW89_KCC][1][97] = 24, -+ [3][1][2][0][RTW89_KCC][0][97] = 127, -+ [3][1][2][0][RTW89_ACMA][1][97] = 127, -+ [3][1][2][0][RTW89_ACMA][0][97] = 127, -+ [3][1][2][0][RTW89_CHILE][1][97] = 32, -+ [3][1][2][0][RTW89_QATAR][1][97] = 127, -+ [3][1][2][0][RTW89_QATAR][0][97] = 127, -+ [3][1][2][0][RTW89_UK][1][97] = 127, -+ [3][1][2][0][RTW89_UK][0][97] = 127, -+ [3][1][2][0][RTW89_FCC][1][112] = 127, -+ [3][1][2][0][RTW89_FCC][2][112] = 127, -+ [3][1][2][0][RTW89_ETSI][1][112] = 127, -+ [3][1][2][0][RTW89_ETSI][0][112] = 127, -+ [3][1][2][0][RTW89_MKK][1][112] = 127, -+ [3][1][2][0][RTW89_MKK][0][112] = 127, -+ [3][1][2][0][RTW89_IC][1][112] = 127, -+ [3][1][2][0][RTW89_KCC][1][112] = 127, -+ [3][1][2][0][RTW89_KCC][0][112] = 127, -+ [3][1][2][0][RTW89_ACMA][1][112] = 127, -+ [3][1][2][0][RTW89_ACMA][0][112] = 127, -+ [3][1][2][0][RTW89_CHILE][1][112] = 127, -+ [3][1][2][0][RTW89_QATAR][1][112] = 127, -+ [3][1][2][0][RTW89_QATAR][0][112] = 127, -+ [3][1][2][0][RTW89_UK][1][112] = 127, -+ [3][1][2][0][RTW89_UK][0][112] = 127, -+ [3][1][2][1][RTW89_FCC][1][7] = 32, -+ [3][1][2][1][RTW89_FCC][2][7] = 46, -+ [3][1][2][1][RTW89_ETSI][1][7] = 42, -+ [3][1][2][1][RTW89_ETSI][0][7] = 6, -+ [3][1][2][1][RTW89_MKK][1][7] = 38, -+ [3][1][2][1][RTW89_MKK][0][7] = 10, -+ [3][1][2][1][RTW89_IC][1][7] = 32, -+ [3][1][2][1][RTW89_KCC][1][7] = 40, -+ [3][1][2][1][RTW89_KCC][0][7] = 12, -+ [3][1][2][1][RTW89_ACMA][1][7] = 42, -+ [3][1][2][1][RTW89_ACMA][0][7] = 6, -+ [3][1][2][1][RTW89_CHILE][1][7] = 32, -+ [3][1][2][1][RTW89_QATAR][1][7] = 42, -+ [3][1][2][1][RTW89_QATAR][0][7] = 6, -+ [3][1][2][1][RTW89_UK][1][7] = 42, -+ [3][1][2][1][RTW89_UK][0][7] = 6, -+ [3][1][2][1][RTW89_FCC][1][22] = 30, -+ [3][1][2][1][RTW89_FCC][2][22] = 52, -+ [3][1][2][1][RTW89_ETSI][1][22] = 42, -+ [3][1][2][1][RTW89_ETSI][0][22] = 6, -+ [3][1][2][1][RTW89_MKK][1][22] = 48, -+ [3][1][2][1][RTW89_MKK][0][22] = 8, -+ [3][1][2][1][RTW89_IC][1][22] = 30, -+ [3][1][2][1][RTW89_KCC][1][22] = 40, -+ [3][1][2][1][RTW89_KCC][0][22] = 12, -+ [3][1][2][1][RTW89_ACMA][1][22] = 42, -+ [3][1][2][1][RTW89_ACMA][0][22] = 6, -+ [3][1][2][1][RTW89_CHILE][1][22] = 30, -+ [3][1][2][1][RTW89_QATAR][1][22] = 42, -+ [3][1][2][1][RTW89_QATAR][0][22] = 6, -+ [3][1][2][1][RTW89_UK][1][22] = 42, -+ [3][1][2][1][RTW89_UK][0][22] = 6, -+ [3][1][2][1][RTW89_FCC][1][37] = 30, -+ [3][1][2][1][RTW89_FCC][2][37] = 52, -+ [3][1][2][1][RTW89_ETSI][1][37] = 42, -+ [3][1][2][1][RTW89_ETSI][0][37] = 6, -+ [3][1][2][1][RTW89_MKK][1][37] = 48, -+ [3][1][2][1][RTW89_MKK][0][37] = 8, -+ [3][1][2][1][RTW89_IC][1][37] = 30, -+ [3][1][2][1][RTW89_KCC][1][37] = 40, -+ [3][1][2][1][RTW89_KCC][0][37] = 12, -+ [3][1][2][1][RTW89_ACMA][1][37] = 42, -+ [3][1][2][1][RTW89_ACMA][0][37] = 6, -+ [3][1][2][1][RTW89_CHILE][1][37] = 30, -+ [3][1][2][1][RTW89_QATAR][1][37] = 42, -+ [3][1][2][1][RTW89_QATAR][0][37] = 6, -+ [3][1][2][1][RTW89_UK][1][37] = 42, -+ [3][1][2][1][RTW89_UK][0][37] = 6, -+ [3][1][2][1][RTW89_FCC][1][52] = 30, -+ [3][1][2][1][RTW89_FCC][2][52] = 127, -+ [3][1][2][1][RTW89_ETSI][1][52] = 127, -+ [3][1][2][1][RTW89_ETSI][0][52] = 127, -+ [3][1][2][1][RTW89_MKK][1][52] = 127, -+ [3][1][2][1][RTW89_MKK][0][52] = 127, -+ [3][1][2][1][RTW89_IC][1][52] = 30, -+ [3][1][2][1][RTW89_KCC][1][52] = 48, -+ [3][1][2][1][RTW89_KCC][0][52] = 127, -+ [3][1][2][1][RTW89_ACMA][1][52] = 127, -+ [3][1][2][1][RTW89_ACMA][0][52] = 127, -+ [3][1][2][1][RTW89_CHILE][1][52] = 30, -+ [3][1][2][1][RTW89_QATAR][1][52] = 127, -+ [3][1][2][1][RTW89_QATAR][0][52] = 127, -+ [3][1][2][1][RTW89_UK][1][52] = 127, -+ [3][1][2][1][RTW89_UK][0][52] = 127, -+ [3][1][2][1][RTW89_FCC][1][67] = 32, -+ [3][1][2][1][RTW89_FCC][2][67] = 54, -+ [3][1][2][1][RTW89_ETSI][1][67] = 127, -+ [3][1][2][1][RTW89_ETSI][0][67] = 127, -+ [3][1][2][1][RTW89_MKK][1][67] = 127, -+ [3][1][2][1][RTW89_MKK][0][67] = 127, -+ [3][1][2][1][RTW89_IC][1][67] = 32, -+ [3][1][2][1][RTW89_KCC][1][67] = 48, -+ [3][1][2][1][RTW89_KCC][0][67] = 127, -+ [3][1][2][1][RTW89_ACMA][1][67] = 127, -+ [3][1][2][1][RTW89_ACMA][0][67] = 127, -+ [3][1][2][1][RTW89_CHILE][1][67] = 32, -+ [3][1][2][1][RTW89_QATAR][1][67] = 127, -+ [3][1][2][1][RTW89_QATAR][0][67] = 127, -+ [3][1][2][1][RTW89_UK][1][67] = 127, -+ [3][1][2][1][RTW89_UK][0][67] = 127, -+ [3][1][2][1][RTW89_FCC][1][82] = 32, -+ [3][1][2][1][RTW89_FCC][2][82] = 127, -+ [3][1][2][1][RTW89_ETSI][1][82] = 127, -+ [3][1][2][1][RTW89_ETSI][0][82] = 127, -+ [3][1][2][1][RTW89_MKK][1][82] = 127, -+ [3][1][2][1][RTW89_MKK][0][82] = 127, -+ [3][1][2][1][RTW89_IC][1][82] = 32, -+ [3][1][2][1][RTW89_KCC][1][82] = 24, -+ [3][1][2][1][RTW89_KCC][0][82] = 127, -+ [3][1][2][1][RTW89_ACMA][1][82] = 127, -+ [3][1][2][1][RTW89_ACMA][0][82] = 127, -+ [3][1][2][1][RTW89_CHILE][1][82] = 32, -+ [3][1][2][1][RTW89_QATAR][1][82] = 127, -+ [3][1][2][1][RTW89_QATAR][0][82] = 127, -+ [3][1][2][1][RTW89_UK][1][82] = 127, -+ [3][1][2][1][RTW89_UK][0][82] = 127, -+ [3][1][2][1][RTW89_FCC][1][97] = 32, -+ [3][1][2][1][RTW89_FCC][2][97] = 127, -+ [3][1][2][1][RTW89_ETSI][1][97] = 127, -+ [3][1][2][1][RTW89_ETSI][0][97] = 127, -+ [3][1][2][1][RTW89_MKK][1][97] = 127, -+ [3][1][2][1][RTW89_MKK][0][97] = 127, -+ [3][1][2][1][RTW89_IC][1][97] = 32, -+ [3][1][2][1][RTW89_KCC][1][97] = 24, -+ [3][1][2][1][RTW89_KCC][0][97] = 127, -+ [3][1][2][1][RTW89_ACMA][1][97] = 127, -+ [3][1][2][1][RTW89_ACMA][0][97] = 127, -+ [3][1][2][1][RTW89_CHILE][1][97] = 32, -+ [3][1][2][1][RTW89_QATAR][1][97] = 127, -+ [3][1][2][1][RTW89_QATAR][0][97] = 127, -+ [3][1][2][1][RTW89_UK][1][97] = 127, -+ [3][1][2][1][RTW89_UK][0][97] = 127, -+ [3][1][2][1][RTW89_FCC][1][112] = 127, -+ [3][1][2][1][RTW89_FCC][2][112] = 127, -+ [3][1][2][1][RTW89_ETSI][1][112] = 127, -+ [3][1][2][1][RTW89_ETSI][0][112] = 127, -+ [3][1][2][1][RTW89_MKK][1][112] = 127, -+ [3][1][2][1][RTW89_MKK][0][112] = 127, -+ [3][1][2][1][RTW89_IC][1][112] = 127, -+ [3][1][2][1][RTW89_KCC][1][112] = 127, -+ [3][1][2][1][RTW89_KCC][0][112] = 127, -+ [3][1][2][1][RTW89_ACMA][1][112] = 127, -+ [3][1][2][1][RTW89_ACMA][0][112] = 127, -+ [3][1][2][1][RTW89_CHILE][1][112] = 127, -+ [3][1][2][1][RTW89_QATAR][1][112] = 127, -+ [3][1][2][1][RTW89_QATAR][0][112] = 127, -+ [3][1][2][1][RTW89_UK][1][112] = 127, -+ [3][1][2][1][RTW89_UK][0][112] = 127, - }; - - static diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-132-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-132-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch deleted file mode 100644 index ab9aa6a1a..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-132-wifi-rtw89-8852c-update-TX-power-tables-to-R63-with-.patch +++ /dev/null @@ -1,8532 +0,0 @@ -From dad142c3f56a2459b1f18cac63e1a436d0a31c84 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 2 Jun 2023 23:05:55 +0800 -Subject: [PATCH 132/136] wifi: rtw89: 8852c: update TX power tables to R63 - with 6 GHz power type (3 of 3) - -Update TX power tables to RF version R63. - -TX power tables' changes: -* TX power byrate: - tweak a bit -* TX power limit, TX power limit RU, TX power shape: - configure values for MEXICO, UKRAINE, CHILE, QATAR - tweak a bit on other configured values -* 6 GHz TX power limit, 6 GHz TX power limit RU: - add an extra dimension for 6 GHz regulatory power type, i.e. - STD (standard power), LPI (low power indoor), VLP (very low power) - -Besides, we adjust TX power handling at 6 GHz in phy to consider 6 GHz -regulatory power type. - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-8-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 +- - drivers/net/wireless/realtek/rtw89/phy.c | 8 +- - .../wireless/realtek/rtw89/rtw8852c_table.c | 8451 ++++++++++++++--- - 3 files changed, 7306 insertions(+), 1156 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3049,7 +3049,8 @@ struct rtw89_txpwr_rule_6ghz { - [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] - [RTW89_6G_CH_NUM]; - const s8 (*lmt_ru)[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM]; -+ [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] -+ [RTW89_6G_CH_NUM]; - }; - - struct rtw89_rfe_parms { ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1881,8 +1881,10 @@ static s8 rtw89_phy_read_txpwr_limit_ru( - const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz; - const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz; - const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz; -+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; - u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); - u8 regd = rtw89_regd_get(rtwdev, band); -+ u8 reg6 = regulatory->reg_6ghz_power; - s8 lmt_ru = 0, sar; - - switch (band) { -@@ -1901,11 +1903,13 @@ static s8 rtw89_phy_read_txpwr_limit_ru( - lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; - break; - case RTW89_BAND_6G: -- lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][ch_idx]; -+ lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx]; - if (lmt_ru) - break; - -- lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx]; -+ lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][RTW89_WW] -+ [RTW89_REG_6GHZ_POWER_DFLT] -+ [ch_idx]; - break; - default: - rtw89_warn(rtwdev, "unknown band type: %d\n", band); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -46127,1159 +46127,7304 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW - - static - const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM] -- [RTW89_REGD_NUM][RTW89_6G_CH_NUM] = { -- [0][0][RTW89_WW][0] = -16, -- [0][0][RTW89_WW][2] = -18, -- [0][0][RTW89_WW][4] = -18, -- [0][0][RTW89_WW][6] = -18, -- [0][0][RTW89_WW][8] = -18, -- [0][0][RTW89_WW][10] = -18, -- [0][0][RTW89_WW][12] = -18, -- [0][0][RTW89_WW][14] = -18, -- [0][0][RTW89_WW][15] = -18, -- [0][0][RTW89_WW][17] = -18, -- [0][0][RTW89_WW][19] = -18, -- [0][0][RTW89_WW][21] = -18, -- [0][0][RTW89_WW][23] = -18, -- [0][0][RTW89_WW][25] = -18, -- [0][0][RTW89_WW][27] = -18, -- [0][0][RTW89_WW][29] = -18, -- [0][0][RTW89_WW][30] = -18, -- [0][0][RTW89_WW][32] = -18, -- [0][0][RTW89_WW][34] = -18, -- [0][0][RTW89_WW][36] = -18, -- [0][0][RTW89_WW][38] = -18, -- [0][0][RTW89_WW][40] = -18, -- [0][0][RTW89_WW][42] = -18, -- [0][0][RTW89_WW][44] = -16, -- [0][0][RTW89_WW][45] = -16, -- [0][0][RTW89_WW][47] = -18, -- [0][0][RTW89_WW][49] = -18, -- [0][0][RTW89_WW][51] = -18, -- [0][0][RTW89_WW][53] = -16, -- [0][0][RTW89_WW][55] = -18, -- [0][0][RTW89_WW][57] = -18, -- [0][0][RTW89_WW][59] = -18, -- [0][0][RTW89_WW][60] = -18, -- [0][0][RTW89_WW][62] = -18, -- [0][0][RTW89_WW][64] = -18, -- [0][0][RTW89_WW][66] = -18, -- [0][0][RTW89_WW][68] = -18, -- [0][0][RTW89_WW][70] = -16, -- [0][0][RTW89_WW][72] = -18, -- [0][0][RTW89_WW][74] = -18, -- [0][0][RTW89_WW][75] = -18, -- [0][0][RTW89_WW][77] = -18, -- [0][0][RTW89_WW][79] = -18, -- [0][0][RTW89_WW][81] = -18, -- [0][0][RTW89_WW][83] = -18, -- [0][0][RTW89_WW][85] = -18, -- [0][0][RTW89_WW][87] = -16, -- [0][0][RTW89_WW][89] = -16, -- [0][0][RTW89_WW][90] = -16, -- [0][0][RTW89_WW][92] = -16, -- [0][0][RTW89_WW][94] = -16, -- [0][0][RTW89_WW][96] = -16, -- [0][0][RTW89_WW][98] = -16, -- [0][0][RTW89_WW][100] = -16, -- [0][0][RTW89_WW][102] = -16, -- [0][0][RTW89_WW][104] = -16, -- [0][0][RTW89_WW][105] = -16, -- [0][0][RTW89_WW][107] = -12, -- [0][0][RTW89_WW][109] = -12, -- [0][0][RTW89_WW][111] = 0, -- [0][0][RTW89_WW][113] = 0, -- [0][0][RTW89_WW][115] = 0, -- [0][0][RTW89_WW][117] = 0, -- [0][0][RTW89_WW][119] = 0, -- [0][1][RTW89_WW][0] = -40, -- [0][1][RTW89_WW][2] = -40, -- [0][1][RTW89_WW][4] = -40, -- [0][1][RTW89_WW][6] = -40, -- [0][1][RTW89_WW][8] = -40, -- [0][1][RTW89_WW][10] = -40, -- [0][1][RTW89_WW][12] = -40, -- [0][1][RTW89_WW][14] = -40, -- [0][1][RTW89_WW][15] = -40, -- [0][1][RTW89_WW][17] = -40, -- [0][1][RTW89_WW][19] = -40, -- [0][1][RTW89_WW][21] = -40, -- [0][1][RTW89_WW][23] = -40, -- [0][1][RTW89_WW][25] = -40, -- [0][1][RTW89_WW][27] = -40, -- [0][1][RTW89_WW][29] = -40, -- [0][1][RTW89_WW][30] = -40, -- [0][1][RTW89_WW][32] = -40, -- [0][1][RTW89_WW][34] = -40, -- [0][1][RTW89_WW][36] = -40, -- [0][1][RTW89_WW][38] = -40, -- [0][1][RTW89_WW][40] = -40, -- [0][1][RTW89_WW][42] = -40, -- [0][1][RTW89_WW][44] = -40, -- [0][1][RTW89_WW][45] = -40, -- [0][1][RTW89_WW][47] = -40, -- [0][1][RTW89_WW][49] = -40, -- [0][1][RTW89_WW][51] = -40, -- [0][1][RTW89_WW][53] = -40, -- [0][1][RTW89_WW][55] = -40, -- [0][1][RTW89_WW][57] = -40, -- [0][1][RTW89_WW][59] = -40, -- [0][1][RTW89_WW][60] = -40, -- [0][1][RTW89_WW][62] = -40, -- [0][1][RTW89_WW][64] = -40, -- [0][1][RTW89_WW][66] = -40, -- [0][1][RTW89_WW][68] = -40, -- [0][1][RTW89_WW][70] = -38, -- [0][1][RTW89_WW][72] = -38, -- [0][1][RTW89_WW][74] = -38, -- [0][1][RTW89_WW][75] = -38, -- [0][1][RTW89_WW][77] = -38, -- [0][1][RTW89_WW][79] = -38, -- [0][1][RTW89_WW][81] = -38, -- [0][1][RTW89_WW][83] = -38, -- [0][1][RTW89_WW][85] = -38, -- [0][1][RTW89_WW][87] = -40, -- [0][1][RTW89_WW][89] = -38, -- [0][1][RTW89_WW][90] = -38, -- [0][1][RTW89_WW][92] = -38, -- [0][1][RTW89_WW][94] = -38, -- [0][1][RTW89_WW][96] = -38, -- [0][1][RTW89_WW][98] = -38, -- [0][1][RTW89_WW][100] = -38, -- [0][1][RTW89_WW][102] = -38, -- [0][1][RTW89_WW][104] = -38, -- [0][1][RTW89_WW][105] = -38, -- [0][1][RTW89_WW][107] = -34, -- [0][1][RTW89_WW][109] = -34, -- [0][1][RTW89_WW][111] = 0, -- [0][1][RTW89_WW][113] = 0, -- [0][1][RTW89_WW][115] = 0, -- [0][1][RTW89_WW][117] = 0, -- [0][1][RTW89_WW][119] = 0, -- [1][0][RTW89_WW][0] = -4, -- [1][0][RTW89_WW][2] = -4, -- [1][0][RTW89_WW][4] = -4, -- [1][0][RTW89_WW][6] = -4, -- [1][0][RTW89_WW][8] = -4, -- [1][0][RTW89_WW][10] = -4, -- [1][0][RTW89_WW][12] = -4, -- [1][0][RTW89_WW][14] = -4, -- [1][0][RTW89_WW][15] = -4, -- [1][0][RTW89_WW][17] = -4, -- [1][0][RTW89_WW][19] = -4, -- [1][0][RTW89_WW][21] = -4, -- [1][0][RTW89_WW][23] = -4, -- [1][0][RTW89_WW][25] = -4, -- [1][0][RTW89_WW][27] = -4, -- [1][0][RTW89_WW][29] = -4, -- [1][0][RTW89_WW][30] = -4, -- [1][0][RTW89_WW][32] = -4, -- [1][0][RTW89_WW][34] = -4, -- [1][0][RTW89_WW][36] = -4, -- [1][0][RTW89_WW][38] = -4, -- [1][0][RTW89_WW][40] = -4, -- [1][0][RTW89_WW][42] = -4, -- [1][0][RTW89_WW][44] = -4, -- [1][0][RTW89_WW][45] = -4, -- [1][0][RTW89_WW][47] = -4, -- [1][0][RTW89_WW][49] = -4, -- [1][0][RTW89_WW][51] = -4, -- [1][0][RTW89_WW][53] = -4, -- [1][0][RTW89_WW][55] = -4, -- [1][0][RTW89_WW][57] = -4, -- [1][0][RTW89_WW][59] = -4, -- [1][0][RTW89_WW][60] = -4, -- [1][0][RTW89_WW][62] = -4, -- [1][0][RTW89_WW][64] = -4, -- [1][0][RTW89_WW][66] = -4, -- [1][0][RTW89_WW][68] = -4, -- [1][0][RTW89_WW][70] = -4, -- [1][0][RTW89_WW][72] = -4, -- [1][0][RTW89_WW][74] = -4, -- [1][0][RTW89_WW][75] = -4, -- [1][0][RTW89_WW][77] = -4, -- [1][0][RTW89_WW][79] = -4, -- [1][0][RTW89_WW][81] = -4, -- [1][0][RTW89_WW][83] = -4, -- [1][0][RTW89_WW][85] = -4, -- [1][0][RTW89_WW][87] = -4, -- [1][0][RTW89_WW][89] = -4, -- [1][0][RTW89_WW][90] = -4, -- [1][0][RTW89_WW][92] = -4, -- [1][0][RTW89_WW][94] = -4, -- [1][0][RTW89_WW][96] = -4, -- [1][0][RTW89_WW][98] = -4, -- [1][0][RTW89_WW][100] = -4, -- [1][0][RTW89_WW][102] = -4, -- [1][0][RTW89_WW][104] = -4, -- [1][0][RTW89_WW][105] = -4, -- [1][0][RTW89_WW][107] = 1, -- [1][0][RTW89_WW][109] = 2, -- [1][0][RTW89_WW][111] = 0, -- [1][0][RTW89_WW][113] = 0, -- [1][0][RTW89_WW][115] = 0, -- [1][0][RTW89_WW][117] = 0, -- [1][0][RTW89_WW][119] = 0, -- [1][1][RTW89_WW][0] = -26, -- [1][1][RTW89_WW][2] = -28, -- [1][1][RTW89_WW][4] = -28, -- [1][1][RTW89_WW][6] = -28, -- [1][1][RTW89_WW][8] = -28, -- [1][1][RTW89_WW][10] = -28, -- [1][1][RTW89_WW][12] = -28, -- [1][1][RTW89_WW][14] = -28, -- [1][1][RTW89_WW][15] = -28, -- [1][1][RTW89_WW][17] = -28, -- [1][1][RTW89_WW][19] = -28, -- [1][1][RTW89_WW][21] = -28, -- [1][1][RTW89_WW][23] = -28, -- [1][1][RTW89_WW][25] = -28, -- [1][1][RTW89_WW][27] = -28, -- [1][1][RTW89_WW][29] = -28, -- [1][1][RTW89_WW][30] = -28, -- [1][1][RTW89_WW][32] = -28, -- [1][1][RTW89_WW][34] = -28, -- [1][1][RTW89_WW][36] = -28, -- [1][1][RTW89_WW][38] = -28, -- [1][1][RTW89_WW][40] = -28, -- [1][1][RTW89_WW][42] = -28, -- [1][1][RTW89_WW][44] = -28, -- [1][1][RTW89_WW][45] = -26, -- [1][1][RTW89_WW][47] = -28, -- [1][1][RTW89_WW][49] = -28, -- [1][1][RTW89_WW][51] = -28, -- [1][1][RTW89_WW][53] = -26, -- [1][1][RTW89_WW][55] = -28, -- [1][1][RTW89_WW][57] = -28, -- [1][1][RTW89_WW][59] = -28, -- [1][1][RTW89_WW][60] = -28, -- [1][1][RTW89_WW][62] = -28, -- [1][1][RTW89_WW][64] = -28, -- [1][1][RTW89_WW][66] = -28, -- [1][1][RTW89_WW][68] = -28, -- [1][1][RTW89_WW][70] = -26, -- [1][1][RTW89_WW][72] = -28, -- [1][1][RTW89_WW][74] = -28, -- [1][1][RTW89_WW][75] = -28, -- [1][1][RTW89_WW][77] = -28, -- [1][1][RTW89_WW][79] = -28, -- [1][1][RTW89_WW][81] = -28, -- [1][1][RTW89_WW][83] = -28, -- [1][1][RTW89_WW][85] = -28, -- [1][1][RTW89_WW][87] = -28, -- [1][1][RTW89_WW][89] = -26, -- [1][1][RTW89_WW][90] = -26, -- [1][1][RTW89_WW][92] = -26, -- [1][1][RTW89_WW][94] = -26, -- [1][1][RTW89_WW][96] = -26, -- [1][1][RTW89_WW][98] = -26, -- [1][1][RTW89_WW][100] = -26, -- [1][1][RTW89_WW][102] = -26, -- [1][1][RTW89_WW][104] = -26, -- [1][1][RTW89_WW][105] = -26, -- [1][1][RTW89_WW][107] = -22, -- [1][1][RTW89_WW][109] = -22, -- [1][1][RTW89_WW][111] = 0, -- [1][1][RTW89_WW][113] = 0, -- [1][1][RTW89_WW][115] = 0, -- [1][1][RTW89_WW][117] = 0, -- [1][1][RTW89_WW][119] = 0, -- [2][0][RTW89_WW][0] = 8, -- [2][0][RTW89_WW][2] = 8, -- [2][0][RTW89_WW][4] = 8, -- [2][0][RTW89_WW][6] = 8, -- [2][0][RTW89_WW][8] = 8, -- [2][0][RTW89_WW][10] = 8, -- [2][0][RTW89_WW][12] = 8, -- [2][0][RTW89_WW][14] = 8, -- [2][0][RTW89_WW][15] = 8, -- [2][0][RTW89_WW][17] = 8, -- [2][0][RTW89_WW][19] = 8, -- [2][0][RTW89_WW][21] = 8, -- [2][0][RTW89_WW][23] = 8, -- [2][0][RTW89_WW][25] = 8, -- [2][0][RTW89_WW][27] = 8, -- [2][0][RTW89_WW][29] = 8, -- [2][0][RTW89_WW][30] = 8, -- [2][0][RTW89_WW][32] = 8, -- [2][0][RTW89_WW][34] = 8, -- [2][0][RTW89_WW][36] = 8, -- [2][0][RTW89_WW][38] = 8, -- [2][0][RTW89_WW][40] = 8, -- [2][0][RTW89_WW][42] = 8, -- [2][0][RTW89_WW][44] = 8, -- [2][0][RTW89_WW][45] = 8, -- [2][0][RTW89_WW][47] = 8, -- [2][0][RTW89_WW][49] = 8, -- [2][0][RTW89_WW][51] = 8, -- [2][0][RTW89_WW][53] = 8, -- [2][0][RTW89_WW][55] = 8, -- [2][0][RTW89_WW][57] = 8, -- [2][0][RTW89_WW][59] = 8, -- [2][0][RTW89_WW][60] = 8, -- [2][0][RTW89_WW][62] = 8, -- [2][0][RTW89_WW][64] = 8, -- [2][0][RTW89_WW][66] = 8, -- [2][0][RTW89_WW][68] = 8, -- [2][0][RTW89_WW][70] = 8, -- [2][0][RTW89_WW][72] = 8, -- [2][0][RTW89_WW][74] = 8, -- [2][0][RTW89_WW][75] = 8, -- [2][0][RTW89_WW][77] = 8, -- [2][0][RTW89_WW][79] = 8, -- [2][0][RTW89_WW][81] = 8, -- [2][0][RTW89_WW][83] = 8, -- [2][0][RTW89_WW][85] = 8, -- [2][0][RTW89_WW][87] = 8, -- [2][0][RTW89_WW][89] = 8, -- [2][0][RTW89_WW][90] = 8, -- [2][0][RTW89_WW][92] = 8, -- [2][0][RTW89_WW][94] = 8, -- [2][0][RTW89_WW][96] = 8, -- [2][0][RTW89_WW][98] = 8, -- [2][0][RTW89_WW][100] = 8, -- [2][0][RTW89_WW][102] = 8, -- [2][0][RTW89_WW][104] = 8, -- [2][0][RTW89_WW][105] = 8, -- [2][0][RTW89_WW][107] = 10, -- [2][0][RTW89_WW][109] = 12, -- [2][0][RTW89_WW][111] = 0, -- [2][0][RTW89_WW][113] = 0, -- [2][0][RTW89_WW][115] = 0, -- [2][0][RTW89_WW][117] = 0, -- [2][0][RTW89_WW][119] = 0, -- [2][1][RTW89_WW][0] = -16, -- [2][1][RTW89_WW][2] = -16, -- [2][1][RTW89_WW][4] = -16, -- [2][1][RTW89_WW][6] = -16, -- [2][1][RTW89_WW][8] = -16, -- [2][1][RTW89_WW][10] = -16, -- [2][1][RTW89_WW][12] = -16, -- [2][1][RTW89_WW][14] = -16, -- [2][1][RTW89_WW][15] = -16, -- [2][1][RTW89_WW][17] = -16, -- [2][1][RTW89_WW][19] = -16, -- [2][1][RTW89_WW][21] = -16, -- [2][1][RTW89_WW][23] = -16, -- [2][1][RTW89_WW][25] = -16, -- [2][1][RTW89_WW][27] = -16, -- [2][1][RTW89_WW][29] = -16, -- [2][1][RTW89_WW][30] = -16, -- [2][1][RTW89_WW][32] = -16, -- [2][1][RTW89_WW][34] = -16, -- [2][1][RTW89_WW][36] = -16, -- [2][1][RTW89_WW][38] = -16, -- [2][1][RTW89_WW][40] = -16, -- [2][1][RTW89_WW][42] = -16, -- [2][1][RTW89_WW][44] = -16, -- [2][1][RTW89_WW][45] = -16, -- [2][1][RTW89_WW][47] = -16, -- [2][1][RTW89_WW][49] = -16, -- [2][1][RTW89_WW][51] = -16, -- [2][1][RTW89_WW][53] = -16, -- [2][1][RTW89_WW][55] = -16, -- [2][1][RTW89_WW][57] = -16, -- [2][1][RTW89_WW][59] = -16, -- [2][1][RTW89_WW][60] = -16, -- [2][1][RTW89_WW][62] = -16, -- [2][1][RTW89_WW][64] = -16, -- [2][1][RTW89_WW][66] = -16, -- [2][1][RTW89_WW][68] = -16, -- [2][1][RTW89_WW][70] = -16, -- [2][1][RTW89_WW][72] = -16, -- [2][1][RTW89_WW][74] = -16, -- [2][1][RTW89_WW][75] = -16, -- [2][1][RTW89_WW][77] = -16, -- [2][1][RTW89_WW][79] = -16, -- [2][1][RTW89_WW][81] = -16, -- [2][1][RTW89_WW][83] = -16, -- [2][1][RTW89_WW][85] = -18, -- [2][1][RTW89_WW][87] = -16, -- [2][1][RTW89_WW][89] = -16, -- [2][1][RTW89_WW][90] = -16, -- [2][1][RTW89_WW][92] = -16, -- [2][1][RTW89_WW][94] = -16, -- [2][1][RTW89_WW][96] = -16, -- [2][1][RTW89_WW][98] = -16, -- [2][1][RTW89_WW][100] = -16, -- [2][1][RTW89_WW][102] = -16, -- [2][1][RTW89_WW][104] = -16, -- [2][1][RTW89_WW][105] = -16, -- [2][1][RTW89_WW][107] = -12, -- [2][1][RTW89_WW][109] = -10, -- [2][1][RTW89_WW][111] = 0, -- [2][1][RTW89_WW][113] = 0, -- [2][1][RTW89_WW][115] = 0, -- [2][1][RTW89_WW][117] = 0, -- [2][1][RTW89_WW][119] = 0, -- [0][0][RTW89_FCC][0] = -16, -- [0][0][RTW89_ETSI][0] = 32, -- [0][0][RTW89_FCC][2] = -18, -- [0][0][RTW89_ETSI][2] = 32, -- [0][0][RTW89_FCC][4] = -18, -- [0][0][RTW89_ETSI][4] = 32, -- [0][0][RTW89_FCC][6] = -18, -- [0][0][RTW89_ETSI][6] = 32, -- [0][0][RTW89_FCC][8] = -18, -- [0][0][RTW89_ETSI][8] = 32, -- [0][0][RTW89_FCC][10] = -18, -- [0][0][RTW89_ETSI][10] = 32, -- [0][0][RTW89_FCC][12] = -18, -- [0][0][RTW89_ETSI][12] = 32, -- [0][0][RTW89_FCC][14] = -18, -- [0][0][RTW89_ETSI][14] = 32, -- [0][0][RTW89_FCC][15] = -18, -- [0][0][RTW89_ETSI][15] = 32, -- [0][0][RTW89_FCC][17] = -18, -- [0][0][RTW89_ETSI][17] = 32, -- [0][0][RTW89_FCC][19] = -18, -- [0][0][RTW89_ETSI][19] = 32, -- [0][0][RTW89_FCC][21] = -18, -- [0][0][RTW89_ETSI][21] = 32, -- [0][0][RTW89_FCC][23] = -18, -- [0][0][RTW89_ETSI][23] = 32, -- [0][0][RTW89_FCC][25] = -18, -- [0][0][RTW89_ETSI][25] = 32, -- [0][0][RTW89_FCC][27] = -18, -- [0][0][RTW89_ETSI][27] = 32, -- [0][0][RTW89_FCC][29] = -18, -- [0][0][RTW89_ETSI][29] = 32, -- [0][0][RTW89_FCC][30] = -18, -- [0][0][RTW89_ETSI][30] = 32, -- [0][0][RTW89_FCC][32] = -18, -- [0][0][RTW89_ETSI][32] = 32, -- [0][0][RTW89_FCC][34] = -18, -- [0][0][RTW89_ETSI][34] = 32, -- [0][0][RTW89_FCC][36] = -18, -- [0][0][RTW89_ETSI][36] = 32, -- [0][0][RTW89_FCC][38] = -18, -- [0][0][RTW89_ETSI][38] = 32, -- [0][0][RTW89_FCC][40] = -18, -- [0][0][RTW89_ETSI][40] = 32, -- [0][0][RTW89_FCC][42] = -18, -- [0][0][RTW89_ETSI][42] = 32, -- [0][0][RTW89_FCC][44] = -16, -- [0][0][RTW89_ETSI][44] = 32, -- [0][0][RTW89_FCC][45] = -16, -- [0][0][RTW89_ETSI][45] = 127, -- [0][0][RTW89_FCC][47] = -18, -- [0][0][RTW89_ETSI][47] = 127, -- [0][0][RTW89_FCC][49] = -18, -- [0][0][RTW89_ETSI][49] = 127, -- [0][0][RTW89_FCC][51] = -18, -- [0][0][RTW89_ETSI][51] = 127, -- [0][0][RTW89_FCC][53] = -16, -- [0][0][RTW89_ETSI][53] = 127, -- [0][0][RTW89_FCC][55] = -18, -- [0][0][RTW89_ETSI][55] = 127, -- [0][0][RTW89_FCC][57] = -18, -- [0][0][RTW89_ETSI][57] = 127, -- [0][0][RTW89_FCC][59] = -18, -- [0][0][RTW89_ETSI][59] = 127, -- [0][0][RTW89_FCC][60] = -18, -- [0][0][RTW89_ETSI][60] = 127, -- [0][0][RTW89_FCC][62] = -18, -- [0][0][RTW89_ETSI][62] = 127, -- [0][0][RTW89_FCC][64] = -18, -- [0][0][RTW89_ETSI][64] = 127, -- [0][0][RTW89_FCC][66] = -18, -- [0][0][RTW89_ETSI][66] = 127, -- [0][0][RTW89_FCC][68] = -18, -- [0][0][RTW89_ETSI][68] = 127, -- [0][0][RTW89_FCC][70] = -16, -- [0][0][RTW89_ETSI][70] = 127, -- [0][0][RTW89_FCC][72] = -18, -- [0][0][RTW89_ETSI][72] = 127, -- [0][0][RTW89_FCC][74] = -18, -- [0][0][RTW89_ETSI][74] = 127, -- [0][0][RTW89_FCC][75] = -18, -- [0][0][RTW89_ETSI][75] = 127, -- [0][0][RTW89_FCC][77] = -18, -- [0][0][RTW89_ETSI][77] = 127, -- [0][0][RTW89_FCC][79] = -18, -- [0][0][RTW89_ETSI][79] = 127, -- [0][0][RTW89_FCC][81] = -18, -- [0][0][RTW89_ETSI][81] = 127, -- [0][0][RTW89_FCC][83] = -18, -- [0][0][RTW89_ETSI][83] = 127, -- [0][0][RTW89_FCC][85] = -18, -- [0][0][RTW89_ETSI][85] = 127, -- [0][0][RTW89_FCC][87] = -16, -- [0][0][RTW89_ETSI][87] = 127, -- [0][0][RTW89_FCC][89] = -16, -- [0][0][RTW89_ETSI][89] = 127, -- [0][0][RTW89_FCC][90] = -16, -- [0][0][RTW89_ETSI][90] = 127, -- [0][0][RTW89_FCC][92] = -16, -- [0][0][RTW89_ETSI][92] = 127, -- [0][0][RTW89_FCC][94] = -16, -- [0][0][RTW89_ETSI][94] = 127, -- [0][0][RTW89_FCC][96] = -16, -- [0][0][RTW89_ETSI][96] = 127, -- [0][0][RTW89_FCC][98] = -16, -- [0][0][RTW89_ETSI][98] = 127, -- [0][0][RTW89_FCC][100] = -16, -- [0][0][RTW89_ETSI][100] = 127, -- [0][0][RTW89_FCC][102] = -16, -- [0][0][RTW89_ETSI][102] = 127, -- [0][0][RTW89_FCC][104] = -16, -- [0][0][RTW89_ETSI][104] = 127, -- [0][0][RTW89_FCC][105] = -16, -- [0][0][RTW89_ETSI][105] = 127, -- [0][0][RTW89_FCC][107] = -12, -- [0][0][RTW89_ETSI][107] = 127, -- [0][0][RTW89_FCC][109] = -12, -- [0][0][RTW89_ETSI][109] = 127, -- [0][0][RTW89_FCC][111] = 127, -- [0][0][RTW89_ETSI][111] = 127, -- [0][0][RTW89_FCC][113] = 127, -- [0][0][RTW89_ETSI][113] = 127, -- [0][0][RTW89_FCC][115] = 127, -- [0][0][RTW89_ETSI][115] = 127, -- [0][0][RTW89_FCC][117] = 127, -- [0][0][RTW89_ETSI][117] = 127, -- [0][0][RTW89_FCC][119] = 127, -- [0][0][RTW89_ETSI][119] = 127, -- [0][1][RTW89_FCC][0] = -40, -- [0][1][RTW89_ETSI][0] = 20, -- [0][1][RTW89_FCC][2] = -40, -- [0][1][RTW89_ETSI][2] = 20, -- [0][1][RTW89_FCC][4] = -40, -- [0][1][RTW89_ETSI][4] = 20, -- [0][1][RTW89_FCC][6] = -40, -- [0][1][RTW89_ETSI][6] = 20, -- [0][1][RTW89_FCC][8] = -40, -- [0][1][RTW89_ETSI][8] = 20, -- [0][1][RTW89_FCC][10] = -40, -- [0][1][RTW89_ETSI][10] = 20, -- [0][1][RTW89_FCC][12] = -40, -- [0][1][RTW89_ETSI][12] = 20, -- [0][1][RTW89_FCC][14] = -40, -- [0][1][RTW89_ETSI][14] = 20, -- [0][1][RTW89_FCC][15] = -40, -- [0][1][RTW89_ETSI][15] = 20, -- [0][1][RTW89_FCC][17] = -40, -- [0][1][RTW89_ETSI][17] = 20, -- [0][1][RTW89_FCC][19] = -40, -- [0][1][RTW89_ETSI][19] = 20, -- [0][1][RTW89_FCC][21] = -40, -- [0][1][RTW89_ETSI][21] = 20, -- [0][1][RTW89_FCC][23] = -40, -- [0][1][RTW89_ETSI][23] = 20, -- [0][1][RTW89_FCC][25] = -40, -- [0][1][RTW89_ETSI][25] = 20, -- [0][1][RTW89_FCC][27] = -40, -- [0][1][RTW89_ETSI][27] = 20, -- [0][1][RTW89_FCC][29] = -40, -- [0][1][RTW89_ETSI][29] = 20, -- [0][1][RTW89_FCC][30] = -40, -- [0][1][RTW89_ETSI][30] = 20, -- [0][1][RTW89_FCC][32] = -40, -- [0][1][RTW89_ETSI][32] = 20, -- [0][1][RTW89_FCC][34] = -40, -- [0][1][RTW89_ETSI][34] = 20, -- [0][1][RTW89_FCC][36] = -40, -- [0][1][RTW89_ETSI][36] = 20, -- [0][1][RTW89_FCC][38] = -40, -- [0][1][RTW89_ETSI][38] = 20, -- [0][1][RTW89_FCC][40] = -40, -- [0][1][RTW89_ETSI][40] = 20, -- [0][1][RTW89_FCC][42] = -40, -- [0][1][RTW89_ETSI][42] = 20, -- [0][1][RTW89_FCC][44] = -40, -- [0][1][RTW89_ETSI][44] = 20, -- [0][1][RTW89_FCC][45] = -40, -- [0][1][RTW89_ETSI][45] = 127, -- [0][1][RTW89_FCC][47] = -40, -- [0][1][RTW89_ETSI][47] = 127, -- [0][1][RTW89_FCC][49] = -40, -- [0][1][RTW89_ETSI][49] = 127, -- [0][1][RTW89_FCC][51] = -40, -- [0][1][RTW89_ETSI][51] = 127, -- [0][1][RTW89_FCC][53] = -40, -- [0][1][RTW89_ETSI][53] = 127, -- [0][1][RTW89_FCC][55] = -40, -- [0][1][RTW89_ETSI][55] = 127, -- [0][1][RTW89_FCC][57] = -40, -- [0][1][RTW89_ETSI][57] = 127, -- [0][1][RTW89_FCC][59] = -40, -- [0][1][RTW89_ETSI][59] = 127, -- [0][1][RTW89_FCC][60] = -40, -- [0][1][RTW89_ETSI][60] = 127, -- [0][1][RTW89_FCC][62] = -40, -- [0][1][RTW89_ETSI][62] = 127, -- [0][1][RTW89_FCC][64] = -40, -- [0][1][RTW89_ETSI][64] = 127, -- [0][1][RTW89_FCC][66] = -40, -- [0][1][RTW89_ETSI][66] = 127, -- [0][1][RTW89_FCC][68] = -40, -- [0][1][RTW89_ETSI][68] = 127, -- [0][1][RTW89_FCC][70] = -38, -- [0][1][RTW89_ETSI][70] = 127, -- [0][1][RTW89_FCC][72] = -38, -- [0][1][RTW89_ETSI][72] = 127, -- [0][1][RTW89_FCC][74] = -38, -- [0][1][RTW89_ETSI][74] = 127, -- [0][1][RTW89_FCC][75] = -38, -- [0][1][RTW89_ETSI][75] = 127, -- [0][1][RTW89_FCC][77] = -38, -- [0][1][RTW89_ETSI][77] = 127, -- [0][1][RTW89_FCC][79] = -38, -- [0][1][RTW89_ETSI][79] = 127, -- [0][1][RTW89_FCC][81] = -38, -- [0][1][RTW89_ETSI][81] = 127, -- [0][1][RTW89_FCC][83] = -38, -- [0][1][RTW89_ETSI][83] = 127, -- [0][1][RTW89_FCC][85] = -38, -- [0][1][RTW89_ETSI][85] = 127, -- [0][1][RTW89_FCC][87] = -40, -- [0][1][RTW89_ETSI][87] = 127, -- [0][1][RTW89_FCC][89] = -38, -- [0][1][RTW89_ETSI][89] = 127, -- [0][1][RTW89_FCC][90] = -38, -- [0][1][RTW89_ETSI][90] = 127, -- [0][1][RTW89_FCC][92] = -38, -- [0][1][RTW89_ETSI][92] = 127, -- [0][1][RTW89_FCC][94] = -38, -- [0][1][RTW89_ETSI][94] = 127, -- [0][1][RTW89_FCC][96] = -38, -- [0][1][RTW89_ETSI][96] = 127, -- [0][1][RTW89_FCC][98] = -38, -- [0][1][RTW89_ETSI][98] = 127, -- [0][1][RTW89_FCC][100] = -38, -- [0][1][RTW89_ETSI][100] = 127, -- [0][1][RTW89_FCC][102] = -38, -- [0][1][RTW89_ETSI][102] = 127, -- [0][1][RTW89_FCC][104] = -38, -- [0][1][RTW89_ETSI][104] = 127, -- [0][1][RTW89_FCC][105] = -38, -- [0][1][RTW89_ETSI][105] = 127, -- [0][1][RTW89_FCC][107] = -34, -- [0][1][RTW89_ETSI][107] = 127, -- [0][1][RTW89_FCC][109] = -34, -- [0][1][RTW89_ETSI][109] = 127, -- [0][1][RTW89_FCC][111] = 127, -- [0][1][RTW89_ETSI][111] = 127, -- [0][1][RTW89_FCC][113] = 127, -- [0][1][RTW89_ETSI][113] = 127, -- [0][1][RTW89_FCC][115] = 127, -- [0][1][RTW89_ETSI][115] = 127, -- [0][1][RTW89_FCC][117] = 127, -- [0][1][RTW89_ETSI][117] = 127, -- [0][1][RTW89_FCC][119] = 127, -- [0][1][RTW89_ETSI][119] = 127, -- [1][0][RTW89_FCC][0] = -4, -- [1][0][RTW89_ETSI][0] = 46, -- [1][0][RTW89_FCC][2] = -4, -- [1][0][RTW89_ETSI][2] = 46, -- [1][0][RTW89_FCC][4] = -4, -- [1][0][RTW89_ETSI][4] = 46, -- [1][0][RTW89_FCC][6] = -4, -- [1][0][RTW89_ETSI][6] = 46, -- [1][0][RTW89_FCC][8] = -4, -- [1][0][RTW89_ETSI][8] = 46, -- [1][0][RTW89_FCC][10] = -4, -- [1][0][RTW89_ETSI][10] = 46, -- [1][0][RTW89_FCC][12] = -4, -- [1][0][RTW89_ETSI][12] = 46, -- [1][0][RTW89_FCC][14] = -4, -- [1][0][RTW89_ETSI][14] = 46, -- [1][0][RTW89_FCC][15] = -4, -- [1][0][RTW89_ETSI][15] = 46, -- [1][0][RTW89_FCC][17] = -4, -- [1][0][RTW89_ETSI][17] = 46, -- [1][0][RTW89_FCC][19] = -4, -- [1][0][RTW89_ETSI][19] = 46, -- [1][0][RTW89_FCC][21] = -4, -- [1][0][RTW89_ETSI][21] = 46, -- [1][0][RTW89_FCC][23] = -4, -- [1][0][RTW89_ETSI][23] = 46, -- [1][0][RTW89_FCC][25] = -4, -- [1][0][RTW89_ETSI][25] = 46, -- [1][0][RTW89_FCC][27] = -4, -- [1][0][RTW89_ETSI][27] = 46, -- [1][0][RTW89_FCC][29] = -4, -- [1][0][RTW89_ETSI][29] = 46, -- [1][0][RTW89_FCC][30] = -4, -- [1][0][RTW89_ETSI][30] = 46, -- [1][0][RTW89_FCC][32] = -4, -- [1][0][RTW89_ETSI][32] = 46, -- [1][0][RTW89_FCC][34] = -4, -- [1][0][RTW89_ETSI][34] = 46, -- [1][0][RTW89_FCC][36] = -4, -- [1][0][RTW89_ETSI][36] = 46, -- [1][0][RTW89_FCC][38] = -4, -- [1][0][RTW89_ETSI][38] = 46, -- [1][0][RTW89_FCC][40] = -4, -- [1][0][RTW89_ETSI][40] = 46, -- [1][0][RTW89_FCC][42] = -4, -- [1][0][RTW89_ETSI][42] = 46, -- [1][0][RTW89_FCC][44] = -4, -- [1][0][RTW89_ETSI][44] = 46, -- [1][0][RTW89_FCC][45] = -4, -- [1][0][RTW89_ETSI][45] = 127, -- [1][0][RTW89_FCC][47] = -4, -- [1][0][RTW89_ETSI][47] = 127, -- [1][0][RTW89_FCC][49] = -4, -- [1][0][RTW89_ETSI][49] = 127, -- [1][0][RTW89_FCC][51] = -4, -- [1][0][RTW89_ETSI][51] = 127, -- [1][0][RTW89_FCC][53] = -4, -- [1][0][RTW89_ETSI][53] = 127, -- [1][0][RTW89_FCC][55] = -4, -- [1][0][RTW89_ETSI][55] = 127, -- [1][0][RTW89_FCC][57] = -4, -- [1][0][RTW89_ETSI][57] = 127, -- [1][0][RTW89_FCC][59] = -4, -- [1][0][RTW89_ETSI][59] = 127, -- [1][0][RTW89_FCC][60] = -4, -- [1][0][RTW89_ETSI][60] = 127, -- [1][0][RTW89_FCC][62] = -4, -- [1][0][RTW89_ETSI][62] = 127, -- [1][0][RTW89_FCC][64] = -4, -- [1][0][RTW89_ETSI][64] = 127, -- [1][0][RTW89_FCC][66] = -4, -- [1][0][RTW89_ETSI][66] = 127, -- [1][0][RTW89_FCC][68] = -4, -- [1][0][RTW89_ETSI][68] = 127, -- [1][0][RTW89_FCC][70] = -4, -- [1][0][RTW89_ETSI][70] = 127, -- [1][0][RTW89_FCC][72] = -4, -- [1][0][RTW89_ETSI][72] = 127, -- [1][0][RTW89_FCC][74] = -4, -- [1][0][RTW89_ETSI][74] = 127, -- [1][0][RTW89_FCC][75] = -4, -- [1][0][RTW89_ETSI][75] = 127, -- [1][0][RTW89_FCC][77] = -4, -- [1][0][RTW89_ETSI][77] = 127, -- [1][0][RTW89_FCC][79] = -4, -- [1][0][RTW89_ETSI][79] = 127, -- [1][0][RTW89_FCC][81] = -4, -- [1][0][RTW89_ETSI][81] = 127, -- [1][0][RTW89_FCC][83] = -4, -- [1][0][RTW89_ETSI][83] = 127, -- [1][0][RTW89_FCC][85] = -4, -- [1][0][RTW89_ETSI][85] = 127, -- [1][0][RTW89_FCC][87] = -4, -- [1][0][RTW89_ETSI][87] = 127, -- [1][0][RTW89_FCC][89] = -4, -- [1][0][RTW89_ETSI][89] = 127, -- [1][0][RTW89_FCC][90] = -4, -- [1][0][RTW89_ETSI][90] = 127, -- [1][0][RTW89_FCC][92] = -4, -- [1][0][RTW89_ETSI][92] = 127, -- [1][0][RTW89_FCC][94] = -4, -- [1][0][RTW89_ETSI][94] = 127, -- [1][0][RTW89_FCC][96] = -4, -- [1][0][RTW89_ETSI][96] = 127, -- [1][0][RTW89_FCC][98] = -4, -- [1][0][RTW89_ETSI][98] = 127, -- [1][0][RTW89_FCC][100] = -4, -- [1][0][RTW89_ETSI][100] = 127, -- [1][0][RTW89_FCC][102] = -4, -- [1][0][RTW89_ETSI][102] = 127, -- [1][0][RTW89_FCC][104] = -4, -- [1][0][RTW89_ETSI][104] = 127, -- [1][0][RTW89_FCC][105] = -4, -- [1][0][RTW89_ETSI][105] = 127, -- [1][0][RTW89_FCC][107] = 0, -- [1][0][RTW89_ETSI][107] = 127, -- [1][0][RTW89_FCC][109] = 2, -- [1][0][RTW89_ETSI][109] = 127, -- [1][0][RTW89_FCC][111] = 127, -- [1][0][RTW89_ETSI][111] = 127, -- [1][0][RTW89_FCC][113] = 127, -- [1][0][RTW89_ETSI][113] = 127, -- [1][0][RTW89_FCC][115] = 127, -- [1][0][RTW89_ETSI][115] = 127, -- [1][0][RTW89_FCC][117] = 127, -- [1][0][RTW89_ETSI][117] = 127, -- [1][0][RTW89_FCC][119] = 127, -- [1][0][RTW89_ETSI][119] = 127, -- [1][1][RTW89_FCC][0] = -26, -- [1][1][RTW89_ETSI][0] = 32, -- [1][1][RTW89_FCC][2] = -28, -- [1][1][RTW89_ETSI][2] = 32, -- [1][1][RTW89_FCC][4] = -28, -- [1][1][RTW89_ETSI][4] = 32, -- [1][1][RTW89_FCC][6] = -28, -- [1][1][RTW89_ETSI][6] = 32, -- [1][1][RTW89_FCC][8] = -28, -- [1][1][RTW89_ETSI][8] = 32, -- [1][1][RTW89_FCC][10] = -28, -- [1][1][RTW89_ETSI][10] = 32, -- [1][1][RTW89_FCC][12] = -28, -- [1][1][RTW89_ETSI][12] = 32, -- [1][1][RTW89_FCC][14] = -28, -- [1][1][RTW89_ETSI][14] = 32, -- [1][1][RTW89_FCC][15] = -28, -- [1][1][RTW89_ETSI][15] = 32, -- [1][1][RTW89_FCC][17] = -28, -- [1][1][RTW89_ETSI][17] = 32, -- [1][1][RTW89_FCC][19] = -28, -- [1][1][RTW89_ETSI][19] = 32, -- [1][1][RTW89_FCC][21] = -28, -- [1][1][RTW89_ETSI][21] = 32, -- [1][1][RTW89_FCC][23] = -28, -- [1][1][RTW89_ETSI][23] = 32, -- [1][1][RTW89_FCC][25] = -28, -- [1][1][RTW89_ETSI][25] = 32, -- [1][1][RTW89_FCC][27] = -28, -- [1][1][RTW89_ETSI][27] = 32, -- [1][1][RTW89_FCC][29] = -28, -- [1][1][RTW89_ETSI][29] = 32, -- [1][1][RTW89_FCC][30] = -28, -- [1][1][RTW89_ETSI][30] = 32, -- [1][1][RTW89_FCC][32] = -28, -- [1][1][RTW89_ETSI][32] = 32, -- [1][1][RTW89_FCC][34] = -28, -- [1][1][RTW89_ETSI][34] = 32, -- [1][1][RTW89_FCC][36] = -28, -- [1][1][RTW89_ETSI][36] = 32, -- [1][1][RTW89_FCC][38] = -28, -- [1][1][RTW89_ETSI][38] = 32, -- [1][1][RTW89_FCC][40] = -28, -- [1][1][RTW89_ETSI][40] = 32, -- [1][1][RTW89_FCC][42] = -28, -- [1][1][RTW89_ETSI][42] = 32, -- [1][1][RTW89_FCC][44] = -28, -- [1][1][RTW89_ETSI][44] = 34, -- [1][1][RTW89_FCC][45] = -26, -- [1][1][RTW89_ETSI][45] = 127, -- [1][1][RTW89_FCC][47] = -28, -- [1][1][RTW89_ETSI][47] = 127, -- [1][1][RTW89_FCC][49] = -28, -- [1][1][RTW89_ETSI][49] = 127, -- [1][1][RTW89_FCC][51] = -28, -- [1][1][RTW89_ETSI][51] = 127, -- [1][1][RTW89_FCC][53] = -26, -- [1][1][RTW89_ETSI][53] = 127, -- [1][1][RTW89_FCC][55] = -28, -- [1][1][RTW89_ETSI][55] = 127, -- [1][1][RTW89_FCC][57] = -28, -- [1][1][RTW89_ETSI][57] = 127, -- [1][1][RTW89_FCC][59] = -28, -- [1][1][RTW89_ETSI][59] = 127, -- [1][1][RTW89_FCC][60] = -28, -- [1][1][RTW89_ETSI][60] = 127, -- [1][1][RTW89_FCC][62] = -28, -- [1][1][RTW89_ETSI][62] = 127, -- [1][1][RTW89_FCC][64] = -28, -- [1][1][RTW89_ETSI][64] = 127, -- [1][1][RTW89_FCC][66] = -28, -- [1][1][RTW89_ETSI][66] = 127, -- [1][1][RTW89_FCC][68] = -28, -- [1][1][RTW89_ETSI][68] = 127, -- [1][1][RTW89_FCC][70] = -26, -- [1][1][RTW89_ETSI][70] = 127, -- [1][1][RTW89_FCC][72] = -28, -- [1][1][RTW89_ETSI][72] = 127, -- [1][1][RTW89_FCC][74] = -28, -- [1][1][RTW89_ETSI][74] = 127, -- [1][1][RTW89_FCC][75] = -28, -- [1][1][RTW89_ETSI][75] = 127, -- [1][1][RTW89_FCC][77] = -28, -- [1][1][RTW89_ETSI][77] = 127, -- [1][1][RTW89_FCC][79] = -28, -- [1][1][RTW89_ETSI][79] = 127, -- [1][1][RTW89_FCC][81] = -28, -- [1][1][RTW89_ETSI][81] = 127, -- [1][1][RTW89_FCC][83] = -28, -- [1][1][RTW89_ETSI][83] = 127, -- [1][1][RTW89_FCC][85] = -28, -- [1][1][RTW89_ETSI][85] = 127, -- [1][1][RTW89_FCC][87] = -28, -- [1][1][RTW89_ETSI][87] = 127, -- [1][1][RTW89_FCC][89] = -26, -- [1][1][RTW89_ETSI][89] = 127, -- [1][1][RTW89_FCC][90] = -26, -- [1][1][RTW89_ETSI][90] = 127, -- [1][1][RTW89_FCC][92] = -26, -- [1][1][RTW89_ETSI][92] = 127, -- [1][1][RTW89_FCC][94] = -26, -- [1][1][RTW89_ETSI][94] = 127, -- [1][1][RTW89_FCC][96] = -26, -- [1][1][RTW89_ETSI][96] = 127, -- [1][1][RTW89_FCC][98] = -26, -- [1][1][RTW89_ETSI][98] = 127, -- [1][1][RTW89_FCC][100] = -26, -- [1][1][RTW89_ETSI][100] = 127, -- [1][1][RTW89_FCC][102] = -26, -- [1][1][RTW89_ETSI][102] = 127, -- [1][1][RTW89_FCC][104] = -26, -- [1][1][RTW89_ETSI][104] = 127, -- [1][1][RTW89_FCC][105] = -26, -- [1][1][RTW89_ETSI][105] = 127, -- [1][1][RTW89_FCC][107] = -22, -- [1][1][RTW89_ETSI][107] = 127, -- [1][1][RTW89_FCC][109] = -22, -- [1][1][RTW89_ETSI][109] = 127, -- [1][1][RTW89_FCC][111] = 127, -- [1][1][RTW89_ETSI][111] = 127, -- [1][1][RTW89_FCC][113] = 127, -- [1][1][RTW89_ETSI][113] = 127, -- [1][1][RTW89_FCC][115] = 127, -- [1][1][RTW89_ETSI][115] = 127, -- [1][1][RTW89_FCC][117] = 127, -- [1][1][RTW89_ETSI][117] = 127, -- [1][1][RTW89_FCC][119] = 127, -- [1][1][RTW89_ETSI][119] = 127, -- [2][0][RTW89_FCC][0] = 8, -- [2][0][RTW89_ETSI][0] = 56, -- [2][0][RTW89_FCC][2] = 8, -- [2][0][RTW89_ETSI][2] = 56, -- [2][0][RTW89_FCC][4] = 8, -- [2][0][RTW89_ETSI][4] = 56, -- [2][0][RTW89_FCC][6] = 8, -- [2][0][RTW89_ETSI][6] = 56, -- [2][0][RTW89_FCC][8] = 8, -- [2][0][RTW89_ETSI][8] = 56, -- [2][0][RTW89_FCC][10] = 8, -- [2][0][RTW89_ETSI][10] = 56, -- [2][0][RTW89_FCC][12] = 8, -- [2][0][RTW89_ETSI][12] = 56, -- [2][0][RTW89_FCC][14] = 8, -- [2][0][RTW89_ETSI][14] = 56, -- [2][0][RTW89_FCC][15] = 8, -- [2][0][RTW89_ETSI][15] = 56, -- [2][0][RTW89_FCC][17] = 8, -- [2][0][RTW89_ETSI][17] = 56, -- [2][0][RTW89_FCC][19] = 8, -- [2][0][RTW89_ETSI][19] = 56, -- [2][0][RTW89_FCC][21] = 8, -- [2][0][RTW89_ETSI][21] = 56, -- [2][0][RTW89_FCC][23] = 8, -- [2][0][RTW89_ETSI][23] = 56, -- [2][0][RTW89_FCC][25] = 8, -- [2][0][RTW89_ETSI][25] = 56, -- [2][0][RTW89_FCC][27] = 8, -- [2][0][RTW89_ETSI][27] = 56, -- [2][0][RTW89_FCC][29] = 8, -- [2][0][RTW89_ETSI][29] = 56, -- [2][0][RTW89_FCC][30] = 8, -- [2][0][RTW89_ETSI][30] = 56, -- [2][0][RTW89_FCC][32] = 8, -- [2][0][RTW89_ETSI][32] = 56, -- [2][0][RTW89_FCC][34] = 8, -- [2][0][RTW89_ETSI][34] = 56, -- [2][0][RTW89_FCC][36] = 8, -- [2][0][RTW89_ETSI][36] = 56, -- [2][0][RTW89_FCC][38] = 8, -- [2][0][RTW89_ETSI][38] = 56, -- [2][0][RTW89_FCC][40] = 8, -- [2][0][RTW89_ETSI][40] = 56, -- [2][0][RTW89_FCC][42] = 8, -- [2][0][RTW89_ETSI][42] = 56, -- [2][0][RTW89_FCC][44] = 8, -- [2][0][RTW89_ETSI][44] = 56, -- [2][0][RTW89_FCC][45] = 8, -- [2][0][RTW89_ETSI][45] = 127, -- [2][0][RTW89_FCC][47] = 8, -- [2][0][RTW89_ETSI][47] = 127, -- [2][0][RTW89_FCC][49] = 8, -- [2][0][RTW89_ETSI][49] = 127, -- [2][0][RTW89_FCC][51] = 8, -- [2][0][RTW89_ETSI][51] = 127, -- [2][0][RTW89_FCC][53] = 8, -- [2][0][RTW89_ETSI][53] = 127, -- [2][0][RTW89_FCC][55] = 8, -- [2][0][RTW89_ETSI][55] = 127, -- [2][0][RTW89_FCC][57] = 8, -- [2][0][RTW89_ETSI][57] = 127, -- [2][0][RTW89_FCC][59] = 8, -- [2][0][RTW89_ETSI][59] = 127, -- [2][0][RTW89_FCC][60] = 8, -- [2][0][RTW89_ETSI][60] = 127, -- [2][0][RTW89_FCC][62] = 8, -- [2][0][RTW89_ETSI][62] = 127, -- [2][0][RTW89_FCC][64] = 8, -- [2][0][RTW89_ETSI][64] = 127, -- [2][0][RTW89_FCC][66] = 8, -- [2][0][RTW89_ETSI][66] = 127, -- [2][0][RTW89_FCC][68] = 8, -- [2][0][RTW89_ETSI][68] = 127, -- [2][0][RTW89_FCC][70] = 8, -- [2][0][RTW89_ETSI][70] = 127, -- [2][0][RTW89_FCC][72] = 8, -- [2][0][RTW89_ETSI][72] = 127, -- [2][0][RTW89_FCC][74] = 8, -- [2][0][RTW89_ETSI][74] = 127, -- [2][0][RTW89_FCC][75] = 8, -- [2][0][RTW89_ETSI][75] = 127, -- [2][0][RTW89_FCC][77] = 8, -- [2][0][RTW89_ETSI][77] = 127, -- [2][0][RTW89_FCC][79] = 8, -- [2][0][RTW89_ETSI][79] = 127, -- [2][0][RTW89_FCC][81] = 8, -- [2][0][RTW89_ETSI][81] = 127, -- [2][0][RTW89_FCC][83] = 8, -- [2][0][RTW89_ETSI][83] = 127, -- [2][0][RTW89_FCC][85] = 8, -- [2][0][RTW89_ETSI][85] = 127, -- [2][0][RTW89_FCC][87] = 8, -- [2][0][RTW89_ETSI][87] = 127, -- [2][0][RTW89_FCC][89] = 8, -- [2][0][RTW89_ETSI][89] = 127, -- [2][0][RTW89_FCC][90] = 8, -- [2][0][RTW89_ETSI][90] = 127, -- [2][0][RTW89_FCC][92] = 8, -- [2][0][RTW89_ETSI][92] = 127, -- [2][0][RTW89_FCC][94] = 8, -- [2][0][RTW89_ETSI][94] = 127, -- [2][0][RTW89_FCC][96] = 8, -- [2][0][RTW89_ETSI][96] = 127, -- [2][0][RTW89_FCC][98] = 8, -- [2][0][RTW89_ETSI][98] = 127, -- [2][0][RTW89_FCC][100] = 8, -- [2][0][RTW89_ETSI][100] = 127, -- [2][0][RTW89_FCC][102] = 8, -- [2][0][RTW89_ETSI][102] = 127, -- [2][0][RTW89_FCC][104] = 8, -- [2][0][RTW89_ETSI][104] = 127, -- [2][0][RTW89_FCC][105] = 8, -- [2][0][RTW89_ETSI][105] = 127, -- [2][0][RTW89_FCC][107] = 10, -- [2][0][RTW89_ETSI][107] = 127, -- [2][0][RTW89_FCC][109] = 12, -- [2][0][RTW89_ETSI][109] = 127, -- [2][0][RTW89_FCC][111] = 127, -- [2][0][RTW89_ETSI][111] = 127, -- [2][0][RTW89_FCC][113] = 127, -- [2][0][RTW89_ETSI][113] = 127, -- [2][0][RTW89_FCC][115] = 127, -- [2][0][RTW89_ETSI][115] = 127, -- [2][0][RTW89_FCC][117] = 127, -- [2][0][RTW89_ETSI][117] = 127, -- [2][0][RTW89_FCC][119] = 127, -- [2][0][RTW89_ETSI][119] = 127, -- [2][1][RTW89_FCC][0] = -16, -- [2][1][RTW89_ETSI][0] = 44, -- [2][1][RTW89_FCC][2] = -16, -- [2][1][RTW89_ETSI][2] = 44, -- [2][1][RTW89_FCC][4] = -16, -- [2][1][RTW89_ETSI][4] = 44, -- [2][1][RTW89_FCC][6] = -16, -- [2][1][RTW89_ETSI][6] = 44, -- [2][1][RTW89_FCC][8] = -16, -- [2][1][RTW89_ETSI][8] = 44, -- [2][1][RTW89_FCC][10] = -16, -- [2][1][RTW89_ETSI][10] = 44, -- [2][1][RTW89_FCC][12] = -16, -- [2][1][RTW89_ETSI][12] = 44, -- [2][1][RTW89_FCC][14] = -16, -- [2][1][RTW89_ETSI][14] = 44, -- [2][1][RTW89_FCC][15] = -16, -- [2][1][RTW89_ETSI][15] = 44, -- [2][1][RTW89_FCC][17] = -16, -- [2][1][RTW89_ETSI][17] = 44, -- [2][1][RTW89_FCC][19] = -16, -- [2][1][RTW89_ETSI][19] = 44, -- [2][1][RTW89_FCC][21] = -16, -- [2][1][RTW89_ETSI][21] = 44, -- [2][1][RTW89_FCC][23] = -16, -- [2][1][RTW89_ETSI][23] = 44, -- [2][1][RTW89_FCC][25] = -16, -- [2][1][RTW89_ETSI][25] = 44, -- [2][1][RTW89_FCC][27] = -16, -- [2][1][RTW89_ETSI][27] = 44, -- [2][1][RTW89_FCC][29] = -16, -- [2][1][RTW89_ETSI][29] = 44, -- [2][1][RTW89_FCC][30] = -16, -- [2][1][RTW89_ETSI][30] = 44, -- [2][1][RTW89_FCC][32] = -16, -- [2][1][RTW89_ETSI][32] = 44, -- [2][1][RTW89_FCC][34] = -16, -- [2][1][RTW89_ETSI][34] = 44, -- [2][1][RTW89_FCC][36] = -16, -- [2][1][RTW89_ETSI][36] = 44, -- [2][1][RTW89_FCC][38] = -16, -- [2][1][RTW89_ETSI][38] = 44, -- [2][1][RTW89_FCC][40] = -16, -- [2][1][RTW89_ETSI][40] = 44, -- [2][1][RTW89_FCC][42] = -16, -- [2][1][RTW89_ETSI][42] = 44, -- [2][1][RTW89_FCC][44] = -16, -- [2][1][RTW89_ETSI][44] = 44, -- [2][1][RTW89_FCC][45] = -16, -- [2][1][RTW89_ETSI][45] = 127, -- [2][1][RTW89_FCC][47] = -16, -- [2][1][RTW89_ETSI][47] = 127, -- [2][1][RTW89_FCC][49] = -16, -- [2][1][RTW89_ETSI][49] = 127, -- [2][1][RTW89_FCC][51] = -16, -- [2][1][RTW89_ETSI][51] = 127, -- [2][1][RTW89_FCC][53] = -16, -- [2][1][RTW89_ETSI][53] = 127, -- [2][1][RTW89_FCC][55] = -16, -- [2][1][RTW89_ETSI][55] = 127, -- [2][1][RTW89_FCC][57] = -16, -- [2][1][RTW89_ETSI][57] = 127, -- [2][1][RTW89_FCC][59] = -16, -- [2][1][RTW89_ETSI][59] = 127, -- [2][1][RTW89_FCC][60] = -16, -- [2][1][RTW89_ETSI][60] = 127, -- [2][1][RTW89_FCC][62] = -16, -- [2][1][RTW89_ETSI][62] = 127, -- [2][1][RTW89_FCC][64] = -16, -- [2][1][RTW89_ETSI][64] = 127, -- [2][1][RTW89_FCC][66] = -16, -- [2][1][RTW89_ETSI][66] = 127, -- [2][1][RTW89_FCC][68] = -16, -- [2][1][RTW89_ETSI][68] = 127, -- [2][1][RTW89_FCC][70] = -16, -- [2][1][RTW89_ETSI][70] = 127, -- [2][1][RTW89_FCC][72] = -16, -- [2][1][RTW89_ETSI][72] = 127, -- [2][1][RTW89_FCC][74] = -16, -- [2][1][RTW89_ETSI][74] = 127, -- [2][1][RTW89_FCC][75] = -16, -- [2][1][RTW89_ETSI][75] = 127, -- [2][1][RTW89_FCC][77] = -16, -- [2][1][RTW89_ETSI][77] = 127, -- [2][1][RTW89_FCC][79] = -16, -- [2][1][RTW89_ETSI][79] = 127, -- [2][1][RTW89_FCC][81] = -16, -- [2][1][RTW89_ETSI][81] = 127, -- [2][1][RTW89_FCC][83] = -16, -- [2][1][RTW89_ETSI][83] = 127, -- [2][1][RTW89_FCC][85] = -18, -- [2][1][RTW89_ETSI][85] = 127, -- [2][1][RTW89_FCC][87] = -16, -- [2][1][RTW89_ETSI][87] = 127, -- [2][1][RTW89_FCC][89] = -16, -- [2][1][RTW89_ETSI][89] = 127, -- [2][1][RTW89_FCC][90] = -16, -- [2][1][RTW89_ETSI][90] = 127, -- [2][1][RTW89_FCC][92] = -16, -- [2][1][RTW89_ETSI][92] = 127, -- [2][1][RTW89_FCC][94] = -16, -- [2][1][RTW89_ETSI][94] = 127, -- [2][1][RTW89_FCC][96] = -16, -- [2][1][RTW89_ETSI][96] = 127, -- [2][1][RTW89_FCC][98] = -16, -- [2][1][RTW89_ETSI][98] = 127, -- [2][1][RTW89_FCC][100] = -16, -- [2][1][RTW89_ETSI][100] = 127, -- [2][1][RTW89_FCC][102] = -16, -- [2][1][RTW89_ETSI][102] = 127, -- [2][1][RTW89_FCC][104] = -16, -- [2][1][RTW89_ETSI][104] = 127, -- [2][1][RTW89_FCC][105] = -16, -- [2][1][RTW89_ETSI][105] = 127, -- [2][1][RTW89_FCC][107] = -12, -- [2][1][RTW89_ETSI][107] = 127, -- [2][1][RTW89_FCC][109] = -10, -- [2][1][RTW89_ETSI][109] = 127, -- [2][1][RTW89_FCC][111] = 127, -- [2][1][RTW89_ETSI][111] = 127, -- [2][1][RTW89_FCC][113] = 127, -- [2][1][RTW89_ETSI][113] = 127, -- [2][1][RTW89_FCC][115] = 127, -- [2][1][RTW89_ETSI][115] = 127, -- [2][1][RTW89_FCC][117] = 127, -- [2][1][RTW89_ETSI][117] = 127, -- [2][1][RTW89_FCC][119] = 127, -- [2][1][RTW89_ETSI][119] = 127, -+ [RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER] -+ [RTW89_6G_CH_NUM] = { -+ [0][0][RTW89_WW][0][0] = -16, -+ [0][0][RTW89_WW][1][0] = -16, -+ [0][0][RTW89_WW][2][0] = 44, -+ [0][0][RTW89_WW][0][2] = -18, -+ [0][0][RTW89_WW][1][2] = -18, -+ [0][0][RTW89_WW][2][2] = 44, -+ [0][0][RTW89_WW][0][4] = -18, -+ [0][0][RTW89_WW][1][4] = -18, -+ [0][0][RTW89_WW][2][4] = 44, -+ [0][0][RTW89_WW][0][6] = -18, -+ [0][0][RTW89_WW][1][6] = -18, -+ [0][0][RTW89_WW][2][6] = 44, -+ [0][0][RTW89_WW][0][8] = -18, -+ [0][0][RTW89_WW][1][8] = -18, -+ [0][0][RTW89_WW][2][8] = 44, -+ [0][0][RTW89_WW][0][10] = -18, -+ [0][0][RTW89_WW][1][10] = -18, -+ [0][0][RTW89_WW][2][10] = 44, -+ [0][0][RTW89_WW][0][12] = -18, -+ [0][0][RTW89_WW][1][12] = -18, -+ [0][0][RTW89_WW][2][12] = 44, -+ [0][0][RTW89_WW][0][14] = -18, -+ [0][0][RTW89_WW][1][14] = -18, -+ [0][0][RTW89_WW][2][14] = 44, -+ [0][0][RTW89_WW][0][15] = -18, -+ [0][0][RTW89_WW][1][15] = -18, -+ [0][0][RTW89_WW][2][15] = 44, -+ [0][0][RTW89_WW][0][17] = -18, -+ [0][0][RTW89_WW][1][17] = -18, -+ [0][0][RTW89_WW][2][17] = 44, -+ [0][0][RTW89_WW][0][19] = -18, -+ [0][0][RTW89_WW][1][19] = -18, -+ [0][0][RTW89_WW][2][19] = 44, -+ [0][0][RTW89_WW][0][21] = -18, -+ [0][0][RTW89_WW][1][21] = -18, -+ [0][0][RTW89_WW][2][21] = 44, -+ [0][0][RTW89_WW][0][23] = -18, -+ [0][0][RTW89_WW][1][23] = -18, -+ [0][0][RTW89_WW][2][23] = 54, -+ [0][0][RTW89_WW][0][25] = -18, -+ [0][0][RTW89_WW][1][25] = -18, -+ [0][0][RTW89_WW][2][25] = 54, -+ [0][0][RTW89_WW][0][27] = -18, -+ [0][0][RTW89_WW][1][27] = -18, -+ [0][0][RTW89_WW][2][27] = 54, -+ [0][0][RTW89_WW][0][29] = -18, -+ [0][0][RTW89_WW][1][29] = -18, -+ [0][0][RTW89_WW][2][29] = 54, -+ [0][0][RTW89_WW][0][30] = -18, -+ [0][0][RTW89_WW][1][30] = -18, -+ [0][0][RTW89_WW][2][30] = 54, -+ [0][0][RTW89_WW][0][32] = -18, -+ [0][0][RTW89_WW][1][32] = -18, -+ [0][0][RTW89_WW][2][32] = 54, -+ [0][0][RTW89_WW][0][34] = -18, -+ [0][0][RTW89_WW][1][34] = -18, -+ [0][0][RTW89_WW][2][34] = 54, -+ [0][0][RTW89_WW][0][36] = -18, -+ [0][0][RTW89_WW][1][36] = -18, -+ [0][0][RTW89_WW][2][36] = 54, -+ [0][0][RTW89_WW][0][38] = -18, -+ [0][0][RTW89_WW][1][38] = -18, -+ [0][0][RTW89_WW][2][38] = 54, -+ [0][0][RTW89_WW][0][40] = -18, -+ [0][0][RTW89_WW][1][40] = -18, -+ [0][0][RTW89_WW][2][40] = 54, -+ [0][0][RTW89_WW][0][42] = -18, -+ [0][0][RTW89_WW][1][42] = -18, -+ [0][0][RTW89_WW][2][42] = 54, -+ [0][0][RTW89_WW][0][44] = -16, -+ [0][0][RTW89_WW][1][44] = -16, -+ [0][0][RTW89_WW][2][44] = 56, -+ [0][0][RTW89_WW][0][45] = -16, -+ [0][0][RTW89_WW][1][45] = -16, -+ [0][0][RTW89_WW][2][45] = 0, -+ [0][0][RTW89_WW][0][47] = -18, -+ [0][0][RTW89_WW][1][47] = -18, -+ [0][0][RTW89_WW][2][47] = 0, -+ [0][0][RTW89_WW][0][49] = -18, -+ [0][0][RTW89_WW][1][49] = -18, -+ [0][0][RTW89_WW][2][49] = 0, -+ [0][0][RTW89_WW][0][51] = -18, -+ [0][0][RTW89_WW][1][51] = -18, -+ [0][0][RTW89_WW][2][51] = 0, -+ [0][0][RTW89_WW][0][53] = -16, -+ [0][0][RTW89_WW][1][53] = -16, -+ [0][0][RTW89_WW][2][53] = 0, -+ [0][0][RTW89_WW][0][55] = -18, -+ [0][0][RTW89_WW][1][55] = -18, -+ [0][0][RTW89_WW][2][55] = 56, -+ [0][0][RTW89_WW][0][57] = -18, -+ [0][0][RTW89_WW][1][57] = -18, -+ [0][0][RTW89_WW][2][57] = 56, -+ [0][0][RTW89_WW][0][59] = -18, -+ [0][0][RTW89_WW][1][59] = -18, -+ [0][0][RTW89_WW][2][59] = 56, -+ [0][0][RTW89_WW][0][60] = -18, -+ [0][0][RTW89_WW][1][60] = -18, -+ [0][0][RTW89_WW][2][60] = 56, -+ [0][0][RTW89_WW][0][62] = -18, -+ [0][0][RTW89_WW][1][62] = -18, -+ [0][0][RTW89_WW][2][62] = 56, -+ [0][0][RTW89_WW][0][64] = -18, -+ [0][0][RTW89_WW][1][64] = -18, -+ [0][0][RTW89_WW][2][64] = 56, -+ [0][0][RTW89_WW][0][66] = -18, -+ [0][0][RTW89_WW][1][66] = -18, -+ [0][0][RTW89_WW][2][66] = 56, -+ [0][0][RTW89_WW][0][68] = -18, -+ [0][0][RTW89_WW][1][68] = -18, -+ [0][0][RTW89_WW][2][68] = 56, -+ [0][0][RTW89_WW][0][70] = -16, -+ [0][0][RTW89_WW][1][70] = -16, -+ [0][0][RTW89_WW][2][70] = 56, -+ [0][0][RTW89_WW][0][72] = -18, -+ [0][0][RTW89_WW][1][72] = -18, -+ [0][0][RTW89_WW][2][72] = 56, -+ [0][0][RTW89_WW][0][74] = -18, -+ [0][0][RTW89_WW][1][74] = -18, -+ [0][0][RTW89_WW][2][74] = 56, -+ [0][0][RTW89_WW][0][75] = -18, -+ [0][0][RTW89_WW][1][75] = -18, -+ [0][0][RTW89_WW][2][75] = 56, -+ [0][0][RTW89_WW][0][77] = -18, -+ [0][0][RTW89_WW][1][77] = -18, -+ [0][0][RTW89_WW][2][77] = 56, -+ [0][0][RTW89_WW][0][79] = -18, -+ [0][0][RTW89_WW][1][79] = -18, -+ [0][0][RTW89_WW][2][79] = 56, -+ [0][0][RTW89_WW][0][81] = -18, -+ [0][0][RTW89_WW][1][81] = -18, -+ [0][0][RTW89_WW][2][81] = 56, -+ [0][0][RTW89_WW][0][83] = -18, -+ [0][0][RTW89_WW][1][83] = -18, -+ [0][0][RTW89_WW][2][83] = 56, -+ [0][0][RTW89_WW][0][85] = -18, -+ [0][0][RTW89_WW][1][85] = -18, -+ [0][0][RTW89_WW][2][85] = 56, -+ [0][0][RTW89_WW][0][87] = -16, -+ [0][0][RTW89_WW][1][87] = -16, -+ [0][0][RTW89_WW][2][87] = 0, -+ [0][0][RTW89_WW][0][89] = -16, -+ [0][0][RTW89_WW][1][89] = -16, -+ [0][0][RTW89_WW][2][89] = 0, -+ [0][0][RTW89_WW][0][90] = -16, -+ [0][0][RTW89_WW][1][90] = -16, -+ [0][0][RTW89_WW][2][90] = 0, -+ [0][0][RTW89_WW][0][92] = -16, -+ [0][0][RTW89_WW][1][92] = -16, -+ [0][0][RTW89_WW][2][92] = 0, -+ [0][0][RTW89_WW][0][94] = -16, -+ [0][0][RTW89_WW][1][94] = -16, -+ [0][0][RTW89_WW][2][94] = 0, -+ [0][0][RTW89_WW][0][96] = -16, -+ [0][0][RTW89_WW][1][96] = -16, -+ [0][0][RTW89_WW][2][96] = 0, -+ [0][0][RTW89_WW][0][98] = -16, -+ [0][0][RTW89_WW][1][98] = -16, -+ [0][0][RTW89_WW][2][98] = 0, -+ [0][0][RTW89_WW][0][100] = -16, -+ [0][0][RTW89_WW][1][100] = -16, -+ [0][0][RTW89_WW][2][100] = 0, -+ [0][0][RTW89_WW][0][102] = -16, -+ [0][0][RTW89_WW][1][102] = -16, -+ [0][0][RTW89_WW][2][102] = 0, -+ [0][0][RTW89_WW][0][104] = -16, -+ [0][0][RTW89_WW][1][104] = -16, -+ [0][0][RTW89_WW][2][104] = 0, -+ [0][0][RTW89_WW][0][105] = -16, -+ [0][0][RTW89_WW][1][105] = -16, -+ [0][0][RTW89_WW][2][105] = 0, -+ [0][0][RTW89_WW][0][107] = -12, -+ [0][0][RTW89_WW][1][107] = -12, -+ [0][0][RTW89_WW][2][107] = 0, -+ [0][0][RTW89_WW][0][109] = -12, -+ [0][0][RTW89_WW][1][109] = -12, -+ [0][0][RTW89_WW][2][109] = 0, -+ [0][0][RTW89_WW][0][111] = 0, -+ [0][0][RTW89_WW][1][111] = 0, -+ [0][0][RTW89_WW][2][111] = 0, -+ [0][0][RTW89_WW][0][113] = 0, -+ [0][0][RTW89_WW][1][113] = 0, -+ [0][0][RTW89_WW][2][113] = 0, -+ [0][0][RTW89_WW][0][115] = 0, -+ [0][0][RTW89_WW][1][115] = 0, -+ [0][0][RTW89_WW][2][115] = 0, -+ [0][0][RTW89_WW][0][117] = 0, -+ [0][0][RTW89_WW][1][117] = 0, -+ [0][0][RTW89_WW][2][117] = 0, -+ [0][0][RTW89_WW][0][119] = 0, -+ [0][0][RTW89_WW][1][119] = 0, -+ [0][0][RTW89_WW][2][119] = 0, -+ [0][1][RTW89_WW][0][0] = -40, -+ [0][1][RTW89_WW][1][0] = -40, -+ [0][1][RTW89_WW][2][0] = 32, -+ [0][1][RTW89_WW][0][2] = -40, -+ [0][1][RTW89_WW][1][2] = -40, -+ [0][1][RTW89_WW][2][2] = 32, -+ [0][1][RTW89_WW][0][4] = -40, -+ [0][1][RTW89_WW][1][4] = -40, -+ [0][1][RTW89_WW][2][4] = 32, -+ [0][1][RTW89_WW][0][6] = -40, -+ [0][1][RTW89_WW][1][6] = -40, -+ [0][1][RTW89_WW][2][6] = 32, -+ [0][1][RTW89_WW][0][8] = -40, -+ [0][1][RTW89_WW][1][8] = -40, -+ [0][1][RTW89_WW][2][8] = 32, -+ [0][1][RTW89_WW][0][10] = -40, -+ [0][1][RTW89_WW][1][10] = -40, -+ [0][1][RTW89_WW][2][10] = 32, -+ [0][1][RTW89_WW][0][12] = -40, -+ [0][1][RTW89_WW][1][12] = -40, -+ [0][1][RTW89_WW][2][12] = 32, -+ [0][1][RTW89_WW][0][14] = -40, -+ [0][1][RTW89_WW][1][14] = -40, -+ [0][1][RTW89_WW][2][14] = 32, -+ [0][1][RTW89_WW][0][15] = -40, -+ [0][1][RTW89_WW][1][15] = -40, -+ [0][1][RTW89_WW][2][15] = 32, -+ [0][1][RTW89_WW][0][17] = -40, -+ [0][1][RTW89_WW][1][17] = -40, -+ [0][1][RTW89_WW][2][17] = 32, -+ [0][1][RTW89_WW][0][19] = -40, -+ [0][1][RTW89_WW][1][19] = -40, -+ [0][1][RTW89_WW][2][19] = 32, -+ [0][1][RTW89_WW][0][21] = -40, -+ [0][1][RTW89_WW][1][21] = -40, -+ [0][1][RTW89_WW][2][21] = 32, -+ [0][1][RTW89_WW][0][23] = -40, -+ [0][1][RTW89_WW][1][23] = -40, -+ [0][1][RTW89_WW][2][23] = 32, -+ [0][1][RTW89_WW][0][25] = -40, -+ [0][1][RTW89_WW][1][25] = -40, -+ [0][1][RTW89_WW][2][25] = 32, -+ [0][1][RTW89_WW][0][27] = -40, -+ [0][1][RTW89_WW][1][27] = -40, -+ [0][1][RTW89_WW][2][27] = 32, -+ [0][1][RTW89_WW][0][29] = -40, -+ [0][1][RTW89_WW][1][29] = -40, -+ [0][1][RTW89_WW][2][29] = 32, -+ [0][1][RTW89_WW][0][30] = -40, -+ [0][1][RTW89_WW][1][30] = -40, -+ [0][1][RTW89_WW][2][30] = 32, -+ [0][1][RTW89_WW][0][32] = -40, -+ [0][1][RTW89_WW][1][32] = -40, -+ [0][1][RTW89_WW][2][32] = 32, -+ [0][1][RTW89_WW][0][34] = -40, -+ [0][1][RTW89_WW][1][34] = -40, -+ [0][1][RTW89_WW][2][34] = 32, -+ [0][1][RTW89_WW][0][36] = -40, -+ [0][1][RTW89_WW][1][36] = -40, -+ [0][1][RTW89_WW][2][36] = 32, -+ [0][1][RTW89_WW][0][38] = -40, -+ [0][1][RTW89_WW][1][38] = -40, -+ [0][1][RTW89_WW][2][38] = 32, -+ [0][1][RTW89_WW][0][40] = -40, -+ [0][1][RTW89_WW][1][40] = -40, -+ [0][1][RTW89_WW][2][40] = 32, -+ [0][1][RTW89_WW][0][42] = -40, -+ [0][1][RTW89_WW][1][42] = -40, -+ [0][1][RTW89_WW][2][42] = 32, -+ [0][1][RTW89_WW][0][44] = -40, -+ [0][1][RTW89_WW][1][44] = -40, -+ [0][1][RTW89_WW][2][44] = 32, -+ [0][1][RTW89_WW][0][45] = -40, -+ [0][1][RTW89_WW][1][45] = -40, -+ [0][1][RTW89_WW][2][45] = 0, -+ [0][1][RTW89_WW][0][47] = -40, -+ [0][1][RTW89_WW][1][47] = -40, -+ [0][1][RTW89_WW][2][47] = 0, -+ [0][1][RTW89_WW][0][49] = -40, -+ [0][1][RTW89_WW][1][49] = -40, -+ [0][1][RTW89_WW][2][49] = 0, -+ [0][1][RTW89_WW][0][51] = -40, -+ [0][1][RTW89_WW][1][51] = -40, -+ [0][1][RTW89_WW][2][51] = 0, -+ [0][1][RTW89_WW][0][53] = -40, -+ [0][1][RTW89_WW][1][53] = -40, -+ [0][1][RTW89_WW][2][53] = 0, -+ [0][1][RTW89_WW][0][55] = -40, -+ [0][1][RTW89_WW][1][55] = -40, -+ [0][1][RTW89_WW][2][55] = 30, -+ [0][1][RTW89_WW][0][57] = -40, -+ [0][1][RTW89_WW][1][57] = -40, -+ [0][1][RTW89_WW][2][57] = 30, -+ [0][1][RTW89_WW][0][59] = -40, -+ [0][1][RTW89_WW][1][59] = -40, -+ [0][1][RTW89_WW][2][59] = 30, -+ [0][1][RTW89_WW][0][60] = -40, -+ [0][1][RTW89_WW][1][60] = -40, -+ [0][1][RTW89_WW][2][60] = 30, -+ [0][1][RTW89_WW][0][62] = -40, -+ [0][1][RTW89_WW][1][62] = -40, -+ [0][1][RTW89_WW][2][62] = 30, -+ [0][1][RTW89_WW][0][64] = -40, -+ [0][1][RTW89_WW][1][64] = -40, -+ [0][1][RTW89_WW][2][64] = 30, -+ [0][1][RTW89_WW][0][66] = -40, -+ [0][1][RTW89_WW][1][66] = -40, -+ [0][1][RTW89_WW][2][66] = 30, -+ [0][1][RTW89_WW][0][68] = -40, -+ [0][1][RTW89_WW][1][68] = -40, -+ [0][1][RTW89_WW][2][68] = 30, -+ [0][1][RTW89_WW][0][70] = -38, -+ [0][1][RTW89_WW][1][70] = -38, -+ [0][1][RTW89_WW][2][70] = 30, -+ [0][1][RTW89_WW][0][72] = -38, -+ [0][1][RTW89_WW][1][72] = -38, -+ [0][1][RTW89_WW][2][72] = 30, -+ [0][1][RTW89_WW][0][74] = -38, -+ [0][1][RTW89_WW][1][74] = -38, -+ [0][1][RTW89_WW][2][74] = 30, -+ [0][1][RTW89_WW][0][75] = -38, -+ [0][1][RTW89_WW][1][75] = -38, -+ [0][1][RTW89_WW][2][75] = 30, -+ [0][1][RTW89_WW][0][77] = -38, -+ [0][1][RTW89_WW][1][77] = -38, -+ [0][1][RTW89_WW][2][77] = 30, -+ [0][1][RTW89_WW][0][79] = -38, -+ [0][1][RTW89_WW][1][79] = -38, -+ [0][1][RTW89_WW][2][79] = 30, -+ [0][1][RTW89_WW][0][81] = -38, -+ [0][1][RTW89_WW][1][81] = -38, -+ [0][1][RTW89_WW][2][81] = 30, -+ [0][1][RTW89_WW][0][83] = -38, -+ [0][1][RTW89_WW][1][83] = -38, -+ [0][1][RTW89_WW][2][83] = 30, -+ [0][1][RTW89_WW][0][85] = -38, -+ [0][1][RTW89_WW][1][85] = -38, -+ [0][1][RTW89_WW][2][85] = 30, -+ [0][1][RTW89_WW][0][87] = -40, -+ [0][1][RTW89_WW][1][87] = -40, -+ [0][1][RTW89_WW][2][87] = 0, -+ [0][1][RTW89_WW][0][89] = -38, -+ [0][1][RTW89_WW][1][89] = -38, -+ [0][1][RTW89_WW][2][89] = 0, -+ [0][1][RTW89_WW][0][90] = -38, -+ [0][1][RTW89_WW][1][90] = -38, -+ [0][1][RTW89_WW][2][90] = 0, -+ [0][1][RTW89_WW][0][92] = -38, -+ [0][1][RTW89_WW][1][92] = -38, -+ [0][1][RTW89_WW][2][92] = 0, -+ [0][1][RTW89_WW][0][94] = -38, -+ [0][1][RTW89_WW][1][94] = -38, -+ [0][1][RTW89_WW][2][94] = 0, -+ [0][1][RTW89_WW][0][96] = -38, -+ [0][1][RTW89_WW][1][96] = -38, -+ [0][1][RTW89_WW][2][96] = 0, -+ [0][1][RTW89_WW][0][98] = -38, -+ [0][1][RTW89_WW][1][98] = -38, -+ [0][1][RTW89_WW][2][98] = 0, -+ [0][1][RTW89_WW][0][100] = -38, -+ [0][1][RTW89_WW][1][100] = -38, -+ [0][1][RTW89_WW][2][100] = 0, -+ [0][1][RTW89_WW][0][102] = -38, -+ [0][1][RTW89_WW][1][102] = -38, -+ [0][1][RTW89_WW][2][102] = 0, -+ [0][1][RTW89_WW][0][104] = -38, -+ [0][1][RTW89_WW][1][104] = -38, -+ [0][1][RTW89_WW][2][104] = 0, -+ [0][1][RTW89_WW][0][105] = -38, -+ [0][1][RTW89_WW][1][105] = -38, -+ [0][1][RTW89_WW][2][105] = 0, -+ [0][1][RTW89_WW][0][107] = -34, -+ [0][1][RTW89_WW][1][107] = -34, -+ [0][1][RTW89_WW][2][107] = 0, -+ [0][1][RTW89_WW][0][109] = -34, -+ [0][1][RTW89_WW][1][109] = -34, -+ [0][1][RTW89_WW][2][109] = 0, -+ [0][1][RTW89_WW][0][111] = 0, -+ [0][1][RTW89_WW][1][111] = 0, -+ [0][1][RTW89_WW][2][111] = 0, -+ [0][1][RTW89_WW][0][113] = 0, -+ [0][1][RTW89_WW][1][113] = 0, -+ [0][1][RTW89_WW][2][113] = 0, -+ [0][1][RTW89_WW][0][115] = 0, -+ [0][1][RTW89_WW][1][115] = 0, -+ [0][1][RTW89_WW][2][115] = 0, -+ [0][1][RTW89_WW][0][117] = 0, -+ [0][1][RTW89_WW][1][117] = 0, -+ [0][1][RTW89_WW][2][117] = 0, -+ [0][1][RTW89_WW][0][119] = 0, -+ [0][1][RTW89_WW][1][119] = 0, -+ [0][1][RTW89_WW][2][119] = 0, -+ [1][0][RTW89_WW][0][0] = -4, -+ [1][0][RTW89_WW][1][0] = -4, -+ [1][0][RTW89_WW][2][0] = 52, -+ [1][0][RTW89_WW][0][2] = -4, -+ [1][0][RTW89_WW][1][2] = -4, -+ [1][0][RTW89_WW][2][2] = 52, -+ [1][0][RTW89_WW][0][4] = -4, -+ [1][0][RTW89_WW][1][4] = -4, -+ [1][0][RTW89_WW][2][4] = 52, -+ [1][0][RTW89_WW][0][6] = -4, -+ [1][0][RTW89_WW][1][6] = -4, -+ [1][0][RTW89_WW][2][6] = 52, -+ [1][0][RTW89_WW][0][8] = -4, -+ [1][0][RTW89_WW][1][8] = -4, -+ [1][0][RTW89_WW][2][8] = 52, -+ [1][0][RTW89_WW][0][10] = -4, -+ [1][0][RTW89_WW][1][10] = -4, -+ [1][0][RTW89_WW][2][10] = 52, -+ [1][0][RTW89_WW][0][12] = -4, -+ [1][0][RTW89_WW][1][12] = -4, -+ [1][0][RTW89_WW][2][12] = 52, -+ [1][0][RTW89_WW][0][14] = -4, -+ [1][0][RTW89_WW][1][14] = -4, -+ [1][0][RTW89_WW][2][14] = 52, -+ [1][0][RTW89_WW][0][15] = -4, -+ [1][0][RTW89_WW][1][15] = -4, -+ [1][0][RTW89_WW][2][15] = 52, -+ [1][0][RTW89_WW][0][17] = -4, -+ [1][0][RTW89_WW][1][17] = -4, -+ [1][0][RTW89_WW][2][17] = 52, -+ [1][0][RTW89_WW][0][19] = -4, -+ [1][0][RTW89_WW][1][19] = -4, -+ [1][0][RTW89_WW][2][19] = 52, -+ [1][0][RTW89_WW][0][21] = -4, -+ [1][0][RTW89_WW][1][21] = -4, -+ [1][0][RTW89_WW][2][21] = 52, -+ [1][0][RTW89_WW][0][23] = -4, -+ [1][0][RTW89_WW][1][23] = -4, -+ [1][0][RTW89_WW][2][23] = 66, -+ [1][0][RTW89_WW][0][25] = -4, -+ [1][0][RTW89_WW][1][25] = -4, -+ [1][0][RTW89_WW][2][25] = 66, -+ [1][0][RTW89_WW][0][27] = -4, -+ [1][0][RTW89_WW][1][27] = -4, -+ [1][0][RTW89_WW][2][27] = 66, -+ [1][0][RTW89_WW][0][29] = -4, -+ [1][0][RTW89_WW][1][29] = -4, -+ [1][0][RTW89_WW][2][29] = 66, -+ [1][0][RTW89_WW][0][30] = -4, -+ [1][0][RTW89_WW][1][30] = -4, -+ [1][0][RTW89_WW][2][30] = 66, -+ [1][0][RTW89_WW][0][32] = -4, -+ [1][0][RTW89_WW][1][32] = -4, -+ [1][0][RTW89_WW][2][32] = 66, -+ [1][0][RTW89_WW][0][34] = -4, -+ [1][0][RTW89_WW][1][34] = -4, -+ [1][0][RTW89_WW][2][34] = 66, -+ [1][0][RTW89_WW][0][36] = -4, -+ [1][0][RTW89_WW][1][36] = -4, -+ [1][0][RTW89_WW][2][36] = 66, -+ [1][0][RTW89_WW][0][38] = -4, -+ [1][0][RTW89_WW][1][38] = -4, -+ [1][0][RTW89_WW][2][38] = 66, -+ [1][0][RTW89_WW][0][40] = -4, -+ [1][0][RTW89_WW][1][40] = -4, -+ [1][0][RTW89_WW][2][40] = 66, -+ [1][0][RTW89_WW][0][42] = -4, -+ [1][0][RTW89_WW][1][42] = -4, -+ [1][0][RTW89_WW][2][42] = 66, -+ [1][0][RTW89_WW][0][44] = -4, -+ [1][0][RTW89_WW][1][44] = -4, -+ [1][0][RTW89_WW][2][44] = 66, -+ [1][0][RTW89_WW][0][45] = -4, -+ [1][0][RTW89_WW][1][45] = -4, -+ [1][0][RTW89_WW][2][45] = 0, -+ [1][0][RTW89_WW][0][47] = -4, -+ [1][0][RTW89_WW][1][47] = -4, -+ [1][0][RTW89_WW][2][47] = 0, -+ [1][0][RTW89_WW][0][49] = -4, -+ [1][0][RTW89_WW][1][49] = -4, -+ [1][0][RTW89_WW][2][49] = 0, -+ [1][0][RTW89_WW][0][51] = -4, -+ [1][0][RTW89_WW][1][51] = -4, -+ [1][0][RTW89_WW][2][51] = 0, -+ [1][0][RTW89_WW][0][53] = -4, -+ [1][0][RTW89_WW][1][53] = -4, -+ [1][0][RTW89_WW][2][53] = 0, -+ [1][0][RTW89_WW][0][55] = -4, -+ [1][0][RTW89_WW][1][55] = -4, -+ [1][0][RTW89_WW][2][55] = 68, -+ [1][0][RTW89_WW][0][57] = -4, -+ [1][0][RTW89_WW][1][57] = -4, -+ [1][0][RTW89_WW][2][57] = 68, -+ [1][0][RTW89_WW][0][59] = -4, -+ [1][0][RTW89_WW][1][59] = -4, -+ [1][0][RTW89_WW][2][59] = 68, -+ [1][0][RTW89_WW][0][60] = -4, -+ [1][0][RTW89_WW][1][60] = -4, -+ [1][0][RTW89_WW][2][60] = 68, -+ [1][0][RTW89_WW][0][62] = -4, -+ [1][0][RTW89_WW][1][62] = -4, -+ [1][0][RTW89_WW][2][62] = 68, -+ [1][0][RTW89_WW][0][64] = -4, -+ [1][0][RTW89_WW][1][64] = -4, -+ [1][0][RTW89_WW][2][64] = 68, -+ [1][0][RTW89_WW][0][66] = -4, -+ [1][0][RTW89_WW][1][66] = -4, -+ [1][0][RTW89_WW][2][66] = 68, -+ [1][0][RTW89_WW][0][68] = -4, -+ [1][0][RTW89_WW][1][68] = -4, -+ [1][0][RTW89_WW][2][68] = 68, -+ [1][0][RTW89_WW][0][70] = -4, -+ [1][0][RTW89_WW][1][70] = -4, -+ [1][0][RTW89_WW][2][70] = 68, -+ [1][0][RTW89_WW][0][72] = -4, -+ [1][0][RTW89_WW][1][72] = -4, -+ [1][0][RTW89_WW][2][72] = 68, -+ [1][0][RTW89_WW][0][74] = -4, -+ [1][0][RTW89_WW][1][74] = -4, -+ [1][0][RTW89_WW][2][74] = 68, -+ [1][0][RTW89_WW][0][75] = -4, -+ [1][0][RTW89_WW][1][75] = -4, -+ [1][0][RTW89_WW][2][75] = 68, -+ [1][0][RTW89_WW][0][77] = -4, -+ [1][0][RTW89_WW][1][77] = -4, -+ [1][0][RTW89_WW][2][77] = 68, -+ [1][0][RTW89_WW][0][79] = -4, -+ [1][0][RTW89_WW][1][79] = -4, -+ [1][0][RTW89_WW][2][79] = 68, -+ [1][0][RTW89_WW][0][81] = -4, -+ [1][0][RTW89_WW][1][81] = -4, -+ [1][0][RTW89_WW][2][81] = 68, -+ [1][0][RTW89_WW][0][83] = -4, -+ [1][0][RTW89_WW][1][83] = -4, -+ [1][0][RTW89_WW][2][83] = 68, -+ [1][0][RTW89_WW][0][85] = -4, -+ [1][0][RTW89_WW][1][85] = -4, -+ [1][0][RTW89_WW][2][85] = 68, -+ [1][0][RTW89_WW][0][87] = -4, -+ [1][0][RTW89_WW][1][87] = -4, -+ [1][0][RTW89_WW][2][87] = 0, -+ [1][0][RTW89_WW][0][89] = -4, -+ [1][0][RTW89_WW][1][89] = -4, -+ [1][0][RTW89_WW][2][89] = 0, -+ [1][0][RTW89_WW][0][90] = -4, -+ [1][0][RTW89_WW][1][90] = -4, -+ [1][0][RTW89_WW][2][90] = 0, -+ [1][0][RTW89_WW][0][92] = -4, -+ [1][0][RTW89_WW][1][92] = -4, -+ [1][0][RTW89_WW][2][92] = 0, -+ [1][0][RTW89_WW][0][94] = -4, -+ [1][0][RTW89_WW][1][94] = -4, -+ [1][0][RTW89_WW][2][94] = 0, -+ [1][0][RTW89_WW][0][96] = -4, -+ [1][0][RTW89_WW][1][96] = -4, -+ [1][0][RTW89_WW][2][96] = 0, -+ [1][0][RTW89_WW][0][98] = -4, -+ [1][0][RTW89_WW][1][98] = -4, -+ [1][0][RTW89_WW][2][98] = 0, -+ [1][0][RTW89_WW][0][100] = -4, -+ [1][0][RTW89_WW][1][100] = -4, -+ [1][0][RTW89_WW][2][100] = 0, -+ [1][0][RTW89_WW][0][102] = -4, -+ [1][0][RTW89_WW][1][102] = -4, -+ [1][0][RTW89_WW][2][102] = 0, -+ [1][0][RTW89_WW][0][104] = -4, -+ [1][0][RTW89_WW][1][104] = -4, -+ [1][0][RTW89_WW][2][104] = 0, -+ [1][0][RTW89_WW][0][105] = -4, -+ [1][0][RTW89_WW][1][105] = -4, -+ [1][0][RTW89_WW][2][105] = 0, -+ [1][0][RTW89_WW][0][107] = -2, -+ [1][0][RTW89_WW][1][107] = -2, -+ [1][0][RTW89_WW][2][107] = 0, -+ [1][0][RTW89_WW][0][109] = 2, -+ [1][0][RTW89_WW][1][109] = 2, -+ [1][0][RTW89_WW][2][109] = 0, -+ [1][0][RTW89_WW][0][111] = 0, -+ [1][0][RTW89_WW][1][111] = 0, -+ [1][0][RTW89_WW][2][111] = 0, -+ [1][0][RTW89_WW][0][113] = 0, -+ [1][0][RTW89_WW][1][113] = 0, -+ [1][0][RTW89_WW][2][113] = 0, -+ [1][0][RTW89_WW][0][115] = 0, -+ [1][0][RTW89_WW][1][115] = 0, -+ [1][0][RTW89_WW][2][115] = 0, -+ [1][0][RTW89_WW][0][117] = 0, -+ [1][0][RTW89_WW][1][117] = 0, -+ [1][0][RTW89_WW][2][117] = 0, -+ [1][0][RTW89_WW][0][119] = 0, -+ [1][0][RTW89_WW][1][119] = 0, -+ [1][0][RTW89_WW][2][119] = 0, -+ [1][1][RTW89_WW][0][0] = -26, -+ [1][1][RTW89_WW][1][0] = -26, -+ [1][1][RTW89_WW][2][0] = 44, -+ [1][1][RTW89_WW][0][2] = -28, -+ [1][1][RTW89_WW][1][2] = -28, -+ [1][1][RTW89_WW][2][2] = 44, -+ [1][1][RTW89_WW][0][4] = -28, -+ [1][1][RTW89_WW][1][4] = -28, -+ [1][1][RTW89_WW][2][4] = 44, -+ [1][1][RTW89_WW][0][6] = -28, -+ [1][1][RTW89_WW][1][6] = -28, -+ [1][1][RTW89_WW][2][6] = 44, -+ [1][1][RTW89_WW][0][8] = -28, -+ [1][1][RTW89_WW][1][8] = -28, -+ [1][1][RTW89_WW][2][8] = 44, -+ [1][1][RTW89_WW][0][10] = -28, -+ [1][1][RTW89_WW][1][10] = -28, -+ [1][1][RTW89_WW][2][10] = 44, -+ [1][1][RTW89_WW][0][12] = -28, -+ [1][1][RTW89_WW][1][12] = -28, -+ [1][1][RTW89_WW][2][12] = 44, -+ [1][1][RTW89_WW][0][14] = -28, -+ [1][1][RTW89_WW][1][14] = -28, -+ [1][1][RTW89_WW][2][14] = 44, -+ [1][1][RTW89_WW][0][15] = -28, -+ [1][1][RTW89_WW][1][15] = -28, -+ [1][1][RTW89_WW][2][15] = 44, -+ [1][1][RTW89_WW][0][17] = -28, -+ [1][1][RTW89_WW][1][17] = -28, -+ [1][1][RTW89_WW][2][17] = 44, -+ [1][1][RTW89_WW][0][19] = -28, -+ [1][1][RTW89_WW][1][19] = -28, -+ [1][1][RTW89_WW][2][19] = 44, -+ [1][1][RTW89_WW][0][21] = -28, -+ [1][1][RTW89_WW][1][21] = -28, -+ [1][1][RTW89_WW][2][21] = 44, -+ [1][1][RTW89_WW][0][23] = -28, -+ [1][1][RTW89_WW][1][23] = -28, -+ [1][1][RTW89_WW][2][23] = 44, -+ [1][1][RTW89_WW][0][25] = -28, -+ [1][1][RTW89_WW][1][25] = -28, -+ [1][1][RTW89_WW][2][25] = 44, -+ [1][1][RTW89_WW][0][27] = -28, -+ [1][1][RTW89_WW][1][27] = -28, -+ [1][1][RTW89_WW][2][27] = 44, -+ [1][1][RTW89_WW][0][29] = -28, -+ [1][1][RTW89_WW][1][29] = -28, -+ [1][1][RTW89_WW][2][29] = 44, -+ [1][1][RTW89_WW][0][30] = -28, -+ [1][1][RTW89_WW][1][30] = -28, -+ [1][1][RTW89_WW][2][30] = 44, -+ [1][1][RTW89_WW][0][32] = -28, -+ [1][1][RTW89_WW][1][32] = -28, -+ [1][1][RTW89_WW][2][32] = 44, -+ [1][1][RTW89_WW][0][34] = -28, -+ [1][1][RTW89_WW][1][34] = -28, -+ [1][1][RTW89_WW][2][34] = 44, -+ [1][1][RTW89_WW][0][36] = -28, -+ [1][1][RTW89_WW][1][36] = -28, -+ [1][1][RTW89_WW][2][36] = 44, -+ [1][1][RTW89_WW][0][38] = -28, -+ [1][1][RTW89_WW][1][38] = -28, -+ [1][1][RTW89_WW][2][38] = 44, -+ [1][1][RTW89_WW][0][40] = -28, -+ [1][1][RTW89_WW][1][40] = -28, -+ [1][1][RTW89_WW][2][40] = 44, -+ [1][1][RTW89_WW][0][42] = -28, -+ [1][1][RTW89_WW][1][42] = -28, -+ [1][1][RTW89_WW][2][42] = 44, -+ [1][1][RTW89_WW][0][44] = -28, -+ [1][1][RTW89_WW][1][44] = -28, -+ [1][1][RTW89_WW][2][44] = 44, -+ [1][1][RTW89_WW][0][45] = -26, -+ [1][1][RTW89_WW][1][45] = -26, -+ [1][1][RTW89_WW][2][45] = 0, -+ [1][1][RTW89_WW][0][47] = -28, -+ [1][1][RTW89_WW][1][47] = -28, -+ [1][1][RTW89_WW][2][47] = 0, -+ [1][1][RTW89_WW][0][49] = -28, -+ [1][1][RTW89_WW][1][49] = -28, -+ [1][1][RTW89_WW][2][49] = 0, -+ [1][1][RTW89_WW][0][51] = -28, -+ [1][1][RTW89_WW][1][51] = -28, -+ [1][1][RTW89_WW][2][51] = 0, -+ [1][1][RTW89_WW][0][53] = -26, -+ [1][1][RTW89_WW][1][53] = -26, -+ [1][1][RTW89_WW][2][53] = 0, -+ [1][1][RTW89_WW][0][55] = -28, -+ [1][1][RTW89_WW][1][55] = -28, -+ [1][1][RTW89_WW][2][55] = 44, -+ [1][1][RTW89_WW][0][57] = -28, -+ [1][1][RTW89_WW][1][57] = -28, -+ [1][1][RTW89_WW][2][57] = 44, -+ [1][1][RTW89_WW][0][59] = -28, -+ [1][1][RTW89_WW][1][59] = -28, -+ [1][1][RTW89_WW][2][59] = 44, -+ [1][1][RTW89_WW][0][60] = -28, -+ [1][1][RTW89_WW][1][60] = -28, -+ [1][1][RTW89_WW][2][60] = 44, -+ [1][1][RTW89_WW][0][62] = -28, -+ [1][1][RTW89_WW][1][62] = -28, -+ [1][1][RTW89_WW][2][62] = 44, -+ [1][1][RTW89_WW][0][64] = -28, -+ [1][1][RTW89_WW][1][64] = -28, -+ [1][1][RTW89_WW][2][64] = 44, -+ [1][1][RTW89_WW][0][66] = -28, -+ [1][1][RTW89_WW][1][66] = -28, -+ [1][1][RTW89_WW][2][66] = 44, -+ [1][1][RTW89_WW][0][68] = -28, -+ [1][1][RTW89_WW][1][68] = -28, -+ [1][1][RTW89_WW][2][68] = 44, -+ [1][1][RTW89_WW][0][70] = -26, -+ [1][1][RTW89_WW][1][70] = -26, -+ [1][1][RTW89_WW][2][70] = 44, -+ [1][1][RTW89_WW][0][72] = -28, -+ [1][1][RTW89_WW][1][72] = -28, -+ [1][1][RTW89_WW][2][72] = 44, -+ [1][1][RTW89_WW][0][74] = -28, -+ [1][1][RTW89_WW][1][74] = -28, -+ [1][1][RTW89_WW][2][74] = 44, -+ [1][1][RTW89_WW][0][75] = -28, -+ [1][1][RTW89_WW][1][75] = -28, -+ [1][1][RTW89_WW][2][75] = 44, -+ [1][1][RTW89_WW][0][77] = -28, -+ [1][1][RTW89_WW][1][77] = -28, -+ [1][1][RTW89_WW][2][77] = 44, -+ [1][1][RTW89_WW][0][79] = -28, -+ [1][1][RTW89_WW][1][79] = -28, -+ [1][1][RTW89_WW][2][79] = 44, -+ [1][1][RTW89_WW][0][81] = -28, -+ [1][1][RTW89_WW][1][81] = -28, -+ [1][1][RTW89_WW][2][81] = 44, -+ [1][1][RTW89_WW][0][83] = -28, -+ [1][1][RTW89_WW][1][83] = -28, -+ [1][1][RTW89_WW][2][83] = 44, -+ [1][1][RTW89_WW][0][85] = -28, -+ [1][1][RTW89_WW][1][85] = -28, -+ [1][1][RTW89_WW][2][85] = 44, -+ [1][1][RTW89_WW][0][87] = -28, -+ [1][1][RTW89_WW][1][87] = -28, -+ [1][1][RTW89_WW][2][87] = 0, -+ [1][1][RTW89_WW][0][89] = -26, -+ [1][1][RTW89_WW][1][89] = -26, -+ [1][1][RTW89_WW][2][89] = 0, -+ [1][1][RTW89_WW][0][90] = -26, -+ [1][1][RTW89_WW][1][90] = -26, -+ [1][1][RTW89_WW][2][90] = 0, -+ [1][1][RTW89_WW][0][92] = -26, -+ [1][1][RTW89_WW][1][92] = -26, -+ [1][1][RTW89_WW][2][92] = 0, -+ [1][1][RTW89_WW][0][94] = -26, -+ [1][1][RTW89_WW][1][94] = -26, -+ [1][1][RTW89_WW][2][94] = 0, -+ [1][1][RTW89_WW][0][96] = -26, -+ [1][1][RTW89_WW][1][96] = -26, -+ [1][1][RTW89_WW][2][96] = 0, -+ [1][1][RTW89_WW][0][98] = -26, -+ [1][1][RTW89_WW][1][98] = -26, -+ [1][1][RTW89_WW][2][98] = 0, -+ [1][1][RTW89_WW][0][100] = -26, -+ [1][1][RTW89_WW][1][100] = -26, -+ [1][1][RTW89_WW][2][100] = 0, -+ [1][1][RTW89_WW][0][102] = -26, -+ [1][1][RTW89_WW][1][102] = -26, -+ [1][1][RTW89_WW][2][102] = 0, -+ [1][1][RTW89_WW][0][104] = -26, -+ [1][1][RTW89_WW][1][104] = -26, -+ [1][1][RTW89_WW][2][104] = 0, -+ [1][1][RTW89_WW][0][105] = -26, -+ [1][1][RTW89_WW][1][105] = -26, -+ [1][1][RTW89_WW][2][105] = 0, -+ [1][1][RTW89_WW][0][107] = -22, -+ [1][1][RTW89_WW][1][107] = -22, -+ [1][1][RTW89_WW][2][107] = 0, -+ [1][1][RTW89_WW][0][109] = -22, -+ [1][1][RTW89_WW][1][109] = -22, -+ [1][1][RTW89_WW][2][109] = 0, -+ [1][1][RTW89_WW][0][111] = 0, -+ [1][1][RTW89_WW][1][111] = 0, -+ [1][1][RTW89_WW][2][111] = 0, -+ [1][1][RTW89_WW][0][113] = 0, -+ [1][1][RTW89_WW][1][113] = 0, -+ [1][1][RTW89_WW][2][113] = 0, -+ [1][1][RTW89_WW][0][115] = 0, -+ [1][1][RTW89_WW][1][115] = 0, -+ [1][1][RTW89_WW][2][115] = 0, -+ [1][1][RTW89_WW][0][117] = 0, -+ [1][1][RTW89_WW][1][117] = 0, -+ [1][1][RTW89_WW][2][117] = 0, -+ [1][1][RTW89_WW][0][119] = 0, -+ [1][1][RTW89_WW][1][119] = 0, -+ [1][1][RTW89_WW][2][119] = 0, -+ [2][0][RTW89_WW][0][0] = -2, -+ [2][0][RTW89_WW][1][0] = -2, -+ [2][0][RTW89_WW][2][0] = 60, -+ [2][0][RTW89_WW][0][2] = -2, -+ [2][0][RTW89_WW][1][2] = -2, -+ [2][0][RTW89_WW][2][2] = 60, -+ [2][0][RTW89_WW][0][4] = -2, -+ [2][0][RTW89_WW][1][4] = -2, -+ [2][0][RTW89_WW][2][4] = 60, -+ [2][0][RTW89_WW][0][6] = -2, -+ [2][0][RTW89_WW][1][6] = -2, -+ [2][0][RTW89_WW][2][6] = 60, -+ [2][0][RTW89_WW][0][8] = -2, -+ [2][0][RTW89_WW][1][8] = -2, -+ [2][0][RTW89_WW][2][8] = 60, -+ [2][0][RTW89_WW][0][10] = -2, -+ [2][0][RTW89_WW][1][10] = -2, -+ [2][0][RTW89_WW][2][10] = 60, -+ [2][0][RTW89_WW][0][12] = -2, -+ [2][0][RTW89_WW][1][12] = -2, -+ [2][0][RTW89_WW][2][12] = 60, -+ [2][0][RTW89_WW][0][14] = -2, -+ [2][0][RTW89_WW][1][14] = -2, -+ [2][0][RTW89_WW][2][14] = 60, -+ [2][0][RTW89_WW][0][15] = -2, -+ [2][0][RTW89_WW][1][15] = -2, -+ [2][0][RTW89_WW][2][15] = 60, -+ [2][0][RTW89_WW][0][17] = -2, -+ [2][0][RTW89_WW][1][17] = -2, -+ [2][0][RTW89_WW][2][17] = 60, -+ [2][0][RTW89_WW][0][19] = -2, -+ [2][0][RTW89_WW][1][19] = -2, -+ [2][0][RTW89_WW][2][19] = 60, -+ [2][0][RTW89_WW][0][21] = -2, -+ [2][0][RTW89_WW][1][21] = -2, -+ [2][0][RTW89_WW][2][21] = 60, -+ [2][0][RTW89_WW][0][23] = -2, -+ [2][0][RTW89_WW][1][23] = -2, -+ [2][0][RTW89_WW][2][23] = 78, -+ [2][0][RTW89_WW][0][25] = -2, -+ [2][0][RTW89_WW][1][25] = -2, -+ [2][0][RTW89_WW][2][25] = 78, -+ [2][0][RTW89_WW][0][27] = -2, -+ [2][0][RTW89_WW][1][27] = -2, -+ [2][0][RTW89_WW][2][27] = 78, -+ [2][0][RTW89_WW][0][29] = -2, -+ [2][0][RTW89_WW][1][29] = -2, -+ [2][0][RTW89_WW][2][29] = 78, -+ [2][0][RTW89_WW][0][30] = -2, -+ [2][0][RTW89_WW][1][30] = -2, -+ [2][0][RTW89_WW][2][30] = 78, -+ [2][0][RTW89_WW][0][32] = -2, -+ [2][0][RTW89_WW][1][32] = -2, -+ [2][0][RTW89_WW][2][32] = 78, -+ [2][0][RTW89_WW][0][34] = -2, -+ [2][0][RTW89_WW][1][34] = -2, -+ [2][0][RTW89_WW][2][34] = 78, -+ [2][0][RTW89_WW][0][36] = -2, -+ [2][0][RTW89_WW][1][36] = -2, -+ [2][0][RTW89_WW][2][36] = 78, -+ [2][0][RTW89_WW][0][38] = -2, -+ [2][0][RTW89_WW][1][38] = -2, -+ [2][0][RTW89_WW][2][38] = 78, -+ [2][0][RTW89_WW][0][40] = -2, -+ [2][0][RTW89_WW][1][40] = -2, -+ [2][0][RTW89_WW][2][40] = 78, -+ [2][0][RTW89_WW][0][42] = -2, -+ [2][0][RTW89_WW][1][42] = -2, -+ [2][0][RTW89_WW][2][42] = 78, -+ [2][0][RTW89_WW][0][44] = -2, -+ [2][0][RTW89_WW][1][44] = -2, -+ [2][0][RTW89_WW][2][44] = 78, -+ [2][0][RTW89_WW][0][45] = -2, -+ [2][0][RTW89_WW][1][45] = -2, -+ [2][0][RTW89_WW][2][45] = 0, -+ [2][0][RTW89_WW][0][47] = -2, -+ [2][0][RTW89_WW][1][47] = -2, -+ [2][0][RTW89_WW][2][47] = 0, -+ [2][0][RTW89_WW][0][49] = -2, -+ [2][0][RTW89_WW][1][49] = -2, -+ [2][0][RTW89_WW][2][49] = 0, -+ [2][0][RTW89_WW][0][51] = -2, -+ [2][0][RTW89_WW][1][51] = -2, -+ [2][0][RTW89_WW][2][51] = 0, -+ [2][0][RTW89_WW][0][53] = -2, -+ [2][0][RTW89_WW][1][53] = -2, -+ [2][0][RTW89_WW][2][53] = 0, -+ [2][0][RTW89_WW][0][55] = -2, -+ [2][0][RTW89_WW][1][55] = -2, -+ [2][0][RTW89_WW][2][55] = 78, -+ [2][0][RTW89_WW][0][57] = -2, -+ [2][0][RTW89_WW][1][57] = -2, -+ [2][0][RTW89_WW][2][57] = 78, -+ [2][0][RTW89_WW][0][59] = -2, -+ [2][0][RTW89_WW][1][59] = -2, -+ [2][0][RTW89_WW][2][59] = 78, -+ [2][0][RTW89_WW][0][60] = -2, -+ [2][0][RTW89_WW][1][60] = -2, -+ [2][0][RTW89_WW][2][60] = 78, -+ [2][0][RTW89_WW][0][62] = -2, -+ [2][0][RTW89_WW][1][62] = -2, -+ [2][0][RTW89_WW][2][62] = 78, -+ [2][0][RTW89_WW][0][64] = -2, -+ [2][0][RTW89_WW][1][64] = -2, -+ [2][0][RTW89_WW][2][64] = 78, -+ [2][0][RTW89_WW][0][66] = -2, -+ [2][0][RTW89_WW][1][66] = -2, -+ [2][0][RTW89_WW][2][66] = 78, -+ [2][0][RTW89_WW][0][68] = -2, -+ [2][0][RTW89_WW][1][68] = -2, -+ [2][0][RTW89_WW][2][68] = 78, -+ [2][0][RTW89_WW][0][70] = -2, -+ [2][0][RTW89_WW][1][70] = -2, -+ [2][0][RTW89_WW][2][70] = 78, -+ [2][0][RTW89_WW][0][72] = -2, -+ [2][0][RTW89_WW][1][72] = -2, -+ [2][0][RTW89_WW][2][72] = 78, -+ [2][0][RTW89_WW][0][74] = -2, -+ [2][0][RTW89_WW][1][74] = -2, -+ [2][0][RTW89_WW][2][74] = 78, -+ [2][0][RTW89_WW][0][75] = -2, -+ [2][0][RTW89_WW][1][75] = -2, -+ [2][0][RTW89_WW][2][75] = 78, -+ [2][0][RTW89_WW][0][77] = -2, -+ [2][0][RTW89_WW][1][77] = -2, -+ [2][0][RTW89_WW][2][77] = 78, -+ [2][0][RTW89_WW][0][79] = -2, -+ [2][0][RTW89_WW][1][79] = -2, -+ [2][0][RTW89_WW][2][79] = 78, -+ [2][0][RTW89_WW][0][81] = -2, -+ [2][0][RTW89_WW][1][81] = -2, -+ [2][0][RTW89_WW][2][81] = 78, -+ [2][0][RTW89_WW][0][83] = -2, -+ [2][0][RTW89_WW][1][83] = -2, -+ [2][0][RTW89_WW][2][83] = 78, -+ [2][0][RTW89_WW][0][85] = -2, -+ [2][0][RTW89_WW][1][85] = -2, -+ [2][0][RTW89_WW][2][85] = 78, -+ [2][0][RTW89_WW][0][87] = -2, -+ [2][0][RTW89_WW][1][87] = -2, -+ [2][0][RTW89_WW][2][87] = 0, -+ [2][0][RTW89_WW][0][89] = -2, -+ [2][0][RTW89_WW][1][89] = -2, -+ [2][0][RTW89_WW][2][89] = 0, -+ [2][0][RTW89_WW][0][90] = -2, -+ [2][0][RTW89_WW][1][90] = -2, -+ [2][0][RTW89_WW][2][90] = 0, -+ [2][0][RTW89_WW][0][92] = -2, -+ [2][0][RTW89_WW][1][92] = -2, -+ [2][0][RTW89_WW][2][92] = 0, -+ [2][0][RTW89_WW][0][94] = -2, -+ [2][0][RTW89_WW][1][94] = -2, -+ [2][0][RTW89_WW][2][94] = 0, -+ [2][0][RTW89_WW][0][96] = -2, -+ [2][0][RTW89_WW][1][96] = -2, -+ [2][0][RTW89_WW][2][96] = 0, -+ [2][0][RTW89_WW][0][98] = -2, -+ [2][0][RTW89_WW][1][98] = -2, -+ [2][0][RTW89_WW][2][98] = 0, -+ [2][0][RTW89_WW][0][100] = -2, -+ [2][0][RTW89_WW][1][100] = -2, -+ [2][0][RTW89_WW][2][100] = 0, -+ [2][0][RTW89_WW][0][102] = -2, -+ [2][0][RTW89_WW][1][102] = -2, -+ [2][0][RTW89_WW][2][102] = 0, -+ [2][0][RTW89_WW][0][104] = -2, -+ [2][0][RTW89_WW][1][104] = -2, -+ [2][0][RTW89_WW][2][104] = 0, -+ [2][0][RTW89_WW][0][105] = -2, -+ [2][0][RTW89_WW][1][105] = -2, -+ [2][0][RTW89_WW][2][105] = 0, -+ [2][0][RTW89_WW][0][107] = -2, -+ [2][0][RTW89_WW][1][107] = -2, -+ [2][0][RTW89_WW][2][107] = 0, -+ [2][0][RTW89_WW][0][109] = 12, -+ [2][0][RTW89_WW][1][109] = 12, -+ [2][0][RTW89_WW][2][109] = 0, -+ [2][0][RTW89_WW][0][111] = 0, -+ [2][0][RTW89_WW][1][111] = 0, -+ [2][0][RTW89_WW][2][111] = 0, -+ [2][0][RTW89_WW][0][113] = 0, -+ [2][0][RTW89_WW][1][113] = 0, -+ [2][0][RTW89_WW][2][113] = 0, -+ [2][0][RTW89_WW][0][115] = 0, -+ [2][0][RTW89_WW][1][115] = 0, -+ [2][0][RTW89_WW][2][115] = 0, -+ [2][0][RTW89_WW][0][117] = 0, -+ [2][0][RTW89_WW][1][117] = 0, -+ [2][0][RTW89_WW][2][117] = 0, -+ [2][0][RTW89_WW][0][119] = 0, -+ [2][0][RTW89_WW][1][119] = 0, -+ [2][0][RTW89_WW][2][119] = 0, -+ [2][1][RTW89_WW][0][0] = -16, -+ [2][1][RTW89_WW][1][0] = -16, -+ [2][1][RTW89_WW][2][0] = 54, -+ [2][1][RTW89_WW][0][2] = -16, -+ [2][1][RTW89_WW][1][2] = -16, -+ [2][1][RTW89_WW][2][2] = 54, -+ [2][1][RTW89_WW][0][4] = -16, -+ [2][1][RTW89_WW][1][4] = -16, -+ [2][1][RTW89_WW][2][4] = 54, -+ [2][1][RTW89_WW][0][6] = -16, -+ [2][1][RTW89_WW][1][6] = -16, -+ [2][1][RTW89_WW][2][6] = 54, -+ [2][1][RTW89_WW][0][8] = -16, -+ [2][1][RTW89_WW][1][8] = -16, -+ [2][1][RTW89_WW][2][8] = 54, -+ [2][1][RTW89_WW][0][10] = -16, -+ [2][1][RTW89_WW][1][10] = -16, -+ [2][1][RTW89_WW][2][10] = 54, -+ [2][1][RTW89_WW][0][12] = -16, -+ [2][1][RTW89_WW][1][12] = -16, -+ [2][1][RTW89_WW][2][12] = 54, -+ [2][1][RTW89_WW][0][14] = -16, -+ [2][1][RTW89_WW][1][14] = -16, -+ [2][1][RTW89_WW][2][14] = 54, -+ [2][1][RTW89_WW][0][15] = -16, -+ [2][1][RTW89_WW][1][15] = -16, -+ [2][1][RTW89_WW][2][15] = 54, -+ [2][1][RTW89_WW][0][17] = -16, -+ [2][1][RTW89_WW][1][17] = -16, -+ [2][1][RTW89_WW][2][17] = 54, -+ [2][1][RTW89_WW][0][19] = -16, -+ [2][1][RTW89_WW][1][19] = -16, -+ [2][1][RTW89_WW][2][19] = 54, -+ [2][1][RTW89_WW][0][21] = -16, -+ [2][1][RTW89_WW][1][21] = -16, -+ [2][1][RTW89_WW][2][21] = 54, -+ [2][1][RTW89_WW][0][23] = -16, -+ [2][1][RTW89_WW][1][23] = -16, -+ [2][1][RTW89_WW][2][23] = 54, -+ [2][1][RTW89_WW][0][25] = -16, -+ [2][1][RTW89_WW][1][25] = -16, -+ [2][1][RTW89_WW][2][25] = 54, -+ [2][1][RTW89_WW][0][27] = -16, -+ [2][1][RTW89_WW][1][27] = -16, -+ [2][1][RTW89_WW][2][27] = 54, -+ [2][1][RTW89_WW][0][29] = -16, -+ [2][1][RTW89_WW][1][29] = -16, -+ [2][1][RTW89_WW][2][29] = 54, -+ [2][1][RTW89_WW][0][30] = -16, -+ [2][1][RTW89_WW][1][30] = -16, -+ [2][1][RTW89_WW][2][30] = 54, -+ [2][1][RTW89_WW][0][32] = -16, -+ [2][1][RTW89_WW][1][32] = -16, -+ [2][1][RTW89_WW][2][32] = 54, -+ [2][1][RTW89_WW][0][34] = -16, -+ [2][1][RTW89_WW][1][34] = -16, -+ [2][1][RTW89_WW][2][34] = 54, -+ [2][1][RTW89_WW][0][36] = -16, -+ [2][1][RTW89_WW][1][36] = -16, -+ [2][1][RTW89_WW][2][36] = 54, -+ [2][1][RTW89_WW][0][38] = -16, -+ [2][1][RTW89_WW][1][38] = -16, -+ [2][1][RTW89_WW][2][38] = 54, -+ [2][1][RTW89_WW][0][40] = -16, -+ [2][1][RTW89_WW][1][40] = -16, -+ [2][1][RTW89_WW][2][40] = 54, -+ [2][1][RTW89_WW][0][42] = -16, -+ [2][1][RTW89_WW][1][42] = -16, -+ [2][1][RTW89_WW][2][42] = 54, -+ [2][1][RTW89_WW][0][44] = -16, -+ [2][1][RTW89_WW][1][44] = -16, -+ [2][1][RTW89_WW][2][44] = 54, -+ [2][1][RTW89_WW][0][45] = -16, -+ [2][1][RTW89_WW][1][45] = -16, -+ [2][1][RTW89_WW][2][45] = 0, -+ [2][1][RTW89_WW][0][47] = -16, -+ [2][1][RTW89_WW][1][47] = -16, -+ [2][1][RTW89_WW][2][47] = 0, -+ [2][1][RTW89_WW][0][49] = -16, -+ [2][1][RTW89_WW][1][49] = -16, -+ [2][1][RTW89_WW][2][49] = 0, -+ [2][1][RTW89_WW][0][51] = -16, -+ [2][1][RTW89_WW][1][51] = -16, -+ [2][1][RTW89_WW][2][51] = 0, -+ [2][1][RTW89_WW][0][53] = -16, -+ [2][1][RTW89_WW][1][53] = -16, -+ [2][1][RTW89_WW][2][53] = 0, -+ [2][1][RTW89_WW][0][55] = -16, -+ [2][1][RTW89_WW][1][55] = -16, -+ [2][1][RTW89_WW][2][55] = 54, -+ [2][1][RTW89_WW][0][57] = -16, -+ [2][1][RTW89_WW][1][57] = -16, -+ [2][1][RTW89_WW][2][57] = 54, -+ [2][1][RTW89_WW][0][59] = -16, -+ [2][1][RTW89_WW][1][59] = -16, -+ [2][1][RTW89_WW][2][59] = 54, -+ [2][1][RTW89_WW][0][60] = -16, -+ [2][1][RTW89_WW][1][60] = -16, -+ [2][1][RTW89_WW][2][60] = 54, -+ [2][1][RTW89_WW][0][62] = -16, -+ [2][1][RTW89_WW][1][62] = -16, -+ [2][1][RTW89_WW][2][62] = 54, -+ [2][1][RTW89_WW][0][64] = -16, -+ [2][1][RTW89_WW][1][64] = -16, -+ [2][1][RTW89_WW][2][64] = 54, -+ [2][1][RTW89_WW][0][66] = -16, -+ [2][1][RTW89_WW][1][66] = -16, -+ [2][1][RTW89_WW][2][66] = 54, -+ [2][1][RTW89_WW][0][68] = -16, -+ [2][1][RTW89_WW][1][68] = -16, -+ [2][1][RTW89_WW][2][68] = 54, -+ [2][1][RTW89_WW][0][70] = -16, -+ [2][1][RTW89_WW][1][70] = -16, -+ [2][1][RTW89_WW][2][70] = 56, -+ [2][1][RTW89_WW][0][72] = -16, -+ [2][1][RTW89_WW][1][72] = -16, -+ [2][1][RTW89_WW][2][72] = 56, -+ [2][1][RTW89_WW][0][74] = -16, -+ [2][1][RTW89_WW][1][74] = -16, -+ [2][1][RTW89_WW][2][74] = 56, -+ [2][1][RTW89_WW][0][75] = -16, -+ [2][1][RTW89_WW][1][75] = -16, -+ [2][1][RTW89_WW][2][75] = 56, -+ [2][1][RTW89_WW][0][77] = -16, -+ [2][1][RTW89_WW][1][77] = -16, -+ [2][1][RTW89_WW][2][77] = 56, -+ [2][1][RTW89_WW][0][79] = -16, -+ [2][1][RTW89_WW][1][79] = -16, -+ [2][1][RTW89_WW][2][79] = 56, -+ [2][1][RTW89_WW][0][81] = -16, -+ [2][1][RTW89_WW][1][81] = -16, -+ [2][1][RTW89_WW][2][81] = 56, -+ [2][1][RTW89_WW][0][83] = -16, -+ [2][1][RTW89_WW][1][83] = -16, -+ [2][1][RTW89_WW][2][83] = 56, -+ [2][1][RTW89_WW][0][85] = -18, -+ [2][1][RTW89_WW][1][85] = -18, -+ [2][1][RTW89_WW][2][85] = 56, -+ [2][1][RTW89_WW][0][87] = -16, -+ [2][1][RTW89_WW][1][87] = -16, -+ [2][1][RTW89_WW][2][87] = 0, -+ [2][1][RTW89_WW][0][89] = -16, -+ [2][1][RTW89_WW][1][89] = -16, -+ [2][1][RTW89_WW][2][89] = 0, -+ [2][1][RTW89_WW][0][90] = -16, -+ [2][1][RTW89_WW][1][90] = -16, -+ [2][1][RTW89_WW][2][90] = 0, -+ [2][1][RTW89_WW][0][92] = -16, -+ [2][1][RTW89_WW][1][92] = -16, -+ [2][1][RTW89_WW][2][92] = 0, -+ [2][1][RTW89_WW][0][94] = -16, -+ [2][1][RTW89_WW][1][94] = -16, -+ [2][1][RTW89_WW][2][94] = 0, -+ [2][1][RTW89_WW][0][96] = -16, -+ [2][1][RTW89_WW][1][96] = -16, -+ [2][1][RTW89_WW][2][96] = 0, -+ [2][1][RTW89_WW][0][98] = -16, -+ [2][1][RTW89_WW][1][98] = -16, -+ [2][1][RTW89_WW][2][98] = 0, -+ [2][1][RTW89_WW][0][100] = -16, -+ [2][1][RTW89_WW][1][100] = -16, -+ [2][1][RTW89_WW][2][100] = 0, -+ [2][1][RTW89_WW][0][102] = -16, -+ [2][1][RTW89_WW][1][102] = -16, -+ [2][1][RTW89_WW][2][102] = 0, -+ [2][1][RTW89_WW][0][104] = -16, -+ [2][1][RTW89_WW][1][104] = -16, -+ [2][1][RTW89_WW][2][104] = 0, -+ [2][1][RTW89_WW][0][105] = -16, -+ [2][1][RTW89_WW][1][105] = -16, -+ [2][1][RTW89_WW][2][105] = 0, -+ [2][1][RTW89_WW][0][107] = -14, -+ [2][1][RTW89_WW][1][107] = -14, -+ [2][1][RTW89_WW][2][107] = 0, -+ [2][1][RTW89_WW][0][109] = -10, -+ [2][1][RTW89_WW][1][109] = -10, -+ [2][1][RTW89_WW][2][109] = 0, -+ [2][1][RTW89_WW][0][111] = 0, -+ [2][1][RTW89_WW][1][111] = 0, -+ [2][1][RTW89_WW][2][111] = 0, -+ [2][1][RTW89_WW][0][113] = 0, -+ [2][1][RTW89_WW][1][113] = 0, -+ [2][1][RTW89_WW][2][113] = 0, -+ [2][1][RTW89_WW][0][115] = 0, -+ [2][1][RTW89_WW][1][115] = 0, -+ [2][1][RTW89_WW][2][115] = 0, -+ [2][1][RTW89_WW][0][117] = 0, -+ [2][1][RTW89_WW][1][117] = 0, -+ [2][1][RTW89_WW][2][117] = 0, -+ [2][1][RTW89_WW][0][119] = 0, -+ [2][1][RTW89_WW][1][119] = 0, -+ [2][1][RTW89_WW][2][119] = 0, -+ [0][0][RTW89_FCC][1][0] = -16, -+ [0][0][RTW89_FCC][2][0] = 44, -+ [0][0][RTW89_ETSI][1][0] = 32, -+ [0][0][RTW89_ETSI][0][0] = -8, -+ [0][0][RTW89_MKK][1][0] = 30, -+ [0][0][RTW89_MKK][0][0] = -8, -+ [0][0][RTW89_IC][1][0] = -16, -+ [0][0][RTW89_KCC][1][0] = -2, -+ [0][0][RTW89_KCC][0][0] = -2, -+ [0][0][RTW89_ACMA][1][0] = 32, -+ [0][0][RTW89_ACMA][0][0] = -8, -+ [0][0][RTW89_CHILE][1][0] = -16, -+ [0][0][RTW89_QATAR][1][0] = 32, -+ [0][0][RTW89_QATAR][0][0] = -8, -+ [0][0][RTW89_UK][1][0] = 32, -+ [0][0][RTW89_UK][0][0] = -8, -+ [0][0][RTW89_FCC][1][2] = -18, -+ [0][0][RTW89_FCC][2][2] = 44, -+ [0][0][RTW89_ETSI][1][2] = 32, -+ [0][0][RTW89_ETSI][0][2] = -8, -+ [0][0][RTW89_MKK][1][2] = 30, -+ [0][0][RTW89_MKK][0][2] = -8, -+ [0][0][RTW89_IC][1][2] = -18, -+ [0][0][RTW89_KCC][1][2] = -2, -+ [0][0][RTW89_KCC][0][2] = -2, -+ [0][0][RTW89_ACMA][1][2] = 32, -+ [0][0][RTW89_ACMA][0][2] = -8, -+ [0][0][RTW89_CHILE][1][2] = -18, -+ [0][0][RTW89_QATAR][1][2] = 32, -+ [0][0][RTW89_QATAR][0][2] = -8, -+ [0][0][RTW89_UK][1][2] = 32, -+ [0][0][RTW89_UK][0][2] = -8, -+ [0][0][RTW89_FCC][1][4] = -18, -+ [0][0][RTW89_FCC][2][4] = 44, -+ [0][0][RTW89_ETSI][1][4] = 32, -+ [0][0][RTW89_ETSI][0][4] = -8, -+ [0][0][RTW89_MKK][1][4] = 30, -+ [0][0][RTW89_MKK][0][4] = -8, -+ [0][0][RTW89_IC][1][4] = -18, -+ [0][0][RTW89_KCC][1][4] = -2, -+ [0][0][RTW89_KCC][0][4] = -2, -+ [0][0][RTW89_ACMA][1][4] = 32, -+ [0][0][RTW89_ACMA][0][4] = -8, -+ [0][0][RTW89_CHILE][1][4] = -18, -+ [0][0][RTW89_QATAR][1][4] = 32, -+ [0][0][RTW89_QATAR][0][4] = -8, -+ [0][0][RTW89_UK][1][4] = 32, -+ [0][0][RTW89_UK][0][4] = -8, -+ [0][0][RTW89_FCC][1][6] = -18, -+ [0][0][RTW89_FCC][2][6] = 44, -+ [0][0][RTW89_ETSI][1][6] = 32, -+ [0][0][RTW89_ETSI][0][6] = -8, -+ [0][0][RTW89_MKK][1][6] = 30, -+ [0][0][RTW89_MKK][0][6] = -8, -+ [0][0][RTW89_IC][1][6] = -18, -+ [0][0][RTW89_KCC][1][6] = -2, -+ [0][0][RTW89_KCC][0][6] = -2, -+ [0][0][RTW89_ACMA][1][6] = 32, -+ [0][0][RTW89_ACMA][0][6] = -8, -+ [0][0][RTW89_CHILE][1][6] = -18, -+ [0][0][RTW89_QATAR][1][6] = 32, -+ [0][0][RTW89_QATAR][0][6] = -8, -+ [0][0][RTW89_UK][1][6] = 32, -+ [0][0][RTW89_UK][0][6] = -8, -+ [0][0][RTW89_FCC][1][8] = -18, -+ [0][0][RTW89_FCC][2][8] = 44, -+ [0][0][RTW89_ETSI][1][8] = 32, -+ [0][0][RTW89_ETSI][0][8] = -8, -+ [0][0][RTW89_MKK][1][8] = 30, -+ [0][0][RTW89_MKK][0][8] = -8, -+ [0][0][RTW89_IC][1][8] = -18, -+ [0][0][RTW89_KCC][1][8] = -2, -+ [0][0][RTW89_KCC][0][8] = -2, -+ [0][0][RTW89_ACMA][1][8] = 32, -+ [0][0][RTW89_ACMA][0][8] = -8, -+ [0][0][RTW89_CHILE][1][8] = -18, -+ [0][0][RTW89_QATAR][1][8] = 32, -+ [0][0][RTW89_QATAR][0][8] = -8, -+ [0][0][RTW89_UK][1][8] = 32, -+ [0][0][RTW89_UK][0][8] = -8, -+ [0][0][RTW89_FCC][1][10] = -18, -+ [0][0][RTW89_FCC][2][10] = 44, -+ [0][0][RTW89_ETSI][1][10] = 32, -+ [0][0][RTW89_ETSI][0][10] = -8, -+ [0][0][RTW89_MKK][1][10] = 30, -+ [0][0][RTW89_MKK][0][10] = -8, -+ [0][0][RTW89_IC][1][10] = -18, -+ [0][0][RTW89_KCC][1][10] = -2, -+ [0][0][RTW89_KCC][0][10] = -2, -+ [0][0][RTW89_ACMA][1][10] = 32, -+ [0][0][RTW89_ACMA][0][10] = -8, -+ [0][0][RTW89_CHILE][1][10] = -18, -+ [0][0][RTW89_QATAR][1][10] = 32, -+ [0][0][RTW89_QATAR][0][10] = -8, -+ [0][0][RTW89_UK][1][10] = 32, -+ [0][0][RTW89_UK][0][10] = -8, -+ [0][0][RTW89_FCC][1][12] = -18, -+ [0][0][RTW89_FCC][2][12] = 44, -+ [0][0][RTW89_ETSI][1][12] = 32, -+ [0][0][RTW89_ETSI][0][12] = -8, -+ [0][0][RTW89_MKK][1][12] = 30, -+ [0][0][RTW89_MKK][0][12] = -8, -+ [0][0][RTW89_IC][1][12] = -18, -+ [0][0][RTW89_KCC][1][12] = -2, -+ [0][0][RTW89_KCC][0][12] = -2, -+ [0][0][RTW89_ACMA][1][12] = 32, -+ [0][0][RTW89_ACMA][0][12] = -8, -+ [0][0][RTW89_CHILE][1][12] = -18, -+ [0][0][RTW89_QATAR][1][12] = 32, -+ [0][0][RTW89_QATAR][0][12] = -8, -+ [0][0][RTW89_UK][1][12] = 32, -+ [0][0][RTW89_UK][0][12] = -8, -+ [0][0][RTW89_FCC][1][14] = -18, -+ [0][0][RTW89_FCC][2][14] = 44, -+ [0][0][RTW89_ETSI][1][14] = 32, -+ [0][0][RTW89_ETSI][0][14] = -8, -+ [0][0][RTW89_MKK][1][14] = 30, -+ [0][0][RTW89_MKK][0][14] = -8, -+ [0][0][RTW89_IC][1][14] = -18, -+ [0][0][RTW89_KCC][1][14] = -2, -+ [0][0][RTW89_KCC][0][14] = -2, -+ [0][0][RTW89_ACMA][1][14] = 32, -+ [0][0][RTW89_ACMA][0][14] = -8, -+ [0][0][RTW89_CHILE][1][14] = -18, -+ [0][0][RTW89_QATAR][1][14] = 32, -+ [0][0][RTW89_QATAR][0][14] = -8, -+ [0][0][RTW89_UK][1][14] = 32, -+ [0][0][RTW89_UK][0][14] = -8, -+ [0][0][RTW89_FCC][1][15] = -18, -+ [0][0][RTW89_FCC][2][15] = 44, -+ [0][0][RTW89_ETSI][1][15] = 32, -+ [0][0][RTW89_ETSI][0][15] = -8, -+ [0][0][RTW89_MKK][1][15] = 30, -+ [0][0][RTW89_MKK][0][15] = -8, -+ [0][0][RTW89_IC][1][15] = -18, -+ [0][0][RTW89_KCC][1][15] = -2, -+ [0][0][RTW89_KCC][0][15] = -2, -+ [0][0][RTW89_ACMA][1][15] = 32, -+ [0][0][RTW89_ACMA][0][15] = -8, -+ [0][0][RTW89_CHILE][1][15] = -18, -+ [0][0][RTW89_QATAR][1][15] = 32, -+ [0][0][RTW89_QATAR][0][15] = -8, -+ [0][0][RTW89_UK][1][15] = 32, -+ [0][0][RTW89_UK][0][15] = -8, -+ [0][0][RTW89_FCC][1][17] = -18, -+ [0][0][RTW89_FCC][2][17] = 44, -+ [0][0][RTW89_ETSI][1][17] = 32, -+ [0][0][RTW89_ETSI][0][17] = -8, -+ [0][0][RTW89_MKK][1][17] = 30, -+ [0][0][RTW89_MKK][0][17] = -8, -+ [0][0][RTW89_IC][1][17] = -18, -+ [0][0][RTW89_KCC][1][17] = -2, -+ [0][0][RTW89_KCC][0][17] = -2, -+ [0][0][RTW89_ACMA][1][17] = 32, -+ [0][0][RTW89_ACMA][0][17] = -8, -+ [0][0][RTW89_CHILE][1][17] = -18, -+ [0][0][RTW89_QATAR][1][17] = 32, -+ [0][0][RTW89_QATAR][0][17] = -8, -+ [0][0][RTW89_UK][1][17] = 32, -+ [0][0][RTW89_UK][0][17] = -8, -+ [0][0][RTW89_FCC][1][19] = -18, -+ [0][0][RTW89_FCC][2][19] = 44, -+ [0][0][RTW89_ETSI][1][19] = 32, -+ [0][0][RTW89_ETSI][0][19] = -8, -+ [0][0][RTW89_MKK][1][19] = 30, -+ [0][0][RTW89_MKK][0][19] = -8, -+ [0][0][RTW89_IC][1][19] = -18, -+ [0][0][RTW89_KCC][1][19] = -2, -+ [0][0][RTW89_KCC][0][19] = -2, -+ [0][0][RTW89_ACMA][1][19] = 32, -+ [0][0][RTW89_ACMA][0][19] = -8, -+ [0][0][RTW89_CHILE][1][19] = -18, -+ [0][0][RTW89_QATAR][1][19] = 32, -+ [0][0][RTW89_QATAR][0][19] = -8, -+ [0][0][RTW89_UK][1][19] = 32, -+ [0][0][RTW89_UK][0][19] = -8, -+ [0][0][RTW89_FCC][1][21] = -18, -+ [0][0][RTW89_FCC][2][21] = 44, -+ [0][0][RTW89_ETSI][1][21] = 32, -+ [0][0][RTW89_ETSI][0][21] = -8, -+ [0][0][RTW89_MKK][1][21] = 30, -+ [0][0][RTW89_MKK][0][21] = -8, -+ [0][0][RTW89_IC][1][21] = -18, -+ [0][0][RTW89_KCC][1][21] = -2, -+ [0][0][RTW89_KCC][0][21] = -2, -+ [0][0][RTW89_ACMA][1][21] = 32, -+ [0][0][RTW89_ACMA][0][21] = -8, -+ [0][0][RTW89_CHILE][1][21] = -18, -+ [0][0][RTW89_QATAR][1][21] = 32, -+ [0][0][RTW89_QATAR][0][21] = -8, -+ [0][0][RTW89_UK][1][21] = 32, -+ [0][0][RTW89_UK][0][21] = -8, -+ [0][0][RTW89_FCC][1][23] = -18, -+ [0][0][RTW89_FCC][2][23] = 54, -+ [0][0][RTW89_ETSI][1][23] = 32, -+ [0][0][RTW89_ETSI][0][23] = -8, -+ [0][0][RTW89_MKK][1][23] = 30, -+ [0][0][RTW89_MKK][0][23] = -8, -+ [0][0][RTW89_IC][1][23] = -18, -+ [0][0][RTW89_KCC][1][23] = -2, -+ [0][0][RTW89_KCC][0][23] = -2, -+ [0][0][RTW89_ACMA][1][23] = 32, -+ [0][0][RTW89_ACMA][0][23] = -8, -+ [0][0][RTW89_CHILE][1][23] = -18, -+ [0][0][RTW89_QATAR][1][23] = 32, -+ [0][0][RTW89_QATAR][0][23] = -8, -+ [0][0][RTW89_UK][1][23] = 32, -+ [0][0][RTW89_UK][0][23] = -8, -+ [0][0][RTW89_FCC][1][25] = -18, -+ [0][0][RTW89_FCC][2][25] = 54, -+ [0][0][RTW89_ETSI][1][25] = 32, -+ [0][0][RTW89_ETSI][0][25] = -8, -+ [0][0][RTW89_MKK][1][25] = 30, -+ [0][0][RTW89_MKK][0][25] = -8, -+ [0][0][RTW89_IC][1][25] = -18, -+ [0][0][RTW89_KCC][1][25] = -2, -+ [0][0][RTW89_KCC][0][25] = -2, -+ [0][0][RTW89_ACMA][1][25] = 32, -+ [0][0][RTW89_ACMA][0][25] = -8, -+ [0][0][RTW89_CHILE][1][25] = -18, -+ [0][0][RTW89_QATAR][1][25] = 32, -+ [0][0][RTW89_QATAR][0][25] = -8, -+ [0][0][RTW89_UK][1][25] = 32, -+ [0][0][RTW89_UK][0][25] = -8, -+ [0][0][RTW89_FCC][1][27] = -18, -+ [0][0][RTW89_FCC][2][27] = 54, -+ [0][0][RTW89_ETSI][1][27] = 32, -+ [0][0][RTW89_ETSI][0][27] = -8, -+ [0][0][RTW89_MKK][1][27] = 30, -+ [0][0][RTW89_MKK][0][27] = -8, -+ [0][0][RTW89_IC][1][27] = -18, -+ [0][0][RTW89_KCC][1][27] = -2, -+ [0][0][RTW89_KCC][0][27] = -2, -+ [0][0][RTW89_ACMA][1][27] = 32, -+ [0][0][RTW89_ACMA][0][27] = -8, -+ [0][0][RTW89_CHILE][1][27] = -18, -+ [0][0][RTW89_QATAR][1][27] = 32, -+ [0][0][RTW89_QATAR][0][27] = -8, -+ [0][0][RTW89_UK][1][27] = 32, -+ [0][0][RTW89_UK][0][27] = -8, -+ [0][0][RTW89_FCC][1][29] = -18, -+ [0][0][RTW89_FCC][2][29] = 54, -+ [0][0][RTW89_ETSI][1][29] = 32, -+ [0][0][RTW89_ETSI][0][29] = -8, -+ [0][0][RTW89_MKK][1][29] = 30, -+ [0][0][RTW89_MKK][0][29] = -8, -+ [0][0][RTW89_IC][1][29] = -18, -+ [0][0][RTW89_KCC][1][29] = -2, -+ [0][0][RTW89_KCC][0][29] = -2, -+ [0][0][RTW89_ACMA][1][29] = 32, -+ [0][0][RTW89_ACMA][0][29] = -8, -+ [0][0][RTW89_CHILE][1][29] = -18, -+ [0][0][RTW89_QATAR][1][29] = 32, -+ [0][0][RTW89_QATAR][0][29] = -8, -+ [0][0][RTW89_UK][1][29] = 32, -+ [0][0][RTW89_UK][0][29] = -8, -+ [0][0][RTW89_FCC][1][30] = -18, -+ [0][0][RTW89_FCC][2][30] = 54, -+ [0][0][RTW89_ETSI][1][30] = 32, -+ [0][0][RTW89_ETSI][0][30] = -8, -+ [0][0][RTW89_MKK][1][30] = 30, -+ [0][0][RTW89_MKK][0][30] = -8, -+ [0][0][RTW89_IC][1][30] = -18, -+ [0][0][RTW89_KCC][1][30] = -2, -+ [0][0][RTW89_KCC][0][30] = -2, -+ [0][0][RTW89_ACMA][1][30] = 32, -+ [0][0][RTW89_ACMA][0][30] = -8, -+ [0][0][RTW89_CHILE][1][30] = -18, -+ [0][0][RTW89_QATAR][1][30] = 32, -+ [0][0][RTW89_QATAR][0][30] = -8, -+ [0][0][RTW89_UK][1][30] = 32, -+ [0][0][RTW89_UK][0][30] = -8, -+ [0][0][RTW89_FCC][1][32] = -18, -+ [0][0][RTW89_FCC][2][32] = 54, -+ [0][0][RTW89_ETSI][1][32] = 32, -+ [0][0][RTW89_ETSI][0][32] = -8, -+ [0][0][RTW89_MKK][1][32] = 30, -+ [0][0][RTW89_MKK][0][32] = -8, -+ [0][0][RTW89_IC][1][32] = -18, -+ [0][0][RTW89_KCC][1][32] = -2, -+ [0][0][RTW89_KCC][0][32] = -2, -+ [0][0][RTW89_ACMA][1][32] = 32, -+ [0][0][RTW89_ACMA][0][32] = -8, -+ [0][0][RTW89_CHILE][1][32] = -18, -+ [0][0][RTW89_QATAR][1][32] = 32, -+ [0][0][RTW89_QATAR][0][32] = -8, -+ [0][0][RTW89_UK][1][32] = 32, -+ [0][0][RTW89_UK][0][32] = -8, -+ [0][0][RTW89_FCC][1][34] = -18, -+ [0][0][RTW89_FCC][2][34] = 54, -+ [0][0][RTW89_ETSI][1][34] = 32, -+ [0][0][RTW89_ETSI][0][34] = -8, -+ [0][0][RTW89_MKK][1][34] = 30, -+ [0][0][RTW89_MKK][0][34] = -8, -+ [0][0][RTW89_IC][1][34] = -18, -+ [0][0][RTW89_KCC][1][34] = -2, -+ [0][0][RTW89_KCC][0][34] = -2, -+ [0][0][RTW89_ACMA][1][34] = 32, -+ [0][0][RTW89_ACMA][0][34] = -8, -+ [0][0][RTW89_CHILE][1][34] = -18, -+ [0][0][RTW89_QATAR][1][34] = 32, -+ [0][0][RTW89_QATAR][0][34] = -8, -+ [0][0][RTW89_UK][1][34] = 32, -+ [0][0][RTW89_UK][0][34] = -8, -+ [0][0][RTW89_FCC][1][36] = -18, -+ [0][0][RTW89_FCC][2][36] = 54, -+ [0][0][RTW89_ETSI][1][36] = 32, -+ [0][0][RTW89_ETSI][0][36] = -8, -+ [0][0][RTW89_MKK][1][36] = 30, -+ [0][0][RTW89_MKK][0][36] = -8, -+ [0][0][RTW89_IC][1][36] = -18, -+ [0][0][RTW89_KCC][1][36] = -2, -+ [0][0][RTW89_KCC][0][36] = -2, -+ [0][0][RTW89_ACMA][1][36] = 32, -+ [0][0][RTW89_ACMA][0][36] = -8, -+ [0][0][RTW89_CHILE][1][36] = -18, -+ [0][0][RTW89_QATAR][1][36] = 32, -+ [0][0][RTW89_QATAR][0][36] = -8, -+ [0][0][RTW89_UK][1][36] = 32, -+ [0][0][RTW89_UK][0][36] = -8, -+ [0][0][RTW89_FCC][1][38] = -18, -+ [0][0][RTW89_FCC][2][38] = 54, -+ [0][0][RTW89_ETSI][1][38] = 32, -+ [0][0][RTW89_ETSI][0][38] = -8, -+ [0][0][RTW89_MKK][1][38] = 30, -+ [0][0][RTW89_MKK][0][38] = -8, -+ [0][0][RTW89_IC][1][38] = -18, -+ [0][0][RTW89_KCC][1][38] = -2, -+ [0][0][RTW89_KCC][0][38] = -2, -+ [0][0][RTW89_ACMA][1][38] = 32, -+ [0][0][RTW89_ACMA][0][38] = -8, -+ [0][0][RTW89_CHILE][1][38] = -18, -+ [0][0][RTW89_QATAR][1][38] = 32, -+ [0][0][RTW89_QATAR][0][38] = -8, -+ [0][0][RTW89_UK][1][38] = 32, -+ [0][0][RTW89_UK][0][38] = -8, -+ [0][0][RTW89_FCC][1][40] = -18, -+ [0][0][RTW89_FCC][2][40] = 54, -+ [0][0][RTW89_ETSI][1][40] = 32, -+ [0][0][RTW89_ETSI][0][40] = -8, -+ [0][0][RTW89_MKK][1][40] = 30, -+ [0][0][RTW89_MKK][0][40] = -8, -+ [0][0][RTW89_IC][1][40] = -18, -+ [0][0][RTW89_KCC][1][40] = -2, -+ [0][0][RTW89_KCC][0][40] = -2, -+ [0][0][RTW89_ACMA][1][40] = 32, -+ [0][0][RTW89_ACMA][0][40] = -8, -+ [0][0][RTW89_CHILE][1][40] = -18, -+ [0][0][RTW89_QATAR][1][40] = 32, -+ [0][0][RTW89_QATAR][0][40] = -8, -+ [0][0][RTW89_UK][1][40] = 32, -+ [0][0][RTW89_UK][0][40] = -8, -+ [0][0][RTW89_FCC][1][42] = -18, -+ [0][0][RTW89_FCC][2][42] = 54, -+ [0][0][RTW89_ETSI][1][42] = 32, -+ [0][0][RTW89_ETSI][0][42] = -8, -+ [0][0][RTW89_MKK][1][42] = 30, -+ [0][0][RTW89_MKK][0][42] = -8, -+ [0][0][RTW89_IC][1][42] = -18, -+ [0][0][RTW89_KCC][1][42] = -2, -+ [0][0][RTW89_KCC][0][42] = -2, -+ [0][0][RTW89_ACMA][1][42] = 32, -+ [0][0][RTW89_ACMA][0][42] = -8, -+ [0][0][RTW89_CHILE][1][42] = -18, -+ [0][0][RTW89_QATAR][1][42] = 32, -+ [0][0][RTW89_QATAR][0][42] = -8, -+ [0][0][RTW89_UK][1][42] = 32, -+ [0][0][RTW89_UK][0][42] = -8, -+ [0][0][RTW89_FCC][1][44] = -16, -+ [0][0][RTW89_FCC][2][44] = 56, -+ [0][0][RTW89_ETSI][1][44] = 32, -+ [0][0][RTW89_ETSI][0][44] = -6, -+ [0][0][RTW89_MKK][1][44] = 8, -+ [0][0][RTW89_MKK][0][44] = -10, -+ [0][0][RTW89_IC][1][44] = -16, -+ [0][0][RTW89_KCC][1][44] = -2, -+ [0][0][RTW89_KCC][0][44] = -2, -+ [0][0][RTW89_ACMA][1][44] = 32, -+ [0][0][RTW89_ACMA][0][44] = -6, -+ [0][0][RTW89_CHILE][1][44] = -16, -+ [0][0][RTW89_QATAR][1][44] = 32, -+ [0][0][RTW89_QATAR][0][44] = -6, -+ [0][0][RTW89_UK][1][44] = 32, -+ [0][0][RTW89_UK][0][44] = -6, -+ [0][0][RTW89_FCC][1][45] = -16, -+ [0][0][RTW89_FCC][2][45] = 127, -+ [0][0][RTW89_ETSI][1][45] = 127, -+ [0][0][RTW89_ETSI][0][45] = 127, -+ [0][0][RTW89_MKK][1][45] = 127, -+ [0][0][RTW89_MKK][0][45] = 127, -+ [0][0][RTW89_IC][1][45] = -16, -+ [0][0][RTW89_KCC][1][45] = -2, -+ [0][0][RTW89_KCC][0][45] = 127, -+ [0][0][RTW89_ACMA][1][45] = 127, -+ [0][0][RTW89_ACMA][0][45] = 127, -+ [0][0][RTW89_CHILE][1][45] = 127, -+ [0][0][RTW89_QATAR][1][45] = 127, -+ [0][0][RTW89_QATAR][0][45] = 127, -+ [0][0][RTW89_UK][1][45] = 127, -+ [0][0][RTW89_UK][0][45] = 127, -+ [0][0][RTW89_FCC][1][47] = -18, -+ [0][0][RTW89_FCC][2][47] = 127, -+ [0][0][RTW89_ETSI][1][47] = 127, -+ [0][0][RTW89_ETSI][0][47] = 127, -+ [0][0][RTW89_MKK][1][47] = 127, -+ [0][0][RTW89_MKK][0][47] = 127, -+ [0][0][RTW89_IC][1][47] = -18, -+ [0][0][RTW89_KCC][1][47] = -2, -+ [0][0][RTW89_KCC][0][47] = 127, -+ [0][0][RTW89_ACMA][1][47] = 127, -+ [0][0][RTW89_ACMA][0][47] = 127, -+ [0][0][RTW89_CHILE][1][47] = 127, -+ [0][0][RTW89_QATAR][1][47] = 127, -+ [0][0][RTW89_QATAR][0][47] = 127, -+ [0][0][RTW89_UK][1][47] = 127, -+ [0][0][RTW89_UK][0][47] = 127, -+ [0][0][RTW89_FCC][1][49] = -18, -+ [0][0][RTW89_FCC][2][49] = 127, -+ [0][0][RTW89_ETSI][1][49] = 127, -+ [0][0][RTW89_ETSI][0][49] = 127, -+ [0][0][RTW89_MKK][1][49] = 127, -+ [0][0][RTW89_MKK][0][49] = 127, -+ [0][0][RTW89_IC][1][49] = -18, -+ [0][0][RTW89_KCC][1][49] = -2, -+ [0][0][RTW89_KCC][0][49] = 127, -+ [0][0][RTW89_ACMA][1][49] = 127, -+ [0][0][RTW89_ACMA][0][49] = 127, -+ [0][0][RTW89_CHILE][1][49] = 127, -+ [0][0][RTW89_QATAR][1][49] = 127, -+ [0][0][RTW89_QATAR][0][49] = 127, -+ [0][0][RTW89_UK][1][49] = 127, -+ [0][0][RTW89_UK][0][49] = 127, -+ [0][0][RTW89_FCC][1][51] = -18, -+ [0][0][RTW89_FCC][2][51] = 127, -+ [0][0][RTW89_ETSI][1][51] = 127, -+ [0][0][RTW89_ETSI][0][51] = 127, -+ [0][0][RTW89_MKK][1][51] = 127, -+ [0][0][RTW89_MKK][0][51] = 127, -+ [0][0][RTW89_IC][1][51] = -18, -+ [0][0][RTW89_KCC][1][51] = -2, -+ [0][0][RTW89_KCC][0][51] = 127, -+ [0][0][RTW89_ACMA][1][51] = 127, -+ [0][0][RTW89_ACMA][0][51] = 127, -+ [0][0][RTW89_CHILE][1][51] = 127, -+ [0][0][RTW89_QATAR][1][51] = 127, -+ [0][0][RTW89_QATAR][0][51] = 127, -+ [0][0][RTW89_UK][1][51] = 127, -+ [0][0][RTW89_UK][0][51] = 127, -+ [0][0][RTW89_FCC][1][53] = -16, -+ [0][0][RTW89_FCC][2][53] = 127, -+ [0][0][RTW89_ETSI][1][53] = 127, -+ [0][0][RTW89_ETSI][0][53] = 127, -+ [0][0][RTW89_MKK][1][53] = 127, -+ [0][0][RTW89_MKK][0][53] = 127, -+ [0][0][RTW89_IC][1][53] = -16, -+ [0][0][RTW89_KCC][1][53] = -2, -+ [0][0][RTW89_KCC][0][53] = 127, -+ [0][0][RTW89_ACMA][1][53] = 127, -+ [0][0][RTW89_ACMA][0][53] = 127, -+ [0][0][RTW89_CHILE][1][53] = 127, -+ [0][0][RTW89_QATAR][1][53] = 127, -+ [0][0][RTW89_QATAR][0][53] = 127, -+ [0][0][RTW89_UK][1][53] = 127, -+ [0][0][RTW89_UK][0][53] = 127, -+ [0][0][RTW89_FCC][1][55] = -18, -+ [0][0][RTW89_FCC][2][55] = 56, -+ [0][0][RTW89_ETSI][1][55] = 127, -+ [0][0][RTW89_ETSI][0][55] = 127, -+ [0][0][RTW89_MKK][1][55] = 127, -+ [0][0][RTW89_MKK][0][55] = 127, -+ [0][0][RTW89_IC][1][55] = -18, -+ [0][0][RTW89_KCC][1][55] = -2, -+ [0][0][RTW89_KCC][0][55] = 127, -+ [0][0][RTW89_ACMA][1][55] = 127, -+ [0][0][RTW89_ACMA][0][55] = 127, -+ [0][0][RTW89_CHILE][1][55] = 127, -+ [0][0][RTW89_QATAR][1][55] = 127, -+ [0][0][RTW89_QATAR][0][55] = 127, -+ [0][0][RTW89_UK][1][55] = 127, -+ [0][0][RTW89_UK][0][55] = 127, -+ [0][0][RTW89_FCC][1][57] = -18, -+ [0][0][RTW89_FCC][2][57] = 56, -+ [0][0][RTW89_ETSI][1][57] = 127, -+ [0][0][RTW89_ETSI][0][57] = 127, -+ [0][0][RTW89_MKK][1][57] = 127, -+ [0][0][RTW89_MKK][0][57] = 127, -+ [0][0][RTW89_IC][1][57] = -18, -+ [0][0][RTW89_KCC][1][57] = -2, -+ [0][0][RTW89_KCC][0][57] = 127, -+ [0][0][RTW89_ACMA][1][57] = 127, -+ [0][0][RTW89_ACMA][0][57] = 127, -+ [0][0][RTW89_CHILE][1][57] = 127, -+ [0][0][RTW89_QATAR][1][57] = 127, -+ [0][0][RTW89_QATAR][0][57] = 127, -+ [0][0][RTW89_UK][1][57] = 127, -+ [0][0][RTW89_UK][0][57] = 127, -+ [0][0][RTW89_FCC][1][59] = -18, -+ [0][0][RTW89_FCC][2][59] = 56, -+ [0][0][RTW89_ETSI][1][59] = 127, -+ [0][0][RTW89_ETSI][0][59] = 127, -+ [0][0][RTW89_MKK][1][59] = 127, -+ [0][0][RTW89_MKK][0][59] = 127, -+ [0][0][RTW89_IC][1][59] = -18, -+ [0][0][RTW89_KCC][1][59] = -2, -+ [0][0][RTW89_KCC][0][59] = 127, -+ [0][0][RTW89_ACMA][1][59] = 127, -+ [0][0][RTW89_ACMA][0][59] = 127, -+ [0][0][RTW89_CHILE][1][59] = 127, -+ [0][0][RTW89_QATAR][1][59] = 127, -+ [0][0][RTW89_QATAR][0][59] = 127, -+ [0][0][RTW89_UK][1][59] = 127, -+ [0][0][RTW89_UK][0][59] = 127, -+ [0][0][RTW89_FCC][1][60] = -18, -+ [0][0][RTW89_FCC][2][60] = 56, -+ [0][0][RTW89_ETSI][1][60] = 127, -+ [0][0][RTW89_ETSI][0][60] = 127, -+ [0][0][RTW89_MKK][1][60] = 127, -+ [0][0][RTW89_MKK][0][60] = 127, -+ [0][0][RTW89_IC][1][60] = -18, -+ [0][0][RTW89_KCC][1][60] = -2, -+ [0][0][RTW89_KCC][0][60] = 127, -+ [0][0][RTW89_ACMA][1][60] = 127, -+ [0][0][RTW89_ACMA][0][60] = 127, -+ [0][0][RTW89_CHILE][1][60] = 127, -+ [0][0][RTW89_QATAR][1][60] = 127, -+ [0][0][RTW89_QATAR][0][60] = 127, -+ [0][0][RTW89_UK][1][60] = 127, -+ [0][0][RTW89_UK][0][60] = 127, -+ [0][0][RTW89_FCC][1][62] = -18, -+ [0][0][RTW89_FCC][2][62] = 56, -+ [0][0][RTW89_ETSI][1][62] = 127, -+ [0][0][RTW89_ETSI][0][62] = 127, -+ [0][0][RTW89_MKK][1][62] = 127, -+ [0][0][RTW89_MKK][0][62] = 127, -+ [0][0][RTW89_IC][1][62] = -18, -+ [0][0][RTW89_KCC][1][62] = -2, -+ [0][0][RTW89_KCC][0][62] = 127, -+ [0][0][RTW89_ACMA][1][62] = 127, -+ [0][0][RTW89_ACMA][0][62] = 127, -+ [0][0][RTW89_CHILE][1][62] = 127, -+ [0][0][RTW89_QATAR][1][62] = 127, -+ [0][0][RTW89_QATAR][0][62] = 127, -+ [0][0][RTW89_UK][1][62] = 127, -+ [0][0][RTW89_UK][0][62] = 127, -+ [0][0][RTW89_FCC][1][64] = -18, -+ [0][0][RTW89_FCC][2][64] = 56, -+ [0][0][RTW89_ETSI][1][64] = 127, -+ [0][0][RTW89_ETSI][0][64] = 127, -+ [0][0][RTW89_MKK][1][64] = 127, -+ [0][0][RTW89_MKK][0][64] = 127, -+ [0][0][RTW89_IC][1][64] = -18, -+ [0][0][RTW89_KCC][1][64] = -2, -+ [0][0][RTW89_KCC][0][64] = 127, -+ [0][0][RTW89_ACMA][1][64] = 127, -+ [0][0][RTW89_ACMA][0][64] = 127, -+ [0][0][RTW89_CHILE][1][64] = 127, -+ [0][0][RTW89_QATAR][1][64] = 127, -+ [0][0][RTW89_QATAR][0][64] = 127, -+ [0][0][RTW89_UK][1][64] = 127, -+ [0][0][RTW89_UK][0][64] = 127, -+ [0][0][RTW89_FCC][1][66] = -18, -+ [0][0][RTW89_FCC][2][66] = 56, -+ [0][0][RTW89_ETSI][1][66] = 127, -+ [0][0][RTW89_ETSI][0][66] = 127, -+ [0][0][RTW89_MKK][1][66] = 127, -+ [0][0][RTW89_MKK][0][66] = 127, -+ [0][0][RTW89_IC][1][66] = -18, -+ [0][0][RTW89_KCC][1][66] = -2, -+ [0][0][RTW89_KCC][0][66] = 127, -+ [0][0][RTW89_ACMA][1][66] = 127, -+ [0][0][RTW89_ACMA][0][66] = 127, -+ [0][0][RTW89_CHILE][1][66] = 127, -+ [0][0][RTW89_QATAR][1][66] = 127, -+ [0][0][RTW89_QATAR][0][66] = 127, -+ [0][0][RTW89_UK][1][66] = 127, -+ [0][0][RTW89_UK][0][66] = 127, -+ [0][0][RTW89_FCC][1][68] = -18, -+ [0][0][RTW89_FCC][2][68] = 56, -+ [0][0][RTW89_ETSI][1][68] = 127, -+ [0][0][RTW89_ETSI][0][68] = 127, -+ [0][0][RTW89_MKK][1][68] = 127, -+ [0][0][RTW89_MKK][0][68] = 127, -+ [0][0][RTW89_IC][1][68] = -18, -+ [0][0][RTW89_KCC][1][68] = -2, -+ [0][0][RTW89_KCC][0][68] = 127, -+ [0][0][RTW89_ACMA][1][68] = 127, -+ [0][0][RTW89_ACMA][0][68] = 127, -+ [0][0][RTW89_CHILE][1][68] = 127, -+ [0][0][RTW89_QATAR][1][68] = 127, -+ [0][0][RTW89_QATAR][0][68] = 127, -+ [0][0][RTW89_UK][1][68] = 127, -+ [0][0][RTW89_UK][0][68] = 127, -+ [0][0][RTW89_FCC][1][70] = -16, -+ [0][0][RTW89_FCC][2][70] = 56, -+ [0][0][RTW89_ETSI][1][70] = 127, -+ [0][0][RTW89_ETSI][0][70] = 127, -+ [0][0][RTW89_MKK][1][70] = 127, -+ [0][0][RTW89_MKK][0][70] = 127, -+ [0][0][RTW89_IC][1][70] = -16, -+ [0][0][RTW89_KCC][1][70] = -2, -+ [0][0][RTW89_KCC][0][70] = 127, -+ [0][0][RTW89_ACMA][1][70] = 127, -+ [0][0][RTW89_ACMA][0][70] = 127, -+ [0][0][RTW89_CHILE][1][70] = 127, -+ [0][0][RTW89_QATAR][1][70] = 127, -+ [0][0][RTW89_QATAR][0][70] = 127, -+ [0][0][RTW89_UK][1][70] = 127, -+ [0][0][RTW89_UK][0][70] = 127, -+ [0][0][RTW89_FCC][1][72] = -18, -+ [0][0][RTW89_FCC][2][72] = 56, -+ [0][0][RTW89_ETSI][1][72] = 127, -+ [0][0][RTW89_ETSI][0][72] = 127, -+ [0][0][RTW89_MKK][1][72] = 127, -+ [0][0][RTW89_MKK][0][72] = 127, -+ [0][0][RTW89_IC][1][72] = -18, -+ [0][0][RTW89_KCC][1][72] = -2, -+ [0][0][RTW89_KCC][0][72] = 127, -+ [0][0][RTW89_ACMA][1][72] = 127, -+ [0][0][RTW89_ACMA][0][72] = 127, -+ [0][0][RTW89_CHILE][1][72] = 127, -+ [0][0][RTW89_QATAR][1][72] = 127, -+ [0][0][RTW89_QATAR][0][72] = 127, -+ [0][0][RTW89_UK][1][72] = 127, -+ [0][0][RTW89_UK][0][72] = 127, -+ [0][0][RTW89_FCC][1][74] = -18, -+ [0][0][RTW89_FCC][2][74] = 56, -+ [0][0][RTW89_ETSI][1][74] = 127, -+ [0][0][RTW89_ETSI][0][74] = 127, -+ [0][0][RTW89_MKK][1][74] = 127, -+ [0][0][RTW89_MKK][0][74] = 127, -+ [0][0][RTW89_IC][1][74] = -18, -+ [0][0][RTW89_KCC][1][74] = -2, -+ [0][0][RTW89_KCC][0][74] = 127, -+ [0][0][RTW89_ACMA][1][74] = 127, -+ [0][0][RTW89_ACMA][0][74] = 127, -+ [0][0][RTW89_CHILE][1][74] = 127, -+ [0][0][RTW89_QATAR][1][74] = 127, -+ [0][0][RTW89_QATAR][0][74] = 127, -+ [0][0][RTW89_UK][1][74] = 127, -+ [0][0][RTW89_UK][0][74] = 127, -+ [0][0][RTW89_FCC][1][75] = -18, -+ [0][0][RTW89_FCC][2][75] = 56, -+ [0][0][RTW89_ETSI][1][75] = 127, -+ [0][0][RTW89_ETSI][0][75] = 127, -+ [0][0][RTW89_MKK][1][75] = 127, -+ [0][0][RTW89_MKK][0][75] = 127, -+ [0][0][RTW89_IC][1][75] = -18, -+ [0][0][RTW89_KCC][1][75] = -2, -+ [0][0][RTW89_KCC][0][75] = 127, -+ [0][0][RTW89_ACMA][1][75] = 127, -+ [0][0][RTW89_ACMA][0][75] = 127, -+ [0][0][RTW89_CHILE][1][75] = 127, -+ [0][0][RTW89_QATAR][1][75] = 127, -+ [0][0][RTW89_QATAR][0][75] = 127, -+ [0][0][RTW89_UK][1][75] = 127, -+ [0][0][RTW89_UK][0][75] = 127, -+ [0][0][RTW89_FCC][1][77] = -18, -+ [0][0][RTW89_FCC][2][77] = 56, -+ [0][0][RTW89_ETSI][1][77] = 127, -+ [0][0][RTW89_ETSI][0][77] = 127, -+ [0][0][RTW89_MKK][1][77] = 127, -+ [0][0][RTW89_MKK][0][77] = 127, -+ [0][0][RTW89_IC][1][77] = -18, -+ [0][0][RTW89_KCC][1][77] = -2, -+ [0][0][RTW89_KCC][0][77] = 127, -+ [0][0][RTW89_ACMA][1][77] = 127, -+ [0][0][RTW89_ACMA][0][77] = 127, -+ [0][0][RTW89_CHILE][1][77] = 127, -+ [0][0][RTW89_QATAR][1][77] = 127, -+ [0][0][RTW89_QATAR][0][77] = 127, -+ [0][0][RTW89_UK][1][77] = 127, -+ [0][0][RTW89_UK][0][77] = 127, -+ [0][0][RTW89_FCC][1][79] = -18, -+ [0][0][RTW89_FCC][2][79] = 56, -+ [0][0][RTW89_ETSI][1][79] = 127, -+ [0][0][RTW89_ETSI][0][79] = 127, -+ [0][0][RTW89_MKK][1][79] = 127, -+ [0][0][RTW89_MKK][0][79] = 127, -+ [0][0][RTW89_IC][1][79] = -18, -+ [0][0][RTW89_KCC][1][79] = -2, -+ [0][0][RTW89_KCC][0][79] = 127, -+ [0][0][RTW89_ACMA][1][79] = 127, -+ [0][0][RTW89_ACMA][0][79] = 127, -+ [0][0][RTW89_CHILE][1][79] = 127, -+ [0][0][RTW89_QATAR][1][79] = 127, -+ [0][0][RTW89_QATAR][0][79] = 127, -+ [0][0][RTW89_UK][1][79] = 127, -+ [0][0][RTW89_UK][0][79] = 127, -+ [0][0][RTW89_FCC][1][81] = -18, -+ [0][0][RTW89_FCC][2][81] = 56, -+ [0][0][RTW89_ETSI][1][81] = 127, -+ [0][0][RTW89_ETSI][0][81] = 127, -+ [0][0][RTW89_MKK][1][81] = 127, -+ [0][0][RTW89_MKK][0][81] = 127, -+ [0][0][RTW89_IC][1][81] = -18, -+ [0][0][RTW89_KCC][1][81] = -2, -+ [0][0][RTW89_KCC][0][81] = 127, -+ [0][0][RTW89_ACMA][1][81] = 127, -+ [0][0][RTW89_ACMA][0][81] = 127, -+ [0][0][RTW89_CHILE][1][81] = 127, -+ [0][0][RTW89_QATAR][1][81] = 127, -+ [0][0][RTW89_QATAR][0][81] = 127, -+ [0][0][RTW89_UK][1][81] = 127, -+ [0][0][RTW89_UK][0][81] = 127, -+ [0][0][RTW89_FCC][1][83] = -18, -+ [0][0][RTW89_FCC][2][83] = 56, -+ [0][0][RTW89_ETSI][1][83] = 127, -+ [0][0][RTW89_ETSI][0][83] = 127, -+ [0][0][RTW89_MKK][1][83] = 127, -+ [0][0][RTW89_MKK][0][83] = 127, -+ [0][0][RTW89_IC][1][83] = -18, -+ [0][0][RTW89_KCC][1][83] = -2, -+ [0][0][RTW89_KCC][0][83] = 127, -+ [0][0][RTW89_ACMA][1][83] = 127, -+ [0][0][RTW89_ACMA][0][83] = 127, -+ [0][0][RTW89_CHILE][1][83] = 127, -+ [0][0][RTW89_QATAR][1][83] = 127, -+ [0][0][RTW89_QATAR][0][83] = 127, -+ [0][0][RTW89_UK][1][83] = 127, -+ [0][0][RTW89_UK][0][83] = 127, -+ [0][0][RTW89_FCC][1][85] = -18, -+ [0][0][RTW89_FCC][2][85] = 56, -+ [0][0][RTW89_ETSI][1][85] = 127, -+ [0][0][RTW89_ETSI][0][85] = 127, -+ [0][0][RTW89_MKK][1][85] = 127, -+ [0][0][RTW89_MKK][0][85] = 127, -+ [0][0][RTW89_IC][1][85] = -18, -+ [0][0][RTW89_KCC][1][85] = -2, -+ [0][0][RTW89_KCC][0][85] = 127, -+ [0][0][RTW89_ACMA][1][85] = 127, -+ [0][0][RTW89_ACMA][0][85] = 127, -+ [0][0][RTW89_CHILE][1][85] = 127, -+ [0][0][RTW89_QATAR][1][85] = 127, -+ [0][0][RTW89_QATAR][0][85] = 127, -+ [0][0][RTW89_UK][1][85] = 127, -+ [0][0][RTW89_UK][0][85] = 127, -+ [0][0][RTW89_FCC][1][87] = -16, -+ [0][0][RTW89_FCC][2][87] = 127, -+ [0][0][RTW89_ETSI][1][87] = 127, -+ [0][0][RTW89_ETSI][0][87] = 127, -+ [0][0][RTW89_MKK][1][87] = 127, -+ [0][0][RTW89_MKK][0][87] = 127, -+ [0][0][RTW89_IC][1][87] = -16, -+ [0][0][RTW89_KCC][1][87] = -2, -+ [0][0][RTW89_KCC][0][87] = 127, -+ [0][0][RTW89_ACMA][1][87] = 127, -+ [0][0][RTW89_ACMA][0][87] = 127, -+ [0][0][RTW89_CHILE][1][87] = 127, -+ [0][0][RTW89_QATAR][1][87] = 127, -+ [0][0][RTW89_QATAR][0][87] = 127, -+ [0][0][RTW89_UK][1][87] = 127, -+ [0][0][RTW89_UK][0][87] = 127, -+ [0][0][RTW89_FCC][1][89] = -16, -+ [0][0][RTW89_FCC][2][89] = 127, -+ [0][0][RTW89_ETSI][1][89] = 127, -+ [0][0][RTW89_ETSI][0][89] = 127, -+ [0][0][RTW89_MKK][1][89] = 127, -+ [0][0][RTW89_MKK][0][89] = 127, -+ [0][0][RTW89_IC][1][89] = -16, -+ [0][0][RTW89_KCC][1][89] = -2, -+ [0][0][RTW89_KCC][0][89] = 127, -+ [0][0][RTW89_ACMA][1][89] = 127, -+ [0][0][RTW89_ACMA][0][89] = 127, -+ [0][0][RTW89_CHILE][1][89] = 127, -+ [0][0][RTW89_QATAR][1][89] = 127, -+ [0][0][RTW89_QATAR][0][89] = 127, -+ [0][0][RTW89_UK][1][89] = 127, -+ [0][0][RTW89_UK][0][89] = 127, -+ [0][0][RTW89_FCC][1][90] = -16, -+ [0][0][RTW89_FCC][2][90] = 127, -+ [0][0][RTW89_ETSI][1][90] = 127, -+ [0][0][RTW89_ETSI][0][90] = 127, -+ [0][0][RTW89_MKK][1][90] = 127, -+ [0][0][RTW89_MKK][0][90] = 127, -+ [0][0][RTW89_IC][1][90] = -16, -+ [0][0][RTW89_KCC][1][90] = -2, -+ [0][0][RTW89_KCC][0][90] = 127, -+ [0][0][RTW89_ACMA][1][90] = 127, -+ [0][0][RTW89_ACMA][0][90] = 127, -+ [0][0][RTW89_CHILE][1][90] = 127, -+ [0][0][RTW89_QATAR][1][90] = 127, -+ [0][0][RTW89_QATAR][0][90] = 127, -+ [0][0][RTW89_UK][1][90] = 127, -+ [0][0][RTW89_UK][0][90] = 127, -+ [0][0][RTW89_FCC][1][92] = -16, -+ [0][0][RTW89_FCC][2][92] = 127, -+ [0][0][RTW89_ETSI][1][92] = 127, -+ [0][0][RTW89_ETSI][0][92] = 127, -+ [0][0][RTW89_MKK][1][92] = 127, -+ [0][0][RTW89_MKK][0][92] = 127, -+ [0][0][RTW89_IC][1][92] = -16, -+ [0][0][RTW89_KCC][1][92] = -2, -+ [0][0][RTW89_KCC][0][92] = 127, -+ [0][0][RTW89_ACMA][1][92] = 127, -+ [0][0][RTW89_ACMA][0][92] = 127, -+ [0][0][RTW89_CHILE][1][92] = 127, -+ [0][0][RTW89_QATAR][1][92] = 127, -+ [0][0][RTW89_QATAR][0][92] = 127, -+ [0][0][RTW89_UK][1][92] = 127, -+ [0][0][RTW89_UK][0][92] = 127, -+ [0][0][RTW89_FCC][1][94] = -16, -+ [0][0][RTW89_FCC][2][94] = 127, -+ [0][0][RTW89_ETSI][1][94] = 127, -+ [0][0][RTW89_ETSI][0][94] = 127, -+ [0][0][RTW89_MKK][1][94] = 127, -+ [0][0][RTW89_MKK][0][94] = 127, -+ [0][0][RTW89_IC][1][94] = -16, -+ [0][0][RTW89_KCC][1][94] = -2, -+ [0][0][RTW89_KCC][0][94] = 127, -+ [0][0][RTW89_ACMA][1][94] = 127, -+ [0][0][RTW89_ACMA][0][94] = 127, -+ [0][0][RTW89_CHILE][1][94] = 127, -+ [0][0][RTW89_QATAR][1][94] = 127, -+ [0][0][RTW89_QATAR][0][94] = 127, -+ [0][0][RTW89_UK][1][94] = 127, -+ [0][0][RTW89_UK][0][94] = 127, -+ [0][0][RTW89_FCC][1][96] = -16, -+ [0][0][RTW89_FCC][2][96] = 127, -+ [0][0][RTW89_ETSI][1][96] = 127, -+ [0][0][RTW89_ETSI][0][96] = 127, -+ [0][0][RTW89_MKK][1][96] = 127, -+ [0][0][RTW89_MKK][0][96] = 127, -+ [0][0][RTW89_IC][1][96] = -16, -+ [0][0][RTW89_KCC][1][96] = -2, -+ [0][0][RTW89_KCC][0][96] = 127, -+ [0][0][RTW89_ACMA][1][96] = 127, -+ [0][0][RTW89_ACMA][0][96] = 127, -+ [0][0][RTW89_CHILE][1][96] = 127, -+ [0][0][RTW89_QATAR][1][96] = 127, -+ [0][0][RTW89_QATAR][0][96] = 127, -+ [0][0][RTW89_UK][1][96] = 127, -+ [0][0][RTW89_UK][0][96] = 127, -+ [0][0][RTW89_FCC][1][98] = -16, -+ [0][0][RTW89_FCC][2][98] = 127, -+ [0][0][RTW89_ETSI][1][98] = 127, -+ [0][0][RTW89_ETSI][0][98] = 127, -+ [0][0][RTW89_MKK][1][98] = 127, -+ [0][0][RTW89_MKK][0][98] = 127, -+ [0][0][RTW89_IC][1][98] = -16, -+ [0][0][RTW89_KCC][1][98] = -2, -+ [0][0][RTW89_KCC][0][98] = 127, -+ [0][0][RTW89_ACMA][1][98] = 127, -+ [0][0][RTW89_ACMA][0][98] = 127, -+ [0][0][RTW89_CHILE][1][98] = 127, -+ [0][0][RTW89_QATAR][1][98] = 127, -+ [0][0][RTW89_QATAR][0][98] = 127, -+ [0][0][RTW89_UK][1][98] = 127, -+ [0][0][RTW89_UK][0][98] = 127, -+ [0][0][RTW89_FCC][1][100] = -16, -+ [0][0][RTW89_FCC][2][100] = 127, -+ [0][0][RTW89_ETSI][1][100] = 127, -+ [0][0][RTW89_ETSI][0][100] = 127, -+ [0][0][RTW89_MKK][1][100] = 127, -+ [0][0][RTW89_MKK][0][100] = 127, -+ [0][0][RTW89_IC][1][100] = -16, -+ [0][0][RTW89_KCC][1][100] = -2, -+ [0][0][RTW89_KCC][0][100] = 127, -+ [0][0][RTW89_ACMA][1][100] = 127, -+ [0][0][RTW89_ACMA][0][100] = 127, -+ [0][0][RTW89_CHILE][1][100] = 127, -+ [0][0][RTW89_QATAR][1][100] = 127, -+ [0][0][RTW89_QATAR][0][100] = 127, -+ [0][0][RTW89_UK][1][100] = 127, -+ [0][0][RTW89_UK][0][100] = 127, -+ [0][0][RTW89_FCC][1][102] = -16, -+ [0][0][RTW89_FCC][2][102] = 127, -+ [0][0][RTW89_ETSI][1][102] = 127, -+ [0][0][RTW89_ETSI][0][102] = 127, -+ [0][0][RTW89_MKK][1][102] = 127, -+ [0][0][RTW89_MKK][0][102] = 127, -+ [0][0][RTW89_IC][1][102] = -16, -+ [0][0][RTW89_KCC][1][102] = -2, -+ [0][0][RTW89_KCC][0][102] = 127, -+ [0][0][RTW89_ACMA][1][102] = 127, -+ [0][0][RTW89_ACMA][0][102] = 127, -+ [0][0][RTW89_CHILE][1][102] = 127, -+ [0][0][RTW89_QATAR][1][102] = 127, -+ [0][0][RTW89_QATAR][0][102] = 127, -+ [0][0][RTW89_UK][1][102] = 127, -+ [0][0][RTW89_UK][0][102] = 127, -+ [0][0][RTW89_FCC][1][104] = -16, -+ [0][0][RTW89_FCC][2][104] = 127, -+ [0][0][RTW89_ETSI][1][104] = 127, -+ [0][0][RTW89_ETSI][0][104] = 127, -+ [0][0][RTW89_MKK][1][104] = 127, -+ [0][0][RTW89_MKK][0][104] = 127, -+ [0][0][RTW89_IC][1][104] = -16, -+ [0][0][RTW89_KCC][1][104] = -2, -+ [0][0][RTW89_KCC][0][104] = 127, -+ [0][0][RTW89_ACMA][1][104] = 127, -+ [0][0][RTW89_ACMA][0][104] = 127, -+ [0][0][RTW89_CHILE][1][104] = 127, -+ [0][0][RTW89_QATAR][1][104] = 127, -+ [0][0][RTW89_QATAR][0][104] = 127, -+ [0][0][RTW89_UK][1][104] = 127, -+ [0][0][RTW89_UK][0][104] = 127, -+ [0][0][RTW89_FCC][1][105] = -16, -+ [0][0][RTW89_FCC][2][105] = 127, -+ [0][0][RTW89_ETSI][1][105] = 127, -+ [0][0][RTW89_ETSI][0][105] = 127, -+ [0][0][RTW89_MKK][1][105] = 127, -+ [0][0][RTW89_MKK][0][105] = 127, -+ [0][0][RTW89_IC][1][105] = -16, -+ [0][0][RTW89_KCC][1][105] = -2, -+ [0][0][RTW89_KCC][0][105] = 127, -+ [0][0][RTW89_ACMA][1][105] = 127, -+ [0][0][RTW89_ACMA][0][105] = 127, -+ [0][0][RTW89_CHILE][1][105] = 127, -+ [0][0][RTW89_QATAR][1][105] = 127, -+ [0][0][RTW89_QATAR][0][105] = 127, -+ [0][0][RTW89_UK][1][105] = 127, -+ [0][0][RTW89_UK][0][105] = 127, -+ [0][0][RTW89_FCC][1][107] = -12, -+ [0][0][RTW89_FCC][2][107] = 127, -+ [0][0][RTW89_ETSI][1][107] = 127, -+ [0][0][RTW89_ETSI][0][107] = 127, -+ [0][0][RTW89_MKK][1][107] = 127, -+ [0][0][RTW89_MKK][0][107] = 127, -+ [0][0][RTW89_IC][1][107] = -12, -+ [0][0][RTW89_KCC][1][107] = -2, -+ [0][0][RTW89_KCC][0][107] = 127, -+ [0][0][RTW89_ACMA][1][107] = 127, -+ [0][0][RTW89_ACMA][0][107] = 127, -+ [0][0][RTW89_CHILE][1][107] = 127, -+ [0][0][RTW89_QATAR][1][107] = 127, -+ [0][0][RTW89_QATAR][0][107] = 127, -+ [0][0][RTW89_UK][1][107] = 127, -+ [0][0][RTW89_UK][0][107] = 127, -+ [0][0][RTW89_FCC][1][109] = -12, -+ [0][0][RTW89_FCC][2][109] = 127, -+ [0][0][RTW89_ETSI][1][109] = 127, -+ [0][0][RTW89_ETSI][0][109] = 127, -+ [0][0][RTW89_MKK][1][109] = 127, -+ [0][0][RTW89_MKK][0][109] = 127, -+ [0][0][RTW89_IC][1][109] = -12, -+ [0][0][RTW89_KCC][1][109] = 127, -+ [0][0][RTW89_KCC][0][109] = 127, -+ [0][0][RTW89_ACMA][1][109] = 127, -+ [0][0][RTW89_ACMA][0][109] = 127, -+ [0][0][RTW89_CHILE][1][109] = 127, -+ [0][0][RTW89_QATAR][1][109] = 127, -+ [0][0][RTW89_QATAR][0][109] = 127, -+ [0][0][RTW89_UK][1][109] = 127, -+ [0][0][RTW89_UK][0][109] = 127, -+ [0][0][RTW89_FCC][1][111] = 127, -+ [0][0][RTW89_FCC][2][111] = 127, -+ [0][0][RTW89_ETSI][1][111] = 127, -+ [0][0][RTW89_ETSI][0][111] = 127, -+ [0][0][RTW89_MKK][1][111] = 127, -+ [0][0][RTW89_MKK][0][111] = 127, -+ [0][0][RTW89_IC][1][111] = 127, -+ [0][0][RTW89_KCC][1][111] = 127, -+ [0][0][RTW89_KCC][0][111] = 127, -+ [0][0][RTW89_ACMA][1][111] = 127, -+ [0][0][RTW89_ACMA][0][111] = 127, -+ [0][0][RTW89_CHILE][1][111] = 127, -+ [0][0][RTW89_QATAR][1][111] = 127, -+ [0][0][RTW89_QATAR][0][111] = 127, -+ [0][0][RTW89_UK][1][111] = 127, -+ [0][0][RTW89_UK][0][111] = 127, -+ [0][0][RTW89_FCC][1][113] = 127, -+ [0][0][RTW89_FCC][2][113] = 127, -+ [0][0][RTW89_ETSI][1][113] = 127, -+ [0][0][RTW89_ETSI][0][113] = 127, -+ [0][0][RTW89_MKK][1][113] = 127, -+ [0][0][RTW89_MKK][0][113] = 127, -+ [0][0][RTW89_IC][1][113] = 127, -+ [0][0][RTW89_KCC][1][113] = 127, -+ [0][0][RTW89_KCC][0][113] = 127, -+ [0][0][RTW89_ACMA][1][113] = 127, -+ [0][0][RTW89_ACMA][0][113] = 127, -+ [0][0][RTW89_CHILE][1][113] = 127, -+ [0][0][RTW89_QATAR][1][113] = 127, -+ [0][0][RTW89_QATAR][0][113] = 127, -+ [0][0][RTW89_UK][1][113] = 127, -+ [0][0][RTW89_UK][0][113] = 127, -+ [0][0][RTW89_FCC][1][115] = 127, -+ [0][0][RTW89_FCC][2][115] = 127, -+ [0][0][RTW89_ETSI][1][115] = 127, -+ [0][0][RTW89_ETSI][0][115] = 127, -+ [0][0][RTW89_MKK][1][115] = 127, -+ [0][0][RTW89_MKK][0][115] = 127, -+ [0][0][RTW89_IC][1][115] = 127, -+ [0][0][RTW89_KCC][1][115] = 127, -+ [0][0][RTW89_KCC][0][115] = 127, -+ [0][0][RTW89_ACMA][1][115] = 127, -+ [0][0][RTW89_ACMA][0][115] = 127, -+ [0][0][RTW89_CHILE][1][115] = 127, -+ [0][0][RTW89_QATAR][1][115] = 127, -+ [0][0][RTW89_QATAR][0][115] = 127, -+ [0][0][RTW89_UK][1][115] = 127, -+ [0][0][RTW89_UK][0][115] = 127, -+ [0][0][RTW89_FCC][1][117] = 127, -+ [0][0][RTW89_FCC][2][117] = 127, -+ [0][0][RTW89_ETSI][1][117] = 127, -+ [0][0][RTW89_ETSI][0][117] = 127, -+ [0][0][RTW89_MKK][1][117] = 127, -+ [0][0][RTW89_MKK][0][117] = 127, -+ [0][0][RTW89_IC][1][117] = 127, -+ [0][0][RTW89_KCC][1][117] = 127, -+ [0][0][RTW89_KCC][0][117] = 127, -+ [0][0][RTW89_ACMA][1][117] = 127, -+ [0][0][RTW89_ACMA][0][117] = 127, -+ [0][0][RTW89_CHILE][1][117] = 127, -+ [0][0][RTW89_QATAR][1][117] = 127, -+ [0][0][RTW89_QATAR][0][117] = 127, -+ [0][0][RTW89_UK][1][117] = 127, -+ [0][0][RTW89_UK][0][117] = 127, -+ [0][0][RTW89_FCC][1][119] = 127, -+ [0][0][RTW89_FCC][2][119] = 127, -+ [0][0][RTW89_ETSI][1][119] = 127, -+ [0][0][RTW89_ETSI][0][119] = 127, -+ [0][0][RTW89_MKK][1][119] = 127, -+ [0][0][RTW89_MKK][0][119] = 127, -+ [0][0][RTW89_IC][1][119] = 127, -+ [0][0][RTW89_KCC][1][119] = 127, -+ [0][0][RTW89_KCC][0][119] = 127, -+ [0][0][RTW89_ACMA][1][119] = 127, -+ [0][0][RTW89_ACMA][0][119] = 127, -+ [0][0][RTW89_CHILE][1][119] = 127, -+ [0][0][RTW89_QATAR][1][119] = 127, -+ [0][0][RTW89_QATAR][0][119] = 127, -+ [0][0][RTW89_UK][1][119] = 127, -+ [0][0][RTW89_UK][0][119] = 127, -+ [0][1][RTW89_FCC][1][0] = -40, -+ [0][1][RTW89_FCC][2][0] = 32, -+ [0][1][RTW89_ETSI][1][0] = 20, -+ [0][1][RTW89_ETSI][0][0] = -18, -+ [0][1][RTW89_MKK][1][0] = 18, -+ [0][1][RTW89_MKK][0][0] = -20, -+ [0][1][RTW89_IC][1][0] = -40, -+ [0][1][RTW89_KCC][1][0] = -14, -+ [0][1][RTW89_KCC][0][0] = -14, -+ [0][1][RTW89_ACMA][1][0] = 20, -+ [0][1][RTW89_ACMA][0][0] = -18, -+ [0][1][RTW89_CHILE][1][0] = -40, -+ [0][1][RTW89_QATAR][1][0] = 20, -+ [0][1][RTW89_QATAR][0][0] = -18, -+ [0][1][RTW89_UK][1][0] = 20, -+ [0][1][RTW89_UK][0][0] = -18, -+ [0][1][RTW89_FCC][1][2] = -40, -+ [0][1][RTW89_FCC][2][2] = 32, -+ [0][1][RTW89_ETSI][1][2] = 20, -+ [0][1][RTW89_ETSI][0][2] = -18, -+ [0][1][RTW89_MKK][1][2] = 18, -+ [0][1][RTW89_MKK][0][2] = -22, -+ [0][1][RTW89_IC][1][2] = -40, -+ [0][1][RTW89_KCC][1][2] = -14, -+ [0][1][RTW89_KCC][0][2] = -14, -+ [0][1][RTW89_ACMA][1][2] = 20, -+ [0][1][RTW89_ACMA][0][2] = -18, -+ [0][1][RTW89_CHILE][1][2] = -40, -+ [0][1][RTW89_QATAR][1][2] = 20, -+ [0][1][RTW89_QATAR][0][2] = -18, -+ [0][1][RTW89_UK][1][2] = 20, -+ [0][1][RTW89_UK][0][2] = -18, -+ [0][1][RTW89_FCC][1][4] = -40, -+ [0][1][RTW89_FCC][2][4] = 32, -+ [0][1][RTW89_ETSI][1][4] = 20, -+ [0][1][RTW89_ETSI][0][4] = -18, -+ [0][1][RTW89_MKK][1][4] = 18, -+ [0][1][RTW89_MKK][0][4] = -22, -+ [0][1][RTW89_IC][1][4] = -40, -+ [0][1][RTW89_KCC][1][4] = -14, -+ [0][1][RTW89_KCC][0][4] = -14, -+ [0][1][RTW89_ACMA][1][4] = 20, -+ [0][1][RTW89_ACMA][0][4] = -18, -+ [0][1][RTW89_CHILE][1][4] = -40, -+ [0][1][RTW89_QATAR][1][4] = 20, -+ [0][1][RTW89_QATAR][0][4] = -18, -+ [0][1][RTW89_UK][1][4] = 20, -+ [0][1][RTW89_UK][0][4] = -18, -+ [0][1][RTW89_FCC][1][6] = -40, -+ [0][1][RTW89_FCC][2][6] = 32, -+ [0][1][RTW89_ETSI][1][6] = 20, -+ [0][1][RTW89_ETSI][0][6] = -18, -+ [0][1][RTW89_MKK][1][6] = 18, -+ [0][1][RTW89_MKK][0][6] = -22, -+ [0][1][RTW89_IC][1][6] = -40, -+ [0][1][RTW89_KCC][1][6] = -14, -+ [0][1][RTW89_KCC][0][6] = -14, -+ [0][1][RTW89_ACMA][1][6] = 20, -+ [0][1][RTW89_ACMA][0][6] = -18, -+ [0][1][RTW89_CHILE][1][6] = -40, -+ [0][1][RTW89_QATAR][1][6] = 20, -+ [0][1][RTW89_QATAR][0][6] = -18, -+ [0][1][RTW89_UK][1][6] = 20, -+ [0][1][RTW89_UK][0][6] = -18, -+ [0][1][RTW89_FCC][1][8] = -40, -+ [0][1][RTW89_FCC][2][8] = 32, -+ [0][1][RTW89_ETSI][1][8] = 20, -+ [0][1][RTW89_ETSI][0][8] = -18, -+ [0][1][RTW89_MKK][1][8] = 18, -+ [0][1][RTW89_MKK][0][8] = -22, -+ [0][1][RTW89_IC][1][8] = -40, -+ [0][1][RTW89_KCC][1][8] = -14, -+ [0][1][RTW89_KCC][0][8] = -14, -+ [0][1][RTW89_ACMA][1][8] = 20, -+ [0][1][RTW89_ACMA][0][8] = -18, -+ [0][1][RTW89_CHILE][1][8] = -40, -+ [0][1][RTW89_QATAR][1][8] = 20, -+ [0][1][RTW89_QATAR][0][8] = -18, -+ [0][1][RTW89_UK][1][8] = 20, -+ [0][1][RTW89_UK][0][8] = -18, -+ [0][1][RTW89_FCC][1][10] = -40, -+ [0][1][RTW89_FCC][2][10] = 32, -+ [0][1][RTW89_ETSI][1][10] = 20, -+ [0][1][RTW89_ETSI][0][10] = -18, -+ [0][1][RTW89_MKK][1][10] = 18, -+ [0][1][RTW89_MKK][0][10] = -22, -+ [0][1][RTW89_IC][1][10] = -40, -+ [0][1][RTW89_KCC][1][10] = -14, -+ [0][1][RTW89_KCC][0][10] = -14, -+ [0][1][RTW89_ACMA][1][10] = 20, -+ [0][1][RTW89_ACMA][0][10] = -18, -+ [0][1][RTW89_CHILE][1][10] = -40, -+ [0][1][RTW89_QATAR][1][10] = 20, -+ [0][1][RTW89_QATAR][0][10] = -18, -+ [0][1][RTW89_UK][1][10] = 20, -+ [0][1][RTW89_UK][0][10] = -18, -+ [0][1][RTW89_FCC][1][12] = -40, -+ [0][1][RTW89_FCC][2][12] = 32, -+ [0][1][RTW89_ETSI][1][12] = 20, -+ [0][1][RTW89_ETSI][0][12] = -18, -+ [0][1][RTW89_MKK][1][12] = 18, -+ [0][1][RTW89_MKK][0][12] = -22, -+ [0][1][RTW89_IC][1][12] = -40, -+ [0][1][RTW89_KCC][1][12] = -14, -+ [0][1][RTW89_KCC][0][12] = -14, -+ [0][1][RTW89_ACMA][1][12] = 20, -+ [0][1][RTW89_ACMA][0][12] = -18, -+ [0][1][RTW89_CHILE][1][12] = -40, -+ [0][1][RTW89_QATAR][1][12] = 20, -+ [0][1][RTW89_QATAR][0][12] = -18, -+ [0][1][RTW89_UK][1][12] = 20, -+ [0][1][RTW89_UK][0][12] = -18, -+ [0][1][RTW89_FCC][1][14] = -40, -+ [0][1][RTW89_FCC][2][14] = 32, -+ [0][1][RTW89_ETSI][1][14] = 20, -+ [0][1][RTW89_ETSI][0][14] = -18, -+ [0][1][RTW89_MKK][1][14] = 18, -+ [0][1][RTW89_MKK][0][14] = -22, -+ [0][1][RTW89_IC][1][14] = -40, -+ [0][1][RTW89_KCC][1][14] = -14, -+ [0][1][RTW89_KCC][0][14] = -14, -+ [0][1][RTW89_ACMA][1][14] = 20, -+ [0][1][RTW89_ACMA][0][14] = -18, -+ [0][1][RTW89_CHILE][1][14] = -40, -+ [0][1][RTW89_QATAR][1][14] = 20, -+ [0][1][RTW89_QATAR][0][14] = -18, -+ [0][1][RTW89_UK][1][14] = 20, -+ [0][1][RTW89_UK][0][14] = -18, -+ [0][1][RTW89_FCC][1][15] = -40, -+ [0][1][RTW89_FCC][2][15] = 32, -+ [0][1][RTW89_ETSI][1][15] = 20, -+ [0][1][RTW89_ETSI][0][15] = -18, -+ [0][1][RTW89_MKK][1][15] = 18, -+ [0][1][RTW89_MKK][0][15] = -22, -+ [0][1][RTW89_IC][1][15] = -40, -+ [0][1][RTW89_KCC][1][15] = -14, -+ [0][1][RTW89_KCC][0][15] = -14, -+ [0][1][RTW89_ACMA][1][15] = 20, -+ [0][1][RTW89_ACMA][0][15] = -18, -+ [0][1][RTW89_CHILE][1][15] = -40, -+ [0][1][RTW89_QATAR][1][15] = 20, -+ [0][1][RTW89_QATAR][0][15] = -18, -+ [0][1][RTW89_UK][1][15] = 20, -+ [0][1][RTW89_UK][0][15] = -18, -+ [0][1][RTW89_FCC][1][17] = -40, -+ [0][1][RTW89_FCC][2][17] = 32, -+ [0][1][RTW89_ETSI][1][17] = 20, -+ [0][1][RTW89_ETSI][0][17] = -18, -+ [0][1][RTW89_MKK][1][17] = 18, -+ [0][1][RTW89_MKK][0][17] = -22, -+ [0][1][RTW89_IC][1][17] = -40, -+ [0][1][RTW89_KCC][1][17] = -14, -+ [0][1][RTW89_KCC][0][17] = -14, -+ [0][1][RTW89_ACMA][1][17] = 20, -+ [0][1][RTW89_ACMA][0][17] = -18, -+ [0][1][RTW89_CHILE][1][17] = -40, -+ [0][1][RTW89_QATAR][1][17] = 20, -+ [0][1][RTW89_QATAR][0][17] = -18, -+ [0][1][RTW89_UK][1][17] = 20, -+ [0][1][RTW89_UK][0][17] = -18, -+ [0][1][RTW89_FCC][1][19] = -40, -+ [0][1][RTW89_FCC][2][19] = 32, -+ [0][1][RTW89_ETSI][1][19] = 20, -+ [0][1][RTW89_ETSI][0][19] = -18, -+ [0][1][RTW89_MKK][1][19] = 18, -+ [0][1][RTW89_MKK][0][19] = -22, -+ [0][1][RTW89_IC][1][19] = -40, -+ [0][1][RTW89_KCC][1][19] = -14, -+ [0][1][RTW89_KCC][0][19] = -14, -+ [0][1][RTW89_ACMA][1][19] = 20, -+ [0][1][RTW89_ACMA][0][19] = -18, -+ [0][1][RTW89_CHILE][1][19] = -40, -+ [0][1][RTW89_QATAR][1][19] = 20, -+ [0][1][RTW89_QATAR][0][19] = -18, -+ [0][1][RTW89_UK][1][19] = 20, -+ [0][1][RTW89_UK][0][19] = -18, -+ [0][1][RTW89_FCC][1][21] = -40, -+ [0][1][RTW89_FCC][2][21] = 32, -+ [0][1][RTW89_ETSI][1][21] = 20, -+ [0][1][RTW89_ETSI][0][21] = -18, -+ [0][1][RTW89_MKK][1][21] = 18, -+ [0][1][RTW89_MKK][0][21] = -22, -+ [0][1][RTW89_IC][1][21] = -40, -+ [0][1][RTW89_KCC][1][21] = -14, -+ [0][1][RTW89_KCC][0][21] = -14, -+ [0][1][RTW89_ACMA][1][21] = 20, -+ [0][1][RTW89_ACMA][0][21] = -18, -+ [0][1][RTW89_CHILE][1][21] = -40, -+ [0][1][RTW89_QATAR][1][21] = 20, -+ [0][1][RTW89_QATAR][0][21] = -18, -+ [0][1][RTW89_UK][1][21] = 20, -+ [0][1][RTW89_UK][0][21] = -18, -+ [0][1][RTW89_FCC][1][23] = -40, -+ [0][1][RTW89_FCC][2][23] = 32, -+ [0][1][RTW89_ETSI][1][23] = 20, -+ [0][1][RTW89_ETSI][0][23] = -18, -+ [0][1][RTW89_MKK][1][23] = 18, -+ [0][1][RTW89_MKK][0][23] = -22, -+ [0][1][RTW89_IC][1][23] = -40, -+ [0][1][RTW89_KCC][1][23] = -14, -+ [0][1][RTW89_KCC][0][23] = -14, -+ [0][1][RTW89_ACMA][1][23] = 20, -+ [0][1][RTW89_ACMA][0][23] = -18, -+ [0][1][RTW89_CHILE][1][23] = -40, -+ [0][1][RTW89_QATAR][1][23] = 20, -+ [0][1][RTW89_QATAR][0][23] = -18, -+ [0][1][RTW89_UK][1][23] = 20, -+ [0][1][RTW89_UK][0][23] = -18, -+ [0][1][RTW89_FCC][1][25] = -40, -+ [0][1][RTW89_FCC][2][25] = 32, -+ [0][1][RTW89_ETSI][1][25] = 20, -+ [0][1][RTW89_ETSI][0][25] = -18, -+ [0][1][RTW89_MKK][1][25] = -4, -+ [0][1][RTW89_MKK][0][25] = -22, -+ [0][1][RTW89_IC][1][25] = -40, -+ [0][1][RTW89_KCC][1][25] = -14, -+ [0][1][RTW89_KCC][0][25] = -14, -+ [0][1][RTW89_ACMA][1][25] = 20, -+ [0][1][RTW89_ACMA][0][25] = -18, -+ [0][1][RTW89_CHILE][1][25] = -40, -+ [0][1][RTW89_QATAR][1][25] = 20, -+ [0][1][RTW89_QATAR][0][25] = -18, -+ [0][1][RTW89_UK][1][25] = 20, -+ [0][1][RTW89_UK][0][25] = -18, -+ [0][1][RTW89_FCC][1][27] = -40, -+ [0][1][RTW89_FCC][2][27] = 32, -+ [0][1][RTW89_ETSI][1][27] = 20, -+ [0][1][RTW89_ETSI][0][27] = -18, -+ [0][1][RTW89_MKK][1][27] = -4, -+ [0][1][RTW89_MKK][0][27] = -22, -+ [0][1][RTW89_IC][1][27] = -40, -+ [0][1][RTW89_KCC][1][27] = -14, -+ [0][1][RTW89_KCC][0][27] = -14, -+ [0][1][RTW89_ACMA][1][27] = 20, -+ [0][1][RTW89_ACMA][0][27] = -18, -+ [0][1][RTW89_CHILE][1][27] = -40, -+ [0][1][RTW89_QATAR][1][27] = 20, -+ [0][1][RTW89_QATAR][0][27] = -18, -+ [0][1][RTW89_UK][1][27] = 20, -+ [0][1][RTW89_UK][0][27] = -18, -+ [0][1][RTW89_FCC][1][29] = -40, -+ [0][1][RTW89_FCC][2][29] = 32, -+ [0][1][RTW89_ETSI][1][29] = 20, -+ [0][1][RTW89_ETSI][0][29] = -18, -+ [0][1][RTW89_MKK][1][29] = -4, -+ [0][1][RTW89_MKK][0][29] = -22, -+ [0][1][RTW89_IC][1][29] = -40, -+ [0][1][RTW89_KCC][1][29] = -14, -+ [0][1][RTW89_KCC][0][29] = -14, -+ [0][1][RTW89_ACMA][1][29] = 20, -+ [0][1][RTW89_ACMA][0][29] = -18, -+ [0][1][RTW89_CHILE][1][29] = -40, -+ [0][1][RTW89_QATAR][1][29] = 20, -+ [0][1][RTW89_QATAR][0][29] = -18, -+ [0][1][RTW89_UK][1][29] = 20, -+ [0][1][RTW89_UK][0][29] = -18, -+ [0][1][RTW89_FCC][1][30] = -40, -+ [0][1][RTW89_FCC][2][30] = 32, -+ [0][1][RTW89_ETSI][1][30] = 20, -+ [0][1][RTW89_ETSI][0][30] = -18, -+ [0][1][RTW89_MKK][1][30] = -4, -+ [0][1][RTW89_MKK][0][30] = -22, -+ [0][1][RTW89_IC][1][30] = -40, -+ [0][1][RTW89_KCC][1][30] = -14, -+ [0][1][RTW89_KCC][0][30] = -14, -+ [0][1][RTW89_ACMA][1][30] = 20, -+ [0][1][RTW89_ACMA][0][30] = -18, -+ [0][1][RTW89_CHILE][1][30] = -40, -+ [0][1][RTW89_QATAR][1][30] = 20, -+ [0][1][RTW89_QATAR][0][30] = -18, -+ [0][1][RTW89_UK][1][30] = 20, -+ [0][1][RTW89_UK][0][30] = -18, -+ [0][1][RTW89_FCC][1][32] = -40, -+ [0][1][RTW89_FCC][2][32] = 32, -+ [0][1][RTW89_ETSI][1][32] = 20, -+ [0][1][RTW89_ETSI][0][32] = -18, -+ [0][1][RTW89_MKK][1][32] = -4, -+ [0][1][RTW89_MKK][0][32] = -22, -+ [0][1][RTW89_IC][1][32] = -40, -+ [0][1][RTW89_KCC][1][32] = -14, -+ [0][1][RTW89_KCC][0][32] = -14, -+ [0][1][RTW89_ACMA][1][32] = 20, -+ [0][1][RTW89_ACMA][0][32] = -18, -+ [0][1][RTW89_CHILE][1][32] = -40, -+ [0][1][RTW89_QATAR][1][32] = 20, -+ [0][1][RTW89_QATAR][0][32] = -18, -+ [0][1][RTW89_UK][1][32] = 20, -+ [0][1][RTW89_UK][0][32] = -18, -+ [0][1][RTW89_FCC][1][34] = -40, -+ [0][1][RTW89_FCC][2][34] = 32, -+ [0][1][RTW89_ETSI][1][34] = 20, -+ [0][1][RTW89_ETSI][0][34] = -18, -+ [0][1][RTW89_MKK][1][34] = -4, -+ [0][1][RTW89_MKK][0][34] = -22, -+ [0][1][RTW89_IC][1][34] = -40, -+ [0][1][RTW89_KCC][1][34] = -14, -+ [0][1][RTW89_KCC][0][34] = -14, -+ [0][1][RTW89_ACMA][1][34] = 20, -+ [0][1][RTW89_ACMA][0][34] = -18, -+ [0][1][RTW89_CHILE][1][34] = -40, -+ [0][1][RTW89_QATAR][1][34] = 20, -+ [0][1][RTW89_QATAR][0][34] = -18, -+ [0][1][RTW89_UK][1][34] = 20, -+ [0][1][RTW89_UK][0][34] = -18, -+ [0][1][RTW89_FCC][1][36] = -40, -+ [0][1][RTW89_FCC][2][36] = 32, -+ [0][1][RTW89_ETSI][1][36] = 20, -+ [0][1][RTW89_ETSI][0][36] = -18, -+ [0][1][RTW89_MKK][1][36] = -4, -+ [0][1][RTW89_MKK][0][36] = -22, -+ [0][1][RTW89_IC][1][36] = -40, -+ [0][1][RTW89_KCC][1][36] = -14, -+ [0][1][RTW89_KCC][0][36] = -14, -+ [0][1][RTW89_ACMA][1][36] = 20, -+ [0][1][RTW89_ACMA][0][36] = -18, -+ [0][1][RTW89_CHILE][1][36] = -40, -+ [0][1][RTW89_QATAR][1][36] = 20, -+ [0][1][RTW89_QATAR][0][36] = -18, -+ [0][1][RTW89_UK][1][36] = 20, -+ [0][1][RTW89_UK][0][36] = -18, -+ [0][1][RTW89_FCC][1][38] = -40, -+ [0][1][RTW89_FCC][2][38] = 32, -+ [0][1][RTW89_ETSI][1][38] = 20, -+ [0][1][RTW89_ETSI][0][38] = -18, -+ [0][1][RTW89_MKK][1][38] = -4, -+ [0][1][RTW89_MKK][0][38] = -22, -+ [0][1][RTW89_IC][1][38] = -40, -+ [0][1][RTW89_KCC][1][38] = -14, -+ [0][1][RTW89_KCC][0][38] = -14, -+ [0][1][RTW89_ACMA][1][38] = 20, -+ [0][1][RTW89_ACMA][0][38] = -18, -+ [0][1][RTW89_CHILE][1][38] = -40, -+ [0][1][RTW89_QATAR][1][38] = 20, -+ [0][1][RTW89_QATAR][0][38] = -18, -+ [0][1][RTW89_UK][1][38] = 20, -+ [0][1][RTW89_UK][0][38] = -18, -+ [0][1][RTW89_FCC][1][40] = -40, -+ [0][1][RTW89_FCC][2][40] = 32, -+ [0][1][RTW89_ETSI][1][40] = 20, -+ [0][1][RTW89_ETSI][0][40] = -18, -+ [0][1][RTW89_MKK][1][40] = -4, -+ [0][1][RTW89_MKK][0][40] = -22, -+ [0][1][RTW89_IC][1][40] = -40, -+ [0][1][RTW89_KCC][1][40] = -14, -+ [0][1][RTW89_KCC][0][40] = -14, -+ [0][1][RTW89_ACMA][1][40] = 20, -+ [0][1][RTW89_ACMA][0][40] = -18, -+ [0][1][RTW89_CHILE][1][40] = -40, -+ [0][1][RTW89_QATAR][1][40] = 20, -+ [0][1][RTW89_QATAR][0][40] = -18, -+ [0][1][RTW89_UK][1][40] = 20, -+ [0][1][RTW89_UK][0][40] = -18, -+ [0][1][RTW89_FCC][1][42] = -40, -+ [0][1][RTW89_FCC][2][42] = 32, -+ [0][1][RTW89_ETSI][1][42] = 20, -+ [0][1][RTW89_ETSI][0][42] = -18, -+ [0][1][RTW89_MKK][1][42] = -4, -+ [0][1][RTW89_MKK][0][42] = -22, -+ [0][1][RTW89_IC][1][42] = -40, -+ [0][1][RTW89_KCC][1][42] = -14, -+ [0][1][RTW89_KCC][0][42] = -14, -+ [0][1][RTW89_ACMA][1][42] = 20, -+ [0][1][RTW89_ACMA][0][42] = -18, -+ [0][1][RTW89_CHILE][1][42] = -40, -+ [0][1][RTW89_QATAR][1][42] = 20, -+ [0][1][RTW89_QATAR][0][42] = -18, -+ [0][1][RTW89_UK][1][42] = 20, -+ [0][1][RTW89_UK][0][42] = -18, -+ [0][1][RTW89_FCC][1][44] = -40, -+ [0][1][RTW89_FCC][2][44] = 32, -+ [0][1][RTW89_ETSI][1][44] = 20, -+ [0][1][RTW89_ETSI][0][44] = -18, -+ [0][1][RTW89_MKK][1][44] = -4, -+ [0][1][RTW89_MKK][0][44] = -22, -+ [0][1][RTW89_IC][1][44] = -40, -+ [0][1][RTW89_KCC][1][44] = -14, -+ [0][1][RTW89_KCC][0][44] = -14, -+ [0][1][RTW89_ACMA][1][44] = 20, -+ [0][1][RTW89_ACMA][0][44] = -18, -+ [0][1][RTW89_CHILE][1][44] = -40, -+ [0][1][RTW89_QATAR][1][44] = 20, -+ [0][1][RTW89_QATAR][0][44] = -18, -+ [0][1][RTW89_UK][1][44] = 20, -+ [0][1][RTW89_UK][0][44] = -18, -+ [0][1][RTW89_FCC][1][45] = -40, -+ [0][1][RTW89_FCC][2][45] = 127, -+ [0][1][RTW89_ETSI][1][45] = 127, -+ [0][1][RTW89_ETSI][0][45] = 127, -+ [0][1][RTW89_MKK][1][45] = 127, -+ [0][1][RTW89_MKK][0][45] = 127, -+ [0][1][RTW89_IC][1][45] = -40, -+ [0][1][RTW89_KCC][1][45] = -14, -+ [0][1][RTW89_KCC][0][45] = 127, -+ [0][1][RTW89_ACMA][1][45] = 127, -+ [0][1][RTW89_ACMA][0][45] = 127, -+ [0][1][RTW89_CHILE][1][45] = 127, -+ [0][1][RTW89_QATAR][1][45] = 127, -+ [0][1][RTW89_QATAR][0][45] = 127, -+ [0][1][RTW89_UK][1][45] = 127, -+ [0][1][RTW89_UK][0][45] = 127, -+ [0][1][RTW89_FCC][1][47] = -40, -+ [0][1][RTW89_FCC][2][47] = 127, -+ [0][1][RTW89_ETSI][1][47] = 127, -+ [0][1][RTW89_ETSI][0][47] = 127, -+ [0][1][RTW89_MKK][1][47] = 127, -+ [0][1][RTW89_MKK][0][47] = 127, -+ [0][1][RTW89_IC][1][47] = -40, -+ [0][1][RTW89_KCC][1][47] = -14, -+ [0][1][RTW89_KCC][0][47] = 127, -+ [0][1][RTW89_ACMA][1][47] = 127, -+ [0][1][RTW89_ACMA][0][47] = 127, -+ [0][1][RTW89_CHILE][1][47] = 127, -+ [0][1][RTW89_QATAR][1][47] = 127, -+ [0][1][RTW89_QATAR][0][47] = 127, -+ [0][1][RTW89_UK][1][47] = 127, -+ [0][1][RTW89_UK][0][47] = 127, -+ [0][1][RTW89_FCC][1][49] = -40, -+ [0][1][RTW89_FCC][2][49] = 127, -+ [0][1][RTW89_ETSI][1][49] = 127, -+ [0][1][RTW89_ETSI][0][49] = 127, -+ [0][1][RTW89_MKK][1][49] = 127, -+ [0][1][RTW89_MKK][0][49] = 127, -+ [0][1][RTW89_IC][1][49] = -40, -+ [0][1][RTW89_KCC][1][49] = -14, -+ [0][1][RTW89_KCC][0][49] = 127, -+ [0][1][RTW89_ACMA][1][49] = 127, -+ [0][1][RTW89_ACMA][0][49] = 127, -+ [0][1][RTW89_CHILE][1][49] = 127, -+ [0][1][RTW89_QATAR][1][49] = 127, -+ [0][1][RTW89_QATAR][0][49] = 127, -+ [0][1][RTW89_UK][1][49] = 127, -+ [0][1][RTW89_UK][0][49] = 127, -+ [0][1][RTW89_FCC][1][51] = -40, -+ [0][1][RTW89_FCC][2][51] = 127, -+ [0][1][RTW89_ETSI][1][51] = 127, -+ [0][1][RTW89_ETSI][0][51] = 127, -+ [0][1][RTW89_MKK][1][51] = 127, -+ [0][1][RTW89_MKK][0][51] = 127, -+ [0][1][RTW89_IC][1][51] = -40, -+ [0][1][RTW89_KCC][1][51] = -14, -+ [0][1][RTW89_KCC][0][51] = 127, -+ [0][1][RTW89_ACMA][1][51] = 127, -+ [0][1][RTW89_ACMA][0][51] = 127, -+ [0][1][RTW89_CHILE][1][51] = 127, -+ [0][1][RTW89_QATAR][1][51] = 127, -+ [0][1][RTW89_QATAR][0][51] = 127, -+ [0][1][RTW89_UK][1][51] = 127, -+ [0][1][RTW89_UK][0][51] = 127, -+ [0][1][RTW89_FCC][1][53] = -40, -+ [0][1][RTW89_FCC][2][53] = 127, -+ [0][1][RTW89_ETSI][1][53] = 127, -+ [0][1][RTW89_ETSI][0][53] = 127, -+ [0][1][RTW89_MKK][1][53] = 127, -+ [0][1][RTW89_MKK][0][53] = 127, -+ [0][1][RTW89_IC][1][53] = -40, -+ [0][1][RTW89_KCC][1][53] = -14, -+ [0][1][RTW89_KCC][0][53] = 127, -+ [0][1][RTW89_ACMA][1][53] = 127, -+ [0][1][RTW89_ACMA][0][53] = 127, -+ [0][1][RTW89_CHILE][1][53] = 127, -+ [0][1][RTW89_QATAR][1][53] = 127, -+ [0][1][RTW89_QATAR][0][53] = 127, -+ [0][1][RTW89_UK][1][53] = 127, -+ [0][1][RTW89_UK][0][53] = 127, -+ [0][1][RTW89_FCC][1][55] = -40, -+ [0][1][RTW89_FCC][2][55] = 30, -+ [0][1][RTW89_ETSI][1][55] = 127, -+ [0][1][RTW89_ETSI][0][55] = 127, -+ [0][1][RTW89_MKK][1][55] = 127, -+ [0][1][RTW89_MKK][0][55] = 127, -+ [0][1][RTW89_IC][1][55] = -40, -+ [0][1][RTW89_KCC][1][55] = -14, -+ [0][1][RTW89_KCC][0][55] = 127, -+ [0][1][RTW89_ACMA][1][55] = 127, -+ [0][1][RTW89_ACMA][0][55] = 127, -+ [0][1][RTW89_CHILE][1][55] = 127, -+ [0][1][RTW89_QATAR][1][55] = 127, -+ [0][1][RTW89_QATAR][0][55] = 127, -+ [0][1][RTW89_UK][1][55] = 127, -+ [0][1][RTW89_UK][0][55] = 127, -+ [0][1][RTW89_FCC][1][57] = -40, -+ [0][1][RTW89_FCC][2][57] = 30, -+ [0][1][RTW89_ETSI][1][57] = 127, -+ [0][1][RTW89_ETSI][0][57] = 127, -+ [0][1][RTW89_MKK][1][57] = 127, -+ [0][1][RTW89_MKK][0][57] = 127, -+ [0][1][RTW89_IC][1][57] = -40, -+ [0][1][RTW89_KCC][1][57] = -14, -+ [0][1][RTW89_KCC][0][57] = 127, -+ [0][1][RTW89_ACMA][1][57] = 127, -+ [0][1][RTW89_ACMA][0][57] = 127, -+ [0][1][RTW89_CHILE][1][57] = 127, -+ [0][1][RTW89_QATAR][1][57] = 127, -+ [0][1][RTW89_QATAR][0][57] = 127, -+ [0][1][RTW89_UK][1][57] = 127, -+ [0][1][RTW89_UK][0][57] = 127, -+ [0][1][RTW89_FCC][1][59] = -40, -+ [0][1][RTW89_FCC][2][59] = 30, -+ [0][1][RTW89_ETSI][1][59] = 127, -+ [0][1][RTW89_ETSI][0][59] = 127, -+ [0][1][RTW89_MKK][1][59] = 127, -+ [0][1][RTW89_MKK][0][59] = 127, -+ [0][1][RTW89_IC][1][59] = -40, -+ [0][1][RTW89_KCC][1][59] = -14, -+ [0][1][RTW89_KCC][0][59] = 127, -+ [0][1][RTW89_ACMA][1][59] = 127, -+ [0][1][RTW89_ACMA][0][59] = 127, -+ [0][1][RTW89_CHILE][1][59] = 127, -+ [0][1][RTW89_QATAR][1][59] = 127, -+ [0][1][RTW89_QATAR][0][59] = 127, -+ [0][1][RTW89_UK][1][59] = 127, -+ [0][1][RTW89_UK][0][59] = 127, -+ [0][1][RTW89_FCC][1][60] = -40, -+ [0][1][RTW89_FCC][2][60] = 30, -+ [0][1][RTW89_ETSI][1][60] = 127, -+ [0][1][RTW89_ETSI][0][60] = 127, -+ [0][1][RTW89_MKK][1][60] = 127, -+ [0][1][RTW89_MKK][0][60] = 127, -+ [0][1][RTW89_IC][1][60] = -40, -+ [0][1][RTW89_KCC][1][60] = -14, -+ [0][1][RTW89_KCC][0][60] = 127, -+ [0][1][RTW89_ACMA][1][60] = 127, -+ [0][1][RTW89_ACMA][0][60] = 127, -+ [0][1][RTW89_CHILE][1][60] = 127, -+ [0][1][RTW89_QATAR][1][60] = 127, -+ [0][1][RTW89_QATAR][0][60] = 127, -+ [0][1][RTW89_UK][1][60] = 127, -+ [0][1][RTW89_UK][0][60] = 127, -+ [0][1][RTW89_FCC][1][62] = -40, -+ [0][1][RTW89_FCC][2][62] = 30, -+ [0][1][RTW89_ETSI][1][62] = 127, -+ [0][1][RTW89_ETSI][0][62] = 127, -+ [0][1][RTW89_MKK][1][62] = 127, -+ [0][1][RTW89_MKK][0][62] = 127, -+ [0][1][RTW89_IC][1][62] = -40, -+ [0][1][RTW89_KCC][1][62] = -14, -+ [0][1][RTW89_KCC][0][62] = 127, -+ [0][1][RTW89_ACMA][1][62] = 127, -+ [0][1][RTW89_ACMA][0][62] = 127, -+ [0][1][RTW89_CHILE][1][62] = 127, -+ [0][1][RTW89_QATAR][1][62] = 127, -+ [0][1][RTW89_QATAR][0][62] = 127, -+ [0][1][RTW89_UK][1][62] = 127, -+ [0][1][RTW89_UK][0][62] = 127, -+ [0][1][RTW89_FCC][1][64] = -40, -+ [0][1][RTW89_FCC][2][64] = 30, -+ [0][1][RTW89_ETSI][1][64] = 127, -+ [0][1][RTW89_ETSI][0][64] = 127, -+ [0][1][RTW89_MKK][1][64] = 127, -+ [0][1][RTW89_MKK][0][64] = 127, -+ [0][1][RTW89_IC][1][64] = -40, -+ [0][1][RTW89_KCC][1][64] = -14, -+ [0][1][RTW89_KCC][0][64] = 127, -+ [0][1][RTW89_ACMA][1][64] = 127, -+ [0][1][RTW89_ACMA][0][64] = 127, -+ [0][1][RTW89_CHILE][1][64] = 127, -+ [0][1][RTW89_QATAR][1][64] = 127, -+ [0][1][RTW89_QATAR][0][64] = 127, -+ [0][1][RTW89_UK][1][64] = 127, -+ [0][1][RTW89_UK][0][64] = 127, -+ [0][1][RTW89_FCC][1][66] = -40, -+ [0][1][RTW89_FCC][2][66] = 30, -+ [0][1][RTW89_ETSI][1][66] = 127, -+ [0][1][RTW89_ETSI][0][66] = 127, -+ [0][1][RTW89_MKK][1][66] = 127, -+ [0][1][RTW89_MKK][0][66] = 127, -+ [0][1][RTW89_IC][1][66] = -40, -+ [0][1][RTW89_KCC][1][66] = -14, -+ [0][1][RTW89_KCC][0][66] = 127, -+ [0][1][RTW89_ACMA][1][66] = 127, -+ [0][1][RTW89_ACMA][0][66] = 127, -+ [0][1][RTW89_CHILE][1][66] = 127, -+ [0][1][RTW89_QATAR][1][66] = 127, -+ [0][1][RTW89_QATAR][0][66] = 127, -+ [0][1][RTW89_UK][1][66] = 127, -+ [0][1][RTW89_UK][0][66] = 127, -+ [0][1][RTW89_FCC][1][68] = -40, -+ [0][1][RTW89_FCC][2][68] = 30, -+ [0][1][RTW89_ETSI][1][68] = 127, -+ [0][1][RTW89_ETSI][0][68] = 127, -+ [0][1][RTW89_MKK][1][68] = 127, -+ [0][1][RTW89_MKK][0][68] = 127, -+ [0][1][RTW89_IC][1][68] = -40, -+ [0][1][RTW89_KCC][1][68] = -14, -+ [0][1][RTW89_KCC][0][68] = 127, -+ [0][1][RTW89_ACMA][1][68] = 127, -+ [0][1][RTW89_ACMA][0][68] = 127, -+ [0][1][RTW89_CHILE][1][68] = 127, -+ [0][1][RTW89_QATAR][1][68] = 127, -+ [0][1][RTW89_QATAR][0][68] = 127, -+ [0][1][RTW89_UK][1][68] = 127, -+ [0][1][RTW89_UK][0][68] = 127, -+ [0][1][RTW89_FCC][1][70] = -38, -+ [0][1][RTW89_FCC][2][70] = 30, -+ [0][1][RTW89_ETSI][1][70] = 127, -+ [0][1][RTW89_ETSI][0][70] = 127, -+ [0][1][RTW89_MKK][1][70] = 127, -+ [0][1][RTW89_MKK][0][70] = 127, -+ [0][1][RTW89_IC][1][70] = -38, -+ [0][1][RTW89_KCC][1][70] = -14, -+ [0][1][RTW89_KCC][0][70] = 127, -+ [0][1][RTW89_ACMA][1][70] = 127, -+ [0][1][RTW89_ACMA][0][70] = 127, -+ [0][1][RTW89_CHILE][1][70] = 127, -+ [0][1][RTW89_QATAR][1][70] = 127, -+ [0][1][RTW89_QATAR][0][70] = 127, -+ [0][1][RTW89_UK][1][70] = 127, -+ [0][1][RTW89_UK][0][70] = 127, -+ [0][1][RTW89_FCC][1][72] = -38, -+ [0][1][RTW89_FCC][2][72] = 30, -+ [0][1][RTW89_ETSI][1][72] = 127, -+ [0][1][RTW89_ETSI][0][72] = 127, -+ [0][1][RTW89_MKK][1][72] = 127, -+ [0][1][RTW89_MKK][0][72] = 127, -+ [0][1][RTW89_IC][1][72] = -38, -+ [0][1][RTW89_KCC][1][72] = -14, -+ [0][1][RTW89_KCC][0][72] = 127, -+ [0][1][RTW89_ACMA][1][72] = 127, -+ [0][1][RTW89_ACMA][0][72] = 127, -+ [0][1][RTW89_CHILE][1][72] = 127, -+ [0][1][RTW89_QATAR][1][72] = 127, -+ [0][1][RTW89_QATAR][0][72] = 127, -+ [0][1][RTW89_UK][1][72] = 127, -+ [0][1][RTW89_UK][0][72] = 127, -+ [0][1][RTW89_FCC][1][74] = -38, -+ [0][1][RTW89_FCC][2][74] = 30, -+ [0][1][RTW89_ETSI][1][74] = 127, -+ [0][1][RTW89_ETSI][0][74] = 127, -+ [0][1][RTW89_MKK][1][74] = 127, -+ [0][1][RTW89_MKK][0][74] = 127, -+ [0][1][RTW89_IC][1][74] = -38, -+ [0][1][RTW89_KCC][1][74] = -14, -+ [0][1][RTW89_KCC][0][74] = 127, -+ [0][1][RTW89_ACMA][1][74] = 127, -+ [0][1][RTW89_ACMA][0][74] = 127, -+ [0][1][RTW89_CHILE][1][74] = 127, -+ [0][1][RTW89_QATAR][1][74] = 127, -+ [0][1][RTW89_QATAR][0][74] = 127, -+ [0][1][RTW89_UK][1][74] = 127, -+ [0][1][RTW89_UK][0][74] = 127, -+ [0][1][RTW89_FCC][1][75] = -38, -+ [0][1][RTW89_FCC][2][75] = 30, -+ [0][1][RTW89_ETSI][1][75] = 127, -+ [0][1][RTW89_ETSI][0][75] = 127, -+ [0][1][RTW89_MKK][1][75] = 127, -+ [0][1][RTW89_MKK][0][75] = 127, -+ [0][1][RTW89_IC][1][75] = -38, -+ [0][1][RTW89_KCC][1][75] = -14, -+ [0][1][RTW89_KCC][0][75] = 127, -+ [0][1][RTW89_ACMA][1][75] = 127, -+ [0][1][RTW89_ACMA][0][75] = 127, -+ [0][1][RTW89_CHILE][1][75] = 127, -+ [0][1][RTW89_QATAR][1][75] = 127, -+ [0][1][RTW89_QATAR][0][75] = 127, -+ [0][1][RTW89_UK][1][75] = 127, -+ [0][1][RTW89_UK][0][75] = 127, -+ [0][1][RTW89_FCC][1][77] = -38, -+ [0][1][RTW89_FCC][2][77] = 30, -+ [0][1][RTW89_ETSI][1][77] = 127, -+ [0][1][RTW89_ETSI][0][77] = 127, -+ [0][1][RTW89_MKK][1][77] = 127, -+ [0][1][RTW89_MKK][0][77] = 127, -+ [0][1][RTW89_IC][1][77] = -38, -+ [0][1][RTW89_KCC][1][77] = -14, -+ [0][1][RTW89_KCC][0][77] = 127, -+ [0][1][RTW89_ACMA][1][77] = 127, -+ [0][1][RTW89_ACMA][0][77] = 127, -+ [0][1][RTW89_CHILE][1][77] = 127, -+ [0][1][RTW89_QATAR][1][77] = 127, -+ [0][1][RTW89_QATAR][0][77] = 127, -+ [0][1][RTW89_UK][1][77] = 127, -+ [0][1][RTW89_UK][0][77] = 127, -+ [0][1][RTW89_FCC][1][79] = -38, -+ [0][1][RTW89_FCC][2][79] = 30, -+ [0][1][RTW89_ETSI][1][79] = 127, -+ [0][1][RTW89_ETSI][0][79] = 127, -+ [0][1][RTW89_MKK][1][79] = 127, -+ [0][1][RTW89_MKK][0][79] = 127, -+ [0][1][RTW89_IC][1][79] = -38, -+ [0][1][RTW89_KCC][1][79] = -14, -+ [0][1][RTW89_KCC][0][79] = 127, -+ [0][1][RTW89_ACMA][1][79] = 127, -+ [0][1][RTW89_ACMA][0][79] = 127, -+ [0][1][RTW89_CHILE][1][79] = 127, -+ [0][1][RTW89_QATAR][1][79] = 127, -+ [0][1][RTW89_QATAR][0][79] = 127, -+ [0][1][RTW89_UK][1][79] = 127, -+ [0][1][RTW89_UK][0][79] = 127, -+ [0][1][RTW89_FCC][1][81] = -38, -+ [0][1][RTW89_FCC][2][81] = 30, -+ [0][1][RTW89_ETSI][1][81] = 127, -+ [0][1][RTW89_ETSI][0][81] = 127, -+ [0][1][RTW89_MKK][1][81] = 127, -+ [0][1][RTW89_MKK][0][81] = 127, -+ [0][1][RTW89_IC][1][81] = -38, -+ [0][1][RTW89_KCC][1][81] = -14, -+ [0][1][RTW89_KCC][0][81] = 127, -+ [0][1][RTW89_ACMA][1][81] = 127, -+ [0][1][RTW89_ACMA][0][81] = 127, -+ [0][1][RTW89_CHILE][1][81] = 127, -+ [0][1][RTW89_QATAR][1][81] = 127, -+ [0][1][RTW89_QATAR][0][81] = 127, -+ [0][1][RTW89_UK][1][81] = 127, -+ [0][1][RTW89_UK][0][81] = 127, -+ [0][1][RTW89_FCC][1][83] = -38, -+ [0][1][RTW89_FCC][2][83] = 30, -+ [0][1][RTW89_ETSI][1][83] = 127, -+ [0][1][RTW89_ETSI][0][83] = 127, -+ [0][1][RTW89_MKK][1][83] = 127, -+ [0][1][RTW89_MKK][0][83] = 127, -+ [0][1][RTW89_IC][1][83] = -38, -+ [0][1][RTW89_KCC][1][83] = -14, -+ [0][1][RTW89_KCC][0][83] = 127, -+ [0][1][RTW89_ACMA][1][83] = 127, -+ [0][1][RTW89_ACMA][0][83] = 127, -+ [0][1][RTW89_CHILE][1][83] = 127, -+ [0][1][RTW89_QATAR][1][83] = 127, -+ [0][1][RTW89_QATAR][0][83] = 127, -+ [0][1][RTW89_UK][1][83] = 127, -+ [0][1][RTW89_UK][0][83] = 127, -+ [0][1][RTW89_FCC][1][85] = -38, -+ [0][1][RTW89_FCC][2][85] = 30, -+ [0][1][RTW89_ETSI][1][85] = 127, -+ [0][1][RTW89_ETSI][0][85] = 127, -+ [0][1][RTW89_MKK][1][85] = 127, -+ [0][1][RTW89_MKK][0][85] = 127, -+ [0][1][RTW89_IC][1][85] = -38, -+ [0][1][RTW89_KCC][1][85] = -14, -+ [0][1][RTW89_KCC][0][85] = 127, -+ [0][1][RTW89_ACMA][1][85] = 127, -+ [0][1][RTW89_ACMA][0][85] = 127, -+ [0][1][RTW89_CHILE][1][85] = 127, -+ [0][1][RTW89_QATAR][1][85] = 127, -+ [0][1][RTW89_QATAR][0][85] = 127, -+ [0][1][RTW89_UK][1][85] = 127, -+ [0][1][RTW89_UK][0][85] = 127, -+ [0][1][RTW89_FCC][1][87] = -40, -+ [0][1][RTW89_FCC][2][87] = 127, -+ [0][1][RTW89_ETSI][1][87] = 127, -+ [0][1][RTW89_ETSI][0][87] = 127, -+ [0][1][RTW89_MKK][1][87] = 127, -+ [0][1][RTW89_MKK][0][87] = 127, -+ [0][1][RTW89_IC][1][87] = -40, -+ [0][1][RTW89_KCC][1][87] = -14, -+ [0][1][RTW89_KCC][0][87] = 127, -+ [0][1][RTW89_ACMA][1][87] = 127, -+ [0][1][RTW89_ACMA][0][87] = 127, -+ [0][1][RTW89_CHILE][1][87] = 127, -+ [0][1][RTW89_QATAR][1][87] = 127, -+ [0][1][RTW89_QATAR][0][87] = 127, -+ [0][1][RTW89_UK][1][87] = 127, -+ [0][1][RTW89_UK][0][87] = 127, -+ [0][1][RTW89_FCC][1][89] = -38, -+ [0][1][RTW89_FCC][2][89] = 127, -+ [0][1][RTW89_ETSI][1][89] = 127, -+ [0][1][RTW89_ETSI][0][89] = 127, -+ [0][1][RTW89_MKK][1][89] = 127, -+ [0][1][RTW89_MKK][0][89] = 127, -+ [0][1][RTW89_IC][1][89] = -38, -+ [0][1][RTW89_KCC][1][89] = -14, -+ [0][1][RTW89_KCC][0][89] = 127, -+ [0][1][RTW89_ACMA][1][89] = 127, -+ [0][1][RTW89_ACMA][0][89] = 127, -+ [0][1][RTW89_CHILE][1][89] = 127, -+ [0][1][RTW89_QATAR][1][89] = 127, -+ [0][1][RTW89_QATAR][0][89] = 127, -+ [0][1][RTW89_UK][1][89] = 127, -+ [0][1][RTW89_UK][0][89] = 127, -+ [0][1][RTW89_FCC][1][90] = -38, -+ [0][1][RTW89_FCC][2][90] = 127, -+ [0][1][RTW89_ETSI][1][90] = 127, -+ [0][1][RTW89_ETSI][0][90] = 127, -+ [0][1][RTW89_MKK][1][90] = 127, -+ [0][1][RTW89_MKK][0][90] = 127, -+ [0][1][RTW89_IC][1][90] = -38, -+ [0][1][RTW89_KCC][1][90] = -14, -+ [0][1][RTW89_KCC][0][90] = 127, -+ [0][1][RTW89_ACMA][1][90] = 127, -+ [0][1][RTW89_ACMA][0][90] = 127, -+ [0][1][RTW89_CHILE][1][90] = 127, -+ [0][1][RTW89_QATAR][1][90] = 127, -+ [0][1][RTW89_QATAR][0][90] = 127, -+ [0][1][RTW89_UK][1][90] = 127, -+ [0][1][RTW89_UK][0][90] = 127, -+ [0][1][RTW89_FCC][1][92] = -38, -+ [0][1][RTW89_FCC][2][92] = 127, -+ [0][1][RTW89_ETSI][1][92] = 127, -+ [0][1][RTW89_ETSI][0][92] = 127, -+ [0][1][RTW89_MKK][1][92] = 127, -+ [0][1][RTW89_MKK][0][92] = 127, -+ [0][1][RTW89_IC][1][92] = -38, -+ [0][1][RTW89_KCC][1][92] = -14, -+ [0][1][RTW89_KCC][0][92] = 127, -+ [0][1][RTW89_ACMA][1][92] = 127, -+ [0][1][RTW89_ACMA][0][92] = 127, -+ [0][1][RTW89_CHILE][1][92] = 127, -+ [0][1][RTW89_QATAR][1][92] = 127, -+ [0][1][RTW89_QATAR][0][92] = 127, -+ [0][1][RTW89_UK][1][92] = 127, -+ [0][1][RTW89_UK][0][92] = 127, -+ [0][1][RTW89_FCC][1][94] = -38, -+ [0][1][RTW89_FCC][2][94] = 127, -+ [0][1][RTW89_ETSI][1][94] = 127, -+ [0][1][RTW89_ETSI][0][94] = 127, -+ [0][1][RTW89_MKK][1][94] = 127, -+ [0][1][RTW89_MKK][0][94] = 127, -+ [0][1][RTW89_IC][1][94] = -38, -+ [0][1][RTW89_KCC][1][94] = -14, -+ [0][1][RTW89_KCC][0][94] = 127, -+ [0][1][RTW89_ACMA][1][94] = 127, -+ [0][1][RTW89_ACMA][0][94] = 127, -+ [0][1][RTW89_CHILE][1][94] = 127, -+ [0][1][RTW89_QATAR][1][94] = 127, -+ [0][1][RTW89_QATAR][0][94] = 127, -+ [0][1][RTW89_UK][1][94] = 127, -+ [0][1][RTW89_UK][0][94] = 127, -+ [0][1][RTW89_FCC][1][96] = -38, -+ [0][1][RTW89_FCC][2][96] = 127, -+ [0][1][RTW89_ETSI][1][96] = 127, -+ [0][1][RTW89_ETSI][0][96] = 127, -+ [0][1][RTW89_MKK][1][96] = 127, -+ [0][1][RTW89_MKK][0][96] = 127, -+ [0][1][RTW89_IC][1][96] = -38, -+ [0][1][RTW89_KCC][1][96] = -14, -+ [0][1][RTW89_KCC][0][96] = 127, -+ [0][1][RTW89_ACMA][1][96] = 127, -+ [0][1][RTW89_ACMA][0][96] = 127, -+ [0][1][RTW89_CHILE][1][96] = 127, -+ [0][1][RTW89_QATAR][1][96] = 127, -+ [0][1][RTW89_QATAR][0][96] = 127, -+ [0][1][RTW89_UK][1][96] = 127, -+ [0][1][RTW89_UK][0][96] = 127, -+ [0][1][RTW89_FCC][1][98] = -38, -+ [0][1][RTW89_FCC][2][98] = 127, -+ [0][1][RTW89_ETSI][1][98] = 127, -+ [0][1][RTW89_ETSI][0][98] = 127, -+ [0][1][RTW89_MKK][1][98] = 127, -+ [0][1][RTW89_MKK][0][98] = 127, -+ [0][1][RTW89_IC][1][98] = -38, -+ [0][1][RTW89_KCC][1][98] = -14, -+ [0][1][RTW89_KCC][0][98] = 127, -+ [0][1][RTW89_ACMA][1][98] = 127, -+ [0][1][RTW89_ACMA][0][98] = 127, -+ [0][1][RTW89_CHILE][1][98] = 127, -+ [0][1][RTW89_QATAR][1][98] = 127, -+ [0][1][RTW89_QATAR][0][98] = 127, -+ [0][1][RTW89_UK][1][98] = 127, -+ [0][1][RTW89_UK][0][98] = 127, -+ [0][1][RTW89_FCC][1][100] = -38, -+ [0][1][RTW89_FCC][2][100] = 127, -+ [0][1][RTW89_ETSI][1][100] = 127, -+ [0][1][RTW89_ETSI][0][100] = 127, -+ [0][1][RTW89_MKK][1][100] = 127, -+ [0][1][RTW89_MKK][0][100] = 127, -+ [0][1][RTW89_IC][1][100] = -38, -+ [0][1][RTW89_KCC][1][100] = -14, -+ [0][1][RTW89_KCC][0][100] = 127, -+ [0][1][RTW89_ACMA][1][100] = 127, -+ [0][1][RTW89_ACMA][0][100] = 127, -+ [0][1][RTW89_CHILE][1][100] = 127, -+ [0][1][RTW89_QATAR][1][100] = 127, -+ [0][1][RTW89_QATAR][0][100] = 127, -+ [0][1][RTW89_UK][1][100] = 127, -+ [0][1][RTW89_UK][0][100] = 127, -+ [0][1][RTW89_FCC][1][102] = -38, -+ [0][1][RTW89_FCC][2][102] = 127, -+ [0][1][RTW89_ETSI][1][102] = 127, -+ [0][1][RTW89_ETSI][0][102] = 127, -+ [0][1][RTW89_MKK][1][102] = 127, -+ [0][1][RTW89_MKK][0][102] = 127, -+ [0][1][RTW89_IC][1][102] = -38, -+ [0][1][RTW89_KCC][1][102] = -14, -+ [0][1][RTW89_KCC][0][102] = 127, -+ [0][1][RTW89_ACMA][1][102] = 127, -+ [0][1][RTW89_ACMA][0][102] = 127, -+ [0][1][RTW89_CHILE][1][102] = 127, -+ [0][1][RTW89_QATAR][1][102] = 127, -+ [0][1][RTW89_QATAR][0][102] = 127, -+ [0][1][RTW89_UK][1][102] = 127, -+ [0][1][RTW89_UK][0][102] = 127, -+ [0][1][RTW89_FCC][1][104] = -38, -+ [0][1][RTW89_FCC][2][104] = 127, -+ [0][1][RTW89_ETSI][1][104] = 127, -+ [0][1][RTW89_ETSI][0][104] = 127, -+ [0][1][RTW89_MKK][1][104] = 127, -+ [0][1][RTW89_MKK][0][104] = 127, -+ [0][1][RTW89_IC][1][104] = -38, -+ [0][1][RTW89_KCC][1][104] = -14, -+ [0][1][RTW89_KCC][0][104] = 127, -+ [0][1][RTW89_ACMA][1][104] = 127, -+ [0][1][RTW89_ACMA][0][104] = 127, -+ [0][1][RTW89_CHILE][1][104] = 127, -+ [0][1][RTW89_QATAR][1][104] = 127, -+ [0][1][RTW89_QATAR][0][104] = 127, -+ [0][1][RTW89_UK][1][104] = 127, -+ [0][1][RTW89_UK][0][104] = 127, -+ [0][1][RTW89_FCC][1][105] = -38, -+ [0][1][RTW89_FCC][2][105] = 127, -+ [0][1][RTW89_ETSI][1][105] = 127, -+ [0][1][RTW89_ETSI][0][105] = 127, -+ [0][1][RTW89_MKK][1][105] = 127, -+ [0][1][RTW89_MKK][0][105] = 127, -+ [0][1][RTW89_IC][1][105] = -38, -+ [0][1][RTW89_KCC][1][105] = -14, -+ [0][1][RTW89_KCC][0][105] = 127, -+ [0][1][RTW89_ACMA][1][105] = 127, -+ [0][1][RTW89_ACMA][0][105] = 127, -+ [0][1][RTW89_CHILE][1][105] = 127, -+ [0][1][RTW89_QATAR][1][105] = 127, -+ [0][1][RTW89_QATAR][0][105] = 127, -+ [0][1][RTW89_UK][1][105] = 127, -+ [0][1][RTW89_UK][0][105] = 127, -+ [0][1][RTW89_FCC][1][107] = -34, -+ [0][1][RTW89_FCC][2][107] = 127, -+ [0][1][RTW89_ETSI][1][107] = 127, -+ [0][1][RTW89_ETSI][0][107] = 127, -+ [0][1][RTW89_MKK][1][107] = 127, -+ [0][1][RTW89_MKK][0][107] = 127, -+ [0][1][RTW89_IC][1][107] = -34, -+ [0][1][RTW89_KCC][1][107] = -14, -+ [0][1][RTW89_KCC][0][107] = 127, -+ [0][1][RTW89_ACMA][1][107] = 127, -+ [0][1][RTW89_ACMA][0][107] = 127, -+ [0][1][RTW89_CHILE][1][107] = 127, -+ [0][1][RTW89_QATAR][1][107] = 127, -+ [0][1][RTW89_QATAR][0][107] = 127, -+ [0][1][RTW89_UK][1][107] = 127, -+ [0][1][RTW89_UK][0][107] = 127, -+ [0][1][RTW89_FCC][1][109] = -34, -+ [0][1][RTW89_FCC][2][109] = 127, -+ [0][1][RTW89_ETSI][1][109] = 127, -+ [0][1][RTW89_ETSI][0][109] = 127, -+ [0][1][RTW89_MKK][1][109] = 127, -+ [0][1][RTW89_MKK][0][109] = 127, -+ [0][1][RTW89_IC][1][109] = -34, -+ [0][1][RTW89_KCC][1][109] = 127, -+ [0][1][RTW89_KCC][0][109] = 127, -+ [0][1][RTW89_ACMA][1][109] = 127, -+ [0][1][RTW89_ACMA][0][109] = 127, -+ [0][1][RTW89_CHILE][1][109] = 127, -+ [0][1][RTW89_QATAR][1][109] = 127, -+ [0][1][RTW89_QATAR][0][109] = 127, -+ [0][1][RTW89_UK][1][109] = 127, -+ [0][1][RTW89_UK][0][109] = 127, -+ [0][1][RTW89_FCC][1][111] = 127, -+ [0][1][RTW89_FCC][2][111] = 127, -+ [0][1][RTW89_ETSI][1][111] = 127, -+ [0][1][RTW89_ETSI][0][111] = 127, -+ [0][1][RTW89_MKK][1][111] = 127, -+ [0][1][RTW89_MKK][0][111] = 127, -+ [0][1][RTW89_IC][1][111] = 127, -+ [0][1][RTW89_KCC][1][111] = 127, -+ [0][1][RTW89_KCC][0][111] = 127, -+ [0][1][RTW89_ACMA][1][111] = 127, -+ [0][1][RTW89_ACMA][0][111] = 127, -+ [0][1][RTW89_CHILE][1][111] = 127, -+ [0][1][RTW89_QATAR][1][111] = 127, -+ [0][1][RTW89_QATAR][0][111] = 127, -+ [0][1][RTW89_UK][1][111] = 127, -+ [0][1][RTW89_UK][0][111] = 127, -+ [0][1][RTW89_FCC][1][113] = 127, -+ [0][1][RTW89_FCC][2][113] = 127, -+ [0][1][RTW89_ETSI][1][113] = 127, -+ [0][1][RTW89_ETSI][0][113] = 127, -+ [0][1][RTW89_MKK][1][113] = 127, -+ [0][1][RTW89_MKK][0][113] = 127, -+ [0][1][RTW89_IC][1][113] = 127, -+ [0][1][RTW89_KCC][1][113] = 127, -+ [0][1][RTW89_KCC][0][113] = 127, -+ [0][1][RTW89_ACMA][1][113] = 127, -+ [0][1][RTW89_ACMA][0][113] = 127, -+ [0][1][RTW89_CHILE][1][113] = 127, -+ [0][1][RTW89_QATAR][1][113] = 127, -+ [0][1][RTW89_QATAR][0][113] = 127, -+ [0][1][RTW89_UK][1][113] = 127, -+ [0][1][RTW89_UK][0][113] = 127, -+ [0][1][RTW89_FCC][1][115] = 127, -+ [0][1][RTW89_FCC][2][115] = 127, -+ [0][1][RTW89_ETSI][1][115] = 127, -+ [0][1][RTW89_ETSI][0][115] = 127, -+ [0][1][RTW89_MKK][1][115] = 127, -+ [0][1][RTW89_MKK][0][115] = 127, -+ [0][1][RTW89_IC][1][115] = 127, -+ [0][1][RTW89_KCC][1][115] = 127, -+ [0][1][RTW89_KCC][0][115] = 127, -+ [0][1][RTW89_ACMA][1][115] = 127, -+ [0][1][RTW89_ACMA][0][115] = 127, -+ [0][1][RTW89_CHILE][1][115] = 127, -+ [0][1][RTW89_QATAR][1][115] = 127, -+ [0][1][RTW89_QATAR][0][115] = 127, -+ [0][1][RTW89_UK][1][115] = 127, -+ [0][1][RTW89_UK][0][115] = 127, -+ [0][1][RTW89_FCC][1][117] = 127, -+ [0][1][RTW89_FCC][2][117] = 127, -+ [0][1][RTW89_ETSI][1][117] = 127, -+ [0][1][RTW89_ETSI][0][117] = 127, -+ [0][1][RTW89_MKK][1][117] = 127, -+ [0][1][RTW89_MKK][0][117] = 127, -+ [0][1][RTW89_IC][1][117] = 127, -+ [0][1][RTW89_KCC][1][117] = 127, -+ [0][1][RTW89_KCC][0][117] = 127, -+ [0][1][RTW89_ACMA][1][117] = 127, -+ [0][1][RTW89_ACMA][0][117] = 127, -+ [0][1][RTW89_CHILE][1][117] = 127, -+ [0][1][RTW89_QATAR][1][117] = 127, -+ [0][1][RTW89_QATAR][0][117] = 127, -+ [0][1][RTW89_UK][1][117] = 127, -+ [0][1][RTW89_UK][0][117] = 127, -+ [0][1][RTW89_FCC][1][119] = 127, -+ [0][1][RTW89_FCC][2][119] = 127, -+ [0][1][RTW89_ETSI][1][119] = 127, -+ [0][1][RTW89_ETSI][0][119] = 127, -+ [0][1][RTW89_MKK][1][119] = 127, -+ [0][1][RTW89_MKK][0][119] = 127, -+ [0][1][RTW89_IC][1][119] = 127, -+ [0][1][RTW89_KCC][1][119] = 127, -+ [0][1][RTW89_KCC][0][119] = 127, -+ [0][1][RTW89_ACMA][1][119] = 127, -+ [0][1][RTW89_ACMA][0][119] = 127, -+ [0][1][RTW89_CHILE][1][119] = 127, -+ [0][1][RTW89_QATAR][1][119] = 127, -+ [0][1][RTW89_QATAR][0][119] = 127, -+ [0][1][RTW89_UK][1][119] = 127, -+ [0][1][RTW89_UK][0][119] = 127, -+ [1][0][RTW89_FCC][1][0] = -4, -+ [1][0][RTW89_FCC][2][0] = 52, -+ [1][0][RTW89_ETSI][1][0] = 46, -+ [1][0][RTW89_ETSI][0][0] = 6, -+ [1][0][RTW89_MKK][1][0] = 42, -+ [1][0][RTW89_MKK][0][0] = 2, -+ [1][0][RTW89_IC][1][0] = -4, -+ [1][0][RTW89_KCC][1][0] = -2, -+ [1][0][RTW89_KCC][0][0] = -2, -+ [1][0][RTW89_ACMA][1][0] = 46, -+ [1][0][RTW89_ACMA][0][0] = 6, -+ [1][0][RTW89_CHILE][1][0] = -4, -+ [1][0][RTW89_QATAR][1][0] = 46, -+ [1][0][RTW89_QATAR][0][0] = 6, -+ [1][0][RTW89_UK][1][0] = 46, -+ [1][0][RTW89_UK][0][0] = 6, -+ [1][0][RTW89_FCC][1][2] = -4, -+ [1][0][RTW89_FCC][2][2] = 52, -+ [1][0][RTW89_ETSI][1][2] = 46, -+ [1][0][RTW89_ETSI][0][2] = 6, -+ [1][0][RTW89_MKK][1][2] = 42, -+ [1][0][RTW89_MKK][0][2] = 2, -+ [1][0][RTW89_IC][1][2] = -4, -+ [1][0][RTW89_KCC][1][2] = -2, -+ [1][0][RTW89_KCC][0][2] = -2, -+ [1][0][RTW89_ACMA][1][2] = 46, -+ [1][0][RTW89_ACMA][0][2] = 6, -+ [1][0][RTW89_CHILE][1][2] = -4, -+ [1][0][RTW89_QATAR][1][2] = 46, -+ [1][0][RTW89_QATAR][0][2] = 6, -+ [1][0][RTW89_UK][1][2] = 46, -+ [1][0][RTW89_UK][0][2] = 6, -+ [1][0][RTW89_FCC][1][4] = -4, -+ [1][0][RTW89_FCC][2][4] = 52, -+ [1][0][RTW89_ETSI][1][4] = 46, -+ [1][0][RTW89_ETSI][0][4] = 6, -+ [1][0][RTW89_MKK][1][4] = 42, -+ [1][0][RTW89_MKK][0][4] = 2, -+ [1][0][RTW89_IC][1][4] = -4, -+ [1][0][RTW89_KCC][1][4] = -2, -+ [1][0][RTW89_KCC][0][4] = -2, -+ [1][0][RTW89_ACMA][1][4] = 46, -+ [1][0][RTW89_ACMA][0][4] = 6, -+ [1][0][RTW89_CHILE][1][4] = -4, -+ [1][0][RTW89_QATAR][1][4] = 46, -+ [1][0][RTW89_QATAR][0][4] = 6, -+ [1][0][RTW89_UK][1][4] = 46, -+ [1][0][RTW89_UK][0][4] = 6, -+ [1][0][RTW89_FCC][1][6] = -4, -+ [1][0][RTW89_FCC][2][6] = 52, -+ [1][0][RTW89_ETSI][1][6] = 46, -+ [1][0][RTW89_ETSI][0][6] = 6, -+ [1][0][RTW89_MKK][1][6] = 42, -+ [1][0][RTW89_MKK][0][6] = 2, -+ [1][0][RTW89_IC][1][6] = -4, -+ [1][0][RTW89_KCC][1][6] = -2, -+ [1][0][RTW89_KCC][0][6] = -2, -+ [1][0][RTW89_ACMA][1][6] = 46, -+ [1][0][RTW89_ACMA][0][6] = 6, -+ [1][0][RTW89_CHILE][1][6] = -4, -+ [1][0][RTW89_QATAR][1][6] = 46, -+ [1][0][RTW89_QATAR][0][6] = 6, -+ [1][0][RTW89_UK][1][6] = 46, -+ [1][0][RTW89_UK][0][6] = 6, -+ [1][0][RTW89_FCC][1][8] = -4, -+ [1][0][RTW89_FCC][2][8] = 52, -+ [1][0][RTW89_ETSI][1][8] = 46, -+ [1][0][RTW89_ETSI][0][8] = 6, -+ [1][0][RTW89_MKK][1][8] = 42, -+ [1][0][RTW89_MKK][0][8] = 2, -+ [1][0][RTW89_IC][1][8] = -4, -+ [1][0][RTW89_KCC][1][8] = -2, -+ [1][0][RTW89_KCC][0][8] = -2, -+ [1][0][RTW89_ACMA][1][8] = 46, -+ [1][0][RTW89_ACMA][0][8] = 6, -+ [1][0][RTW89_CHILE][1][8] = -4, -+ [1][0][RTW89_QATAR][1][8] = 46, -+ [1][0][RTW89_QATAR][0][8] = 6, -+ [1][0][RTW89_UK][1][8] = 46, -+ [1][0][RTW89_UK][0][8] = 6, -+ [1][0][RTW89_FCC][1][10] = -4, -+ [1][0][RTW89_FCC][2][10] = 52, -+ [1][0][RTW89_ETSI][1][10] = 46, -+ [1][0][RTW89_ETSI][0][10] = 6, -+ [1][0][RTW89_MKK][1][10] = 42, -+ [1][0][RTW89_MKK][0][10] = 2, -+ [1][0][RTW89_IC][1][10] = -4, -+ [1][0][RTW89_KCC][1][10] = -2, -+ [1][0][RTW89_KCC][0][10] = -2, -+ [1][0][RTW89_ACMA][1][10] = 46, -+ [1][0][RTW89_ACMA][0][10] = 6, -+ [1][0][RTW89_CHILE][1][10] = -4, -+ [1][0][RTW89_QATAR][1][10] = 46, -+ [1][0][RTW89_QATAR][0][10] = 6, -+ [1][0][RTW89_UK][1][10] = 46, -+ [1][0][RTW89_UK][0][10] = 6, -+ [1][0][RTW89_FCC][1][12] = -4, -+ [1][0][RTW89_FCC][2][12] = 52, -+ [1][0][RTW89_ETSI][1][12] = 46, -+ [1][0][RTW89_ETSI][0][12] = 6, -+ [1][0][RTW89_MKK][1][12] = 42, -+ [1][0][RTW89_MKK][0][12] = 2, -+ [1][0][RTW89_IC][1][12] = -4, -+ [1][0][RTW89_KCC][1][12] = -2, -+ [1][0][RTW89_KCC][0][12] = -2, -+ [1][0][RTW89_ACMA][1][12] = 46, -+ [1][0][RTW89_ACMA][0][12] = 6, -+ [1][0][RTW89_CHILE][1][12] = -4, -+ [1][0][RTW89_QATAR][1][12] = 46, -+ [1][0][RTW89_QATAR][0][12] = 6, -+ [1][0][RTW89_UK][1][12] = 46, -+ [1][0][RTW89_UK][0][12] = 6, -+ [1][0][RTW89_FCC][1][14] = -4, -+ [1][0][RTW89_FCC][2][14] = 52, -+ [1][0][RTW89_ETSI][1][14] = 46, -+ [1][0][RTW89_ETSI][0][14] = 6, -+ [1][0][RTW89_MKK][1][14] = 42, -+ [1][0][RTW89_MKK][0][14] = 2, -+ [1][0][RTW89_IC][1][14] = -4, -+ [1][0][RTW89_KCC][1][14] = -2, -+ [1][0][RTW89_KCC][0][14] = -2, -+ [1][0][RTW89_ACMA][1][14] = 46, -+ [1][0][RTW89_ACMA][0][14] = 6, -+ [1][0][RTW89_CHILE][1][14] = -4, -+ [1][0][RTW89_QATAR][1][14] = 46, -+ [1][0][RTW89_QATAR][0][14] = 6, -+ [1][0][RTW89_UK][1][14] = 46, -+ [1][0][RTW89_UK][0][14] = 6, -+ [1][0][RTW89_FCC][1][15] = -4, -+ [1][0][RTW89_FCC][2][15] = 52, -+ [1][0][RTW89_ETSI][1][15] = 46, -+ [1][0][RTW89_ETSI][0][15] = 6, -+ [1][0][RTW89_MKK][1][15] = 42, -+ [1][0][RTW89_MKK][0][15] = 2, -+ [1][0][RTW89_IC][1][15] = -4, -+ [1][0][RTW89_KCC][1][15] = -2, -+ [1][0][RTW89_KCC][0][15] = -2, -+ [1][0][RTW89_ACMA][1][15] = 46, -+ [1][0][RTW89_ACMA][0][15] = 6, -+ [1][0][RTW89_CHILE][1][15] = -4, -+ [1][0][RTW89_QATAR][1][15] = 46, -+ [1][0][RTW89_QATAR][0][15] = 6, -+ [1][0][RTW89_UK][1][15] = 46, -+ [1][0][RTW89_UK][0][15] = 6, -+ [1][0][RTW89_FCC][1][17] = -4, -+ [1][0][RTW89_FCC][2][17] = 52, -+ [1][0][RTW89_ETSI][1][17] = 46, -+ [1][0][RTW89_ETSI][0][17] = 6, -+ [1][0][RTW89_MKK][1][17] = 42, -+ [1][0][RTW89_MKK][0][17] = 2, -+ [1][0][RTW89_IC][1][17] = -4, -+ [1][0][RTW89_KCC][1][17] = -2, -+ [1][0][RTW89_KCC][0][17] = -2, -+ [1][0][RTW89_ACMA][1][17] = 46, -+ [1][0][RTW89_ACMA][0][17] = 6, -+ [1][0][RTW89_CHILE][1][17] = -4, -+ [1][0][RTW89_QATAR][1][17] = 46, -+ [1][0][RTW89_QATAR][0][17] = 6, -+ [1][0][RTW89_UK][1][17] = 46, -+ [1][0][RTW89_UK][0][17] = 6, -+ [1][0][RTW89_FCC][1][19] = -4, -+ [1][0][RTW89_FCC][2][19] = 52, -+ [1][0][RTW89_ETSI][1][19] = 46, -+ [1][0][RTW89_ETSI][0][19] = 6, -+ [1][0][RTW89_MKK][1][19] = 42, -+ [1][0][RTW89_MKK][0][19] = 2, -+ [1][0][RTW89_IC][1][19] = -4, -+ [1][0][RTW89_KCC][1][19] = -2, -+ [1][0][RTW89_KCC][0][19] = -2, -+ [1][0][RTW89_ACMA][1][19] = 46, -+ [1][0][RTW89_ACMA][0][19] = 6, -+ [1][0][RTW89_CHILE][1][19] = -4, -+ [1][0][RTW89_QATAR][1][19] = 46, -+ [1][0][RTW89_QATAR][0][19] = 6, -+ [1][0][RTW89_UK][1][19] = 46, -+ [1][0][RTW89_UK][0][19] = 6, -+ [1][0][RTW89_FCC][1][21] = -4, -+ [1][0][RTW89_FCC][2][21] = 52, -+ [1][0][RTW89_ETSI][1][21] = 46, -+ [1][0][RTW89_ETSI][0][21] = 6, -+ [1][0][RTW89_MKK][1][21] = 42, -+ [1][0][RTW89_MKK][0][21] = 2, -+ [1][0][RTW89_IC][1][21] = -4, -+ [1][0][RTW89_KCC][1][21] = -2, -+ [1][0][RTW89_KCC][0][21] = -2, -+ [1][0][RTW89_ACMA][1][21] = 46, -+ [1][0][RTW89_ACMA][0][21] = 6, -+ [1][0][RTW89_CHILE][1][21] = -4, -+ [1][0][RTW89_QATAR][1][21] = 46, -+ [1][0][RTW89_QATAR][0][21] = 6, -+ [1][0][RTW89_UK][1][21] = 46, -+ [1][0][RTW89_UK][0][21] = 6, -+ [1][0][RTW89_FCC][1][23] = -4, -+ [1][0][RTW89_FCC][2][23] = 66, -+ [1][0][RTW89_ETSI][1][23] = 46, -+ [1][0][RTW89_ETSI][0][23] = 6, -+ [1][0][RTW89_MKK][1][23] = 42, -+ [1][0][RTW89_MKK][0][23] = 2, -+ [1][0][RTW89_IC][1][23] = -4, -+ [1][0][RTW89_KCC][1][23] = -2, -+ [1][0][RTW89_KCC][0][23] = -2, -+ [1][0][RTW89_ACMA][1][23] = 46, -+ [1][0][RTW89_ACMA][0][23] = 6, -+ [1][0][RTW89_CHILE][1][23] = -4, -+ [1][0][RTW89_QATAR][1][23] = 46, -+ [1][0][RTW89_QATAR][0][23] = 6, -+ [1][0][RTW89_UK][1][23] = 46, -+ [1][0][RTW89_UK][0][23] = 6, -+ [1][0][RTW89_FCC][1][25] = -4, -+ [1][0][RTW89_FCC][2][25] = 66, -+ [1][0][RTW89_ETSI][1][25] = 46, -+ [1][0][RTW89_ETSI][0][25] = 6, -+ [1][0][RTW89_MKK][1][25] = 42, -+ [1][0][RTW89_MKK][0][25] = 2, -+ [1][0][RTW89_IC][1][25] = -4, -+ [1][0][RTW89_KCC][1][25] = -2, -+ [1][0][RTW89_KCC][0][25] = -2, -+ [1][0][RTW89_ACMA][1][25] = 46, -+ [1][0][RTW89_ACMA][0][25] = 6, -+ [1][0][RTW89_CHILE][1][25] = -4, -+ [1][0][RTW89_QATAR][1][25] = 46, -+ [1][0][RTW89_QATAR][0][25] = 6, -+ [1][0][RTW89_UK][1][25] = 46, -+ [1][0][RTW89_UK][0][25] = 6, -+ [1][0][RTW89_FCC][1][27] = -4, -+ [1][0][RTW89_FCC][2][27] = 66, -+ [1][0][RTW89_ETSI][1][27] = 46, -+ [1][0][RTW89_ETSI][0][27] = 6, -+ [1][0][RTW89_MKK][1][27] = 42, -+ [1][0][RTW89_MKK][0][27] = 2, -+ [1][0][RTW89_IC][1][27] = -4, -+ [1][0][RTW89_KCC][1][27] = -2, -+ [1][0][RTW89_KCC][0][27] = -2, -+ [1][0][RTW89_ACMA][1][27] = 46, -+ [1][0][RTW89_ACMA][0][27] = 6, -+ [1][0][RTW89_CHILE][1][27] = -4, -+ [1][0][RTW89_QATAR][1][27] = 46, -+ [1][0][RTW89_QATAR][0][27] = 6, -+ [1][0][RTW89_UK][1][27] = 46, -+ [1][0][RTW89_UK][0][27] = 6, -+ [1][0][RTW89_FCC][1][29] = -4, -+ [1][0][RTW89_FCC][2][29] = 66, -+ [1][0][RTW89_ETSI][1][29] = 46, -+ [1][0][RTW89_ETSI][0][29] = 6, -+ [1][0][RTW89_MKK][1][29] = 42, -+ [1][0][RTW89_MKK][0][29] = 2, -+ [1][0][RTW89_IC][1][29] = -4, -+ [1][0][RTW89_KCC][1][29] = -2, -+ [1][0][RTW89_KCC][0][29] = -2, -+ [1][0][RTW89_ACMA][1][29] = 46, -+ [1][0][RTW89_ACMA][0][29] = 6, -+ [1][0][RTW89_CHILE][1][29] = -4, -+ [1][0][RTW89_QATAR][1][29] = 46, -+ [1][0][RTW89_QATAR][0][29] = 6, -+ [1][0][RTW89_UK][1][29] = 46, -+ [1][0][RTW89_UK][0][29] = 6, -+ [1][0][RTW89_FCC][1][30] = -4, -+ [1][0][RTW89_FCC][2][30] = 66, -+ [1][0][RTW89_ETSI][1][30] = 46, -+ [1][0][RTW89_ETSI][0][30] = 6, -+ [1][0][RTW89_MKK][1][30] = 42, -+ [1][0][RTW89_MKK][0][30] = 2, -+ [1][0][RTW89_IC][1][30] = -4, -+ [1][0][RTW89_KCC][1][30] = -2, -+ [1][0][RTW89_KCC][0][30] = -2, -+ [1][0][RTW89_ACMA][1][30] = 46, -+ [1][0][RTW89_ACMA][0][30] = 6, -+ [1][0][RTW89_CHILE][1][30] = -4, -+ [1][0][RTW89_QATAR][1][30] = 46, -+ [1][0][RTW89_QATAR][0][30] = 6, -+ [1][0][RTW89_UK][1][30] = 46, -+ [1][0][RTW89_UK][0][30] = 6, -+ [1][0][RTW89_FCC][1][32] = -4, -+ [1][0][RTW89_FCC][2][32] = 66, -+ [1][0][RTW89_ETSI][1][32] = 46, -+ [1][0][RTW89_ETSI][0][32] = 6, -+ [1][0][RTW89_MKK][1][32] = 42, -+ [1][0][RTW89_MKK][0][32] = 2, -+ [1][0][RTW89_IC][1][32] = -4, -+ [1][0][RTW89_KCC][1][32] = -2, -+ [1][0][RTW89_KCC][0][32] = -2, -+ [1][0][RTW89_ACMA][1][32] = 46, -+ [1][0][RTW89_ACMA][0][32] = 6, -+ [1][0][RTW89_CHILE][1][32] = -4, -+ [1][0][RTW89_QATAR][1][32] = 46, -+ [1][0][RTW89_QATAR][0][32] = 6, -+ [1][0][RTW89_UK][1][32] = 46, -+ [1][0][RTW89_UK][0][32] = 6, -+ [1][0][RTW89_FCC][1][34] = -4, -+ [1][0][RTW89_FCC][2][34] = 66, -+ [1][0][RTW89_ETSI][1][34] = 46, -+ [1][0][RTW89_ETSI][0][34] = 6, -+ [1][0][RTW89_MKK][1][34] = 42, -+ [1][0][RTW89_MKK][0][34] = 2, -+ [1][0][RTW89_IC][1][34] = -4, -+ [1][0][RTW89_KCC][1][34] = -2, -+ [1][0][RTW89_KCC][0][34] = -2, -+ [1][0][RTW89_ACMA][1][34] = 46, -+ [1][0][RTW89_ACMA][0][34] = 6, -+ [1][0][RTW89_CHILE][1][34] = -4, -+ [1][0][RTW89_QATAR][1][34] = 46, -+ [1][0][RTW89_QATAR][0][34] = 6, -+ [1][0][RTW89_UK][1][34] = 46, -+ [1][0][RTW89_UK][0][34] = 6, -+ [1][0][RTW89_FCC][1][36] = -4, -+ [1][0][RTW89_FCC][2][36] = 66, -+ [1][0][RTW89_ETSI][1][36] = 46, -+ [1][0][RTW89_ETSI][0][36] = 6, -+ [1][0][RTW89_MKK][1][36] = 42, -+ [1][0][RTW89_MKK][0][36] = 2, -+ [1][0][RTW89_IC][1][36] = -4, -+ [1][0][RTW89_KCC][1][36] = -2, -+ [1][0][RTW89_KCC][0][36] = -2, -+ [1][0][RTW89_ACMA][1][36] = 46, -+ [1][0][RTW89_ACMA][0][36] = 6, -+ [1][0][RTW89_CHILE][1][36] = -4, -+ [1][0][RTW89_QATAR][1][36] = 46, -+ [1][0][RTW89_QATAR][0][36] = 6, -+ [1][0][RTW89_UK][1][36] = 46, -+ [1][0][RTW89_UK][0][36] = 6, -+ [1][0][RTW89_FCC][1][38] = -4, -+ [1][0][RTW89_FCC][2][38] = 66, -+ [1][0][RTW89_ETSI][1][38] = 46, -+ [1][0][RTW89_ETSI][0][38] = 6, -+ [1][0][RTW89_MKK][1][38] = 42, -+ [1][0][RTW89_MKK][0][38] = 2, -+ [1][0][RTW89_IC][1][38] = -4, -+ [1][0][RTW89_KCC][1][38] = -2, -+ [1][0][RTW89_KCC][0][38] = -2, -+ [1][0][RTW89_ACMA][1][38] = 46, -+ [1][0][RTW89_ACMA][0][38] = 6, -+ [1][0][RTW89_CHILE][1][38] = -4, -+ [1][0][RTW89_QATAR][1][38] = 46, -+ [1][0][RTW89_QATAR][0][38] = 6, -+ [1][0][RTW89_UK][1][38] = 46, -+ [1][0][RTW89_UK][0][38] = 6, -+ [1][0][RTW89_FCC][1][40] = -4, -+ [1][0][RTW89_FCC][2][40] = 66, -+ [1][0][RTW89_ETSI][1][40] = 46, -+ [1][0][RTW89_ETSI][0][40] = 6, -+ [1][0][RTW89_MKK][1][40] = 42, -+ [1][0][RTW89_MKK][0][40] = 2, -+ [1][0][RTW89_IC][1][40] = -4, -+ [1][0][RTW89_KCC][1][40] = -2, -+ [1][0][RTW89_KCC][0][40] = -2, -+ [1][0][RTW89_ACMA][1][40] = 46, -+ [1][0][RTW89_ACMA][0][40] = 6, -+ [1][0][RTW89_CHILE][1][40] = -4, -+ [1][0][RTW89_QATAR][1][40] = 46, -+ [1][0][RTW89_QATAR][0][40] = 6, -+ [1][0][RTW89_UK][1][40] = 46, -+ [1][0][RTW89_UK][0][40] = 6, -+ [1][0][RTW89_FCC][1][42] = -4, -+ [1][0][RTW89_FCC][2][42] = 66, -+ [1][0][RTW89_ETSI][1][42] = 46, -+ [1][0][RTW89_ETSI][0][42] = 6, -+ [1][0][RTW89_MKK][1][42] = 42, -+ [1][0][RTW89_MKK][0][42] = 2, -+ [1][0][RTW89_IC][1][42] = -4, -+ [1][0][RTW89_KCC][1][42] = -2, -+ [1][0][RTW89_KCC][0][42] = -2, -+ [1][0][RTW89_ACMA][1][42] = 46, -+ [1][0][RTW89_ACMA][0][42] = 6, -+ [1][0][RTW89_CHILE][1][42] = -4, -+ [1][0][RTW89_QATAR][1][42] = 46, -+ [1][0][RTW89_QATAR][0][42] = 6, -+ [1][0][RTW89_UK][1][42] = 46, -+ [1][0][RTW89_UK][0][42] = 6, -+ [1][0][RTW89_FCC][1][44] = -4, -+ [1][0][RTW89_FCC][2][44] = 66, -+ [1][0][RTW89_ETSI][1][44] = 46, -+ [1][0][RTW89_ETSI][0][44] = 8, -+ [1][0][RTW89_MKK][1][44] = 22, -+ [1][0][RTW89_MKK][0][44] = 4, -+ [1][0][RTW89_IC][1][44] = -4, -+ [1][0][RTW89_KCC][1][44] = -2, -+ [1][0][RTW89_KCC][0][44] = -2, -+ [1][0][RTW89_ACMA][1][44] = 46, -+ [1][0][RTW89_ACMA][0][44] = 8, -+ [1][0][RTW89_CHILE][1][44] = -4, -+ [1][0][RTW89_QATAR][1][44] = 46, -+ [1][0][RTW89_QATAR][0][44] = 8, -+ [1][0][RTW89_UK][1][44] = 46, -+ [1][0][RTW89_UK][0][44] = 8, -+ [1][0][RTW89_FCC][1][45] = -4, -+ [1][0][RTW89_FCC][2][45] = 127, -+ [1][0][RTW89_ETSI][1][45] = 127, -+ [1][0][RTW89_ETSI][0][45] = 127, -+ [1][0][RTW89_MKK][1][45] = 127, -+ [1][0][RTW89_MKK][0][45] = 127, -+ [1][0][RTW89_IC][1][45] = -4, -+ [1][0][RTW89_KCC][1][45] = -2, -+ [1][0][RTW89_KCC][0][45] = 127, -+ [1][0][RTW89_ACMA][1][45] = 127, -+ [1][0][RTW89_ACMA][0][45] = 127, -+ [1][0][RTW89_CHILE][1][45] = 127, -+ [1][0][RTW89_QATAR][1][45] = 127, -+ [1][0][RTW89_QATAR][0][45] = 127, -+ [1][0][RTW89_UK][1][45] = 127, -+ [1][0][RTW89_UK][0][45] = 127, -+ [1][0][RTW89_FCC][1][47] = -4, -+ [1][0][RTW89_FCC][2][47] = 127, -+ [1][0][RTW89_ETSI][1][47] = 127, -+ [1][0][RTW89_ETSI][0][47] = 127, -+ [1][0][RTW89_MKK][1][47] = 127, -+ [1][0][RTW89_MKK][0][47] = 127, -+ [1][0][RTW89_IC][1][47] = -4, -+ [1][0][RTW89_KCC][1][47] = -2, -+ [1][0][RTW89_KCC][0][47] = 127, -+ [1][0][RTW89_ACMA][1][47] = 127, -+ [1][0][RTW89_ACMA][0][47] = 127, -+ [1][0][RTW89_CHILE][1][47] = 127, -+ [1][0][RTW89_QATAR][1][47] = 127, -+ [1][0][RTW89_QATAR][0][47] = 127, -+ [1][0][RTW89_UK][1][47] = 127, -+ [1][0][RTW89_UK][0][47] = 127, -+ [1][0][RTW89_FCC][1][49] = -4, -+ [1][0][RTW89_FCC][2][49] = 127, -+ [1][0][RTW89_ETSI][1][49] = 127, -+ [1][0][RTW89_ETSI][0][49] = 127, -+ [1][0][RTW89_MKK][1][49] = 127, -+ [1][0][RTW89_MKK][0][49] = 127, -+ [1][0][RTW89_IC][1][49] = -4, -+ [1][0][RTW89_KCC][1][49] = -2, -+ [1][0][RTW89_KCC][0][49] = 127, -+ [1][0][RTW89_ACMA][1][49] = 127, -+ [1][0][RTW89_ACMA][0][49] = 127, -+ [1][0][RTW89_CHILE][1][49] = 127, -+ [1][0][RTW89_QATAR][1][49] = 127, -+ [1][0][RTW89_QATAR][0][49] = 127, -+ [1][0][RTW89_UK][1][49] = 127, -+ [1][0][RTW89_UK][0][49] = 127, -+ [1][0][RTW89_FCC][1][51] = -4, -+ [1][0][RTW89_FCC][2][51] = 127, -+ [1][0][RTW89_ETSI][1][51] = 127, -+ [1][0][RTW89_ETSI][0][51] = 127, -+ [1][0][RTW89_MKK][1][51] = 127, -+ [1][0][RTW89_MKK][0][51] = 127, -+ [1][0][RTW89_IC][1][51] = -4, -+ [1][0][RTW89_KCC][1][51] = -2, -+ [1][0][RTW89_KCC][0][51] = 127, -+ [1][0][RTW89_ACMA][1][51] = 127, -+ [1][0][RTW89_ACMA][0][51] = 127, -+ [1][0][RTW89_CHILE][1][51] = 127, -+ [1][0][RTW89_QATAR][1][51] = 127, -+ [1][0][RTW89_QATAR][0][51] = 127, -+ [1][0][RTW89_UK][1][51] = 127, -+ [1][0][RTW89_UK][0][51] = 127, -+ [1][0][RTW89_FCC][1][53] = -4, -+ [1][0][RTW89_FCC][2][53] = 127, -+ [1][0][RTW89_ETSI][1][53] = 127, -+ [1][0][RTW89_ETSI][0][53] = 127, -+ [1][0][RTW89_MKK][1][53] = 127, -+ [1][0][RTW89_MKK][0][53] = 127, -+ [1][0][RTW89_IC][1][53] = -4, -+ [1][0][RTW89_KCC][1][53] = -2, -+ [1][0][RTW89_KCC][0][53] = 127, -+ [1][0][RTW89_ACMA][1][53] = 127, -+ [1][0][RTW89_ACMA][0][53] = 127, -+ [1][0][RTW89_CHILE][1][53] = 127, -+ [1][0][RTW89_QATAR][1][53] = 127, -+ [1][0][RTW89_QATAR][0][53] = 127, -+ [1][0][RTW89_UK][1][53] = 127, -+ [1][0][RTW89_UK][0][53] = 127, -+ [1][0][RTW89_FCC][1][55] = -4, -+ [1][0][RTW89_FCC][2][55] = 68, -+ [1][0][RTW89_ETSI][1][55] = 127, -+ [1][0][RTW89_ETSI][0][55] = 127, -+ [1][0][RTW89_MKK][1][55] = 127, -+ [1][0][RTW89_MKK][0][55] = 127, -+ [1][0][RTW89_IC][1][55] = -4, -+ [1][0][RTW89_KCC][1][55] = -2, -+ [1][0][RTW89_KCC][0][55] = 127, -+ [1][0][RTW89_ACMA][1][55] = 127, -+ [1][0][RTW89_ACMA][0][55] = 127, -+ [1][0][RTW89_CHILE][1][55] = 127, -+ [1][0][RTW89_QATAR][1][55] = 127, -+ [1][0][RTW89_QATAR][0][55] = 127, -+ [1][0][RTW89_UK][1][55] = 127, -+ [1][0][RTW89_UK][0][55] = 127, -+ [1][0][RTW89_FCC][1][57] = -4, -+ [1][0][RTW89_FCC][2][57] = 68, -+ [1][0][RTW89_ETSI][1][57] = 127, -+ [1][0][RTW89_ETSI][0][57] = 127, -+ [1][0][RTW89_MKK][1][57] = 127, -+ [1][0][RTW89_MKK][0][57] = 127, -+ [1][0][RTW89_IC][1][57] = -4, -+ [1][0][RTW89_KCC][1][57] = -2, -+ [1][0][RTW89_KCC][0][57] = 127, -+ [1][0][RTW89_ACMA][1][57] = 127, -+ [1][0][RTW89_ACMA][0][57] = 127, -+ [1][0][RTW89_CHILE][1][57] = 127, -+ [1][0][RTW89_QATAR][1][57] = 127, -+ [1][0][RTW89_QATAR][0][57] = 127, -+ [1][0][RTW89_UK][1][57] = 127, -+ [1][0][RTW89_UK][0][57] = 127, -+ [1][0][RTW89_FCC][1][59] = -4, -+ [1][0][RTW89_FCC][2][59] = 68, -+ [1][0][RTW89_ETSI][1][59] = 127, -+ [1][0][RTW89_ETSI][0][59] = 127, -+ [1][0][RTW89_MKK][1][59] = 127, -+ [1][0][RTW89_MKK][0][59] = 127, -+ [1][0][RTW89_IC][1][59] = -4, -+ [1][0][RTW89_KCC][1][59] = -2, -+ [1][0][RTW89_KCC][0][59] = 127, -+ [1][0][RTW89_ACMA][1][59] = 127, -+ [1][0][RTW89_ACMA][0][59] = 127, -+ [1][0][RTW89_CHILE][1][59] = 127, -+ [1][0][RTW89_QATAR][1][59] = 127, -+ [1][0][RTW89_QATAR][0][59] = 127, -+ [1][0][RTW89_UK][1][59] = 127, -+ [1][0][RTW89_UK][0][59] = 127, -+ [1][0][RTW89_FCC][1][60] = -4, -+ [1][0][RTW89_FCC][2][60] = 68, -+ [1][0][RTW89_ETSI][1][60] = 127, -+ [1][0][RTW89_ETSI][0][60] = 127, -+ [1][0][RTW89_MKK][1][60] = 127, -+ [1][0][RTW89_MKK][0][60] = 127, -+ [1][0][RTW89_IC][1][60] = -4, -+ [1][0][RTW89_KCC][1][60] = -2, -+ [1][0][RTW89_KCC][0][60] = 127, -+ [1][0][RTW89_ACMA][1][60] = 127, -+ [1][0][RTW89_ACMA][0][60] = 127, -+ [1][0][RTW89_CHILE][1][60] = 127, -+ [1][0][RTW89_QATAR][1][60] = 127, -+ [1][0][RTW89_QATAR][0][60] = 127, -+ [1][0][RTW89_UK][1][60] = 127, -+ [1][0][RTW89_UK][0][60] = 127, -+ [1][0][RTW89_FCC][1][62] = -4, -+ [1][0][RTW89_FCC][2][62] = 68, -+ [1][0][RTW89_ETSI][1][62] = 127, -+ [1][0][RTW89_ETSI][0][62] = 127, -+ [1][0][RTW89_MKK][1][62] = 127, -+ [1][0][RTW89_MKK][0][62] = 127, -+ [1][0][RTW89_IC][1][62] = -4, -+ [1][0][RTW89_KCC][1][62] = -2, -+ [1][0][RTW89_KCC][0][62] = 127, -+ [1][0][RTW89_ACMA][1][62] = 127, -+ [1][0][RTW89_ACMA][0][62] = 127, -+ [1][0][RTW89_CHILE][1][62] = 127, -+ [1][0][RTW89_QATAR][1][62] = 127, -+ [1][0][RTW89_QATAR][0][62] = 127, -+ [1][0][RTW89_UK][1][62] = 127, -+ [1][0][RTW89_UK][0][62] = 127, -+ [1][0][RTW89_FCC][1][64] = -4, -+ [1][0][RTW89_FCC][2][64] = 68, -+ [1][0][RTW89_ETSI][1][64] = 127, -+ [1][0][RTW89_ETSI][0][64] = 127, -+ [1][0][RTW89_MKK][1][64] = 127, -+ [1][0][RTW89_MKK][0][64] = 127, -+ [1][0][RTW89_IC][1][64] = -4, -+ [1][0][RTW89_KCC][1][64] = -2, -+ [1][0][RTW89_KCC][0][64] = 127, -+ [1][0][RTW89_ACMA][1][64] = 127, -+ [1][0][RTW89_ACMA][0][64] = 127, -+ [1][0][RTW89_CHILE][1][64] = 127, -+ [1][0][RTW89_QATAR][1][64] = 127, -+ [1][0][RTW89_QATAR][0][64] = 127, -+ [1][0][RTW89_UK][1][64] = 127, -+ [1][0][RTW89_UK][0][64] = 127, -+ [1][0][RTW89_FCC][1][66] = -4, -+ [1][0][RTW89_FCC][2][66] = 68, -+ [1][0][RTW89_ETSI][1][66] = 127, -+ [1][0][RTW89_ETSI][0][66] = 127, -+ [1][0][RTW89_MKK][1][66] = 127, -+ [1][0][RTW89_MKK][0][66] = 127, -+ [1][0][RTW89_IC][1][66] = -4, -+ [1][0][RTW89_KCC][1][66] = -2, -+ [1][0][RTW89_KCC][0][66] = 127, -+ [1][0][RTW89_ACMA][1][66] = 127, -+ [1][0][RTW89_ACMA][0][66] = 127, -+ [1][0][RTW89_CHILE][1][66] = 127, -+ [1][0][RTW89_QATAR][1][66] = 127, -+ [1][0][RTW89_QATAR][0][66] = 127, -+ [1][0][RTW89_UK][1][66] = 127, -+ [1][0][RTW89_UK][0][66] = 127, -+ [1][0][RTW89_FCC][1][68] = -4, -+ [1][0][RTW89_FCC][2][68] = 68, -+ [1][0][RTW89_ETSI][1][68] = 127, -+ [1][0][RTW89_ETSI][0][68] = 127, -+ [1][0][RTW89_MKK][1][68] = 127, -+ [1][0][RTW89_MKK][0][68] = 127, -+ [1][0][RTW89_IC][1][68] = -4, -+ [1][0][RTW89_KCC][1][68] = -2, -+ [1][0][RTW89_KCC][0][68] = 127, -+ [1][0][RTW89_ACMA][1][68] = 127, -+ [1][0][RTW89_ACMA][0][68] = 127, -+ [1][0][RTW89_CHILE][1][68] = 127, -+ [1][0][RTW89_QATAR][1][68] = 127, -+ [1][0][RTW89_QATAR][0][68] = 127, -+ [1][0][RTW89_UK][1][68] = 127, -+ [1][0][RTW89_UK][0][68] = 127, -+ [1][0][RTW89_FCC][1][70] = -4, -+ [1][0][RTW89_FCC][2][70] = 68, -+ [1][0][RTW89_ETSI][1][70] = 127, -+ [1][0][RTW89_ETSI][0][70] = 127, -+ [1][0][RTW89_MKK][1][70] = 127, -+ [1][0][RTW89_MKK][0][70] = 127, -+ [1][0][RTW89_IC][1][70] = -4, -+ [1][0][RTW89_KCC][1][70] = -2, -+ [1][0][RTW89_KCC][0][70] = 127, -+ [1][0][RTW89_ACMA][1][70] = 127, -+ [1][0][RTW89_ACMA][0][70] = 127, -+ [1][0][RTW89_CHILE][1][70] = 127, -+ [1][0][RTW89_QATAR][1][70] = 127, -+ [1][0][RTW89_QATAR][0][70] = 127, -+ [1][0][RTW89_UK][1][70] = 127, -+ [1][0][RTW89_UK][0][70] = 127, -+ [1][0][RTW89_FCC][1][72] = -4, -+ [1][0][RTW89_FCC][2][72] = 68, -+ [1][0][RTW89_ETSI][1][72] = 127, -+ [1][0][RTW89_ETSI][0][72] = 127, -+ [1][0][RTW89_MKK][1][72] = 127, -+ [1][0][RTW89_MKK][0][72] = 127, -+ [1][0][RTW89_IC][1][72] = -4, -+ [1][0][RTW89_KCC][1][72] = -2, -+ [1][0][RTW89_KCC][0][72] = 127, -+ [1][0][RTW89_ACMA][1][72] = 127, -+ [1][0][RTW89_ACMA][0][72] = 127, -+ [1][0][RTW89_CHILE][1][72] = 127, -+ [1][0][RTW89_QATAR][1][72] = 127, -+ [1][0][RTW89_QATAR][0][72] = 127, -+ [1][0][RTW89_UK][1][72] = 127, -+ [1][0][RTW89_UK][0][72] = 127, -+ [1][0][RTW89_FCC][1][74] = -4, -+ [1][0][RTW89_FCC][2][74] = 68, -+ [1][0][RTW89_ETSI][1][74] = 127, -+ [1][0][RTW89_ETSI][0][74] = 127, -+ [1][0][RTW89_MKK][1][74] = 127, -+ [1][0][RTW89_MKK][0][74] = 127, -+ [1][0][RTW89_IC][1][74] = -4, -+ [1][0][RTW89_KCC][1][74] = -2, -+ [1][0][RTW89_KCC][0][74] = 127, -+ [1][0][RTW89_ACMA][1][74] = 127, -+ [1][0][RTW89_ACMA][0][74] = 127, -+ [1][0][RTW89_CHILE][1][74] = 127, -+ [1][0][RTW89_QATAR][1][74] = 127, -+ [1][0][RTW89_QATAR][0][74] = 127, -+ [1][0][RTW89_UK][1][74] = 127, -+ [1][0][RTW89_UK][0][74] = 127, -+ [1][0][RTW89_FCC][1][75] = -4, -+ [1][0][RTW89_FCC][2][75] = 68, -+ [1][0][RTW89_ETSI][1][75] = 127, -+ [1][0][RTW89_ETSI][0][75] = 127, -+ [1][0][RTW89_MKK][1][75] = 127, -+ [1][0][RTW89_MKK][0][75] = 127, -+ [1][0][RTW89_IC][1][75] = -4, -+ [1][0][RTW89_KCC][1][75] = -2, -+ [1][0][RTW89_KCC][0][75] = 127, -+ [1][0][RTW89_ACMA][1][75] = 127, -+ [1][0][RTW89_ACMA][0][75] = 127, -+ [1][0][RTW89_CHILE][1][75] = 127, -+ [1][0][RTW89_QATAR][1][75] = 127, -+ [1][0][RTW89_QATAR][0][75] = 127, -+ [1][0][RTW89_UK][1][75] = 127, -+ [1][0][RTW89_UK][0][75] = 127, -+ [1][0][RTW89_FCC][1][77] = -4, -+ [1][0][RTW89_FCC][2][77] = 68, -+ [1][0][RTW89_ETSI][1][77] = 127, -+ [1][0][RTW89_ETSI][0][77] = 127, -+ [1][0][RTW89_MKK][1][77] = 127, -+ [1][0][RTW89_MKK][0][77] = 127, -+ [1][0][RTW89_IC][1][77] = -4, -+ [1][0][RTW89_KCC][1][77] = -2, -+ [1][0][RTW89_KCC][0][77] = 127, -+ [1][0][RTW89_ACMA][1][77] = 127, -+ [1][0][RTW89_ACMA][0][77] = 127, -+ [1][0][RTW89_CHILE][1][77] = 127, -+ [1][0][RTW89_QATAR][1][77] = 127, -+ [1][0][RTW89_QATAR][0][77] = 127, -+ [1][0][RTW89_UK][1][77] = 127, -+ [1][0][RTW89_UK][0][77] = 127, -+ [1][0][RTW89_FCC][1][79] = -4, -+ [1][0][RTW89_FCC][2][79] = 68, -+ [1][0][RTW89_ETSI][1][79] = 127, -+ [1][0][RTW89_ETSI][0][79] = 127, -+ [1][0][RTW89_MKK][1][79] = 127, -+ [1][0][RTW89_MKK][0][79] = 127, -+ [1][0][RTW89_IC][1][79] = -4, -+ [1][0][RTW89_KCC][1][79] = -2, -+ [1][0][RTW89_KCC][0][79] = 127, -+ [1][0][RTW89_ACMA][1][79] = 127, -+ [1][0][RTW89_ACMA][0][79] = 127, -+ [1][0][RTW89_CHILE][1][79] = 127, -+ [1][0][RTW89_QATAR][1][79] = 127, -+ [1][0][RTW89_QATAR][0][79] = 127, -+ [1][0][RTW89_UK][1][79] = 127, -+ [1][0][RTW89_UK][0][79] = 127, -+ [1][0][RTW89_FCC][1][81] = -4, -+ [1][0][RTW89_FCC][2][81] = 68, -+ [1][0][RTW89_ETSI][1][81] = 127, -+ [1][0][RTW89_ETSI][0][81] = 127, -+ [1][0][RTW89_MKK][1][81] = 127, -+ [1][0][RTW89_MKK][0][81] = 127, -+ [1][0][RTW89_IC][1][81] = -4, -+ [1][0][RTW89_KCC][1][81] = -2, -+ [1][0][RTW89_KCC][0][81] = 127, -+ [1][0][RTW89_ACMA][1][81] = 127, -+ [1][0][RTW89_ACMA][0][81] = 127, -+ [1][0][RTW89_CHILE][1][81] = 127, -+ [1][0][RTW89_QATAR][1][81] = 127, -+ [1][0][RTW89_QATAR][0][81] = 127, -+ [1][0][RTW89_UK][1][81] = 127, -+ [1][0][RTW89_UK][0][81] = 127, -+ [1][0][RTW89_FCC][1][83] = -4, -+ [1][0][RTW89_FCC][2][83] = 68, -+ [1][0][RTW89_ETSI][1][83] = 127, -+ [1][0][RTW89_ETSI][0][83] = 127, -+ [1][0][RTW89_MKK][1][83] = 127, -+ [1][0][RTW89_MKK][0][83] = 127, -+ [1][0][RTW89_IC][1][83] = -4, -+ [1][0][RTW89_KCC][1][83] = -2, -+ [1][0][RTW89_KCC][0][83] = 127, -+ [1][0][RTW89_ACMA][1][83] = 127, -+ [1][0][RTW89_ACMA][0][83] = 127, -+ [1][0][RTW89_CHILE][1][83] = 127, -+ [1][0][RTW89_QATAR][1][83] = 127, -+ [1][0][RTW89_QATAR][0][83] = 127, -+ [1][0][RTW89_UK][1][83] = 127, -+ [1][0][RTW89_UK][0][83] = 127, -+ [1][0][RTW89_FCC][1][85] = -4, -+ [1][0][RTW89_FCC][2][85] = 68, -+ [1][0][RTW89_ETSI][1][85] = 127, -+ [1][0][RTW89_ETSI][0][85] = 127, -+ [1][0][RTW89_MKK][1][85] = 127, -+ [1][0][RTW89_MKK][0][85] = 127, -+ [1][0][RTW89_IC][1][85] = -4, -+ [1][0][RTW89_KCC][1][85] = -2, -+ [1][0][RTW89_KCC][0][85] = 127, -+ [1][0][RTW89_ACMA][1][85] = 127, -+ [1][0][RTW89_ACMA][0][85] = 127, -+ [1][0][RTW89_CHILE][1][85] = 127, -+ [1][0][RTW89_QATAR][1][85] = 127, -+ [1][0][RTW89_QATAR][0][85] = 127, -+ [1][0][RTW89_UK][1][85] = 127, -+ [1][0][RTW89_UK][0][85] = 127, -+ [1][0][RTW89_FCC][1][87] = -4, -+ [1][0][RTW89_FCC][2][87] = 127, -+ [1][0][RTW89_ETSI][1][87] = 127, -+ [1][0][RTW89_ETSI][0][87] = 127, -+ [1][0][RTW89_MKK][1][87] = 127, -+ [1][0][RTW89_MKK][0][87] = 127, -+ [1][0][RTW89_IC][1][87] = -4, -+ [1][0][RTW89_KCC][1][87] = -2, -+ [1][0][RTW89_KCC][0][87] = 127, -+ [1][0][RTW89_ACMA][1][87] = 127, -+ [1][0][RTW89_ACMA][0][87] = 127, -+ [1][0][RTW89_CHILE][1][87] = 127, -+ [1][0][RTW89_QATAR][1][87] = 127, -+ [1][0][RTW89_QATAR][0][87] = 127, -+ [1][0][RTW89_UK][1][87] = 127, -+ [1][0][RTW89_UK][0][87] = 127, -+ [1][0][RTW89_FCC][1][89] = -4, -+ [1][0][RTW89_FCC][2][89] = 127, -+ [1][0][RTW89_ETSI][1][89] = 127, -+ [1][0][RTW89_ETSI][0][89] = 127, -+ [1][0][RTW89_MKK][1][89] = 127, -+ [1][0][RTW89_MKK][0][89] = 127, -+ [1][0][RTW89_IC][1][89] = -4, -+ [1][0][RTW89_KCC][1][89] = -2, -+ [1][0][RTW89_KCC][0][89] = 127, -+ [1][0][RTW89_ACMA][1][89] = 127, -+ [1][0][RTW89_ACMA][0][89] = 127, -+ [1][0][RTW89_CHILE][1][89] = 127, -+ [1][0][RTW89_QATAR][1][89] = 127, -+ [1][0][RTW89_QATAR][0][89] = 127, -+ [1][0][RTW89_UK][1][89] = 127, -+ [1][0][RTW89_UK][0][89] = 127, -+ [1][0][RTW89_FCC][1][90] = -4, -+ [1][0][RTW89_FCC][2][90] = 127, -+ [1][0][RTW89_ETSI][1][90] = 127, -+ [1][0][RTW89_ETSI][0][90] = 127, -+ [1][0][RTW89_MKK][1][90] = 127, -+ [1][0][RTW89_MKK][0][90] = 127, -+ [1][0][RTW89_IC][1][90] = -4, -+ [1][0][RTW89_KCC][1][90] = -2, -+ [1][0][RTW89_KCC][0][90] = 127, -+ [1][0][RTW89_ACMA][1][90] = 127, -+ [1][0][RTW89_ACMA][0][90] = 127, -+ [1][0][RTW89_CHILE][1][90] = 127, -+ [1][0][RTW89_QATAR][1][90] = 127, -+ [1][0][RTW89_QATAR][0][90] = 127, -+ [1][0][RTW89_UK][1][90] = 127, -+ [1][0][RTW89_UK][0][90] = 127, -+ [1][0][RTW89_FCC][1][92] = -4, -+ [1][0][RTW89_FCC][2][92] = 127, -+ [1][0][RTW89_ETSI][1][92] = 127, -+ [1][0][RTW89_ETSI][0][92] = 127, -+ [1][0][RTW89_MKK][1][92] = 127, -+ [1][0][RTW89_MKK][0][92] = 127, -+ [1][0][RTW89_IC][1][92] = -4, -+ [1][0][RTW89_KCC][1][92] = -2, -+ [1][0][RTW89_KCC][0][92] = 127, -+ [1][0][RTW89_ACMA][1][92] = 127, -+ [1][0][RTW89_ACMA][0][92] = 127, -+ [1][0][RTW89_CHILE][1][92] = 127, -+ [1][0][RTW89_QATAR][1][92] = 127, -+ [1][0][RTW89_QATAR][0][92] = 127, -+ [1][0][RTW89_UK][1][92] = 127, -+ [1][0][RTW89_UK][0][92] = 127, -+ [1][0][RTW89_FCC][1][94] = -4, -+ [1][0][RTW89_FCC][2][94] = 127, -+ [1][0][RTW89_ETSI][1][94] = 127, -+ [1][0][RTW89_ETSI][0][94] = 127, -+ [1][0][RTW89_MKK][1][94] = 127, -+ [1][0][RTW89_MKK][0][94] = 127, -+ [1][0][RTW89_IC][1][94] = -4, -+ [1][0][RTW89_KCC][1][94] = -2, -+ [1][0][RTW89_KCC][0][94] = 127, -+ [1][0][RTW89_ACMA][1][94] = 127, -+ [1][0][RTW89_ACMA][0][94] = 127, -+ [1][0][RTW89_CHILE][1][94] = 127, -+ [1][0][RTW89_QATAR][1][94] = 127, -+ [1][0][RTW89_QATAR][0][94] = 127, -+ [1][0][RTW89_UK][1][94] = 127, -+ [1][0][RTW89_UK][0][94] = 127, -+ [1][0][RTW89_FCC][1][96] = -4, -+ [1][0][RTW89_FCC][2][96] = 127, -+ [1][0][RTW89_ETSI][1][96] = 127, -+ [1][0][RTW89_ETSI][0][96] = 127, -+ [1][0][RTW89_MKK][1][96] = 127, -+ [1][0][RTW89_MKK][0][96] = 127, -+ [1][0][RTW89_IC][1][96] = -4, -+ [1][0][RTW89_KCC][1][96] = -2, -+ [1][0][RTW89_KCC][0][96] = 127, -+ [1][0][RTW89_ACMA][1][96] = 127, -+ [1][0][RTW89_ACMA][0][96] = 127, -+ [1][0][RTW89_CHILE][1][96] = 127, -+ [1][0][RTW89_QATAR][1][96] = 127, -+ [1][0][RTW89_QATAR][0][96] = 127, -+ [1][0][RTW89_UK][1][96] = 127, -+ [1][0][RTW89_UK][0][96] = 127, -+ [1][0][RTW89_FCC][1][98] = -4, -+ [1][0][RTW89_FCC][2][98] = 127, -+ [1][0][RTW89_ETSI][1][98] = 127, -+ [1][0][RTW89_ETSI][0][98] = 127, -+ [1][0][RTW89_MKK][1][98] = 127, -+ [1][0][RTW89_MKK][0][98] = 127, -+ [1][0][RTW89_IC][1][98] = -4, -+ [1][0][RTW89_KCC][1][98] = -2, -+ [1][0][RTW89_KCC][0][98] = 127, -+ [1][0][RTW89_ACMA][1][98] = 127, -+ [1][0][RTW89_ACMA][0][98] = 127, -+ [1][0][RTW89_CHILE][1][98] = 127, -+ [1][0][RTW89_QATAR][1][98] = 127, -+ [1][0][RTW89_QATAR][0][98] = 127, -+ [1][0][RTW89_UK][1][98] = 127, -+ [1][0][RTW89_UK][0][98] = 127, -+ [1][0][RTW89_FCC][1][100] = -4, -+ [1][0][RTW89_FCC][2][100] = 127, -+ [1][0][RTW89_ETSI][1][100] = 127, -+ [1][0][RTW89_ETSI][0][100] = 127, -+ [1][0][RTW89_MKK][1][100] = 127, -+ [1][0][RTW89_MKK][0][100] = 127, -+ [1][0][RTW89_IC][1][100] = -4, -+ [1][0][RTW89_KCC][1][100] = -2, -+ [1][0][RTW89_KCC][0][100] = 127, -+ [1][0][RTW89_ACMA][1][100] = 127, -+ [1][0][RTW89_ACMA][0][100] = 127, -+ [1][0][RTW89_CHILE][1][100] = 127, -+ [1][0][RTW89_QATAR][1][100] = 127, -+ [1][0][RTW89_QATAR][0][100] = 127, -+ [1][0][RTW89_UK][1][100] = 127, -+ [1][0][RTW89_UK][0][100] = 127, -+ [1][0][RTW89_FCC][1][102] = -4, -+ [1][0][RTW89_FCC][2][102] = 127, -+ [1][0][RTW89_ETSI][1][102] = 127, -+ [1][0][RTW89_ETSI][0][102] = 127, -+ [1][0][RTW89_MKK][1][102] = 127, -+ [1][0][RTW89_MKK][0][102] = 127, -+ [1][0][RTW89_IC][1][102] = -4, -+ [1][0][RTW89_KCC][1][102] = -2, -+ [1][0][RTW89_KCC][0][102] = 127, -+ [1][0][RTW89_ACMA][1][102] = 127, -+ [1][0][RTW89_ACMA][0][102] = 127, -+ [1][0][RTW89_CHILE][1][102] = 127, -+ [1][0][RTW89_QATAR][1][102] = 127, -+ [1][0][RTW89_QATAR][0][102] = 127, -+ [1][0][RTW89_UK][1][102] = 127, -+ [1][0][RTW89_UK][0][102] = 127, -+ [1][0][RTW89_FCC][1][104] = -4, -+ [1][0][RTW89_FCC][2][104] = 127, -+ [1][0][RTW89_ETSI][1][104] = 127, -+ [1][0][RTW89_ETSI][0][104] = 127, -+ [1][0][RTW89_MKK][1][104] = 127, -+ [1][0][RTW89_MKK][0][104] = 127, -+ [1][0][RTW89_IC][1][104] = -4, -+ [1][0][RTW89_KCC][1][104] = -2, -+ [1][0][RTW89_KCC][0][104] = 127, -+ [1][0][RTW89_ACMA][1][104] = 127, -+ [1][0][RTW89_ACMA][0][104] = 127, -+ [1][0][RTW89_CHILE][1][104] = 127, -+ [1][0][RTW89_QATAR][1][104] = 127, -+ [1][0][RTW89_QATAR][0][104] = 127, -+ [1][0][RTW89_UK][1][104] = 127, -+ [1][0][RTW89_UK][0][104] = 127, -+ [1][0][RTW89_FCC][1][105] = -4, -+ [1][0][RTW89_FCC][2][105] = 127, -+ [1][0][RTW89_ETSI][1][105] = 127, -+ [1][0][RTW89_ETSI][0][105] = 127, -+ [1][0][RTW89_MKK][1][105] = 127, -+ [1][0][RTW89_MKK][0][105] = 127, -+ [1][0][RTW89_IC][1][105] = -4, -+ [1][0][RTW89_KCC][1][105] = -2, -+ [1][0][RTW89_KCC][0][105] = 127, -+ [1][0][RTW89_ACMA][1][105] = 127, -+ [1][0][RTW89_ACMA][0][105] = 127, -+ [1][0][RTW89_CHILE][1][105] = 127, -+ [1][0][RTW89_QATAR][1][105] = 127, -+ [1][0][RTW89_QATAR][0][105] = 127, -+ [1][0][RTW89_UK][1][105] = 127, -+ [1][0][RTW89_UK][0][105] = 127, -+ [1][0][RTW89_FCC][1][107] = 1, -+ [1][0][RTW89_FCC][2][107] = 127, -+ [1][0][RTW89_ETSI][1][107] = 127, -+ [1][0][RTW89_ETSI][0][107] = 127, -+ [1][0][RTW89_MKK][1][107] = 127, -+ [1][0][RTW89_MKK][0][107] = 127, -+ [1][0][RTW89_IC][1][107] = 1, -+ [1][0][RTW89_KCC][1][107] = -2, -+ [1][0][RTW89_KCC][0][107] = 127, -+ [1][0][RTW89_ACMA][1][107] = 127, -+ [1][0][RTW89_ACMA][0][107] = 127, -+ [1][0][RTW89_CHILE][1][107] = 127, -+ [1][0][RTW89_QATAR][1][107] = 127, -+ [1][0][RTW89_QATAR][0][107] = 127, -+ [1][0][RTW89_UK][1][107] = 127, -+ [1][0][RTW89_UK][0][107] = 127, -+ [1][0][RTW89_FCC][1][109] = 2, -+ [1][0][RTW89_FCC][2][109] = 127, -+ [1][0][RTW89_ETSI][1][109] = 127, -+ [1][0][RTW89_ETSI][0][109] = 127, -+ [1][0][RTW89_MKK][1][109] = 127, -+ [1][0][RTW89_MKK][0][109] = 127, -+ [1][0][RTW89_IC][1][109] = 2, -+ [1][0][RTW89_KCC][1][109] = 127, -+ [1][0][RTW89_KCC][0][109] = 127, -+ [1][0][RTW89_ACMA][1][109] = 127, -+ [1][0][RTW89_ACMA][0][109] = 127, -+ [1][0][RTW89_CHILE][1][109] = 127, -+ [1][0][RTW89_QATAR][1][109] = 127, -+ [1][0][RTW89_QATAR][0][109] = 127, -+ [1][0][RTW89_UK][1][109] = 127, -+ [1][0][RTW89_UK][0][109] = 127, -+ [1][0][RTW89_FCC][1][111] = 127, -+ [1][0][RTW89_FCC][2][111] = 127, -+ [1][0][RTW89_ETSI][1][111] = 127, -+ [1][0][RTW89_ETSI][0][111] = 127, -+ [1][0][RTW89_MKK][1][111] = 127, -+ [1][0][RTW89_MKK][0][111] = 127, -+ [1][0][RTW89_IC][1][111] = 127, -+ [1][0][RTW89_KCC][1][111] = 127, -+ [1][0][RTW89_KCC][0][111] = 127, -+ [1][0][RTW89_ACMA][1][111] = 127, -+ [1][0][RTW89_ACMA][0][111] = 127, -+ [1][0][RTW89_CHILE][1][111] = 127, -+ [1][0][RTW89_QATAR][1][111] = 127, -+ [1][0][RTW89_QATAR][0][111] = 127, -+ [1][0][RTW89_UK][1][111] = 127, -+ [1][0][RTW89_UK][0][111] = 127, -+ [1][0][RTW89_FCC][1][113] = 127, -+ [1][0][RTW89_FCC][2][113] = 127, -+ [1][0][RTW89_ETSI][1][113] = 127, -+ [1][0][RTW89_ETSI][0][113] = 127, -+ [1][0][RTW89_MKK][1][113] = 127, -+ [1][0][RTW89_MKK][0][113] = 127, -+ [1][0][RTW89_IC][1][113] = 127, -+ [1][0][RTW89_KCC][1][113] = 127, -+ [1][0][RTW89_KCC][0][113] = 127, -+ [1][0][RTW89_ACMA][1][113] = 127, -+ [1][0][RTW89_ACMA][0][113] = 127, -+ [1][0][RTW89_CHILE][1][113] = 127, -+ [1][0][RTW89_QATAR][1][113] = 127, -+ [1][0][RTW89_QATAR][0][113] = 127, -+ [1][0][RTW89_UK][1][113] = 127, -+ [1][0][RTW89_UK][0][113] = 127, -+ [1][0][RTW89_FCC][1][115] = 127, -+ [1][0][RTW89_FCC][2][115] = 127, -+ [1][0][RTW89_ETSI][1][115] = 127, -+ [1][0][RTW89_ETSI][0][115] = 127, -+ [1][0][RTW89_MKK][1][115] = 127, -+ [1][0][RTW89_MKK][0][115] = 127, -+ [1][0][RTW89_IC][1][115] = 127, -+ [1][0][RTW89_KCC][1][115] = 127, -+ [1][0][RTW89_KCC][0][115] = 127, -+ [1][0][RTW89_ACMA][1][115] = 127, -+ [1][0][RTW89_ACMA][0][115] = 127, -+ [1][0][RTW89_CHILE][1][115] = 127, -+ [1][0][RTW89_QATAR][1][115] = 127, -+ [1][0][RTW89_QATAR][0][115] = 127, -+ [1][0][RTW89_UK][1][115] = 127, -+ [1][0][RTW89_UK][0][115] = 127, -+ [1][0][RTW89_FCC][1][117] = 127, -+ [1][0][RTW89_FCC][2][117] = 127, -+ [1][0][RTW89_ETSI][1][117] = 127, -+ [1][0][RTW89_ETSI][0][117] = 127, -+ [1][0][RTW89_MKK][1][117] = 127, -+ [1][0][RTW89_MKK][0][117] = 127, -+ [1][0][RTW89_IC][1][117] = 127, -+ [1][0][RTW89_KCC][1][117] = 127, -+ [1][0][RTW89_KCC][0][117] = 127, -+ [1][0][RTW89_ACMA][1][117] = 127, -+ [1][0][RTW89_ACMA][0][117] = 127, -+ [1][0][RTW89_CHILE][1][117] = 127, -+ [1][0][RTW89_QATAR][1][117] = 127, -+ [1][0][RTW89_QATAR][0][117] = 127, -+ [1][0][RTW89_UK][1][117] = 127, -+ [1][0][RTW89_UK][0][117] = 127, -+ [1][0][RTW89_FCC][1][119] = 127, -+ [1][0][RTW89_FCC][2][119] = 127, -+ [1][0][RTW89_ETSI][1][119] = 127, -+ [1][0][RTW89_ETSI][0][119] = 127, -+ [1][0][RTW89_MKK][1][119] = 127, -+ [1][0][RTW89_MKK][0][119] = 127, -+ [1][0][RTW89_IC][1][119] = 127, -+ [1][0][RTW89_KCC][1][119] = 127, -+ [1][0][RTW89_KCC][0][119] = 127, -+ [1][0][RTW89_ACMA][1][119] = 127, -+ [1][0][RTW89_ACMA][0][119] = 127, -+ [1][0][RTW89_CHILE][1][119] = 127, -+ [1][0][RTW89_QATAR][1][119] = 127, -+ [1][0][RTW89_QATAR][0][119] = 127, -+ [1][0][RTW89_UK][1][119] = 127, -+ [1][0][RTW89_UK][0][119] = 127, -+ [1][1][RTW89_FCC][1][0] = -26, -+ [1][1][RTW89_FCC][2][0] = 44, -+ [1][1][RTW89_ETSI][1][0] = 32, -+ [1][1][RTW89_ETSI][0][0] = -6, -+ [1][1][RTW89_MKK][1][0] = 30, -+ [1][1][RTW89_MKK][0][0] = -10, -+ [1][1][RTW89_IC][1][0] = -26, -+ [1][1][RTW89_KCC][1][0] = -14, -+ [1][1][RTW89_KCC][0][0] = -14, -+ [1][1][RTW89_ACMA][1][0] = 32, -+ [1][1][RTW89_ACMA][0][0] = -6, -+ [1][1][RTW89_CHILE][1][0] = -26, -+ [1][1][RTW89_QATAR][1][0] = 32, -+ [1][1][RTW89_QATAR][0][0] = -6, -+ [1][1][RTW89_UK][1][0] = 32, -+ [1][1][RTW89_UK][0][0] = -6, -+ [1][1][RTW89_FCC][1][2] = -28, -+ [1][1][RTW89_FCC][2][2] = 44, -+ [1][1][RTW89_ETSI][1][2] = 32, -+ [1][1][RTW89_ETSI][0][2] = -6, -+ [1][1][RTW89_MKK][1][2] = 30, -+ [1][1][RTW89_MKK][0][2] = -10, -+ [1][1][RTW89_IC][1][2] = -28, -+ [1][1][RTW89_KCC][1][2] = -14, -+ [1][1][RTW89_KCC][0][2] = -14, -+ [1][1][RTW89_ACMA][1][2] = 32, -+ [1][1][RTW89_ACMA][0][2] = -6, -+ [1][1][RTW89_CHILE][1][2] = -28, -+ [1][1][RTW89_QATAR][1][2] = 32, -+ [1][1][RTW89_QATAR][0][2] = -6, -+ [1][1][RTW89_UK][1][2] = 32, -+ [1][1][RTW89_UK][0][2] = -6, -+ [1][1][RTW89_FCC][1][4] = -28, -+ [1][1][RTW89_FCC][2][4] = 44, -+ [1][1][RTW89_ETSI][1][4] = 32, -+ [1][1][RTW89_ETSI][0][4] = -6, -+ [1][1][RTW89_MKK][1][4] = 30, -+ [1][1][RTW89_MKK][0][4] = -10, -+ [1][1][RTW89_IC][1][4] = -28, -+ [1][1][RTW89_KCC][1][4] = -14, -+ [1][1][RTW89_KCC][0][4] = -14, -+ [1][1][RTW89_ACMA][1][4] = 32, -+ [1][1][RTW89_ACMA][0][4] = -6, -+ [1][1][RTW89_CHILE][1][4] = -28, -+ [1][1][RTW89_QATAR][1][4] = 32, -+ [1][1][RTW89_QATAR][0][4] = -6, -+ [1][1][RTW89_UK][1][4] = 32, -+ [1][1][RTW89_UK][0][4] = -6, -+ [1][1][RTW89_FCC][1][6] = -28, -+ [1][1][RTW89_FCC][2][6] = 44, -+ [1][1][RTW89_ETSI][1][6] = 32, -+ [1][1][RTW89_ETSI][0][6] = -6, -+ [1][1][RTW89_MKK][1][6] = 30, -+ [1][1][RTW89_MKK][0][6] = -10, -+ [1][1][RTW89_IC][1][6] = -28, -+ [1][1][RTW89_KCC][1][6] = -14, -+ [1][1][RTW89_KCC][0][6] = -14, -+ [1][1][RTW89_ACMA][1][6] = 32, -+ [1][1][RTW89_ACMA][0][6] = -6, -+ [1][1][RTW89_CHILE][1][6] = -28, -+ [1][1][RTW89_QATAR][1][6] = 32, -+ [1][1][RTW89_QATAR][0][6] = -6, -+ [1][1][RTW89_UK][1][6] = 32, -+ [1][1][RTW89_UK][0][6] = -6, -+ [1][1][RTW89_FCC][1][8] = -28, -+ [1][1][RTW89_FCC][2][8] = 44, -+ [1][1][RTW89_ETSI][1][8] = 32, -+ [1][1][RTW89_ETSI][0][8] = -6, -+ [1][1][RTW89_MKK][1][8] = 30, -+ [1][1][RTW89_MKK][0][8] = -10, -+ [1][1][RTW89_IC][1][8] = -28, -+ [1][1][RTW89_KCC][1][8] = -14, -+ [1][1][RTW89_KCC][0][8] = -14, -+ [1][1][RTW89_ACMA][1][8] = 32, -+ [1][1][RTW89_ACMA][0][8] = -6, -+ [1][1][RTW89_CHILE][1][8] = -28, -+ [1][1][RTW89_QATAR][1][8] = 32, -+ [1][1][RTW89_QATAR][0][8] = -6, -+ [1][1][RTW89_UK][1][8] = 32, -+ [1][1][RTW89_UK][0][8] = -6, -+ [1][1][RTW89_FCC][1][10] = -28, -+ [1][1][RTW89_FCC][2][10] = 44, -+ [1][1][RTW89_ETSI][1][10] = 32, -+ [1][1][RTW89_ETSI][0][10] = -6, -+ [1][1][RTW89_MKK][1][10] = 30, -+ [1][1][RTW89_MKK][0][10] = -10, -+ [1][1][RTW89_IC][1][10] = -28, -+ [1][1][RTW89_KCC][1][10] = -14, -+ [1][1][RTW89_KCC][0][10] = -14, -+ [1][1][RTW89_ACMA][1][10] = 32, -+ [1][1][RTW89_ACMA][0][10] = -6, -+ [1][1][RTW89_CHILE][1][10] = -28, -+ [1][1][RTW89_QATAR][1][10] = 32, -+ [1][1][RTW89_QATAR][0][10] = -6, -+ [1][1][RTW89_UK][1][10] = 32, -+ [1][1][RTW89_UK][0][10] = -6, -+ [1][1][RTW89_FCC][1][12] = -28, -+ [1][1][RTW89_FCC][2][12] = 44, -+ [1][1][RTW89_ETSI][1][12] = 32, -+ [1][1][RTW89_ETSI][0][12] = -6, -+ [1][1][RTW89_MKK][1][12] = 30, -+ [1][1][RTW89_MKK][0][12] = -10, -+ [1][1][RTW89_IC][1][12] = -28, -+ [1][1][RTW89_KCC][1][12] = -14, -+ [1][1][RTW89_KCC][0][12] = -14, -+ [1][1][RTW89_ACMA][1][12] = 32, -+ [1][1][RTW89_ACMA][0][12] = -6, -+ [1][1][RTW89_CHILE][1][12] = -28, -+ [1][1][RTW89_QATAR][1][12] = 32, -+ [1][1][RTW89_QATAR][0][12] = -6, -+ [1][1][RTW89_UK][1][12] = 32, -+ [1][1][RTW89_UK][0][12] = -6, -+ [1][1][RTW89_FCC][1][14] = -28, -+ [1][1][RTW89_FCC][2][14] = 44, -+ [1][1][RTW89_ETSI][1][14] = 32, -+ [1][1][RTW89_ETSI][0][14] = -6, -+ [1][1][RTW89_MKK][1][14] = 30, -+ [1][1][RTW89_MKK][0][14] = -10, -+ [1][1][RTW89_IC][1][14] = -28, -+ [1][1][RTW89_KCC][1][14] = -14, -+ [1][1][RTW89_KCC][0][14] = -14, -+ [1][1][RTW89_ACMA][1][14] = 32, -+ [1][1][RTW89_ACMA][0][14] = -6, -+ [1][1][RTW89_CHILE][1][14] = -28, -+ [1][1][RTW89_QATAR][1][14] = 32, -+ [1][1][RTW89_QATAR][0][14] = -6, -+ [1][1][RTW89_UK][1][14] = 32, -+ [1][1][RTW89_UK][0][14] = -6, -+ [1][1][RTW89_FCC][1][15] = -28, -+ [1][1][RTW89_FCC][2][15] = 44, -+ [1][1][RTW89_ETSI][1][15] = 32, -+ [1][1][RTW89_ETSI][0][15] = -6, -+ [1][1][RTW89_MKK][1][15] = 30, -+ [1][1][RTW89_MKK][0][15] = -10, -+ [1][1][RTW89_IC][1][15] = -28, -+ [1][1][RTW89_KCC][1][15] = -14, -+ [1][1][RTW89_KCC][0][15] = -14, -+ [1][1][RTW89_ACMA][1][15] = 32, -+ [1][1][RTW89_ACMA][0][15] = -6, -+ [1][1][RTW89_CHILE][1][15] = -28, -+ [1][1][RTW89_QATAR][1][15] = 32, -+ [1][1][RTW89_QATAR][0][15] = -6, -+ [1][1][RTW89_UK][1][15] = 32, -+ [1][1][RTW89_UK][0][15] = -6, -+ [1][1][RTW89_FCC][1][17] = -28, -+ [1][1][RTW89_FCC][2][17] = 44, -+ [1][1][RTW89_ETSI][1][17] = 32, -+ [1][1][RTW89_ETSI][0][17] = -6, -+ [1][1][RTW89_MKK][1][17] = 30, -+ [1][1][RTW89_MKK][0][17] = -10, -+ [1][1][RTW89_IC][1][17] = -28, -+ [1][1][RTW89_KCC][1][17] = -14, -+ [1][1][RTW89_KCC][0][17] = -14, -+ [1][1][RTW89_ACMA][1][17] = 32, -+ [1][1][RTW89_ACMA][0][17] = -6, -+ [1][1][RTW89_CHILE][1][17] = -28, -+ [1][1][RTW89_QATAR][1][17] = 32, -+ [1][1][RTW89_QATAR][0][17] = -6, -+ [1][1][RTW89_UK][1][17] = 32, -+ [1][1][RTW89_UK][0][17] = -6, -+ [1][1][RTW89_FCC][1][19] = -28, -+ [1][1][RTW89_FCC][2][19] = 44, -+ [1][1][RTW89_ETSI][1][19] = 32, -+ [1][1][RTW89_ETSI][0][19] = -6, -+ [1][1][RTW89_MKK][1][19] = 30, -+ [1][1][RTW89_MKK][0][19] = -10, -+ [1][1][RTW89_IC][1][19] = -28, -+ [1][1][RTW89_KCC][1][19] = -14, -+ [1][1][RTW89_KCC][0][19] = -14, -+ [1][1][RTW89_ACMA][1][19] = 32, -+ [1][1][RTW89_ACMA][0][19] = -6, -+ [1][1][RTW89_CHILE][1][19] = -28, -+ [1][1][RTW89_QATAR][1][19] = 32, -+ [1][1][RTW89_QATAR][0][19] = -6, -+ [1][1][RTW89_UK][1][19] = 32, -+ [1][1][RTW89_UK][0][19] = -6, -+ [1][1][RTW89_FCC][1][21] = -28, -+ [1][1][RTW89_FCC][2][21] = 44, -+ [1][1][RTW89_ETSI][1][21] = 32, -+ [1][1][RTW89_ETSI][0][21] = -6, -+ [1][1][RTW89_MKK][1][21] = 30, -+ [1][1][RTW89_MKK][0][21] = -10, -+ [1][1][RTW89_IC][1][21] = -28, -+ [1][1][RTW89_KCC][1][21] = -14, -+ [1][1][RTW89_KCC][0][21] = -14, -+ [1][1][RTW89_ACMA][1][21] = 32, -+ [1][1][RTW89_ACMA][0][21] = -6, -+ [1][1][RTW89_CHILE][1][21] = -28, -+ [1][1][RTW89_QATAR][1][21] = 32, -+ [1][1][RTW89_QATAR][0][21] = -6, -+ [1][1][RTW89_UK][1][21] = 32, -+ [1][1][RTW89_UK][0][21] = -6, -+ [1][1][RTW89_FCC][1][23] = -28, -+ [1][1][RTW89_FCC][2][23] = 44, -+ [1][1][RTW89_ETSI][1][23] = 32, -+ [1][1][RTW89_ETSI][0][23] = -6, -+ [1][1][RTW89_MKK][1][23] = 32, -+ [1][1][RTW89_MKK][0][23] = -10, -+ [1][1][RTW89_IC][1][23] = -28, -+ [1][1][RTW89_KCC][1][23] = -14, -+ [1][1][RTW89_KCC][0][23] = -14, -+ [1][1][RTW89_ACMA][1][23] = 32, -+ [1][1][RTW89_ACMA][0][23] = -6, -+ [1][1][RTW89_CHILE][1][23] = -28, -+ [1][1][RTW89_QATAR][1][23] = 32, -+ [1][1][RTW89_QATAR][0][23] = -6, -+ [1][1][RTW89_UK][1][23] = 32, -+ [1][1][RTW89_UK][0][23] = -6, -+ [1][1][RTW89_FCC][1][25] = -28, -+ [1][1][RTW89_FCC][2][25] = 44, -+ [1][1][RTW89_ETSI][1][25] = 32, -+ [1][1][RTW89_ETSI][0][25] = -6, -+ [1][1][RTW89_MKK][1][25] = 32, -+ [1][1][RTW89_MKK][0][25] = -10, -+ [1][1][RTW89_IC][1][25] = -28, -+ [1][1][RTW89_KCC][1][25] = -14, -+ [1][1][RTW89_KCC][0][25] = -14, -+ [1][1][RTW89_ACMA][1][25] = 32, -+ [1][1][RTW89_ACMA][0][25] = -6, -+ [1][1][RTW89_CHILE][1][25] = -28, -+ [1][1][RTW89_QATAR][1][25] = 32, -+ [1][1][RTW89_QATAR][0][25] = -6, -+ [1][1][RTW89_UK][1][25] = 32, -+ [1][1][RTW89_UK][0][25] = -6, -+ [1][1][RTW89_FCC][1][27] = -28, -+ [1][1][RTW89_FCC][2][27] = 44, -+ [1][1][RTW89_ETSI][1][27] = 32, -+ [1][1][RTW89_ETSI][0][27] = -6, -+ [1][1][RTW89_MKK][1][27] = 32, -+ [1][1][RTW89_MKK][0][27] = -10, -+ [1][1][RTW89_IC][1][27] = -28, -+ [1][1][RTW89_KCC][1][27] = -14, -+ [1][1][RTW89_KCC][0][27] = -14, -+ [1][1][RTW89_ACMA][1][27] = 32, -+ [1][1][RTW89_ACMA][0][27] = -6, -+ [1][1][RTW89_CHILE][1][27] = -28, -+ [1][1][RTW89_QATAR][1][27] = 32, -+ [1][1][RTW89_QATAR][0][27] = -6, -+ [1][1][RTW89_UK][1][27] = 32, -+ [1][1][RTW89_UK][0][27] = -6, -+ [1][1][RTW89_FCC][1][29] = -28, -+ [1][1][RTW89_FCC][2][29] = 44, -+ [1][1][RTW89_ETSI][1][29] = 32, -+ [1][1][RTW89_ETSI][0][29] = -6, -+ [1][1][RTW89_MKK][1][29] = 32, -+ [1][1][RTW89_MKK][0][29] = -10, -+ [1][1][RTW89_IC][1][29] = -28, -+ [1][1][RTW89_KCC][1][29] = -14, -+ [1][1][RTW89_KCC][0][29] = -14, -+ [1][1][RTW89_ACMA][1][29] = 32, -+ [1][1][RTW89_ACMA][0][29] = -6, -+ [1][1][RTW89_CHILE][1][29] = -28, -+ [1][1][RTW89_QATAR][1][29] = 32, -+ [1][1][RTW89_QATAR][0][29] = -6, -+ [1][1][RTW89_UK][1][29] = 32, -+ [1][1][RTW89_UK][0][29] = -6, -+ [1][1][RTW89_FCC][1][30] = -28, -+ [1][1][RTW89_FCC][2][30] = 44, -+ [1][1][RTW89_ETSI][1][30] = 32, -+ [1][1][RTW89_ETSI][0][30] = -6, -+ [1][1][RTW89_MKK][1][30] = 32, -+ [1][1][RTW89_MKK][0][30] = -10, -+ [1][1][RTW89_IC][1][30] = -28, -+ [1][1][RTW89_KCC][1][30] = -14, -+ [1][1][RTW89_KCC][0][30] = -14, -+ [1][1][RTW89_ACMA][1][30] = 32, -+ [1][1][RTW89_ACMA][0][30] = -6, -+ [1][1][RTW89_CHILE][1][30] = -28, -+ [1][1][RTW89_QATAR][1][30] = 32, -+ [1][1][RTW89_QATAR][0][30] = -6, -+ [1][1][RTW89_UK][1][30] = 32, -+ [1][1][RTW89_UK][0][30] = -6, -+ [1][1][RTW89_FCC][1][32] = -28, -+ [1][1][RTW89_FCC][2][32] = 44, -+ [1][1][RTW89_ETSI][1][32] = 32, -+ [1][1][RTW89_ETSI][0][32] = -6, -+ [1][1][RTW89_MKK][1][32] = 32, -+ [1][1][RTW89_MKK][0][32] = -10, -+ [1][1][RTW89_IC][1][32] = -28, -+ [1][1][RTW89_KCC][1][32] = -14, -+ [1][1][RTW89_KCC][0][32] = -14, -+ [1][1][RTW89_ACMA][1][32] = 32, -+ [1][1][RTW89_ACMA][0][32] = -6, -+ [1][1][RTW89_CHILE][1][32] = -28, -+ [1][1][RTW89_QATAR][1][32] = 32, -+ [1][1][RTW89_QATAR][0][32] = -6, -+ [1][1][RTW89_UK][1][32] = 32, -+ [1][1][RTW89_UK][0][32] = -6, -+ [1][1][RTW89_FCC][1][34] = -28, -+ [1][1][RTW89_FCC][2][34] = 44, -+ [1][1][RTW89_ETSI][1][34] = 32, -+ [1][1][RTW89_ETSI][0][34] = -6, -+ [1][1][RTW89_MKK][1][34] = 32, -+ [1][1][RTW89_MKK][0][34] = -10, -+ [1][1][RTW89_IC][1][34] = -28, -+ [1][1][RTW89_KCC][1][34] = -14, -+ [1][1][RTW89_KCC][0][34] = -14, -+ [1][1][RTW89_ACMA][1][34] = 32, -+ [1][1][RTW89_ACMA][0][34] = -6, -+ [1][1][RTW89_CHILE][1][34] = -28, -+ [1][1][RTW89_QATAR][1][34] = 32, -+ [1][1][RTW89_QATAR][0][34] = -6, -+ [1][1][RTW89_UK][1][34] = 32, -+ [1][1][RTW89_UK][0][34] = -6, -+ [1][1][RTW89_FCC][1][36] = -28, -+ [1][1][RTW89_FCC][2][36] = 44, -+ [1][1][RTW89_ETSI][1][36] = 32, -+ [1][1][RTW89_ETSI][0][36] = -6, -+ [1][1][RTW89_MKK][1][36] = 32, -+ [1][1][RTW89_MKK][0][36] = -10, -+ [1][1][RTW89_IC][1][36] = -28, -+ [1][1][RTW89_KCC][1][36] = -14, -+ [1][1][RTW89_KCC][0][36] = -14, -+ [1][1][RTW89_ACMA][1][36] = 32, -+ [1][1][RTW89_ACMA][0][36] = -6, -+ [1][1][RTW89_CHILE][1][36] = -28, -+ [1][1][RTW89_QATAR][1][36] = 32, -+ [1][1][RTW89_QATAR][0][36] = -6, -+ [1][1][RTW89_UK][1][36] = 32, -+ [1][1][RTW89_UK][0][36] = -6, -+ [1][1][RTW89_FCC][1][38] = -28, -+ [1][1][RTW89_FCC][2][38] = 44, -+ [1][1][RTW89_ETSI][1][38] = 32, -+ [1][1][RTW89_ETSI][0][38] = -6, -+ [1][1][RTW89_MKK][1][38] = 32, -+ [1][1][RTW89_MKK][0][38] = -10, -+ [1][1][RTW89_IC][1][38] = -28, -+ [1][1][RTW89_KCC][1][38] = -14, -+ [1][1][RTW89_KCC][0][38] = -14, -+ [1][1][RTW89_ACMA][1][38] = 32, -+ [1][1][RTW89_ACMA][0][38] = -6, -+ [1][1][RTW89_CHILE][1][38] = -28, -+ [1][1][RTW89_QATAR][1][38] = 32, -+ [1][1][RTW89_QATAR][0][38] = -6, -+ [1][1][RTW89_UK][1][38] = 32, -+ [1][1][RTW89_UK][0][38] = -6, -+ [1][1][RTW89_FCC][1][40] = -28, -+ [1][1][RTW89_FCC][2][40] = 44, -+ [1][1][RTW89_ETSI][1][40] = 32, -+ [1][1][RTW89_ETSI][0][40] = -6, -+ [1][1][RTW89_MKK][1][40] = 32, -+ [1][1][RTW89_MKK][0][40] = -10, -+ [1][1][RTW89_IC][1][40] = -28, -+ [1][1][RTW89_KCC][1][40] = -14, -+ [1][1][RTW89_KCC][0][40] = -14, -+ [1][1][RTW89_ACMA][1][40] = 32, -+ [1][1][RTW89_ACMA][0][40] = -6, -+ [1][1][RTW89_CHILE][1][40] = -28, -+ [1][1][RTW89_QATAR][1][40] = 32, -+ [1][1][RTW89_QATAR][0][40] = -6, -+ [1][1][RTW89_UK][1][40] = 32, -+ [1][1][RTW89_UK][0][40] = -6, -+ [1][1][RTW89_FCC][1][42] = -28, -+ [1][1][RTW89_FCC][2][42] = 44, -+ [1][1][RTW89_ETSI][1][42] = 32, -+ [1][1][RTW89_ETSI][0][42] = -6, -+ [1][1][RTW89_MKK][1][42] = 32, -+ [1][1][RTW89_MKK][0][42] = -10, -+ [1][1][RTW89_IC][1][42] = -28, -+ [1][1][RTW89_KCC][1][42] = -14, -+ [1][1][RTW89_KCC][0][42] = -14, -+ [1][1][RTW89_ACMA][1][42] = 32, -+ [1][1][RTW89_ACMA][0][42] = -6, -+ [1][1][RTW89_CHILE][1][42] = -28, -+ [1][1][RTW89_QATAR][1][42] = 32, -+ [1][1][RTW89_QATAR][0][42] = -6, -+ [1][1][RTW89_UK][1][42] = 32, -+ [1][1][RTW89_UK][0][42] = -6, -+ [1][1][RTW89_FCC][1][44] = -28, -+ [1][1][RTW89_FCC][2][44] = 44, -+ [1][1][RTW89_ETSI][1][44] = 34, -+ [1][1][RTW89_ETSI][0][44] = -4, -+ [1][1][RTW89_MKK][1][44] = 4, -+ [1][1][RTW89_MKK][0][44] = -8, -+ [1][1][RTW89_IC][1][44] = -28, -+ [1][1][RTW89_KCC][1][44] = -14, -+ [1][1][RTW89_KCC][0][44] = -14, -+ [1][1][RTW89_ACMA][1][44] = 34, -+ [1][1][RTW89_ACMA][0][44] = -4, -+ [1][1][RTW89_CHILE][1][44] = -28, -+ [1][1][RTW89_QATAR][1][44] = 34, -+ [1][1][RTW89_QATAR][0][44] = -4, -+ [1][1][RTW89_UK][1][44] = 34, -+ [1][1][RTW89_UK][0][44] = -4, -+ [1][1][RTW89_FCC][1][45] = -26, -+ [1][1][RTW89_FCC][2][45] = 127, -+ [1][1][RTW89_ETSI][1][45] = 127, -+ [1][1][RTW89_ETSI][0][45] = 127, -+ [1][1][RTW89_MKK][1][45] = 127, -+ [1][1][RTW89_MKK][0][45] = 127, -+ [1][1][RTW89_IC][1][45] = -26, -+ [1][1][RTW89_KCC][1][45] = -14, -+ [1][1][RTW89_KCC][0][45] = 127, -+ [1][1][RTW89_ACMA][1][45] = 127, -+ [1][1][RTW89_ACMA][0][45] = 127, -+ [1][1][RTW89_CHILE][1][45] = 127, -+ [1][1][RTW89_QATAR][1][45] = 127, -+ [1][1][RTW89_QATAR][0][45] = 127, -+ [1][1][RTW89_UK][1][45] = 127, -+ [1][1][RTW89_UK][0][45] = 127, -+ [1][1][RTW89_FCC][1][47] = -28, -+ [1][1][RTW89_FCC][2][47] = 127, -+ [1][1][RTW89_ETSI][1][47] = 127, -+ [1][1][RTW89_ETSI][0][47] = 127, -+ [1][1][RTW89_MKK][1][47] = 127, -+ [1][1][RTW89_MKK][0][47] = 127, -+ [1][1][RTW89_IC][1][47] = -28, -+ [1][1][RTW89_KCC][1][47] = -14, -+ [1][1][RTW89_KCC][0][47] = 127, -+ [1][1][RTW89_ACMA][1][47] = 127, -+ [1][1][RTW89_ACMA][0][47] = 127, -+ [1][1][RTW89_CHILE][1][47] = 127, -+ [1][1][RTW89_QATAR][1][47] = 127, -+ [1][1][RTW89_QATAR][0][47] = 127, -+ [1][1][RTW89_UK][1][47] = 127, -+ [1][1][RTW89_UK][0][47] = 127, -+ [1][1][RTW89_FCC][1][49] = -28, -+ [1][1][RTW89_FCC][2][49] = 127, -+ [1][1][RTW89_ETSI][1][49] = 127, -+ [1][1][RTW89_ETSI][0][49] = 127, -+ [1][1][RTW89_MKK][1][49] = 127, -+ [1][1][RTW89_MKK][0][49] = 127, -+ [1][1][RTW89_IC][1][49] = -28, -+ [1][1][RTW89_KCC][1][49] = -14, -+ [1][1][RTW89_KCC][0][49] = 127, -+ [1][1][RTW89_ACMA][1][49] = 127, -+ [1][1][RTW89_ACMA][0][49] = 127, -+ [1][1][RTW89_CHILE][1][49] = 127, -+ [1][1][RTW89_QATAR][1][49] = 127, -+ [1][1][RTW89_QATAR][0][49] = 127, -+ [1][1][RTW89_UK][1][49] = 127, -+ [1][1][RTW89_UK][0][49] = 127, -+ [1][1][RTW89_FCC][1][51] = -28, -+ [1][1][RTW89_FCC][2][51] = 127, -+ [1][1][RTW89_ETSI][1][51] = 127, -+ [1][1][RTW89_ETSI][0][51] = 127, -+ [1][1][RTW89_MKK][1][51] = 127, -+ [1][1][RTW89_MKK][0][51] = 127, -+ [1][1][RTW89_IC][1][51] = -28, -+ [1][1][RTW89_KCC][1][51] = -14, -+ [1][1][RTW89_KCC][0][51] = 127, -+ [1][1][RTW89_ACMA][1][51] = 127, -+ [1][1][RTW89_ACMA][0][51] = 127, -+ [1][1][RTW89_CHILE][1][51] = 127, -+ [1][1][RTW89_QATAR][1][51] = 127, -+ [1][1][RTW89_QATAR][0][51] = 127, -+ [1][1][RTW89_UK][1][51] = 127, -+ [1][1][RTW89_UK][0][51] = 127, -+ [1][1][RTW89_FCC][1][53] = -26, -+ [1][1][RTW89_FCC][2][53] = 127, -+ [1][1][RTW89_ETSI][1][53] = 127, -+ [1][1][RTW89_ETSI][0][53] = 127, -+ [1][1][RTW89_MKK][1][53] = 127, -+ [1][1][RTW89_MKK][0][53] = 127, -+ [1][1][RTW89_IC][1][53] = -26, -+ [1][1][RTW89_KCC][1][53] = -14, -+ [1][1][RTW89_KCC][0][53] = 127, -+ [1][1][RTW89_ACMA][1][53] = 127, -+ [1][1][RTW89_ACMA][0][53] = 127, -+ [1][1][RTW89_CHILE][1][53] = 127, -+ [1][1][RTW89_QATAR][1][53] = 127, -+ [1][1][RTW89_QATAR][0][53] = 127, -+ [1][1][RTW89_UK][1][53] = 127, -+ [1][1][RTW89_UK][0][53] = 127, -+ [1][1][RTW89_FCC][1][55] = -28, -+ [1][1][RTW89_FCC][2][55] = 44, -+ [1][1][RTW89_ETSI][1][55] = 127, -+ [1][1][RTW89_ETSI][0][55] = 127, -+ [1][1][RTW89_MKK][1][55] = 127, -+ [1][1][RTW89_MKK][0][55] = 127, -+ [1][1][RTW89_IC][1][55] = -28, -+ [1][1][RTW89_KCC][1][55] = -14, -+ [1][1][RTW89_KCC][0][55] = 127, -+ [1][1][RTW89_ACMA][1][55] = 127, -+ [1][1][RTW89_ACMA][0][55] = 127, -+ [1][1][RTW89_CHILE][1][55] = 127, -+ [1][1][RTW89_QATAR][1][55] = 127, -+ [1][1][RTW89_QATAR][0][55] = 127, -+ [1][1][RTW89_UK][1][55] = 127, -+ [1][1][RTW89_UK][0][55] = 127, -+ [1][1][RTW89_FCC][1][57] = -28, -+ [1][1][RTW89_FCC][2][57] = 44, -+ [1][1][RTW89_ETSI][1][57] = 127, -+ [1][1][RTW89_ETSI][0][57] = 127, -+ [1][1][RTW89_MKK][1][57] = 127, -+ [1][1][RTW89_MKK][0][57] = 127, -+ [1][1][RTW89_IC][1][57] = -28, -+ [1][1][RTW89_KCC][1][57] = -14, -+ [1][1][RTW89_KCC][0][57] = 127, -+ [1][1][RTW89_ACMA][1][57] = 127, -+ [1][1][RTW89_ACMA][0][57] = 127, -+ [1][1][RTW89_CHILE][1][57] = 127, -+ [1][1][RTW89_QATAR][1][57] = 127, -+ [1][1][RTW89_QATAR][0][57] = 127, -+ [1][1][RTW89_UK][1][57] = 127, -+ [1][1][RTW89_UK][0][57] = 127, -+ [1][1][RTW89_FCC][1][59] = -28, -+ [1][1][RTW89_FCC][2][59] = 44, -+ [1][1][RTW89_ETSI][1][59] = 127, -+ [1][1][RTW89_ETSI][0][59] = 127, -+ [1][1][RTW89_MKK][1][59] = 127, -+ [1][1][RTW89_MKK][0][59] = 127, -+ [1][1][RTW89_IC][1][59] = -28, -+ [1][1][RTW89_KCC][1][59] = -14, -+ [1][1][RTW89_KCC][0][59] = 127, -+ [1][1][RTW89_ACMA][1][59] = 127, -+ [1][1][RTW89_ACMA][0][59] = 127, -+ [1][1][RTW89_CHILE][1][59] = 127, -+ [1][1][RTW89_QATAR][1][59] = 127, -+ [1][1][RTW89_QATAR][0][59] = 127, -+ [1][1][RTW89_UK][1][59] = 127, -+ [1][1][RTW89_UK][0][59] = 127, -+ [1][1][RTW89_FCC][1][60] = -28, -+ [1][1][RTW89_FCC][2][60] = 44, -+ [1][1][RTW89_ETSI][1][60] = 127, -+ [1][1][RTW89_ETSI][0][60] = 127, -+ [1][1][RTW89_MKK][1][60] = 127, -+ [1][1][RTW89_MKK][0][60] = 127, -+ [1][1][RTW89_IC][1][60] = -28, -+ [1][1][RTW89_KCC][1][60] = -14, -+ [1][1][RTW89_KCC][0][60] = 127, -+ [1][1][RTW89_ACMA][1][60] = 127, -+ [1][1][RTW89_ACMA][0][60] = 127, -+ [1][1][RTW89_CHILE][1][60] = 127, -+ [1][1][RTW89_QATAR][1][60] = 127, -+ [1][1][RTW89_QATAR][0][60] = 127, -+ [1][1][RTW89_UK][1][60] = 127, -+ [1][1][RTW89_UK][0][60] = 127, -+ [1][1][RTW89_FCC][1][62] = -28, -+ [1][1][RTW89_FCC][2][62] = 44, -+ [1][1][RTW89_ETSI][1][62] = 127, -+ [1][1][RTW89_ETSI][0][62] = 127, -+ [1][1][RTW89_MKK][1][62] = 127, -+ [1][1][RTW89_MKK][0][62] = 127, -+ [1][1][RTW89_IC][1][62] = -28, -+ [1][1][RTW89_KCC][1][62] = -14, -+ [1][1][RTW89_KCC][0][62] = 127, -+ [1][1][RTW89_ACMA][1][62] = 127, -+ [1][1][RTW89_ACMA][0][62] = 127, -+ [1][1][RTW89_CHILE][1][62] = 127, -+ [1][1][RTW89_QATAR][1][62] = 127, -+ [1][1][RTW89_QATAR][0][62] = 127, -+ [1][1][RTW89_UK][1][62] = 127, -+ [1][1][RTW89_UK][0][62] = 127, -+ [1][1][RTW89_FCC][1][64] = -28, -+ [1][1][RTW89_FCC][2][64] = 44, -+ [1][1][RTW89_ETSI][1][64] = 127, -+ [1][1][RTW89_ETSI][0][64] = 127, -+ [1][1][RTW89_MKK][1][64] = 127, -+ [1][1][RTW89_MKK][0][64] = 127, -+ [1][1][RTW89_IC][1][64] = -28, -+ [1][1][RTW89_KCC][1][64] = -14, -+ [1][1][RTW89_KCC][0][64] = 127, -+ [1][1][RTW89_ACMA][1][64] = 127, -+ [1][1][RTW89_ACMA][0][64] = 127, -+ [1][1][RTW89_CHILE][1][64] = 127, -+ [1][1][RTW89_QATAR][1][64] = 127, -+ [1][1][RTW89_QATAR][0][64] = 127, -+ [1][1][RTW89_UK][1][64] = 127, -+ [1][1][RTW89_UK][0][64] = 127, -+ [1][1][RTW89_FCC][1][66] = -28, -+ [1][1][RTW89_FCC][2][66] = 44, -+ [1][1][RTW89_ETSI][1][66] = 127, -+ [1][1][RTW89_ETSI][0][66] = 127, -+ [1][1][RTW89_MKK][1][66] = 127, -+ [1][1][RTW89_MKK][0][66] = 127, -+ [1][1][RTW89_IC][1][66] = -28, -+ [1][1][RTW89_KCC][1][66] = -14, -+ [1][1][RTW89_KCC][0][66] = 127, -+ [1][1][RTW89_ACMA][1][66] = 127, -+ [1][1][RTW89_ACMA][0][66] = 127, -+ [1][1][RTW89_CHILE][1][66] = 127, -+ [1][1][RTW89_QATAR][1][66] = 127, -+ [1][1][RTW89_QATAR][0][66] = 127, -+ [1][1][RTW89_UK][1][66] = 127, -+ [1][1][RTW89_UK][0][66] = 127, -+ [1][1][RTW89_FCC][1][68] = -28, -+ [1][1][RTW89_FCC][2][68] = 44, -+ [1][1][RTW89_ETSI][1][68] = 127, -+ [1][1][RTW89_ETSI][0][68] = 127, -+ [1][1][RTW89_MKK][1][68] = 127, -+ [1][1][RTW89_MKK][0][68] = 127, -+ [1][1][RTW89_IC][1][68] = -28, -+ [1][1][RTW89_KCC][1][68] = -14, -+ [1][1][RTW89_KCC][0][68] = 127, -+ [1][1][RTW89_ACMA][1][68] = 127, -+ [1][1][RTW89_ACMA][0][68] = 127, -+ [1][1][RTW89_CHILE][1][68] = 127, -+ [1][1][RTW89_QATAR][1][68] = 127, -+ [1][1][RTW89_QATAR][0][68] = 127, -+ [1][1][RTW89_UK][1][68] = 127, -+ [1][1][RTW89_UK][0][68] = 127, -+ [1][1][RTW89_FCC][1][70] = -26, -+ [1][1][RTW89_FCC][2][70] = 44, -+ [1][1][RTW89_ETSI][1][70] = 127, -+ [1][1][RTW89_ETSI][0][70] = 127, -+ [1][1][RTW89_MKK][1][70] = 127, -+ [1][1][RTW89_MKK][0][70] = 127, -+ [1][1][RTW89_IC][1][70] = -26, -+ [1][1][RTW89_KCC][1][70] = -14, -+ [1][1][RTW89_KCC][0][70] = 127, -+ [1][1][RTW89_ACMA][1][70] = 127, -+ [1][1][RTW89_ACMA][0][70] = 127, -+ [1][1][RTW89_CHILE][1][70] = 127, -+ [1][1][RTW89_QATAR][1][70] = 127, -+ [1][1][RTW89_QATAR][0][70] = 127, -+ [1][1][RTW89_UK][1][70] = 127, -+ [1][1][RTW89_UK][0][70] = 127, -+ [1][1][RTW89_FCC][1][72] = -28, -+ [1][1][RTW89_FCC][2][72] = 44, -+ [1][1][RTW89_ETSI][1][72] = 127, -+ [1][1][RTW89_ETSI][0][72] = 127, -+ [1][1][RTW89_MKK][1][72] = 127, -+ [1][1][RTW89_MKK][0][72] = 127, -+ [1][1][RTW89_IC][1][72] = -28, -+ [1][1][RTW89_KCC][1][72] = -14, -+ [1][1][RTW89_KCC][0][72] = 127, -+ [1][1][RTW89_ACMA][1][72] = 127, -+ [1][1][RTW89_ACMA][0][72] = 127, -+ [1][1][RTW89_CHILE][1][72] = 127, -+ [1][1][RTW89_QATAR][1][72] = 127, -+ [1][1][RTW89_QATAR][0][72] = 127, -+ [1][1][RTW89_UK][1][72] = 127, -+ [1][1][RTW89_UK][0][72] = 127, -+ [1][1][RTW89_FCC][1][74] = -28, -+ [1][1][RTW89_FCC][2][74] = 44, -+ [1][1][RTW89_ETSI][1][74] = 127, -+ [1][1][RTW89_ETSI][0][74] = 127, -+ [1][1][RTW89_MKK][1][74] = 127, -+ [1][1][RTW89_MKK][0][74] = 127, -+ [1][1][RTW89_IC][1][74] = -28, -+ [1][1][RTW89_KCC][1][74] = -14, -+ [1][1][RTW89_KCC][0][74] = 127, -+ [1][1][RTW89_ACMA][1][74] = 127, -+ [1][1][RTW89_ACMA][0][74] = 127, -+ [1][1][RTW89_CHILE][1][74] = 127, -+ [1][1][RTW89_QATAR][1][74] = 127, -+ [1][1][RTW89_QATAR][0][74] = 127, -+ [1][1][RTW89_UK][1][74] = 127, -+ [1][1][RTW89_UK][0][74] = 127, -+ [1][1][RTW89_FCC][1][75] = -28, -+ [1][1][RTW89_FCC][2][75] = 44, -+ [1][1][RTW89_ETSI][1][75] = 127, -+ [1][1][RTW89_ETSI][0][75] = 127, -+ [1][1][RTW89_MKK][1][75] = 127, -+ [1][1][RTW89_MKK][0][75] = 127, -+ [1][1][RTW89_IC][1][75] = -28, -+ [1][1][RTW89_KCC][1][75] = -14, -+ [1][1][RTW89_KCC][0][75] = 127, -+ [1][1][RTW89_ACMA][1][75] = 127, -+ [1][1][RTW89_ACMA][0][75] = 127, -+ [1][1][RTW89_CHILE][1][75] = 127, -+ [1][1][RTW89_QATAR][1][75] = 127, -+ [1][1][RTW89_QATAR][0][75] = 127, -+ [1][1][RTW89_UK][1][75] = 127, -+ [1][1][RTW89_UK][0][75] = 127, -+ [1][1][RTW89_FCC][1][77] = -28, -+ [1][1][RTW89_FCC][2][77] = 44, -+ [1][1][RTW89_ETSI][1][77] = 127, -+ [1][1][RTW89_ETSI][0][77] = 127, -+ [1][1][RTW89_MKK][1][77] = 127, -+ [1][1][RTW89_MKK][0][77] = 127, -+ [1][1][RTW89_IC][1][77] = -28, -+ [1][1][RTW89_KCC][1][77] = -14, -+ [1][1][RTW89_KCC][0][77] = 127, -+ [1][1][RTW89_ACMA][1][77] = 127, -+ [1][1][RTW89_ACMA][0][77] = 127, -+ [1][1][RTW89_CHILE][1][77] = 127, -+ [1][1][RTW89_QATAR][1][77] = 127, -+ [1][1][RTW89_QATAR][0][77] = 127, -+ [1][1][RTW89_UK][1][77] = 127, -+ [1][1][RTW89_UK][0][77] = 127, -+ [1][1][RTW89_FCC][1][79] = -28, -+ [1][1][RTW89_FCC][2][79] = 44, -+ [1][1][RTW89_ETSI][1][79] = 127, -+ [1][1][RTW89_ETSI][0][79] = 127, -+ [1][1][RTW89_MKK][1][79] = 127, -+ [1][1][RTW89_MKK][0][79] = 127, -+ [1][1][RTW89_IC][1][79] = -28, -+ [1][1][RTW89_KCC][1][79] = -14, -+ [1][1][RTW89_KCC][0][79] = 127, -+ [1][1][RTW89_ACMA][1][79] = 127, -+ [1][1][RTW89_ACMA][0][79] = 127, -+ [1][1][RTW89_CHILE][1][79] = 127, -+ [1][1][RTW89_QATAR][1][79] = 127, -+ [1][1][RTW89_QATAR][0][79] = 127, -+ [1][1][RTW89_UK][1][79] = 127, -+ [1][1][RTW89_UK][0][79] = 127, -+ [1][1][RTW89_FCC][1][81] = -28, -+ [1][1][RTW89_FCC][2][81] = 44, -+ [1][1][RTW89_ETSI][1][81] = 127, -+ [1][1][RTW89_ETSI][0][81] = 127, -+ [1][1][RTW89_MKK][1][81] = 127, -+ [1][1][RTW89_MKK][0][81] = 127, -+ [1][1][RTW89_IC][1][81] = -28, -+ [1][1][RTW89_KCC][1][81] = -14, -+ [1][1][RTW89_KCC][0][81] = 127, -+ [1][1][RTW89_ACMA][1][81] = 127, -+ [1][1][RTW89_ACMA][0][81] = 127, -+ [1][1][RTW89_CHILE][1][81] = 127, -+ [1][1][RTW89_QATAR][1][81] = 127, -+ [1][1][RTW89_QATAR][0][81] = 127, -+ [1][1][RTW89_UK][1][81] = 127, -+ [1][1][RTW89_UK][0][81] = 127, -+ [1][1][RTW89_FCC][1][83] = -28, -+ [1][1][RTW89_FCC][2][83] = 44, -+ [1][1][RTW89_ETSI][1][83] = 127, -+ [1][1][RTW89_ETSI][0][83] = 127, -+ [1][1][RTW89_MKK][1][83] = 127, -+ [1][1][RTW89_MKK][0][83] = 127, -+ [1][1][RTW89_IC][1][83] = -28, -+ [1][1][RTW89_KCC][1][83] = -14, -+ [1][1][RTW89_KCC][0][83] = 127, -+ [1][1][RTW89_ACMA][1][83] = 127, -+ [1][1][RTW89_ACMA][0][83] = 127, -+ [1][1][RTW89_CHILE][1][83] = 127, -+ [1][1][RTW89_QATAR][1][83] = 127, -+ [1][1][RTW89_QATAR][0][83] = 127, -+ [1][1][RTW89_UK][1][83] = 127, -+ [1][1][RTW89_UK][0][83] = 127, -+ [1][1][RTW89_FCC][1][85] = -28, -+ [1][1][RTW89_FCC][2][85] = 44, -+ [1][1][RTW89_ETSI][1][85] = 127, -+ [1][1][RTW89_ETSI][0][85] = 127, -+ [1][1][RTW89_MKK][1][85] = 127, -+ [1][1][RTW89_MKK][0][85] = 127, -+ [1][1][RTW89_IC][1][85] = -28, -+ [1][1][RTW89_KCC][1][85] = -14, -+ [1][1][RTW89_KCC][0][85] = 127, -+ [1][1][RTW89_ACMA][1][85] = 127, -+ [1][1][RTW89_ACMA][0][85] = 127, -+ [1][1][RTW89_CHILE][1][85] = 127, -+ [1][1][RTW89_QATAR][1][85] = 127, -+ [1][1][RTW89_QATAR][0][85] = 127, -+ [1][1][RTW89_UK][1][85] = 127, -+ [1][1][RTW89_UK][0][85] = 127, -+ [1][1][RTW89_FCC][1][87] = -28, -+ [1][1][RTW89_FCC][2][87] = 127, -+ [1][1][RTW89_ETSI][1][87] = 127, -+ [1][1][RTW89_ETSI][0][87] = 127, -+ [1][1][RTW89_MKK][1][87] = 127, -+ [1][1][RTW89_MKK][0][87] = 127, -+ [1][1][RTW89_IC][1][87] = -28, -+ [1][1][RTW89_KCC][1][87] = -14, -+ [1][1][RTW89_KCC][0][87] = 127, -+ [1][1][RTW89_ACMA][1][87] = 127, -+ [1][1][RTW89_ACMA][0][87] = 127, -+ [1][1][RTW89_CHILE][1][87] = 127, -+ [1][1][RTW89_QATAR][1][87] = 127, -+ [1][1][RTW89_QATAR][0][87] = 127, -+ [1][1][RTW89_UK][1][87] = 127, -+ [1][1][RTW89_UK][0][87] = 127, -+ [1][1][RTW89_FCC][1][89] = -26, -+ [1][1][RTW89_FCC][2][89] = 127, -+ [1][1][RTW89_ETSI][1][89] = 127, -+ [1][1][RTW89_ETSI][0][89] = 127, -+ [1][1][RTW89_MKK][1][89] = 127, -+ [1][1][RTW89_MKK][0][89] = 127, -+ [1][1][RTW89_IC][1][89] = -26, -+ [1][1][RTW89_KCC][1][89] = -14, -+ [1][1][RTW89_KCC][0][89] = 127, -+ [1][1][RTW89_ACMA][1][89] = 127, -+ [1][1][RTW89_ACMA][0][89] = 127, -+ [1][1][RTW89_CHILE][1][89] = 127, -+ [1][1][RTW89_QATAR][1][89] = 127, -+ [1][1][RTW89_QATAR][0][89] = 127, -+ [1][1][RTW89_UK][1][89] = 127, -+ [1][1][RTW89_UK][0][89] = 127, -+ [1][1][RTW89_FCC][1][90] = -26, -+ [1][1][RTW89_FCC][2][90] = 127, -+ [1][1][RTW89_ETSI][1][90] = 127, -+ [1][1][RTW89_ETSI][0][90] = 127, -+ [1][1][RTW89_MKK][1][90] = 127, -+ [1][1][RTW89_MKK][0][90] = 127, -+ [1][1][RTW89_IC][1][90] = -26, -+ [1][1][RTW89_KCC][1][90] = -14, -+ [1][1][RTW89_KCC][0][90] = 127, -+ [1][1][RTW89_ACMA][1][90] = 127, -+ [1][1][RTW89_ACMA][0][90] = 127, -+ [1][1][RTW89_CHILE][1][90] = 127, -+ [1][1][RTW89_QATAR][1][90] = 127, -+ [1][1][RTW89_QATAR][0][90] = 127, -+ [1][1][RTW89_UK][1][90] = 127, -+ [1][1][RTW89_UK][0][90] = 127, -+ [1][1][RTW89_FCC][1][92] = -26, -+ [1][1][RTW89_FCC][2][92] = 127, -+ [1][1][RTW89_ETSI][1][92] = 127, -+ [1][1][RTW89_ETSI][0][92] = 127, -+ [1][1][RTW89_MKK][1][92] = 127, -+ [1][1][RTW89_MKK][0][92] = 127, -+ [1][1][RTW89_IC][1][92] = -26, -+ [1][1][RTW89_KCC][1][92] = -14, -+ [1][1][RTW89_KCC][0][92] = 127, -+ [1][1][RTW89_ACMA][1][92] = 127, -+ [1][1][RTW89_ACMA][0][92] = 127, -+ [1][1][RTW89_CHILE][1][92] = 127, -+ [1][1][RTW89_QATAR][1][92] = 127, -+ [1][1][RTW89_QATAR][0][92] = 127, -+ [1][1][RTW89_UK][1][92] = 127, -+ [1][1][RTW89_UK][0][92] = 127, -+ [1][1][RTW89_FCC][1][94] = -26, -+ [1][1][RTW89_FCC][2][94] = 127, -+ [1][1][RTW89_ETSI][1][94] = 127, -+ [1][1][RTW89_ETSI][0][94] = 127, -+ [1][1][RTW89_MKK][1][94] = 127, -+ [1][1][RTW89_MKK][0][94] = 127, -+ [1][1][RTW89_IC][1][94] = -26, -+ [1][1][RTW89_KCC][1][94] = -14, -+ [1][1][RTW89_KCC][0][94] = 127, -+ [1][1][RTW89_ACMA][1][94] = 127, -+ [1][1][RTW89_ACMA][0][94] = 127, -+ [1][1][RTW89_CHILE][1][94] = 127, -+ [1][1][RTW89_QATAR][1][94] = 127, -+ [1][1][RTW89_QATAR][0][94] = 127, -+ [1][1][RTW89_UK][1][94] = 127, -+ [1][1][RTW89_UK][0][94] = 127, -+ [1][1][RTW89_FCC][1][96] = -26, -+ [1][1][RTW89_FCC][2][96] = 127, -+ [1][1][RTW89_ETSI][1][96] = 127, -+ [1][1][RTW89_ETSI][0][96] = 127, -+ [1][1][RTW89_MKK][1][96] = 127, -+ [1][1][RTW89_MKK][0][96] = 127, -+ [1][1][RTW89_IC][1][96] = -26, -+ [1][1][RTW89_KCC][1][96] = -14, -+ [1][1][RTW89_KCC][0][96] = 127, -+ [1][1][RTW89_ACMA][1][96] = 127, -+ [1][1][RTW89_ACMA][0][96] = 127, -+ [1][1][RTW89_CHILE][1][96] = 127, -+ [1][1][RTW89_QATAR][1][96] = 127, -+ [1][1][RTW89_QATAR][0][96] = 127, -+ [1][1][RTW89_UK][1][96] = 127, -+ [1][1][RTW89_UK][0][96] = 127, -+ [1][1][RTW89_FCC][1][98] = -26, -+ [1][1][RTW89_FCC][2][98] = 127, -+ [1][1][RTW89_ETSI][1][98] = 127, -+ [1][1][RTW89_ETSI][0][98] = 127, -+ [1][1][RTW89_MKK][1][98] = 127, -+ [1][1][RTW89_MKK][0][98] = 127, -+ [1][1][RTW89_IC][1][98] = -26, -+ [1][1][RTW89_KCC][1][98] = -14, -+ [1][1][RTW89_KCC][0][98] = 127, -+ [1][1][RTW89_ACMA][1][98] = 127, -+ [1][1][RTW89_ACMA][0][98] = 127, -+ [1][1][RTW89_CHILE][1][98] = 127, -+ [1][1][RTW89_QATAR][1][98] = 127, -+ [1][1][RTW89_QATAR][0][98] = 127, -+ [1][1][RTW89_UK][1][98] = 127, -+ [1][1][RTW89_UK][0][98] = 127, -+ [1][1][RTW89_FCC][1][100] = -26, -+ [1][1][RTW89_FCC][2][100] = 127, -+ [1][1][RTW89_ETSI][1][100] = 127, -+ [1][1][RTW89_ETSI][0][100] = 127, -+ [1][1][RTW89_MKK][1][100] = 127, -+ [1][1][RTW89_MKK][0][100] = 127, -+ [1][1][RTW89_IC][1][100] = -26, -+ [1][1][RTW89_KCC][1][100] = -14, -+ [1][1][RTW89_KCC][0][100] = 127, -+ [1][1][RTW89_ACMA][1][100] = 127, -+ [1][1][RTW89_ACMA][0][100] = 127, -+ [1][1][RTW89_CHILE][1][100] = 127, -+ [1][1][RTW89_QATAR][1][100] = 127, -+ [1][1][RTW89_QATAR][0][100] = 127, -+ [1][1][RTW89_UK][1][100] = 127, -+ [1][1][RTW89_UK][0][100] = 127, -+ [1][1][RTW89_FCC][1][102] = -26, -+ [1][1][RTW89_FCC][2][102] = 127, -+ [1][1][RTW89_ETSI][1][102] = 127, -+ [1][1][RTW89_ETSI][0][102] = 127, -+ [1][1][RTW89_MKK][1][102] = 127, -+ [1][1][RTW89_MKK][0][102] = 127, -+ [1][1][RTW89_IC][1][102] = -26, -+ [1][1][RTW89_KCC][1][102] = -14, -+ [1][1][RTW89_KCC][0][102] = 127, -+ [1][1][RTW89_ACMA][1][102] = 127, -+ [1][1][RTW89_ACMA][0][102] = 127, -+ [1][1][RTW89_CHILE][1][102] = 127, -+ [1][1][RTW89_QATAR][1][102] = 127, -+ [1][1][RTW89_QATAR][0][102] = 127, -+ [1][1][RTW89_UK][1][102] = 127, -+ [1][1][RTW89_UK][0][102] = 127, -+ [1][1][RTW89_FCC][1][104] = -26, -+ [1][1][RTW89_FCC][2][104] = 127, -+ [1][1][RTW89_ETSI][1][104] = 127, -+ [1][1][RTW89_ETSI][0][104] = 127, -+ [1][1][RTW89_MKK][1][104] = 127, -+ [1][1][RTW89_MKK][0][104] = 127, -+ [1][1][RTW89_IC][1][104] = -26, -+ [1][1][RTW89_KCC][1][104] = -14, -+ [1][1][RTW89_KCC][0][104] = 127, -+ [1][1][RTW89_ACMA][1][104] = 127, -+ [1][1][RTW89_ACMA][0][104] = 127, -+ [1][1][RTW89_CHILE][1][104] = 127, -+ [1][1][RTW89_QATAR][1][104] = 127, -+ [1][1][RTW89_QATAR][0][104] = 127, -+ [1][1][RTW89_UK][1][104] = 127, -+ [1][1][RTW89_UK][0][104] = 127, -+ [1][1][RTW89_FCC][1][105] = -26, -+ [1][1][RTW89_FCC][2][105] = 127, -+ [1][1][RTW89_ETSI][1][105] = 127, -+ [1][1][RTW89_ETSI][0][105] = 127, -+ [1][1][RTW89_MKK][1][105] = 127, -+ [1][1][RTW89_MKK][0][105] = 127, -+ [1][1][RTW89_IC][1][105] = -26, -+ [1][1][RTW89_KCC][1][105] = -14, -+ [1][1][RTW89_KCC][0][105] = 127, -+ [1][1][RTW89_ACMA][1][105] = 127, -+ [1][1][RTW89_ACMA][0][105] = 127, -+ [1][1][RTW89_CHILE][1][105] = 127, -+ [1][1][RTW89_QATAR][1][105] = 127, -+ [1][1][RTW89_QATAR][0][105] = 127, -+ [1][1][RTW89_UK][1][105] = 127, -+ [1][1][RTW89_UK][0][105] = 127, -+ [1][1][RTW89_FCC][1][107] = -22, -+ [1][1][RTW89_FCC][2][107] = 127, -+ [1][1][RTW89_ETSI][1][107] = 127, -+ [1][1][RTW89_ETSI][0][107] = 127, -+ [1][1][RTW89_MKK][1][107] = 127, -+ [1][1][RTW89_MKK][0][107] = 127, -+ [1][1][RTW89_IC][1][107] = -22, -+ [1][1][RTW89_KCC][1][107] = -14, -+ [1][1][RTW89_KCC][0][107] = 127, -+ [1][1][RTW89_ACMA][1][107] = 127, -+ [1][1][RTW89_ACMA][0][107] = 127, -+ [1][1][RTW89_CHILE][1][107] = 127, -+ [1][1][RTW89_QATAR][1][107] = 127, -+ [1][1][RTW89_QATAR][0][107] = 127, -+ [1][1][RTW89_UK][1][107] = 127, -+ [1][1][RTW89_UK][0][107] = 127, -+ [1][1][RTW89_FCC][1][109] = -22, -+ [1][1][RTW89_FCC][2][109] = 127, -+ [1][1][RTW89_ETSI][1][109] = 127, -+ [1][1][RTW89_ETSI][0][109] = 127, -+ [1][1][RTW89_MKK][1][109] = 127, -+ [1][1][RTW89_MKK][0][109] = 127, -+ [1][1][RTW89_IC][1][109] = -22, -+ [1][1][RTW89_KCC][1][109] = 127, -+ [1][1][RTW89_KCC][0][109] = 127, -+ [1][1][RTW89_ACMA][1][109] = 127, -+ [1][1][RTW89_ACMA][0][109] = 127, -+ [1][1][RTW89_CHILE][1][109] = 127, -+ [1][1][RTW89_QATAR][1][109] = 127, -+ [1][1][RTW89_QATAR][0][109] = 127, -+ [1][1][RTW89_UK][1][109] = 127, -+ [1][1][RTW89_UK][0][109] = 127, -+ [1][1][RTW89_FCC][1][111] = 127, -+ [1][1][RTW89_FCC][2][111] = 127, -+ [1][1][RTW89_ETSI][1][111] = 127, -+ [1][1][RTW89_ETSI][0][111] = 127, -+ [1][1][RTW89_MKK][1][111] = 127, -+ [1][1][RTW89_MKK][0][111] = 127, -+ [1][1][RTW89_IC][1][111] = 127, -+ [1][1][RTW89_KCC][1][111] = 127, -+ [1][1][RTW89_KCC][0][111] = 127, -+ [1][1][RTW89_ACMA][1][111] = 127, -+ [1][1][RTW89_ACMA][0][111] = 127, -+ [1][1][RTW89_CHILE][1][111] = 127, -+ [1][1][RTW89_QATAR][1][111] = 127, -+ [1][1][RTW89_QATAR][0][111] = 127, -+ [1][1][RTW89_UK][1][111] = 127, -+ [1][1][RTW89_UK][0][111] = 127, -+ [1][1][RTW89_FCC][1][113] = 127, -+ [1][1][RTW89_FCC][2][113] = 127, -+ [1][1][RTW89_ETSI][1][113] = 127, -+ [1][1][RTW89_ETSI][0][113] = 127, -+ [1][1][RTW89_MKK][1][113] = 127, -+ [1][1][RTW89_MKK][0][113] = 127, -+ [1][1][RTW89_IC][1][113] = 127, -+ [1][1][RTW89_KCC][1][113] = 127, -+ [1][1][RTW89_KCC][0][113] = 127, -+ [1][1][RTW89_ACMA][1][113] = 127, -+ [1][1][RTW89_ACMA][0][113] = 127, -+ [1][1][RTW89_CHILE][1][113] = 127, -+ [1][1][RTW89_QATAR][1][113] = 127, -+ [1][1][RTW89_QATAR][0][113] = 127, -+ [1][1][RTW89_UK][1][113] = 127, -+ [1][1][RTW89_UK][0][113] = 127, -+ [1][1][RTW89_FCC][1][115] = 127, -+ [1][1][RTW89_FCC][2][115] = 127, -+ [1][1][RTW89_ETSI][1][115] = 127, -+ [1][1][RTW89_ETSI][0][115] = 127, -+ [1][1][RTW89_MKK][1][115] = 127, -+ [1][1][RTW89_MKK][0][115] = 127, -+ [1][1][RTW89_IC][1][115] = 127, -+ [1][1][RTW89_KCC][1][115] = 127, -+ [1][1][RTW89_KCC][0][115] = 127, -+ [1][1][RTW89_ACMA][1][115] = 127, -+ [1][1][RTW89_ACMA][0][115] = 127, -+ [1][1][RTW89_CHILE][1][115] = 127, -+ [1][1][RTW89_QATAR][1][115] = 127, -+ [1][1][RTW89_QATAR][0][115] = 127, -+ [1][1][RTW89_UK][1][115] = 127, -+ [1][1][RTW89_UK][0][115] = 127, -+ [1][1][RTW89_FCC][1][117] = 127, -+ [1][1][RTW89_FCC][2][117] = 127, -+ [1][1][RTW89_ETSI][1][117] = 127, -+ [1][1][RTW89_ETSI][0][117] = 127, -+ [1][1][RTW89_MKK][1][117] = 127, -+ [1][1][RTW89_MKK][0][117] = 127, -+ [1][1][RTW89_IC][1][117] = 127, -+ [1][1][RTW89_KCC][1][117] = 127, -+ [1][1][RTW89_KCC][0][117] = 127, -+ [1][1][RTW89_ACMA][1][117] = 127, -+ [1][1][RTW89_ACMA][0][117] = 127, -+ [1][1][RTW89_CHILE][1][117] = 127, -+ [1][1][RTW89_QATAR][1][117] = 127, -+ [1][1][RTW89_QATAR][0][117] = 127, -+ [1][1][RTW89_UK][1][117] = 127, -+ [1][1][RTW89_UK][0][117] = 127, -+ [1][1][RTW89_FCC][1][119] = 127, -+ [1][1][RTW89_FCC][2][119] = 127, -+ [1][1][RTW89_ETSI][1][119] = 127, -+ [1][1][RTW89_ETSI][0][119] = 127, -+ [1][1][RTW89_MKK][1][119] = 127, -+ [1][1][RTW89_MKK][0][119] = 127, -+ [1][1][RTW89_IC][1][119] = 127, -+ [1][1][RTW89_KCC][1][119] = 127, -+ [1][1][RTW89_KCC][0][119] = 127, -+ [1][1][RTW89_ACMA][1][119] = 127, -+ [1][1][RTW89_ACMA][0][119] = 127, -+ [1][1][RTW89_CHILE][1][119] = 127, -+ [1][1][RTW89_QATAR][1][119] = 127, -+ [1][1][RTW89_QATAR][0][119] = 127, -+ [1][1][RTW89_UK][1][119] = 127, -+ [1][1][RTW89_UK][0][119] = 127, -+ [2][0][RTW89_FCC][1][0] = 8, -+ [2][0][RTW89_FCC][2][0] = 60, -+ [2][0][RTW89_ETSI][1][0] = 56, -+ [2][0][RTW89_ETSI][0][0] = 18, -+ [2][0][RTW89_MKK][1][0] = 54, -+ [2][0][RTW89_MKK][0][0] = 14, -+ [2][0][RTW89_IC][1][0] = 8, -+ [2][0][RTW89_KCC][1][0] = -2, -+ [2][0][RTW89_KCC][0][0] = -2, -+ [2][0][RTW89_ACMA][1][0] = 56, -+ [2][0][RTW89_ACMA][0][0] = 18, -+ [2][0][RTW89_CHILE][1][0] = 8, -+ [2][0][RTW89_QATAR][1][0] = 56, -+ [2][0][RTW89_QATAR][0][0] = 18, -+ [2][0][RTW89_UK][1][0] = 56, -+ [2][0][RTW89_UK][0][0] = 18, -+ [2][0][RTW89_FCC][1][2] = 8, -+ [2][0][RTW89_FCC][2][2] = 60, -+ [2][0][RTW89_ETSI][1][2] = 56, -+ [2][0][RTW89_ETSI][0][2] = 18, -+ [2][0][RTW89_MKK][1][2] = 54, -+ [2][0][RTW89_MKK][0][2] = 14, -+ [2][0][RTW89_IC][1][2] = 8, -+ [2][0][RTW89_KCC][1][2] = -2, -+ [2][0][RTW89_KCC][0][2] = -2, -+ [2][0][RTW89_ACMA][1][2] = 56, -+ [2][0][RTW89_ACMA][0][2] = 18, -+ [2][0][RTW89_CHILE][1][2] = 8, -+ [2][0][RTW89_QATAR][1][2] = 56, -+ [2][0][RTW89_QATAR][0][2] = 18, -+ [2][0][RTW89_UK][1][2] = 56, -+ [2][0][RTW89_UK][0][2] = 18, -+ [2][0][RTW89_FCC][1][4] = 8, -+ [2][0][RTW89_FCC][2][4] = 60, -+ [2][0][RTW89_ETSI][1][4] = 56, -+ [2][0][RTW89_ETSI][0][4] = 18, -+ [2][0][RTW89_MKK][1][4] = 54, -+ [2][0][RTW89_MKK][0][4] = 14, -+ [2][0][RTW89_IC][1][4] = 8, -+ [2][0][RTW89_KCC][1][4] = -2, -+ [2][0][RTW89_KCC][0][4] = -2, -+ [2][0][RTW89_ACMA][1][4] = 56, -+ [2][0][RTW89_ACMA][0][4] = 18, -+ [2][0][RTW89_CHILE][1][4] = 8, -+ [2][0][RTW89_QATAR][1][4] = 56, -+ [2][0][RTW89_QATAR][0][4] = 18, -+ [2][0][RTW89_UK][1][4] = 56, -+ [2][0][RTW89_UK][0][4] = 18, -+ [2][0][RTW89_FCC][1][6] = 8, -+ [2][0][RTW89_FCC][2][6] = 60, -+ [2][0][RTW89_ETSI][1][6] = 56, -+ [2][0][RTW89_ETSI][0][6] = 18, -+ [2][0][RTW89_MKK][1][6] = 54, -+ [2][0][RTW89_MKK][0][6] = 14, -+ [2][0][RTW89_IC][1][6] = 8, -+ [2][0][RTW89_KCC][1][6] = -2, -+ [2][0][RTW89_KCC][0][6] = -2, -+ [2][0][RTW89_ACMA][1][6] = 56, -+ [2][0][RTW89_ACMA][0][6] = 18, -+ [2][0][RTW89_CHILE][1][6] = 8, -+ [2][0][RTW89_QATAR][1][6] = 56, -+ [2][0][RTW89_QATAR][0][6] = 18, -+ [2][0][RTW89_UK][1][6] = 56, -+ [2][0][RTW89_UK][0][6] = 18, -+ [2][0][RTW89_FCC][1][8] = 8, -+ [2][0][RTW89_FCC][2][8] = 60, -+ [2][0][RTW89_ETSI][1][8] = 56, -+ [2][0][RTW89_ETSI][0][8] = 18, -+ [2][0][RTW89_MKK][1][8] = 54, -+ [2][0][RTW89_MKK][0][8] = 14, -+ [2][0][RTW89_IC][1][8] = 8, -+ [2][0][RTW89_KCC][1][8] = -2, -+ [2][0][RTW89_KCC][0][8] = -2, -+ [2][0][RTW89_ACMA][1][8] = 56, -+ [2][0][RTW89_ACMA][0][8] = 18, -+ [2][0][RTW89_CHILE][1][8] = 8, -+ [2][0][RTW89_QATAR][1][8] = 56, -+ [2][0][RTW89_QATAR][0][8] = 18, -+ [2][0][RTW89_UK][1][8] = 56, -+ [2][0][RTW89_UK][0][8] = 18, -+ [2][0][RTW89_FCC][1][10] = 8, -+ [2][0][RTW89_FCC][2][10] = 60, -+ [2][0][RTW89_ETSI][1][10] = 56, -+ [2][0][RTW89_ETSI][0][10] = 18, -+ [2][0][RTW89_MKK][1][10] = 54, -+ [2][0][RTW89_MKK][0][10] = 14, -+ [2][0][RTW89_IC][1][10] = 8, -+ [2][0][RTW89_KCC][1][10] = -2, -+ [2][0][RTW89_KCC][0][10] = -2, -+ [2][0][RTW89_ACMA][1][10] = 56, -+ [2][0][RTW89_ACMA][0][10] = 18, -+ [2][0][RTW89_CHILE][1][10] = 8, -+ [2][0][RTW89_QATAR][1][10] = 56, -+ [2][0][RTW89_QATAR][0][10] = 18, -+ [2][0][RTW89_UK][1][10] = 56, -+ [2][0][RTW89_UK][0][10] = 18, -+ [2][0][RTW89_FCC][1][12] = 8, -+ [2][0][RTW89_FCC][2][12] = 60, -+ [2][0][RTW89_ETSI][1][12] = 56, -+ [2][0][RTW89_ETSI][0][12] = 18, -+ [2][0][RTW89_MKK][1][12] = 54, -+ [2][0][RTW89_MKK][0][12] = 14, -+ [2][0][RTW89_IC][1][12] = 8, -+ [2][0][RTW89_KCC][1][12] = -2, -+ [2][0][RTW89_KCC][0][12] = -2, -+ [2][0][RTW89_ACMA][1][12] = 56, -+ [2][0][RTW89_ACMA][0][12] = 18, -+ [2][0][RTW89_CHILE][1][12] = 8, -+ [2][0][RTW89_QATAR][1][12] = 56, -+ [2][0][RTW89_QATAR][0][12] = 18, -+ [2][0][RTW89_UK][1][12] = 56, -+ [2][0][RTW89_UK][0][12] = 18, -+ [2][0][RTW89_FCC][1][14] = 8, -+ [2][0][RTW89_FCC][2][14] = 60, -+ [2][0][RTW89_ETSI][1][14] = 56, -+ [2][0][RTW89_ETSI][0][14] = 18, -+ [2][0][RTW89_MKK][1][14] = 54, -+ [2][0][RTW89_MKK][0][14] = 14, -+ [2][0][RTW89_IC][1][14] = 8, -+ [2][0][RTW89_KCC][1][14] = -2, -+ [2][0][RTW89_KCC][0][14] = -2, -+ [2][0][RTW89_ACMA][1][14] = 56, -+ [2][0][RTW89_ACMA][0][14] = 18, -+ [2][0][RTW89_CHILE][1][14] = 8, -+ [2][0][RTW89_QATAR][1][14] = 56, -+ [2][0][RTW89_QATAR][0][14] = 18, -+ [2][0][RTW89_UK][1][14] = 56, -+ [2][0][RTW89_UK][0][14] = 18, -+ [2][0][RTW89_FCC][1][15] = 8, -+ [2][0][RTW89_FCC][2][15] = 60, -+ [2][0][RTW89_ETSI][1][15] = 56, -+ [2][0][RTW89_ETSI][0][15] = 18, -+ [2][0][RTW89_MKK][1][15] = 54, -+ [2][0][RTW89_MKK][0][15] = 14, -+ [2][0][RTW89_IC][1][15] = 8, -+ [2][0][RTW89_KCC][1][15] = -2, -+ [2][0][RTW89_KCC][0][15] = -2, -+ [2][0][RTW89_ACMA][1][15] = 56, -+ [2][0][RTW89_ACMA][0][15] = 18, -+ [2][0][RTW89_CHILE][1][15] = 8, -+ [2][0][RTW89_QATAR][1][15] = 56, -+ [2][0][RTW89_QATAR][0][15] = 18, -+ [2][0][RTW89_UK][1][15] = 56, -+ [2][0][RTW89_UK][0][15] = 18, -+ [2][0][RTW89_FCC][1][17] = 8, -+ [2][0][RTW89_FCC][2][17] = 60, -+ [2][0][RTW89_ETSI][1][17] = 56, -+ [2][0][RTW89_ETSI][0][17] = 18, -+ [2][0][RTW89_MKK][1][17] = 54, -+ [2][0][RTW89_MKK][0][17] = 14, -+ [2][0][RTW89_IC][1][17] = 8, -+ [2][0][RTW89_KCC][1][17] = -2, -+ [2][0][RTW89_KCC][0][17] = -2, -+ [2][0][RTW89_ACMA][1][17] = 56, -+ [2][0][RTW89_ACMA][0][17] = 18, -+ [2][0][RTW89_CHILE][1][17] = 8, -+ [2][0][RTW89_QATAR][1][17] = 56, -+ [2][0][RTW89_QATAR][0][17] = 18, -+ [2][0][RTW89_UK][1][17] = 56, -+ [2][0][RTW89_UK][0][17] = 18, -+ [2][0][RTW89_FCC][1][19] = 8, -+ [2][0][RTW89_FCC][2][19] = 60, -+ [2][0][RTW89_ETSI][1][19] = 56, -+ [2][0][RTW89_ETSI][0][19] = 18, -+ [2][0][RTW89_MKK][1][19] = 54, -+ [2][0][RTW89_MKK][0][19] = 14, -+ [2][0][RTW89_IC][1][19] = 8, -+ [2][0][RTW89_KCC][1][19] = -2, -+ [2][0][RTW89_KCC][0][19] = -2, -+ [2][0][RTW89_ACMA][1][19] = 56, -+ [2][0][RTW89_ACMA][0][19] = 18, -+ [2][0][RTW89_CHILE][1][19] = 8, -+ [2][0][RTW89_QATAR][1][19] = 56, -+ [2][0][RTW89_QATAR][0][19] = 18, -+ [2][0][RTW89_UK][1][19] = 56, -+ [2][0][RTW89_UK][0][19] = 18, -+ [2][0][RTW89_FCC][1][21] = 8, -+ [2][0][RTW89_FCC][2][21] = 60, -+ [2][0][RTW89_ETSI][1][21] = 56, -+ [2][0][RTW89_ETSI][0][21] = 18, -+ [2][0][RTW89_MKK][1][21] = 54, -+ [2][0][RTW89_MKK][0][21] = 14, -+ [2][0][RTW89_IC][1][21] = 8, -+ [2][0][RTW89_KCC][1][21] = -2, -+ [2][0][RTW89_KCC][0][21] = -2, -+ [2][0][RTW89_ACMA][1][21] = 56, -+ [2][0][RTW89_ACMA][0][21] = 18, -+ [2][0][RTW89_CHILE][1][21] = 8, -+ [2][0][RTW89_QATAR][1][21] = 56, -+ [2][0][RTW89_QATAR][0][21] = 18, -+ [2][0][RTW89_UK][1][21] = 56, -+ [2][0][RTW89_UK][0][21] = 18, -+ [2][0][RTW89_FCC][1][23] = 8, -+ [2][0][RTW89_FCC][2][23] = 78, -+ [2][0][RTW89_ETSI][1][23] = 56, -+ [2][0][RTW89_ETSI][0][23] = 18, -+ [2][0][RTW89_MKK][1][23] = 56, -+ [2][0][RTW89_MKK][0][23] = 14, -+ [2][0][RTW89_IC][1][23] = 8, -+ [2][0][RTW89_KCC][1][23] = -2, -+ [2][0][RTW89_KCC][0][23] = -2, -+ [2][0][RTW89_ACMA][1][23] = 56, -+ [2][0][RTW89_ACMA][0][23] = 18, -+ [2][0][RTW89_CHILE][1][23] = 8, -+ [2][0][RTW89_QATAR][1][23] = 56, -+ [2][0][RTW89_QATAR][0][23] = 18, -+ [2][0][RTW89_UK][1][23] = 56, -+ [2][0][RTW89_UK][0][23] = 18, -+ [2][0][RTW89_FCC][1][25] = 8, -+ [2][0][RTW89_FCC][2][25] = 78, -+ [2][0][RTW89_ETSI][1][25] = 56, -+ [2][0][RTW89_ETSI][0][25] = 18, -+ [2][0][RTW89_MKK][1][25] = 56, -+ [2][0][RTW89_MKK][0][25] = 14, -+ [2][0][RTW89_IC][1][25] = 8, -+ [2][0][RTW89_KCC][1][25] = -2, -+ [2][0][RTW89_KCC][0][25] = -2, -+ [2][0][RTW89_ACMA][1][25] = 56, -+ [2][0][RTW89_ACMA][0][25] = 18, -+ [2][0][RTW89_CHILE][1][25] = 8, -+ [2][0][RTW89_QATAR][1][25] = 56, -+ [2][0][RTW89_QATAR][0][25] = 18, -+ [2][0][RTW89_UK][1][25] = 56, -+ [2][0][RTW89_UK][0][25] = 18, -+ [2][0][RTW89_FCC][1][27] = 8, -+ [2][0][RTW89_FCC][2][27] = 78, -+ [2][0][RTW89_ETSI][1][27] = 56, -+ [2][0][RTW89_ETSI][0][27] = 18, -+ [2][0][RTW89_MKK][1][27] = 56, -+ [2][0][RTW89_MKK][0][27] = 14, -+ [2][0][RTW89_IC][1][27] = 8, -+ [2][0][RTW89_KCC][1][27] = -2, -+ [2][0][RTW89_KCC][0][27] = -2, -+ [2][0][RTW89_ACMA][1][27] = 56, -+ [2][0][RTW89_ACMA][0][27] = 18, -+ [2][0][RTW89_CHILE][1][27] = 8, -+ [2][0][RTW89_QATAR][1][27] = 56, -+ [2][0][RTW89_QATAR][0][27] = 18, -+ [2][0][RTW89_UK][1][27] = 56, -+ [2][0][RTW89_UK][0][27] = 18, -+ [2][0][RTW89_FCC][1][29] = 8, -+ [2][0][RTW89_FCC][2][29] = 78, -+ [2][0][RTW89_ETSI][1][29] = 56, -+ [2][0][RTW89_ETSI][0][29] = 18, -+ [2][0][RTW89_MKK][1][29] = 56, -+ [2][0][RTW89_MKK][0][29] = 14, -+ [2][0][RTW89_IC][1][29] = 8, -+ [2][0][RTW89_KCC][1][29] = -2, -+ [2][0][RTW89_KCC][0][29] = -2, -+ [2][0][RTW89_ACMA][1][29] = 56, -+ [2][0][RTW89_ACMA][0][29] = 18, -+ [2][0][RTW89_CHILE][1][29] = 8, -+ [2][0][RTW89_QATAR][1][29] = 56, -+ [2][0][RTW89_QATAR][0][29] = 18, -+ [2][0][RTW89_UK][1][29] = 56, -+ [2][0][RTW89_UK][0][29] = 18, -+ [2][0][RTW89_FCC][1][30] = 8, -+ [2][0][RTW89_FCC][2][30] = 78, -+ [2][0][RTW89_ETSI][1][30] = 56, -+ [2][0][RTW89_ETSI][0][30] = 18, -+ [2][0][RTW89_MKK][1][30] = 56, -+ [2][0][RTW89_MKK][0][30] = 14, -+ [2][0][RTW89_IC][1][30] = 8, -+ [2][0][RTW89_KCC][1][30] = -2, -+ [2][0][RTW89_KCC][0][30] = -2, -+ [2][0][RTW89_ACMA][1][30] = 56, -+ [2][0][RTW89_ACMA][0][30] = 18, -+ [2][0][RTW89_CHILE][1][30] = 8, -+ [2][0][RTW89_QATAR][1][30] = 56, -+ [2][0][RTW89_QATAR][0][30] = 18, -+ [2][0][RTW89_UK][1][30] = 56, -+ [2][0][RTW89_UK][0][30] = 18, -+ [2][0][RTW89_FCC][1][32] = 8, -+ [2][0][RTW89_FCC][2][32] = 78, -+ [2][0][RTW89_ETSI][1][32] = 56, -+ [2][0][RTW89_ETSI][0][32] = 18, -+ [2][0][RTW89_MKK][1][32] = 56, -+ [2][0][RTW89_MKK][0][32] = 14, -+ [2][0][RTW89_IC][1][32] = 8, -+ [2][0][RTW89_KCC][1][32] = -2, -+ [2][0][RTW89_KCC][0][32] = -2, -+ [2][0][RTW89_ACMA][1][32] = 56, -+ [2][0][RTW89_ACMA][0][32] = 18, -+ [2][0][RTW89_CHILE][1][32] = 8, -+ [2][0][RTW89_QATAR][1][32] = 56, -+ [2][0][RTW89_QATAR][0][32] = 18, -+ [2][0][RTW89_UK][1][32] = 56, -+ [2][0][RTW89_UK][0][32] = 18, -+ [2][0][RTW89_FCC][1][34] = 8, -+ [2][0][RTW89_FCC][2][34] = 78, -+ [2][0][RTW89_ETSI][1][34] = 56, -+ [2][0][RTW89_ETSI][0][34] = 18, -+ [2][0][RTW89_MKK][1][34] = 56, -+ [2][0][RTW89_MKK][0][34] = 14, -+ [2][0][RTW89_IC][1][34] = 8, -+ [2][0][RTW89_KCC][1][34] = -2, -+ [2][0][RTW89_KCC][0][34] = -2, -+ [2][0][RTW89_ACMA][1][34] = 56, -+ [2][0][RTW89_ACMA][0][34] = 18, -+ [2][0][RTW89_CHILE][1][34] = 8, -+ [2][0][RTW89_QATAR][1][34] = 56, -+ [2][0][RTW89_QATAR][0][34] = 18, -+ [2][0][RTW89_UK][1][34] = 56, -+ [2][0][RTW89_UK][0][34] = 18, -+ [2][0][RTW89_FCC][1][36] = 8, -+ [2][0][RTW89_FCC][2][36] = 78, -+ [2][0][RTW89_ETSI][1][36] = 56, -+ [2][0][RTW89_ETSI][0][36] = 18, -+ [2][0][RTW89_MKK][1][36] = 56, -+ [2][0][RTW89_MKK][0][36] = 14, -+ [2][0][RTW89_IC][1][36] = 8, -+ [2][0][RTW89_KCC][1][36] = -2, -+ [2][0][RTW89_KCC][0][36] = -2, -+ [2][0][RTW89_ACMA][1][36] = 56, -+ [2][0][RTW89_ACMA][0][36] = 18, -+ [2][0][RTW89_CHILE][1][36] = 8, -+ [2][0][RTW89_QATAR][1][36] = 56, -+ [2][0][RTW89_QATAR][0][36] = 18, -+ [2][0][RTW89_UK][1][36] = 56, -+ [2][0][RTW89_UK][0][36] = 18, -+ [2][0][RTW89_FCC][1][38] = 8, -+ [2][0][RTW89_FCC][2][38] = 78, -+ [2][0][RTW89_ETSI][1][38] = 56, -+ [2][0][RTW89_ETSI][0][38] = 18, -+ [2][0][RTW89_MKK][1][38] = 56, -+ [2][0][RTW89_MKK][0][38] = 14, -+ [2][0][RTW89_IC][1][38] = 8, -+ [2][0][RTW89_KCC][1][38] = -2, -+ [2][0][RTW89_KCC][0][38] = -2, -+ [2][0][RTW89_ACMA][1][38] = 56, -+ [2][0][RTW89_ACMA][0][38] = 18, -+ [2][0][RTW89_CHILE][1][38] = 8, -+ [2][0][RTW89_QATAR][1][38] = 56, -+ [2][0][RTW89_QATAR][0][38] = 18, -+ [2][0][RTW89_UK][1][38] = 56, -+ [2][0][RTW89_UK][0][38] = 18, -+ [2][0][RTW89_FCC][1][40] = 8, -+ [2][0][RTW89_FCC][2][40] = 78, -+ [2][0][RTW89_ETSI][1][40] = 56, -+ [2][0][RTW89_ETSI][0][40] = 18, -+ [2][0][RTW89_MKK][1][40] = 56, -+ [2][0][RTW89_MKK][0][40] = 14, -+ [2][0][RTW89_IC][1][40] = 8, -+ [2][0][RTW89_KCC][1][40] = -2, -+ [2][0][RTW89_KCC][0][40] = -2, -+ [2][0][RTW89_ACMA][1][40] = 56, -+ [2][0][RTW89_ACMA][0][40] = 18, -+ [2][0][RTW89_CHILE][1][40] = 8, -+ [2][0][RTW89_QATAR][1][40] = 56, -+ [2][0][RTW89_QATAR][0][40] = 18, -+ [2][0][RTW89_UK][1][40] = 56, -+ [2][0][RTW89_UK][0][40] = 18, -+ [2][0][RTW89_FCC][1][42] = 8, -+ [2][0][RTW89_FCC][2][42] = 78, -+ [2][0][RTW89_ETSI][1][42] = 56, -+ [2][0][RTW89_ETSI][0][42] = 18, -+ [2][0][RTW89_MKK][1][42] = 56, -+ [2][0][RTW89_MKK][0][42] = 14, -+ [2][0][RTW89_IC][1][42] = 8, -+ [2][0][RTW89_KCC][1][42] = -2, -+ [2][0][RTW89_KCC][0][42] = -2, -+ [2][0][RTW89_ACMA][1][42] = 56, -+ [2][0][RTW89_ACMA][0][42] = 18, -+ [2][0][RTW89_CHILE][1][42] = 8, -+ [2][0][RTW89_QATAR][1][42] = 56, -+ [2][0][RTW89_QATAR][0][42] = 18, -+ [2][0][RTW89_UK][1][42] = 56, -+ [2][0][RTW89_UK][0][42] = 18, -+ [2][0][RTW89_FCC][1][44] = 8, -+ [2][0][RTW89_FCC][2][44] = 78, -+ [2][0][RTW89_ETSI][1][44] = 56, -+ [2][0][RTW89_ETSI][0][44] = 18, -+ [2][0][RTW89_MKK][1][44] = 32, -+ [2][0][RTW89_MKK][0][44] = 14, -+ [2][0][RTW89_IC][1][44] = 8, -+ [2][0][RTW89_KCC][1][44] = -2, -+ [2][0][RTW89_KCC][0][44] = -2, -+ [2][0][RTW89_ACMA][1][44] = 56, -+ [2][0][RTW89_ACMA][0][44] = 18, -+ [2][0][RTW89_CHILE][1][44] = 8, -+ [2][0][RTW89_QATAR][1][44] = 56, -+ [2][0][RTW89_QATAR][0][44] = 18, -+ [2][0][RTW89_UK][1][44] = 56, -+ [2][0][RTW89_UK][0][44] = 18, -+ [2][0][RTW89_FCC][1][45] = 8, -+ [2][0][RTW89_FCC][2][45] = 127, -+ [2][0][RTW89_ETSI][1][45] = 127, -+ [2][0][RTW89_ETSI][0][45] = 127, -+ [2][0][RTW89_MKK][1][45] = 127, -+ [2][0][RTW89_MKK][0][45] = 127, -+ [2][0][RTW89_IC][1][45] = 8, -+ [2][0][RTW89_KCC][1][45] = -2, -+ [2][0][RTW89_KCC][0][45] = 127, -+ [2][0][RTW89_ACMA][1][45] = 127, -+ [2][0][RTW89_ACMA][0][45] = 127, -+ [2][0][RTW89_CHILE][1][45] = 127, -+ [2][0][RTW89_QATAR][1][45] = 127, -+ [2][0][RTW89_QATAR][0][45] = 127, -+ [2][0][RTW89_UK][1][45] = 127, -+ [2][0][RTW89_UK][0][45] = 127, -+ [2][0][RTW89_FCC][1][47] = 8, -+ [2][0][RTW89_FCC][2][47] = 127, -+ [2][0][RTW89_ETSI][1][47] = 127, -+ [2][0][RTW89_ETSI][0][47] = 127, -+ [2][0][RTW89_MKK][1][47] = 127, -+ [2][0][RTW89_MKK][0][47] = 127, -+ [2][0][RTW89_IC][1][47] = 8, -+ [2][0][RTW89_KCC][1][47] = -2, -+ [2][0][RTW89_KCC][0][47] = 127, -+ [2][0][RTW89_ACMA][1][47] = 127, -+ [2][0][RTW89_ACMA][0][47] = 127, -+ [2][0][RTW89_CHILE][1][47] = 127, -+ [2][0][RTW89_QATAR][1][47] = 127, -+ [2][0][RTW89_QATAR][0][47] = 127, -+ [2][0][RTW89_UK][1][47] = 127, -+ [2][0][RTW89_UK][0][47] = 127, -+ [2][0][RTW89_FCC][1][49] = 8, -+ [2][0][RTW89_FCC][2][49] = 127, -+ [2][0][RTW89_ETSI][1][49] = 127, -+ [2][0][RTW89_ETSI][0][49] = 127, -+ [2][0][RTW89_MKK][1][49] = 127, -+ [2][0][RTW89_MKK][0][49] = 127, -+ [2][0][RTW89_IC][1][49] = 8, -+ [2][0][RTW89_KCC][1][49] = -2, -+ [2][0][RTW89_KCC][0][49] = 127, -+ [2][0][RTW89_ACMA][1][49] = 127, -+ [2][0][RTW89_ACMA][0][49] = 127, -+ [2][0][RTW89_CHILE][1][49] = 127, -+ [2][0][RTW89_QATAR][1][49] = 127, -+ [2][0][RTW89_QATAR][0][49] = 127, -+ [2][0][RTW89_UK][1][49] = 127, -+ [2][0][RTW89_UK][0][49] = 127, -+ [2][0][RTW89_FCC][1][51] = 8, -+ [2][0][RTW89_FCC][2][51] = 127, -+ [2][0][RTW89_ETSI][1][51] = 127, -+ [2][0][RTW89_ETSI][0][51] = 127, -+ [2][0][RTW89_MKK][1][51] = 127, -+ [2][0][RTW89_MKK][0][51] = 127, -+ [2][0][RTW89_IC][1][51] = 8, -+ [2][0][RTW89_KCC][1][51] = -2, -+ [2][0][RTW89_KCC][0][51] = 127, -+ [2][0][RTW89_ACMA][1][51] = 127, -+ [2][0][RTW89_ACMA][0][51] = 127, -+ [2][0][RTW89_CHILE][1][51] = 127, -+ [2][0][RTW89_QATAR][1][51] = 127, -+ [2][0][RTW89_QATAR][0][51] = 127, -+ [2][0][RTW89_UK][1][51] = 127, -+ [2][0][RTW89_UK][0][51] = 127, -+ [2][0][RTW89_FCC][1][53] = 8, -+ [2][0][RTW89_FCC][2][53] = 127, -+ [2][0][RTW89_ETSI][1][53] = 127, -+ [2][0][RTW89_ETSI][0][53] = 127, -+ [2][0][RTW89_MKK][1][53] = 127, -+ [2][0][RTW89_MKK][0][53] = 127, -+ [2][0][RTW89_IC][1][53] = 8, -+ [2][0][RTW89_KCC][1][53] = -2, -+ [2][0][RTW89_KCC][0][53] = 127, -+ [2][0][RTW89_ACMA][1][53] = 127, -+ [2][0][RTW89_ACMA][0][53] = 127, -+ [2][0][RTW89_CHILE][1][53] = 127, -+ [2][0][RTW89_QATAR][1][53] = 127, -+ [2][0][RTW89_QATAR][0][53] = 127, -+ [2][0][RTW89_UK][1][53] = 127, -+ [2][0][RTW89_UK][0][53] = 127, -+ [2][0][RTW89_FCC][1][55] = 8, -+ [2][0][RTW89_FCC][2][55] = 78, -+ [2][0][RTW89_ETSI][1][55] = 127, -+ [2][0][RTW89_ETSI][0][55] = 127, -+ [2][0][RTW89_MKK][1][55] = 127, -+ [2][0][RTW89_MKK][0][55] = 127, -+ [2][0][RTW89_IC][1][55] = 8, -+ [2][0][RTW89_KCC][1][55] = -2, -+ [2][0][RTW89_KCC][0][55] = 127, -+ [2][0][RTW89_ACMA][1][55] = 127, -+ [2][0][RTW89_ACMA][0][55] = 127, -+ [2][0][RTW89_CHILE][1][55] = 127, -+ [2][0][RTW89_QATAR][1][55] = 127, -+ [2][0][RTW89_QATAR][0][55] = 127, -+ [2][0][RTW89_UK][1][55] = 127, -+ [2][0][RTW89_UK][0][55] = 127, -+ [2][0][RTW89_FCC][1][57] = 8, -+ [2][0][RTW89_FCC][2][57] = 78, -+ [2][0][RTW89_ETSI][1][57] = 127, -+ [2][0][RTW89_ETSI][0][57] = 127, -+ [2][0][RTW89_MKK][1][57] = 127, -+ [2][0][RTW89_MKK][0][57] = 127, -+ [2][0][RTW89_IC][1][57] = 8, -+ [2][0][RTW89_KCC][1][57] = -2, -+ [2][0][RTW89_KCC][0][57] = 127, -+ [2][0][RTW89_ACMA][1][57] = 127, -+ [2][0][RTW89_ACMA][0][57] = 127, -+ [2][0][RTW89_CHILE][1][57] = 127, -+ [2][0][RTW89_QATAR][1][57] = 127, -+ [2][0][RTW89_QATAR][0][57] = 127, -+ [2][0][RTW89_UK][1][57] = 127, -+ [2][0][RTW89_UK][0][57] = 127, -+ [2][0][RTW89_FCC][1][59] = 8, -+ [2][0][RTW89_FCC][2][59] = 78, -+ [2][0][RTW89_ETSI][1][59] = 127, -+ [2][0][RTW89_ETSI][0][59] = 127, -+ [2][0][RTW89_MKK][1][59] = 127, -+ [2][0][RTW89_MKK][0][59] = 127, -+ [2][0][RTW89_IC][1][59] = 8, -+ [2][0][RTW89_KCC][1][59] = -2, -+ [2][0][RTW89_KCC][0][59] = 127, -+ [2][0][RTW89_ACMA][1][59] = 127, -+ [2][0][RTW89_ACMA][0][59] = 127, -+ [2][0][RTW89_CHILE][1][59] = 127, -+ [2][0][RTW89_QATAR][1][59] = 127, -+ [2][0][RTW89_QATAR][0][59] = 127, -+ [2][0][RTW89_UK][1][59] = 127, -+ [2][0][RTW89_UK][0][59] = 127, -+ [2][0][RTW89_FCC][1][60] = 8, -+ [2][0][RTW89_FCC][2][60] = 78, -+ [2][0][RTW89_ETSI][1][60] = 127, -+ [2][0][RTW89_ETSI][0][60] = 127, -+ [2][0][RTW89_MKK][1][60] = 127, -+ [2][0][RTW89_MKK][0][60] = 127, -+ [2][0][RTW89_IC][1][60] = 8, -+ [2][0][RTW89_KCC][1][60] = -2, -+ [2][0][RTW89_KCC][0][60] = 127, -+ [2][0][RTW89_ACMA][1][60] = 127, -+ [2][0][RTW89_ACMA][0][60] = 127, -+ [2][0][RTW89_CHILE][1][60] = 127, -+ [2][0][RTW89_QATAR][1][60] = 127, -+ [2][0][RTW89_QATAR][0][60] = 127, -+ [2][0][RTW89_UK][1][60] = 127, -+ [2][0][RTW89_UK][0][60] = 127, -+ [2][0][RTW89_FCC][1][62] = 8, -+ [2][0][RTW89_FCC][2][62] = 78, -+ [2][0][RTW89_ETSI][1][62] = 127, -+ [2][0][RTW89_ETSI][0][62] = 127, -+ [2][0][RTW89_MKK][1][62] = 127, -+ [2][0][RTW89_MKK][0][62] = 127, -+ [2][0][RTW89_IC][1][62] = 8, -+ [2][0][RTW89_KCC][1][62] = -2, -+ [2][0][RTW89_KCC][0][62] = 127, -+ [2][0][RTW89_ACMA][1][62] = 127, -+ [2][0][RTW89_ACMA][0][62] = 127, -+ [2][0][RTW89_CHILE][1][62] = 127, -+ [2][0][RTW89_QATAR][1][62] = 127, -+ [2][0][RTW89_QATAR][0][62] = 127, -+ [2][0][RTW89_UK][1][62] = 127, -+ [2][0][RTW89_UK][0][62] = 127, -+ [2][0][RTW89_FCC][1][64] = 8, -+ [2][0][RTW89_FCC][2][64] = 78, -+ [2][0][RTW89_ETSI][1][64] = 127, -+ [2][0][RTW89_ETSI][0][64] = 127, -+ [2][0][RTW89_MKK][1][64] = 127, -+ [2][0][RTW89_MKK][0][64] = 127, -+ [2][0][RTW89_IC][1][64] = 8, -+ [2][0][RTW89_KCC][1][64] = -2, -+ [2][0][RTW89_KCC][0][64] = 127, -+ [2][0][RTW89_ACMA][1][64] = 127, -+ [2][0][RTW89_ACMA][0][64] = 127, -+ [2][0][RTW89_CHILE][1][64] = 127, -+ [2][0][RTW89_QATAR][1][64] = 127, -+ [2][0][RTW89_QATAR][0][64] = 127, -+ [2][0][RTW89_UK][1][64] = 127, -+ [2][0][RTW89_UK][0][64] = 127, -+ [2][0][RTW89_FCC][1][66] = 8, -+ [2][0][RTW89_FCC][2][66] = 78, -+ [2][0][RTW89_ETSI][1][66] = 127, -+ [2][0][RTW89_ETSI][0][66] = 127, -+ [2][0][RTW89_MKK][1][66] = 127, -+ [2][0][RTW89_MKK][0][66] = 127, -+ [2][0][RTW89_IC][1][66] = 8, -+ [2][0][RTW89_KCC][1][66] = -2, -+ [2][0][RTW89_KCC][0][66] = 127, -+ [2][0][RTW89_ACMA][1][66] = 127, -+ [2][0][RTW89_ACMA][0][66] = 127, -+ [2][0][RTW89_CHILE][1][66] = 127, -+ [2][0][RTW89_QATAR][1][66] = 127, -+ [2][0][RTW89_QATAR][0][66] = 127, -+ [2][0][RTW89_UK][1][66] = 127, -+ [2][0][RTW89_UK][0][66] = 127, -+ [2][0][RTW89_FCC][1][68] = 8, -+ [2][0][RTW89_FCC][2][68] = 78, -+ [2][0][RTW89_ETSI][1][68] = 127, -+ [2][0][RTW89_ETSI][0][68] = 127, -+ [2][0][RTW89_MKK][1][68] = 127, -+ [2][0][RTW89_MKK][0][68] = 127, -+ [2][0][RTW89_IC][1][68] = 8, -+ [2][0][RTW89_KCC][1][68] = -2, -+ [2][0][RTW89_KCC][0][68] = 127, -+ [2][0][RTW89_ACMA][1][68] = 127, -+ [2][0][RTW89_ACMA][0][68] = 127, -+ [2][0][RTW89_CHILE][1][68] = 127, -+ [2][0][RTW89_QATAR][1][68] = 127, -+ [2][0][RTW89_QATAR][0][68] = 127, -+ [2][0][RTW89_UK][1][68] = 127, -+ [2][0][RTW89_UK][0][68] = 127, -+ [2][0][RTW89_FCC][1][70] = 8, -+ [2][0][RTW89_FCC][2][70] = 78, -+ [2][0][RTW89_ETSI][1][70] = 127, -+ [2][0][RTW89_ETSI][0][70] = 127, -+ [2][0][RTW89_MKK][1][70] = 127, -+ [2][0][RTW89_MKK][0][70] = 127, -+ [2][0][RTW89_IC][1][70] = 8, -+ [2][0][RTW89_KCC][1][70] = -2, -+ [2][0][RTW89_KCC][0][70] = 127, -+ [2][0][RTW89_ACMA][1][70] = 127, -+ [2][0][RTW89_ACMA][0][70] = 127, -+ [2][0][RTW89_CHILE][1][70] = 127, -+ [2][0][RTW89_QATAR][1][70] = 127, -+ [2][0][RTW89_QATAR][0][70] = 127, -+ [2][0][RTW89_UK][1][70] = 127, -+ [2][0][RTW89_UK][0][70] = 127, -+ [2][0][RTW89_FCC][1][72] = 8, -+ [2][0][RTW89_FCC][2][72] = 78, -+ [2][0][RTW89_ETSI][1][72] = 127, -+ [2][0][RTW89_ETSI][0][72] = 127, -+ [2][0][RTW89_MKK][1][72] = 127, -+ [2][0][RTW89_MKK][0][72] = 127, -+ [2][0][RTW89_IC][1][72] = 8, -+ [2][0][RTW89_KCC][1][72] = -2, -+ [2][0][RTW89_KCC][0][72] = 127, -+ [2][0][RTW89_ACMA][1][72] = 127, -+ [2][0][RTW89_ACMA][0][72] = 127, -+ [2][0][RTW89_CHILE][1][72] = 127, -+ [2][0][RTW89_QATAR][1][72] = 127, -+ [2][0][RTW89_QATAR][0][72] = 127, -+ [2][0][RTW89_UK][1][72] = 127, -+ [2][0][RTW89_UK][0][72] = 127, -+ [2][0][RTW89_FCC][1][74] = 8, -+ [2][0][RTW89_FCC][2][74] = 78, -+ [2][0][RTW89_ETSI][1][74] = 127, -+ [2][0][RTW89_ETSI][0][74] = 127, -+ [2][0][RTW89_MKK][1][74] = 127, -+ [2][0][RTW89_MKK][0][74] = 127, -+ [2][0][RTW89_IC][1][74] = 8, -+ [2][0][RTW89_KCC][1][74] = -2, -+ [2][0][RTW89_KCC][0][74] = 127, -+ [2][0][RTW89_ACMA][1][74] = 127, -+ [2][0][RTW89_ACMA][0][74] = 127, -+ [2][0][RTW89_CHILE][1][74] = 127, -+ [2][0][RTW89_QATAR][1][74] = 127, -+ [2][0][RTW89_QATAR][0][74] = 127, -+ [2][0][RTW89_UK][1][74] = 127, -+ [2][0][RTW89_UK][0][74] = 127, -+ [2][0][RTW89_FCC][1][75] = 8, -+ [2][0][RTW89_FCC][2][75] = 78, -+ [2][0][RTW89_ETSI][1][75] = 127, -+ [2][0][RTW89_ETSI][0][75] = 127, -+ [2][0][RTW89_MKK][1][75] = 127, -+ [2][0][RTW89_MKK][0][75] = 127, -+ [2][0][RTW89_IC][1][75] = 8, -+ [2][0][RTW89_KCC][1][75] = -2, -+ [2][0][RTW89_KCC][0][75] = 127, -+ [2][0][RTW89_ACMA][1][75] = 127, -+ [2][0][RTW89_ACMA][0][75] = 127, -+ [2][0][RTW89_CHILE][1][75] = 127, -+ [2][0][RTW89_QATAR][1][75] = 127, -+ [2][0][RTW89_QATAR][0][75] = 127, -+ [2][0][RTW89_UK][1][75] = 127, -+ [2][0][RTW89_UK][0][75] = 127, -+ [2][0][RTW89_FCC][1][77] = 8, -+ [2][0][RTW89_FCC][2][77] = 78, -+ [2][0][RTW89_ETSI][1][77] = 127, -+ [2][0][RTW89_ETSI][0][77] = 127, -+ [2][0][RTW89_MKK][1][77] = 127, -+ [2][0][RTW89_MKK][0][77] = 127, -+ [2][0][RTW89_IC][1][77] = 8, -+ [2][0][RTW89_KCC][1][77] = -2, -+ [2][0][RTW89_KCC][0][77] = 127, -+ [2][0][RTW89_ACMA][1][77] = 127, -+ [2][0][RTW89_ACMA][0][77] = 127, -+ [2][0][RTW89_CHILE][1][77] = 127, -+ [2][0][RTW89_QATAR][1][77] = 127, -+ [2][0][RTW89_QATAR][0][77] = 127, -+ [2][0][RTW89_UK][1][77] = 127, -+ [2][0][RTW89_UK][0][77] = 127, -+ [2][0][RTW89_FCC][1][79] = 8, -+ [2][0][RTW89_FCC][2][79] = 78, -+ [2][0][RTW89_ETSI][1][79] = 127, -+ [2][0][RTW89_ETSI][0][79] = 127, -+ [2][0][RTW89_MKK][1][79] = 127, -+ [2][0][RTW89_MKK][0][79] = 127, -+ [2][0][RTW89_IC][1][79] = 8, -+ [2][0][RTW89_KCC][1][79] = -2, -+ [2][0][RTW89_KCC][0][79] = 127, -+ [2][0][RTW89_ACMA][1][79] = 127, -+ [2][0][RTW89_ACMA][0][79] = 127, -+ [2][0][RTW89_CHILE][1][79] = 127, -+ [2][0][RTW89_QATAR][1][79] = 127, -+ [2][0][RTW89_QATAR][0][79] = 127, -+ [2][0][RTW89_UK][1][79] = 127, -+ [2][0][RTW89_UK][0][79] = 127, -+ [2][0][RTW89_FCC][1][81] = 8, -+ [2][0][RTW89_FCC][2][81] = 78, -+ [2][0][RTW89_ETSI][1][81] = 127, -+ [2][0][RTW89_ETSI][0][81] = 127, -+ [2][0][RTW89_MKK][1][81] = 127, -+ [2][0][RTW89_MKK][0][81] = 127, -+ [2][0][RTW89_IC][1][81] = 8, -+ [2][0][RTW89_KCC][1][81] = -2, -+ [2][0][RTW89_KCC][0][81] = 127, -+ [2][0][RTW89_ACMA][1][81] = 127, -+ [2][0][RTW89_ACMA][0][81] = 127, -+ [2][0][RTW89_CHILE][1][81] = 127, -+ [2][0][RTW89_QATAR][1][81] = 127, -+ [2][0][RTW89_QATAR][0][81] = 127, -+ [2][0][RTW89_UK][1][81] = 127, -+ [2][0][RTW89_UK][0][81] = 127, -+ [2][0][RTW89_FCC][1][83] = 8, -+ [2][0][RTW89_FCC][2][83] = 78, -+ [2][0][RTW89_ETSI][1][83] = 127, -+ [2][0][RTW89_ETSI][0][83] = 127, -+ [2][0][RTW89_MKK][1][83] = 127, -+ [2][0][RTW89_MKK][0][83] = 127, -+ [2][0][RTW89_IC][1][83] = 8, -+ [2][0][RTW89_KCC][1][83] = -2, -+ [2][0][RTW89_KCC][0][83] = 127, -+ [2][0][RTW89_ACMA][1][83] = 127, -+ [2][0][RTW89_ACMA][0][83] = 127, -+ [2][0][RTW89_CHILE][1][83] = 127, -+ [2][0][RTW89_QATAR][1][83] = 127, -+ [2][0][RTW89_QATAR][0][83] = 127, -+ [2][0][RTW89_UK][1][83] = 127, -+ [2][0][RTW89_UK][0][83] = 127, -+ [2][0][RTW89_FCC][1][85] = 8, -+ [2][0][RTW89_FCC][2][85] = 78, -+ [2][0][RTW89_ETSI][1][85] = 127, -+ [2][0][RTW89_ETSI][0][85] = 127, -+ [2][0][RTW89_MKK][1][85] = 127, -+ [2][0][RTW89_MKK][0][85] = 127, -+ [2][0][RTW89_IC][1][85] = 8, -+ [2][0][RTW89_KCC][1][85] = -2, -+ [2][0][RTW89_KCC][0][85] = 127, -+ [2][0][RTW89_ACMA][1][85] = 127, -+ [2][0][RTW89_ACMA][0][85] = 127, -+ [2][0][RTW89_CHILE][1][85] = 127, -+ [2][0][RTW89_QATAR][1][85] = 127, -+ [2][0][RTW89_QATAR][0][85] = 127, -+ [2][0][RTW89_UK][1][85] = 127, -+ [2][0][RTW89_UK][0][85] = 127, -+ [2][0][RTW89_FCC][1][87] = 8, -+ [2][0][RTW89_FCC][2][87] = 127, -+ [2][0][RTW89_ETSI][1][87] = 127, -+ [2][0][RTW89_ETSI][0][87] = 127, -+ [2][0][RTW89_MKK][1][87] = 127, -+ [2][0][RTW89_MKK][0][87] = 127, -+ [2][0][RTW89_IC][1][87] = 8, -+ [2][0][RTW89_KCC][1][87] = -2, -+ [2][0][RTW89_KCC][0][87] = 127, -+ [2][0][RTW89_ACMA][1][87] = 127, -+ [2][0][RTW89_ACMA][0][87] = 127, -+ [2][0][RTW89_CHILE][1][87] = 127, -+ [2][0][RTW89_QATAR][1][87] = 127, -+ [2][0][RTW89_QATAR][0][87] = 127, -+ [2][0][RTW89_UK][1][87] = 127, -+ [2][0][RTW89_UK][0][87] = 127, -+ [2][0][RTW89_FCC][1][89] = 8, -+ [2][0][RTW89_FCC][2][89] = 127, -+ [2][0][RTW89_ETSI][1][89] = 127, -+ [2][0][RTW89_ETSI][0][89] = 127, -+ [2][0][RTW89_MKK][1][89] = 127, -+ [2][0][RTW89_MKK][0][89] = 127, -+ [2][0][RTW89_IC][1][89] = 8, -+ [2][0][RTW89_KCC][1][89] = -2, -+ [2][0][RTW89_KCC][0][89] = 127, -+ [2][0][RTW89_ACMA][1][89] = 127, -+ [2][0][RTW89_ACMA][0][89] = 127, -+ [2][0][RTW89_CHILE][1][89] = 127, -+ [2][0][RTW89_QATAR][1][89] = 127, -+ [2][0][RTW89_QATAR][0][89] = 127, -+ [2][0][RTW89_UK][1][89] = 127, -+ [2][0][RTW89_UK][0][89] = 127, -+ [2][0][RTW89_FCC][1][90] = 8, -+ [2][0][RTW89_FCC][2][90] = 127, -+ [2][0][RTW89_ETSI][1][90] = 127, -+ [2][0][RTW89_ETSI][0][90] = 127, -+ [2][0][RTW89_MKK][1][90] = 127, -+ [2][0][RTW89_MKK][0][90] = 127, -+ [2][0][RTW89_IC][1][90] = 8, -+ [2][0][RTW89_KCC][1][90] = -2, -+ [2][0][RTW89_KCC][0][90] = 127, -+ [2][0][RTW89_ACMA][1][90] = 127, -+ [2][0][RTW89_ACMA][0][90] = 127, -+ [2][0][RTW89_CHILE][1][90] = 127, -+ [2][0][RTW89_QATAR][1][90] = 127, -+ [2][0][RTW89_QATAR][0][90] = 127, -+ [2][0][RTW89_UK][1][90] = 127, -+ [2][0][RTW89_UK][0][90] = 127, -+ [2][0][RTW89_FCC][1][92] = 8, -+ [2][0][RTW89_FCC][2][92] = 127, -+ [2][0][RTW89_ETSI][1][92] = 127, -+ [2][0][RTW89_ETSI][0][92] = 127, -+ [2][0][RTW89_MKK][1][92] = 127, -+ [2][0][RTW89_MKK][0][92] = 127, -+ [2][0][RTW89_IC][1][92] = 8, -+ [2][0][RTW89_KCC][1][92] = -2, -+ [2][0][RTW89_KCC][0][92] = 127, -+ [2][0][RTW89_ACMA][1][92] = 127, -+ [2][0][RTW89_ACMA][0][92] = 127, -+ [2][0][RTW89_CHILE][1][92] = 127, -+ [2][0][RTW89_QATAR][1][92] = 127, -+ [2][0][RTW89_QATAR][0][92] = 127, -+ [2][0][RTW89_UK][1][92] = 127, -+ [2][0][RTW89_UK][0][92] = 127, -+ [2][0][RTW89_FCC][1][94] = 8, -+ [2][0][RTW89_FCC][2][94] = 127, -+ [2][0][RTW89_ETSI][1][94] = 127, -+ [2][0][RTW89_ETSI][0][94] = 127, -+ [2][0][RTW89_MKK][1][94] = 127, -+ [2][0][RTW89_MKK][0][94] = 127, -+ [2][0][RTW89_IC][1][94] = 8, -+ [2][0][RTW89_KCC][1][94] = -2, -+ [2][0][RTW89_KCC][0][94] = 127, -+ [2][0][RTW89_ACMA][1][94] = 127, -+ [2][0][RTW89_ACMA][0][94] = 127, -+ [2][0][RTW89_CHILE][1][94] = 127, -+ [2][0][RTW89_QATAR][1][94] = 127, -+ [2][0][RTW89_QATAR][0][94] = 127, -+ [2][0][RTW89_UK][1][94] = 127, -+ [2][0][RTW89_UK][0][94] = 127, -+ [2][0][RTW89_FCC][1][96] = 8, -+ [2][0][RTW89_FCC][2][96] = 127, -+ [2][0][RTW89_ETSI][1][96] = 127, -+ [2][0][RTW89_ETSI][0][96] = 127, -+ [2][0][RTW89_MKK][1][96] = 127, -+ [2][0][RTW89_MKK][0][96] = 127, -+ [2][0][RTW89_IC][1][96] = 8, -+ [2][0][RTW89_KCC][1][96] = -2, -+ [2][0][RTW89_KCC][0][96] = 127, -+ [2][0][RTW89_ACMA][1][96] = 127, -+ [2][0][RTW89_ACMA][0][96] = 127, -+ [2][0][RTW89_CHILE][1][96] = 127, -+ [2][0][RTW89_QATAR][1][96] = 127, -+ [2][0][RTW89_QATAR][0][96] = 127, -+ [2][0][RTW89_UK][1][96] = 127, -+ [2][0][RTW89_UK][0][96] = 127, -+ [2][0][RTW89_FCC][1][98] = 8, -+ [2][0][RTW89_FCC][2][98] = 127, -+ [2][0][RTW89_ETSI][1][98] = 127, -+ [2][0][RTW89_ETSI][0][98] = 127, -+ [2][0][RTW89_MKK][1][98] = 127, -+ [2][0][RTW89_MKK][0][98] = 127, -+ [2][0][RTW89_IC][1][98] = 8, -+ [2][0][RTW89_KCC][1][98] = -2, -+ [2][0][RTW89_KCC][0][98] = 127, -+ [2][0][RTW89_ACMA][1][98] = 127, -+ [2][0][RTW89_ACMA][0][98] = 127, -+ [2][0][RTW89_CHILE][1][98] = 127, -+ [2][0][RTW89_QATAR][1][98] = 127, -+ [2][0][RTW89_QATAR][0][98] = 127, -+ [2][0][RTW89_UK][1][98] = 127, -+ [2][0][RTW89_UK][0][98] = 127, -+ [2][0][RTW89_FCC][1][100] = 8, -+ [2][0][RTW89_FCC][2][100] = 127, -+ [2][0][RTW89_ETSI][1][100] = 127, -+ [2][0][RTW89_ETSI][0][100] = 127, -+ [2][0][RTW89_MKK][1][100] = 127, -+ [2][0][RTW89_MKK][0][100] = 127, -+ [2][0][RTW89_IC][1][100] = 8, -+ [2][0][RTW89_KCC][1][100] = -2, -+ [2][0][RTW89_KCC][0][100] = 127, -+ [2][0][RTW89_ACMA][1][100] = 127, -+ [2][0][RTW89_ACMA][0][100] = 127, -+ [2][0][RTW89_CHILE][1][100] = 127, -+ [2][0][RTW89_QATAR][1][100] = 127, -+ [2][0][RTW89_QATAR][0][100] = 127, -+ [2][0][RTW89_UK][1][100] = 127, -+ [2][0][RTW89_UK][0][100] = 127, -+ [2][0][RTW89_FCC][1][102] = 8, -+ [2][0][RTW89_FCC][2][102] = 127, -+ [2][0][RTW89_ETSI][1][102] = 127, -+ [2][0][RTW89_ETSI][0][102] = 127, -+ [2][0][RTW89_MKK][1][102] = 127, -+ [2][0][RTW89_MKK][0][102] = 127, -+ [2][0][RTW89_IC][1][102] = 8, -+ [2][0][RTW89_KCC][1][102] = -2, -+ [2][0][RTW89_KCC][0][102] = 127, -+ [2][0][RTW89_ACMA][1][102] = 127, -+ [2][0][RTW89_ACMA][0][102] = 127, -+ [2][0][RTW89_CHILE][1][102] = 127, -+ [2][0][RTW89_QATAR][1][102] = 127, -+ [2][0][RTW89_QATAR][0][102] = 127, -+ [2][0][RTW89_UK][1][102] = 127, -+ [2][0][RTW89_UK][0][102] = 127, -+ [2][0][RTW89_FCC][1][104] = 8, -+ [2][0][RTW89_FCC][2][104] = 127, -+ [2][0][RTW89_ETSI][1][104] = 127, -+ [2][0][RTW89_ETSI][0][104] = 127, -+ [2][0][RTW89_MKK][1][104] = 127, -+ [2][0][RTW89_MKK][0][104] = 127, -+ [2][0][RTW89_IC][1][104] = 8, -+ [2][0][RTW89_KCC][1][104] = -2, -+ [2][0][RTW89_KCC][0][104] = 127, -+ [2][0][RTW89_ACMA][1][104] = 127, -+ [2][0][RTW89_ACMA][0][104] = 127, -+ [2][0][RTW89_CHILE][1][104] = 127, -+ [2][0][RTW89_QATAR][1][104] = 127, -+ [2][0][RTW89_QATAR][0][104] = 127, -+ [2][0][RTW89_UK][1][104] = 127, -+ [2][0][RTW89_UK][0][104] = 127, -+ [2][0][RTW89_FCC][1][105] = 8, -+ [2][0][RTW89_FCC][2][105] = 127, -+ [2][0][RTW89_ETSI][1][105] = 127, -+ [2][0][RTW89_ETSI][0][105] = 127, -+ [2][0][RTW89_MKK][1][105] = 127, -+ [2][0][RTW89_MKK][0][105] = 127, -+ [2][0][RTW89_IC][1][105] = 8, -+ [2][0][RTW89_KCC][1][105] = -2, -+ [2][0][RTW89_KCC][0][105] = 127, -+ [2][0][RTW89_ACMA][1][105] = 127, -+ [2][0][RTW89_ACMA][0][105] = 127, -+ [2][0][RTW89_CHILE][1][105] = 127, -+ [2][0][RTW89_QATAR][1][105] = 127, -+ [2][0][RTW89_QATAR][0][105] = 127, -+ [2][0][RTW89_UK][1][105] = 127, -+ [2][0][RTW89_UK][0][105] = 127, -+ [2][0][RTW89_FCC][1][107] = 10, -+ [2][0][RTW89_FCC][2][107] = 127, -+ [2][0][RTW89_ETSI][1][107] = 127, -+ [2][0][RTW89_ETSI][0][107] = 127, -+ [2][0][RTW89_MKK][1][107] = 127, -+ [2][0][RTW89_MKK][0][107] = 127, -+ [2][0][RTW89_IC][1][107] = 10, -+ [2][0][RTW89_KCC][1][107] = -2, -+ [2][0][RTW89_KCC][0][107] = 127, -+ [2][0][RTW89_ACMA][1][107] = 127, -+ [2][0][RTW89_ACMA][0][107] = 127, -+ [2][0][RTW89_CHILE][1][107] = 127, -+ [2][0][RTW89_QATAR][1][107] = 127, -+ [2][0][RTW89_QATAR][0][107] = 127, -+ [2][0][RTW89_UK][1][107] = 127, -+ [2][0][RTW89_UK][0][107] = 127, -+ [2][0][RTW89_FCC][1][109] = 12, -+ [2][0][RTW89_FCC][2][109] = 127, -+ [2][0][RTW89_ETSI][1][109] = 127, -+ [2][0][RTW89_ETSI][0][109] = 127, -+ [2][0][RTW89_MKK][1][109] = 127, -+ [2][0][RTW89_MKK][0][109] = 127, -+ [2][0][RTW89_IC][1][109] = 12, -+ [2][0][RTW89_KCC][1][109] = 127, -+ [2][0][RTW89_KCC][0][109] = 127, -+ [2][0][RTW89_ACMA][1][109] = 127, -+ [2][0][RTW89_ACMA][0][109] = 127, -+ [2][0][RTW89_CHILE][1][109] = 127, -+ [2][0][RTW89_QATAR][1][109] = 127, -+ [2][0][RTW89_QATAR][0][109] = 127, -+ [2][0][RTW89_UK][1][109] = 127, -+ [2][0][RTW89_UK][0][109] = 127, -+ [2][0][RTW89_FCC][1][111] = 127, -+ [2][0][RTW89_FCC][2][111] = 127, -+ [2][0][RTW89_ETSI][1][111] = 127, -+ [2][0][RTW89_ETSI][0][111] = 127, -+ [2][0][RTW89_MKK][1][111] = 127, -+ [2][0][RTW89_MKK][0][111] = 127, -+ [2][0][RTW89_IC][1][111] = 127, -+ [2][0][RTW89_KCC][1][111] = 127, -+ [2][0][RTW89_KCC][0][111] = 127, -+ [2][0][RTW89_ACMA][1][111] = 127, -+ [2][0][RTW89_ACMA][0][111] = 127, -+ [2][0][RTW89_CHILE][1][111] = 127, -+ [2][0][RTW89_QATAR][1][111] = 127, -+ [2][0][RTW89_QATAR][0][111] = 127, -+ [2][0][RTW89_UK][1][111] = 127, -+ [2][0][RTW89_UK][0][111] = 127, -+ [2][0][RTW89_FCC][1][113] = 127, -+ [2][0][RTW89_FCC][2][113] = 127, -+ [2][0][RTW89_ETSI][1][113] = 127, -+ [2][0][RTW89_ETSI][0][113] = 127, -+ [2][0][RTW89_MKK][1][113] = 127, -+ [2][0][RTW89_MKK][0][113] = 127, -+ [2][0][RTW89_IC][1][113] = 127, -+ [2][0][RTW89_KCC][1][113] = 127, -+ [2][0][RTW89_KCC][0][113] = 127, -+ [2][0][RTW89_ACMA][1][113] = 127, -+ [2][0][RTW89_ACMA][0][113] = 127, -+ [2][0][RTW89_CHILE][1][113] = 127, -+ [2][0][RTW89_QATAR][1][113] = 127, -+ [2][0][RTW89_QATAR][0][113] = 127, -+ [2][0][RTW89_UK][1][113] = 127, -+ [2][0][RTW89_UK][0][113] = 127, -+ [2][0][RTW89_FCC][1][115] = 127, -+ [2][0][RTW89_FCC][2][115] = 127, -+ [2][0][RTW89_ETSI][1][115] = 127, -+ [2][0][RTW89_ETSI][0][115] = 127, -+ [2][0][RTW89_MKK][1][115] = 127, -+ [2][0][RTW89_MKK][0][115] = 127, -+ [2][0][RTW89_IC][1][115] = 127, -+ [2][0][RTW89_KCC][1][115] = 127, -+ [2][0][RTW89_KCC][0][115] = 127, -+ [2][0][RTW89_ACMA][1][115] = 127, -+ [2][0][RTW89_ACMA][0][115] = 127, -+ [2][0][RTW89_CHILE][1][115] = 127, -+ [2][0][RTW89_QATAR][1][115] = 127, -+ [2][0][RTW89_QATAR][0][115] = 127, -+ [2][0][RTW89_UK][1][115] = 127, -+ [2][0][RTW89_UK][0][115] = 127, -+ [2][0][RTW89_FCC][1][117] = 127, -+ [2][0][RTW89_FCC][2][117] = 127, -+ [2][0][RTW89_ETSI][1][117] = 127, -+ [2][0][RTW89_ETSI][0][117] = 127, -+ [2][0][RTW89_MKK][1][117] = 127, -+ [2][0][RTW89_MKK][0][117] = 127, -+ [2][0][RTW89_IC][1][117] = 127, -+ [2][0][RTW89_KCC][1][117] = 127, -+ [2][0][RTW89_KCC][0][117] = 127, -+ [2][0][RTW89_ACMA][1][117] = 127, -+ [2][0][RTW89_ACMA][0][117] = 127, -+ [2][0][RTW89_CHILE][1][117] = 127, -+ [2][0][RTW89_QATAR][1][117] = 127, -+ [2][0][RTW89_QATAR][0][117] = 127, -+ [2][0][RTW89_UK][1][117] = 127, -+ [2][0][RTW89_UK][0][117] = 127, -+ [2][0][RTW89_FCC][1][119] = 127, -+ [2][0][RTW89_FCC][2][119] = 127, -+ [2][0][RTW89_ETSI][1][119] = 127, -+ [2][0][RTW89_ETSI][0][119] = 127, -+ [2][0][RTW89_MKK][1][119] = 127, -+ [2][0][RTW89_MKK][0][119] = 127, -+ [2][0][RTW89_IC][1][119] = 127, -+ [2][0][RTW89_KCC][1][119] = 127, -+ [2][0][RTW89_KCC][0][119] = 127, -+ [2][0][RTW89_ACMA][1][119] = 127, -+ [2][0][RTW89_ACMA][0][119] = 127, -+ [2][0][RTW89_CHILE][1][119] = 127, -+ [2][0][RTW89_QATAR][1][119] = 127, -+ [2][0][RTW89_QATAR][0][119] = 127, -+ [2][0][RTW89_UK][1][119] = 127, -+ [2][0][RTW89_UK][0][119] = 127, -+ [2][1][RTW89_FCC][1][0] = -16, -+ [2][1][RTW89_FCC][2][0] = 54, -+ [2][1][RTW89_ETSI][1][0] = 44, -+ [2][1][RTW89_ETSI][0][0] = 6, -+ [2][1][RTW89_MKK][1][0] = 42, -+ [2][1][RTW89_MKK][0][0] = 2, -+ [2][1][RTW89_IC][1][0] = -16, -+ [2][1][RTW89_KCC][1][0] = -14, -+ [2][1][RTW89_KCC][0][0] = -14, -+ [2][1][RTW89_ACMA][1][0] = 44, -+ [2][1][RTW89_ACMA][0][0] = 6, -+ [2][1][RTW89_CHILE][1][0] = -16, -+ [2][1][RTW89_QATAR][1][0] = 44, -+ [2][1][RTW89_QATAR][0][0] = 6, -+ [2][1][RTW89_UK][1][0] = 44, -+ [2][1][RTW89_UK][0][0] = 6, -+ [2][1][RTW89_FCC][1][2] = -16, -+ [2][1][RTW89_FCC][2][2] = 54, -+ [2][1][RTW89_ETSI][1][2] = 44, -+ [2][1][RTW89_ETSI][0][2] = 6, -+ [2][1][RTW89_MKK][1][2] = 40, -+ [2][1][RTW89_MKK][0][2] = 2, -+ [2][1][RTW89_IC][1][2] = -16, -+ [2][1][RTW89_KCC][1][2] = -14, -+ [2][1][RTW89_KCC][0][2] = -14, -+ [2][1][RTW89_ACMA][1][2] = 44, -+ [2][1][RTW89_ACMA][0][2] = 6, -+ [2][1][RTW89_CHILE][1][2] = -16, -+ [2][1][RTW89_QATAR][1][2] = 44, -+ [2][1][RTW89_QATAR][0][2] = 6, -+ [2][1][RTW89_UK][1][2] = 44, -+ [2][1][RTW89_UK][0][2] = 6, -+ [2][1][RTW89_FCC][1][4] = -16, -+ [2][1][RTW89_FCC][2][4] = 54, -+ [2][1][RTW89_ETSI][1][4] = 44, -+ [2][1][RTW89_ETSI][0][4] = 6, -+ [2][1][RTW89_MKK][1][4] = 40, -+ [2][1][RTW89_MKK][0][4] = 2, -+ [2][1][RTW89_IC][1][4] = -16, -+ [2][1][RTW89_KCC][1][4] = -14, -+ [2][1][RTW89_KCC][0][4] = -14, -+ [2][1][RTW89_ACMA][1][4] = 44, -+ [2][1][RTW89_ACMA][0][4] = 6, -+ [2][1][RTW89_CHILE][1][4] = -16, -+ [2][1][RTW89_QATAR][1][4] = 44, -+ [2][1][RTW89_QATAR][0][4] = 6, -+ [2][1][RTW89_UK][1][4] = 44, -+ [2][1][RTW89_UK][0][4] = 6, -+ [2][1][RTW89_FCC][1][6] = -16, -+ [2][1][RTW89_FCC][2][6] = 54, -+ [2][1][RTW89_ETSI][1][6] = 44, -+ [2][1][RTW89_ETSI][0][6] = 6, -+ [2][1][RTW89_MKK][1][6] = 40, -+ [2][1][RTW89_MKK][0][6] = 2, -+ [2][1][RTW89_IC][1][6] = -16, -+ [2][1][RTW89_KCC][1][6] = -14, -+ [2][1][RTW89_KCC][0][6] = -14, -+ [2][1][RTW89_ACMA][1][6] = 44, -+ [2][1][RTW89_ACMA][0][6] = 6, -+ [2][1][RTW89_CHILE][1][6] = -16, -+ [2][1][RTW89_QATAR][1][6] = 44, -+ [2][1][RTW89_QATAR][0][6] = 6, -+ [2][1][RTW89_UK][1][6] = 44, -+ [2][1][RTW89_UK][0][6] = 6, -+ [2][1][RTW89_FCC][1][8] = -16, -+ [2][1][RTW89_FCC][2][8] = 54, -+ [2][1][RTW89_ETSI][1][8] = 44, -+ [2][1][RTW89_ETSI][0][8] = 6, -+ [2][1][RTW89_MKK][1][8] = 40, -+ [2][1][RTW89_MKK][0][8] = 2, -+ [2][1][RTW89_IC][1][8] = -16, -+ [2][1][RTW89_KCC][1][8] = -14, -+ [2][1][RTW89_KCC][0][8] = -14, -+ [2][1][RTW89_ACMA][1][8] = 44, -+ [2][1][RTW89_ACMA][0][8] = 6, -+ [2][1][RTW89_CHILE][1][8] = -16, -+ [2][1][RTW89_QATAR][1][8] = 44, -+ [2][1][RTW89_QATAR][0][8] = 6, -+ [2][1][RTW89_UK][1][8] = 44, -+ [2][1][RTW89_UK][0][8] = 6, -+ [2][1][RTW89_FCC][1][10] = -16, -+ [2][1][RTW89_FCC][2][10] = 54, -+ [2][1][RTW89_ETSI][1][10] = 44, -+ [2][1][RTW89_ETSI][0][10] = 6, -+ [2][1][RTW89_MKK][1][10] = 40, -+ [2][1][RTW89_MKK][0][10] = 2, -+ [2][1][RTW89_IC][1][10] = -16, -+ [2][1][RTW89_KCC][1][10] = -14, -+ [2][1][RTW89_KCC][0][10] = -14, -+ [2][1][RTW89_ACMA][1][10] = 44, -+ [2][1][RTW89_ACMA][0][10] = 6, -+ [2][1][RTW89_CHILE][1][10] = -16, -+ [2][1][RTW89_QATAR][1][10] = 44, -+ [2][1][RTW89_QATAR][0][10] = 6, -+ [2][1][RTW89_UK][1][10] = 44, -+ [2][1][RTW89_UK][0][10] = 6, -+ [2][1][RTW89_FCC][1][12] = -16, -+ [2][1][RTW89_FCC][2][12] = 54, -+ [2][1][RTW89_ETSI][1][12] = 44, -+ [2][1][RTW89_ETSI][0][12] = 6, -+ [2][1][RTW89_MKK][1][12] = 40, -+ [2][1][RTW89_MKK][0][12] = 2, -+ [2][1][RTW89_IC][1][12] = -16, -+ [2][1][RTW89_KCC][1][12] = -14, -+ [2][1][RTW89_KCC][0][12] = -14, -+ [2][1][RTW89_ACMA][1][12] = 44, -+ [2][1][RTW89_ACMA][0][12] = 6, -+ [2][1][RTW89_CHILE][1][12] = -16, -+ [2][1][RTW89_QATAR][1][12] = 44, -+ [2][1][RTW89_QATAR][0][12] = 6, -+ [2][1][RTW89_UK][1][12] = 44, -+ [2][1][RTW89_UK][0][12] = 6, -+ [2][1][RTW89_FCC][1][14] = -16, -+ [2][1][RTW89_FCC][2][14] = 54, -+ [2][1][RTW89_ETSI][1][14] = 44, -+ [2][1][RTW89_ETSI][0][14] = 6, -+ [2][1][RTW89_MKK][1][14] = 40, -+ [2][1][RTW89_MKK][0][14] = 2, -+ [2][1][RTW89_IC][1][14] = -16, -+ [2][1][RTW89_KCC][1][14] = -14, -+ [2][1][RTW89_KCC][0][14] = -14, -+ [2][1][RTW89_ACMA][1][14] = 44, -+ [2][1][RTW89_ACMA][0][14] = 6, -+ [2][1][RTW89_CHILE][1][14] = -16, -+ [2][1][RTW89_QATAR][1][14] = 44, -+ [2][1][RTW89_QATAR][0][14] = 6, -+ [2][1][RTW89_UK][1][14] = 44, -+ [2][1][RTW89_UK][0][14] = 6, -+ [2][1][RTW89_FCC][1][15] = -16, -+ [2][1][RTW89_FCC][2][15] = 54, -+ [2][1][RTW89_ETSI][1][15] = 44, -+ [2][1][RTW89_ETSI][0][15] = 6, -+ [2][1][RTW89_MKK][1][15] = 40, -+ [2][1][RTW89_MKK][0][15] = 2, -+ [2][1][RTW89_IC][1][15] = -16, -+ [2][1][RTW89_KCC][1][15] = -14, -+ [2][1][RTW89_KCC][0][15] = -14, -+ [2][1][RTW89_ACMA][1][15] = 44, -+ [2][1][RTW89_ACMA][0][15] = 6, -+ [2][1][RTW89_CHILE][1][15] = -16, -+ [2][1][RTW89_QATAR][1][15] = 44, -+ [2][1][RTW89_QATAR][0][15] = 6, -+ [2][1][RTW89_UK][1][15] = 44, -+ [2][1][RTW89_UK][0][15] = 6, -+ [2][1][RTW89_FCC][1][17] = -16, -+ [2][1][RTW89_FCC][2][17] = 54, -+ [2][1][RTW89_ETSI][1][17] = 44, -+ [2][1][RTW89_ETSI][0][17] = 6, -+ [2][1][RTW89_MKK][1][17] = 40, -+ [2][1][RTW89_MKK][0][17] = 2, -+ [2][1][RTW89_IC][1][17] = -16, -+ [2][1][RTW89_KCC][1][17] = -14, -+ [2][1][RTW89_KCC][0][17] = -14, -+ [2][1][RTW89_ACMA][1][17] = 44, -+ [2][1][RTW89_ACMA][0][17] = 6, -+ [2][1][RTW89_CHILE][1][17] = -16, -+ [2][1][RTW89_QATAR][1][17] = 44, -+ [2][1][RTW89_QATAR][0][17] = 6, -+ [2][1][RTW89_UK][1][17] = 44, -+ [2][1][RTW89_UK][0][17] = 6, -+ [2][1][RTW89_FCC][1][19] = -16, -+ [2][1][RTW89_FCC][2][19] = 54, -+ [2][1][RTW89_ETSI][1][19] = 44, -+ [2][1][RTW89_ETSI][0][19] = 6, -+ [2][1][RTW89_MKK][1][19] = 40, -+ [2][1][RTW89_MKK][0][19] = 2, -+ [2][1][RTW89_IC][1][19] = -16, -+ [2][1][RTW89_KCC][1][19] = -14, -+ [2][1][RTW89_KCC][0][19] = -14, -+ [2][1][RTW89_ACMA][1][19] = 44, -+ [2][1][RTW89_ACMA][0][19] = 6, -+ [2][1][RTW89_CHILE][1][19] = -16, -+ [2][1][RTW89_QATAR][1][19] = 44, -+ [2][1][RTW89_QATAR][0][19] = 6, -+ [2][1][RTW89_UK][1][19] = 44, -+ [2][1][RTW89_UK][0][19] = 6, -+ [2][1][RTW89_FCC][1][21] = -16, -+ [2][1][RTW89_FCC][2][21] = 54, -+ [2][1][RTW89_ETSI][1][21] = 44, -+ [2][1][RTW89_ETSI][0][21] = 6, -+ [2][1][RTW89_MKK][1][21] = 40, -+ [2][1][RTW89_MKK][0][21] = 2, -+ [2][1][RTW89_IC][1][21] = -16, -+ [2][1][RTW89_KCC][1][21] = -14, -+ [2][1][RTW89_KCC][0][21] = -14, -+ [2][1][RTW89_ACMA][1][21] = 44, -+ [2][1][RTW89_ACMA][0][21] = 6, -+ [2][1][RTW89_CHILE][1][21] = -16, -+ [2][1][RTW89_QATAR][1][21] = 44, -+ [2][1][RTW89_QATAR][0][21] = 6, -+ [2][1][RTW89_UK][1][21] = 44, -+ [2][1][RTW89_UK][0][21] = 6, -+ [2][1][RTW89_FCC][1][23] = -16, -+ [2][1][RTW89_FCC][2][23] = 54, -+ [2][1][RTW89_ETSI][1][23] = 44, -+ [2][1][RTW89_ETSI][0][23] = 6, -+ [2][1][RTW89_MKK][1][23] = 40, -+ [2][1][RTW89_MKK][0][23] = 2, -+ [2][1][RTW89_IC][1][23] = -16, -+ [2][1][RTW89_KCC][1][23] = -14, -+ [2][1][RTW89_KCC][0][23] = -14, -+ [2][1][RTW89_ACMA][1][23] = 44, -+ [2][1][RTW89_ACMA][0][23] = 6, -+ [2][1][RTW89_CHILE][1][23] = -16, -+ [2][1][RTW89_QATAR][1][23] = 44, -+ [2][1][RTW89_QATAR][0][23] = 6, -+ [2][1][RTW89_UK][1][23] = 44, -+ [2][1][RTW89_UK][0][23] = 6, -+ [2][1][RTW89_FCC][1][25] = -16, -+ [2][1][RTW89_FCC][2][25] = 54, -+ [2][1][RTW89_ETSI][1][25] = 44, -+ [2][1][RTW89_ETSI][0][25] = 6, -+ [2][1][RTW89_MKK][1][25] = 40, -+ [2][1][RTW89_MKK][0][25] = 2, -+ [2][1][RTW89_IC][1][25] = -16, -+ [2][1][RTW89_KCC][1][25] = -14, -+ [2][1][RTW89_KCC][0][25] = -14, -+ [2][1][RTW89_ACMA][1][25] = 44, -+ [2][1][RTW89_ACMA][0][25] = 6, -+ [2][1][RTW89_CHILE][1][25] = -16, -+ [2][1][RTW89_QATAR][1][25] = 44, -+ [2][1][RTW89_QATAR][0][25] = 6, -+ [2][1][RTW89_UK][1][25] = 44, -+ [2][1][RTW89_UK][0][25] = 6, -+ [2][1][RTW89_FCC][1][27] = -16, -+ [2][1][RTW89_FCC][2][27] = 54, -+ [2][1][RTW89_ETSI][1][27] = 44, -+ [2][1][RTW89_ETSI][0][27] = 6, -+ [2][1][RTW89_MKK][1][27] = 40, -+ [2][1][RTW89_MKK][0][27] = 2, -+ [2][1][RTW89_IC][1][27] = -16, -+ [2][1][RTW89_KCC][1][27] = -14, -+ [2][1][RTW89_KCC][0][27] = -14, -+ [2][1][RTW89_ACMA][1][27] = 44, -+ [2][1][RTW89_ACMA][0][27] = 6, -+ [2][1][RTW89_CHILE][1][27] = -16, -+ [2][1][RTW89_QATAR][1][27] = 44, -+ [2][1][RTW89_QATAR][0][27] = 6, -+ [2][1][RTW89_UK][1][27] = 44, -+ [2][1][RTW89_UK][0][27] = 6, -+ [2][1][RTW89_FCC][1][29] = -16, -+ [2][1][RTW89_FCC][2][29] = 54, -+ [2][1][RTW89_ETSI][1][29] = 44, -+ [2][1][RTW89_ETSI][0][29] = 6, -+ [2][1][RTW89_MKK][1][29] = 40, -+ [2][1][RTW89_MKK][0][29] = 2, -+ [2][1][RTW89_IC][1][29] = -16, -+ [2][1][RTW89_KCC][1][29] = -14, -+ [2][1][RTW89_KCC][0][29] = -14, -+ [2][1][RTW89_ACMA][1][29] = 44, -+ [2][1][RTW89_ACMA][0][29] = 6, -+ [2][1][RTW89_CHILE][1][29] = -16, -+ [2][1][RTW89_QATAR][1][29] = 44, -+ [2][1][RTW89_QATAR][0][29] = 6, -+ [2][1][RTW89_UK][1][29] = 44, -+ [2][1][RTW89_UK][0][29] = 6, -+ [2][1][RTW89_FCC][1][30] = -16, -+ [2][1][RTW89_FCC][2][30] = 54, -+ [2][1][RTW89_ETSI][1][30] = 44, -+ [2][1][RTW89_ETSI][0][30] = 6, -+ [2][1][RTW89_MKK][1][30] = 40, -+ [2][1][RTW89_MKK][0][30] = 2, -+ [2][1][RTW89_IC][1][30] = -16, -+ [2][1][RTW89_KCC][1][30] = -14, -+ [2][1][RTW89_KCC][0][30] = -14, -+ [2][1][RTW89_ACMA][1][30] = 44, -+ [2][1][RTW89_ACMA][0][30] = 6, -+ [2][1][RTW89_CHILE][1][30] = -16, -+ [2][1][RTW89_QATAR][1][30] = 44, -+ [2][1][RTW89_QATAR][0][30] = 6, -+ [2][1][RTW89_UK][1][30] = 44, -+ [2][1][RTW89_UK][0][30] = 6, -+ [2][1][RTW89_FCC][1][32] = -16, -+ [2][1][RTW89_FCC][2][32] = 54, -+ [2][1][RTW89_ETSI][1][32] = 44, -+ [2][1][RTW89_ETSI][0][32] = 6, -+ [2][1][RTW89_MKK][1][32] = 40, -+ [2][1][RTW89_MKK][0][32] = 2, -+ [2][1][RTW89_IC][1][32] = -16, -+ [2][1][RTW89_KCC][1][32] = -14, -+ [2][1][RTW89_KCC][0][32] = -14, -+ [2][1][RTW89_ACMA][1][32] = 44, -+ [2][1][RTW89_ACMA][0][32] = 6, -+ [2][1][RTW89_CHILE][1][32] = -16, -+ [2][1][RTW89_QATAR][1][32] = 44, -+ [2][1][RTW89_QATAR][0][32] = 6, -+ [2][1][RTW89_UK][1][32] = 44, -+ [2][1][RTW89_UK][0][32] = 6, -+ [2][1][RTW89_FCC][1][34] = -16, -+ [2][1][RTW89_FCC][2][34] = 54, -+ [2][1][RTW89_ETSI][1][34] = 44, -+ [2][1][RTW89_ETSI][0][34] = 6, -+ [2][1][RTW89_MKK][1][34] = 40, -+ [2][1][RTW89_MKK][0][34] = 2, -+ [2][1][RTW89_IC][1][34] = -16, -+ [2][1][RTW89_KCC][1][34] = -14, -+ [2][1][RTW89_KCC][0][34] = -14, -+ [2][1][RTW89_ACMA][1][34] = 44, -+ [2][1][RTW89_ACMA][0][34] = 6, -+ [2][1][RTW89_CHILE][1][34] = -16, -+ [2][1][RTW89_QATAR][1][34] = 44, -+ [2][1][RTW89_QATAR][0][34] = 6, -+ [2][1][RTW89_UK][1][34] = 44, -+ [2][1][RTW89_UK][0][34] = 6, -+ [2][1][RTW89_FCC][1][36] = -16, -+ [2][1][RTW89_FCC][2][36] = 54, -+ [2][1][RTW89_ETSI][1][36] = 44, -+ [2][1][RTW89_ETSI][0][36] = 6, -+ [2][1][RTW89_MKK][1][36] = 40, -+ [2][1][RTW89_MKK][0][36] = 2, -+ [2][1][RTW89_IC][1][36] = -16, -+ [2][1][RTW89_KCC][1][36] = -14, -+ [2][1][RTW89_KCC][0][36] = -14, -+ [2][1][RTW89_ACMA][1][36] = 44, -+ [2][1][RTW89_ACMA][0][36] = 6, -+ [2][1][RTW89_CHILE][1][36] = -16, -+ [2][1][RTW89_QATAR][1][36] = 44, -+ [2][1][RTW89_QATAR][0][36] = 6, -+ [2][1][RTW89_UK][1][36] = 44, -+ [2][1][RTW89_UK][0][36] = 6, -+ [2][1][RTW89_FCC][1][38] = -16, -+ [2][1][RTW89_FCC][2][38] = 54, -+ [2][1][RTW89_ETSI][1][38] = 44, -+ [2][1][RTW89_ETSI][0][38] = 6, -+ [2][1][RTW89_MKK][1][38] = 40, -+ [2][1][RTW89_MKK][0][38] = 2, -+ [2][1][RTW89_IC][1][38] = -16, -+ [2][1][RTW89_KCC][1][38] = -14, -+ [2][1][RTW89_KCC][0][38] = -14, -+ [2][1][RTW89_ACMA][1][38] = 44, -+ [2][1][RTW89_ACMA][0][38] = 6, -+ [2][1][RTW89_CHILE][1][38] = -16, -+ [2][1][RTW89_QATAR][1][38] = 44, -+ [2][1][RTW89_QATAR][0][38] = 6, -+ [2][1][RTW89_UK][1][38] = 44, -+ [2][1][RTW89_UK][0][38] = 6, -+ [2][1][RTW89_FCC][1][40] = -16, -+ [2][1][RTW89_FCC][2][40] = 54, -+ [2][1][RTW89_ETSI][1][40] = 44, -+ [2][1][RTW89_ETSI][0][40] = 6, -+ [2][1][RTW89_MKK][1][40] = 40, -+ [2][1][RTW89_MKK][0][40] = 2, -+ [2][1][RTW89_IC][1][40] = -16, -+ [2][1][RTW89_KCC][1][40] = -14, -+ [2][1][RTW89_KCC][0][40] = -14, -+ [2][1][RTW89_ACMA][1][40] = 44, -+ [2][1][RTW89_ACMA][0][40] = 6, -+ [2][1][RTW89_CHILE][1][40] = -16, -+ [2][1][RTW89_QATAR][1][40] = 44, -+ [2][1][RTW89_QATAR][0][40] = 6, -+ [2][1][RTW89_UK][1][40] = 44, -+ [2][1][RTW89_UK][0][40] = 6, -+ [2][1][RTW89_FCC][1][42] = -16, -+ [2][1][RTW89_FCC][2][42] = 54, -+ [2][1][RTW89_ETSI][1][42] = 44, -+ [2][1][RTW89_ETSI][0][42] = 6, -+ [2][1][RTW89_MKK][1][42] = 40, -+ [2][1][RTW89_MKK][0][42] = 2, -+ [2][1][RTW89_IC][1][42] = -16, -+ [2][1][RTW89_KCC][1][42] = -14, -+ [2][1][RTW89_KCC][0][42] = -14, -+ [2][1][RTW89_ACMA][1][42] = 44, -+ [2][1][RTW89_ACMA][0][42] = 6, -+ [2][1][RTW89_CHILE][1][42] = -16, -+ [2][1][RTW89_QATAR][1][42] = 44, -+ [2][1][RTW89_QATAR][0][42] = 6, -+ [2][1][RTW89_UK][1][42] = 44, -+ [2][1][RTW89_UK][0][42] = 6, -+ [2][1][RTW89_FCC][1][44] = -16, -+ [2][1][RTW89_FCC][2][44] = 54, -+ [2][1][RTW89_ETSI][1][44] = 44, -+ [2][1][RTW89_ETSI][0][44] = 6, -+ [2][1][RTW89_MKK][1][44] = 16, -+ [2][1][RTW89_MKK][0][44] = 2, -+ [2][1][RTW89_IC][1][44] = -16, -+ [2][1][RTW89_KCC][1][44] = -14, -+ [2][1][RTW89_KCC][0][44] = -14, -+ [2][1][RTW89_ACMA][1][44] = 44, -+ [2][1][RTW89_ACMA][0][44] = 6, -+ [2][1][RTW89_CHILE][1][44] = -16, -+ [2][1][RTW89_QATAR][1][44] = 44, -+ [2][1][RTW89_QATAR][0][44] = 6, -+ [2][1][RTW89_UK][1][44] = 44, -+ [2][1][RTW89_UK][0][44] = 6, -+ [2][1][RTW89_FCC][1][45] = -16, -+ [2][1][RTW89_FCC][2][45] = 127, -+ [2][1][RTW89_ETSI][1][45] = 127, -+ [2][1][RTW89_ETSI][0][45] = 127, -+ [2][1][RTW89_MKK][1][45] = 127, -+ [2][1][RTW89_MKK][0][45] = 127, -+ [2][1][RTW89_IC][1][45] = -16, -+ [2][1][RTW89_KCC][1][45] = -14, -+ [2][1][RTW89_KCC][0][45] = 127, -+ [2][1][RTW89_ACMA][1][45] = 127, -+ [2][1][RTW89_ACMA][0][45] = 127, -+ [2][1][RTW89_CHILE][1][45] = 127, -+ [2][1][RTW89_QATAR][1][45] = 127, -+ [2][1][RTW89_QATAR][0][45] = 127, -+ [2][1][RTW89_UK][1][45] = 127, -+ [2][1][RTW89_UK][0][45] = 127, -+ [2][1][RTW89_FCC][1][47] = -16, -+ [2][1][RTW89_FCC][2][47] = 127, -+ [2][1][RTW89_ETSI][1][47] = 127, -+ [2][1][RTW89_ETSI][0][47] = 127, -+ [2][1][RTW89_MKK][1][47] = 127, -+ [2][1][RTW89_MKK][0][47] = 127, -+ [2][1][RTW89_IC][1][47] = -16, -+ [2][1][RTW89_KCC][1][47] = -14, -+ [2][1][RTW89_KCC][0][47] = 127, -+ [2][1][RTW89_ACMA][1][47] = 127, -+ [2][1][RTW89_ACMA][0][47] = 127, -+ [2][1][RTW89_CHILE][1][47] = 127, -+ [2][1][RTW89_QATAR][1][47] = 127, -+ [2][1][RTW89_QATAR][0][47] = 127, -+ [2][1][RTW89_UK][1][47] = 127, -+ [2][1][RTW89_UK][0][47] = 127, -+ [2][1][RTW89_FCC][1][49] = -16, -+ [2][1][RTW89_FCC][2][49] = 127, -+ [2][1][RTW89_ETSI][1][49] = 127, -+ [2][1][RTW89_ETSI][0][49] = 127, -+ [2][1][RTW89_MKK][1][49] = 127, -+ [2][1][RTW89_MKK][0][49] = 127, -+ [2][1][RTW89_IC][1][49] = -16, -+ [2][1][RTW89_KCC][1][49] = -14, -+ [2][1][RTW89_KCC][0][49] = 127, -+ [2][1][RTW89_ACMA][1][49] = 127, -+ [2][1][RTW89_ACMA][0][49] = 127, -+ [2][1][RTW89_CHILE][1][49] = 127, -+ [2][1][RTW89_QATAR][1][49] = 127, -+ [2][1][RTW89_QATAR][0][49] = 127, -+ [2][1][RTW89_UK][1][49] = 127, -+ [2][1][RTW89_UK][0][49] = 127, -+ [2][1][RTW89_FCC][1][51] = -16, -+ [2][1][RTW89_FCC][2][51] = 127, -+ [2][1][RTW89_ETSI][1][51] = 127, -+ [2][1][RTW89_ETSI][0][51] = 127, -+ [2][1][RTW89_MKK][1][51] = 127, -+ [2][1][RTW89_MKK][0][51] = 127, -+ [2][1][RTW89_IC][1][51] = -16, -+ [2][1][RTW89_KCC][1][51] = -14, -+ [2][1][RTW89_KCC][0][51] = 127, -+ [2][1][RTW89_ACMA][1][51] = 127, -+ [2][1][RTW89_ACMA][0][51] = 127, -+ [2][1][RTW89_CHILE][1][51] = 127, -+ [2][1][RTW89_QATAR][1][51] = 127, -+ [2][1][RTW89_QATAR][0][51] = 127, -+ [2][1][RTW89_UK][1][51] = 127, -+ [2][1][RTW89_UK][0][51] = 127, -+ [2][1][RTW89_FCC][1][53] = -16, -+ [2][1][RTW89_FCC][2][53] = 127, -+ [2][1][RTW89_ETSI][1][53] = 127, -+ [2][1][RTW89_ETSI][0][53] = 127, -+ [2][1][RTW89_MKK][1][53] = 127, -+ [2][1][RTW89_MKK][0][53] = 127, -+ [2][1][RTW89_IC][1][53] = -16, -+ [2][1][RTW89_KCC][1][53] = -14, -+ [2][1][RTW89_KCC][0][53] = 127, -+ [2][1][RTW89_ACMA][1][53] = 127, -+ [2][1][RTW89_ACMA][0][53] = 127, -+ [2][1][RTW89_CHILE][1][53] = 127, -+ [2][1][RTW89_QATAR][1][53] = 127, -+ [2][1][RTW89_QATAR][0][53] = 127, -+ [2][1][RTW89_UK][1][53] = 127, -+ [2][1][RTW89_UK][0][53] = 127, -+ [2][1][RTW89_FCC][1][55] = -16, -+ [2][1][RTW89_FCC][2][55] = 54, -+ [2][1][RTW89_ETSI][1][55] = 127, -+ [2][1][RTW89_ETSI][0][55] = 127, -+ [2][1][RTW89_MKK][1][55] = 127, -+ [2][1][RTW89_MKK][0][55] = 127, -+ [2][1][RTW89_IC][1][55] = -16, -+ [2][1][RTW89_KCC][1][55] = -14, -+ [2][1][RTW89_KCC][0][55] = 127, -+ [2][1][RTW89_ACMA][1][55] = 127, -+ [2][1][RTW89_ACMA][0][55] = 127, -+ [2][1][RTW89_CHILE][1][55] = 127, -+ [2][1][RTW89_QATAR][1][55] = 127, -+ [2][1][RTW89_QATAR][0][55] = 127, -+ [2][1][RTW89_UK][1][55] = 127, -+ [2][1][RTW89_UK][0][55] = 127, -+ [2][1][RTW89_FCC][1][57] = -16, -+ [2][1][RTW89_FCC][2][57] = 54, -+ [2][1][RTW89_ETSI][1][57] = 127, -+ [2][1][RTW89_ETSI][0][57] = 127, -+ [2][1][RTW89_MKK][1][57] = 127, -+ [2][1][RTW89_MKK][0][57] = 127, -+ [2][1][RTW89_IC][1][57] = -16, -+ [2][1][RTW89_KCC][1][57] = -14, -+ [2][1][RTW89_KCC][0][57] = 127, -+ [2][1][RTW89_ACMA][1][57] = 127, -+ [2][1][RTW89_ACMA][0][57] = 127, -+ [2][1][RTW89_CHILE][1][57] = 127, -+ [2][1][RTW89_QATAR][1][57] = 127, -+ [2][1][RTW89_QATAR][0][57] = 127, -+ [2][1][RTW89_UK][1][57] = 127, -+ [2][1][RTW89_UK][0][57] = 127, -+ [2][1][RTW89_FCC][1][59] = -16, -+ [2][1][RTW89_FCC][2][59] = 54, -+ [2][1][RTW89_ETSI][1][59] = 127, -+ [2][1][RTW89_ETSI][0][59] = 127, -+ [2][1][RTW89_MKK][1][59] = 127, -+ [2][1][RTW89_MKK][0][59] = 127, -+ [2][1][RTW89_IC][1][59] = -16, -+ [2][1][RTW89_KCC][1][59] = -14, -+ [2][1][RTW89_KCC][0][59] = 127, -+ [2][1][RTW89_ACMA][1][59] = 127, -+ [2][1][RTW89_ACMA][0][59] = 127, -+ [2][1][RTW89_CHILE][1][59] = 127, -+ [2][1][RTW89_QATAR][1][59] = 127, -+ [2][1][RTW89_QATAR][0][59] = 127, -+ [2][1][RTW89_UK][1][59] = 127, -+ [2][1][RTW89_UK][0][59] = 127, -+ [2][1][RTW89_FCC][1][60] = -16, -+ [2][1][RTW89_FCC][2][60] = 54, -+ [2][1][RTW89_ETSI][1][60] = 127, -+ [2][1][RTW89_ETSI][0][60] = 127, -+ [2][1][RTW89_MKK][1][60] = 127, -+ [2][1][RTW89_MKK][0][60] = 127, -+ [2][1][RTW89_IC][1][60] = -16, -+ [2][1][RTW89_KCC][1][60] = -14, -+ [2][1][RTW89_KCC][0][60] = 127, -+ [2][1][RTW89_ACMA][1][60] = 127, -+ [2][1][RTW89_ACMA][0][60] = 127, -+ [2][1][RTW89_CHILE][1][60] = 127, -+ [2][1][RTW89_QATAR][1][60] = 127, -+ [2][1][RTW89_QATAR][0][60] = 127, -+ [2][1][RTW89_UK][1][60] = 127, -+ [2][1][RTW89_UK][0][60] = 127, -+ [2][1][RTW89_FCC][1][62] = -16, -+ [2][1][RTW89_FCC][2][62] = 54, -+ [2][1][RTW89_ETSI][1][62] = 127, -+ [2][1][RTW89_ETSI][0][62] = 127, -+ [2][1][RTW89_MKK][1][62] = 127, -+ [2][1][RTW89_MKK][0][62] = 127, -+ [2][1][RTW89_IC][1][62] = -16, -+ [2][1][RTW89_KCC][1][62] = -14, -+ [2][1][RTW89_KCC][0][62] = 127, -+ [2][1][RTW89_ACMA][1][62] = 127, -+ [2][1][RTW89_ACMA][0][62] = 127, -+ [2][1][RTW89_CHILE][1][62] = 127, -+ [2][1][RTW89_QATAR][1][62] = 127, -+ [2][1][RTW89_QATAR][0][62] = 127, -+ [2][1][RTW89_UK][1][62] = 127, -+ [2][1][RTW89_UK][0][62] = 127, -+ [2][1][RTW89_FCC][1][64] = -16, -+ [2][1][RTW89_FCC][2][64] = 54, -+ [2][1][RTW89_ETSI][1][64] = 127, -+ [2][1][RTW89_ETSI][0][64] = 127, -+ [2][1][RTW89_MKK][1][64] = 127, -+ [2][1][RTW89_MKK][0][64] = 127, -+ [2][1][RTW89_IC][1][64] = -16, -+ [2][1][RTW89_KCC][1][64] = -14, -+ [2][1][RTW89_KCC][0][64] = 127, -+ [2][1][RTW89_ACMA][1][64] = 127, -+ [2][1][RTW89_ACMA][0][64] = 127, -+ [2][1][RTW89_CHILE][1][64] = 127, -+ [2][1][RTW89_QATAR][1][64] = 127, -+ [2][1][RTW89_QATAR][0][64] = 127, -+ [2][1][RTW89_UK][1][64] = 127, -+ [2][1][RTW89_UK][0][64] = 127, -+ [2][1][RTW89_FCC][1][66] = -16, -+ [2][1][RTW89_FCC][2][66] = 54, -+ [2][1][RTW89_ETSI][1][66] = 127, -+ [2][1][RTW89_ETSI][0][66] = 127, -+ [2][1][RTW89_MKK][1][66] = 127, -+ [2][1][RTW89_MKK][0][66] = 127, -+ [2][1][RTW89_IC][1][66] = -16, -+ [2][1][RTW89_KCC][1][66] = -14, -+ [2][1][RTW89_KCC][0][66] = 127, -+ [2][1][RTW89_ACMA][1][66] = 127, -+ [2][1][RTW89_ACMA][0][66] = 127, -+ [2][1][RTW89_CHILE][1][66] = 127, -+ [2][1][RTW89_QATAR][1][66] = 127, -+ [2][1][RTW89_QATAR][0][66] = 127, -+ [2][1][RTW89_UK][1][66] = 127, -+ [2][1][RTW89_UK][0][66] = 127, -+ [2][1][RTW89_FCC][1][68] = -16, -+ [2][1][RTW89_FCC][2][68] = 54, -+ [2][1][RTW89_ETSI][1][68] = 127, -+ [2][1][RTW89_ETSI][0][68] = 127, -+ [2][1][RTW89_MKK][1][68] = 127, -+ [2][1][RTW89_MKK][0][68] = 127, -+ [2][1][RTW89_IC][1][68] = -16, -+ [2][1][RTW89_KCC][1][68] = -14, -+ [2][1][RTW89_KCC][0][68] = 127, -+ [2][1][RTW89_ACMA][1][68] = 127, -+ [2][1][RTW89_ACMA][0][68] = 127, -+ [2][1][RTW89_CHILE][1][68] = 127, -+ [2][1][RTW89_QATAR][1][68] = 127, -+ [2][1][RTW89_QATAR][0][68] = 127, -+ [2][1][RTW89_UK][1][68] = 127, -+ [2][1][RTW89_UK][0][68] = 127, -+ [2][1][RTW89_FCC][1][70] = -16, -+ [2][1][RTW89_FCC][2][70] = 56, -+ [2][1][RTW89_ETSI][1][70] = 127, -+ [2][1][RTW89_ETSI][0][70] = 127, -+ [2][1][RTW89_MKK][1][70] = 127, -+ [2][1][RTW89_MKK][0][70] = 127, -+ [2][1][RTW89_IC][1][70] = -16, -+ [2][1][RTW89_KCC][1][70] = -14, -+ [2][1][RTW89_KCC][0][70] = 127, -+ [2][1][RTW89_ACMA][1][70] = 127, -+ [2][1][RTW89_ACMA][0][70] = 127, -+ [2][1][RTW89_CHILE][1][70] = 127, -+ [2][1][RTW89_QATAR][1][70] = 127, -+ [2][1][RTW89_QATAR][0][70] = 127, -+ [2][1][RTW89_UK][1][70] = 127, -+ [2][1][RTW89_UK][0][70] = 127, -+ [2][1][RTW89_FCC][1][72] = -16, -+ [2][1][RTW89_FCC][2][72] = 56, -+ [2][1][RTW89_ETSI][1][72] = 127, -+ [2][1][RTW89_ETSI][0][72] = 127, -+ [2][1][RTW89_MKK][1][72] = 127, -+ [2][1][RTW89_MKK][0][72] = 127, -+ [2][1][RTW89_IC][1][72] = -16, -+ [2][1][RTW89_KCC][1][72] = -14, -+ [2][1][RTW89_KCC][0][72] = 127, -+ [2][1][RTW89_ACMA][1][72] = 127, -+ [2][1][RTW89_ACMA][0][72] = 127, -+ [2][1][RTW89_CHILE][1][72] = 127, -+ [2][1][RTW89_QATAR][1][72] = 127, -+ [2][1][RTW89_QATAR][0][72] = 127, -+ [2][1][RTW89_UK][1][72] = 127, -+ [2][1][RTW89_UK][0][72] = 127, -+ [2][1][RTW89_FCC][1][74] = -16, -+ [2][1][RTW89_FCC][2][74] = 56, -+ [2][1][RTW89_ETSI][1][74] = 127, -+ [2][1][RTW89_ETSI][0][74] = 127, -+ [2][1][RTW89_MKK][1][74] = 127, -+ [2][1][RTW89_MKK][0][74] = 127, -+ [2][1][RTW89_IC][1][74] = -16, -+ [2][1][RTW89_KCC][1][74] = -14, -+ [2][1][RTW89_KCC][0][74] = 127, -+ [2][1][RTW89_ACMA][1][74] = 127, -+ [2][1][RTW89_ACMA][0][74] = 127, -+ [2][1][RTW89_CHILE][1][74] = 127, -+ [2][1][RTW89_QATAR][1][74] = 127, -+ [2][1][RTW89_QATAR][0][74] = 127, -+ [2][1][RTW89_UK][1][74] = 127, -+ [2][1][RTW89_UK][0][74] = 127, -+ [2][1][RTW89_FCC][1][75] = -16, -+ [2][1][RTW89_FCC][2][75] = 56, -+ [2][1][RTW89_ETSI][1][75] = 127, -+ [2][1][RTW89_ETSI][0][75] = 127, -+ [2][1][RTW89_MKK][1][75] = 127, -+ [2][1][RTW89_MKK][0][75] = 127, -+ [2][1][RTW89_IC][1][75] = -16, -+ [2][1][RTW89_KCC][1][75] = -14, -+ [2][1][RTW89_KCC][0][75] = 127, -+ [2][1][RTW89_ACMA][1][75] = 127, -+ [2][1][RTW89_ACMA][0][75] = 127, -+ [2][1][RTW89_CHILE][1][75] = 127, -+ [2][1][RTW89_QATAR][1][75] = 127, -+ [2][1][RTW89_QATAR][0][75] = 127, -+ [2][1][RTW89_UK][1][75] = 127, -+ [2][1][RTW89_UK][0][75] = 127, -+ [2][1][RTW89_FCC][1][77] = -16, -+ [2][1][RTW89_FCC][2][77] = 56, -+ [2][1][RTW89_ETSI][1][77] = 127, -+ [2][1][RTW89_ETSI][0][77] = 127, -+ [2][1][RTW89_MKK][1][77] = 127, -+ [2][1][RTW89_MKK][0][77] = 127, -+ [2][1][RTW89_IC][1][77] = -16, -+ [2][1][RTW89_KCC][1][77] = -14, -+ [2][1][RTW89_KCC][0][77] = 127, -+ [2][1][RTW89_ACMA][1][77] = 127, -+ [2][1][RTW89_ACMA][0][77] = 127, -+ [2][1][RTW89_CHILE][1][77] = 127, -+ [2][1][RTW89_QATAR][1][77] = 127, -+ [2][1][RTW89_QATAR][0][77] = 127, -+ [2][1][RTW89_UK][1][77] = 127, -+ [2][1][RTW89_UK][0][77] = 127, -+ [2][1][RTW89_FCC][1][79] = -16, -+ [2][1][RTW89_FCC][2][79] = 56, -+ [2][1][RTW89_ETSI][1][79] = 127, -+ [2][1][RTW89_ETSI][0][79] = 127, -+ [2][1][RTW89_MKK][1][79] = 127, -+ [2][1][RTW89_MKK][0][79] = 127, -+ [2][1][RTW89_IC][1][79] = -16, -+ [2][1][RTW89_KCC][1][79] = -14, -+ [2][1][RTW89_KCC][0][79] = 127, -+ [2][1][RTW89_ACMA][1][79] = 127, -+ [2][1][RTW89_ACMA][0][79] = 127, -+ [2][1][RTW89_CHILE][1][79] = 127, -+ [2][1][RTW89_QATAR][1][79] = 127, -+ [2][1][RTW89_QATAR][0][79] = 127, -+ [2][1][RTW89_UK][1][79] = 127, -+ [2][1][RTW89_UK][0][79] = 127, -+ [2][1][RTW89_FCC][1][81] = -16, -+ [2][1][RTW89_FCC][2][81] = 56, -+ [2][1][RTW89_ETSI][1][81] = 127, -+ [2][1][RTW89_ETSI][0][81] = 127, -+ [2][1][RTW89_MKK][1][81] = 127, -+ [2][1][RTW89_MKK][0][81] = 127, -+ [2][1][RTW89_IC][1][81] = -16, -+ [2][1][RTW89_KCC][1][81] = -14, -+ [2][1][RTW89_KCC][0][81] = 127, -+ [2][1][RTW89_ACMA][1][81] = 127, -+ [2][1][RTW89_ACMA][0][81] = 127, -+ [2][1][RTW89_CHILE][1][81] = 127, -+ [2][1][RTW89_QATAR][1][81] = 127, -+ [2][1][RTW89_QATAR][0][81] = 127, -+ [2][1][RTW89_UK][1][81] = 127, -+ [2][1][RTW89_UK][0][81] = 127, -+ [2][1][RTW89_FCC][1][83] = -16, -+ [2][1][RTW89_FCC][2][83] = 56, -+ [2][1][RTW89_ETSI][1][83] = 127, -+ [2][1][RTW89_ETSI][0][83] = 127, -+ [2][1][RTW89_MKK][1][83] = 127, -+ [2][1][RTW89_MKK][0][83] = 127, -+ [2][1][RTW89_IC][1][83] = -16, -+ [2][1][RTW89_KCC][1][83] = -14, -+ [2][1][RTW89_KCC][0][83] = 127, -+ [2][1][RTW89_ACMA][1][83] = 127, -+ [2][1][RTW89_ACMA][0][83] = 127, -+ [2][1][RTW89_CHILE][1][83] = 127, -+ [2][1][RTW89_QATAR][1][83] = 127, -+ [2][1][RTW89_QATAR][0][83] = 127, -+ [2][1][RTW89_UK][1][83] = 127, -+ [2][1][RTW89_UK][0][83] = 127, -+ [2][1][RTW89_FCC][1][85] = -18, -+ [2][1][RTW89_FCC][2][85] = 56, -+ [2][1][RTW89_ETSI][1][85] = 127, -+ [2][1][RTW89_ETSI][0][85] = 127, -+ [2][1][RTW89_MKK][1][85] = 127, -+ [2][1][RTW89_MKK][0][85] = 127, -+ [2][1][RTW89_IC][1][85] = -18, -+ [2][1][RTW89_KCC][1][85] = -14, -+ [2][1][RTW89_KCC][0][85] = 127, -+ [2][1][RTW89_ACMA][1][85] = 127, -+ [2][1][RTW89_ACMA][0][85] = 127, -+ [2][1][RTW89_CHILE][1][85] = 127, -+ [2][1][RTW89_QATAR][1][85] = 127, -+ [2][1][RTW89_QATAR][0][85] = 127, -+ [2][1][RTW89_UK][1][85] = 127, -+ [2][1][RTW89_UK][0][85] = 127, -+ [2][1][RTW89_FCC][1][87] = -16, -+ [2][1][RTW89_FCC][2][87] = 127, -+ [2][1][RTW89_ETSI][1][87] = 127, -+ [2][1][RTW89_ETSI][0][87] = 127, -+ [2][1][RTW89_MKK][1][87] = 127, -+ [2][1][RTW89_MKK][0][87] = 127, -+ [2][1][RTW89_IC][1][87] = -16, -+ [2][1][RTW89_KCC][1][87] = -14, -+ [2][1][RTW89_KCC][0][87] = 127, -+ [2][1][RTW89_ACMA][1][87] = 127, -+ [2][1][RTW89_ACMA][0][87] = 127, -+ [2][1][RTW89_CHILE][1][87] = 127, -+ [2][1][RTW89_QATAR][1][87] = 127, -+ [2][1][RTW89_QATAR][0][87] = 127, -+ [2][1][RTW89_UK][1][87] = 127, -+ [2][1][RTW89_UK][0][87] = 127, -+ [2][1][RTW89_FCC][1][89] = -16, -+ [2][1][RTW89_FCC][2][89] = 127, -+ [2][1][RTW89_ETSI][1][89] = 127, -+ [2][1][RTW89_ETSI][0][89] = 127, -+ [2][1][RTW89_MKK][1][89] = 127, -+ [2][1][RTW89_MKK][0][89] = 127, -+ [2][1][RTW89_IC][1][89] = -16, -+ [2][1][RTW89_KCC][1][89] = -14, -+ [2][1][RTW89_KCC][0][89] = 127, -+ [2][1][RTW89_ACMA][1][89] = 127, -+ [2][1][RTW89_ACMA][0][89] = 127, -+ [2][1][RTW89_CHILE][1][89] = 127, -+ [2][1][RTW89_QATAR][1][89] = 127, -+ [2][1][RTW89_QATAR][0][89] = 127, -+ [2][1][RTW89_UK][1][89] = 127, -+ [2][1][RTW89_UK][0][89] = 127, -+ [2][1][RTW89_FCC][1][90] = -16, -+ [2][1][RTW89_FCC][2][90] = 127, -+ [2][1][RTW89_ETSI][1][90] = 127, -+ [2][1][RTW89_ETSI][0][90] = 127, -+ [2][1][RTW89_MKK][1][90] = 127, -+ [2][1][RTW89_MKK][0][90] = 127, -+ [2][1][RTW89_IC][1][90] = -16, -+ [2][1][RTW89_KCC][1][90] = -14, -+ [2][1][RTW89_KCC][0][90] = 127, -+ [2][1][RTW89_ACMA][1][90] = 127, -+ [2][1][RTW89_ACMA][0][90] = 127, -+ [2][1][RTW89_CHILE][1][90] = 127, -+ [2][1][RTW89_QATAR][1][90] = 127, -+ [2][1][RTW89_QATAR][0][90] = 127, -+ [2][1][RTW89_UK][1][90] = 127, -+ [2][1][RTW89_UK][0][90] = 127, -+ [2][1][RTW89_FCC][1][92] = -16, -+ [2][1][RTW89_FCC][2][92] = 127, -+ [2][1][RTW89_ETSI][1][92] = 127, -+ [2][1][RTW89_ETSI][0][92] = 127, -+ [2][1][RTW89_MKK][1][92] = 127, -+ [2][1][RTW89_MKK][0][92] = 127, -+ [2][1][RTW89_IC][1][92] = -16, -+ [2][1][RTW89_KCC][1][92] = -14, -+ [2][1][RTW89_KCC][0][92] = 127, -+ [2][1][RTW89_ACMA][1][92] = 127, -+ [2][1][RTW89_ACMA][0][92] = 127, -+ [2][1][RTW89_CHILE][1][92] = 127, -+ [2][1][RTW89_QATAR][1][92] = 127, -+ [2][1][RTW89_QATAR][0][92] = 127, -+ [2][1][RTW89_UK][1][92] = 127, -+ [2][1][RTW89_UK][0][92] = 127, -+ [2][1][RTW89_FCC][1][94] = -16, -+ [2][1][RTW89_FCC][2][94] = 127, -+ [2][1][RTW89_ETSI][1][94] = 127, -+ [2][1][RTW89_ETSI][0][94] = 127, -+ [2][1][RTW89_MKK][1][94] = 127, -+ [2][1][RTW89_MKK][0][94] = 127, -+ [2][1][RTW89_IC][1][94] = -16, -+ [2][1][RTW89_KCC][1][94] = -14, -+ [2][1][RTW89_KCC][0][94] = 127, -+ [2][1][RTW89_ACMA][1][94] = 127, -+ [2][1][RTW89_ACMA][0][94] = 127, -+ [2][1][RTW89_CHILE][1][94] = 127, -+ [2][1][RTW89_QATAR][1][94] = 127, -+ [2][1][RTW89_QATAR][0][94] = 127, -+ [2][1][RTW89_UK][1][94] = 127, -+ [2][1][RTW89_UK][0][94] = 127, -+ [2][1][RTW89_FCC][1][96] = -16, -+ [2][1][RTW89_FCC][2][96] = 127, -+ [2][1][RTW89_ETSI][1][96] = 127, -+ [2][1][RTW89_ETSI][0][96] = 127, -+ [2][1][RTW89_MKK][1][96] = 127, -+ [2][1][RTW89_MKK][0][96] = 127, -+ [2][1][RTW89_IC][1][96] = -16, -+ [2][1][RTW89_KCC][1][96] = -14, -+ [2][1][RTW89_KCC][0][96] = 127, -+ [2][1][RTW89_ACMA][1][96] = 127, -+ [2][1][RTW89_ACMA][0][96] = 127, -+ [2][1][RTW89_CHILE][1][96] = 127, -+ [2][1][RTW89_QATAR][1][96] = 127, -+ [2][1][RTW89_QATAR][0][96] = 127, -+ [2][1][RTW89_UK][1][96] = 127, -+ [2][1][RTW89_UK][0][96] = 127, -+ [2][1][RTW89_FCC][1][98] = -16, -+ [2][1][RTW89_FCC][2][98] = 127, -+ [2][1][RTW89_ETSI][1][98] = 127, -+ [2][1][RTW89_ETSI][0][98] = 127, -+ [2][1][RTW89_MKK][1][98] = 127, -+ [2][1][RTW89_MKK][0][98] = 127, -+ [2][1][RTW89_IC][1][98] = -16, -+ [2][1][RTW89_KCC][1][98] = -14, -+ [2][1][RTW89_KCC][0][98] = 127, -+ [2][1][RTW89_ACMA][1][98] = 127, -+ [2][1][RTW89_ACMA][0][98] = 127, -+ [2][1][RTW89_CHILE][1][98] = 127, -+ [2][1][RTW89_QATAR][1][98] = 127, -+ [2][1][RTW89_QATAR][0][98] = 127, -+ [2][1][RTW89_UK][1][98] = 127, -+ [2][1][RTW89_UK][0][98] = 127, -+ [2][1][RTW89_FCC][1][100] = -16, -+ [2][1][RTW89_FCC][2][100] = 127, -+ [2][1][RTW89_ETSI][1][100] = 127, -+ [2][1][RTW89_ETSI][0][100] = 127, -+ [2][1][RTW89_MKK][1][100] = 127, -+ [2][1][RTW89_MKK][0][100] = 127, -+ [2][1][RTW89_IC][1][100] = -16, -+ [2][1][RTW89_KCC][1][100] = -14, -+ [2][1][RTW89_KCC][0][100] = 127, -+ [2][1][RTW89_ACMA][1][100] = 127, -+ [2][1][RTW89_ACMA][0][100] = 127, -+ [2][1][RTW89_CHILE][1][100] = 127, -+ [2][1][RTW89_QATAR][1][100] = 127, -+ [2][1][RTW89_QATAR][0][100] = 127, -+ [2][1][RTW89_UK][1][100] = 127, -+ [2][1][RTW89_UK][0][100] = 127, -+ [2][1][RTW89_FCC][1][102] = -16, -+ [2][1][RTW89_FCC][2][102] = 127, -+ [2][1][RTW89_ETSI][1][102] = 127, -+ [2][1][RTW89_ETSI][0][102] = 127, -+ [2][1][RTW89_MKK][1][102] = 127, -+ [2][1][RTW89_MKK][0][102] = 127, -+ [2][1][RTW89_IC][1][102] = -16, -+ [2][1][RTW89_KCC][1][102] = -14, -+ [2][1][RTW89_KCC][0][102] = 127, -+ [2][1][RTW89_ACMA][1][102] = 127, -+ [2][1][RTW89_ACMA][0][102] = 127, -+ [2][1][RTW89_CHILE][1][102] = 127, -+ [2][1][RTW89_QATAR][1][102] = 127, -+ [2][1][RTW89_QATAR][0][102] = 127, -+ [2][1][RTW89_UK][1][102] = 127, -+ [2][1][RTW89_UK][0][102] = 127, -+ [2][1][RTW89_FCC][1][104] = -16, -+ [2][1][RTW89_FCC][2][104] = 127, -+ [2][1][RTW89_ETSI][1][104] = 127, -+ [2][1][RTW89_ETSI][0][104] = 127, -+ [2][1][RTW89_MKK][1][104] = 127, -+ [2][1][RTW89_MKK][0][104] = 127, -+ [2][1][RTW89_IC][1][104] = -16, -+ [2][1][RTW89_KCC][1][104] = -14, -+ [2][1][RTW89_KCC][0][104] = 127, -+ [2][1][RTW89_ACMA][1][104] = 127, -+ [2][1][RTW89_ACMA][0][104] = 127, -+ [2][1][RTW89_CHILE][1][104] = 127, -+ [2][1][RTW89_QATAR][1][104] = 127, -+ [2][1][RTW89_QATAR][0][104] = 127, -+ [2][1][RTW89_UK][1][104] = 127, -+ [2][1][RTW89_UK][0][104] = 127, -+ [2][1][RTW89_FCC][1][105] = -16, -+ [2][1][RTW89_FCC][2][105] = 127, -+ [2][1][RTW89_ETSI][1][105] = 127, -+ [2][1][RTW89_ETSI][0][105] = 127, -+ [2][1][RTW89_MKK][1][105] = 127, -+ [2][1][RTW89_MKK][0][105] = 127, -+ [2][1][RTW89_IC][1][105] = -16, -+ [2][1][RTW89_KCC][1][105] = -14, -+ [2][1][RTW89_KCC][0][105] = 127, -+ [2][1][RTW89_ACMA][1][105] = 127, -+ [2][1][RTW89_ACMA][0][105] = 127, -+ [2][1][RTW89_CHILE][1][105] = 127, -+ [2][1][RTW89_QATAR][1][105] = 127, -+ [2][1][RTW89_QATAR][0][105] = 127, -+ [2][1][RTW89_UK][1][105] = 127, -+ [2][1][RTW89_UK][0][105] = 127, -+ [2][1][RTW89_FCC][1][107] = -12, -+ [2][1][RTW89_FCC][2][107] = 127, -+ [2][1][RTW89_ETSI][1][107] = 127, -+ [2][1][RTW89_ETSI][0][107] = 127, -+ [2][1][RTW89_MKK][1][107] = 127, -+ [2][1][RTW89_MKK][0][107] = 127, -+ [2][1][RTW89_IC][1][107] = -12, -+ [2][1][RTW89_KCC][1][107] = -14, -+ [2][1][RTW89_KCC][0][107] = 127, -+ [2][1][RTW89_ACMA][1][107] = 127, -+ [2][1][RTW89_ACMA][0][107] = 127, -+ [2][1][RTW89_CHILE][1][107] = 127, -+ [2][1][RTW89_QATAR][1][107] = 127, -+ [2][1][RTW89_QATAR][0][107] = 127, -+ [2][1][RTW89_UK][1][107] = 127, -+ [2][1][RTW89_UK][0][107] = 127, -+ [2][1][RTW89_FCC][1][109] = -10, -+ [2][1][RTW89_FCC][2][109] = 127, -+ [2][1][RTW89_ETSI][1][109] = 127, -+ [2][1][RTW89_ETSI][0][109] = 127, -+ [2][1][RTW89_MKK][1][109] = 127, -+ [2][1][RTW89_MKK][0][109] = 127, -+ [2][1][RTW89_IC][1][109] = -10, -+ [2][1][RTW89_KCC][1][109] = 127, -+ [2][1][RTW89_KCC][0][109] = 127, -+ [2][1][RTW89_ACMA][1][109] = 127, -+ [2][1][RTW89_ACMA][0][109] = 127, -+ [2][1][RTW89_CHILE][1][109] = 127, -+ [2][1][RTW89_QATAR][1][109] = 127, -+ [2][1][RTW89_QATAR][0][109] = 127, -+ [2][1][RTW89_UK][1][109] = 127, -+ [2][1][RTW89_UK][0][109] = 127, -+ [2][1][RTW89_FCC][1][111] = 127, -+ [2][1][RTW89_FCC][2][111] = 127, -+ [2][1][RTW89_ETSI][1][111] = 127, -+ [2][1][RTW89_ETSI][0][111] = 127, -+ [2][1][RTW89_MKK][1][111] = 127, -+ [2][1][RTW89_MKK][0][111] = 127, -+ [2][1][RTW89_IC][1][111] = 127, -+ [2][1][RTW89_KCC][1][111] = 127, -+ [2][1][RTW89_KCC][0][111] = 127, -+ [2][1][RTW89_ACMA][1][111] = 127, -+ [2][1][RTW89_ACMA][0][111] = 127, -+ [2][1][RTW89_CHILE][1][111] = 127, -+ [2][1][RTW89_QATAR][1][111] = 127, -+ [2][1][RTW89_QATAR][0][111] = 127, -+ [2][1][RTW89_UK][1][111] = 127, -+ [2][1][RTW89_UK][0][111] = 127, -+ [2][1][RTW89_FCC][1][113] = 127, -+ [2][1][RTW89_FCC][2][113] = 127, -+ [2][1][RTW89_ETSI][1][113] = 127, -+ [2][1][RTW89_ETSI][0][113] = 127, -+ [2][1][RTW89_MKK][1][113] = 127, -+ [2][1][RTW89_MKK][0][113] = 127, -+ [2][1][RTW89_IC][1][113] = 127, -+ [2][1][RTW89_KCC][1][113] = 127, -+ [2][1][RTW89_KCC][0][113] = 127, -+ [2][1][RTW89_ACMA][1][113] = 127, -+ [2][1][RTW89_ACMA][0][113] = 127, -+ [2][1][RTW89_CHILE][1][113] = 127, -+ [2][1][RTW89_QATAR][1][113] = 127, -+ [2][1][RTW89_QATAR][0][113] = 127, -+ [2][1][RTW89_UK][1][113] = 127, -+ [2][1][RTW89_UK][0][113] = 127, -+ [2][1][RTW89_FCC][1][115] = 127, -+ [2][1][RTW89_FCC][2][115] = 127, -+ [2][1][RTW89_ETSI][1][115] = 127, -+ [2][1][RTW89_ETSI][0][115] = 127, -+ [2][1][RTW89_MKK][1][115] = 127, -+ [2][1][RTW89_MKK][0][115] = 127, -+ [2][1][RTW89_IC][1][115] = 127, -+ [2][1][RTW89_KCC][1][115] = 127, -+ [2][1][RTW89_KCC][0][115] = 127, -+ [2][1][RTW89_ACMA][1][115] = 127, -+ [2][1][RTW89_ACMA][0][115] = 127, -+ [2][1][RTW89_CHILE][1][115] = 127, -+ [2][1][RTW89_QATAR][1][115] = 127, -+ [2][1][RTW89_QATAR][0][115] = 127, -+ [2][1][RTW89_UK][1][115] = 127, -+ [2][1][RTW89_UK][0][115] = 127, -+ [2][1][RTW89_FCC][1][117] = 127, -+ [2][1][RTW89_FCC][2][117] = 127, -+ [2][1][RTW89_ETSI][1][117] = 127, -+ [2][1][RTW89_ETSI][0][117] = 127, -+ [2][1][RTW89_MKK][1][117] = 127, -+ [2][1][RTW89_MKK][0][117] = 127, -+ [2][1][RTW89_IC][1][117] = 127, -+ [2][1][RTW89_KCC][1][117] = 127, -+ [2][1][RTW89_KCC][0][117] = 127, -+ [2][1][RTW89_ACMA][1][117] = 127, -+ [2][1][RTW89_ACMA][0][117] = 127, -+ [2][1][RTW89_CHILE][1][117] = 127, -+ [2][1][RTW89_QATAR][1][117] = 127, -+ [2][1][RTW89_QATAR][0][117] = 127, -+ [2][1][RTW89_UK][1][117] = 127, -+ [2][1][RTW89_UK][0][117] = 127, -+ [2][1][RTW89_FCC][1][119] = 127, -+ [2][1][RTW89_FCC][2][119] = 127, -+ [2][1][RTW89_ETSI][1][119] = 127, -+ [2][1][RTW89_ETSI][0][119] = 127, -+ [2][1][RTW89_MKK][1][119] = 127, -+ [2][1][RTW89_MKK][0][119] = 127, -+ [2][1][RTW89_IC][1][119] = 127, -+ [2][1][RTW89_KCC][1][119] = 127, -+ [2][1][RTW89_KCC][0][119] = 127, -+ [2][1][RTW89_ACMA][1][119] = 127, -+ [2][1][RTW89_ACMA][0][119] = 127, -+ [2][1][RTW89_CHILE][1][119] = 127, -+ [2][1][RTW89_QATAR][1][119] = 127, -+ [2][1][RTW89_QATAR][0][119] = 127, -+ [2][1][RTW89_UK][1][119] = 127, -+ [2][1][RTW89_UK][0][119] = 127, - }; - - const struct rtw89_phy_table rtw89_8852c_phy_bb_table = { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-133-wifi-rtw89-8852c-update-RF-radio-A-B-parameters-to-R.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-133-wifi-rtw89-8852c-update-RF-radio-A-B-parameters-to-R.patch deleted file mode 100644 index fe309522e..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-133-wifi-rtw89-8852c-update-RF-radio-A-B-parameters-to-R.patch +++ /dev/null @@ -1,7787 +0,0 @@ -From 5883fc2ef8573649ee6a63968ae82e679766b878 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 2 Jun 2023 23:05:56 +0800 -Subject: [PATCH 133/136] wifi: rtw89: 8852c: update RF radio A/B parameters to - R63 - -Update 8852c radio A/B parameters from internal HALRF_029_00_102 R63. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230602150556.36777-9-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8852c_table.c | 5138 +++++++++++++---- - 1 file changed, 4052 insertions(+), 1086 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -2551,19 +2551,27 @@ static const struct rtw89_reg2_def rtw89 - {0xF0040001, 0x0000000A}, - {0xF0050001, 0x0000000B}, - {0xF0070001, 0x0000000C}, -- {0xF0320001, 0x0000000D}, -- {0xF0330001, 0x0000000E}, -- {0xF0340001, 0x0000000F}, -- {0xF0350001, 0x00000010}, -- {0xF0360001, 0x00000011}, -- {0xF03F0001, 0x00000012}, -- {0xF0400001, 0x00000013}, -+ {0xF0150001, 0x0000000D}, -+ {0xF0160001, 0x0000000E}, -+ {0xF0320001, 0x0000000F}, -+ {0xF0330001, 0x00000010}, -+ {0xF0340001, 0x00000011}, -+ {0xF0350001, 0x00000012}, -+ {0xF0360001, 0x00000013}, -+ {0xF03F0001, 0x00000014}, -+ {0xF0400001, 0x00000015}, - {0x005, 0x00000000}, - {0x10005, 0x00000000}, - {0x000, 0x00030001}, - {0x10000, 0x00030000}, - {0x018, 0x00011124}, - {0x10018, 0x00011124}, -+ {0x0A3, 0x000B9204}, -+ {0x0AD, 0x00091E0F}, -+ {0x05D, 0x00001012}, -+ {0x05C, 0x00061C5C}, -+ {0x062, 0x00055220}, -+ {0x0D3, 0x00000103}, - {0x0EF, 0x00080000}, - {0x033, 0x00000001}, - {0x03E, 0x00000620}, -@@ -2636,6 +2644,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x067, 0x0000D300}, - {0x0DA, 0x000D4000}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x067, 0x0000D300}, -+ {0x0DA, 0x000D4000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x067, 0x0000D300}, -+ {0x0DA, 0x000D4000}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x067, 0x0000D300}, - {0x0DA, 0x000D4000}, -@@ -2716,6 +2730,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000CC}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000CC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000CC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000CC}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000CC}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2760,6 +2778,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000C4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000C4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000C4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000C4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000C4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2804,6 +2826,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000BC}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000BC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000BC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000BC}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000BC}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2848,6 +2874,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000B4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000B4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000B4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000B4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000B4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2892,6 +2922,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000AC}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000AC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000AC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000AC}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000AC}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2936,6 +2970,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -2980,6 +3018,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000009C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000009C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000009C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000009C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3024,6 +3066,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000094}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000094}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000094}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000094}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000094}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3068,6 +3114,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000008C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000008C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000008C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000008C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000008C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3112,6 +3162,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000084}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000084}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000084}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000084}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000084}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3156,6 +3210,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000BC}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000BC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000BC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000BC}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000BC}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3200,6 +3258,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000B4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000B4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000B4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000B4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000B4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3244,6 +3306,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000AC}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000AC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000AC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000AC}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000AC}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3288,6 +3354,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000000A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000000A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000000A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3332,6 +3402,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000009C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000009C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000009C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000009C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3376,6 +3450,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000094}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000094}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000094}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000094}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000094}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3420,6 +3498,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000008C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000008C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000008C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000008C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000008C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3464,6 +3546,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000084}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000084}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000084}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000084}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000084}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3508,6 +3594,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000003C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000003C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000003C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000003C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000003C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3552,6 +3642,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000034}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000034}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000034}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000034}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000034}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3596,6 +3690,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000002C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000002C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000002C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000002C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000002C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3640,6 +3738,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000024}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000024}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000024}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000024}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000024}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3684,6 +3786,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000001C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000001C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000001C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000001C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000001C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3728,6 +3834,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000014}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000014}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000014}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000014}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000014}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3772,6 +3882,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000000C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000000C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000000C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000000C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000000C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3816,6 +3930,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000004}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000004}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000004}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000004}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000004}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3873,6 +3991,10 @@ static const struct rtw89_reg2_def rtw89 - {0x08F, 0x000D1352}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x08F, 0x000D1352}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x08F, 0x000D1352}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x08F, 0x000D1352}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x08F, 0x000D1352}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -3936,6 +4058,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000007}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000007}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000007}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -4472,6 +4598,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000EFFF}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000EFFF}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000EFFF}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000EFFF}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000EFFF}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -4810,6 +4940,32 @@ static const struct rtw89_reg2_def rtw89 - {0x030, 0x00050112}, - {0x030, 0x00058101}, - {0x030, 0x00060001}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000085ED}, -+ {0x030, 0x000105CC}, -+ {0x030, 0x000184AA}, -+ {0x030, 0x00020388}, -+ {0x030, 0x00028377}, -+ {0x030, 0x00030377}, -+ {0x030, 0x00038255}, -+ {0x030, 0x00040244}, -+ {0x030, 0x00048133}, -+ {0x030, 0x00050112}, -+ {0x030, 0x00058101}, -+ {0x030, 0x00060001}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000085ED}, -+ {0x030, 0x000105CC}, -+ {0x030, 0x000184AA}, -+ {0x030, 0x00020388}, -+ {0x030, 0x00028377}, -+ {0x030, 0x00030377}, -+ {0x030, 0x00038255}, -+ {0x030, 0x00040244}, -+ {0x030, 0x00048133}, -+ {0x030, 0x00050112}, -+ {0x030, 0x00058101}, -+ {0x030, 0x00060001}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x000085ED}, - {0x030, 0x000105CC}, -@@ -5157,6 +5313,10 @@ static const struct rtw89_reg2_def rtw89 - {0x030, 0x000300FF}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x000300FF}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000300FF}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000300FF}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x000300FF}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5178,11 +5338,277 @@ static const struct rtw89_reg2_def rtw89 - {0x0EF, 0x00000000}, - {0x06E, 0x00077A18}, - {0x06D, 0x00000C31}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, - {0x06A, 0x000E0F8A}, - {0x06B, 0x000018A0}, - {0x06F, 0x000F81FC}, - {0x05E, 0x0000001F}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0380}, -+ {0x06B, 0x00003CA0}, -+ {0x06F, 0x000C01FC}, -+ {0x05E, 0x0000001F}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0380}, -+ {0x06B, 0x00003CA0}, -+ {0x06F, 0x000C01FC}, -+ {0x05E, 0x0000001F}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0xA0000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x05E, 0x0000001F}, -+ {0xB0000000, 0x00000000}, - {0x0EF, 0x00000200}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x0003D407}, - {0x030, 0x00035A87}, - {0x030, 0x0002CF07}, -@@ -5191,14 +5617,216 @@ static const struct rtw89_reg2_def rtw89 - {0x030, 0x00014F07}, - {0x030, 0x0000CF07}, - {0x030, 0x00004F07}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0xA0000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0xB0000000, 0x00000000}, - {0x0EF, 0x00000000}, - {0x0EB, 0x00080000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0000803C}, -+ {0x030, 0x0001003C}, -+ {0x030, 0x0001803C}, -+ {0x030, 0x0002003C}, -+ {0x030, 0x0002803C}, -+ {0x030, 0x0003003C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0000803C}, -+ {0x030, 0x0001003C}, -+ {0x030, 0x0001803C}, -+ {0x030, 0x0002003C}, -+ {0x030, 0x0002803C}, -+ {0x030, 0x0003003C}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0xA0000000, 0x00000000}, - {0x030, 0x00008038}, - {0x030, 0x00010038}, - {0x030, 0x00018038}, - {0x030, 0x00020038}, - {0x030, 0x00028038}, - {0x030, 0x00030038}, -+ {0xB0000000, 0x00000000}, - {0x030, 0x0003803C}, - {0x030, 0x0004003C}, - {0x030, 0x0004803C}, -@@ -5235,6 +5863,10 @@ static const struct rtw89_reg2_def rtw89 - {0x095, 0x00000008}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x095, 0x00000008}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x095, 0x00000008}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x095, 0x00000008}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x095, 0x00000008}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5280,6 +5912,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5324,6 +5960,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5368,6 +6008,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5412,6 +6056,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5456,6 +6104,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5500,6 +6152,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5548,6 +6204,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5592,6 +6252,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5636,6 +6300,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5680,6 +6348,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5724,6 +6396,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5768,6 +6444,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5812,6 +6492,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5856,6 +6540,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5900,6 +6588,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5944,6 +6636,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -5988,6 +6684,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6032,6 +6732,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6076,6 +6780,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6120,6 +6828,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6164,6 +6876,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6208,6 +6924,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -6252,20 +6972,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -6296,20 +7020,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -6340,20 +7068,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -6384,20 +7116,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -6428,20 +7164,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -6472,20 +7212,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -6516,20 +7260,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -6560,20 +7308,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -6604,20 +7356,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -6648,20 +7404,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -6692,20 +7452,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -6736,20 +7500,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -6780,20 +7548,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -6824,20 +7596,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -6868,20 +7644,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -6912,20 +7692,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -6956,20 +7740,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -7000,20 +7788,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -7044,20 +7836,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -7088,20 +7884,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -7132,20 +7932,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -7176,20 +7980,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -7220,20 +8028,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -7264,20 +8076,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -7308,20 +8124,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -7352,20 +8172,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -7396,20 +8220,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -7440,20 +8268,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -7484,20 +8316,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -7528,20 +8364,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -9436,7 +10276,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -9581,7 +10421,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -9600,60 +10440,60 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00003C5F}, - {0x10030, 0x00004059}, - {0x10030, 0x00004453}, -- {0x10030, 0x000201A7}, -- {0x10030, 0x000205A1}, -- {0x10030, 0x0002099B}, -- {0x10030, 0x00020D95}, -- {0x10030, 0x0002115B}, -- {0x10030, 0x00021555}, -- {0x10030, 0x00021921}, -- {0x10030, 0x00021D1B}, -- {0x10030, 0x000220E3}, -- {0x10030, 0x000224DD}, -+ {0x10030, 0x000201EF}, -+ {0x10030, 0x000205E9}, -+ {0x10030, 0x000209E3}, -+ {0x10030, 0x00020DA3}, -+ {0x10030, 0x00021161}, -+ {0x10030, 0x0002155B}, -+ {0x10030, 0x0002191F}, -+ {0x10030, 0x00021D19}, -+ {0x10030, 0x000220E1}, -+ {0x10030, 0x000224DB}, - {0x10030, 0x000228A3}, - {0x10030, 0x00022C9D}, - {0x10030, 0x00023063}, - {0x10030, 0x0002345D}, - {0x10030, 0x00023823}, -- {0x10030, 0x00023C1D}, -- {0x10030, 0x00024017}, -- {0x10030, 0x00024411}, -- {0x10030, 0x000281A9}, -- {0x10030, 0x000285A3}, -- {0x10030, 0x0002899D}, -- {0x10030, 0x00028D97}, -- {0x10030, 0x0002915D}, -- {0x10030, 0x00029557}, -- {0x10030, 0x0002991F}, -- {0x10030, 0x00029D19}, -- {0x10030, 0x0002A0E1}, -- {0x10030, 0x0002A4DB}, -+ {0x10030, 0x00023C1B}, -+ {0x10030, 0x00024015}, -+ {0x10030, 0x0002440F}, -+ {0x10030, 0x000281EF}, -+ {0x10030, 0x000285E7}, -+ {0x10030, 0x000289A7}, -+ {0x10030, 0x00028D65}, -+ {0x10030, 0x0002915F}, -+ {0x10030, 0x00029523}, -+ {0x10030, 0x0002991D}, -+ {0x10030, 0x00029CE5}, -+ {0x10030, 0x0002A0DF}, -+ {0x10030, 0x0002A4A7}, - {0x10030, 0x0002A8A1}, -- {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002AC67}, - {0x10030, 0x0002B061}, -- {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B427}, - {0x10030, 0x0002B821}, -- {0x10030, 0x0002BC1B}, -- {0x10030, 0x0002C015}, -- {0x10030, 0x0002C40F}, -- {0x10030, 0x000301A9}, -- {0x10030, 0x000305A3}, -- {0x10030, 0x0003099D}, -- {0x10030, 0x00030D97}, -- {0x10030, 0x0003115D}, -- {0x10030, 0x00031557}, -+ {0x10030, 0x0002BC19}, -+ {0x10030, 0x0002C013}, -+ {0x10030, 0x0002C40D}, -+ {0x10030, 0x000301EF}, -+ {0x10030, 0x000305E7}, -+ {0x10030, 0x000309A7}, -+ {0x10030, 0x00030D65}, -+ {0x10030, 0x0003115F}, -+ {0x10030, 0x00031525}, - {0x10030, 0x0003191F}, -- {0x10030, 0x00031D19}, -+ {0x10030, 0x00031CE7}, - {0x10030, 0x000320E1}, -- {0x10030, 0x000324DB}, -- {0x10030, 0x000328A1}, -- {0x10030, 0x00032C9B}, -- {0x10030, 0x00033061}, -- {0x10030, 0x0003345B}, -- {0x10030, 0x00033821}, -- {0x10030, 0x00033C1B}, -- {0x10030, 0x00034015}, -- {0x10030, 0x0003440F}, -+ {0x10030, 0x000324A9}, -+ {0x10030, 0x000328A3}, -+ {0x10030, 0x00032C69}, -+ {0x10030, 0x00033063}, -+ {0x10030, 0x00033429}, -+ {0x10030, 0x00033823}, -+ {0x10030, 0x00033C1D}, -+ {0x10030, 0x00034013}, -+ {0x10030, 0x0003440D}, - {0x10030, 0x000601F1}, - {0x10030, 0x000605E9}, - {0x10030, 0x000609A9}, -@@ -9697,7 +10537,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007115B}, - {0x10030, 0x00071523}, - {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -+ {0x10030, 0x00071D17}, - {0x10030, 0x000720DF}, - {0x10030, 0x000724D9}, - {0x10030, 0x000728A1}, -@@ -9726,7 +10566,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -9745,60 +10585,60 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00003C5F}, - {0x10030, 0x00004059}, - {0x10030, 0x00004453}, -- {0x10030, 0x000201A7}, -- {0x10030, 0x000205A1}, -- {0x10030, 0x0002099B}, -- {0x10030, 0x00020D95}, -- {0x10030, 0x0002115B}, -- {0x10030, 0x00021555}, -- {0x10030, 0x00021921}, -- {0x10030, 0x00021D1B}, -- {0x10030, 0x000220E3}, -- {0x10030, 0x000224DD}, -+ {0x10030, 0x000201EF}, -+ {0x10030, 0x000205E9}, -+ {0x10030, 0x000209E3}, -+ {0x10030, 0x00020DA3}, -+ {0x10030, 0x00021161}, -+ {0x10030, 0x0002155B}, -+ {0x10030, 0x0002191F}, -+ {0x10030, 0x00021D19}, -+ {0x10030, 0x000220E1}, -+ {0x10030, 0x000224DB}, - {0x10030, 0x000228A3}, - {0x10030, 0x00022C9D}, - {0x10030, 0x00023063}, - {0x10030, 0x0002345D}, - {0x10030, 0x00023823}, -- {0x10030, 0x00023C1D}, -- {0x10030, 0x00024017}, -- {0x10030, 0x00024411}, -- {0x10030, 0x000281A9}, -- {0x10030, 0x000285A3}, -- {0x10030, 0x0002899D}, -- {0x10030, 0x00028D97}, -- {0x10030, 0x0002915D}, -- {0x10030, 0x00029557}, -- {0x10030, 0x0002991F}, -- {0x10030, 0x00029D19}, -- {0x10030, 0x0002A0E1}, -- {0x10030, 0x0002A4DB}, -+ {0x10030, 0x00023C1B}, -+ {0x10030, 0x00024015}, -+ {0x10030, 0x0002440F}, -+ {0x10030, 0x000281EF}, -+ {0x10030, 0x000285E7}, -+ {0x10030, 0x000289A7}, -+ {0x10030, 0x00028D65}, -+ {0x10030, 0x0002915F}, -+ {0x10030, 0x00029523}, -+ {0x10030, 0x0002991D}, -+ {0x10030, 0x00029CE5}, -+ {0x10030, 0x0002A0DF}, -+ {0x10030, 0x0002A4A7}, - {0x10030, 0x0002A8A1}, -- {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002AC67}, - {0x10030, 0x0002B061}, -- {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B427}, - {0x10030, 0x0002B821}, -- {0x10030, 0x0002BC1B}, -- {0x10030, 0x0002C015}, -- {0x10030, 0x0002C40F}, -- {0x10030, 0x000301A9}, -- {0x10030, 0x000305A3}, -- {0x10030, 0x0003099D}, -- {0x10030, 0x00030D97}, -- {0x10030, 0x0003115D}, -- {0x10030, 0x00031557}, -+ {0x10030, 0x0002BC19}, -+ {0x10030, 0x0002C013}, -+ {0x10030, 0x0002C40D}, -+ {0x10030, 0x000301EF}, -+ {0x10030, 0x000305E7}, -+ {0x10030, 0x000309A7}, -+ {0x10030, 0x00030D65}, -+ {0x10030, 0x0003115F}, -+ {0x10030, 0x00031525}, - {0x10030, 0x0003191F}, -- {0x10030, 0x00031D19}, -+ {0x10030, 0x00031CE7}, - {0x10030, 0x000320E1}, -- {0x10030, 0x000324DB}, -- {0x10030, 0x000328A1}, -- {0x10030, 0x00032C9B}, -- {0x10030, 0x00033061}, -- {0x10030, 0x0003345B}, -- {0x10030, 0x00033821}, -- {0x10030, 0x00033C1B}, -- {0x10030, 0x00034015}, -- {0x10030, 0x0003440F}, -+ {0x10030, 0x000324A9}, -+ {0x10030, 0x000328A3}, -+ {0x10030, 0x00032C69}, -+ {0x10030, 0x00033063}, -+ {0x10030, 0x00033429}, -+ {0x10030, 0x00033823}, -+ {0x10030, 0x00033C1D}, -+ {0x10030, 0x00034013}, -+ {0x10030, 0x0003440D}, - {0x10030, 0x000601F1}, - {0x10030, 0x000605E9}, - {0x10030, 0x000609A9}, -@@ -9842,7 +10682,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007115B}, - {0x10030, 0x00071523}, - {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -+ {0x10030, 0x00071D17}, - {0x10030, 0x000720DF}, - {0x10030, 0x000724D9}, - {0x10030, 0x000728A1}, -@@ -9871,6 +10711,296 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000001EF}, -+ {0x10030, 0x000005E9}, -+ {0x10030, 0x000009E3}, -+ {0x10030, 0x00000DDD}, -+ {0x10030, 0x000011D7}, -+ {0x10030, 0x0000159F}, -+ {0x10030, 0x00001999}, -+ {0x10030, 0x00001D5F}, -+ {0x10030, 0x00002159}, -+ {0x10030, 0x0000251F}, -+ {0x10030, 0x00002919}, -+ {0x10030, 0x00002CDF}, -+ {0x10030, 0x000030D9}, -+ {0x10030, 0x0000349F}, -+ {0x10030, 0x00003899}, -+ {0x10030, 0x00003C5F}, -+ {0x10030, 0x00004059}, -+ {0x10030, 0x00004453}, -+ {0x10030, 0x000201A7}, -+ {0x10030, 0x000205A1}, -+ {0x10030, 0x0002099B}, -+ {0x10030, 0x00020D95}, -+ {0x10030, 0x0002115B}, -+ {0x10030, 0x00021555}, -+ {0x10030, 0x00021921}, -+ {0x10030, 0x00021D1B}, -+ {0x10030, 0x000220E3}, -+ {0x10030, 0x000224DD}, -+ {0x10030, 0x000228A3}, -+ {0x10030, 0x00022C9D}, -+ {0x10030, 0x00023063}, -+ {0x10030, 0x0002345D}, -+ {0x10030, 0x00023823}, -+ {0x10030, 0x00023C1D}, -+ {0x10030, 0x00024017}, -+ {0x10030, 0x00024411}, -+ {0x10030, 0x000281A9}, -+ {0x10030, 0x000285A3}, -+ {0x10030, 0x0002899D}, -+ {0x10030, 0x00028D97}, -+ {0x10030, 0x0002915D}, -+ {0x10030, 0x00029557}, -+ {0x10030, 0x0002991F}, -+ {0x10030, 0x00029D19}, -+ {0x10030, 0x0002A0E1}, -+ {0x10030, 0x0002A4DB}, -+ {0x10030, 0x0002A8A1}, -+ {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002B061}, -+ {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B821}, -+ {0x10030, 0x0002BC1B}, -+ {0x10030, 0x0002C015}, -+ {0x10030, 0x0002C40F}, -+ {0x10030, 0x000301A9}, -+ {0x10030, 0x000305A3}, -+ {0x10030, 0x0003099D}, -+ {0x10030, 0x00030D97}, -+ {0x10030, 0x0003115D}, -+ {0x10030, 0x00031557}, -+ {0x10030, 0x0003191F}, -+ {0x10030, 0x00031D19}, -+ {0x10030, 0x000320E1}, -+ {0x10030, 0x000324DB}, -+ {0x10030, 0x000328A1}, -+ {0x10030, 0x00032C9B}, -+ {0x10030, 0x00033061}, -+ {0x10030, 0x0003345B}, -+ {0x10030, 0x00033821}, -+ {0x10030, 0x00033C1B}, -+ {0x10030, 0x00034015}, -+ {0x10030, 0x0003440F}, -+ {0x10030, 0x000601F1}, -+ {0x10030, 0x000605E9}, -+ {0x10030, 0x000609A9}, -+ {0x10030, 0x00060D65}, -+ {0x10030, 0x0006115F}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, -+ {0x10030, 0x000681EF}, -+ {0x10030, 0x000685E7}, -+ {0x10030, 0x000689A7}, -+ {0x10030, 0x00068D61}, -+ {0x10030, 0x0006915B}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, -+ {0x10030, 0x0006B429}, -+ {0x10030, 0x0006B823}, -+ {0x10030, 0x0006BC1D}, -+ {0x10030, 0x0006C017}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000001EF}, -+ {0x10030, 0x000005E9}, -+ {0x10030, 0x000009E3}, -+ {0x10030, 0x00000DDD}, -+ {0x10030, 0x000011D7}, -+ {0x10030, 0x0000159F}, -+ {0x10030, 0x00001999}, -+ {0x10030, 0x00001D5F}, -+ {0x10030, 0x00002159}, -+ {0x10030, 0x0000251F}, -+ {0x10030, 0x00002919}, -+ {0x10030, 0x00002CDF}, -+ {0x10030, 0x000030D9}, -+ {0x10030, 0x0000349F}, -+ {0x10030, 0x00003899}, -+ {0x10030, 0x00003C5F}, -+ {0x10030, 0x00004059}, -+ {0x10030, 0x00004453}, -+ {0x10030, 0x000201A7}, -+ {0x10030, 0x000205A1}, -+ {0x10030, 0x0002099B}, -+ {0x10030, 0x00020D95}, -+ {0x10030, 0x0002115B}, -+ {0x10030, 0x00021555}, -+ {0x10030, 0x00021921}, -+ {0x10030, 0x00021D1B}, -+ {0x10030, 0x000220E3}, -+ {0x10030, 0x000224DD}, -+ {0x10030, 0x000228A3}, -+ {0x10030, 0x00022C9D}, -+ {0x10030, 0x00023063}, -+ {0x10030, 0x0002345D}, -+ {0x10030, 0x00023823}, -+ {0x10030, 0x00023C1D}, -+ {0x10030, 0x00024017}, -+ {0x10030, 0x00024411}, -+ {0x10030, 0x000281A9}, -+ {0x10030, 0x000285A3}, -+ {0x10030, 0x0002899D}, -+ {0x10030, 0x00028D97}, -+ {0x10030, 0x0002915D}, -+ {0x10030, 0x00029557}, -+ {0x10030, 0x0002991F}, -+ {0x10030, 0x00029D19}, -+ {0x10030, 0x0002A0E1}, -+ {0x10030, 0x0002A4DB}, -+ {0x10030, 0x0002A8A1}, -+ {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002B061}, -+ {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B821}, -+ {0x10030, 0x0002BC1B}, -+ {0x10030, 0x0002C015}, -+ {0x10030, 0x0002C40F}, -+ {0x10030, 0x000301A9}, -+ {0x10030, 0x000305A3}, -+ {0x10030, 0x0003099D}, -+ {0x10030, 0x00030D97}, -+ {0x10030, 0x0003115D}, -+ {0x10030, 0x00031557}, -+ {0x10030, 0x0003191F}, -+ {0x10030, 0x00031D19}, -+ {0x10030, 0x000320E1}, -+ {0x10030, 0x000324DB}, -+ {0x10030, 0x000328A1}, -+ {0x10030, 0x00032C9B}, -+ {0x10030, 0x00033061}, -+ {0x10030, 0x0003345B}, -+ {0x10030, 0x00033821}, -+ {0x10030, 0x00033C1B}, -+ {0x10030, 0x00034015}, -+ {0x10030, 0x0003440F}, -+ {0x10030, 0x000601F1}, -+ {0x10030, 0x000605E9}, -+ {0x10030, 0x000609A9}, -+ {0x10030, 0x00060D65}, -+ {0x10030, 0x0006115F}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, -+ {0x10030, 0x000681EF}, -+ {0x10030, 0x000685E7}, -+ {0x10030, 0x000689A7}, -+ {0x10030, 0x00068D61}, -+ {0x10030, 0x0006915B}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, -+ {0x10030, 0x0006B429}, -+ {0x10030, 0x0006B823}, -+ {0x10030, 0x0006BC1D}, -+ {0x10030, 0x0006C017}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -9949,73 +11079,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -+ {0x10030, 0x0006C411}, - {0x10030, 0x000701EF}, -- {0x10030, 0x000705E7}, -- {0x10030, 0x000709A7}, -- {0x10030, 0x00070D61}, -- {0x10030, 0x0007115B}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728A1}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, - {0x10030, 0x000781EF}, - {0x10030, 0x000785E9}, - {0x10030, 0x000789E3}, - {0x10030, 0x00078DA1}, - {0x10030, 0x0007915F}, - {0x10030, 0x00079559}, -- {0x10030, 0x00079921}, -- {0x10030, 0x00079D1B}, -- {0x10030, 0x0007A0E3}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B823}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -10094,73 +11224,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -+ {0x10030, 0x0006C411}, - {0x10030, 0x000701EF}, -- {0x10030, 0x000705E7}, -- {0x10030, 0x000709A7}, -- {0x10030, 0x00070D61}, -- {0x10030, 0x0007115B}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728A1}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, - {0x10030, 0x000781EF}, - {0x10030, 0x000785E9}, - {0x10030, 0x000789E3}, - {0x10030, 0x00078DA1}, - {0x10030, 0x0007915F}, - {0x10030, 0x00079559}, -- {0x10030, 0x00079921}, -- {0x10030, 0x00079D1B}, -- {0x10030, 0x0007A0E3}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B823}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -10239,73 +11369,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -+ {0x10030, 0x0006C411}, - {0x10030, 0x000701EF}, -- {0x10030, 0x000705E7}, -- {0x10030, 0x000709A7}, -- {0x10030, 0x00070D61}, -- {0x10030, 0x0007115B}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728A1}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, - {0x10030, 0x000781EF}, - {0x10030, 0x000785E9}, - {0x10030, 0x000789E3}, - {0x10030, 0x00078DA1}, - {0x10030, 0x0007915F}, - {0x10030, 0x00079559}, -- {0x10030, 0x00079921}, -- {0x10030, 0x00079D1B}, -- {0x10030, 0x0007A0E3}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B823}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -10384,73 +11514,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -+ {0x10030, 0x0006C411}, - {0x10030, 0x000701EF}, -- {0x10030, 0x000705E7}, -- {0x10030, 0x000709A7}, -- {0x10030, 0x00070D61}, -- {0x10030, 0x0007115B}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071CE5}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728A1}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, - {0x10030, 0x000781EF}, - {0x10030, 0x000785E9}, - {0x10030, 0x000789E3}, - {0x10030, 0x00078DA1}, - {0x10030, 0x0007915F}, - {0x10030, 0x00079559}, -- {0x10030, 0x00079921}, -- {0x10030, 0x00079D1B}, -- {0x10030, 0x0007A0E3}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B823}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0xA0000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -11294,6 +12424,110 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000338CC}, - {0x10030, 0x00033C09}, - {0x10030, 0x00034006}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000200E8}, -+ {0x10030, 0x000204E5}, -+ {0x10030, 0x000208E2}, -+ {0x10030, 0x00020CDF}, -+ {0x10030, 0x000210DC}, -+ {0x10030, 0x000214D9}, -+ {0x10030, 0x000218D6}, -+ {0x10030, 0x00021CD3}, -+ {0x10030, 0x000220D0}, -+ {0x10030, 0x0002240D}, -+ {0x10030, 0x0002280A}, -+ {0x10030, 0x00022C07}, -+ {0x10030, 0x00023004}, -+ {0x10030, 0x00023401}, -+ {0x10030, 0x00023800}, -+ {0x10030, 0x00023C00}, -+ {0x10030, 0x00024000}, -+ {0x10030, 0x000280ED}, -+ {0x10030, 0x000284EA}, -+ {0x10030, 0x000288E7}, -+ {0x10030, 0x00028CE4}, -+ {0x10030, 0x000290E1}, -+ {0x10030, 0x000294DE}, -+ {0x10030, 0x000298DB}, -+ {0x10030, 0x00029CD8}, -+ {0x10030, 0x0002A0D5}, -+ {0x10030, 0x0002A4D2}, -+ {0x10030, 0x0002A8CF}, -+ {0x10030, 0x0002AC0C}, -+ {0x10030, 0x0002B009}, -+ {0x10030, 0x0002B406}, -+ {0x10030, 0x0002B803}, -+ {0x10030, 0x0002BC00}, -+ {0x10030, 0x0002C000}, -+ {0x10030, 0x000300EE}, -+ {0x10030, 0x000304EB}, -+ {0x10030, 0x000308E8}, -+ {0x10030, 0x00030CE5}, -+ {0x10030, 0x000310E2}, -+ {0x10030, 0x000314DF}, -+ {0x10030, 0x000318DC}, -+ {0x10030, 0x00031CD9}, -+ {0x10030, 0x000320D6}, -+ {0x10030, 0x000324D3}, -+ {0x10030, 0x000328D0}, -+ {0x10030, 0x00032CCD}, -+ {0x10030, 0x0003300A}, -+ {0x10030, 0x00033407}, -+ {0x10030, 0x00033804}, -+ {0x10030, 0x00033C01}, -+ {0x10030, 0x00034000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000200E8}, -+ {0x10030, 0x000204E5}, -+ {0x10030, 0x000208E2}, -+ {0x10030, 0x00020CDF}, -+ {0x10030, 0x000210DC}, -+ {0x10030, 0x000214D9}, -+ {0x10030, 0x000218D6}, -+ {0x10030, 0x00021CD3}, -+ {0x10030, 0x000220D0}, -+ {0x10030, 0x0002240D}, -+ {0x10030, 0x0002280A}, -+ {0x10030, 0x00022C07}, -+ {0x10030, 0x00023004}, -+ {0x10030, 0x00023401}, -+ {0x10030, 0x00023800}, -+ {0x10030, 0x00023C00}, -+ {0x10030, 0x00024000}, -+ {0x10030, 0x000280ED}, -+ {0x10030, 0x000284EA}, -+ {0x10030, 0x000288E7}, -+ {0x10030, 0x00028CE4}, -+ {0x10030, 0x000290E1}, -+ {0x10030, 0x000294DE}, -+ {0x10030, 0x000298DB}, -+ {0x10030, 0x00029CD8}, -+ {0x10030, 0x0002A0D5}, -+ {0x10030, 0x0002A4D2}, -+ {0x10030, 0x0002A8CF}, -+ {0x10030, 0x0002AC0C}, -+ {0x10030, 0x0002B009}, -+ {0x10030, 0x0002B406}, -+ {0x10030, 0x0002B803}, -+ {0x10030, 0x0002BC00}, -+ {0x10030, 0x0002C000}, -+ {0x10030, 0x000300EE}, -+ {0x10030, 0x000304EB}, -+ {0x10030, 0x000308E8}, -+ {0x10030, 0x00030CE5}, -+ {0x10030, 0x000310E2}, -+ {0x10030, 0x000314DF}, -+ {0x10030, 0x000318DC}, -+ {0x10030, 0x00031CD9}, -+ {0x10030, 0x000320D6}, -+ {0x10030, 0x000324D3}, -+ {0x10030, 0x000328D0}, -+ {0x10030, 0x00032CCD}, -+ {0x10030, 0x0003300A}, -+ {0x10030, 0x00033407}, -+ {0x10030, 0x00033804}, -+ {0x10030, 0x00033C01}, -+ {0x10030, 0x00034000}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000200FA}, - {0x10030, 0x000204F7}, -@@ -11841,6 +13075,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -11885,6 +13123,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -11941,6 +13183,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -11985,6 +13231,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12041,6 +13291,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12085,6 +13339,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12141,6 +13399,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12185,6 +13447,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12241,6 +13507,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12285,6 +13555,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12305,7 +13579,53 @@ static const struct rtw89_reg2_def rtw89 - {0x033, 0x00000070}, - {0x03F, 0x00050002}, - {0x033, 0x00000071}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00060032}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0xB0000000, 0x00000000}, - {0x033, 0x00000072}, - {0x03F, 0x00050042}, - {0x033, 0x00000073}, -@@ -12341,6 +13661,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12385,6 +13709,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12405,7 +13733,53 @@ static const struct rtw89_reg2_def rtw89 - {0x033, 0x00000078}, - {0x03F, 0x00050002}, - {0x033, 0x00000079}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00060032}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0xA0000000, 0x00000000}, -+ {0x03F, 0x00060032}, -+ {0xB0000000, 0x00000000}, - {0x033, 0x0000007A}, - {0x03F, 0x00050042}, - {0x033, 0x0000007B}, -@@ -12441,6 +13815,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12485,6 +13863,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12541,6 +13923,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12585,6 +13971,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12641,6 +14031,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12685,6 +14079,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12741,6 +14139,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12785,6 +14187,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12841,6 +14247,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12885,6 +14295,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12941,6 +14355,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -12985,6 +14403,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13041,6 +14463,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13085,6 +14511,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13141,6 +14571,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13185,6 +14619,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13241,6 +14679,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13285,6 +14727,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13341,6 +14787,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13385,6 +14835,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13441,6 +14895,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13485,6 +14943,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13541,6 +15003,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13585,6 +15051,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13641,6 +15111,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13685,6 +15159,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13741,6 +15219,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13785,6 +15267,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13841,6 +15327,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13885,6 +15375,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13941,6 +15435,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -13985,6 +15483,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14041,6 +15543,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14085,6 +15591,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14141,6 +15651,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14185,6 +15699,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14241,6 +15759,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14285,6 +15807,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14341,6 +15867,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14385,6 +15915,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14441,6 +15975,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14485,6 +16023,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14541,6 +16083,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14585,6 +16131,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14669,6 +16219,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00025003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00025003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00025003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00025003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00025003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14719,6 +16273,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0002D003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0002D003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0002D003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0002D003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0002D003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14769,6 +16327,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00035003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00035003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00035003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00035003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00035003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14819,6 +16381,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0003D003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0003D003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0003D003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0003D003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0003D003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -14882,6 +16448,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00065003}, - {0x10030, 0x00066003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00065003}, -+ {0x10030, 0x00066003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00065003}, -+ {0x10030, 0x00066003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00065003}, - {0x10030, 0x00066003}, -@@ -14952,6 +16524,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0006D003}, - {0x10030, 0x0006E003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0006D003}, -+ {0x10030, 0x0006E003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0006D003}, -+ {0x10030, 0x0006E003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0006D003}, - {0x10030, 0x0006E003}, -@@ -15022,6 +16600,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00075003}, - {0x10030, 0x00076003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00075003}, -+ {0x10030, 0x00076003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00075003}, -+ {0x10030, 0x00076003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00075003}, - {0x10030, 0x00076003}, -@@ -15092,6 +16676,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0007D003}, - {0x10030, 0x0007E003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0007D003}, -+ {0x10030, 0x0007E003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0007D003}, -+ {0x10030, 0x0007E003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0007D003}, - {0x10030, 0x0007E003}, -@@ -15119,7 +16709,7 @@ static const struct rtw89_reg2_def rtw89 - {0xB0000000, 0x00000000}, - {0x10030, 0x0007F003}, - {0x100EE, 0x00000000}, -- {0x0FE, 0x00000048}, -+ {0x0FE, 0x00000063}, - }; - - static const struct rtw89_reg2_def rtw89_8852c_phy_radiob_regs[] = { -@@ -15136,13 +16726,15 @@ static const struct rtw89_reg2_def rtw89 - {0xF0040001, 0x0000000A}, - {0xF0050001, 0x0000000B}, - {0xF0070001, 0x0000000C}, -- {0xF0320001, 0x0000000D}, -- {0xF0330001, 0x0000000E}, -- {0xF0340001, 0x0000000F}, -- {0xF0350001, 0x00000010}, -- {0xF0360001, 0x00000011}, -- {0xF03F0001, 0x00000012}, -- {0xF0400001, 0x00000013}, -+ {0xF0150001, 0x0000000D}, -+ {0xF0160001, 0x0000000E}, -+ {0xF0320001, 0x0000000F}, -+ {0xF0330001, 0x00000010}, -+ {0xF0340001, 0x00000011}, -+ {0xF0350001, 0x00000012}, -+ {0xF0360001, 0x00000013}, -+ {0xF03F0001, 0x00000014}, -+ {0xF0400001, 0x00000015}, - {0x005, 0x00000000}, - {0x10005, 0x00000000}, - {0x0B9, 0x00020440}, -@@ -15150,6 +16742,12 @@ static const struct rtw89_reg2_def rtw89 - {0x10000, 0x00030000}, - {0x018, 0x00011124}, - {0x10018, 0x00011124}, -+ {0x0A3, 0x000B9204}, -+ {0x0AD, 0x00091E0F}, -+ {0x05D, 0x00001012}, -+ {0x05C, 0x00079C5C}, -+ {0x062, 0x00055220}, -+ {0x0D3, 0x00000103}, - {0x05F, 0x00000038}, - {0x097, 0x00043200}, - {0x0A6, 0x00066DB7}, -@@ -15253,6 +16851,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x067, 0x0000D300}, - {0x0DA, 0x000D4000}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x067, 0x0000D300}, -+ {0x0DA, 0x000D4000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x067, 0x0000D300}, -+ {0x0DA, 0x000D4000}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x067, 0x0000D300}, - {0x0DA, 0x000D4000}, -@@ -15319,6 +16923,10 @@ static const struct rtw89_reg2_def rtw89 - {0x08F, 0x000D1352}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x08F, 0x000D1352}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x08F, 0x000D1352}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x08F, 0x000D1352}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x08F, 0x000D1352}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -15382,6 +16990,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000007}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000007}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000017}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000007}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -15918,6 +17530,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000EFFF}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000EFFF}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000EFFF}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000EFFF}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000EFFF}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16256,6 +17872,32 @@ static const struct rtw89_reg2_def rtw89 - {0x030, 0x00050112}, - {0x030, 0x00058101}, - {0x030, 0x00060001}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000085ED}, -+ {0x030, 0x000105CC}, -+ {0x030, 0x000184AA}, -+ {0x030, 0x00020388}, -+ {0x030, 0x00028377}, -+ {0x030, 0x00030377}, -+ {0x030, 0x00038255}, -+ {0x030, 0x00040244}, -+ {0x030, 0x00048133}, -+ {0x030, 0x00050112}, -+ {0x030, 0x00058101}, -+ {0x030, 0x00060001}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x000085ED}, -+ {0x030, 0x000105CC}, -+ {0x030, 0x000184AA}, -+ {0x030, 0x00020388}, -+ {0x030, 0x00028377}, -+ {0x030, 0x00030377}, -+ {0x030, 0x00038255}, -+ {0x030, 0x00040244}, -+ {0x030, 0x00048133}, -+ {0x030, 0x00050112}, -+ {0x030, 0x00058101}, -+ {0x030, 0x00060001}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x000085ED}, - {0x030, 0x000105CC}, -@@ -16582,11 +18224,264 @@ static const struct rtw89_reg2_def rtw89 - {0x0EF, 0x00000000}, - {0x06E, 0x00077A18}, - {0x06D, 0x00000C31}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, - {0x06A, 0x000E0F8A}, - {0x06B, 0x000018A0}, - {0x06F, 0x000F81FC}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0380}, -+ {0x06B, 0x00003CA0}, -+ {0x06F, 0x000C01FC}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0380}, -+ {0x06B, 0x00003CA0}, -+ {0x06F, 0x000C01FC}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0xA0000000, 0x00000000}, -+ {0x06A, 0x000E0F8A}, -+ {0x06B, 0x000018A0}, -+ {0x06F, 0x000F81FC}, -+ {0xB0000000, 0x00000000}, - {0x05E, 0x0000001F}, - {0x0EF, 0x00000200}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x030, 0x0003E207}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, - {0x030, 0x0003D407}, - {0x030, 0x00035A87}, - {0x030, 0x0002CF07}, -@@ -16595,14 +18490,207 @@ static const struct rtw89_reg2_def rtw89 - {0x030, 0x00014F07}, - {0x030, 0x0000CF07}, - {0x030, 0x00004F07}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0xA0000000, 0x00000000}, -+ {0x030, 0x0003D407}, -+ {0x030, 0x00035A87}, -+ {0x030, 0x0002CF07}, -+ {0x030, 0x00024F07}, -+ {0x030, 0x0001CF07}, -+ {0x030, 0x00014F07}, -+ {0x030, 0x0000CF07}, -+ {0x030, 0x00004F07}, -+ {0xB0000000, 0x00000000}, - {0x0EF, 0x00000000}, - {0x0EB, 0x00080000}, -+ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90020000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90320000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90330000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90340000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90350000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90360000, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90040001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90050001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0000803C}, -+ {0x030, 0x0001003C}, -+ {0x030, 0x0001803C}, -+ {0x030, 0x0002003C}, -+ {0x030, 0x0002803C}, -+ {0x030, 0x0003003C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x0000803C}, -+ {0x030, 0x0001003C}, -+ {0x030, 0x0001803C}, -+ {0x030, 0x0002003C}, -+ {0x030, 0x0002803C}, -+ {0x030, 0x0003003C}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x030, 0x00008038}, -+ {0x030, 0x00010038}, -+ {0x030, 0x00018038}, -+ {0x030, 0x00020038}, -+ {0x030, 0x00028038}, -+ {0x030, 0x00030038}, -+ {0xA0000000, 0x00000000}, - {0x030, 0x00008038}, - {0x030, 0x00010038}, - {0x030, 0x00018038}, - {0x030, 0x00020038}, - {0x030, 0x00028038}, - {0x030, 0x00030038}, -+ {0xB0000000, 0x00000000}, - {0x030, 0x0003803C}, - {0x030, 0x0004003C}, - {0x030, 0x0004803C}, -@@ -16639,6 +18727,10 @@ static const struct rtw89_reg2_def rtw89 - {0x095, 0x00000008}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x095, 0x00000008}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x095, 0x00000008}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x095, 0x00000008}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x095, 0x00000008}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16684,6 +18776,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16728,6 +18824,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16772,6 +18872,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16816,6 +18920,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16860,6 +18968,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16904,6 +19016,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16948,6 +19064,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -16992,6 +19112,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17036,6 +19160,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17080,6 +19208,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17124,6 +19256,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17168,6 +19304,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17212,6 +19352,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17256,6 +19400,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17300,6 +19448,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17344,6 +19496,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17388,6 +19544,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17432,6 +19592,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17476,6 +19640,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17520,6 +19688,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17564,6 +19736,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17608,6 +19784,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17652,6 +19832,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17696,6 +19880,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -17740,20 +19928,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -17784,20 +19976,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -17828,20 +20024,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -17872,20 +20072,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -17916,20 +20120,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -17960,20 +20168,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -18004,20 +20216,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -18048,20 +20264,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -18092,20 +20312,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -18136,20 +20360,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -18180,20 +20408,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -18224,20 +20456,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -18268,20 +20504,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -18312,20 +20552,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -18356,20 +20600,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -18400,20 +20648,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -18444,20 +20696,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -18488,20 +20744,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -18532,20 +20792,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -18576,20 +20840,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -18620,20 +20888,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -18664,20 +20936,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -18708,20 +20984,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000002E6}, -+ {0x03F, 0x000002E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0xB0000000, 0x00000000}, -@@ -18752,20 +21032,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000003E7}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000003E7}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000003E7}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000003E6}, -+ {0x03F, 0x000003E7}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000003E6}, - {0xB0000000, 0x00000000}, -@@ -18796,20 +21080,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000152}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00000152}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000152}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x00000052}, -+ {0x03F, 0x00000152}, - {0xA0000000, 0x00000000}, - {0x03F, 0x00000052}, - {0xB0000000, 0x00000000}, -@@ -18840,20 +21128,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000015A}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000015A}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000015A}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000005A}, -+ {0x03F, 0x0000015A}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000005A}, - {0xB0000000, 0x00000000}, -@@ -18884,20 +21176,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000019C}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x0000019C}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000009C}, -+ {0x03F, 0x0000019C}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000009C}, - {0xB0000000, 0x00000000}, -@@ -18928,20 +21224,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001A4}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001A4}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x0000019C}, -+ {0x03F, 0x000001A4}, - {0xA0000000, 0x00000000}, - {0x03F, 0x0000019C}, - {0xB0000000, 0x00000000}, -@@ -18972,20 +21272,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000001E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000001E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001A4}, -+ {0x03F, 0x000001E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001A4}, - {0xB0000000, 0x00000000}, -@@ -19016,20 +21320,24 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x000002E6}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x000002E6}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x000002E6}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, -- {0x03F, 0x000001E6}, -+ {0x03F, 0x000002E6}, - {0xA0000000, 0x00000000}, - {0x03F, 0x000001E6}, - {0xB0000000, 0x00000000}, -@@ -20924,7 +23232,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -21069,7 +23377,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -21088,60 +23396,60 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00003C5F}, - {0x10030, 0x00004059}, - {0x10030, 0x00004453}, -- {0x10030, 0x000201A7}, -- {0x10030, 0x000205A1}, -- {0x10030, 0x0002099B}, -- {0x10030, 0x00020D95}, -- {0x10030, 0x0002115B}, -- {0x10030, 0x00021555}, -- {0x10030, 0x00021921}, -- {0x10030, 0x00021D1B}, -- {0x10030, 0x000220E3}, -- {0x10030, 0x000224DD}, -+ {0x10030, 0x000201EF}, -+ {0x10030, 0x000205E9}, -+ {0x10030, 0x000209E3}, -+ {0x10030, 0x00020DA3}, -+ {0x10030, 0x00021161}, -+ {0x10030, 0x0002155B}, -+ {0x10030, 0x0002191F}, -+ {0x10030, 0x00021D19}, -+ {0x10030, 0x000220E1}, -+ {0x10030, 0x000224DB}, - {0x10030, 0x000228A3}, - {0x10030, 0x00022C9D}, - {0x10030, 0x00023063}, - {0x10030, 0x0002345D}, - {0x10030, 0x00023823}, -- {0x10030, 0x00023C1D}, -- {0x10030, 0x00024017}, -- {0x10030, 0x00024411}, -- {0x10030, 0x000281A9}, -- {0x10030, 0x000285A3}, -- {0x10030, 0x0002899D}, -- {0x10030, 0x00028D97}, -- {0x10030, 0x0002915D}, -- {0x10030, 0x00029557}, -- {0x10030, 0x0002991F}, -- {0x10030, 0x00029D19}, -- {0x10030, 0x0002A0E1}, -- {0x10030, 0x0002A4DB}, -+ {0x10030, 0x00023C1B}, -+ {0x10030, 0x00024015}, -+ {0x10030, 0x0002440F}, -+ {0x10030, 0x000281EF}, -+ {0x10030, 0x000285E7}, -+ {0x10030, 0x000289A7}, -+ {0x10030, 0x00028D65}, -+ {0x10030, 0x0002915F}, -+ {0x10030, 0x00029523}, -+ {0x10030, 0x0002991D}, -+ {0x10030, 0x00029CE5}, -+ {0x10030, 0x0002A0DF}, -+ {0x10030, 0x0002A4A7}, - {0x10030, 0x0002A8A1}, -- {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002AC67}, - {0x10030, 0x0002B061}, -- {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B427}, - {0x10030, 0x0002B821}, -- {0x10030, 0x0002BC1B}, -- {0x10030, 0x0002C015}, -- {0x10030, 0x0002C40F}, -- {0x10030, 0x000301A9}, -- {0x10030, 0x000305A3}, -- {0x10030, 0x0003099D}, -- {0x10030, 0x00030D97}, -- {0x10030, 0x0003115D}, -- {0x10030, 0x00031557}, -+ {0x10030, 0x0002BC19}, -+ {0x10030, 0x0002C013}, -+ {0x10030, 0x0002C40D}, -+ {0x10030, 0x000301EF}, -+ {0x10030, 0x000305E7}, -+ {0x10030, 0x000309A7}, -+ {0x10030, 0x00030D65}, -+ {0x10030, 0x0003115F}, -+ {0x10030, 0x00031525}, - {0x10030, 0x0003191F}, -- {0x10030, 0x00031D19}, -+ {0x10030, 0x00031CE7}, - {0x10030, 0x000320E1}, -- {0x10030, 0x000324DB}, -- {0x10030, 0x000328A1}, -- {0x10030, 0x00032C9B}, -- {0x10030, 0x00033061}, -- {0x10030, 0x0003345B}, -- {0x10030, 0x00033821}, -- {0x10030, 0x00033C1B}, -- {0x10030, 0x00034015}, -- {0x10030, 0x0003440F}, -+ {0x10030, 0x000324A9}, -+ {0x10030, 0x000328A3}, -+ {0x10030, 0x00032C69}, -+ {0x10030, 0x00033063}, -+ {0x10030, 0x00033429}, -+ {0x10030, 0x00033823}, -+ {0x10030, 0x00033C1D}, -+ {0x10030, 0x00034013}, -+ {0x10030, 0x0003440D}, - {0x10030, 0x000601F1}, - {0x10030, 0x000605E9}, - {0x10030, 0x000609A9}, -@@ -21186,7 +23494,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00071523}, - {0x10030, 0x0007191D}, - {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -+ {0x10030, 0x00072111}, - {0x10030, 0x000724D9}, - {0x10030, 0x000728D3}, - {0x10030, 0x00072C67}, -@@ -21214,7 +23522,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -- {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, - {0x10030, 0x000009E3}, -@@ -21233,60 +23541,60 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00003C5F}, - {0x10030, 0x00004059}, - {0x10030, 0x00004453}, -- {0x10030, 0x000201A7}, -- {0x10030, 0x000205A1}, -- {0x10030, 0x0002099B}, -- {0x10030, 0x00020D95}, -- {0x10030, 0x0002115B}, -- {0x10030, 0x00021555}, -- {0x10030, 0x00021921}, -- {0x10030, 0x00021D1B}, -- {0x10030, 0x000220E3}, -- {0x10030, 0x000224DD}, -+ {0x10030, 0x000201EF}, -+ {0x10030, 0x000205E9}, -+ {0x10030, 0x000209E3}, -+ {0x10030, 0x00020DA3}, -+ {0x10030, 0x00021161}, -+ {0x10030, 0x0002155B}, -+ {0x10030, 0x0002191F}, -+ {0x10030, 0x00021D19}, -+ {0x10030, 0x000220E1}, -+ {0x10030, 0x000224DB}, - {0x10030, 0x000228A3}, - {0x10030, 0x00022C9D}, - {0x10030, 0x00023063}, - {0x10030, 0x0002345D}, - {0x10030, 0x00023823}, -- {0x10030, 0x00023C1D}, -- {0x10030, 0x00024017}, -- {0x10030, 0x00024411}, -- {0x10030, 0x000281A9}, -- {0x10030, 0x000285A3}, -- {0x10030, 0x0002899D}, -- {0x10030, 0x00028D97}, -- {0x10030, 0x0002915D}, -- {0x10030, 0x00029557}, -- {0x10030, 0x0002991F}, -- {0x10030, 0x00029D19}, -- {0x10030, 0x0002A0E1}, -- {0x10030, 0x0002A4DB}, -+ {0x10030, 0x00023C1B}, -+ {0x10030, 0x00024015}, -+ {0x10030, 0x0002440F}, -+ {0x10030, 0x000281EF}, -+ {0x10030, 0x000285E7}, -+ {0x10030, 0x000289A7}, -+ {0x10030, 0x00028D65}, -+ {0x10030, 0x0002915F}, -+ {0x10030, 0x00029523}, -+ {0x10030, 0x0002991D}, -+ {0x10030, 0x00029CE5}, -+ {0x10030, 0x0002A0DF}, -+ {0x10030, 0x0002A4A7}, - {0x10030, 0x0002A8A1}, -- {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002AC67}, - {0x10030, 0x0002B061}, -- {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B427}, - {0x10030, 0x0002B821}, -- {0x10030, 0x0002BC1B}, -- {0x10030, 0x0002C015}, -- {0x10030, 0x0002C40F}, -- {0x10030, 0x000301A9}, -- {0x10030, 0x000305A3}, -- {0x10030, 0x0003099D}, -- {0x10030, 0x00030D97}, -- {0x10030, 0x0003115D}, -- {0x10030, 0x00031557}, -+ {0x10030, 0x0002BC19}, -+ {0x10030, 0x0002C013}, -+ {0x10030, 0x0002C40D}, -+ {0x10030, 0x000301EF}, -+ {0x10030, 0x000305E7}, -+ {0x10030, 0x000309A7}, -+ {0x10030, 0x00030D65}, -+ {0x10030, 0x0003115F}, -+ {0x10030, 0x00031525}, - {0x10030, 0x0003191F}, -- {0x10030, 0x00031D19}, -+ {0x10030, 0x00031CE7}, - {0x10030, 0x000320E1}, -- {0x10030, 0x000324DB}, -- {0x10030, 0x000328A1}, -- {0x10030, 0x00032C9B}, -- {0x10030, 0x00033061}, -- {0x10030, 0x0003345B}, -- {0x10030, 0x00033821}, -- {0x10030, 0x00033C1B}, -- {0x10030, 0x00034015}, -- {0x10030, 0x0003440F}, -+ {0x10030, 0x000324A9}, -+ {0x10030, 0x000328A3}, -+ {0x10030, 0x00032C69}, -+ {0x10030, 0x00033063}, -+ {0x10030, 0x00033429}, -+ {0x10030, 0x00033823}, -+ {0x10030, 0x00033C1D}, -+ {0x10030, 0x00034013}, -+ {0x10030, 0x0003440D}, - {0x10030, 0x000601F1}, - {0x10030, 0x000605E9}, - {0x10030, 0x000609A9}, -@@ -21331,7 +23639,7 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00071523}, - {0x10030, 0x0007191D}, - {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -+ {0x10030, 0x00072111}, - {0x10030, 0x000724D9}, - {0x10030, 0x000728D3}, - {0x10030, 0x00072C67}, -@@ -21359,6 +23667,296 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0007BC1D}, - {0x10030, 0x0007C017}, - {0x10030, 0x0007C40F}, -+ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000001EF}, -+ {0x10030, 0x000005E9}, -+ {0x10030, 0x000009E3}, -+ {0x10030, 0x00000DDD}, -+ {0x10030, 0x000011D7}, -+ {0x10030, 0x0000159F}, -+ {0x10030, 0x00001999}, -+ {0x10030, 0x00001D5F}, -+ {0x10030, 0x00002159}, -+ {0x10030, 0x0000251F}, -+ {0x10030, 0x00002919}, -+ {0x10030, 0x00002CDF}, -+ {0x10030, 0x000030D9}, -+ {0x10030, 0x0000349F}, -+ {0x10030, 0x00003899}, -+ {0x10030, 0x00003C5F}, -+ {0x10030, 0x00004059}, -+ {0x10030, 0x00004453}, -+ {0x10030, 0x000201A7}, -+ {0x10030, 0x000205A1}, -+ {0x10030, 0x0002099B}, -+ {0x10030, 0x00020D95}, -+ {0x10030, 0x0002115B}, -+ {0x10030, 0x00021555}, -+ {0x10030, 0x00021921}, -+ {0x10030, 0x00021D1B}, -+ {0x10030, 0x000220E3}, -+ {0x10030, 0x000224DD}, -+ {0x10030, 0x000228A3}, -+ {0x10030, 0x00022C9D}, -+ {0x10030, 0x00023063}, -+ {0x10030, 0x0002345D}, -+ {0x10030, 0x00023823}, -+ {0x10030, 0x00023C1D}, -+ {0x10030, 0x00024017}, -+ {0x10030, 0x00024411}, -+ {0x10030, 0x000281A9}, -+ {0x10030, 0x000285A3}, -+ {0x10030, 0x0002899D}, -+ {0x10030, 0x00028D97}, -+ {0x10030, 0x0002915D}, -+ {0x10030, 0x00029557}, -+ {0x10030, 0x0002991F}, -+ {0x10030, 0x00029D19}, -+ {0x10030, 0x0002A0E1}, -+ {0x10030, 0x0002A4DB}, -+ {0x10030, 0x0002A8A1}, -+ {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002B061}, -+ {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B821}, -+ {0x10030, 0x0002BC1B}, -+ {0x10030, 0x0002C015}, -+ {0x10030, 0x0002C40F}, -+ {0x10030, 0x000301A9}, -+ {0x10030, 0x000305A3}, -+ {0x10030, 0x0003099D}, -+ {0x10030, 0x00030D97}, -+ {0x10030, 0x0003115D}, -+ {0x10030, 0x00031557}, -+ {0x10030, 0x0003191F}, -+ {0x10030, 0x00031D19}, -+ {0x10030, 0x000320E1}, -+ {0x10030, 0x000324DB}, -+ {0x10030, 0x000328A1}, -+ {0x10030, 0x00032C9B}, -+ {0x10030, 0x00033061}, -+ {0x10030, 0x0003345B}, -+ {0x10030, 0x00033821}, -+ {0x10030, 0x00033C1B}, -+ {0x10030, 0x00034015}, -+ {0x10030, 0x0003440F}, -+ {0x10030, 0x000601F1}, -+ {0x10030, 0x000605E9}, -+ {0x10030, 0x000609A9}, -+ {0x10030, 0x00060D65}, -+ {0x10030, 0x0006115F}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, -+ {0x10030, 0x000681EF}, -+ {0x10030, 0x000685E7}, -+ {0x10030, 0x000689A7}, -+ {0x10030, 0x00068D61}, -+ {0x10030, 0x0006915B}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, -+ {0x10030, 0x0006B429}, -+ {0x10030, 0x0006B823}, -+ {0x10030, 0x0006BC1D}, -+ {0x10030, 0x0006C017}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, -+ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000001EF}, -+ {0x10030, 0x000005E9}, -+ {0x10030, 0x000009E3}, -+ {0x10030, 0x00000DDD}, -+ {0x10030, 0x000011D7}, -+ {0x10030, 0x0000159F}, -+ {0x10030, 0x00001999}, -+ {0x10030, 0x00001D5F}, -+ {0x10030, 0x00002159}, -+ {0x10030, 0x0000251F}, -+ {0x10030, 0x00002919}, -+ {0x10030, 0x00002CDF}, -+ {0x10030, 0x000030D9}, -+ {0x10030, 0x0000349F}, -+ {0x10030, 0x00003899}, -+ {0x10030, 0x00003C5F}, -+ {0x10030, 0x00004059}, -+ {0x10030, 0x00004453}, -+ {0x10030, 0x000201A7}, -+ {0x10030, 0x000205A1}, -+ {0x10030, 0x0002099B}, -+ {0x10030, 0x00020D95}, -+ {0x10030, 0x0002115B}, -+ {0x10030, 0x00021555}, -+ {0x10030, 0x00021921}, -+ {0x10030, 0x00021D1B}, -+ {0x10030, 0x000220E3}, -+ {0x10030, 0x000224DD}, -+ {0x10030, 0x000228A3}, -+ {0x10030, 0x00022C9D}, -+ {0x10030, 0x00023063}, -+ {0x10030, 0x0002345D}, -+ {0x10030, 0x00023823}, -+ {0x10030, 0x00023C1D}, -+ {0x10030, 0x00024017}, -+ {0x10030, 0x00024411}, -+ {0x10030, 0x000281A9}, -+ {0x10030, 0x000285A3}, -+ {0x10030, 0x0002899D}, -+ {0x10030, 0x00028D97}, -+ {0x10030, 0x0002915D}, -+ {0x10030, 0x00029557}, -+ {0x10030, 0x0002991F}, -+ {0x10030, 0x00029D19}, -+ {0x10030, 0x0002A0E1}, -+ {0x10030, 0x0002A4DB}, -+ {0x10030, 0x0002A8A1}, -+ {0x10030, 0x0002AC9B}, -+ {0x10030, 0x0002B061}, -+ {0x10030, 0x0002B45B}, -+ {0x10030, 0x0002B821}, -+ {0x10030, 0x0002BC1B}, -+ {0x10030, 0x0002C015}, -+ {0x10030, 0x0002C40F}, -+ {0x10030, 0x000301A9}, -+ {0x10030, 0x000305A3}, -+ {0x10030, 0x0003099D}, -+ {0x10030, 0x00030D97}, -+ {0x10030, 0x0003115D}, -+ {0x10030, 0x00031557}, -+ {0x10030, 0x0003191F}, -+ {0x10030, 0x00031D19}, -+ {0x10030, 0x000320E1}, -+ {0x10030, 0x000324DB}, -+ {0x10030, 0x000328A1}, -+ {0x10030, 0x00032C9B}, -+ {0x10030, 0x00033061}, -+ {0x10030, 0x0003345B}, -+ {0x10030, 0x00033821}, -+ {0x10030, 0x00033C1B}, -+ {0x10030, 0x00034015}, -+ {0x10030, 0x0003440F}, -+ {0x10030, 0x000601F1}, -+ {0x10030, 0x000605E9}, -+ {0x10030, 0x000609A9}, -+ {0x10030, 0x00060D65}, -+ {0x10030, 0x0006115F}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, -+ {0x10030, 0x000681EF}, -+ {0x10030, 0x000685E7}, -+ {0x10030, 0x000689A7}, -+ {0x10030, 0x00068D61}, -+ {0x10030, 0x0006915B}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, -+ {0x10030, 0x0006B429}, -+ {0x10030, 0x0006B823}, -+ {0x10030, 0x0006BC1D}, -+ {0x10030, 0x0006C017}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, -+ {0x10030, 0x000705E9}, -+ {0x10030, 0x000709A9}, -+ {0x10030, 0x00070D63}, -+ {0x10030, 0x0007115D}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -21437,73 +24035,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -- {0x10030, 0x000701F1}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, - {0x10030, 0x000705E9}, - {0x10030, 0x000709A9}, - {0x10030, 0x00070D63}, - {0x10030, 0x0007115D}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728D3}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -- {0x10030, 0x000781F1}, -- {0x10030, 0x000785EB}, -- {0x10030, 0x000789E5}, -- {0x10030, 0x00078DA3}, -- {0x10030, 0x00079161}, -- {0x10030, 0x0007955B}, -- {0x10030, 0x00079923}, -- {0x10030, 0x00079D1D}, -- {0x10030, 0x0007A117}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B857}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -21582,73 +24180,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -- {0x10030, 0x000701F1}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, - {0x10030, 0x000705E9}, - {0x10030, 0x000709A9}, - {0x10030, 0x00070D63}, - {0x10030, 0x0007115D}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728D3}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -- {0x10030, 0x000781F1}, -- {0x10030, 0x000785EB}, -- {0x10030, 0x000789E5}, -- {0x10030, 0x00078DA3}, -- {0x10030, 0x00079161}, -- {0x10030, 0x0007955B}, -- {0x10030, 0x00079923}, -- {0x10030, 0x00079D1D}, -- {0x10030, 0x0007A117}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B857}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x903f0001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -21727,73 +24325,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -- {0x10030, 0x000701F1}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, - {0x10030, 0x000705E9}, - {0x10030, 0x000709A9}, - {0x10030, 0x00070D63}, - {0x10030, 0x0007115D}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728D3}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -- {0x10030, 0x000781F1}, -- {0x10030, 0x000785EB}, -- {0x10030, 0x000789E5}, -- {0x10030, 0x00078DA3}, -- {0x10030, 0x00079161}, -- {0x10030, 0x0007955B}, -- {0x10030, 0x00079923}, -- {0x10030, 0x00079D1D}, -- {0x10030, 0x0007A117}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B857}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0x90400001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -21872,73 +24470,73 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000609A9}, - {0x10030, 0x00060D65}, - {0x10030, 0x0006115F}, -- {0x10030, 0x00061525}, -- {0x10030, 0x0006191F}, -- {0x10030, 0x00061CE7}, -- {0x10030, 0x000620E1}, -- {0x10030, 0x000624DB}, -- {0x10030, 0x000628A3}, -- {0x10030, 0x00062C69}, -- {0x10030, 0x00063063}, -- {0x10030, 0x00063429}, -- {0x10030, 0x00063823}, -- {0x10030, 0x00063C1D}, -- {0x10030, 0x00064013}, -- {0x10030, 0x0006440D}, -+ {0x10030, 0x00061527}, -+ {0x10030, 0x00061921}, -+ {0x10030, 0x00061CE9}, -+ {0x10030, 0x000620E3}, -+ {0x10030, 0x000624DD}, -+ {0x10030, 0x000628A5}, -+ {0x10030, 0x00062C6B}, -+ {0x10030, 0x00063065}, -+ {0x10030, 0x0006342B}, -+ {0x10030, 0x00063825}, -+ {0x10030, 0x00063C1F}, -+ {0x10030, 0x00064019}, -+ {0x10030, 0x00064413}, - {0x10030, 0x000681EF}, - {0x10030, 0x000685E7}, - {0x10030, 0x000689A7}, - {0x10030, 0x00068D61}, - {0x10030, 0x0006915B}, -- {0x10030, 0x00069523}, -- {0x10030, 0x0006991D}, -- {0x10030, 0x00069CE5}, -- {0x10030, 0x0006A0DF}, -- {0x10030, 0x0006A4A7}, -- {0x10030, 0x0006A8A1}, -- {0x10030, 0x0006AC67}, -- {0x10030, 0x0006B061}, -+ {0x10030, 0x00069525}, -+ {0x10030, 0x0006991F}, -+ {0x10030, 0x00069CE7}, -+ {0x10030, 0x0006A0E1}, -+ {0x10030, 0x0006A4A9}, -+ {0x10030, 0x0006A8A3}, -+ {0x10030, 0x0006AC69}, -+ {0x10030, 0x0006B063}, - {0x10030, 0x0006B429}, - {0x10030, 0x0006B823}, - {0x10030, 0x0006BC1D}, - {0x10030, 0x0006C017}, -- {0x10030, 0x0006C40D}, -- {0x10030, 0x000701F1}, -+ {0x10030, 0x0006C411}, -+ {0x10030, 0x000701EF}, - {0x10030, 0x000705E9}, - {0x10030, 0x000709A9}, - {0x10030, 0x00070D63}, - {0x10030, 0x0007115D}, -- {0x10030, 0x00071523}, -- {0x10030, 0x0007191D}, -- {0x10030, 0x00071D17}, -- {0x10030, 0x000720DF}, -- {0x10030, 0x000724D9}, -- {0x10030, 0x000728D3}, -- {0x10030, 0x00072C67}, -- {0x10030, 0x00073061}, -- {0x10030, 0x00073427}, -- {0x10030, 0x00073821}, -- {0x10030, 0x00073C1B}, -- {0x10030, 0x00074015}, -- {0x10030, 0x0007440D}, -- {0x10030, 0x000781F1}, -- {0x10030, 0x000785EB}, -- {0x10030, 0x000789E5}, -- {0x10030, 0x00078DA3}, -- {0x10030, 0x00079161}, -- {0x10030, 0x0007955B}, -- {0x10030, 0x00079923}, -- {0x10030, 0x00079D1D}, -- {0x10030, 0x0007A117}, -- {0x10030, 0x0007A4DD}, -- {0x10030, 0x0007A8D7}, -- {0x10030, 0x0007AC9D}, -- {0x10030, 0x0007B063}, -- {0x10030, 0x0007B45D}, -- {0x10030, 0x0007B857}, -- {0x10030, 0x0007BC1D}, -- {0x10030, 0x0007C017}, -- {0x10030, 0x0007C40F}, -+ {0x10030, 0x00071525}, -+ {0x10030, 0x0007191F}, -+ {0x10030, 0x00071D19}, -+ {0x10030, 0x000720E1}, -+ {0x10030, 0x000724DB}, -+ {0x10030, 0x000728A3}, -+ {0x10030, 0x00072C69}, -+ {0x10030, 0x00073063}, -+ {0x10030, 0x00073429}, -+ {0x10030, 0x00073823}, -+ {0x10030, 0x00073C1D}, -+ {0x10030, 0x00074017}, -+ {0x10030, 0x00074411}, -+ {0x10030, 0x000781EF}, -+ {0x10030, 0x000785E9}, -+ {0x10030, 0x000789E3}, -+ {0x10030, 0x00078DA1}, -+ {0x10030, 0x0007915F}, -+ {0x10030, 0x00079559}, -+ {0x10030, 0x0007991F}, -+ {0x10030, 0x00079D19}, -+ {0x10030, 0x0007A0DF}, -+ {0x10030, 0x0007A4D9}, -+ {0x10030, 0x0007A8D3}, -+ {0x10030, 0x0007AC99}, -+ {0x10030, 0x0007B05F}, -+ {0x10030, 0x0007B459}, -+ {0x10030, 0x0007B81F}, -+ {0x10030, 0x0007BC19}, -+ {0x10030, 0x0007C013}, -+ {0x10030, 0x0007C40D}, - {0xA0000000, 0x00000000}, - {0x10030, 0x000001EF}, - {0x10030, 0x000005E9}, -@@ -22782,6 +25380,110 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x000338CC}, - {0x10030, 0x00033C09}, - {0x10030, 0x00034006}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000200E8}, -+ {0x10030, 0x000204E5}, -+ {0x10030, 0x000208E2}, -+ {0x10030, 0x00020CDF}, -+ {0x10030, 0x000210DC}, -+ {0x10030, 0x000214D9}, -+ {0x10030, 0x000218D6}, -+ {0x10030, 0x00021CD3}, -+ {0x10030, 0x000220D0}, -+ {0x10030, 0x0002240D}, -+ {0x10030, 0x0002280A}, -+ {0x10030, 0x00022C07}, -+ {0x10030, 0x00023004}, -+ {0x10030, 0x00023401}, -+ {0x10030, 0x00023800}, -+ {0x10030, 0x00023C00}, -+ {0x10030, 0x00024000}, -+ {0x10030, 0x000280E7}, -+ {0x10030, 0x000284E4}, -+ {0x10030, 0x000288E1}, -+ {0x10030, 0x00028CDE}, -+ {0x10030, 0x000290DB}, -+ {0x10030, 0x000294D8}, -+ {0x10030, 0x000298D5}, -+ {0x10030, 0x00029CD2}, -+ {0x10030, 0x0002A0CF}, -+ {0x10030, 0x0002A40C}, -+ {0x10030, 0x0002A809}, -+ {0x10030, 0x0002AC06}, -+ {0x10030, 0x0002B003}, -+ {0x10030, 0x0002B400}, -+ {0x10030, 0x0002B800}, -+ {0x10030, 0x0002BC00}, -+ {0x10030, 0x0002C000}, -+ {0x10030, 0x000300E7}, -+ {0x10030, 0x000304E4}, -+ {0x10030, 0x000308E1}, -+ {0x10030, 0x00030CDE}, -+ {0x10030, 0x000310DB}, -+ {0x10030, 0x000314D8}, -+ {0x10030, 0x000318D5}, -+ {0x10030, 0x00031CD2}, -+ {0x10030, 0x000320CF}, -+ {0x10030, 0x000324CC}, -+ {0x10030, 0x00032809}, -+ {0x10030, 0x00032C06}, -+ {0x10030, 0x00033003}, -+ {0x10030, 0x00033400}, -+ {0x10030, 0x00033800}, -+ {0x10030, 0x00033C00}, -+ {0x10030, 0x00034000}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x000200E8}, -+ {0x10030, 0x000204E5}, -+ {0x10030, 0x000208E2}, -+ {0x10030, 0x00020CDF}, -+ {0x10030, 0x000210DC}, -+ {0x10030, 0x000214D9}, -+ {0x10030, 0x000218D6}, -+ {0x10030, 0x00021CD3}, -+ {0x10030, 0x000220D0}, -+ {0x10030, 0x0002240D}, -+ {0x10030, 0x0002280A}, -+ {0x10030, 0x00022C07}, -+ {0x10030, 0x00023004}, -+ {0x10030, 0x00023401}, -+ {0x10030, 0x00023800}, -+ {0x10030, 0x00023C00}, -+ {0x10030, 0x00024000}, -+ {0x10030, 0x000280E7}, -+ {0x10030, 0x000284E4}, -+ {0x10030, 0x000288E1}, -+ {0x10030, 0x00028CDE}, -+ {0x10030, 0x000290DB}, -+ {0x10030, 0x000294D8}, -+ {0x10030, 0x000298D5}, -+ {0x10030, 0x00029CD2}, -+ {0x10030, 0x0002A0CF}, -+ {0x10030, 0x0002A40C}, -+ {0x10030, 0x0002A809}, -+ {0x10030, 0x0002AC06}, -+ {0x10030, 0x0002B003}, -+ {0x10030, 0x0002B400}, -+ {0x10030, 0x0002B800}, -+ {0x10030, 0x0002BC00}, -+ {0x10030, 0x0002C000}, -+ {0x10030, 0x000300E7}, -+ {0x10030, 0x000304E4}, -+ {0x10030, 0x000308E1}, -+ {0x10030, 0x00030CDE}, -+ {0x10030, 0x000310DB}, -+ {0x10030, 0x000314D8}, -+ {0x10030, 0x000318D5}, -+ {0x10030, 0x00031CD2}, -+ {0x10030, 0x000320CF}, -+ {0x10030, 0x000324CC}, -+ {0x10030, 0x00032809}, -+ {0x10030, 0x00032C06}, -+ {0x10030, 0x00033003}, -+ {0x10030, 0x00033400}, -+ {0x10030, 0x00033800}, -+ {0x10030, 0x00033C00}, -+ {0x10030, 0x00034000}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x000200FA}, - {0x10030, 0x000204F7}, -@@ -23329,6 +26031,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23373,6 +26079,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23429,6 +26139,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23473,6 +26187,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23529,6 +26247,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23573,6 +26295,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23629,6 +26355,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23673,6 +26403,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23729,6 +26463,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23773,6 +26511,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23829,6 +26571,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23873,6 +26619,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23929,6 +26679,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -23973,6 +26727,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24029,6 +26787,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24073,6 +26835,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24129,6 +26895,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24173,6 +26943,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24229,6 +27003,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24273,6 +27051,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24329,6 +27111,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24373,6 +27159,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24429,6 +27219,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24473,6 +27267,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24529,6 +27327,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24573,6 +27375,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24629,6 +27435,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24673,6 +27483,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24729,6 +27543,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24773,6 +27591,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24829,6 +27651,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24873,6 +27699,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24929,6 +27759,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -24973,6 +27807,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25029,6 +27867,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25073,6 +27915,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25129,6 +27975,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25173,6 +28023,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25229,6 +28083,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25273,6 +28131,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25329,6 +28191,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25373,6 +28239,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25429,6 +28299,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25473,6 +28347,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25529,6 +28407,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25573,6 +28455,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25629,6 +28515,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25673,6 +28563,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25729,6 +28623,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25773,6 +28671,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25829,6 +28731,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25873,6 +28779,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25929,6 +28839,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -25973,6 +28887,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26029,6 +28947,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26073,6 +28995,10 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x00000003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x03F, 0x00008002}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x03F, 0x00000003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26157,6 +29083,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00025003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00025003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00025003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00025003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00025003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26207,6 +29137,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0002D003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0002D003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0002D003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0002D003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0002D003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26257,6 +29191,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x00035003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00035003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00035003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00035003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00035003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26307,6 +29245,10 @@ static const struct rtw89_reg2_def rtw89 - {0x10030, 0x0003D003}, - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0003D003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0003D003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0003D003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0003D003}, - {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, -@@ -26370,6 +29312,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00065003}, - {0x10030, 0x00066003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00065003}, -+ {0x10030, 0x00066003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00065003}, -+ {0x10030, 0x00066003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00065003}, - {0x10030, 0x00066003}, -@@ -26440,6 +29388,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0006D003}, - {0x10030, 0x0006E003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0006D003}, -+ {0x10030, 0x0006E003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0006D003}, -+ {0x10030, 0x0006E003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0006D003}, - {0x10030, 0x0006E003}, -@@ -26510,6 +29464,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00075003}, - {0x10030, 0x00076003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00075003}, -+ {0x10030, 0x00076003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x00075003}, -+ {0x10030, 0x00076003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x00075003}, - {0x10030, 0x00076003}, -@@ -26580,6 +29540,12 @@ static const struct rtw89_reg2_def rtw89 - {0x90070001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0007D003}, - {0x10030, 0x0007E003}, -+ {0x90150001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0007D003}, -+ {0x10030, 0x0007E003}, -+ {0x90160001, 0x00000000}, {0x40000000, 0x00000000}, -+ {0x10030, 0x0007D003}, -+ {0x10030, 0x0007E003}, - {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, - {0x10030, 0x0007D003}, - {0x10030, 0x0007E003}, -@@ -26621,7 +29587,7 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0000000A}, - {0x0ED, 0x00000000}, - {0x100EE, 0x00000000}, -- {0x0FE, 0x00000048}, -+ {0x0FE, 0x00000063}, - }; - - static const struct rtw89_reg2_def rtw89_8852c_phy_nctl_regs[] = { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-134-wifi-rtw89-cleanup-private-data-structures.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-134-wifi-rtw89-cleanup-private-data-structures.patch deleted file mode 100644 index f5f6687f4..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-134-wifi-rtw89-cleanup-private-data-structures.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 65a9140e38b6f3318af90860ab0128a47996aaa9 Mon Sep 17 00:00:00 2001 -From: Dmitry Antipov -Date: Wed, 14 Jun 2023 11:15:53 +0300 -Subject: [PATCH 134/136] wifi: rtw89: cleanup private data structures - -Remove a bunch of unused (and set but unused) fields -from 'struct rtw89_btc_wl_nhm', 'struct rtw89_dle_info', -'struct rtw89_hal' and 'struct rtw89_env_monitor_info' -driver-specific data structures, adjust related bits. - -Signed-off-by: Dmitry Antipov -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230614081555.91395-1-dmantipov@yandex.ru ---- - drivers/net/wireless/realtek/rtw89/core.h | 39 ----------------------- - drivers/net/wireless/realtek/rtw89/mac.c | 6 +--- - drivers/net/wireless/realtek/rtw89/phy.c | 4 --- - 3 files changed, 1 insertion(+), 48 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -1405,7 +1405,6 @@ struct rtw89_btc_wl_nhm { - u8 current_status; - u8 refresh; - bool start_flag; -- u8 last_ccx_rpt_stamp; - s8 pwr_max; - s8 pwr_min; - }; -@@ -3301,7 +3300,6 @@ enum rtw89_hcifc_mode { - - struct rtw89_dle_info { - enum rtw89_qta_mode qta_mode; -- u16 wde_pg_size; - u16 ple_pg_size; - u16 c0_rx_qta; - u16 c1_rx_qta; -@@ -3484,7 +3482,6 @@ struct rtw89_hal { - u32 rx_fltr; - u8 cv; - u8 acv; -- u32 sw_amsdu_max_size; - u32 antenna_tx; - u32 antenna_rx; - u8 tx_nss; -@@ -3890,35 +3887,16 @@ enum rtw89_ccx_edcca_opt_bw_idx { - #define RTW89_FAHM_RPT_NUM 12 - #define RTW89_IFS_CLM_NUM 4 - struct rtw89_env_monitor_info { -- u32 ccx_trigger_time; -- u64 start_time; -- u8 ccx_rpt_stamp; - u8 ccx_watchdog_result; - bool ccx_ongoing; - u8 ccx_rac_lv; - bool ccx_manual_ctrl; -- u8 ccx_pre_rssi; -- u16 clm_mntr_time; -- u16 nhm_mntr_time; - u16 ifs_clm_mntr_time; - enum rtw89_ifs_clm_application ifs_clm_app; -- u16 fahm_mntr_time; -- u16 edcca_clm_mntr_time; - u16 ccx_period; - u8 ccx_unit_idx; -- enum rtw89_ccx_edcca_opt_bw_idx ccx_edcca_opt_bw_idx; -- u8 nhm_th[RTW89_NHM_TH_NUM]; - u16 ifs_clm_th_l[RTW89_IFS_CLM_NUM]; - u16 ifs_clm_th_h[RTW89_IFS_CLM_NUM]; -- u8 fahm_numer_opt; -- u8 fahm_denom_opt; -- u8 fahm_th[RTW89_FAHM_TH_NUM]; -- u16 clm_result; -- u16 nhm_result[RTW89_NHM_RPT_NUM]; -- u8 nhm_wgt[RTW89_NHM_RPT_NUM]; -- u16 nhm_tx_cnt; -- u16 nhm_cca_cnt; -- u16 nhm_idle_cnt; - u16 ifs_clm_tx; - u16 ifs_clm_edcca_excl_cca; - u16 ifs_clm_ofdmfa; -@@ -3929,17 +3907,6 @@ struct rtw89_env_monitor_info { - u8 ifs_clm_his[RTW89_IFS_CLM_NUM]; - u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; - u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; -- u16 fahm_result[RTW89_FAHM_RPT_NUM]; -- u16 fahm_denom_result; -- u16 edcca_clm_result; -- u8 clm_ratio; -- u8 nhm_rpt[RTW89_NHM_RPT_NUM]; -- u8 nhm_tx_ratio; -- u8 nhm_cca_ratio; -- u8 nhm_idle_ratio; -- u8 nhm_ratio; -- u16 nhm_result_sum; -- u8 nhm_pwr; - u8 ifs_clm_tx_ratio; - u8 ifs_clm_edcca_excl_cca_ratio; - u8 ifs_clm_cck_fa_ratio; -@@ -3950,12 +3917,6 @@ struct rtw89_env_monitor_info { - u16 ifs_clm_ofdm_fa_permil; - u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM]; - u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM]; -- u8 fahm_rpt[RTW89_FAHM_RPT_NUM]; -- u16 fahm_result_sum; -- u8 fahm_ratio; -- u8 fahm_denom_ratio; -- u8 fahm_pwr; -- u8 edcca_clm_ratio; - }; - - enum rtw89_ser_rcvy_step { ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -758,11 +758,8 @@ static int hfc_reset_param(struct rtw89_ - if (param_ini.pub_cfg) - param->pub_cfg = *param_ini.pub_cfg; - -- if (param_ini.prec_cfg) { -+ if (param_ini.prec_cfg) - param->prec_cfg = *param_ini.prec_cfg; -- rtwdev->hal.sw_amsdu_max_size = -- param->prec_cfg.wp_ch07_prec * HFC_PAGE_UNIT; -- } - - if (param_ini.ch_cfg) - param->ch_cfg = param_ini.ch_cfg; -@@ -1541,7 +1538,6 @@ static const struct rtw89_dle_mem *get_d - return NULL; - } - -- mac->dle_info.wde_pg_size = cfg->wde_size->pge_size; - mac->dle_info.ple_pg_size = cfg->ple_size->pge_size; - mac->dle_info.qta_mode = mode; - mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma; ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -3188,11 +3188,8 @@ static void rtw89_phy_ccx_top_setting_in - env->ccx_manual_ctrl = false; - env->ccx_ongoing = false; - env->ccx_rac_lv = RTW89_RAC_RELEASE; -- env->ccx_rpt_stamp = 0; - env->ccx_period = 0; - env->ccx_unit_idx = RTW89_CCX_32_US; -- env->ccx_trigger_time = 0; -- env->ccx_edcca_opt_bw_idx = RTW89_CCX_EDCCA_BW20_0; - - rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EN_MSK, 1); - rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_TRIG_OPT_MSK, 1); -@@ -3400,7 +3397,6 @@ static void rtw89_phy_ccx_trigger(struct - rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 1); - rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1); - -- env->ccx_rpt_stamp++; - env->ccx_ongoing = true; - } - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-135-wifi-rtw89-cleanup-rtw89_iqk_info-and-related-code.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-135-wifi-rtw89-cleanup-rtw89_iqk_info-and-related-code.patch deleted file mode 100644 index 24af5f2ae..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-135-wifi-rtw89-cleanup-rtw89_iqk_info-and-related-code.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 686317a246cd10e343f8ca519a54e6a51a3eb142 Mon Sep 17 00:00:00 2001 -From: Dmitry Antipov -Date: Wed, 14 Jun 2023 11:15:54 +0300 -Subject: [PATCH 135/136] wifi: rtw89: cleanup rtw89_iqk_info and related code - -Drop useless '_iqk_track()' and 'rtw8852a_iqk_track()' (they -just change 'thermal_rek_en' field which is set but unused -and so removed as well) functions, set but unused 'kcount' -field of 'struct rtw89_iqk_info', and convert 'thermal' to -local variables where appropriate (it doesn't need to have -longer storage duration because it is actually used for the -debugging purposes only). - -Signed-off-by: Dmitry Antipov -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230614081555.91395-2-dmantipov@yandex.ru ---- - drivers/net/wireless/realtek/rtw89/core.h | 3 -- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 2 -- - drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 - - .../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 36 ++----------------- - .../net/wireless/realtek/rtw89/rtw8852a_rfk.h | 1 - - .../net/wireless/realtek/rtw89/rtw8852b_rfk.c | 6 ---- - .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 9 ++--- - 7 files changed, 4 insertions(+), 54 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3610,7 +3610,6 @@ struct rtw89_iqk_info { - u8 iqk_band[RTW89_IQK_PATH_NR]; - u8 iqk_ch[RTW89_IQK_PATH_NR]; - u8 iqk_bw[RTW89_IQK_PATH_NR]; -- u8 kcount; - u8 iqk_times; - u8 version; - u32 nb_txcfir[RTW89_IQK_PATH_NR]; -@@ -3625,8 +3624,6 @@ struct rtw89_iqk_info { - bool iqk_xym_en; - bool iqk_sram_en; - bool iqk_cfir_en; -- u8 thermal[RTW89_IQK_PATH_NR]; -- bool thermal_rek_en; - u32 syn1to2; - u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; - u8 iqk_table_idx[RTW89_IQK_PATH_NR]; ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -1560,7 +1560,6 @@ static void _iqk_init(struct rtw89_dev * - iqk_info->iqk_sram_en = false; - iqk_info->iqk_cfir_en = false; - iqk_info->iqk_xym_en = false; -- iqk_info->thermal_rek_en = false; - iqk_info->iqk_times = 0x0; - - for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { -@@ -1589,7 +1588,6 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, - "[IQK]==========IQK strat!!!!!==========\n"); - iqk_info->iqk_times++; -- iqk_info->kcount = 0; - iqk_info->version = RTW8851B_IQK_VER; - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c -@@ -1338,7 +1338,6 @@ static void rtw8852a_rfk_scan(struct rtw - static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev) - { - rtw8852a_dpk_track(rtwdev); -- rtw8852a_iqk_track(rtwdev); - rtw8852a_tssi_track(rtwdev); - } - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c -@@ -1284,11 +1284,8 @@ static void _iqk_info_iqk(struct rtw89_d - u32 tmp = 0x0; - bool flag = 0x0; - -- iqk_info->thermal[path] = -- ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -- iqk_info->thermal_rek_en = false; -- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path, -- iqk_info->thermal[path]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path, -+ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path])); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, - iqk_info->lok_cor_fail[0][path]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, -@@ -1536,28 +1533,6 @@ static void _iqk_dbcc(struct rtw89_dev * - _iqk_afebb_restore(rtwdev, phy_idx, path); - } - --static void _iqk_track(struct rtw89_dev *rtwdev) --{ -- struct rtw89_iqk_info *iqk = &rtwdev->iqk; -- u8 path = 0x0; -- u8 cur_ther; -- -- if (iqk->iqk_band[0] == RTW89_BAND_2G) -- return; -- if (iqk->iqk_bw[0] < RTW89_CHANNEL_WIDTH_80) -- return; -- -- /* only check path 0 */ -- for (path = 0; path < 1; path++) { -- cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -- -- if (abs(cur_ther - iqk->thermal[path]) > RTW8852A_IQK_THR_REK) -- iqk->thermal_rek_en = true; -- else -- iqk->thermal_rek_en = false; -- } --} -- - static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) - { - u32 rf_reg5, rck_val = 0; -@@ -1616,7 +1591,6 @@ static void _iqk_init(struct rtw89_dev * - iqk_info->iqk_sram_en = false; - iqk_info->iqk_cfir_en = false; - iqk_info->iqk_xym_en = false; -- iqk_info->thermal_rek_en = false; - iqk_info->iqk_times = 0x0; - - for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { -@@ -1645,7 +1619,6 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, - "[IQK]==========IQK start!!!!!==========\n"); - iqk_info->iqk_times++; -- iqk_info->kcount = 0; - iqk_info->version = RTW8852A_IQK_VER; - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); -@@ -3655,11 +3628,6 @@ void rtw8852a_iqk(struct rtw89_dev *rtwd - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); - } - --void rtw8852a_iqk_track(struct rtw89_dev *rtwdev) --{ -- _iqk_track(rtwdev); --} -- - void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, - bool is_afe) - { ---- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h -@@ -10,7 +10,6 @@ - void rtw8852a_rck(struct rtw89_dev *rtwdev); - void rtw8852a_dack(struct rtw89_dev *rtwdev); - void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); --void rtw8852a_iqk_track(struct rtw89_dev *rtwdev); - void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, - bool is_afe); - void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -1317,10 +1317,6 @@ static void _iqk_info_iqk(struct rtw89_d - u32 tmp; - bool flag; - -- iqk_info->thermal[path] = -- ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -- iqk_info->thermal_rek_en = false; -- - flag = iqk_info->lok_cor_fail[0][path]; - rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag); - flag = iqk_info->lok_fin_fail[0][path]; -@@ -1568,7 +1564,6 @@ static void _iqk_init(struct rtw89_dev * - iqk_info->iqk_sram_en = false; - iqk_info->iqk_cfir_en = false; - iqk_info->iqk_xym_en = false; -- iqk_info->thermal_rek_en = false; - iqk_info->iqk_times = 0x0; - - for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { -@@ -1624,7 +1619,6 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, - "[IQK]==========IQK strat!!!!!==========\n"); - iqk_info->iqk_times++; -- iqk_info->kcount = 0; - iqk_info->version = RTW8852B_IQK_VER; - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -1261,11 +1261,8 @@ static void _iqk_info_iqk(struct rtw89_d - u32 tmp; - bool flag; - -- iqk_info->thermal[path] = -- ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); -- iqk_info->thermal_rek_en = false; -- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path, -- iqk_info->thermal[path]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path, -+ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path])); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, - iqk_info->lok_cor_fail[0][path]); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, -@@ -1502,7 +1499,6 @@ static void _iqk_init(struct rtw89_dev * - iqk_info->iqk_sram_en = false; - iqk_info->iqk_cfir_en = false; - iqk_info->iqk_xym_en = false; -- iqk_info->thermal_rek_en = false; - iqk_info->iqk_times = 0x0; - - for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { -@@ -1531,7 +1527,6 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, - "[IQK]==========IQK strat!!!!!==========\n"); - iqk_info->iqk_times++; -- iqk_info->kcount = 0; - iqk_info->version = RTW8852C_IQK_VER; - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-136-wifi-rtw89-fix-spelling-typo-of-IQK-debug-messages.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-136-wifi-rtw89-fix-spelling-typo-of-IQK-debug-messages.patch deleted file mode 100644 index 7b8a954d1..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-136-wifi-rtw89-fix-spelling-typo-of-IQK-debug-messages.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5bc9a34ce87bee0ca53b86ff1a5ca340a62c2117 Mon Sep 17 00:00:00 2001 -From: Dmitry Antipov -Date: Wed, 14 Jun 2023 11:15:55 +0300 -Subject: [PATCH 136/136] wifi: rtw89: fix spelling typo of IQK debug messages - -Fix spelling typo of IQK debug messages. - -Signed-off-by: Dmitry Antipov -Acked-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230614081555.91395-3-dmantipov@yandex.ru ---- - drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c | 2 +- - drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 2 +- - drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -1586,7 +1586,7 @@ static void _doiqk(struct rtw89_dev *rtw - BTC_WRFK_ONESHOT_START); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]==========IQK strat!!!!!==========\n"); -+ "[IQK]==========IQK start!!!!!==========\n"); - iqk_info->iqk_times++; - iqk_info->version = RTW8851B_IQK_VER; - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c -@@ -1617,7 +1617,7 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]==========IQK strat!!!!!==========\n"); -+ "[IQK]==========IQK start!!!!!==========\n"); - iqk_info->iqk_times++; - iqk_info->version = RTW8852B_IQK_VER; - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c -@@ -1525,7 +1525,7 @@ static void _doiqk(struct rtw89_dev *rtw - rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]==========IQK strat!!!!!==========\n"); -+ "[IQK]==========IQK start!!!!!==========\n"); - iqk_info->iqk_times++; - iqk_info->version = RTW8852C_IQK_VER; - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-137-wifi-rtw89-8851b-update-RF-radio-A-parameters-to-R28.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-137-wifi-rtw89-8851b-update-RF-radio-A-parameters-to-R28.patch deleted file mode 100644 index 916cfa843..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-137-wifi-rtw89-8851b-update-RF-radio-A-parameters-to-R28.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f5993f39f3a734ba8e84913dfd69d56d997e0aa1 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 15 Jun 2023 21:04:38 +0800 -Subject: [PATCH 1/7] wifi: rtw89: 8851b: update RF radio A parameters to R28 - -Update 8851b radio A parameters to R28 along with internal HALRF_029_00_103 - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615130442.18116-2-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8851b_table.c | 28 +++++++++++++++---- - 1 file changed, 22 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -1273,6 +1273,25 @@ static const struct rtw89_reg2_def rtw89 - {0xF0010000, 0x00000000}, - {0xF0020000, 0x00000001}, - {0xF0030000, 0x00000002}, -+ {0xF0010001, 0x00000003}, -+ {0xF0020001, 0x00000004}, -+ {0xF0030001, 0x00000005}, -+ {0xF0040001, 0x00000006}, -+ {0xF0050001, 0x00000007}, -+ {0xF0060001, 0x00000008}, -+ {0x000, 0x00000000}, -+ {0x0EF, 0x00080000}, -+ {0x033, 0x00000003}, -+ {0x03E, 0x00000150}, -+ {0x03F, 0x0000D79C}, -+ {0x0EF, 0x00000000}, -+ {0x052, 0x000C3338}, -+ {0x053, 0x000608AF}, -+ {0x054, 0x00006C04}, -+ {0x063, 0x000FC082}, -+ {0x065, 0x00018122}, -+ {0x000, 0x00010000}, -+ {0x0FE, 0x0000005A}, - {0x000, 0x00030000}, - {0x018, 0x00013124}, - {0x0EF, 0x00080000}, -@@ -1834,8 +1853,6 @@ static const struct rtw89_reg2_def rtw89 - {0x059, 0x00050033}, - {0x061, 0x0005F48A}, - {0x062, 0x00077435}, -- {0x063, 0x000F80A2}, -- {0x065, 0x00018F22}, - {0x067, 0x00008060}, - {0x07E, 0x0009780B}, - {0x0EE, 0x00000004}, -@@ -2074,9 +2091,6 @@ static const struct rtw89_reg2_def rtw89 - {0x03F, 0x0001C3C3}, - {0x0EF, 0x00000000}, - {0x051, 0x0003D368}, -- {0x052, 0x000A3338}, -- {0x053, 0x000688AF}, -- {0x054, 0x00012C04}, - {0x058, 0x00084221}, - {0x05B, 0x000EB000}, - {0x100EE, 0x00002000}, -@@ -2229,9 +2243,11 @@ static const struct rtw89_reg2_def rtw89 - {0x033, 0x00000000}, - {0x03F, 0x00000004}, - {0x0EF, 0x00000000}, -+ {0x000, 0x00010000}, -+ {0x0FE, 0x0000005A}, - {0x005, 0x00000001}, - {0x10005, 0x00000001}, -- {0x0FE, 0x00000022}, -+ {0x0FE, 0x00000028}, - }; - - static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = { diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-138-wifi-rtw89-8851b-update-TX-power-tables-to-R28.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-138-wifi-rtw89-8851b-update-TX-power-tables-to-R28.patch deleted file mode 100644 index 2322bbfff..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-138-wifi-rtw89-8851b-update-TX-power-tables-to-R28.patch +++ /dev/null @@ -1,740 +0,0 @@ -From b067acb1325abe06159768c351f149b8b621392c Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Thu, 15 Jun 2023 21:04:39 +0800 -Subject: [PATCH 2/7] wifi: rtw89: 8851b: update TX power tables to R28 - -Update 8851B TX power tables to RF version R28. - -TX power tables' changes: -* TX power limit and TX power shape: - update 5 GHz configurations for FCC and IC - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615130442.18116-3-pkshih@realtek.com ---- - .../wireless/realtek/rtw89/rtw8851b_table.c | 220 +++++++++--------- - 1 file changed, 110 insertions(+), 110 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -3342,8 +3342,8 @@ const u8 rtw89_8851b_tx_shape[RTW89_BAND - [1][1][RTW89_ACMA] = 0, - [1][1][RTW89_CN] = 0, - [1][1][RTW89_ETSI] = 0, -- [1][1][RTW89_FCC] = 3, -- [1][1][RTW89_IC] = 3, -+ [1][1][RTW89_FCC] = 1, -+ [1][1][RTW89_IC] = 1, - [1][1][RTW89_KCC] = 0, - [1][1][RTW89_MKK] = 0, - [1][1][RTW89_UK] = 0, -@@ -4896,9 +4896,9 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_WW][42] = 30, - [0][0][1][0][RTW89_WW][44] = 30, - [0][0][1][0][RTW89_WW][46] = 30, -- [0][0][1][0][RTW89_WW][48] = 72, -- [0][0][1][0][RTW89_WW][50] = 72, -- [0][0][1][0][RTW89_WW][52] = 72, -+ [0][0][1][0][RTW89_WW][48] = 68, -+ [0][0][1][0][RTW89_WW][50] = 68, -+ [0][0][1][0][RTW89_WW][52] = 68, - [0][1][1][0][RTW89_WW][0] = 0, - [0][1][1][0][RTW89_WW][2] = 0, - [0][1][1][0][RTW89_WW][4] = 0, -@@ -4952,9 +4952,9 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_WW][42] = 30, - [0][0][2][0][RTW89_WW][44] = 30, - [0][0][2][0][RTW89_WW][46] = 30, -- [0][0][2][0][RTW89_WW][48] = 74, -- [0][0][2][0][RTW89_WW][50] = 76, -- [0][0][2][0][RTW89_WW][52] = 76, -+ [0][0][2][0][RTW89_WW][48] = 70, -+ [0][0][2][0][RTW89_WW][50] = 72, -+ [0][0][2][0][RTW89_WW][52] = 72, - [0][1][2][0][RTW89_WW][0] = 0, - [0][1][2][0][RTW89_WW][2] = 0, - [0][1][2][0][RTW89_WW][4] = 0, -@@ -5011,11 +5011,11 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_WW][48] = 0, - [0][1][2][1][RTW89_WW][50] = 0, - [0][1][2][1][RTW89_WW][52] = 0, -- [1][0][2][0][RTW89_WW][1] = 64, -+ [1][0][2][0][RTW89_WW][1] = 60, - [1][0][2][0][RTW89_WW][5] = 62, - [1][0][2][0][RTW89_WW][9] = 64, -- [1][0][2][0][RTW89_WW][13] = 64, -- [1][0][2][0][RTW89_WW][16] = 66, -+ [1][0][2][0][RTW89_WW][13] = 60, -+ [1][0][2][0][RTW89_WW][16] = 62, - [1][0][2][0][RTW89_WW][20] = 66, - [1][0][2][0][RTW89_WW][24] = 66, - [1][0][2][0][RTW89_WW][28] = 66, -@@ -5023,8 +5023,8 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_WW][36] = 76, - [1][0][2][0][RTW89_WW][39] = 30, - [1][0][2][0][RTW89_WW][43] = 30, -- [1][0][2][0][RTW89_WW][47] = 84, -- [1][0][2][0][RTW89_WW][51] = 84, -+ [1][0][2][0][RTW89_WW][47] = 80, -+ [1][0][2][0][RTW89_WW][51] = 80, - [1][1][2][0][RTW89_WW][1] = 0, - [1][1][2][0][RTW89_WW][5] = 0, - [1][1][2][0][RTW89_WW][9] = 0, -@@ -5053,13 +5053,13 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_WW][43] = 0, - [1][1][2][1][RTW89_WW][47] = 0, - [1][1][2][1][RTW89_WW][51] = 0, -- [2][0][2][0][RTW89_WW][3] = 62, -- [2][0][2][0][RTW89_WW][11] = 62, -- [2][0][2][0][RTW89_WW][18] = 64, -+ [2][0][2][0][RTW89_WW][3] = 60, -+ [2][0][2][0][RTW89_WW][11] = 58, -+ [2][0][2][0][RTW89_WW][18] = 62, - [2][0][2][0][RTW89_WW][26] = 64, - [2][0][2][0][RTW89_WW][34] = 72, - [2][0][2][0][RTW89_WW][41] = 30, -- [2][0][2][0][RTW89_WW][49] = 74, -+ [2][0][2][0][RTW89_WW][49] = 70, - [2][1][2][0][RTW89_WW][3] = 0, - [2][1][2][0][RTW89_WW][11] = 0, - [2][1][2][0][RTW89_WW][18] = 0, -@@ -5083,7 +5083,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [3][1][2][1][RTW89_WW][7] = 0, - [3][1][2][1][RTW89_WW][22] = 0, - [3][1][2][1][RTW89_WW][45] = 0, -- [0][0][1][0][RTW89_FCC][0] = 80, -+ [0][0][1][0][RTW89_FCC][0] = 76, - [0][0][1][0][RTW89_ETSI][0] = 58, - [0][0][1][0][RTW89_MKK][0] = 60, - [0][0][1][0][RTW89_IC][0] = 62, -@@ -5139,7 +5139,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][12] = 58, - [0][0][1][0][RTW89_CN][12] = 60, - [0][0][1][0][RTW89_UK][12] = 58, -- [0][0][1][0][RTW89_FCC][14] = 78, -+ [0][0][1][0][RTW89_FCC][14] = 74, - [0][0][1][0][RTW89_ETSI][14] = 58, - [0][0][1][0][RTW89_MKK][14] = 60, - [0][0][1][0][RTW89_IC][14] = 64, -@@ -5147,10 +5147,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][14] = 58, - [0][0][1][0][RTW89_CN][14] = 60, - [0][0][1][0][RTW89_UK][14] = 58, -- [0][0][1][0][RTW89_FCC][15] = 78, -+ [0][0][1][0][RTW89_FCC][15] = 74, - [0][0][1][0][RTW89_ETSI][15] = 58, - [0][0][1][0][RTW89_MKK][15] = 78, -- [0][0][1][0][RTW89_IC][15] = 78, -+ [0][0][1][0][RTW89_IC][15] = 74, - [0][0][1][0][RTW89_KCC][15] = 78, - [0][0][1][0][RTW89_ACMA][15] = 58, - [0][0][1][0][RTW89_CN][15] = 127, -@@ -5227,10 +5227,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][33] = 60, - [0][0][1][0][RTW89_CN][33] = 127, - [0][0][1][0][RTW89_UK][33] = 60, -- [0][0][1][0][RTW89_FCC][35] = 72, -+ [0][0][1][0][RTW89_FCC][35] = 68, - [0][0][1][0][RTW89_ETSI][35] = 60, - [0][0][1][0][RTW89_MKK][35] = 78, -- [0][0][1][0][RTW89_IC][35] = 72, -+ [0][0][1][0][RTW89_IC][35] = 68, - [0][0][1][0][RTW89_KCC][35] = 74, - [0][0][1][0][RTW89_ACMA][35] = 60, - [0][0][1][0][RTW89_CN][35] = 127, -@@ -5283,7 +5283,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][46] = 78, - [0][0][1][0][RTW89_CN][46] = 78, - [0][0][1][0][RTW89_UK][46] = 58, -- [0][0][1][0][RTW89_FCC][48] = 72, -+ [0][0][1][0][RTW89_FCC][48] = 68, - [0][0][1][0][RTW89_ETSI][48] = 127, - [0][0][1][0][RTW89_MKK][48] = 127, - [0][0][1][0][RTW89_IC][48] = 127, -@@ -5291,7 +5291,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][48] = 127, - [0][0][1][0][RTW89_CN][48] = 127, - [0][0][1][0][RTW89_UK][48] = 127, -- [0][0][1][0][RTW89_FCC][50] = 72, -+ [0][0][1][0][RTW89_FCC][50] = 68, - [0][0][1][0][RTW89_ETSI][50] = 127, - [0][0][1][0][RTW89_MKK][50] = 127, - [0][0][1][0][RTW89_IC][50] = 127, -@@ -5299,7 +5299,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][1][0][RTW89_ACMA][50] = 127, - [0][0][1][0][RTW89_CN][50] = 127, - [0][0][1][0][RTW89_UK][50] = 127, -- [0][0][1][0][RTW89_FCC][52] = 72, -+ [0][0][1][0][RTW89_FCC][52] = 68, - [0][0][1][0][RTW89_ETSI][52] = 127, - [0][0][1][0][RTW89_MKK][52] = 127, - [0][0][1][0][RTW89_IC][52] = 127, -@@ -5531,7 +5531,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][1][1][0][RTW89_ACMA][52] = 127, - [0][1][1][0][RTW89_CN][52] = 127, - [0][1][1][0][RTW89_UK][52] = 127, -- [0][0][2][0][RTW89_FCC][0] = 78, -+ [0][0][2][0][RTW89_FCC][0] = 74, - [0][0][2][0][RTW89_ETSI][0] = 62, - [0][0][2][0][RTW89_MKK][0] = 62, - [0][0][2][0][RTW89_IC][0] = 64, -@@ -5587,7 +5587,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][12] = 62, - [0][0][2][0][RTW89_CN][12] = 62, - [0][0][2][0][RTW89_UK][12] = 62, -- [0][0][2][0][RTW89_FCC][14] = 76, -+ [0][0][2][0][RTW89_FCC][14] = 72, - [0][0][2][0][RTW89_ETSI][14] = 62, - [0][0][2][0][RTW89_MKK][14] = 62, - [0][0][2][0][RTW89_IC][14] = 64, -@@ -5595,10 +5595,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][14] = 62, - [0][0][2][0][RTW89_CN][14] = 62, - [0][0][2][0][RTW89_UK][14] = 62, -- [0][0][2][0][RTW89_FCC][15] = 76, -+ [0][0][2][0][RTW89_FCC][15] = 72, - [0][0][2][0][RTW89_ETSI][15] = 60, - [0][0][2][0][RTW89_MKK][15] = 78, -- [0][0][2][0][RTW89_IC][15] = 76, -+ [0][0][2][0][RTW89_IC][15] = 72, - [0][0][2][0][RTW89_KCC][15] = 78, - [0][0][2][0][RTW89_ACMA][15] = 60, - [0][0][2][0][RTW89_CN][15] = 127, -@@ -5675,10 +5675,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][33] = 62, - [0][0][2][0][RTW89_CN][33] = 127, - [0][0][2][0][RTW89_UK][33] = 62, -- [0][0][2][0][RTW89_FCC][35] = 72, -+ [0][0][2][0][RTW89_FCC][35] = 68, - [0][0][2][0][RTW89_ETSI][35] = 62, - [0][0][2][0][RTW89_MKK][35] = 78, -- [0][0][2][0][RTW89_IC][35] = 72, -+ [0][0][2][0][RTW89_IC][35] = 68, - [0][0][2][0][RTW89_KCC][35] = 74, - [0][0][2][0][RTW89_ACMA][35] = 62, - [0][0][2][0][RTW89_CN][35] = 127, -@@ -5731,7 +5731,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][46] = 78, - [0][0][2][0][RTW89_CN][46] = 78, - [0][0][2][0][RTW89_UK][46] = 60, -- [0][0][2][0][RTW89_FCC][48] = 74, -+ [0][0][2][0][RTW89_FCC][48] = 70, - [0][0][2][0][RTW89_ETSI][48] = 127, - [0][0][2][0][RTW89_MKK][48] = 127, - [0][0][2][0][RTW89_IC][48] = 127, -@@ -5739,7 +5739,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][48] = 127, - [0][0][2][0][RTW89_CN][48] = 127, - [0][0][2][0][RTW89_UK][48] = 127, -- [0][0][2][0][RTW89_FCC][50] = 76, -+ [0][0][2][0][RTW89_FCC][50] = 72, - [0][0][2][0][RTW89_ETSI][50] = 127, - [0][0][2][0][RTW89_MKK][50] = 127, - [0][0][2][0][RTW89_IC][50] = 127, -@@ -5747,7 +5747,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][0][2][0][RTW89_ACMA][50] = 127, - [0][0][2][0][RTW89_CN][50] = 127, - [0][0][2][0][RTW89_UK][50] = 127, -- [0][0][2][0][RTW89_FCC][52] = 76, -+ [0][0][2][0][RTW89_FCC][52] = 72, - [0][0][2][0][RTW89_ETSI][52] = 127, - [0][0][2][0][RTW89_MKK][52] = 127, - [0][0][2][0][RTW89_IC][52] = 127, -@@ -6203,10 +6203,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [0][1][2][1][RTW89_ACMA][52] = 127, - [0][1][2][1][RTW89_CN][52] = 127, - [0][1][2][1][RTW89_UK][52] = 127, -- [1][0][2][0][RTW89_FCC][1] = 68, -+ [1][0][2][0][RTW89_FCC][1] = 64, - [1][0][2][0][RTW89_ETSI][1] = 64, - [1][0][2][0][RTW89_MKK][1] = 64, -- [1][0][2][0][RTW89_IC][1] = 64, -+ [1][0][2][0][RTW89_IC][1] = 60, - [1][0][2][0][RTW89_KCC][1] = 74, - [1][0][2][0][RTW89_ACMA][1] = 64, - [1][0][2][0][RTW89_CN][1] = 64, -@@ -6227,18 +6227,18 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][9] = 64, - [1][0][2][0][RTW89_CN][9] = 64, - [1][0][2][0][RTW89_UK][9] = 64, -- [1][0][2][0][RTW89_FCC][13] = 66, -+ [1][0][2][0][RTW89_FCC][13] = 62, - [1][0][2][0][RTW89_ETSI][13] = 64, - [1][0][2][0][RTW89_MKK][13] = 64, -- [1][0][2][0][RTW89_IC][13] = 64, -+ [1][0][2][0][RTW89_IC][13] = 60, - [1][0][2][0][RTW89_KCC][13] = 72, - [1][0][2][0][RTW89_ACMA][13] = 64, - [1][0][2][0][RTW89_CN][13] = 64, - [1][0][2][0][RTW89_UK][13] = 64, -- [1][0][2][0][RTW89_FCC][16] = 66, -+ [1][0][2][0][RTW89_FCC][16] = 62, - [1][0][2][0][RTW89_ETSI][16] = 66, - [1][0][2][0][RTW89_MKK][16] = 80, -- [1][0][2][0][RTW89_IC][16] = 66, -+ [1][0][2][0][RTW89_IC][16] = 62, - [1][0][2][0][RTW89_KCC][16] = 74, - [1][0][2][0][RTW89_ACMA][16] = 66, - [1][0][2][0][RTW89_CN][16] = 127, -@@ -6246,7 +6246,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_FCC][20] = 80, - [1][0][2][0][RTW89_ETSI][20] = 66, - [1][0][2][0][RTW89_MKK][20] = 80, -- [1][0][2][0][RTW89_IC][20] = 80, -+ [1][0][2][0][RTW89_IC][20] = 76, - [1][0][2][0][RTW89_KCC][20] = 74, - [1][0][2][0][RTW89_ACMA][20] = 66, - [1][0][2][0][RTW89_CN][20] = 127, -@@ -6267,10 +6267,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][28] = 127, - [1][0][2][0][RTW89_CN][28] = 127, - [1][0][2][0][RTW89_UK][28] = 66, -- [1][0][2][0][RTW89_FCC][32] = 76, -+ [1][0][2][0][RTW89_FCC][32] = 72, - [1][0][2][0][RTW89_ETSI][32] = 66, - [1][0][2][0][RTW89_MKK][32] = 80, -- [1][0][2][0][RTW89_IC][32] = 76, -+ [1][0][2][0][RTW89_IC][32] = 72, - [1][0][2][0][RTW89_KCC][32] = 78, - [1][0][2][0][RTW89_ACMA][32] = 66, - [1][0][2][0][RTW89_CN][32] = 127, -@@ -6286,7 +6286,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_FCC][39] = 84, - [1][0][2][0][RTW89_ETSI][39] = 30, - [1][0][2][0][RTW89_MKK][39] = 127, -- [1][0][2][0][RTW89_IC][39] = 84, -+ [1][0][2][0][RTW89_IC][39] = 80, - [1][0][2][0][RTW89_KCC][39] = 68, - [1][0][2][0][RTW89_ACMA][39] = 80, - [1][0][2][0][RTW89_CN][39] = 70, -@@ -6299,7 +6299,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][43] = 80, - [1][0][2][0][RTW89_CN][43] = 80, - [1][0][2][0][RTW89_UK][43] = 64, -- [1][0][2][0][RTW89_FCC][47] = 84, -+ [1][0][2][0][RTW89_FCC][47] = 80, - [1][0][2][0][RTW89_ETSI][47] = 127, - [1][0][2][0][RTW89_MKK][47] = 127, - [1][0][2][0][RTW89_IC][47] = 127, -@@ -6307,7 +6307,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][0][2][0][RTW89_ACMA][47] = 127, - [1][0][2][0][RTW89_CN][47] = 127, - [1][0][2][0][RTW89_UK][47] = 127, -- [1][0][2][0][RTW89_FCC][51] = 84, -+ [1][0][2][0][RTW89_FCC][51] = 80, - [1][0][2][0][RTW89_ETSI][51] = 127, - [1][0][2][0][RTW89_MKK][51] = 127, - [1][0][2][0][RTW89_IC][51] = 127, -@@ -6539,26 +6539,26 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [1][1][2][1][RTW89_ACMA][51] = 127, - [1][1][2][1][RTW89_CN][51] = 127, - [1][1][2][1][RTW89_UK][51] = 127, -- [2][0][2][0][RTW89_FCC][3] = 76, -+ [2][0][2][0][RTW89_FCC][3] = 72, - [2][0][2][0][RTW89_ETSI][3] = 64, - [2][0][2][0][RTW89_MKK][3] = 62, -- [2][0][2][0][RTW89_IC][3] = 64, -+ [2][0][2][0][RTW89_IC][3] = 60, - [2][0][2][0][RTW89_KCC][3] = 72, - [2][0][2][0][RTW89_ACMA][3] = 64, - [2][0][2][0][RTW89_CN][3] = 64, - [2][0][2][0][RTW89_UK][3] = 64, -- [2][0][2][0][RTW89_FCC][11] = 64, -+ [2][0][2][0][RTW89_FCC][11] = 60, - [2][0][2][0][RTW89_ETSI][11] = 64, - [2][0][2][0][RTW89_MKK][11] = 64, -- [2][0][2][0][RTW89_IC][11] = 62, -+ [2][0][2][0][RTW89_IC][11] = 58, - [2][0][2][0][RTW89_KCC][11] = 72, - [2][0][2][0][RTW89_ACMA][11] = 64, - [2][0][2][0][RTW89_CN][11] = 64, - [2][0][2][0][RTW89_UK][11] = 64, -- [2][0][2][0][RTW89_FCC][18] = 66, -+ [2][0][2][0][RTW89_FCC][18] = 62, - [2][0][2][0][RTW89_ETSI][18] = 64, - [2][0][2][0][RTW89_MKK][18] = 72, -- [2][0][2][0][RTW89_IC][18] = 66, -+ [2][0][2][0][RTW89_IC][18] = 62, - [2][0][2][0][RTW89_KCC][18] = 72, - [2][0][2][0][RTW89_ACMA][18] = 64, - [2][0][2][0][RTW89_CN][18] = 127, -@@ -6574,7 +6574,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_FCC][34] = 76, - [2][0][2][0][RTW89_ETSI][34] = 127, - [2][0][2][0][RTW89_MKK][34] = 72, -- [2][0][2][0][RTW89_IC][34] = 76, -+ [2][0][2][0][RTW89_IC][34] = 72, - [2][0][2][0][RTW89_KCC][34] = 72, - [2][0][2][0][RTW89_ACMA][34] = 72, - [2][0][2][0][RTW89_CN][34] = 127, -@@ -6582,12 +6582,12 @@ const s8 rtw89_8851b_txpwr_lmt_5g[RTW89_ - [2][0][2][0][RTW89_FCC][41] = 76, - [2][0][2][0][RTW89_ETSI][41] = 30, - [2][0][2][0][RTW89_MKK][41] = 127, -- [2][0][2][0][RTW89_IC][41] = 76, -+ [2][0][2][0][RTW89_IC][41] = 72, - [2][0][2][0][RTW89_KCC][41] = 64, - [2][0][2][0][RTW89_ACMA][41] = 72, - [2][0][2][0][RTW89_CN][41] = 72, - [2][0][2][0][RTW89_UK][41] = 64, -- [2][0][2][0][RTW89_FCC][49] = 74, -+ [2][0][2][0][RTW89_FCC][49] = 70, - [2][0][2][0][RTW89_ETSI][49] = 127, - [2][0][2][0][RTW89_MKK][49] = 127, - [2][0][2][0][RTW89_IC][49] = 127, -@@ -10606,9 +10606,9 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_WW][42] = 30, - [0][0][1][0][RTW89_WW][44] = 30, - [0][0][1][0][RTW89_WW][46] = 30, -- [0][0][1][0][RTW89_WW][48] = 72, -- [0][0][1][0][RTW89_WW][50] = 72, -- [0][0][1][0][RTW89_WW][52] = 72, -+ [0][0][1][0][RTW89_WW][48] = 68, -+ [0][0][1][0][RTW89_WW][50] = 68, -+ [0][0][1][0][RTW89_WW][52] = 68, - [0][1][1][0][RTW89_WW][0] = 0, - [0][1][1][0][RTW89_WW][2] = 0, - [0][1][1][0][RTW89_WW][4] = 0, -@@ -10662,9 +10662,9 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_WW][42] = 30, - [0][0][2][0][RTW89_WW][44] = 30, - [0][0][2][0][RTW89_WW][46] = 30, -- [0][0][2][0][RTW89_WW][48] = 74, -- [0][0][2][0][RTW89_WW][50] = 74, -- [0][0][2][0][RTW89_WW][52] = 74, -+ [0][0][2][0][RTW89_WW][48] = 70, -+ [0][0][2][0][RTW89_WW][50] = 70, -+ [0][0][2][0][RTW89_WW][52] = 70, - [0][1][2][0][RTW89_WW][0] = 0, - [0][1][2][0][RTW89_WW][2] = 0, - [0][1][2][0][RTW89_WW][4] = 0, -@@ -10721,11 +10721,11 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][1][2][1][RTW89_WW][48] = 0, - [0][1][2][1][RTW89_WW][50] = 0, - [0][1][2][1][RTW89_WW][52] = 0, -- [1][0][2][0][RTW89_WW][1] = 64, -+ [1][0][2][0][RTW89_WW][1] = 60, - [1][0][2][0][RTW89_WW][5] = 62, - [1][0][2][0][RTW89_WW][9] = 64, -- [1][0][2][0][RTW89_WW][13] = 64, -- [1][0][2][0][RTW89_WW][16] = 66, -+ [1][0][2][0][RTW89_WW][13] = 60, -+ [1][0][2][0][RTW89_WW][16] = 62, - [1][0][2][0][RTW89_WW][20] = 66, - [1][0][2][0][RTW89_WW][24] = 66, - [1][0][2][0][RTW89_WW][28] = 66, -@@ -10733,8 +10733,8 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_WW][36] = 76, - [1][0][2][0][RTW89_WW][39] = 30, - [1][0][2][0][RTW89_WW][43] = 30, -- [1][0][2][0][RTW89_WW][47] = 80, -- [1][0][2][0][RTW89_WW][51] = 80, -+ [1][0][2][0][RTW89_WW][47] = 76, -+ [1][0][2][0][RTW89_WW][51] = 76, - [1][1][2][0][RTW89_WW][1] = 0, - [1][1][2][0][RTW89_WW][5] = 0, - [1][1][2][0][RTW89_WW][9] = 0, -@@ -10763,13 +10763,13 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][1][2][1][RTW89_WW][43] = 0, - [1][1][2][1][RTW89_WW][47] = 0, - [1][1][2][1][RTW89_WW][51] = 0, -- [2][0][2][0][RTW89_WW][3] = 62, -- [2][0][2][0][RTW89_WW][11] = 62, -- [2][0][2][0][RTW89_WW][18] = 64, -+ [2][0][2][0][RTW89_WW][3] = 60, -+ [2][0][2][0][RTW89_WW][11] = 58, -+ [2][0][2][0][RTW89_WW][18] = 62, - [2][0][2][0][RTW89_WW][26] = 64, - [2][0][2][0][RTW89_WW][34] = 68, - [2][0][2][0][RTW89_WW][41] = 30, -- [2][0][2][0][RTW89_WW][49] = 72, -+ [2][0][2][0][RTW89_WW][49] = 68, - [2][1][2][0][RTW89_WW][3] = 0, - [2][1][2][0][RTW89_WW][11] = 0, - [2][1][2][0][RTW89_WW][18] = 0, -@@ -10793,7 +10793,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [3][1][2][1][RTW89_WW][7] = 0, - [3][1][2][1][RTW89_WW][22] = 0, - [3][1][2][1][RTW89_WW][45] = 0, -- [0][0][1][0][RTW89_FCC][0] = 78, -+ [0][0][1][0][RTW89_FCC][0] = 74, - [0][0][1][0][RTW89_ETSI][0] = 58, - [0][0][1][0][RTW89_MKK][0] = 60, - [0][0][1][0][RTW89_IC][0] = 62, -@@ -10849,7 +10849,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][12] = 58, - [0][0][1][0][RTW89_CN][12] = 60, - [0][0][1][0][RTW89_UK][12] = 58, -- [0][0][1][0][RTW89_FCC][14] = 76, -+ [0][0][1][0][RTW89_FCC][14] = 72, - [0][0][1][0][RTW89_ETSI][14] = 58, - [0][0][1][0][RTW89_MKK][14] = 60, - [0][0][1][0][RTW89_IC][14] = 62, -@@ -10857,10 +10857,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][14] = 58, - [0][0][1][0][RTW89_CN][14] = 60, - [0][0][1][0][RTW89_UK][14] = 58, -- [0][0][1][0][RTW89_FCC][15] = 76, -+ [0][0][1][0][RTW89_FCC][15] = 72, - [0][0][1][0][RTW89_ETSI][15] = 58, - [0][0][1][0][RTW89_MKK][15] = 74, -- [0][0][1][0][RTW89_IC][15] = 76, -+ [0][0][1][0][RTW89_IC][15] = 72, - [0][0][1][0][RTW89_KCC][15] = 74, - [0][0][1][0][RTW89_ACMA][15] = 58, - [0][0][1][0][RTW89_CN][15] = 127, -@@ -10937,10 +10937,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][33] = 60, - [0][0][1][0][RTW89_CN][33] = 127, - [0][0][1][0][RTW89_UK][33] = 60, -- [0][0][1][0][RTW89_FCC][35] = 70, -+ [0][0][1][0][RTW89_FCC][35] = 66, - [0][0][1][0][RTW89_ETSI][35] = 60, - [0][0][1][0][RTW89_MKK][35] = 74, -- [0][0][1][0][RTW89_IC][35] = 70, -+ [0][0][1][0][RTW89_IC][35] = 66, - [0][0][1][0][RTW89_KCC][35] = 74, - [0][0][1][0][RTW89_ACMA][35] = 60, - [0][0][1][0][RTW89_CN][35] = 127, -@@ -10993,7 +10993,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][46] = 74, - [0][0][1][0][RTW89_CN][46] = 74, - [0][0][1][0][RTW89_UK][46] = 58, -- [0][0][1][0][RTW89_FCC][48] = 72, -+ [0][0][1][0][RTW89_FCC][48] = 68, - [0][0][1][0][RTW89_ETSI][48] = 127, - [0][0][1][0][RTW89_MKK][48] = 127, - [0][0][1][0][RTW89_IC][48] = 127, -@@ -11001,7 +11001,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][48] = 127, - [0][0][1][0][RTW89_CN][48] = 127, - [0][0][1][0][RTW89_UK][48] = 127, -- [0][0][1][0][RTW89_FCC][50] = 72, -+ [0][0][1][0][RTW89_FCC][50] = 68, - [0][0][1][0][RTW89_ETSI][50] = 127, - [0][0][1][0][RTW89_MKK][50] = 127, - [0][0][1][0][RTW89_IC][50] = 127, -@@ -11009,7 +11009,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][1][0][RTW89_ACMA][50] = 127, - [0][0][1][0][RTW89_CN][50] = 127, - [0][0][1][0][RTW89_UK][50] = 127, -- [0][0][1][0][RTW89_FCC][52] = 72, -+ [0][0][1][0][RTW89_FCC][52] = 68, - [0][0][1][0][RTW89_ETSI][52] = 127, - [0][0][1][0][RTW89_MKK][52] = 127, - [0][0][1][0][RTW89_IC][52] = 127, -@@ -11241,7 +11241,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][1][1][0][RTW89_ACMA][52] = 127, - [0][1][1][0][RTW89_CN][52] = 127, - [0][1][1][0][RTW89_UK][52] = 127, -- [0][0][2][0][RTW89_FCC][0] = 76, -+ [0][0][2][0][RTW89_FCC][0] = 72, - [0][0][2][0][RTW89_ETSI][0] = 62, - [0][0][2][0][RTW89_MKK][0] = 62, - [0][0][2][0][RTW89_IC][0] = 64, -@@ -11297,7 +11297,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][12] = 62, - [0][0][2][0][RTW89_CN][12] = 62, - [0][0][2][0][RTW89_UK][12] = 62, -- [0][0][2][0][RTW89_FCC][14] = 74, -+ [0][0][2][0][RTW89_FCC][14] = 70, - [0][0][2][0][RTW89_ETSI][14] = 62, - [0][0][2][0][RTW89_MKK][14] = 62, - [0][0][2][0][RTW89_IC][14] = 64, -@@ -11305,10 +11305,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][14] = 62, - [0][0][2][0][RTW89_CN][14] = 62, - [0][0][2][0][RTW89_UK][14] = 62, -- [0][0][2][0][RTW89_FCC][15] = 74, -+ [0][0][2][0][RTW89_FCC][15] = 70, - [0][0][2][0][RTW89_ETSI][15] = 60, - [0][0][2][0][RTW89_MKK][15] = 74, -- [0][0][2][0][RTW89_IC][15] = 74, -+ [0][0][2][0][RTW89_IC][15] = 70, - [0][0][2][0][RTW89_KCC][15] = 74, - [0][0][2][0][RTW89_ACMA][15] = 60, - [0][0][2][0][RTW89_CN][15] = 127, -@@ -11385,10 +11385,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][33] = 62, - [0][0][2][0][RTW89_CN][33] = 127, - [0][0][2][0][RTW89_UK][33] = 62, -- [0][0][2][0][RTW89_FCC][35] = 72, -+ [0][0][2][0][RTW89_FCC][35] = 68, - [0][0][2][0][RTW89_ETSI][35] = 62, - [0][0][2][0][RTW89_MKK][35] = 74, -- [0][0][2][0][RTW89_IC][35] = 72, -+ [0][0][2][0][RTW89_IC][35] = 68, - [0][0][2][0][RTW89_KCC][35] = 74, - [0][0][2][0][RTW89_ACMA][35] = 62, - [0][0][2][0][RTW89_CN][35] = 127, -@@ -11441,7 +11441,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][46] = 74, - [0][0][2][0][RTW89_CN][46] = 74, - [0][0][2][0][RTW89_UK][46] = 60, -- [0][0][2][0][RTW89_FCC][48] = 74, -+ [0][0][2][0][RTW89_FCC][48] = 70, - [0][0][2][0][RTW89_ETSI][48] = 127, - [0][0][2][0][RTW89_MKK][48] = 127, - [0][0][2][0][RTW89_IC][48] = 127, -@@ -11449,7 +11449,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][48] = 127, - [0][0][2][0][RTW89_CN][48] = 127, - [0][0][2][0][RTW89_UK][48] = 127, -- [0][0][2][0][RTW89_FCC][50] = 74, -+ [0][0][2][0][RTW89_FCC][50] = 70, - [0][0][2][0][RTW89_ETSI][50] = 127, - [0][0][2][0][RTW89_MKK][50] = 127, - [0][0][2][0][RTW89_IC][50] = 127, -@@ -11457,7 +11457,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][0][2][0][RTW89_ACMA][50] = 127, - [0][0][2][0][RTW89_CN][50] = 127, - [0][0][2][0][RTW89_UK][50] = 127, -- [0][0][2][0][RTW89_FCC][52] = 74, -+ [0][0][2][0][RTW89_FCC][52] = 70, - [0][0][2][0][RTW89_ETSI][52] = 127, - [0][0][2][0][RTW89_MKK][52] = 127, - [0][0][2][0][RTW89_IC][52] = 127, -@@ -11913,10 +11913,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [0][1][2][1][RTW89_ACMA][52] = 127, - [0][1][2][1][RTW89_CN][52] = 127, - [0][1][2][1][RTW89_UK][52] = 127, -- [1][0][2][0][RTW89_FCC][1] = 66, -+ [1][0][2][0][RTW89_FCC][1] = 62, - [1][0][2][0][RTW89_ETSI][1] = 64, - [1][0][2][0][RTW89_MKK][1] = 64, -- [1][0][2][0][RTW89_IC][1] = 64, -+ [1][0][2][0][RTW89_IC][1] = 60, - [1][0][2][0][RTW89_KCC][1] = 74, - [1][0][2][0][RTW89_ACMA][1] = 64, - [1][0][2][0][RTW89_CN][1] = 64, -@@ -11937,18 +11937,18 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_ACMA][9] = 64, - [1][0][2][0][RTW89_CN][9] = 64, - [1][0][2][0][RTW89_UK][9] = 64, -- [1][0][2][0][RTW89_FCC][13] = 64, -+ [1][0][2][0][RTW89_FCC][13] = 60, - [1][0][2][0][RTW89_ETSI][13] = 64, - [1][0][2][0][RTW89_MKK][13] = 64, -- [1][0][2][0][RTW89_IC][13] = 64, -+ [1][0][2][0][RTW89_IC][13] = 60, - [1][0][2][0][RTW89_KCC][13] = 72, - [1][0][2][0][RTW89_ACMA][13] = 64, - [1][0][2][0][RTW89_CN][13] = 64, - [1][0][2][0][RTW89_UK][13] = 64, -- [1][0][2][0][RTW89_FCC][16] = 66, -+ [1][0][2][0][RTW89_FCC][16] = 62, - [1][0][2][0][RTW89_ETSI][16] = 66, - [1][0][2][0][RTW89_MKK][16] = 76, -- [1][0][2][0][RTW89_IC][16] = 66, -+ [1][0][2][0][RTW89_IC][16] = 62, - [1][0][2][0][RTW89_KCC][16] = 74, - [1][0][2][0][RTW89_ACMA][16] = 66, - [1][0][2][0][RTW89_CN][16] = 127, -@@ -11956,7 +11956,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_FCC][20] = 80, - [1][0][2][0][RTW89_ETSI][20] = 66, - [1][0][2][0][RTW89_MKK][20] = 76, -- [1][0][2][0][RTW89_IC][20] = 80, -+ [1][0][2][0][RTW89_IC][20] = 76, - [1][0][2][0][RTW89_KCC][20] = 74, - [1][0][2][0][RTW89_ACMA][20] = 66, - [1][0][2][0][RTW89_CN][20] = 127, -@@ -11977,10 +11977,10 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_ACMA][28] = 127, - [1][0][2][0][RTW89_CN][28] = 127, - [1][0][2][0][RTW89_UK][28] = 66, -- [1][0][2][0][RTW89_FCC][32] = 74, -+ [1][0][2][0][RTW89_FCC][32] = 70, - [1][0][2][0][RTW89_ETSI][32] = 66, - [1][0][2][0][RTW89_MKK][32] = 76, -- [1][0][2][0][RTW89_IC][32] = 74, -+ [1][0][2][0][RTW89_IC][32] = 70, - [1][0][2][0][RTW89_KCC][32] = 76, - [1][0][2][0][RTW89_ACMA][32] = 66, - [1][0][2][0][RTW89_CN][32] = 127, -@@ -11996,7 +11996,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_FCC][39] = 80, - [1][0][2][0][RTW89_ETSI][39] = 30, - [1][0][2][0][RTW89_MKK][39] = 127, -- [1][0][2][0][RTW89_IC][39] = 80, -+ [1][0][2][0][RTW89_IC][39] = 76, - [1][0][2][0][RTW89_KCC][39] = 68, - [1][0][2][0][RTW89_ACMA][39] = 76, - [1][0][2][0][RTW89_CN][39] = 70, -@@ -12009,7 +12009,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_ACMA][43] = 76, - [1][0][2][0][RTW89_CN][43] = 76, - [1][0][2][0][RTW89_UK][43] = 64, -- [1][0][2][0][RTW89_FCC][47] = 80, -+ [1][0][2][0][RTW89_FCC][47] = 76, - [1][0][2][0][RTW89_ETSI][47] = 127, - [1][0][2][0][RTW89_MKK][47] = 127, - [1][0][2][0][RTW89_IC][47] = 127, -@@ -12017,7 +12017,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][0][2][0][RTW89_ACMA][47] = 127, - [1][0][2][0][RTW89_CN][47] = 127, - [1][0][2][0][RTW89_UK][47] = 127, -- [1][0][2][0][RTW89_FCC][51] = 80, -+ [1][0][2][0][RTW89_FCC][51] = 76, - [1][0][2][0][RTW89_ETSI][51] = 127, - [1][0][2][0][RTW89_MKK][51] = 127, - [1][0][2][0][RTW89_IC][51] = 127, -@@ -12249,26 +12249,26 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [1][1][2][1][RTW89_ACMA][51] = 127, - [1][1][2][1][RTW89_CN][51] = 127, - [1][1][2][1][RTW89_UK][51] = 127, -- [2][0][2][0][RTW89_FCC][3] = 72, -+ [2][0][2][0][RTW89_FCC][3] = 68, - [2][0][2][0][RTW89_ETSI][3] = 64, - [2][0][2][0][RTW89_MKK][3] = 62, -- [2][0][2][0][RTW89_IC][3] = 64, -+ [2][0][2][0][RTW89_IC][3] = 60, - [2][0][2][0][RTW89_KCC][3] = 68, - [2][0][2][0][RTW89_ACMA][3] = 64, - [2][0][2][0][RTW89_CN][3] = 64, - [2][0][2][0][RTW89_UK][3] = 64, -- [2][0][2][0][RTW89_FCC][11] = 62, -+ [2][0][2][0][RTW89_FCC][11] = 58, - [2][0][2][0][RTW89_ETSI][11] = 64, - [2][0][2][0][RTW89_MKK][11] = 64, -- [2][0][2][0][RTW89_IC][11] = 62, -+ [2][0][2][0][RTW89_IC][11] = 58, - [2][0][2][0][RTW89_KCC][11] = 68, - [2][0][2][0][RTW89_ACMA][11] = 64, - [2][0][2][0][RTW89_CN][11] = 64, - [2][0][2][0][RTW89_UK][11] = 64, -- [2][0][2][0][RTW89_FCC][18] = 66, -+ [2][0][2][0][RTW89_FCC][18] = 62, - [2][0][2][0][RTW89_ETSI][18] = 64, - [2][0][2][0][RTW89_MKK][18] = 68, -- [2][0][2][0][RTW89_IC][18] = 66, -+ [2][0][2][0][RTW89_IC][18] = 62, - [2][0][2][0][RTW89_KCC][18] = 68, - [2][0][2][0][RTW89_ACMA][18] = 64, - [2][0][2][0][RTW89_CN][18] = 127, -@@ -12284,7 +12284,7 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [2][0][2][0][RTW89_FCC][34] = 72, - [2][0][2][0][RTW89_ETSI][34] = 127, - [2][0][2][0][RTW89_MKK][34] = 68, -- [2][0][2][0][RTW89_IC][34] = 72, -+ [2][0][2][0][RTW89_IC][34] = 68, - [2][0][2][0][RTW89_KCC][34] = 68, - [2][0][2][0][RTW89_ACMA][34] = 68, - [2][0][2][0][RTW89_CN][34] = 127, -@@ -12292,12 +12292,12 @@ const s8 rtw89_8851b_txpwr_lmt_5g_type2[ - [2][0][2][0][RTW89_FCC][41] = 72, - [2][0][2][0][RTW89_ETSI][41] = 30, - [2][0][2][0][RTW89_MKK][41] = 127, -- [2][0][2][0][RTW89_IC][41] = 72, -+ [2][0][2][0][RTW89_IC][41] = 68, - [2][0][2][0][RTW89_KCC][41] = 64, - [2][0][2][0][RTW89_ACMA][41] = 68, - [2][0][2][0][RTW89_CN][41] = 68, - [2][0][2][0][RTW89_UK][41] = 64, -- [2][0][2][0][RTW89_FCC][49] = 72, -+ [2][0][2][0][RTW89_FCC][49] = 68, - [2][0][2][0][RTW89_ETSI][49] = 127, - [2][0][2][0][RTW89_MKK][49] = 127, - [2][0][2][0][RTW89_IC][49] = 127, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-139-wifi-rtw89-8851b-rfk-add-LCK-track.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-139-wifi-rtw89-8851b-rfk-add-LCK-track.patch deleted file mode 100644 index ba8e45291..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-139-wifi-rtw89-8851b-rfk-add-LCK-track.patch +++ /dev/null @@ -1,154 +0,0 @@ -From b686bc67e0437eb5791bca6ec89479470ef40513 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 15 Jun 2023 21:04:40 +0800 -Subject: [PATCH 3/7] wifi: rtw89: 8851b: rfk: add LCK track - -LCK is short for LC Tank calibration. To keep RF performance, do this -calibration if difference of thermal value is over a threshold. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615130442.18116-4-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 1 + - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 + - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 65 ++++++++++++++++++- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.h | 2 + - 4 files changed, 69 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3834,6 +3834,7 @@ - #define RR_LCKST_BIN BIT(0) - #define RR_LCK_TRG 0xd3 - #define RR_LCK_TRGSEL BIT(8) -+#define RR_LCK_ST BIT(4) - #define RR_MMD 0xd5 - #define RR_MMD_RST_EN BIT(8) - #define RR_MMD_RST_SYN BIT(6) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -1546,6 +1546,7 @@ static void rtw8851b_rfk_init(struct rtw - { - rtwdev->is_tssi_mode[RF_PATH_A] = false; - rtwdev->is_tssi_mode[RF_PATH_B] = false; -+ rtw8851b_lck_init(rtwdev); - - rtw8851b_dpk_init(rtwdev); - rtw8851b_aack(rtwdev); -@@ -1578,6 +1579,7 @@ static void rtw8851b_rfk_scan(struct rtw - static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev) - { - rtw8851b_dpk_track(rtwdev); -+ rtw8851b_lck_track(rtwdev); - } - - static u32 rtw8851b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -118,6 +118,8 @@ static const u32 dpk_kip_reg[DPK_KIP_REG - 0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8}; - static const u32 dpk_rf_reg[DPK_RF_REG_NUM_8851B] = {0xde, 0x8f, 0x5, 0x10005}; - -+static void _set_ch(struct rtw89_dev *rtwdev, u32 val); -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - return RF_A; -@@ -3133,7 +3135,7 @@ void rtw8851b_dpk_init(struct rtw89_dev - - void rtw8851b_aack(struct rtw89_dev *rtwdev) - { -- u32 tmp05, ib[4]; -+ u32 tmp05, tmpd3, ib[4]; - u32 tmp; - int ret; - int rek; -@@ -3142,8 +3144,10 @@ void rtw8851b_aack(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO AACK\n"); - - tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); -+ tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); - rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); - rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_ST, 0x0); - - for (rek = 0; rek < 4; rek++) { - rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201e); -@@ -3171,6 +3175,65 @@ void rtw8851b_aack(struct rtw89_dev *rtw - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]AACK rek = %d\n", rek); - - rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); -+} -+ -+static void _lck_keep_thermal(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_lck_info *lck = &rtwdev->lck; -+ -+ lck->thermal[RF_PATH_A] = -+ ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[LCK] path=%d thermal=0x%x", RF_PATH_A, lck->thermal[RF_PATH_A]); -+} -+ -+static void rtw8851b_lck(struct rtw89_dev *rtwdev) -+{ -+ u32 tmp05, tmp18, tmpd3; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO LCK\n"); -+ -+ tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); -+ tmp18 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); -+ tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); -+ -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); -+ -+ _set_ch(rtwdev, tmp18); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); -+ -+ _lck_keep_thermal(rtwdev); -+} -+ -+#define RTW8851B_LCK_TH 8 -+ -+void rtw8851b_lck_track(struct rtw89_dev *rtwdev) -+{ -+ struct rtw89_lck_info *lck = &rtwdev->lck; -+ u8 cur_thermal; -+ int delta; -+ -+ cur_thermal = -+ ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); -+ delta = abs((int)cur_thermal - lck->thermal[RF_PATH_A]); -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, -+ "[LCK] path=%d current thermal=0x%x delta=0x%x\n", -+ RF_PATH_A, cur_thermal, delta); -+ -+ if (delta >= RTW8851B_LCK_TH) { -+ rtw8851b_aack(rtwdev); -+ rtw8851b_lck(rtwdev); -+ } -+} -+ -+void rtw8851b_lck_init(struct rtw89_dev *rtwdev) -+{ -+ _lck_keep_thermal(rtwdev); - } - - void rtw8851b_rck(struct rtw89_dev *rtwdev) ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h -@@ -8,6 +8,8 @@ - #include "core.h" - - void rtw8851b_aack(struct rtw89_dev *rtwdev); -+void rtw8851b_lck_init(struct rtw89_dev *rtwdev); -+void rtw8851b_lck_track(struct rtw89_dev *rtwdev); - void rtw8851b_rck(struct rtw89_dev *rtwdev); - void rtw8851b_dack(struct rtw89_dev *rtwdev); - void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-140-wifi-rtw89-8851b-rfk-update-IQK-to-version-0x8.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-140-wifi-rtw89-8851b-rfk-update-IQK-to-version-0x8.patch deleted file mode 100644 index dae91af6b..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-140-wifi-rtw89-8851b-rfk-update-IQK-to-version-0x8.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 76a7c7acaa78b1a4ab59868808fadbeb7a939b81 Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 15 Jun 2023 21:04:41 +0800 -Subject: [PATCH 4/7] wifi: rtw89: 8851b: rfk: update IQK to version 0x8 - -The main change is to adjust RX calibration groups from {0,1,2,3} to {0,2} -in 5 GHz, so reduce elements from 4 to 2, and use index to iterate them. -Meanwhile, always do RX narrowband calibration (ID_NBRXK) for each group. -NCTL is used to assist IQK, so also update NCTL to 0x6 along with internal -tag HALRF_029_00_103. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615130442.18116-5-pkshih@realtek.com ---- - .../net/wireless/realtek/rtw89/rtw8851b_rfk.c | 115 ++++++++++-------- - .../wireless/realtek/rtw89/rtw8851b_table.c | 2 +- - 2 files changed, 63 insertions(+), 54 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c -@@ -17,6 +17,7 @@ - #define DPK_RF_REG_NUM_8851B 4 - #define DPK_KSET_NUM 4 - #define RTW8851B_RXK_GROUP_NR 4 -+#define RTW8851B_RXK_GROUP_IDX_NR 2 - #define RTW8851B_TXK_GROUP_NR 1 - #define RTW8851B_IQK_VER 0x2a - #define RTW8851B_IQK_SS 1 -@@ -95,9 +96,9 @@ static const u32 _tssi_de_mcs_10m[RF_PAT - static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; - static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; - static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; --static const u32 a_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10C, 0x112, 0x28c, 0x292}; --static const u32 a_idxattc2[RTW8851B_RXK_GROUP_NR] = {0xf, 0xf, 0xf, 0xf}; --static const u32 a_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x4, 0x5, 0x6, 0x7}; -+static const u32 a_idxrxgain[RTW8851B_RXK_GROUP_IDX_NR] = {0x10C, 0x28c}; -+static const u32 a_idxattc2[RTW8851B_RXK_GROUP_IDX_NR] = {0xf, 0xf}; -+static const u32 a_idxrxagc[RTW8851B_RXK_GROUP_IDX_NR] = {0x4, 0x6}; - static const u32 a_power_range[RTW8851B_TXK_GROUP_NR] = {0x0}; - static const u32 a_track_range[RTW8851B_TXK_GROUP_NR] = {0x6}; - static const u32 a_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x0a}; -@@ -107,7 +108,7 @@ static const u32 g_track_range[RTW8851B_ - static const u32 g_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x10}; - static const u32 g_itqt[RTW8851B_TXK_GROUP_NR] = {0x12}; - --static const u32 rtw8851b_backup_bb_regs[] = {0xc0ec, 0xc0e8}; -+static const u32 rtw8851b_backup_bb_regs[] = {0xc0d4, 0xc0d8, 0xc0c4, 0xc0ec, 0xc0e8}; - static const u32 rtw8851b_backup_rf_regs[] = { - 0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; - -@@ -120,6 +121,17 @@ static const u32 dpk_rf_reg[DPK_RF_REG_N - - static void _set_ch(struct rtw89_dev *rtwdev, u32 val); - -+static u8 _rxk_5ghz_group_from_idx(u8 idx) -+{ -+ /* There are four RXK groups (RTW8851B_RXK_GROUP_NR), but only group 0 -+ * and 2 are used in 5 GHz band, so reduce elements to 2. -+ */ -+ if (idx < RTW8851B_RXK_GROUP_IDX_NR) -+ return idx * 2; -+ -+ return 0; -+} -+ - static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) - { - return RF_A; -@@ -786,17 +798,11 @@ static bool _rxk_2g_group_sel(struct rtw - rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), - rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); - -- if (gp == 0x3) { -- rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -- rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -- notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -- iqk_info->nb_rxcfir[path] = -- rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -- -- rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -- rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -- } -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; - - notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); - -@@ -834,15 +840,18 @@ static bool _rxk_5g_group_sel(struct rtw - bool kfail = false; - bool notready; - u32 rf_0; -+ u8 idx; - u8 gp; - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); - -- for (gp = 0; gp < RTW8851B_RXK_GROUP_NR; gp++) { -+ for (idx = 0; idx < RTW8851B_RXK_GROUP_IDX_NR; idx++) { -+ gp = _rxk_5ghz_group_from_idx(idx); -+ - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); - -- rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, 0x03ff0, a_idxrxgain[gp]); -- rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[idx]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[idx]); - - rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); - rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -@@ -852,7 +861,7 @@ static bool _rxk_5g_group_sel(struct rtw - fsleep(100); - rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); - rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -- rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[idx]); - rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); - notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); - -@@ -861,17 +870,15 @@ static bool _rxk_5g_group_sel(struct rtw - rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), - rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB)); - -- if (gp == 0x3) { -- rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -- rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -- notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -- iqk_info->nb_rxcfir[path] = -- rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -- -- rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -- rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -- } -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); - - notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); - -@@ -908,14 +915,17 @@ static bool _iqk_5g_nbrxk(struct rtw89_d - struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; - bool kfail = false; - bool notready; -- u8 gp = 0x3; -+ u8 idx = 0x1; - u32 rf_0; -+ u8 gp; -+ -+ gp = _rxk_5ghz_group_from_idx(idx); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); - -- rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]); -- rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[gp]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[idx]); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[idx]); - - rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); - rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); -@@ -925,7 +935,7 @@ static bool _iqk_5g_nbrxk(struct rtw89_d - fsleep(100); - rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); - rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); -- rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[idx]); - rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); - notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); - -@@ -934,17 +944,15 @@ static bool _iqk_5g_nbrxk(struct rtw89_d - rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), - rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); - -- if (gp == 0x3) { -- rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -- rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -- notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -- iqk_info->nb_rxcfir[path] = -- rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; - -- rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -- rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -- } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", - path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -@@ -998,17 +1006,15 @@ static bool _iqk_2g_nbrxk(struct rtw89_d - path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), - rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); - -- if (gp == 0x3) { -- rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -- rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -- notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -- iqk_info->nb_rxcfir[path] = -- rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; -+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); -+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); -+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); -+ iqk_info->nb_rxcfir[path] = -+ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; - -- rtw89_debug(rtwdev, RTW89_DBG_RFK, -- "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -- rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -- } -+ rtw89_debug(rtwdev, RTW89_DBG_RFK, -+ "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, -+ rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); - - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", - path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); -@@ -1516,6 +1522,9 @@ static void _iqk_restore(struct rtw89_de - fail = _iqk_check_cal(rtwdev, path); - rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail=%d\n", fail); - -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RR_LUTWE_LOK, 0x0); -+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_TIA, 0x0); -+ - rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); - rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); - rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -2322,7 +2322,7 @@ static const struct rtw89_reg2_def rtw89 - {0x8144, 0x0b040b03}, - {0x8148, 0x07020b04}, - {0x814c, 0x07020b04}, -- {0x8150, 0xe4e40000}, -+ {0x8150, 0xa0a00000}, - {0x8158, 0xffffffff}, - {0x815c, 0xffffffff}, - {0x8160, 0xffffffff}, diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-141-wifi-rtw89-8851b-configure-to-force-1-TX-power-value.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-141-wifi-rtw89-8851b-configure-to-force-1-TX-power-value.patch deleted file mode 100644 index beac33886..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-141-wifi-rtw89-8851b-configure-to-force-1-TX-power-value.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 076031a09ae9e9394a56805aab92973612763d7e Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Thu, 15 Jun 2023 21:04:42 +0800 -Subject: [PATCH 5/7] wifi: rtw89: 8851b: configure to force 1 TX power value - -RTL8851B is a chip with only single RF path, and it must use 1 TX power -value for transmission, so force 1 TX power value to prevent hardware -logic gets wrong TX power values randomly in certain samples. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230615130442.18116-6-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/reg.h | 22 +++++++++++++++++++ - drivers/net/wireless/realtek/rtw89/rtw8851b.c | 3 +++ - 2 files changed, 25 insertions(+) - ---- a/drivers/net/wireless/realtek/rtw89/reg.h -+++ b/drivers/net/wireless/realtek/rtw89/reg.h -@@ -3333,6 +3333,28 @@ - #define R_AX_PWR_UL_CTRL2 0xD248 - #define B_AX_PWR_UL_CFO_MASK GENMASK(2, 0) - #define B_AX_PWR_UL_CTRL2_MASK 0x07700007 -+ -+#define R_AX_PWR_NORM_FORCE1 0xD260 -+#define R_AX_PWR_NORM_FORCE1_C1 0xF260 -+#define B_AX_TXAGC_BF_PWR_BOOST_FORCE_VAL_EN BIT(29) -+#define B_AX_TXAGC_BF_PWR_BOOST_FORCE_VAL_MASK GENMASK(28, 24) -+#define B_AX_FORCE_HE_ER_SU_EN_EN BIT(23) -+#define B_AX_FORCE_HE_ER_SU_EN_VALUE BIT(22) -+#define B_AX_FORCE_MACID_CCA_TH_EN_EN BIT(21) -+#define B_AX_FORCE_MACID_CCA_TH_EN_VALUE BIT(20) -+#define B_AX_FORCE_BT_GRANT_EN BIT(19) -+#define B_AX_FORCE_BT_GRANT_VALUE BIT(18) -+#define B_AX_FORCE_RX_LTE_EN BIT(17) -+#define B_AX_FORCE_RX_LTE_VALUE BIT(16) -+#define B_AX_FORCE_TXBF_EN_EN BIT(15) -+#define B_AX_FORCE_TXBF_EN_VALUE BIT(14) -+#define B_AX_FORCE_TXSC_EN BIT(13) -+#define B_AX_FORCE_TXSC_VALUE_MASK GENMASK(12, 9) -+#define B_AX_FORCE_NTX_EN BIT(6) -+#define B_AX_FORCE_NTX_VALUE BIT(5) -+#define B_AX_FORCE_PWR_MODE_EN BIT(3) -+#define B_AX_FORCE_PWR_MODE_VALUE_MASK GENMASK(2, 0) -+ - #define R_AX_PWR_UL_TB_CTRL 0xD288 - #define B_AX_PWR_UL_TB_CTRL_EN BIT(31) - #define R_AX_PWR_UL_TB_1T 0xD28C ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c -@@ -1442,6 +1442,9 @@ static void rtw8851b_bb_sethw(struct rtw - rtw8851b_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); - rtw8851b_bb_gpio_init(rtwdev); - -+ rtw89_write32_clr(rtwdev, R_AX_PWR_NORM_FORCE1, B_AX_FORCE_NTX_VALUE); -+ rtw89_write32_set(rtwdev, R_AX_PWR_NORM_FORCE1, B_AX_FORCE_NTX_EN); -+ - /* read these registers after loading BB parameters */ - gain->offset_base[RTW89_PHY_0] = - rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK); diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-142-wifi-rtw89-TX-power-stuffs-replace-confusing-naming-.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-142-wifi-rtw89-TX-power-stuffs-replace-confusing-naming-.patch deleted file mode 100644 index f80e79979..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-142-wifi-rtw89-TX-power-stuffs-replace-confusing-naming-.patch +++ /dev/null @@ -1,264 +0,0 @@ -From b4a283fb6227fa01cdfb4bec891ded3e32b4a287 Mon Sep 17 00:00:00 2001 -From: Zong-Zhe Yang -Date: Fri, 16 Jun 2023 14:05:23 +0800 -Subject: [PATCH 6/7] wifi: rtw89: TX power stuffs replace confusing naming of - _max with _num - -Some old declarations about TX power stuffs were named with confusing -`_max`. But, they mean "the number of". So we change them to be named -with `_num`. - -(No logic is changed.) - -Signed-off-by: Zong-Zhe Yang -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616060523.28396-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 34 ++++++++-------- - drivers/net/wireless/realtek/rtw89/phy.c | 40 +++++++++---------- - .../wireless/realtek/rtw89/rtw8851b_table.c | 2 +- - .../wireless/realtek/rtw89/rtw8851b_table.h | 2 +- - .../wireless/realtek/rtw89/rtw8852b_table.c | 2 +- - .../wireless/realtek/rtw89/rtw8852b_table.h | 2 +- - .../wireless/realtek/rtw89/rtw8852c_table.c | 2 +- - .../wireless/realtek/rtw89/rtw8852c_table.h | 2 +- - 8 files changed, 43 insertions(+), 43 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -251,7 +251,7 @@ enum rtw89_band { - RTW89_BAND_2G = 0, - RTW89_BAND_5G = 1, - RTW89_BAND_6G = 2, -- RTW89_BAND_MAX, -+ RTW89_BAND_NUM, - }; - - enum rtw89_hw_rate { -@@ -434,27 +434,27 @@ enum rtw89_rate_section { - RTW89_RS_MCS, /* for HT/VHT/HE */ - RTW89_RS_HEDCM, - RTW89_RS_OFFSET, -- RTW89_RS_MAX, -+ RTW89_RS_NUM, - RTW89_RS_LMT_NUM = RTW89_RS_MCS + 1, - RTW89_RS_TX_SHAPE_NUM = RTW89_RS_OFDM + 1, - }; - --enum rtw89_rate_max { -- RTW89_RATE_CCK_MAX = 4, -- RTW89_RATE_OFDM_MAX = 8, -- RTW89_RATE_MCS_MAX = 12, -- RTW89_RATE_HEDCM_MAX = 4, /* for HEDCM MCS0/1/3/4 */ -- RTW89_RATE_OFFSET_MAX = 5, /* for HE(HEDCM)/VHT/HT/OFDM/CCK offset */ -+enum rtw89_rate_num { -+ RTW89_RATE_CCK_NUM = 4, -+ RTW89_RATE_OFDM_NUM = 8, -+ RTW89_RATE_MCS_NUM = 12, -+ RTW89_RATE_HEDCM_NUM = 4, /* for HEDCM MCS0/1/3/4 */ -+ RTW89_RATE_OFFSET_NUM = 5, /* for HE(HEDCM)/VHT/HT/OFDM/CCK offset */ - }; - - enum rtw89_nss { - RTW89_NSS_1 = 0, - RTW89_NSS_2 = 1, - /* HE DCM only support 1ss and 2ss */ -- RTW89_NSS_HEDCM_MAX = RTW89_NSS_2 + 1, -+ RTW89_NSS_HEDCM_NUM = RTW89_NSS_2 + 1, - RTW89_NSS_3 = 2, - RTW89_NSS_4 = 3, -- RTW89_NSS_MAX, -+ RTW89_NSS_NUM, - }; - - enum rtw89_ntx { -@@ -512,11 +512,11 @@ enum rtw89_fw_pkt_ofld_type { - }; - - struct rtw89_txpwr_byrate { -- s8 cck[RTW89_RATE_CCK_MAX]; -- s8 ofdm[RTW89_RATE_OFDM_MAX]; -- s8 mcs[RTW89_NSS_MAX][RTW89_RATE_MCS_MAX]; -- s8 hedcm[RTW89_NSS_HEDCM_MAX][RTW89_RATE_HEDCM_MAX]; -- s8 offset[RTW89_RATE_OFFSET_MAX]; -+ s8 cck[RTW89_RATE_CCK_NUM]; -+ s8 ofdm[RTW89_RATE_OFDM_NUM]; -+ s8 mcs[RTW89_NSS_NUM][RTW89_RATE_MCS_NUM]; -+ s8 hedcm[RTW89_NSS_HEDCM_NUM][RTW89_RATE_HEDCM_NUM]; -+ s8 offset[RTW89_RATE_OFFSET_NUM]; - }; - - enum rtw89_bandwidth_section_num { -@@ -3815,7 +3815,7 @@ struct rtw89_power_trim_info { - - struct rtw89_regd { - char alpha2[3]; -- u8 txpwr_regd[RTW89_BAND_MAX]; -+ u8 txpwr_regd[RTW89_BAND_NUM]; - }; - - struct rtw89_regulatory_info { -@@ -4111,7 +4111,7 @@ struct rtw89_dev { - bool is_bt_iqk_timeout; - - struct rtw89_fem_info fem; -- struct rtw89_txpwr_byrate byr[RTW89_BAND_MAX]; -+ struct rtw89_txpwr_byrate byr[RTW89_BAND_NUM]; - struct rtw89_tssi_info tssi; - struct rtw89_power_trim_info pwr_trim; - ---- a/drivers/net/wireless/realtek/rtw89/phy.c -+++ b/drivers/net/wireless/realtek/rtw89/phy.c -@@ -1494,19 +1494,19 @@ void rtw89_phy_write_reg3_tbl(struct rtw - } - EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl); - --static const u8 rtw89_rs_idx_max[] = { -- [RTW89_RS_CCK] = RTW89_RATE_CCK_MAX, -- [RTW89_RS_OFDM] = RTW89_RATE_OFDM_MAX, -- [RTW89_RS_MCS] = RTW89_RATE_MCS_MAX, -- [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_MAX, -- [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_MAX, -+static const u8 rtw89_rs_idx_num[] = { -+ [RTW89_RS_CCK] = RTW89_RATE_CCK_NUM, -+ [RTW89_RS_OFDM] = RTW89_RATE_OFDM_NUM, -+ [RTW89_RS_MCS] = RTW89_RATE_MCS_NUM, -+ [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_NUM, -+ [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_NUM, - }; - --static const u8 rtw89_rs_nss_max[] = { -+static const u8 rtw89_rs_nss_num[] = { - [RTW89_RS_CCK] = 1, - [RTW89_RS_OFDM] = 1, -- [RTW89_RS_MCS] = RTW89_NSS_MAX, -- [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_MAX, -+ [RTW89_RS_MCS] = RTW89_NSS_NUM, -+ [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_NUM, - [RTW89_RS_OFFSET] = 1, - }; - -@@ -1519,9 +1519,9 @@ static const u8 _byr_of_rs[] = { - }; - - #define _byr_seek(rs, raw) ((s8 *)(raw) + _byr_of_rs[rs]) --#define _byr_idx(rs, nss, idx) ((nss) * rtw89_rs_idx_max[rs] + (idx)) -+#define _byr_idx(rs, nss, idx) ((nss) * rtw89_rs_idx_num[rs] + (idx)) - #define _byr_chk(rs, nss, idx) \ -- ((nss) < rtw89_rs_nss_max[rs] && (idx) < rtw89_rs_idx_max[rs]) -+ ((nss) < rtw89_rs_nss_num[rs] && (idx) < rtw89_rs_idx_num[rs]) - - void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, - const struct rtw89_txpwr_table *tbl) -@@ -2084,19 +2084,19 @@ void rtw89_phy_set_txpwr_byrate(struct r - rtw89_debug(rtwdev, RTW89_DBG_TXPWR, - "[TXPWR] set txpwr byrate with ch=%d\n", ch); - -- BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_CCK] % 4); -- BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_OFDM] % 4); -- BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_MCS] % 4); -- BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_num[RTW89_RS_CCK] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_num[RTW89_RS_OFDM] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_num[RTW89_RS_MCS] % 4); -+ BUILD_BUG_ON(rtw89_rs_idx_num[RTW89_RS_HEDCM] % 4); - - addr = R_AX_PWR_BY_RATE; - for (cur.nss = 0; cur.nss < max_nss_num; cur.nss++) { - for (i = 0; i < ARRAY_SIZE(rs); i++) { -- if (cur.nss >= rtw89_rs_nss_max[rs[i]]) -+ if (cur.nss >= rtw89_rs_nss_num[rs[i]]) - continue; - - cur.rs = rs[i]; -- for (cur.idx = 0; cur.idx < rtw89_rs_idx_max[rs[i]]; -+ for (cur.idx = 0; cur.idx < rtw89_rs_idx_num[rs[i]]; - cur.idx++) { - v[cur.idx % 4] = - rtw89_phy_read_txpwr_byrate(rtwdev, -@@ -2129,15 +2129,15 @@ void rtw89_phy_set_txpwr_offset(struct r - .rs = RTW89_RS_OFFSET, - }; - u8 band = chan->band_type; -- s8 v[RTW89_RATE_OFFSET_MAX] = {}; -+ s8 v[RTW89_RATE_OFFSET_NUM] = {}; - u32 val; - - rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); - -- for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) -+ for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_NUM; desc.idx++) - v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); - -- BUILD_BUG_ON(RTW89_RATE_OFFSET_MAX != 5); -+ BUILD_BUG_ON(RTW89_RATE_OFFSET_NUM != 5); - val = FIELD_PREP(GENMASK(3, 0), v[0]) | - FIELD_PREP(GENMASK(7, 4), v[1]) | - FIELD_PREP(GENMASK(11, 8), v[2]) | ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c -@@ -3321,7 +3321,7 @@ static const s8 _txpwr_track_delta_swing - 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4 - }; - --const u8 rtw89_8851b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+const u8 rtw89_8851b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM] = { - [0][0][RTW89_ACMA] = 0, - [0][0][RTW89_CN] = 0, ---- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.h -@@ -13,7 +13,7 @@ extern const struct rtw89_phy_table rtw8 - extern const struct rtw89_phy_table rtw89_8851b_phy_nctl_table; - extern const struct rtw89_txpwr_table rtw89_8851b_byr_table; - extern const struct rtw89_txpwr_track_cfg rtw89_8851b_trk_cfg; --extern const u8 rtw89_8851b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+extern const u8 rtw89_8851b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM]; - extern const struct rtw89_rfe_parms rtw89_8851b_dflt_parms; - extern const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[]; ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c -@@ -14666,7 +14666,7 @@ static const s8 _txpwr_track_delta_swing - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - --const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+const u8 rtw89_8852b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM] = { - [0][0][RTW89_ACMA] = 0, - [0][0][RTW89_CHILE] = 0, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h -@@ -14,7 +14,7 @@ extern const struct rtw89_phy_table rtw8 - extern const struct rtw89_phy_table rtw89_8852b_phy_nctl_table; - extern const struct rtw89_txpwr_table rtw89_8852b_byr_table; - extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg; --extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM]; - extern const struct rtw89_rfe_parms rtw89_8852b_dflt_parms; - ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c -@@ -31525,7 +31525,7 @@ static const s8 _txpwr_track_delta_swing - 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5 - }; - --const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+const u8 rtw89_8852c_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM] = { - [0][0][RTW89_ACMA] = 0, - [0][0][RTW89_CHILE] = 0, ---- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h -+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.h -@@ -15,7 +15,7 @@ extern const struct rtw89_phy_table rtw8 - extern const struct rtw89_txpwr_table rtw89_8852c_byr_table; - extern const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table; - extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg; --extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] -+extern const u8 rtw89_8852c_tx_shape[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM] - [RTW89_REGD_NUM]; - extern const struct rtw89_rfe_parms rtw89_8852c_dflt_parms; - diff --git a/package/kernel/mac80211/patches/rtl/202-v6.4-143-wifi-rtw89-use-struct-to-parse-firmware-header.patch b/package/kernel/mac80211/patches/rtl/202-v6.4-143-wifi-rtw89-use-struct-to-parse-firmware-header.patch deleted file mode 100644 index 6cffbafdf..000000000 --- a/package/kernel/mac80211/patches/rtl/202-v6.4-143-wifi-rtw89-use-struct-to-parse-firmware-header.patch +++ /dev/null @@ -1,263 +0,0 @@ -From f072eb39e4f2c1df60d8641f6260f11a42366abc Mon Sep 17 00:00:00 2001 -From: Ping-Ke Shih -Date: Fri, 16 Jun 2023 14:06:01 +0800 -Subject: [PATCH 7/7] wifi: rtw89: use struct to parse firmware header - -A firmware contains basic header, sections and optional dynamic header. -Define them by a struct, so it will be easier to understand the layout, -and also simply access these elements. - -Signed-off-by: Ping-Ke Shih -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20230616060601.28460-1-pkshih@realtek.com ---- - drivers/net/wireless/realtek/rtw89/core.h | 8 +- - drivers/net/wireless/realtek/rtw89/fw.c | 58 +++++++------ - drivers/net/wireless/realtek/rtw89/fw.h | 101 ++++++++++++---------- - 3 files changed, 87 insertions(+), 80 deletions(-) - ---- a/drivers/net/wireless/realtek/rtw89/core.h -+++ b/drivers/net/wireless/realtek/rtw89/core.h -@@ -3387,10 +3387,10 @@ struct rtw89_fw_suit { - (mfw_hdr)->ver.idx) - - #define RTW89_FW_HDR_VER_CODE(fw_hdr) \ -- RTW89_FW_VER_CODE(GET_FW_HDR_MAJOR_VERSION(fw_hdr), \ -- GET_FW_HDR_MINOR_VERSION(fw_hdr), \ -- GET_FW_HDR_SUBVERSION(fw_hdr), \ -- GET_FW_HDR_SUBINDEX(fw_hdr)) -+ RTW89_FW_VER_CODE(le32_get_bits((fw_hdr)->w1, FW_HDR_W1_MAJOR_VERSION), \ -+ le32_get_bits((fw_hdr)->w1, FW_HDR_W1_MINOR_VERSION), \ -+ le32_get_bits((fw_hdr)->w1, FW_HDR_W1_SUBVERSION), \ -+ le32_get_bits((fw_hdr)->w1, FW_HDR_W1_SUBINDEX)) - - struct rtw89_fw_req_info { - const struct firmware *firmware; ---- a/drivers/net/wireless/realtek/rtw89/fw.c -+++ b/drivers/net/wireless/realtek/rtw89/fw.c -@@ -89,9 +89,11 @@ int rtw89_fw_check_rdy(struct rtw89_dev - static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, - struct rtw89_fw_bin_info *info) - { -+ const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw; - struct rtw89_fw_hdr_section_info *section_info; -+ const struct rtw89_fw_dynhdr_hdr *fwdynhdr; -+ const struct rtw89_fw_hdr_section *section; - const u8 *fw_end = fw + len; -- const u8 *fwdynhdr; - const u8 *bin; - u32 base_hdr_len; - u32 mssc_len = 0; -@@ -100,16 +102,15 @@ static int rtw89_fw_hdr_parser(struct rt - if (!info) - return -EINVAL; - -- info->section_num = GET_FW_HDR_SEC_NUM(fw); -- base_hdr_len = RTW89_FW_HDR_SIZE + -- info->section_num * RTW89_FW_SECTION_HDR_SIZE; -- info->dynamic_hdr_en = GET_FW_HDR_DYN_HDR(fw); -+ info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM); -+ base_hdr_len = struct_size(fw_hdr, sections, info->section_num); -+ info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); - - if (info->dynamic_hdr_en) { -- info->hdr_len = GET_FW_HDR_LEN(fw); -+ info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); - info->dynamic_hdr_len = info->hdr_len - base_hdr_len; -- fwdynhdr = fw + base_hdr_len; -- if (GET_FW_DYNHDR_LEN(fwdynhdr) != info->dynamic_hdr_len) { -+ fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len); -+ if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) { - rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n"); - return -EINVAL; - } -@@ -121,26 +122,27 @@ static int rtw89_fw_hdr_parser(struct rt - bin = fw + info->hdr_len; - - /* jump to section header */ -- fw += RTW89_FW_HDR_SIZE; - section_info = info->section_info; - for (i = 0; i < info->section_num; i++) { -- section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw); -+ section = &fw_hdr->sections[i]; -+ section_info->type = -+ le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); - if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { -- section_info->mssc = GET_FWSECTION_HDR_MSSC(fw); -+ section_info->mssc = -+ le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); - mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; - } else { - section_info->mssc = 0; - } - -- section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); -- if (GET_FWSECTION_HDR_CHECKSUM(fw)) -+ section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); -+ if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) - section_info->len += FWDL_SECTION_CHKSUM_LEN; -- section_info->redl = GET_FWSECTION_HDR_REDL(fw); -+ section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); - section_info->dladdr = -- GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff; -+ le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; - section_info->addr = bin; - bin += section_info->len; -- fw += RTW89_FW_SECTION_HDR_SIZE; - section_info++; - } - -@@ -195,18 +197,18 @@ static void rtw89_fw_update_ver(struct r - enum rtw89_fw_type type, - struct rtw89_fw_suit *fw_suit) - { -- const u8 *hdr = fw_suit->data; -+ const struct rtw89_fw_hdr *hdr = (const struct rtw89_fw_hdr *)fw_suit->data; - -- fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr); -- fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr); -- fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr); -- fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr); -- fw_suit->build_year = GET_FW_HDR_YEAR(hdr); -- fw_suit->build_mon = GET_FW_HDR_MONTH(hdr); -- fw_suit->build_date = GET_FW_HDR_DATE(hdr); -- fw_suit->build_hour = GET_FW_HDR_HOUR(hdr); -- fw_suit->build_min = GET_FW_HDR_MIN(hdr); -- fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr); -+ fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); -+ fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); -+ fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); -+ fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); -+ fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); -+ fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); -+ fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); -+ fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); -+ fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); -+ fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); - - rtw89_info(rtwdev, - "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n", ---- a/drivers/net/wireless/realtek/rtw89/fw.h -+++ b/drivers/net/wireless/realtek/rtw89/fw.h -@@ -528,50 +528,58 @@ static inline void RTW89_SET_EDCA_PARAM( - #define FWDL_SECURITY_SECTION_TYPE 9 - #define FWDL_SECURITY_SIGLEN 512 - --#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) --#define GET_FWSECTION_HDR_SECTIONTYPE(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(27, 24)) --#define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0)) --#define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28)) --#define GET_FWSECTION_HDR_REDL(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29)) --#define GET_FWSECTION_HDR_MSSC(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 2), GENMASK(31, 0)) -- --#define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0)) --#define GET_FW_HDR_MINOR_VERSION(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(15, 8)) --#define GET_FW_HDR_SUBVERSION(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 16)) --#define GET_FW_HDR_SUBINDEX(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(31, 24)) --#define GET_FW_HDR_LEN(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 3), GENMASK(23, 16)) --#define GET_FW_HDR_MONTH(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(7, 0)) --#define GET_FW_HDR_DATE(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(15, 8)) --#define GET_FW_HDR_HOUR(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(23, 16)) --#define GET_FW_HDR_MIN(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(31, 24)) --#define GET_FW_HDR_YEAR(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 5), GENMASK(31, 0)) --#define GET_FW_HDR_SEC_NUM(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 6), GENMASK(15, 8)) --#define GET_FW_HDR_DYN_HDR(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 7), BIT(16)) --#define GET_FW_HDR_CMD_VERSERION(fwhdr) \ -- le32_get_bits(*((const __le32 *)(fwhdr) + 7), GENMASK(31, 24)) -- --#define GET_FW_DYNHDR_LEN(fwdynhdr) \ -- le32_get_bits(*((const __le32 *)(fwdynhdr)), GENMASK(31, 0)) --#define GET_FW_DYNHDR_COUNT(fwdynhdr) \ -- le32_get_bits(*((const __le32 *)(fwdynhdr) + 1), GENMASK(31, 0)) -+struct rtw89_fw_dynhdr_sec { -+ __le32 w0; -+ u8 content[]; -+} __packed; -+ -+struct rtw89_fw_dynhdr_hdr { -+ __le32 hdr_len; -+ __le32 setcion_count; -+ /* struct rtw89_fw_dynhdr_sec (nested flexible structures) */ -+} __packed; -+ -+struct rtw89_fw_hdr_section { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+ __le32 w3; -+} __packed; -+ -+#define FWSECTION_HDR_W0_DL_ADDR GENMASK(31, 0) -+#define FWSECTION_HDR_W1_METADATA GENMASK(31, 24) -+#define FWSECTION_HDR_W1_SECTIONTYPE GENMASK(27, 24) -+#define FWSECTION_HDR_W1_SEC_SIZE GENMASK(23, 0) -+#define FWSECTION_HDR_W1_CHECKSUM BIT(28) -+#define FWSECTION_HDR_W1_REDL BIT(29) -+#define FWSECTION_HDR_W2_MSSC GENMASK(31, 0) -+ -+struct rtw89_fw_hdr { -+ __le32 w0; -+ __le32 w1; -+ __le32 w2; -+ __le32 w3; -+ __le32 w4; -+ __le32 w5; -+ __le32 w6; -+ __le32 w7; -+ struct rtw89_fw_hdr_section sections[]; -+ /* struct rtw89_fw_dynhdr_hdr (optional) */ -+} __packed; -+ -+#define FW_HDR_W1_MAJOR_VERSION GENMASK(7, 0) -+#define FW_HDR_W1_MINOR_VERSION GENMASK(15, 8) -+#define FW_HDR_W1_SUBVERSION GENMASK(23, 16) -+#define FW_HDR_W1_SUBINDEX GENMASK(31, 24) -+#define FW_HDR_W3_LEN GENMASK(23, 16) -+#define FW_HDR_W4_MONTH GENMASK(7, 0) -+#define FW_HDR_W4_DATE GENMASK(15, 8) -+#define FW_HDR_W4_HOUR GENMASK(23, 16) -+#define FW_HDR_W4_MIN GENMASK(31, 24) -+#define FW_HDR_W5_YEAR GENMASK(31, 0) -+#define FW_HDR_W6_SEC_NUM GENMASK(15, 8) -+#define FW_HDR_W7_DYN_HDR BIT(16) -+#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24) - - static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val) - { -@@ -3392,9 +3400,6 @@ struct rtw89_h2c_ofld { - #define RTW89_H2C_OFLD_W0_TX_TP GENMASK(17, 8) - #define RTW89_H2C_OFLD_W0_RX_TP GENMASK(27, 18) - --#define RTW89_FW_HDR_SIZE 32 --#define RTW89_FW_SECTION_HDR_SIZE 16 -- - #define RTW89_MFW_SIG 0xFF - - struct rtw89_mfw_info { -@@ -3428,7 +3433,7 @@ struct fwcmd_hdr { - - union rtw89_compat_fw_hdr { - struct rtw89_mfw_hdr mfw_hdr; -- u8 fw_hdr[RTW89_FW_HDR_SIZE]; -+ struct rtw89_fw_hdr fw_hdr; - }; - - static inline u32 rtw89_compat_fw_hdr_ver_code(const void *fw_buf) diff --git a/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch b/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch new file mode 100644 index 000000000..f7391a580 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch @@ -0,0 +1,219 @@ +From: Felix Fietkau +Date: Fri, 30 Jun 2023 13:11:51 +0200 +Subject: [PATCH] mac80211: split mesh fast tx cache into + local/proxied/forwarded + +Depending on the origin of the packets (and their SA), 802.11 + mesh headers +could be filled in differently. In order to properly deal with that, add a +new field to the lookup key, indicating the type (local, proxied or +forwarded). This can fix spurious packet drop issues that depend on the order +in which nodes/hosts communicate with each other. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -703,6 +703,9 @@ bool ieee80211_mesh_xmit_fast(struct iee + struct sk_buff *skb, u32 ctrl_flags) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ struct ieee80211_mesh_fast_tx_key key = { ++ .type = MESH_FAST_TX_TYPE_LOCAL ++ }; + struct ieee80211_mesh_fast_tx *entry; + struct ieee80211s_hdr *meshhdr; + u8 sa[ETH_ALEN] __aligned(2); +@@ -738,7 +741,10 @@ bool ieee80211_mesh_xmit_fast(struct iee + return false; + } + +- entry = mesh_fast_tx_get(sdata, skb->data); ++ ether_addr_copy(key.addr, skb->data); ++ if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr)) ++ key.type = MESH_FAST_TX_TYPE_PROXIED; ++ entry = mesh_fast_tx_get(sdata, &key); + if (!entry) + return false; + +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -133,9 +133,33 @@ struct mesh_path { + #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ + + /** ++ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type ++ * ++ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA ++ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged) ++ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point ++ */ ++enum ieee80211_mesh_fast_tx_type { ++ MESH_FAST_TX_TYPE_LOCAL, ++ MESH_FAST_TX_TYPE_PROXIED, ++ MESH_FAST_TX_TYPE_FORWARDED, ++}; ++ ++/** ++ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key ++ * ++ * @addr: The Ethernet DA for this entry ++ * @type: cache entry type ++ */ ++struct ieee80211_mesh_fast_tx_key { ++ u8 addr[ETH_ALEN] __aligned(2); ++ enum ieee80211_mesh_fast_tx_type type; ++}; ++ ++/** + * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry + * @rhash: rhashtable pointer +- * @addr_key: The Ethernet DA which is the key for this entry ++ * @key: the lookup key for this cache entry + * @fast_tx: base fast_tx data + * @hdr: cached mesh and rfc1042 headers + * @hdrlen: length of mesh + rfc1042 +@@ -146,7 +170,7 @@ struct mesh_path { + */ + struct ieee80211_mesh_fast_tx { + struct rhash_head rhash; +- u8 addr_key[ETH_ALEN] __aligned(2); ++ struct ieee80211_mesh_fast_tx_key key; + + struct ieee80211_fast_tx fast_tx; + u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; +@@ -329,7 +353,8 @@ void mesh_path_tx_root_frame(struct ieee + + bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); + struct ieee80211_mesh_fast_tx * +-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); ++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_mesh_fast_tx_key *key); + bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 ctrl_flags); + void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -36,8 +36,8 @@ static const struct rhashtable_params me + static const struct rhashtable_params fast_tx_rht_params = { + .nelem_hint = 10, + .automatic_shrinking = true, +- .key_len = ETH_ALEN, +- .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key), ++ .key_len = sizeof(struct ieee80211_mesh_fast_tx_key), ++ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, key), + .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash), + .hashfn = mesh_table_hash, + }; +@@ -426,20 +426,21 @@ static void mesh_fast_tx_entry_free(stru + } + + struct ieee80211_mesh_fast_tx * +-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) ++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_mesh_fast_tx_key *key) + { + struct ieee80211_mesh_fast_tx *entry; + struct mesh_tx_cache *cache; + + cache = &sdata->u.mesh.tx_cache; +- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); ++ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params); + if (!entry) + return NULL; + + if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || + mpath_expired(entry->mpath)) { + spin_lock_bh(&cache->walk_lock); +- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); ++ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params); + if (entry) + mesh_fast_tx_entry_free(cache, entry); + spin_unlock_bh(&cache->walk_lock); +@@ -484,18 +485,24 @@ void mesh_fast_tx_cache(struct ieee80211 + if (!sta) + return; + ++ build.key.type = MESH_FAST_TX_TYPE_LOCAL; + if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { + /* This is required to keep the mppath alive */ + mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); + if (!mppath) + return; + build.mppath = mppath; ++ if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr)) ++ build.key.type = MESH_FAST_TX_TYPE_PROXIED; + } else if (ieee80211_has_a4(hdr->frame_control)) { + mppath = mpath; + } else { + return; + } + ++ if (!ether_addr_equal(hdr->addr4, sdata->vif.addr)) ++ build.key.type = MESH_FAST_TX_TYPE_FORWARDED; ++ + /* rate limit, in case fast xmit can't be enabled */ + if (mppath->fast_tx_check == jiffies) + return; +@@ -542,7 +549,7 @@ void mesh_fast_tx_cache(struct ieee80211 + } + } + +- memcpy(build.addr_key, mppath->dst, ETH_ALEN); ++ memcpy(build.key.addr, mppath->dst, ETH_ALEN); + build.timestamp = jiffies; + build.fast_tx.band = info->band; + build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3); +@@ -644,13 +651,19 @@ void mesh_fast_tx_flush_addr(struct ieee + const u8 *addr) + { + struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; ++ struct ieee80211_mesh_fast_tx_key key = {}; + struct ieee80211_mesh_fast_tx *entry; ++ int i; + ++ ether_addr_copy(key.addr, addr); + cache = &sdata->u.mesh.tx_cache; + spin_lock_bh(&cache->walk_lock); +- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); +- if (entry) +- mesh_fast_tx_entry_free(cache, entry); ++ for (i = MESH_FAST_TX_TYPE_LOCAL; i < MESH_FAST_TX_TYPE_FORWARDED; i++) { ++ key.type = i; ++ entry = rhashtable_lookup(&cache->rht, &key, fast_tx_rht_params); ++ if (entry) ++ mesh_fast_tx_entry_free(cache, entry); ++ } + spin_unlock_bh(&cache->walk_lock); + } + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2726,7 +2726,10 @@ ieee80211_rx_mesh_fast_forward(struct ie + struct sk_buff *skb, int hdrlen) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee80211_mesh_fast_tx *entry = NULL; ++ struct ieee80211_mesh_fast_tx_key key = { ++ .type = MESH_FAST_TX_TYPE_FORWARDED ++ }; ++ struct ieee80211_mesh_fast_tx *entry; + struct ieee80211s_hdr *mesh_hdr; + struct tid_ampdu_tx *tid_tx; + struct sta_info *sta; +@@ -2735,9 +2738,13 @@ ieee80211_rx_mesh_fast_forward(struct ie + + mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); + if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) +- entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1); ++ ether_addr_copy(key.addr, mesh_hdr->eaddr1); + else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) +- entry = mesh_fast_tx_get(sdata, skb->data); ++ ether_addr_copy(key.addr, skb->data); ++ else ++ return false; ++ ++ entry = mesh_fast_tx_get(sdata, &key); + if (!entry) + return false; + diff --git a/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch deleted file mode 100644 index e084773fd..000000000 --- a/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch +++ /dev/null @@ -1,36 +0,0 @@ -From cdf461888f900c3a149b10a04d72b4a590ecdec3 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Tue, 16 May 2023 23:11:32 +0200 -Subject: [PATCH] mac80211: always use mac80211 loss detection - -ath10k does not report excessive loss in case of broken block-ack -sessions. The loss is communicated to the host-os, but ath10k does not -trigger a low-ack events by itself. - -The mac80211 framework for loss detection however detects this -circumstance well in case of ath10k. So use it regardless of ath10k's -own loss detection mechanism. - -Patching this in mac80211 does allow this hack to be used with any -flavor of ath10k/ath11k. - -Signed-off-by: David Bauer ---- - net/mac80211/status.c | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -794,12 +794,6 @@ static void ieee80211_lost_packet(struct - unsigned long pkt_time = STA_LOST_PKT_TIME; - unsigned int pkt_thr = STA_LOST_PKT_THRESHOLD; - -- /* If driver relies on its own algorithm for station kickout, skip -- * mac80211 packet loss mechanism. -- */ -- if (ieee80211_hw_check(&sta->local->hw, REPORTS_LOW_ACK)) -- return; -- - /* This packet was aggregated but doesn't carry status info */ - if ((info->flags & IEEE80211_TX_CTL_AMPDU) && - !(info->flags & IEEE80211_TX_STAT_AMPDU)) diff --git a/package/kernel/mac80211/patches/subsys/401-mac80211-allow-vht-on-2g.patch b/package/kernel/mac80211/patches/subsys/401-mac80211-allow-vht-on-2g.patch new file mode 100644 index 000000000..5d8742ba9 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/401-mac80211-allow-vht-on-2g.patch @@ -0,0 +1,36 @@ +--- a/net/mac80211/vht.c ++++ b/net/mac80211/vht.c +@@ -135,7 +135,8 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru + have_80mhz = false; + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED | +- IEEE80211_CHAN_NO_80MHZ)) ++ IEEE80211_CHAN_NO_80MHZ) & ++ (sband->band != NL80211_BAND_2GHZ)) + continue; + + have_80mhz = true; +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1955,7 +1955,8 @@ static int ieee80211_build_preq_ies_band + /* Check if any channel in this sband supports at least 80 MHz */ + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED | +- IEEE80211_CHAN_NO_80MHZ)) ++ IEEE80211_CHAN_NO_80MHZ) & ++ (sband->band != NL80211_BAND_2GHZ)) + continue; + + have_80mhz = true; +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4744,7 +4744,8 @@ static int ieee80211_prep_channel(struct + have_80mhz = false; + for (i = 0; i < sband->n_channels; i++) { + if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED | +- IEEE80211_CHAN_NO_80MHZ)) ++ IEEE80211_CHAN_NO_80MHZ) & ++ (sband->band != NL80211_BAND_2GHZ)) + continue; + + have_80mhz = true; diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 58a590682..bc5e7e76c 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -129,7 +129,7 @@ local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p +@@ -823,6 +823,7 @@ static const struct nla_policy nl80211_p [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, @@ -137,7 +137,7 @@ }; /* policy for the key attributes */ -@@ -3511,6 +3512,22 @@ static int nl80211_set_wiphy(struct sk_b +@@ -3535,6 +3536,22 @@ static int nl80211_set_wiphy(struct sk_b if (result) goto out; } diff --git a/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch b/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch new file mode 100644 index 000000000..2bc11efd0 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch @@ -0,0 +1,34 @@ +From: David Bauer +Date: Thu, 30 Nov 2023 07:32:52 +0100 +Subject: [PATCH] mac80211: avoid crashing on invalid band info + +Frequent crashes have been observed on MT7916 based platforms. While the +root of these crashes are currently unknown, they happen when decoding +rate information of connected STAs in AP mode. The rate-information is +associated with a band which is not available on the PHY. + +Check for this condition in order to avoid crashing the whole system. +This patch should be removed once the roout cause has been found and +fixed. + +Link: https://github.com/freifunk-gluon/gluon/issues/2980 + +Signed-off-by: David Bauer +--- + +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2422,6 +2422,13 @@ static void sta_stats_decode_rate(struct + + sband = local->hw.wiphy->bands[band]; + ++ if (!sband) { ++ wiphy_warn(local->hw.wiphy, ++ "Invalid band %d\n", ++ band); ++ break; ++ } ++ + if (WARN_ON_ONCE(!sband->bitrates)) + break; + diff --git a/package/kernel/mac80211/patches/subsys/800-rework-eth_hw_addr_set.patch b/package/kernel/mac80211/patches/subsys/800-rework-eth_hw_addr_set.patch new file mode 100644 index 000000000..20f857f2d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/800-rework-eth_hw_addr_set.patch @@ -0,0 +1,11 @@ +--- a/backport-include/linux/etherdevice.h ++++ b/backport-include/linux/etherdevice.h +@@ -39,7 +39,7 @@ static inline void u64_to_ether_addr(u64 + } + #endif /* LINUX_VERSION_IS_LESS(4,11,0) */ + +-#if LINUX_VERSION_IS_LESS(5,15,0) ++#if LINUX_VERSION_IS_LESS(5,4,0) + /** + * eth_hw_addr_set - Assign Ethernet address to a net_device + * @dev: pointer to net_device structure diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk index 40af2f0f4..2f1fa8376 100644 --- a/package/kernel/mac80211/realtek.mk +++ b/package/kernel/mac80211/realtek.mk @@ -1,9 +1,7 @@ PKG_DRIVERS += \ rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \ rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8723bs rtl8821ae \ - rtl8xxxu rtw88 rtw88-pci rtw88-usb rtw88-8821c rtw88-8822b rtw88-8822c \ - rtw88-8723d rtw88-8821ce rtw88-8821cu rtw88-8822be rtw88-8822bu \ - rtw88-8822ce rtw88-8822cu rtw88-8723de rtw89 + rtl8xxxu rtw88 config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI @@ -23,29 +21,11 @@ config-y += RTL8XXXU_UNTESTED config-$(call config_package,rtl8723bs) += RTL8723BS config-y += STAGING -config-$(call config_package,rtw88) += RTW88 RTW88_CORE -config-$(call config_package,rtw88-pci) += RTW88_PCI -config-$(call config_package,rtw88-usb) += RTW88_USB -config-$(call config_package,rtw88-8821c) += RTW88_8821C -config-$(call config_package,rtw88-8821ce) += RTW88_8821CE -config-$(call config_package,rtw88-8821cu) += RTW88_8821CU -config-$(call config_package,rtw88-8822b) += RTW88_8822B -config-$(call config_package,rtw88-8822be) += RTW88_8822BE -config-$(call config_package,rtw88-8822bu) += RTW88_8822BU -config-$(call config_package,rtw88-8822c) += RTW88_8822C -config-$(call config_package,rtw88-8822ce) += RTW88_8822CE -config-$(call config_package,rtw88-8822cu) += RTW88_8822CU -config-$(call config_package,rtw88-8723d) += RTW88_8723D -config-$(call config_package,rtw88-8723de) += RTW88_8723DE +config-$(call config_package,rtw88) += RTW88 RTW88_CORE RTW88_PCI +config-y += RTW88_8821CE RTW88_8822BE RTW88_8822CE RTW88_8723DE config-$(CONFIG_PACKAGE_RTW88_DEBUG) += RTW88_DEBUG config-$(CONFIG_PACKAGE_RTW88_DEBUGFS) += RTW88_DEBUGFS -config-$(call config_package,rtw89) += RTW89 RTW89_CORE RTW89_PCI -config-y += RTW89_8852AE RTW89_8852BE RTW89_8852CE -config-$(CONFIG_PACKAGE_RTW89_DEBUG) += RTW89_DEBUG -config-$(CONFIG_PACKAGE_RTW89_DEBUGFS) += RTW89_DEBUGFS -config-$(CONFIG_PACKAGE_RTW89_DEBUGMSG) += RTW89_DEBUGMSG - define KernelPackage/rtlwifi/config config PACKAGE_RTLWIFI_DEBUG bool "Realtek wireless debugging" @@ -58,7 +38,7 @@ endef define KernelPackage/rtlwifi $(call KernelPackage/mac80211/Default) TITLE:=Realtek common driver part - DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 + DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko HIDDEN:=1 endef @@ -188,121 +168,20 @@ endef define KernelPackage/rtw88 $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTW88 common part - DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko - AUTOLOAD:=$(call AutoProbe,rtw88_core) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-pci - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTW88 PCI chips support - DEPENDS+= @PCI_SUPPORT +kmod-rtw88 - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko - AUTOLOAD:=$(call AutoProbe,rtw88_pci) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-usb - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTW88 USB chips support - DEPENDS+= @USB_SUPPORT +kmod-rtw88 +kmod-usb-core - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_usb.ko - AUTOLOAD:=$(call AutoProbe,rtw88_usb) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-8821c - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8821C family support - DEPENDS+= +kmod-rtw88 +rtl8821ce-firmware +@DRIVER_11AC_SUPPORT - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821c.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8821c) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-8822b - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822B family support - DEPENDS+= +kmod-rtw88 +rtl8822be-firmware +@DRIVER_11AC_SUPPORT - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822b) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-8822c - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822C family support - DEPENDS+= +kmod-rtw88 +rtl8822ce-firmware +@DRIVER_11AC_SUPPORT - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822c) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-8723d - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8723D family support - DEPENDS+= +kmod-rtw88 +rtl8723de-firmware - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8723d) - HIDDEN:=1 -endef - -define KernelPackage/rtw88-8821ce - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8821CE support - DEPENDS+= +kmod-rtw88-pci +kmod-rtw88-8821c - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821ce.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8821ce) -endef - -define KernelPackage/rtw88-8821cu - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8821CU support - DEPENDS+= +kmod-rtw88-usb +kmod-rtw88-8821c - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821cu.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8821cu) -endef - -define KernelPackage/rtw88-8822be - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822BE support - DEPENDS+= +kmod-rtw88-pci +kmod-rtw88-8822b - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822be) -endef - -define KernelPackage/rtw88-8822bu - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822BU support - DEPENDS+= +kmod-rtw88-usb +kmod-rtw88-8822b - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822bu.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822bu) -endef - -define KernelPackage/rtw88-8822ce - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822CE support - DEPENDS+= +kmod-rtw88-pci +kmod-rtw88-8822c - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822ce) -endef - -define KernelPackage/rtw88-8822cu - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8822CU support - DEPENDS+= +kmod-rtw88-usb +kmod-rtw88-8822c - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822cu.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8822cu) -endef - -define KernelPackage/rtw88-8723de - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8723DE support - DEPENDS+= +kmod-rtw88-pci +kmod-rtw88-8723d - FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko - AUTOLOAD:=$(call AutoProbe,rtw88_8723) + TITLE:=Realtek RTL8821CE/RTL8822BE/RTL8822CE/RTL8723DE + DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT + FILES:=\ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821ce.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821c.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821ce rtw88_8822be rtw88_8822ce rtw88_8723de) endef define KernelPackage/rtl8723bs @@ -318,40 +197,3 @@ define KernelPackage/rtl8723bs/description on the 1st gen Intel Compute Stick, the CHIP and many other Intel Atom and ARM based devices. endef - -define KernelPackage/rtw89/config - config PACKAGE_RTW89_DEBUG - bool "Realtek wireless debugging (rtw89)" - depends on PACKAGE_kmod-rtw89 - help - Enable debugging output for rtw89 devices - - config PACKAGE_RTW89_DEBUGFS - bool "Enable rtw89 debugfs support" - select KERNEL_DEBUG_FS - depends on PACKAGE_kmod-rtw89 - help - Select this to see extensive information about - the internal state of rtw89 in debugfs. - config PACKAGE_RTW89_DEBUGMSG - bool "Realtek rtw89 debug message support" - depends on PACKAGE_kmod-rtw89 - help - Enable debug message support -endef - -define KernelPackage/rtw89 - $(call KernelPackage/mac80211/Default) - TITLE:=Realtek RTL8852AE/BE/CE - DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AX_SUPPORT +rtl8851be-firmware +rtl8852ae-firmware +rtl8852be-firmware +rtl8852ce-firmware - FILES:=\ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852a.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852ae.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852b.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852be.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852c.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_8852ce.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_core.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw89/rtw89_pci.ko - AUTOLOAD:=$(call AutoProbe,rtw89_8852ae rtw89_8852be rtw89_8852ce) -endef diff --git a/package/kernel/rtw88-usb/Makefile b/package/kernel/rtw88-usb/Makefile new file mode 100644 index 000000000..7afa41c7f --- /dev/null +++ b/package/kernel/rtw88-usb/Makefile @@ -0,0 +1,105 @@ +# +# Copyright (C) 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rtw88-usb +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2024-04-10 +PKG_SOURCE_URL:=https://github.com/lwfinger/rtw88.git +PKG_SOURCE_VERSION:=2e9f468009df592a51990d024928034e0af1c2b4 +PKG_MIRROR_HASH:=684b30e58d8b990bbe141baae00c48439f45c9f39faa6f552ffb18afb6594c74 + +PKG_BUILD_PARALLEL:=1 + +STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/rtw88-default + SUBMENU:=Wireless Drivers + TITLE:=Realtek rtw88 family usb driver + DEPENDS:=+kmod-mac80211 +kmod-usb-core \ + +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +endef + +define KernelPackage/rtw88-usb + $(KernelPackage/rtw88-default) + HIDDEN:=1 + FILES:= \ + $(PKG_BUILD_DIR)/rtw_core.ko \ + $(PKG_BUILD_DIR)/rtw_usb.ko +endef + +define KernelPackage/rtl8723du + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8723DU support + DEPENDS+=+kmod-rtw88-usb +rtl8723du-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw_8723d.ko \ + $(PKG_BUILD_DIR)/rtw_8723du.ko + AUTOLOAD:=$(call AutoProbe,rtw_8723du) +endef + +define KernelPackage/rtl8821cu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8821CU support + DEPENDS+=+kmod-rtw88-usb +rtl8821ce-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw_8821c.ko \ + $(PKG_BUILD_DIR)/rtw_8821cu.ko + AUTOLOAD:=$(call AutoProbe,rtw_8821cu) +endef + +define KernelPackage/rtl8822bu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8822BU support + DEPENDS+=+kmod-rtw88-usb +rtl8822be-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw_8822b.ko \ + $(PKG_BUILD_DIR)/rtw_8822bu.ko + AUTOLOAD:=$(call AutoProbe,rtw_8822bu) +endef + +define KernelPackage/rtl8822cu + $(KernelPackage/rtw88-default) + TITLE:=Realtek RTL8822CU support + DEPENDS+=+kmod-rtw88-usb +rtl8822ce-firmware + FILES:= \ + $(PKG_BUILD_DIR)/rtw_8822c.ko \ + $(PKG_BUILD_DIR)/rtw_8822cu.ko + AUTOLOAD:=$(call AutoProbe,rtw_8822cu) +endef + +NOSTDINC_FLAGS := \ + $(KERNEL_NOSTDINC_FLAGS) \ + -I$(PKG_BUILD_DIR) \ + -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \ + -I$(STAGING_DIR)/usr/include/mac80211-backport \ + -I$(STAGING_DIR)/usr/include/mac80211/uapi \ + -I$(STAGING_DIR)/usr/include/mac80211 \ + -include backport/autoconf.h \ + -include backport/backport.h + +NOSTDINC_FLAGS+=-DBUILD_OPENWRT + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ + modules +endef + +$(eval $(call KernelPackage,rtw88-usb)) +$(eval $(call KernelPackage,rtl8723du)) +$(eval $(call KernelPackage,rtl8821cu)) +$(eval $(call KernelPackage,rtl8822bu)) +$(eval $(call KernelPackage,rtl8822cu)) diff --git a/package/kernel/rtw88-usb/patches/001-fix-merge-error.patch b/package/kernel/rtw88-usb/patches/001-fix-merge-error.patch new file mode 100644 index 000000000..4439c4f18 --- /dev/null +++ b/package/kernel/rtw88-usb/patches/001-fix-merge-error.patch @@ -0,0 +1,96 @@ +--- a/fw.c ++++ b/fw.c +@@ -1009,7 +1009,7 @@ static u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev, + if (rsvd_pkt->type != RSVD_PROBE_REQ) + continue; + if ((!ssid && !rsvd_pkt->ssid) || +- cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) ++ cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) + location = rsvd_pkt->page; + } + +--- a/mac.c ++++ b/mac.c +@@ -316,13 +316,6 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0)); + } + +- if (pwr_on && rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { +- if (chip->id == RTW_CHIP_TYPE_8822C || +- chip->id == RTW_CHIP_TYPE_8822B || +- chip->id == RTW_CHIP_TYPE_8821C) +- rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0)); +- } +- + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) + rtw_write32(rtwdev, REG_SDIO_HIMR, imr); + +@@ -956,18 +949,6 @@ static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev, + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); + } + +- /* reset firmware if still present */ +- if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && +- rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) { +- rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); +- } +- +- /* reset firmware if still present */ +- if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && +- rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) { +- rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); +- } +- + en_download_firmware_legacy(rtwdev, true); + ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size); + en_download_firmware_legacy(rtwdev, false); +--- a/main.c ++++ b/main.c +@@ -110,9 +110,7 @@ static const struct ieee80211_iface_limit rtw_iface_limits[] = { + }, + { + .max = 1, +- .types = BIT(NL80211_IFTYPE_AP) | +- BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) ++ .types = BIT(NL80211_IFTYPE_AP), + } + }; + +@@ -2124,11 +2122,6 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev) + dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n"); + } + +- if (!is_valid_ether_addr(efuse->addr)) { +- eth_random_addr(efuse->addr); +- dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n"); +- } +- + out_disable: + rtw_chip_efuse_disable(rtwdev); + +@@ -2361,9 +2354,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_ADHOC) | +- BIT(NL80211_IFTYPE_MESH_POINT) | +- BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO); ++ BIT(NL80211_IFTYPE_MESH_POINT); + hw->wiphy->available_antennas_tx = hal->antenna_tx; + hw->wiphy->available_antennas_rx = hal->antenna_rx; + +--- a/usb.c ++++ b/usb.c +@@ -93,11 +93,6 @@ static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len) + rtwdev->chip->id == RTW_CHIP_TYPE_8821C) + rtw_usb_reg_sec(rtwdev, addr, data); + +- if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C || +- rtwdev->chip->id == RTW_CHIP_TYPE_8822B || +- rtwdev->chip->id == RTW_CHIP_TYPE_8821C) +- rtw_usb_reg_sec(rtwdev, addr, data); +- + return le32_to_cpu(*data); + } + diff --git a/package/kernel/rtw88-usb/patches/101-wireless-6.1.patch b/package/kernel/rtw88-usb/patches/101-wireless-6.1.patch new file mode 100644 index 000000000..37a9bca9f --- /dev/null +++ b/package/kernel/rtw88-usb/patches/101-wireless-6.1.patch @@ -0,0 +1,432 @@ +--- a/bf.c ++++ b/bf.c +@@ -57,7 +57,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + } + + ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; +-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) && !defined(BUILD_OPENWRT) + vht_cap = &sta->vht_cap; + #else + vht_cap = &sta->deflink.vht_cap; +@@ -75,7 +75,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + ether_addr_copy(bfee->mac_addr, bssid); + bfee->role = RTW_BFEE_MU; + bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + bfee->aid = vif->cfg.aid; + #else + bfee->aid = bss_conf->aid; +--- a/fw.c ++++ b/fw.c +@@ -191,7 +191,7 @@ legacy: + si->ra_report.desc_rate = rate; + si->ra_report.bit_rate = bit_rate; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT) + sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(bit_rate); + #else + sta->max_rc_amsdu_len = get_max_amsdu_len(bit_rate); +@@ -726,7 +726,7 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT) + void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask) + #else +@@ -735,7 +735,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) + { + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + bool disable_pt = true; +-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) && !defined(BUILD_OPENWRT) + bool reset_ra_mask = true; + #endif + +@@ -1228,7 +1228,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, + + switch (rsvd_pkt->type) { + case RSVD_BEACON: +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL, 0); + #else + skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL); +@@ -1243,7 +1243,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, + break; + case RSVD_NULL: + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 17) +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT) + skb_new = ieee80211_nullfunc_get(hw, vif, -1, false); + #else + skb_new = ieee80211_nullfunc_get(hw, vif, false); +@@ -1254,7 +1254,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, + break; + case RSVD_QOS_NULL: + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 17) +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT) + skb_new = ieee80211_nullfunc_get(hw, vif, -1, true); + #else + skb_new = ieee80211_nullfunc_get(hw, vif, true); +--- a/fw.h ++++ b/fw.h +@@ -834,7 +834,7 @@ void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data); + + void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data); + void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT) + void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool reset_ra_mask); + #else +--- a/mac80211.c ++++ b/mac80211.c +@@ -365,7 +365,7 @@ static void rtw_conf_tx(struct rtw_dev *rtwdev, + static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf, +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + u64 changed) + #else + u32 changed) +@@ -383,7 +383,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, + + if (changed & BSS_CHANGED_ASSOC) { + rtw_vif_assoc_changed(rtwvif, conf); +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + if (vif->cfg.assoc) { + #else + if (conf->assoc) { +@@ -393,7 +393,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, + rtw_fw_download_rsvd_page(rtwdev); + rtw_send_rsvd_page_h2c(rtwdev); + rtw_fw_default_port(rtwdev, rtwvif); +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc); + #else + rtw_coex_media_status_notify(rtwdev, conf->assoc); +@@ -460,7 +460,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, + mutex_unlock(&rtwdev->mutex); + } + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + static int rtw_ops_start_ap(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +@@ -481,7 +481,7 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) + return 0; + } + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + static void rtw_ops_stop_ap(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +@@ -502,7 +502,7 @@ static void rtw_ops_stop_ap(struct ieee80211_hw *hw, + + static int rtw_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + unsigned int link_id, u16 ac, + #else + u16 ac, +@@ -731,7 +731,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw, + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, +- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0)) ++ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0)) || defined(BUILD_OPENWRT) + struct ieee80211_prep_tx_info *info) + #else + u16 duration) +--- a/main.c ++++ b/main.c +@@ -191,7 +191,7 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif) + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + if (vif->type == NL80211_IFTYPE_STATION) +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + if (vif->cfg.assoc) + #else + if (vif->bss_conf.assoc) +@@ -343,7 +343,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) + #else + if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc == 0) +@@ -572,7 +572,7 @@ EXPORT_SYMBOL(rtw_dump_reg); + void rtw_vif_assoc_changed(struct rtw_vif *rtwvif, + struct ieee80211_bss_conf *conf) + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + struct ieee80211_vif *vif = NULL; + + if (conf) +@@ -1000,7 +1000,7 @@ static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num) + static u64 get_vht_ra_mask(struct ieee80211_sta *sta) + { + u64 ra_mask = 0; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); + #else + u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); +@@ -1224,26 +1224,26 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + bool is_vht_enable = false; + bool is_support_sgi = false; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.vht_supported) { + #else + if (sta->vht_cap.vht_supported) { + #endif + is_vht_enable = true; + ra_mask |= get_vht_ra_mask(sta); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + #else + if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) + #endif + stbc_en = VHT_STBC_EN; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + #else + if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) + #endif + ldpc_en = VHT_LDPC_EN; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + } else if (sta->deflink.ht_cap.ht_supported) { + ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | + (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); +@@ -1266,20 +1266,20 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + + if (hal->current_band_type == RTW_BAND_5G) { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; + #else + ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; + #endif + ra_mask_bak = ra_mask; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.vht_supported) { + #else + if (sta->vht_cap.vht_supported) { + #endif + ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT; + wireless_set = WIRELESS_OFDM | WIRELESS_VHT; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + } else if (sta->deflink.ht_cap.ht_supported) { + #else + } else if (sta->ht_cap.ht_supported) { +@@ -1291,13 +1291,13 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + } + dm_info->rrsr_val_init = RRSR_INIT_5G; + } else if (hal->current_band_type == RTW_BAND_2G) { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; + #else + ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ]; + #endif + ra_mask_bak = ra_mask; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.vht_supported) { + #else + if (sta->vht_cap.vht_supported) { +@@ -1306,7 +1306,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + RA_MASK_OFDM_IN_VHT; + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | + WIRELESS_HT | WIRELESS_VHT; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + } else if (sta->deflink.ht_cap.ht_supported) { + #else + } else if (sta->ht_cap.ht_supported) { +@@ -1315,7 +1315,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + RA_MASK_OFDM_IN_HT_2G; + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | + WIRELESS_HT; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + } else if (sta->deflink.supp_rates[0] <= 0xf) { + #else + } else if (sta->supp_rates[0] <= 0xf) { +@@ -1332,14 +1332,14 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + wireless_set = 0; + } + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + switch (sta->deflink.bandwidth) { + #else + switch (sta->bandwidth) { + #endif + case IEEE80211_STA_RX_BW_80: + bw_mode = RTW_CHANNEL_WIDTH_80; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + is_support_sgi = sta->deflink.vht_cap.vht_supported && + (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + #else +@@ -1349,7 +1349,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + break; + case IEEE80211_STA_RX_BW_40: + bw_mode = RTW_CHANNEL_WIDTH_40; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + #else +@@ -1359,7 +1359,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + break; + default: + bw_mode = RTW_CHANNEL_WIDTH_20; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + is_support_sgi = sta->deflink.ht_cap.ht_supported && + (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + #else +@@ -1369,14 +1369,14 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + break; + } + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) { + #else + if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) { + #endif + tx_num = 2; + rf_type = RF_2T2R; +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + } else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) { + #else + } else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) { +@@ -1400,7 +1400,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + si->ra_mask = ra_mask; + si->rate_id = rate_id; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT) + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); + #else + rtw_fw_send_ra_info(rtwdev, si); +@@ -1780,7 +1780,7 @@ static void rtw_vif_smps_iter(void *data, u8 *mac, + { + struct rtw_dev *rtwdev = (struct rtw_dev *)data; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) + #else + if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) +@@ -1788,13 +1788,13 @@ static void rtw_vif_smps_iter(void *data, u8 *mac, + return; + + if (rtwdev->hal.txrx_1ss) +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + ieee80211_request_smps(vif, 0, IEEE80211_SMPS_STATIC); + #else + ieee80211_request_smps(vif, IEEE80211_SMPS_STATIC); + #endif + else +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + ieee80211_request_smps(vif, 0, IEEE80211_SMPS_OFF); + #else + ieee80211_request_smps(vif, IEEE80211_SMPS_OFF); +@@ -2516,7 +2516,7 @@ static void rtw_check_sta_active_iter(void *data, struct ieee80211_vif *vif) + if (vif->type != NL80211_IFTYPE_STATION) + return; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT) + if (vif->cfg.assoc || !is_zero_ether_addr(rtwvif->bssid)) + #else + if (vif->bss_conf.assoc || !is_zero_ether_addr(rtwvif->bssid)) +--- a/ps.c ++++ b/ps.c +@@ -334,7 +334,7 @@ void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif) + __rtw_vif_recalc_lps(&data, new_vif); + rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data); + +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT) + if (data.count == 1 && data.found_vif->cfg.ps) { + rtwdev->ps_enabled = true; + } else { +--- a/tx.c ++++ b/tx.c +@@ -90,7 +90,7 @@ EXPORT_SYMBOL(rtw_tx_fill_tx_desc); + + static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta) + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + u8 exp = sta->deflink.ht_cap.ampdu_factor; + #else + u8 exp = sta->ht_cap.ampdu_factor; +@@ -105,7 +105,7 @@ static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta) + + static u8 get_tx_ampdu_density(struct ieee80211_sta *sta) + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + return sta->deflink.ht_cap.ampdu_density; + #else + return sta->ht_cap.ampdu_density; +@@ -117,7 +117,7 @@ static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev, + { + u8 rate; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (rtwdev->hal.rf_type == RF_2T2R && sta->deflink.ht_cap.mcs.rx_mask[1] != 0) + #else + if (rtwdev->hal.rf_type == RF_2T2R && sta->ht_cap.mcs.rx_mask[1] != 0) +@@ -136,7 +136,7 @@ static u8 get_highest_vht_tx_rate(struct rtw_dev *rtwdev, + u8 rate; + u16 tx_mcs_map; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); + #else + tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map); +@@ -382,7 +382,7 @@ static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, + if (info->control.use_rts || skb->len > hw->wiphy->rts_threshold) + pkt_info->rts = true; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT) + if (sta->deflink.vht_cap.vht_supported) + rate = get_highest_vht_tx_rate(rtwdev, sta); + else if (sta->deflink.ht_cap.ht_supported) diff --git a/package/kernel/rtw88-usb/patches/102-disable-pcie.patch b/package/kernel/rtw88-usb/patches/102-disable-pcie.patch new file mode 100644 index 000000000..f57ad4c88 --- /dev/null +++ b/package/kernel/rtw88-usb/patches/102-disable-pcie.patch @@ -0,0 +1,69 @@ +--- a/Makefile ++++ b/Makefile +@@ -30,10 +30,6 @@ NO_SKIP_SIGN := y + endif + + EXTRA_CFLAGS += -O2 +-EXTRA_CFLAGS += -DCONFIG_RTW88_8822BE=1 +-EXTRA_CFLAGS += -DCONFIG_RTW88_8821CE=1 +-EXTRA_CFLAGS += -DCONFIG_RTW88_8822CE=1 +-EXTRA_CFLAGS += -DCONFIG_RTW88_8723DE=1 + EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUG=1 + EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUGFS=1 + #EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS +@@ -60,9 +56,6 @@ rtw_core-objs += main.o \ + obj-m += rtw_8822b.o + rtw_8822b-objs := rtw8822b.o rtw8822b_table.o + +-obj-m += rtw_8822be.o +-rtw_8822be-objs := rtw8822be.o +- + obj-m += rtw_8822bu.o + rtw_8822bu-objs := rtw8822bu.o + +@@ -72,9 +65,6 @@ rtw_8822bs-objs := rtw8822bs.o + obj-m += rtw_8822c.o + rtw_8822c-objs := rtw8822c.o rtw8822c_table.o + +-obj-m += rtw_8822ce.o +-rtw_8822ce-objs := rtw8822ce.o +- + obj-m += rtw_8822cu.o + rtw_8822cu-objs := rtw8822cu.o + +@@ -102,9 +92,6 @@ rtw_8723cs-objs := rtw8723cs.o + obj-m += rtw_8723d.o + rtw_8723d-objs := rtw8723d.o rtw8723d_table.o + +-obj-m += rtw_8723de.o +-rtw_8723de-objs := rtw8723de.o +- + obj-m += rtw_8723du.o + rtw_8723du-objs := rtw8723du.o + +@@ -114,15 +101,9 @@ rtw_8723ds-objs := rtw8723ds.o + obj-m += rtw_8821c.o + rtw_8821c-objs := rtw8821c.o rtw8821c_table.o + +-obj-m += rtw_8821ce.o +-rtw_8821ce-objs := rtw8821ce.o +- + obj-m += rtw_8821a.o + rtw_8821a-objs := rtw8821a.o rtw8821a_table.o + +-obj-m += rtw_8821ae.o +-rtw_8821ae-objs := rtw8821ae.o +- + obj-m += rtw_8821au.o + rtw_8821au-objs := rtw8821au.o + +@@ -132,9 +113,6 @@ rtw_8821cs-objs := rtw8821cs.o + obj-m += rtw_8821cu.o + rtw_8821cu-objs := rtw8821cu.o + +-obj-m += rtw_pci.o +-rtw_pci-objs := pci.o +- + obj-m += rtw_sdio.o + rtw_sdio-objs := sdio.o + diff --git a/package/lean/autocore/Makefile b/package/lean/autocore/Makefile index 125421234..d0b460558 100644 --- a/package/lean/autocore/Makefile +++ b/package/lean/autocore/Makefile @@ -47,6 +47,7 @@ define Package/autocore-arm/install $(INSTALL_DIR) $(1)/sbin $(INSTALL_BIN) ./files/arm/sbin/cpuinfo $(1)/sbin/cpuinfo $(INSTALL_BIN) ./files/arm/sbin/ethinfo $(1)/sbin/ethinfo + $(INSTALL_BIN) ./files/arm/sbin/usage $(1)/sbin/usage endef define Package/autocore-x86/install diff --git a/package/lean/autocore/files/arm/index.htm b/package/lean/autocore/files/arm/index.htm index 0537b0903..b2eb1fccd 100644 --- a/package/lean/autocore/files/arm/index.htm +++ b/package/lean/autocore/files/arm/index.htm @@ -15,7 +15,7 @@ local has_dhcp = fs.access("/etc/config/dhcp") local has_wifi = ((fs.stat("/etc/config/wireless", "size") or 0) > 0) local has_switch = false - + uci:foreach("network", "switch", function(s) has_switch = true @@ -32,7 +32,7 @@ buffered = 0, shared = 0 } - + local mem_cached = luci.sys.exec("sed -e '/^Cached: /!d; s#Cached: *##; s# kB##g' /proc/meminfo") local swapinfo = sysinfo.swap or { @@ -56,8 +56,8 @@ local user_info = luci.sys.exec("cat /proc/net/arp | grep 'br-lan' | grep '0x2' | wc -l") - local cpu_usage = luci.sys.exec("top -n1 | awk '/^CPU/ { printf(\"%d%%\", 100 - $8) }'") or "6%" - local cpu_info = luci.sys.exec("/sbin/cpuinfo") or "ARM Processor x 0 (233MHz, 2.3°C)" + local cpu_usage = luci.sys.exec("/sbin/usage") or "6%" + local cpu_info = luci.sys.exec("/sbin/cpuinfo") or "?" local eth_info = luci.sys.exec("ethinfo") local rv = { @@ -162,7 +162,7 @@ if (ht) s += ', MCS %s'.format(mcs); if (sgi) s += ', <%:Short GI%>'; } - + if (he) { s += ', HE-MCS %d'.format(mcs); if (nss) s += ', HE-NSS %d'.format(nss); @@ -265,7 +265,7 @@ '<%:Type%>: %s%s
    ', ifc6.proto, (ifc6.ip6prefix) ? '-pd' : '' ); - + if (!ifc6.ip6prefix) { s += String.format( @@ -652,7 +652,7 @@ <% end %> var e; - + if (e = document.getElementById('ethinfo')) { var ports = eval('(' + info.ethinfo + ')'); var tmp = ""; @@ -672,10 +672,10 @@ if (e = document.getElementById('uptime')) e.innerHTML = String.format('%t', info.uptime); - + if (e = document.getElementById('userinfo')) e.innerHTML = info.userinfo; - + if (e = document.getElementById('cpuusage')) e.innerHTML = info.cpuusage; @@ -738,7 +738,7 @@ <%:Local Time%>- <%:Uptime%>- <%:Load Average%>- - <%:CPU usage (%)%>- + <%:CPU usage%>- diff --git a/package/lean/autocore/files/arm/sbin/usage b/package/lean/autocore/files/arm/sbin/usage new file mode 100755 index 000000000..6a170393f --- /dev/null +++ b/package/lean/autocore/files/arm/sbin/usage @@ -0,0 +1,14 @@ +#!/bin/sh + +NSS_PATH="/sys/kernel/debug/qca-nss-drv/stats" + +cpu_usage="$(top -n1 | awk '/^CPU/ {printf("%d%", 100 - $8)}')" + +[ ! -d "$NSS_PATH" ] || \ +npu_usage="$(grep '%' "$NSS_PATH"/cpu_load_ubi | awk -F ' ' '{print $2}')" + +if [ -d "$NSS_PATH" ]; then + echo -n "CPU: ${cpu_usage}, NPU: ${npu_usage}" +else + echo -n "CPU: ${cpu_usage}" +fi diff --git a/package/lean/cpufreq/Makefile b/package/lean/cpufreq/Makefile new file mode 100644 index 000000000..c71f1f36f --- /dev/null +++ b/package/lean/cpufreq/Makefile @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2024 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=cpufreq +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/cpufreq + TITLE:=CPU Frequency Scaling adjustment tool + DEPENDS:=@(arm||aarch64) + PKGARCH:=all +endef + +define Build/Compile +endef + +define Package/cpufreq/install + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(CURDIR)/files/cpufreq.config $(1)/etc/config/cpufreq + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(CURDIR)/files/cpufreq.init $(1)/etc/init.d/cpufreq + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(CURDIR)/files/cpufreq.uci $(1)/etc/uci-defaults/10-cpufreq +endef + +$(eval $(call BuildPackage,cpufreq)) diff --git a/package/lean/cpufreq/files/cpufreq.config b/package/lean/cpufreq/files/cpufreq.config new file mode 100644 index 000000000..9004f1bd8 --- /dev/null +++ b/package/lean/cpufreq/files/cpufreq.config @@ -0,0 +1,5 @@ + +config settings 'cpufreq' + +config settings 'global' + diff --git a/package/lean/cpufreq/files/cpufreq.init b/package/lean/cpufreq/files/cpufreq.init new file mode 100755 index 000000000..fc5dc4777 --- /dev/null +++ b/package/lean/cpufreq/files/cpufreq.init @@ -0,0 +1,58 @@ +#!/bin/sh /etc/rc.common + +START=15 +USE_PROCD=1 + +NAME="cpufreq" +CPUFREQ_PATH="/sys/devices/system/cpu/cpufreq" + +extra_command "get_policies" "Get CPU scaling governors and frequencies" + +get_policies() { + json_init + for policy in $(ls -d "$CPUFREQ_PATH"/policy[0-9]* 2>"/dev/null"); do + [ -s "$policy/scaling_available_frequencies" ] || continue + json_add_object "$(basename "$policy")" + json_add_string "index" "$(basename "$policy" | grep -Eo "[0-9]*$")" + json_add_string "cpus" "$(cat "$policy/affected_cpus")" + json_add_array "freqs" + for freq in $(cat "$policy/scaling_available_frequencies"); do + json_add_string "" "$freq" + done + json_close_array + json_add_array "governors" + for governor in $(cat "$policy/scaling_available_governors"); do + json_add_string "" "$governor" + done + json_close_array + json_close_object + done + json_dump +} + +write_cpufreq_config() { + local value + config_get value "$NAME" "$1" + [ -z "$value" ] || echo -n "$value" > "$2" +} + +start_service() { + config_load "$NAME" + + for i in $(ls -d "$CPUFREQ_PATH"/policy[0-9]* 2>"/dev/null" | grep -Eo "[0-9]*$") + do + [ -z "$(config_get "$NAME" "governor$i")" ] && return + + write_cpufreq_config "governor$i" "$CPUFREQ_PATH/policy$i/scaling_governor" + write_cpufreq_config "minfreq$i" "$CPUFREQ_PATH/policy$i/scaling_min_freq" + write_cpufreq_config "maxfreq$i" "$CPUFREQ_PATH/policy$i/scaling_max_freq" + if [ "$(config_get "$NAME" "governor$i")" = "ondemand" ]; then + write_cpufreq_config "sdfactor$i" "$CPUFREQ_PATH/ondemand/sampling_down_factor" + write_cpufreq_config "upthreshold$i" "$CPUFREQ_PATH/ondemand/up_threshold" + fi + done +} + +service_triggers() { + procd_add_reload_trigger "$NAME" +} diff --git a/package/lean/cpufreq/files/cpufreq.uci b/package/lean/cpufreq/files/cpufreq.uci new file mode 100644 index 000000000..4ee49c931 --- /dev/null +++ b/package/lean/cpufreq/files/cpufreq.uci @@ -0,0 +1,75 @@ +#!/bin/sh + +uci_write_config() { + uci -q set "cpufreq.cpufreq.governor$1"="$2" + uci -q set "cpufreq.cpufreq.minfreq$1"="$3" + uci -q set "cpufreq.cpufreq.maxfreq$1"="$4" + [ -n "$5" ] && uci -q set "cpufreq.cpufreq.sdfactor$1"="$5" + [ -n "$6" ] && uci -q set "cpufreq.cpufreq.upthreshold$1"="$6" + uci -q commit cpufreq +} + +[ "$(uci -q get cpufreq.global.set)" -eq "1" ] && exit 0 + +CPU_FREQS="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies')" +CPU_MIN_FREQ="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq')" +CPU_MAX_FREQ="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq')" +CPU_POLICYS="$(find '/sys/devices/system/cpu/cpufreq/policy'* -maxdepth 0 | grep -Eo '[0-9]+')" + +source "/etc/openwrt_release" +case "$DISTRIB_TARGET" in + "bcm27xx/bcm2710"|\ + "bcm27xx/bcm2711") + uci_write_config 0 ondemand 600000 "$CPU_MAX_FREQ" 10 50 + ;; + "ipq40xx/generic") + uci_write_config 0 performance 200000 "$CPU_MAX_FREQ" + ;; + "ipq806x/generic") + uci_write_config 0 performance 600000 "$CPU_MAX_FREQ" + # IPQ8064/5 + echo "$CPU_POLICYS" | grep -q "1" && uci_write_config 1 performance 600000 1200000 + ;; + "mediatek/mt7622") + uci_write_config 0 ondemand 600000 1350000 10 50 + ;; + "qualcommax/ipq60xx"|\ + "qualcommax/ipq807x") + uci_write_config 0 schedutil "$CPU_MIN_FREQ" "$CPU_MAX_FREQ" + ;; + "rockchip/armv8") + if echo "$CPU_POLICYS" | grep -q "6"; then + # RK3588/S + uci_write_config 0 schedutil 1008000 1800000 + uci_write_config 4 schedutil 816000 2208000 + uci_write_config 6 schedutil 816000 2208000 + elif echo "$CPU_POLICYS" | grep -q "4"; then + # RK3399 + uci_write_config 0 schedutil 600000 1608000 + uci_write_config 4 schedutil 600000 2016000 + else + if ! echo "$CPU_FREQS" | grep -q "1992000"; then + # RK3328 + CPU_MAX_FREQ="1512000" + fi + uci_write_config 0 schedutil 816000 "$CPU_MAX_FREQ" + fi + ;; + "sunxi/cortexa53") + if echo "$CPU_FREQS" | grep -q "1800000"; then + # H6 + uci_write_config 0 schedutil "888000" "$CPU_MAX_FREQ" + elif echo "$CPU_FREQS" | grep -q "1512000"; then + # H616/8 + uci_write_config 0 schedutil "936000" "1512000" + elif echo "$CPU_FREQS" | grep -q "1296000"; then + # H5 + uci_write_config 0 ondemand "$CPU_MIN_FREQ" "1296000" 10 50 + else + # A64 + uci_write_config 0 ondemand "$CPU_MIN_FREQ" "$CPU_MAX_FREQ" 10 50 + fi + ;; +esac + +exit 0 diff --git a/package/lean/csstidy/Makefile b/package/lean/csstidy/Makefile deleted file mode 100644 index 5f0910aa3..000000000 --- a/package/lean/csstidy/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=csstidy -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL=https://github.com/jow-/csstidy-cpp.git -PKG_SOURCE_DATE:=2021-06-13 -PKG_SOURCE_VERSION:=707feaec556c40c999514a598b1a1ea5b50826c6 -PKG_MIRROR_HASH:=a6db35de692d1b94561e725634ce410b75f5f7e26dc6f3fc92931813c0721ded - -PKG_LICENSE:=LGPL-2.1 -PKG_LICENSE_FILES:=COPYING - -PKG_MAINTAINER:=Jo-Philipp Wich - -include $(INCLUDE_DIR)/host-build.mk -include $(INCLUDE_DIR)/package.mk - -define Package/csstidy - SECTION:=utils - CATEGORY:=Utilities - TITLE:=CSSTidy parser and optimiser - DEPENDS:=+libstdcpp -endef - -define Package/csstidy/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/csstidy/csstidy $(1)/usr/bin/ -endef - - -define Host/Install - $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin/ - $(INSTALL_BIN) $(HOST_BUILD_DIR)/csstidy/csstidy $(1)/bin/ -endef - -$(eval $(call HostBuild)) -$(eval $(call BuildPackage,csstidy)) diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile index 12388dac6..acd35b1bb 100644 --- a/package/lean/default-settings/Makefile +++ b/package/lean/default-settings/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2016-2017 GitHub +# Copyright (C) 2016-2023 GitHub # # This is free software, licensed under the GNU General Public License v3. # See /LICENSE for more information. @@ -7,8 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=default-settings -PKG_VERSION:=2 -PKG_RELEASE:=35 +PKG_RELEASE:=$(COMMITCOUNT) PKG_LICENSE:=GPLv3 PKG_LICENSE_FILES:=LICENSE @@ -19,7 +18,7 @@ define Package/default-settings CATEGORY:=LuCI TITLE:=LuCI support for Default Settings PKGARCH:=all - DEPENDS:=+luci-base +luci +@LUCI_LANG_zh-cn + DEPENDS:=+luci-base +luci +@LUCI_LANG_zh-cn +@LUCI_LANG_zh_Hans endef define Package/default-settings/description diff --git a/package/lean/default-settings/files/zzz-default-settings b/package/lean/default-settings/files/zzz-default-settings index 47965500e..61b4c5e2c 100755 --- a/package/lean/default-settings/files/zzz-default-settings +++ b/package/lean/default-settings/files/zzz-default-settings @@ -28,7 +28,7 @@ sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/usb_printer.lua sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/xunlei.lua sed -i 's/services/nas/g' /usr/lib/lua/luci/view/minidlna_status.htm -ln -sf /sbin/ip /usr/bin/ip +#ln -sf /sbin/ip /usr/bin/ip sed -i 's#downloads.openwrt.org#mirrors.cloud.tencent.com/lede#g' /etc/opkg/distfeeds.conf sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow @@ -37,13 +37,21 @@ sed -i 's/root:::0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999: sed -i "s/# //g" /etc/opkg/distfeeds.conf sed -i '/openwrt_luci/ { s/snapshots/releases\/18.06.9/g; }' /etc/opkg/distfeeds.conf +sed -i '/check_signature/d' /etc/opkg.conf + sed -i '/REDIRECT --to-ports 53/d' /etc/firewall.user -# echo 'iptables -A OUTPUT -m string --string "api.installer.xiaomi.cn" --algo bm --to 65535 -j DROP' >> /etc/firewall.user +#echo 'iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53' >> /etc/firewall.user +#echo 'iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53' >> /etc/firewall.user +#echo '[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53' >> /etc/firewall.user +#echo '[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53' >> /etc/firewall.user + +#echo 'iptables -A OUTPUT -m string --string "api.installer.xiaomi.cn" --algo bm --to 65535 -j DROP' >> /etc/firewall.user sed -i '/option disabled/d' /etc/config/wireless +sed -i '/set wireless.radio${devidx}.disabled/d' /lib/wifi/mac80211.sh sed -i '/DISTRIB_REVISION/d' /etc/openwrt_release -echo "DISTRIB_REVISION='R24.03.20-D'" >> /etc/openwrt_release +echo "DISTRIB_REVISION='R24.6.6'" >> /etc/openwrt_release sed -i '/DISTRIB_DESCRIPTION/d' /etc/openwrt_release echo "DISTRIB_DESCRIPTION='OpenWrt '" >> /etc/openwrt_release diff --git a/package/lean/default-settings/po/zh-cn/default.po b/package/lean/default-settings/po/zh-cn/default.po index f6c36823c..9ba70ec28 100644 --- a/package/lean/default-settings/po/zh-cn/default.po +++ b/package/lean/default-settings/po/zh-cn/default.po @@ -1,3 +1,6 @@ +msgid "Swap" +msgstr "虚拟内存" + msgid "Processor" msgstr "处理器" @@ -13,6 +16,9 @@ msgstr "CPU 信息" msgid "CPU Model" msgstr "处理器型号" +msgid "CPU usage" +msgstr "CPU 使用率" + msgid "CPU frequency" msgstr "CPU 频率" @@ -49,9 +55,6 @@ msgstr "划分给 ZRam 分区的内存大小(MB),推荐留空由系统自 msgid "Number of parallel threads used for compression" msgstr "用于压缩内存数据的CPU并发线程数" -msgid "Swap" -msgstr "虚拟内存" - msgid "Force 40MHz mode" msgstr "强制 40MHz 频宽" diff --git a/package/lean/default-settings/po/zh-cn/more.po b/package/lean/default-settings/po/zh-cn/more.po deleted file mode 100644 index 6a3b160a7..000000000 --- a/package/lean/default-settings/po/zh-cn/more.po +++ /dev/null @@ -1,1035 +0,0 @@ -msgid "%d hour" -msgstr "%d 小时" - -msgid "%d minute" -msgstr "%d 分钟" - -msgid "%d minutes" -msgstr "%d 分钟" - -msgid "%d second" -msgstr "%d 秒" - -msgid "%d seconds" -msgstr "%d 秒" - -msgid "" -"Acceptable values: 1-100. This many Tracking IP addresses must respond for " -"the link to be deemed up" -msgstr "" -"取值范围: 1-100。这个设置项指定了当多少个 IP 地址能够连通时接口会被认为在线" - -msgid "Acceptable values: 1-1000. Defaults to 1 if not set" -msgstr "取值范围: 1-100。如果不填写,默认值为 1" - -msgid "Advanced" -msgstr "高级" - -msgid "Check IP rules" -msgstr "检查 IP 规则" - -msgid "Check routing table" -msgstr "检查路由表" - -msgid "Collecting data..." -msgstr "正在收集数据..." - -msgid "Configuration" -msgstr "配置" - -msgid "Currently Configured Interfaces" -msgstr "当前配置的接口" - -msgid "Currently Configured Members" -msgstr "当前配置的成员" - -msgid "Currently Configured Policies" -msgstr "当前配置的策略" - -msgid "Destination address" -msgstr "目标地址" - -msgid "Destination port" -msgstr "目标端口" - -msgid "Detailed Status" -msgstr "详细状态" - -msgid "Diagnostic Results" -msgstr "诊断结果" - -msgid "Diagnostics" -msgstr "诊断" - -msgid "Disabled" -msgstr "禁用" - -msgid "" -"Downed interface will be deemed up after this many successful ping tests" -msgstr "当 Ping 成功次数达到这个数值后,已经被认为离线的接口将会重新上线" - -msgid "Enabled" -msgstr "启用" - -msgid "Error collecting troubleshooting information" -msgstr "收集故障排除信息时出错" - -msgid "Errors" -msgstr "错误" - -msgid "Failure interval" -msgstr "故障检测间隔" - -msgid "Flush conntrack table" -msgstr "刷新连接跟踪表" - -msgid "Flush global firewall conntrack table on interface events" -msgstr "在接口事件触发时刷新全局防火墙连接跟踪表" - -msgid "Hotplug Script" -msgstr "Hotplug 脚本" - -msgid "Hotplug ifdown" -msgstr "Hotplug ifdown" - -msgid "Hotplug ifup" -msgstr "Hotplug ifup" - -msgid "IPset" -msgstr "IPset" - -msgid "IPv4" -msgstr "IPv4" - -msgid "IPv6" -msgstr "IPv6" - -msgid "Interface" -msgstr "接口" - -msgid "Interface Status" -msgstr "接口状态" - -msgid "Interface down" -msgstr "接口离线" - -msgid "Interface up" -msgstr "接口上线" - -msgid "Interface will be deemed down after this many failed ping tests" -msgstr "当 Ping 失败次数达到这个数值后接口会被认为离线" - -msgid "Interfaces" -msgstr "接口" - -msgid "Internet Protocol" -msgstr "互联网协议" - -msgid "Last 50 MWAN systemlog entries. Newest entries sorted at the top :" -msgstr "最近 50 条 MWAN 系统日志,最新条目排在顶部:" - -msgid "Last resort" -msgstr "备用成员" - -msgid "Load Balancing" -msgstr "负载均衡" - -msgid "Loading" -msgstr "载入中" - -msgid "MWAN Config" -msgstr "MWAN 配置文件" - -msgid "MWAN Detailed Status" -msgstr "MWAN 详细状态" - -msgid "MWAN Interface Configuration" -msgstr "MWAN 接口配置" - -msgid "MWAN Interface Configuration - %s" -msgstr "MWAN 接口配置 - %s" - -msgid "MWAN Interface Diagnostics" -msgstr "MWAN 接口诊断" - -msgid "MWAN Interface Live Status" -msgstr "MWAN 接口实时状态" - -msgid "MWAN Interface Systemlog" -msgstr "MWAN 接口系统日志" - -msgid "MWAN Member Configuration" -msgstr "MWAN 成员配置" - -msgid "MWAN Member Configuration - %s" -msgstr "MWAN 成员配置 - %s" - -msgid "MWAN Policy Configuration" -msgstr "MWAN 策略配置" - -msgid "MWAN Policy Configuration - %s" -msgstr "MWAN 策略配置 - %s" - -msgid "MWAN Rule Configuration" -msgstr "MWAN 规则配置" - -msgid "MWAN Rule Configuration - %s" -msgstr "MWAN 规则配置 - %s" - -msgid "MWAN Service Control" -msgstr "MWAN 服务控制" - -msgid "" -"MWAN supports up to 250 physical and/or logical interfaces
    MWAN " -"requires that all interfaces have a unique metric configured in /etc/config/" -"network
    Names must match the interface name found in /etc/config/" -"network (see advanced tab)
    Names may contain characters A-Z, a-z, 0-9, " -"_ and no spaces
    Interfaces may not share the same name as configured " -"members, policies or rules" -msgstr "" -"MWAN 支持最多 250 个物理或逻辑接口。
    MWAN 要求所有接口必须在 /etc/" -"config/network 中设定唯一的网关跃点。
    名称必须与 /etc/config/network 中" -"的接口名称匹配。(可查看“高级”选项卡)
    名称允许包括A-Z、a-z、0-9、_ 但是" -"不能有空格。
    接口不应该与成员、策略、规则中的任意一个设置项使用相同的名" -"称" - -msgid "" -"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or " -"as a portrange (eg \"1024:2048\") without quotes" -msgstr "" -"可以输入一个或多个端口(例如 \"22\" 或者 \"80,443\")或者是一个端口范围(例" -"如 \"1024:2048\")不含引号" - -msgid "Member" -msgstr "成员" - -msgid "Member used" -msgstr "使用的成员" - -msgid "Members" -msgstr "成员" - -msgid "" -"Members are profiles attaching a metric and weight to an MWAN interface
    Names may contain characters A-Z, a-z, 0-9, _ and no spaces
    Members " -"may not share the same name as configured interfaces, policies or rules" -msgstr "" -"“成员”用来设置每一个 MWAN 接口的跃点数(即接口优先级)和所占比重。
    名称" -"允许包括 A-Z、 a-、0-9、_ 但是不能有空格。
    成员不应该与接口、策略、规则" -"中的任意一个设置项使用相同的名称" - -msgid "Members assigned" -msgstr "分配的成员" - -msgid "Metric" -msgstr "跃点数" - -msgid "" -"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/" -"youtube.com/youtube\")" -msgstr "" -"匹配 IPset 规则列表名称。需要先配置 /etc/dnsmasq.conf 中的 IPset 规则 (例如: " -"\"ipset=/youtube.com/youtube\")" - -msgid "Network Config" -msgstr "网络配置文件" - -msgid "No" -msgstr "否" - -msgid "No MWAN interfaces found" -msgstr "没有找到 MWAN 接口" - -msgid "No MWAN systemlog history found" -msgstr "没有在系统日志中找到 MWAN 历史信息" - -msgid "No detailed status information available" -msgstr "没有状态详细信息可用" - -msgid "No diagnostic results returned" -msgstr "没有返回诊断结果" - -msgid "No protocol specified" -msgstr "未指定协议" - -msgid "Offline" -msgstr "离线" - -msgid "Online (tracking active)" -msgstr "在线(追踪启用中)" - -msgid "Online (tracking off)" -msgstr "在线(追踪已关闭)" - -msgid "Overview" -msgstr "概况" - -msgid "Ping count" -msgstr "Ping 计数" - -msgid "Ping default gateway" -msgstr "Ping 默认网关" - -msgid "Ping interval" -msgstr "Ping 间隔" - -msgid "Ping interval during failure detection" -msgstr "故障检测期间的 Ping 间隔" - -msgid "Ping interval during failure recovering" -msgstr "故障恢复期间的 Ping 间隔" - -msgid "Ping size" -msgstr "Ping 大小" - -msgid "Ping timeout" -msgstr "Ping 超时" - -msgid "Ping tracking IP" -msgstr "Ping 跟踪 IP" - -msgid "Policies" -msgstr "策略" - -msgid "" -"Policies are profiles grouping one or more members controlling how MWAN " -"distributes traffic
    Member interfaces with lower metrics are used " -"first. Interfaces with the same metric load-balance
    Load-balanced " -"member interfaces distribute more traffic out those with higher weights
    Names may contain characters A-Z, a-z, 0-9, _ and no spaces. Names must be " -"15 characters or less
    Policies may not share the same name as " -"configured interfaces, members or rules" -msgstr "" -"“策略”把成员进行分组,告诉 MWAN 如何分配“规则”中使用这一策略的流量
    拥有" -"较低跃点数的成员将会被优先使用。拥有相同跃点数的成员把流量进行负载均衡。
    进行负载均衡的成员之间拥有较高比重的成员将会被分配到更多流量。
    名称允许" -"包括A-Z、a-z、0-9、_ 但是不能有空格。名称应该在 15 个字符以内
    策略不应该" -"与接口、成员、规则中的任意一个设置项使用相同的名称" - -msgid "Policy" -msgstr "策略" - -msgid "Policy assigned" -msgstr "分配的策略" - -msgid "Protocol" -msgstr "协议" - -msgid "Recovery interval" -msgstr "故障恢复间隔" - -msgid "Restart MWAN" -msgstr "重启 MWAN" - -msgid "Restore default hotplug script" -msgstr "恢复默认的 hotplug 脚本" - -msgid "Restore..." -msgstr "恢复..." - -msgid "Rule" -msgstr "规则" - -msgid "Rules" -msgstr "规则" - -msgid "" -"Rules specify which traffic will use a particular MWAN policy based on IP " -"address, port or protocol
    Rules are matched from top to bottom. Rules " -"below a matching rule are ignored. Traffic not matching any rule is routed " -"using the main routing table
    Traffic destined for known (other than " -"default) networks is handled by the main routing table. Traffic matching a " -"rule, but all WAN interfaces for that policy are down will be blackholed
    Names may contain characters A-Z, a-z, 0-9, _ and no spaces
    Rules may " -"not share the same name as configured interfaces, members or policies" -msgstr "" -"“规则”基于 IP 地址、协议、端口把流量划分到指定的“策略”中。
    规则按照从上" -"到下的顺序进行匹配。除了第一条能够匹配一次通信的规则以外,其它规则将被忽略。" -"不匹配任何规则的通信将会由系统默认路由表进行。
    来自已知的网络的转发流量" -"由系统默认路由表接手,然后 MWAN 从中匹配出相应的流量并转移到 MWAN 自己的路由" -"表。但是所有被划分到一个无法使用的策略的流量将会无法正常进行路由。
    名称" -"允许包括A-Z、a-z、0-9、_ 但是不能有空格。
    规则不应该与接口、成员、策略中" -"的任意一个设置项使用相同的名称" - -msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set" -msgstr "单位为秒。接受的值: 1-1000000。留空则使用默认值 600 秒" - -msgid "Source address" -msgstr "源地址" - -msgid "Source port" -msgstr "源端口" - -msgid "Start MWAN" -msgstr "启动 MWAN" - -msgid "Sticky" -msgstr "粘滞模式" - -msgid "Sticky timeout" -msgstr "粘滞超时" - -msgid "Stop MWAN" -msgstr "停止 MWAN" - -msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes" -msgstr "支持 CIDR 记法(例如: \"192.168.100.0/24\")不含引号" - -msgid "There are currently %d of 250 supported interfaces configured" -msgstr "当前已配置 %d 个接口,最大支持 250 个" - -msgid "" -"This displays the metric assigned to this interface in /etc/config/network" -msgstr "这里显示了这个接口在 /etc/config/network 中配置的跃点数" - -msgid "" -"This hostname or IP address will be pinged to determine if the link is up or " -"down. Leave blank to assume interface is always online" -msgstr "通过 ping 此主机或 IP 地址来确定链路是否在线。留空则认为接口始终在线" - -msgid "This section allows you to modify the contents of /etc/config/mwan3" -msgstr "这里允许你修改 /etc/config/mwan3 的内容" - -msgid "This section allows you to modify the contents of /etc/config/network" -msgstr "这里允许你修改 /etc/config/network 的内容" - -msgid "This section allows you to modify the contents of /etc/config/wireless" -msgstr "这里允许你修改 /etc/config/wireless 的内容" - -msgid "" -"This section allows you to modify the contents of /etc/hotplug.d/iface/16-" -"mwancustom
    This is useful for running system commands and/or scripts " -"based on interface ifup or ifdown hotplug events

    Notes:
    The " -"first line of the script must be "#!/bin/sh" without quotes
    Lines beginning with # are comments and are not executed

    Available variables:
    $ACTION is the hotplug event (ifup, ifdown)
    " -"$INTERFACE is the interface name (wan1, wan2, etc.)
    $DEVICE is the " -"device name attached to the interface (eth0.1, eth1, etc.)" -msgstr "" -"这里允许你修改 /etc/hotplug.d/iface/16-mwancustom 的内容
    这可以在接口 " -"ifup 或 ifdown Hotplug 事件时运行系统命令或脚本

    注意:
    脚本的" -"第一行必须是 "#!/bin/sh" 不含引号
    以#开头的行是注释,不会执行" -"

    可用变量:
    $ACTION 是 Hotplug 事件(ifup, ifdown)
    " -"$INTERFACE 是接口名称(wan1、wan2 等)
    $DEVICE 是连接到接口的设备名称 " -"(eth0.1、eth1 等)" - -msgid "Tracking IP" -msgstr "追踪的 IP" - -msgid "Tracking hostname or IP address" -msgstr "追踪的主机或 IP 地址" - -msgid "Tracking reliability" -msgstr "追踪可靠性" - -msgid "Traffic Rules" -msgstr "流量规则" - -msgid "" -"Traffic from the same source IP address that previously matched this rule " -"within the sticky timeout period will use the same WAN interface" -msgstr "" -"来自相同源 IP 的流量,如果已经匹配过此规则并且在粘滞超时时间内,将会使用相同" -"的 WAN 接口" - -msgid "Troubleshooting" -msgstr "故障排除" - -msgid "Troubleshooting Data" -msgstr "故障排除数据" - -msgid "View the contents of /etc/protocols for protocol descriptions" -msgstr "请查看 /etc/protocols 获取可选协议详情" - -msgid "WARNING: %d interfaces are configured exceeding the maximum of 250!" -msgstr "警告: 已配置 %d 个接口,超过最大值 250!" - -msgid "" -"WARNING: Some policies have names exceeding the maximum of 15 characters!" -msgstr "警告: 某些策略的名称超过了 15 个字符!" - -msgid "" -"WARNING: some interfaces are configured incorrectly or not at all in /etc/" -"config/network!" -msgstr "警告: 某些接口配置不正确或未配置到 /etc/config/network!" - -msgid "" -"WARNING: some interfaces have a higher reliability requirement than there " -"are tracking IP addresses!" -msgstr "警告: 某些接口的追踪可靠性要求大于了追踪 IP 地址总数!" - -msgid "" -"WARNING: some interfaces have duplicate metrics configured in /etc/config/" -"network!" -msgstr "警告: 某些接口在 /etc/config/network 中配置了相同的跃点数!" - -msgid "" -"WARNING: some interfaces have no default route in the main routing table!" -msgstr "警告: 某些接口在主路由表中没有默认路由!" - -msgid "" -"WARNING: some interfaces have no metric configured in /etc/config/network!" -msgstr "警告: 某些接口没有在 /etc/config/network 中配置跃点数!" - -msgid "" -"WARNING: some rules have a port configured with no or improper protocol " -"specified! Please configure a specific protocol!" -msgstr "" -"警告: 某些规则指定了端口却没有配置或配置了不正确的协议,请重新指定协议!" - -msgid "" -"WARNING: this and other interfaces have duplicate metrics configured in /etc/" -"config/network!" -msgstr "警告: 此接口和其他接口在 /etc/config/network 中配置了相同的跃点数!" - -msgid "" -"WARNING: this interface has a higher reliability requirement than there are " -"tracking IP addresses!" -msgstr "警告: 此接口的追踪可靠性要求大于了追踪 IP 地址总数!" - -msgid "WARNING: this interface has no default route in the main routing table!" -msgstr "警告: 此接口在主路由表中没有默认路由!" - -msgid "" -"WARNING: this interface has no metric configured in /etc/config/network!" -msgstr "警告: 此接口没有在 /etc/config/network 中配置跃点数!" - -msgid "" -"WARNING: this interface is configured incorrectly or not at all in /etc/" -"config/network!" -msgstr "警告: 此接口配置不正确或未配置到 /etc/config/network!" - -msgid "" -"WARNING: this policy's name is %d characters exceeding the maximum of 15!" -msgstr "警告: 此策略的名称具有 %d 个字符,超过了 15 个字符!" - -msgid "" -"WARNING: this rule is incorrectly configured with no or improper protocol " -"specified! Please configure a specific protocol!" -msgstr "警告: 此规则没有配置或配置了不正确的协议,请重新指定协议!" - -msgid "Waiting for MWAN to %s..." -msgstr "等待 MWAN %s..." - -msgid "Waiting for diagnostic results..." -msgstr "等待诊断结果..." - -msgid "Weight" -msgstr "比重" - -msgid "" -"When all policy members are offline use this behavior for matched traffic" -msgstr "当所有策略成员都无法使用的时候,对使用该策略的流量使用这个操作" - -msgid "Wireless Config" -msgstr "无线配置" - -msgid "Yes" -msgstr "是" - -msgid "always" -msgstr "总是" - -msgid "blackhole (drop)" -msgstr "黑洞(丢弃)" - -msgid "default (use main routing table)" -msgstr "默认(使用主路由表)" - -msgid "ifdown" -msgstr "ifdown" - -msgid "ifup" -msgstr "ifup" - -msgid "never" -msgstr "从不" - -msgid "restart" -msgstr "重启" - -msgid "start" -msgstr "启动" - -msgid "stop" -msgstr "关闭" - -msgid "unreachable (reject)" -msgstr "不可达(拒绝)" - -msgid "%d IPv4-only hosts" -msgstr "%d 个主机仅支持 IPv4" - -msgid "%d IPv6-only hosts" -msgstr "%d 个主机仅支持 IPv6" - -msgid "%d dual-stack hosts" -msgstr "%d 个双协议栈主机" - -msgid "%s and %s" -msgstr "%s 和 %s" - -msgid "%s, %s and %s" -msgstr "%s, %s 和 %s" - -msgid "-1 - Restart every last day of month" -msgstr "-1 - 每月的最后一天重新开始" - -msgid "-7 - Restart a week before end of month" -msgstr "-7 - 每月底前一周重新开始" - -msgid "1 - Restart every 1st of month" -msgstr "1 - 每月的第一天重新开始" - -msgid "10m - frequent commits at the expense of flash wear" -msgstr "10m - 频繁提交,闪存损耗的开销也增大" - -msgid "12h - compromise between risk of data loss and flash wear" -msgstr "12h - 平衡统计数据丢失的风险以及闪存使用寿命" - -msgid "24h - least flash wear at the expense of data loss risk" -msgstr "24h - 以数据丢失风险的代价换取最小的闪存损耗" - -msgid "30s - refresh twice per minute for reasonably current stats" -msgstr "30s - 每分钟刷新二次以获得较准确的当前统计值" - -msgid "5m - rarely refresh to avoid frequently clearing conntrack counters" -msgstr "5m - 较少刷新以避免频繁清除连接跟踪计数器" - -msgid "60s - commit minutely, useful for non-flash storage" -msgstr "60s - 每分钟提交,适用于非闪存类型存储" - -msgid "0 connections" -msgstr "连接:0" - -msgid "0 hosts" -msgstr "主机:0" - -msgid "0% IPv6 support rate among hosts" -msgstr "支持 IPv6 的主机比例:0%" - -msgid "0B total IPv6 download" -msgstr "IPv6 总下载量:0B" - -msgid "0% of the total traffic is IPv6" -msgstr "IPv6 流量比例:0%" - -msgid "0B total IPv6 upload" -msgstr "IPv6 总上传量:0B" - -msgid "0 cause the most connections" -msgstr "0 是连接数最多的协议" - -msgid "0 cause the most download" -msgstr "0 是下载量最大的协议" - -msgid "0 cause the most upload" -msgstr "0 是上传量最大的协议" - -msgid "0 different application protocols" -msgstr "0 种不同的应用层协议" - -msgid "0 download" -msgstr "下载:0" - -msgid "0 upload" -msgstr "上传:0" - -msgid "Accounting period" -msgstr "统计周期" - -msgid "Advanced Settings" -msgstr "高级设置" - -msgid "Application" -msgstr "应用层协议" - -msgid "Application Protocols" -msgstr "应用层协议" - -msgid "Backup" -msgstr "备份" - -msgid "Bandwidth Monitor" -msgstr "带宽监控" - -msgid "CSV, grouped by IP" -msgstr "CSV,按 IP 分组" - -msgid "CSV, grouped by MAC" -msgstr "CSV,按 MAC 分组" - -msgid "CSV, grouped by protocol" -msgstr "CSV,按协议分组" - -msgid "" -"Changing the accounting interval type will invalidate existing databases!" -"
    Download backup." -msgstr "" -"更改统计周期类型会使现有数据库无效!
    下载备份." - -msgid "" -"Choose \"Day of month\" to restart the accounting period monthly on a " -"specific date, e.g. every 3rd. Choose \"Fixed interval\" to restart the " -"accounting period exactly every N days, beginning at a given date." -msgstr "" -"选择“每月的某一天”来设置统计周期的重启时间,例如:每个月的第 3 天。选择“固定" -"周期”来设置从给定日期开始每 N 天重启统计周期。" - -msgid "Commit interval" -msgstr "提交间隔" - -msgid "Compress database" -msgstr "压缩数据库" - -msgid "Conn." -msgstr "连接。" - -msgid "Connections" -msgstr "连接" - -msgid "Connections / Host" -msgstr "连接 / 主机" - -msgid "Database directory" -msgstr "数据库目录" - -msgid "" -"Database storage directory. One file per accounting period will be placed " -"into this directory." -msgstr "数据库存储目录。每个“统计周期”的文件将被放到这个目录中。" - -msgid "Day of month" -msgstr "每月的某一天" - -msgid "" -"Day of month to restart the accounting period. Use negative values to count " -"towards the end of month, e.g. \"-5\" to specify the 27th of July or the " -"24th of Februrary." -msgstr "" -"每个月重启统计周期的日期。使用负数表示从月底开始计算,例如:\"-5\" 可以表示 " -"7 月份的 27 号或者 2 月份的 24 号。" - -msgid "Display" -msgstr "显示" - -msgid "Down. (Bytes / Pkts.)" -msgstr "下载(字节 / 数据包)" - -msgid "Download (Bytes / Packets)" -msgstr "下载(字节 / 数据包)" - -msgid "Download / Application" -msgstr "下载 / 应用层协议" - -msgid "Download Database Backup" -msgstr "下载数据库备份" - -msgid "Dualstack enabled hosts" -msgstr "双协议栈主机" - -msgid "Due date" -msgstr "重置日期" - -msgid "Export" -msgstr "导出" - -msgid "Family" -msgstr "协议类型" - -msgid "Fixed interval" -msgstr "固定周期" - -msgid "Force reload…" -msgstr "强制重新加载..…" - -msgid "General Settings" -msgstr "基本设置" - -msgid "Generate Backup" -msgstr "生成备份" - -msgid "Host" -msgstr "主机" - -msgid "Hostname: example.org" -msgstr "主机名:example.org" - -msgid "IPv4 vs. IPv6" -msgstr "IPv4 与 IPv6" - -msgid "Interval" -msgstr "周期" - -msgid "" -"Interval at which the temporary in-memory database is committed to the " -"persistent database directory." -msgstr "将内存中的临时数据库提交到持久性数据库目录的间隔时间。" - -msgid "" -"Interval at which traffic counters of still established connections are " -"refreshed from netlink information." -msgstr "从 netlink 信息中刷新“已建立连接”的流量计数器的间隔时间。" - -msgid "Invalid or empty backup archive" -msgstr "备份存档无效或为空" - -msgid "JSON dump" -msgstr "JSON 输出" - -msgid "Length of accounting interval in days." -msgstr "统计周期(天)。" - -msgid "Local interfaces" -msgstr "本地接口" - -msgid "Local subnets" -msgstr "本地子网" - -msgid "MAC" -msgstr "MAC" - -msgid "Maximum entries" -msgstr "最大条目" - -msgid "" -"Maximum number of accounting periods to keep, use zero to keep databases " -"forever." -msgstr "保留的统计周期数据库的最大数量,设置 0 表示不限制。" - -msgid "Netlink Bandwidth Monitor" -msgstr "网络带宽监视器" - -msgid "Netlink Bandwidth Monitor - Backup / Restore" -msgstr "网络带宽监视器 - 备份 / 恢复" - -msgid "Netlink Bandwidth Monitor - Configuration" -msgstr "网络带宽监视器 - 配置" - -msgid "No data recorded yet." -msgstr "暂无数据记录。" - -msgid "Only conntrack streams from or to any of these networks are counted." -msgstr "仅统计来自或目标为这些网络接口的连接流量。" - -msgid "Only conntrack streams from or to any of these subnets are counted." -msgstr "仅统计来自或目标为这些子网的连接流量。" - -msgid "Preallocate database" -msgstr "预分配数据库" - -msgid "Protocol Mapping" -msgstr "协议映射" - -msgid "" -"Protocol mappings to distinguish traffic types per host, one mapping per " -"line. The first value specifies the IP protocol, the second value the port " -"number and the third column is the name of the mapped protocol." -msgstr "" -"协议映射用于区分流量类型,每行一条。第一个值指定 IP 协议类型,第二个值是端口" -"号,第三个值是映射的协议名称。" - -msgid "Refresh interval" -msgstr "刷新间隔" - -msgid "Restore" -msgstr "恢复" - -msgid "Restore Database Backup" -msgstr "恢复数据库备份" - -msgid "Select accounting period:" -msgstr "选择统计周期:" - -msgid "Source IP" -msgstr "源 IP" - -msgid "Start date" -msgstr "起始日期" - -msgid "Start date of the first accounting period, e.g. begin of ISP contract." -msgstr "第一个统计周期的起始日期,例如:ISP 合约的起始日期。" - -msgid "Stored periods" -msgstr "储存周期" - -msgid "" -"The Netlink Bandwidth Monitor (nlbwmon) is a lightweight, efficient traffic " -"accounting program keeping track of bandwidth usage per host and protocol." -msgstr "" -"网络带宽监视器(nlbwmon)是一个轻量、高效的流量统计程序,可以统计每个主机和协" -"议的带宽使用情况。" - -msgid "The following database files have been restored: %s" -msgstr "以下数据库文件已恢复:%s" - -msgid "" -"The maximum amount of entries that should be put into the database, setting " -"the limit to 0 will allow databases to grow indefinitely." -msgstr "数据库中的最大条目数量, 设置为 0 将允许数据库无限增长。" - -msgid "Traffic / Host" -msgstr "流量 / 主机" - -msgid "Traffic Distribution" -msgstr "流量分布" - -msgid "Up. (Bytes / Pkts.)" -msgstr "上传(字节 / 数据包)" - -msgid "Upload (Bytes / Packets)" -msgstr "上传(字节 / 数据包)" - -msgid "Upload / Application" -msgstr "上传 / 应用层协议" - -msgid "Vendor: Example Corp." -msgstr "供应商: Example Corp." - -msgid "Warning" -msgstr "警告" - -msgid "" -"Whether to gzip compress archive databases. Compressing the database files " -"makes accessing old data slightly slower but helps to reduce storage " -"requirements." -msgstr "" -"是否使用 gzip 压缩数据库存档。压缩数据库文件会使访问旧数据稍微慢一些, 但有助" -"于减少存储占用空间。" - -msgid "" -"Whether to preallocate the maximum possible database size in memory. This is " -"mainly useful for memory constrained systems which might not be able to " -"satisfy memory allocation after longer uptime periods." -msgstr "" -"是否预先分配数据库最大可能占用的内存大小。这主要适用于内存较小系统,这些系统" -"在长时间运行之后可能无法满足数据库的内存需求。" - -msgid "no traffic" -msgstr "无流量数据" - -msgid "other" -msgstr "其他" - -msgid "" -"Enable IGMP " -"snooping" -msgstr "" -"开启 IGMP snooping" - -msgid "Enables IGMP snooping on this bridge" -msgstr "在此桥接上启用 IGMP snooping 组播(多播)" - -msgid "Action" -msgstr "动作" - -msgid "Advanced Reboot" -msgstr "双分区启动切换" - -msgid "Alternative" -msgstr "备选" - -msgid "Cancel" -msgstr "取消" - -msgid "Confirm" -msgstr "确定" - -msgid "Current" -msgstr "当前" - -msgid "Firmware/OS (Kernel)" -msgstr "固件/系统 (内核)" - -msgid "Partition" -msgstr "分区" - -msgid "Partitions" -msgstr "分区" - -msgid "Perform power off..." -msgstr "点击关机..." - -msgid "Power Off Device" -msgstr "关闭设备" - -msgid "Proceed" -msgstr "处理" - -msgid "Reboot Device to an Alternative Partition" -msgstr "重启设备到备选分区" - -msgid "Reboot to alternative partition..." -msgstr "重启到备选分区。" - -msgid "Reboot to current partition" -msgstr "重启到当前分区" - -msgid "Rebooting..." -msgstr "正在重启..." - -msgid "Shutting down..." -msgstr "正在关闭..." - -msgid "Status" -msgstr "状态" - -msgid "" -"The system is rebooting now.
    DO NOT POWER OFF THE DEVICE!
    Wait a " -"few minutes before you try to reconnect. It might be necessary to renew the " -"address of your computer to reach the device again, depending on your " -"settings." -msgstr "" -"系统正在重启。
    请勿关闭设备电源!
    请等待几分钟,然后再尝试重新连" -"接。根据您的设置,可能需要更新计算机的地址才能再次访问该设备。" - -msgid "" -"The system is rebooting to an alternative partition now.
    DO NOT POWER " -"OFF THE DEVICE!
    Wait a few minutes before you try to reconnect. It " -"might be necessary to renew the address of your computer to reach the device " -"again, depending on your settings." -msgstr "" -"系统正在重新引导到备用分区。
    请勿关闭设备电源!
    请等待几分钟,然" -"后再尝试重新连接。根据您的设置,可能需要更新计算机的地址才能再次访问该设备。" - -msgid "" -"The system is shutting down now.
    DO NOT POWER OFF THE DEVICE!
    It " -"might be necessary to renew the address of your computer to reach the device " -"again, depending on your settings." -msgstr "" -"系统正在关闭。
    请勿关闭设备电源!
    根据您的设置,可能需要更新计算" -"机的地址才能再次访问该设备。" - -msgid "" -"WARNING: An alternative partition might have its own settings and completely " -"different firmware.

    As your network configuration and WiFi SSID/" -"password on alternative partition might be different, you might have to " -"adjust your computer settings to be able to access your device once it " -"reboots.

    Please also be aware that alternative partition " -"firmware might not provide an easy way to switch active partition and boot " -"back to the currently active partition.

    Click \"Proceed\" below " -"to reboot device to an alternative partition." -msgstr "" -"警告:备用分区可能具有自己的设置和完全不同的固件。

    由于备用分区上" -"的网络配置和WiFi SSID /密码可能有所不同,因此您可能必须调整计算机设置才能在设" -"备重启后访问设备。

    另请注意,备用分区固件可能无法提供切换活动分区" -"并引导回当前活动分区的简便方法。

    点击 \"继续\" 下面将设备重新引导" -"到备用分区。" - -msgid "" -"WARNING: Power off might result in a reboot on a device which doesn't " -"support power off.

    Click \"Proceed\" below to power off your " -"device." -msgstr "" -"警告: 关闭电源可能会导致不支持关闭电源的设备重新启动。

    单击下面的" -"\"继续\"以关闭设备电源。" - -msgid "Warning: There are unsaved changes that will get lost on reboot!" -msgstr "警告:某些设置没有保存,重启将导致丢失这些配置!" - -msgid "Warning: This system does not have two partitions!" -msgstr "警告:当前系统没有包括两个分区!" - -msgid "Warning: This system does not support powering off!" -msgstr "警告:本系统不支持软关机!" diff --git a/package/lean/r8125/Makefile b/package/lean/r8125/Makefile index 16062ab37..a1ec478cb 100644 --- a/package/lean/r8125/Makefile +++ b/package/lean/r8125/Makefile @@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=r8125 -PKG_VERSION:=9.012.03-1 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=9.013.02-2 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/awesometic/realtek-r8125-dkms/tar.gz/$(PKG_VERSION)? -PKG_HASH:=7964aacf4a2873cbe4133aeca830bd0725f819ea286bab162026ff283510144f +PKG_HASH:=eae10100680de13e8119602c50a1748b8a0669eccd61d9a4515b4c846deb3960 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/realtek-$(PKG_NAME)-dkms-$(PKG_VERSION) PKG_LICENSE:=GPL-2.0-only diff --git a/package/lean/r8125/patches/010-config.patch b/package/lean/r8125/patches/010-config.patch index fe4e7008d..a923f3efc 100644 --- a/package/lean/r8125/patches/010-config.patch +++ b/package/lean/r8125/patches/010-config.patch @@ -1,6 +1,6 @@ --- a/src/Makefile +++ b/src/Makefile -@@ -35,16 +35,16 @@ ENABLE_REALWOW_SUPPORT = n +@@ -35,7 +35,7 @@ ENABLE_REALWOW_SUPPORT = n ENABLE_DASH_SUPPORT = n ENABLE_DASH_PRINTER_SUPPORT = n CONFIG_DOWN_SPEED_100 = n @@ -9,10 +9,8 @@ ENABLE_S5WOL = y ENABLE_S5_KEEP_CURR_MAC = n ENABLE_EEE = y - ENABLE_S0_MAGIC_PACKET = n - ENABLE_TX_NO_CLOSE = y --ENABLE_MULTIPLE_TX_QUEUE = n -+ENABLE_MULTIPLE_TX_QUEUE = y +@@ -44,7 +44,7 @@ ENABLE_TX_NO_CLOSE = y + ENABLE_MULTIPLE_TX_QUEUE = y ENABLE_PTP_SUPPORT = n ENABLE_PTP_MASTER_MODE = n -ENABLE_RSS_SUPPORT = n diff --git a/package/lean/r8125/patches/011-ignore-rss-log.patch b/package/lean/r8125/patches/011-ignore-rss-log.patch new file mode 100644 index 000000000..05e9eee6b --- /dev/null +++ b/package/lean/r8125/patches/011-ignore-rss-log.patch @@ -0,0 +1,11 @@ +--- a/src/r8125_rss.c ++++ b/src/r8125_rss.c +@@ -91,7 +91,7 @@ int rtl8125_get_rxnfc(struct net_device + struct rtl8125_private *tp = netdev_priv(dev); + int ret = -EOPNOTSUPP; + +- netif_info(tp, drv, tp->dev, "rss get rxnfc\n"); ++ netif_dbg(tp, drv, tp->dev, "rss get rxnfc\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return ret; diff --git a/package/lean/r8125/patches/020-fixes-build-werror.patch b/package/lean/r8125/patches/020-fixes-build-werror.patch deleted file mode 100644 index 640b50b1a..000000000 --- a/package/lean/r8125/patches/020-fixes-build-werror.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/src/r8125_rss.c -+++ b/src/r8125_rss.c -@@ -60,21 +60,21 @@ static int rtl8125_get_rss_hash_opts(str - switch (cmd->flow_type) { - case TCP_V4_FLOW: - cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; -- /* fallthrough */ -+ fallthrough; - case UDP_V4_FLOW: - if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) - cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; -- /* fallthrough */ -+ fallthrough; - case IPV4_FLOW: - cmd->data |= RXH_IP_SRC | RXH_IP_DST; - break; - case TCP_V6_FLOW: - cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; -- /* fallthrough */ -+ fallthrough; - case UDP_V6_FLOW: - if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) - cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; -- /* fallthrough */ -+ fallthrough; - case IPV6_FLOW: - cmd->data |= RXH_IP_SRC | RXH_IP_DST; - break; diff --git a/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch b/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch index 9b5d8d340..5fb3f941a 100644 --- a/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch +++ b/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch @@ -8,8 +8,8 @@ #include #include #include -@@ -14818,6 +14819,23 @@ rtl8125_setup_mqs_reg(struct rtl8125_pri - } +@@ -13626,6 +13627,23 @@ rtl8125_setup_mqs_reg(struct rtl8125_pri + tp->imr_reg[i] = (u16)(IMR1_8125 + (i - 1) * 4); } +static int @@ -32,9 +32,9 @@ static void rtl8125_init_software_variable(struct net_device *dev) { -@@ -15384,6 +15402,8 @@ rtl8125_init_software_variable(struct ne - if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) - tp->rtl8125_rx_config |= EnableRxDescV3; +@@ -14260,6 +14278,8 @@ rtl8125_init_software_variable(struct ne + else if (tp->InitRxDescType == RX_DESC_RING_TYPE_4) + tp->rtl8125_rx_config &= ~EnableRxDescV4_1; + rtl8125_led_configuration(tp); + diff --git a/package/lean/r8125/patches/040-add-devname-configuration-from-OF.patch b/package/lean/r8125/patches/040-add-devname-configuration-from-OF.patch index 8caea8b94..48f991749 100644 --- a/package/lean/r8125/patches/040-add-devname-configuration-from-OF.patch +++ b/package/lean/r8125/patches/040-add-devname-configuration-from-OF.patch @@ -1,6 +1,6 @@ --- a/src/r8125_n.c +++ b/src/r8125_n.c -@@ -14820,6 +14820,23 @@ rtl8125_setup_mqs_reg(struct rtl8125_pri +@@ -13628,6 +13628,23 @@ rtl8125_setup_mqs_reg(struct rtl8125_pri } static int @@ -24,9 +24,9 @@ rtl8125_led_configuration(struct rtl8125_private *tp) { u32 led_data; -@@ -15402,6 +15419,7 @@ rtl8125_init_software_variable(struct ne - if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) - tp->rtl8125_rx_config |= EnableRxDescV3; +@@ -14278,6 +14295,7 @@ rtl8125_init_software_variable(struct ne + else if (tp->InitRxDescType == RX_DESC_RING_TYPE_4) + tp->rtl8125_rx_config &= ~EnableRxDescV4_1; + rtl8125_devname_configuration(tp); rtl8125_led_configuration(tp); diff --git a/package/lean/r8126/Makefile b/package/lean/r8126/Makefile new file mode 100644 index 000000000..0ea28b3e4 --- /dev/null +++ b/package/lean/r8126/Makefile @@ -0,0 +1,34 @@ +# +# Download realtek r8126 linux driver from official site: +# [https://www.realtek.com/en/component/zoo/category/network-interface-controllers-10-100-1000m-gigabit-ethernet-pci-express-software] +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=r8126 +PKG_VERSION:=10.013.00 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/r8126 + TITLE:=Driver for Realtek r8126 chipsets + SUBMENU:=Network Devices + VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE) + DEPENDS:=@PCI_SUPPORT + FILES:= $(PKG_BUILD_DIR)/r8126.ko + AUTOLOAD:=$(call AutoProbe,r8126) +endef + +define Package/r8126/description + This package contains a driver for Realtek r8126 chipsets. +endef + +define Build/Compile + +$(KERNEL_MAKE) M=$(PKG_BUILD_DIR) modules +endef + +$(eval $(call KernelPackage,r8126)) diff --git a/package/lean/r8126/patches/010-config.patch b/package/lean/r8126/patches/010-config.patch new file mode 100644 index 000000000..e0837e9b1 --- /dev/null +++ b/package/lean/r8126/patches/010-config.patch @@ -0,0 +1,11 @@ +--- a/Makefile ++++ b/Makefile +@@ -44,7 +44,7 @@ ENABLE_TX_NO_CLOSE = y + ENABLE_MULTIPLE_TX_QUEUE = y + ENABLE_PTP_SUPPORT = n + ENABLE_PTP_MASTER_MODE = n +-ENABLE_RSS_SUPPORT = n ++ENABLE_RSS_SUPPORT = y + ENABLE_LIB_SUPPORT = n + ENABLE_USE_FIRMWARE_FILE = n + DISABLE_WOL_SUPPORT = n diff --git a/package/lean/r8126/src/Makefile b/package/lean/r8126/src/Makefile new file mode 100644 index 000000000..3e75c19ef --- /dev/null +++ b/package/lean/r8126/src/Makefile @@ -0,0 +1,209 @@ +# SPDX-License-Identifier: GPL-2.0-only +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ + +################################################################################ +# This product is covered by one or more of the following patents: +# US6,570,884, US6,115,776, and US6,327,625. +################################################################################ + +CONFIG_SOC_LAN = n +ENABLE_REALWOW_SUPPORT = n +ENABLE_DASH_SUPPORT = n +ENABLE_DASH_PRINTER_SUPPORT = n +CONFIG_DOWN_SPEED_100 = n +CONFIG_ASPM = y +ENABLE_S5WOL = y +ENABLE_S5_KEEP_CURR_MAC = n +ENABLE_EEE = y +ENABLE_S0_MAGIC_PACKET = n +ENABLE_TX_NO_CLOSE = y +ENABLE_MULTIPLE_TX_QUEUE = y +ENABLE_PTP_SUPPORT = n +ENABLE_PTP_MASTER_MODE = n +ENABLE_RSS_SUPPORT = n +ENABLE_LIB_SUPPORT = n +ENABLE_USE_FIRMWARE_FILE = n +DISABLE_WOL_SUPPORT = n +DISABLE_MULTI_MSIX_VECTOR = n +ENABLE_DOUBLE_VLAN = n +ENABLE_PAGE_REUSE = n +ENABLE_RX_PACKET_FRAGMENT = n + +ifneq ($(KERNELRELEASE),) + obj-m := r8126.o + r8126-objs := r8126_n.o rtl_eeprom.o rtltool.o + ifeq ($(CONFIG_SOC_LAN), y) + EXTRA_CFLAGS += -DCONFIG_SOC_LAN + endif + ifeq ($(ENABLE_REALWOW_SUPPORT), y) + r8126-objs += r8126_realwow.o + EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT + endif + ifeq ($(ENABLE_DASH_SUPPORT), y) + r8126-objs += r8126_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT + endif + ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y) + r8126-objs += r8126_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT + endif + EXTRA_CFLAGS += -DCONFIG_R8126_NAPI + EXTRA_CFLAGS += -DCONFIG_R8126_VLAN + ifeq ($(CONFIG_DOWN_SPEED_100), y) + EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100 + endif + ifeq ($(CONFIG_ASPM), y) + EXTRA_CFLAGS += -DCONFIG_ASPM + endif + ifeq ($(ENABLE_S5WOL), y) + EXTRA_CFLAGS += -DENABLE_S5WOL + endif + ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y) + EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC + endif + ifeq ($(ENABLE_EEE), y) + EXTRA_CFLAGS += -DENABLE_EEE + endif + ifeq ($(ENABLE_S0_MAGIC_PACKET), y) + EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET + endif + ifeq ($(ENABLE_TX_NO_CLOSE), y) + EXTRA_CFLAGS += -DENABLE_TX_NO_CLOSE + endif + ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y) + EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE + endif + ifeq ($(ENABLE_PTP_SUPPORT), y) + r8126-objs += r8126_ptp.o + EXTRA_CFLAGS += -DENABLE_PTP_SUPPORT + endif + ifeq ($(ENABLE_PTP_MASTER_MODE), y) + EXTRA_CFLAGS += -DENABLE_PTP_MASTER_MODE + endif + ifeq ($(ENABLE_RSS_SUPPORT), y) + r8126-objs += r8126_rss.o + EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT + endif + ifeq ($(ENABLE_LIB_SUPPORT), y) + r8126-objs += r8126_lib.o + EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT + endif + ifeq ($(ENABLE_USE_FIRMWARE_FILE), y) + r8126-objs += r8126_firmware.o + EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE + endif + ifeq ($(DISABLE_WOL_SUPPORT), y) + EXTRA_CFLAGS += -DDISABLE_WOL_SUPPORT + endif + ifeq ($(DISABLE_MULTI_MSIX_VECTOR), y) + EXTRA_CFLAGS += -DDISABLE_MULTI_MSIX_VECTOR + endif + ifeq ($(ENABLE_DOUBLE_VLAN), y) + EXTRA_CFLAGS += -DENABLE_DOUBLE_VLAN + endif + ifeq ($(ENABLE_PAGE_REUSE), y) + EXTRA_CFLAGS += -DENABLE_PAGE_REUSE + endif + ifeq ($(ENABLE_RX_PACKET_FRAGMENT), y) + EXTRA_CFLAGS += -DENABLE_RX_PACKET_FRAGMENT + endif +else + BASEDIR := /lib/modules/$(shell uname -r) + KERNELDIR ?= $(BASEDIR)/build + PWD :=$(shell pwd) + DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net/ethernet -name realtek -type d) + ifeq ($(DRIVERDIR),) + DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net -name realtek -type d) + endif + ifeq ($(DRIVERDIR),) + DRIVERDIR := $(BASEDIR)/kernel/drivers/net + endif + RTKDIR := $(subst $(BASEDIR)/,,$(DRIVERDIR)) + + KERNEL_GCC_VERSION := $(shell cat /proc/version | sed -n 's/.*gcc version \([[:digit:]]\.[[:digit:]]\.[[:digit:]]\).*/\1/p') + CCVERSION = $(shell $(CC) -dumpversion) + + KVER = $(shell uname -r) + KMAJ = $(shell echo $(KVER) | \ + sed -e 's/^\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*.*/\1/') + KMIN = $(shell echo $(KVER) | \ + sed -e 's/^[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*.*/\1/') + KREV = $(shell echo $(KVER) | \ + sed -e 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/') + + kver_ge = $(shell \ + echo test | awk '{if($(KMAJ) < $(1)) {print 0} else { \ + if($(KMAJ) > $(1)) {print 1} else { \ + if($(KMIN) < $(2)) {print 0} else { \ + if($(KMIN) > $(2)) {print 1} else { \ + if($(KREV) < $(3)) {print 0} else { print 1 } \ + }}}}}' \ + ) + +.PHONY: all +all: print_vars clean modules install + +print_vars: + @echo + @echo "CC: " $(CC) + @echo "CCVERSION: " $(CCVERSION) + @echo "KERNEL_GCC_VERSION: " $(KERNEL_GCC_VERSION) + @echo "KVER: " $(KVER) + @echo "KMAJ: " $(KMAJ) + @echo "KMIN: " $(KMIN) + @echo "KREV: " $(KREV) + @echo "BASEDIR: " $(BASEDIR) + @echo "DRIVERDIR: " $(DRIVERDIR) + @echo "PWD: " $(PWD) + @echo "RTKDIR: " $(RTKDIR) + @echo + +.PHONY:modules +modules: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules +#endif + +.PHONY:clean +clean: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) clean +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean +#endif + +.PHONY:install +install: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install +#endif + +endif diff --git a/package/lean/r8126/src/Makefile_linux24x b/package/lean/r8126/src/Makefile_linux24x new file mode 100644 index 000000000..244bb08c8 --- /dev/null +++ b/package/lean/r8126/src/Makefile_linux24x @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-only +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ + +################################################################################ +# This product is covered by one or more of the following patents: +# US6,570,884, US6,115,776, and US6,327,625. +################################################################################ + +CC := gcc +LD := ld +ARCH := $(shell uname -m | sed 's/i.86/i386/') +KSRC := /lib/modules/$(shell uname -r)/build +CONFIG_FILE := $(KSRC)/include/linux/autoconf.h +KMISC := /lib/modules/$(shell uname -r)/kernel/drivers/net/ + + +ifeq ($(ARCH),x86_64) + MODCFLAGS += -mcmodel=kernel -mno-red-zone +endif + +#standard flags for module builds +MODCFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall +MODCFLAGS += -I$(KSRC)/include -I. +MODCFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/linux/modversions.h +SOURCE := r8126_n.c rtl_eeprom.c rtltool.c +OBJS := $(SOURCE:.c=.o) + + +SMP := $(shell $(CC) $(MODCFLAGS) -E -dM $(CONFIG_FILE) | \ + grep CONFIG_SMP | awk '{print $$3}') + +ifneq ($(SMP),1) + SMP := 0 +endif + +ifeq ($(SMP),1) + MODCFLAGS += -D__SMP__ +endif + +modules: $(OBJS) + $(LD) -r $^ -o r8126.o + strip --strip-debug r8126.o + +%.o: %.c + $(CC) $(MODCFLAGS) -c $< -o $@ + +clean: + rm *.o -f + +install: + install -m 744 -c r8126.o $(KMISC) diff --git a/package/lean/r8126/src/r8126.h b/package/lean/r8126/src/r8126.h new file mode 100644 index 000000000..9c66f2441 --- /dev/null +++ b/package/lean/r8126/src/r8126.h @@ -0,0 +1,2789 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef __R8126_H +#define __R8126_H + +//#include +#include +#include +#include +#include "r8126_dash.h" +#include "r8126_realwow.h" +#include "r8126_ptp.h" +#include "r8126_rss.h" +#ifdef ENABLE_LIB_SUPPORT +#include "r8126_lib.h" +#endif + +#ifndef fallthrough +#define fallthrough +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) +static inline +ssize_t strscpy(char *dest, const char *src, size_t count) +{ + long res = 0; + + if (count == 0) + return -E2BIG; + + while (count) { + char c; + + c = src[res]; + dest[res] = c; + if (!c) + return res; + res++; + count--; + } + + /* Hit buffer length without finding a NUL; force NUL-termination. */ + if (res) + dest[res-1] = '\0'; + + return -E2BIG; +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) +static inline unsigned char *skb_checksum_start(const struct sk_buff *skb) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) + return skb->head + skb->csum_start; +#else /* < 2.6.22 */ + return skb_transport_header(skb); +#endif +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, + unsigned int bytes) +{} +static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, + unsigned int pkts, + unsigned int bytes) +{} +static inline void netdev_tx_reset_queue(struct netdev_queue *q) {} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0) +#define netdev_xmit_more() (0) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) +#define netif_testing_on(dev) +#define netif_testing_off(dev) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) +typedef int netdev_tx_t; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) +static inline bool dev_page_is_reusable(struct page *page) +{ + return likely(page_to_nid(page) == numa_mem_id() && + !page_is_pfmemalloc(page)); +} +#endif + +/* +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)&& !defined(ENABLE_LIB_SUPPORT) +#define RTL_USE_NEW_INTR_API +#endif +*/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) +#define dma_map_page_attrs(dev, page, offset, size, dir, attrs) \ + dma_map_page(dev, page, offset, size, dir) +#define dma_unmap_page_attrs(dev, page, size, dir, attrs) \ + dma_unmap_page(dev, page, size, dir) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) +#define page_ref_inc(page) atomic_inc(&page->_count) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,216) +#define page_ref_count(page) atomic_read(&page->_count) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,4,216) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define skb_transport_offset(skb) (skb->h.raw - skb->data) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define device_set_wakeup_enable(dev, val) do {} while (0) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) +static inline void ether_addr_copy(u8 *dst, const u8 *src) +{ + u16 *a = (u16 *)dst; + const u16 *b = (const u16 *)src; + + a[0] = b[0]; + a[1] = b[1]; + a[2] = b[2]; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) +#define IS_ERR_OR_NULL(ptr) (!ptr) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) +#define reinit_completion(x) ((x)->done = 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#define pm_runtime_mark_last_busy(x) +#define pm_runtime_put_autosuspend(x) pm_runtime_put(x) +#define pm_runtime_put_sync_autosuspend(x) pm_runtime_put_sync(x) + +static inline bool pm_runtime_suspended(struct device *dev) +{ + return dev->power.runtime_status == RPM_SUSPENDED + && !dev->power.disable_depth; +} + +static inline bool pm_runtime_active(struct device *dev) +{ + return dev->power.runtime_status == RPM_ACTIVE + || dev->power.disable_depth; +} +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +#define queue_delayed_work(long_wq, work, delay) schedule_delayed_work(work, delay) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#define netif_printk(priv, type, level, netdev, fmt, args...) \ + do { \ + if (netif_msg_##type(priv)) \ + printk(level "%s: " fmt,(netdev)->name , ##args); \ + } while (0) + +#define netif_emerg(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_EMERG, netdev, fmt, ##args) +#define netif_alert(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_ALERT, netdev, fmt, ##args) +#define netif_crit(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_CRIT, netdev, fmt, ##args) +#define netif_err(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_ERR, netdev, fmt, ##args) +#define netif_warn(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_WARNING, netdev, fmt, ##args) +#define netif_notice(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_NOTICE, netdev, fmt, ##args) +#define netif_info(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_INFO, (netdev), fmt, ##args) +#endif +#endif +#endif +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#define setup_timer(_timer, _function, _data) \ +do { \ + (_timer)->function = _function; \ + (_timer)->data = _data; \ + init_timer(_timer); \ +} while (0) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) +#if defined(skb_vlan_tag_present) && !defined(vlan_tx_tag_present) +#define vlan_tx_tag_present skb_vlan_tag_present +#endif +#if defined(skb_vlan_tag_get) && !defined(vlan_tx_tag_get) +#define vlan_tx_tag_get skb_vlan_tag_get +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) + +#define RTL_ALLOC_SKB_INTR(napi, length) dev_alloc_skb(length) +#define R8126_USE_NAPI_ALLOC_SKB 0 +#ifdef CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) +#undef RTL_ALLOC_SKB_INTR +#define RTL_ALLOC_SKB_INTR(napi, length) napi_alloc_skb(napi, length) +#undef R8126_USE_NAPI_ALLOC_SKB +#define R8126_USE_NAPI_ALLOC_SKB 1 +#endif +#endif + +#define RTL_BUILD_SKB_INTR(data, frag_size) build_skb(data, frag_size) +#ifdef CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0) +#undef RTL_BUILD_SKB_INTR +#define RTL_BUILD_SKB_INTR(data, frag_size) napi_build_skb(data, frag_size) +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +#define eth_random_addr(addr) random_ether_addr(addr) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#define netdev_features_t u32 +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) +#define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK +#else +#ifndef NETIF_F_ALL_CSUM +#define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) +#define ENABLE_R8126_PROCFS +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#define ENABLE_R8126_SYSFS +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX +#define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) +#define __devinit +#define __devexit +#define __devexit_p(func) func +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define CHECKSUM_PARTIAL CHECKSUM_HW +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#define irqreturn_t void +#define IRQ_HANDLED 1 +#define IRQ_NONE 0 +#define IRQ_RETVAL(x) +#endif + +#ifndef NETIF_F_RXALL +#define NETIF_F_RXALL 0 +#endif + +#ifndef NETIF_F_RXFCS +#define NETIF_F_RXFCS 0 +#endif + +#if !defined(HAVE_FREE_NETDEV) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) +#define free_netdev(x) kfree(x) +#endif + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(net, pdev) +#endif + +#ifndef SET_MODULE_OWNER +#define SET_MODULE_OWNER(dev) +#endif + +#ifndef SA_SHIRQ +#define SA_SHIRQ IRQF_SHARED +#endif + +#ifndef NETIF_F_GSO +#define gso_size tso_size +#define gso_segs tso_segs +#endif + +#ifndef PCI_VENDOR_ID_DLINK +#define PCI_VENDOR_ID_DLINK 0x1186 +#endif + +#ifndef dma_mapping_error +#define dma_mapping_error(a,b) 0 +#endif + +#ifndef netif_err +#define netif_err(a,b,c,d) +#endif + +#ifndef AUTONEG_DISABLE +#define AUTONEG_DISABLE 0x00 +#endif + +#ifndef AUTONEG_ENABLE +#define AUTONEG_ENABLE 0x01 +#endif + +#ifndef BMCR_SPEED1000 +#define BMCR_SPEED1000 0x0040 +#endif + +#ifndef BMCR_SPEED100 +#define BMCR_SPEED100 0x2000 +#endif + +#ifndef BMCR_SPEED10 +#define BMCR_SPEED10 0x0000 +#endif + +#ifndef SPEED_UNKNOWN +#define SPEED_UNKNOWN -1 +#endif + +#ifndef DUPLEX_UNKNOWN +#define DUPLEX_UNKNOWN 0xff +#endif + +#ifndef SUPPORTED_Pause +#define SUPPORTED_Pause (1 << 13) +#endif + +#ifndef SUPPORTED_Asym_Pause +#define SUPPORTED_Asym_Pause (1 << 14) +#endif + +#ifndef MDIO_EEE_100TX +#define MDIO_EEE_100TX 0x0002 +#endif + +#ifndef MDIO_EEE_1000T +#define MDIO_EEE_1000T 0x0004 +#endif + +#ifndef MDIO_EEE_2_5GT +#define MDIO_EEE_2_5GT 0x0001 +#endif + +#ifndef MDIO_EEE_5GT +#define MDIO_EEE_5GT 0x0002 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +#ifdef CONFIG_NET_POLL_CONTROLLER +#define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8126_netpoll +#else +#define RTL_NET_POLL_CONTROLLER +#endif + +#ifdef CONFIG_R8126_VLAN +#define RTL_SET_VLAN dev->vlan_rx_register=rtl8126_vlan_rx_register +#else +#define RTL_SET_VLAN +#endif + +#define RTL_NET_DEVICE_OPS(ops) dev->open=rtl8126_open; \ + dev->hard_start_xmit=rtl8126_start_xmit; \ + dev->get_stats=rtl8126_get_stats; \ + dev->stop=rtl8126_close; \ + dev->tx_timeout=rtl8126_tx_timeout; \ + dev->set_multicast_list=rtl8126_set_rx_mode; \ + dev->change_mtu=rtl8126_change_mtu; \ + dev->set_mac_address=rtl8126_set_mac_address; \ + dev->do_ioctl=rtl8126_do_ioctl; \ + RTL_NET_POLL_CONTROLLER; \ + RTL_SET_VLAN; +#else +#define RTL_NET_DEVICE_OPS(ops) dev->netdev_ops=&ops +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +//Hardware will continue interrupt 10 times after interrupt finished. +#define RTK_KEEP_INTERRUPT_COUNT (10) + +//the low 32 bit address of receive buffer must be 8-byte alignment. +#ifndef NET_IP_ALIGN +#define NET_IP_ALIGN 2 +#endif +#define R8126_RX_ALIGN NET_IP_ALIGN + +#ifdef CONFIG_R8126_NAPI +#define NAPI_SUFFIX "-NAPI" +#else +#define NAPI_SUFFIX "" +#endif +#if defined(ENABLE_DASH_PRINTER_SUPPORT) +#define DASH_SUFFIX "-PRINTER" +#elif defined(ENABLE_DASH_SUPPORT) +#define DASH_SUFFIX "-DASH" +#else +#define DASH_SUFFIX "" +#endif + +#if defined(ENABLE_REALWOW_SUPPORT) +#define REALWOW_SUFFIX "-REALWOW" +#else +#define REALWOW_SUFFIX "" +#endif + +#if defined(ENABLE_PTP_SUPPORT) +#define PTP_SUFFIX "-PTP" +#else +#define PTP_SUFFIX "" +#endif + +#if defined(ENABLE_RSS_SUPPORT) +#define RSS_SUFFIX "-RSS" +#else +#define RSS_SUFFIX "" +#endif + +#define RTL8126_VERSION "10.013.00" NAPI_SUFFIX DASH_SUFFIX REALWOW_SUFFIX PTP_SUFFIX RSS_SUFFIX +#define MODULENAME "r8126" +#define PFX MODULENAME ": " + +#define GPL_CLAIM "\ +r8126 Copyright (C) 2024 Realtek NIC software team \n \ +This program comes with ABSOLUTELY NO WARRANTY; for details, please see . \n \ +This is free software, and you are welcome to redistribute it under certain conditions; see . \n" + +#ifdef RTL8126_DEBUG +#define assert(expr) \ + if(!(expr)) { \ + printk( "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) +#else +#define assert(expr) do {} while (0) +#define dprintk(fmt, args...) do {} while (0) +#endif /* RTL8126_DEBUG */ + +#define R8126_MSG_DEFAULT \ + (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) + +#ifdef CONFIG_R8126_NAPI +#define rtl8126_rx_hwaccel_skb vlan_hwaccel_receive_skb +#define rtl8126_rx_quota(count, quota) min(count, quota) +#else +#define rtl8126_rx_hwaccel_skb vlan_hwaccel_rx +#define rtl8126_rx_quota(count, quota) count +#endif + +/* MAC address length */ +#ifndef MAC_ADDR_LEN +#define MAC_ADDR_LEN 6 +#endif + +#ifndef MAC_PROTOCOL_LEN +#define MAC_PROTOCOL_LEN 2 +#endif + +#ifndef ETH_FCS_LEN +#define ETH_FCS_LEN 4 +#endif + +#ifndef NETIF_F_TSO6 +#define NETIF_F_TSO6 0 +#endif + +#define Reserved2_data 7 +#define RX_DMA_BURST_unlimited 7 /* Maximum PCI burst, '7' is unlimited */ +#define RX_DMA_BURST_512 5 +#define RX_DMA_BURST_256 4 +#define TX_DMA_BURST_unlimited 7 +#define TX_DMA_BURST_1024 6 +#define TX_DMA_BURST_512 5 +#define TX_DMA_BURST_256 4 +#define TX_DMA_BURST_128 3 +#define TX_DMA_BURST_64 2 +#define TX_DMA_BURST_32 1 +#define TX_DMA_BURST_16 0 +#define Reserved1_data 0x3F +#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ +#define Jumbo_Frame_1k ETH_DATA_LEN +#define Jumbo_Frame_2k (2*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_3k (3*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_4k (4*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_5k (5*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_6k (6*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_7k (7*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_8k (8*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_9k (9*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ +#define RxEarly_off_V1 (0x07 << 11) +#define RxEarly_off_V2 (1 << 11) +#define Rx_Single_fetch_V2 (1 << 14) +#define Rx_Close_Multiple (1 << 21) +#define Rx_Fetch_Number_8 (1 << 30) + +#define R8126_REGS_SIZE (256) +#define R8126_MAC_REGS_SIZE (256) +#define R8126_PHY_REGS_SIZE (16*2) +#define R8126_EPHY_REGS_SIZE (31*2) +#define R8126_ERI_REGS_SIZE (0x100) +#define R8126_REGS_DUMP_SIZE (0x400) +#define R8126_PCI_REGS_SIZE (0x100) +#define R8126_NAPI_WEIGHT 64 + +#define R8126_MAX_MSIX_VEC_8125A 4 +#define R8126_MAX_MSIX_VEC_8125B 32 +#define R8126_MAX_MSIX_VEC_8125D 32 +#define R8126_MIN_MSIX_VEC_8125B 22 +#define R8126_MIN_MSIX_VEC_8125BP 31 +#define R8126_MIN_MSIX_VEC_8125D 20 +#define R8126_MAX_MSIX_VEC 32 +#define R8126_MAX_RX_QUEUES_VEC_V3 (16) + +#define RTL8126_TX_TIMEOUT (6 * HZ) +#define RTL8126_LINK_TIMEOUT (1 * HZ) +#define RTL8126_ESD_TIMEOUT (2 * HZ) + +#define rtl8126_rx_page_size(order) (PAGE_SIZE << order) + +#define MAX_NUM_TX_DESC 1024 /* Maximum number of Tx descriptor registers */ +#define MAX_NUM_RX_DESC 1024 /* Maximum number of Rx descriptor registers */ + +#define MIN_NUM_TX_DESC 256 /* Minimum number of Tx descriptor registers */ +#define MIN_NUM_RX_DESC 256 /* Minimum number of Rx descriptor registers */ + +#define NUM_TX_DESC MAX_NUM_TX_DESC /* Number of Tx descriptor registers */ +#define NUM_RX_DESC MAX_NUM_RX_DESC /* Number of Rx descriptor registers */ + +#ifdef ENABLE_DOUBLE_VLAN +#define RX_BUF_SIZE 0x05F6 /* 0x05F6(1526) = 1514 + 8(double vlan) + 4(crc) bytes */ +#define RT_VALN_HLEN 8 /* 8(double vlan) bytes */ +#else +#define RX_BUF_SIZE 0x05F2 /* 0x05F2(1522) = 1514 + 4(single vlan) + 4(crc) bytes */ +#define RT_VALN_HLEN 4 /* 4(single vlan) bytes */ +#endif + +#define R8126_MAX_TX_QUEUES (2) +#define R8126_MAX_RX_QUEUES (4) +#define R8126_MAX_QUEUES R8126_MAX_RX_QUEUES + +#define OCP_STD_PHY_BASE 0xa400 + +//Channel Wait Count +#define R8126_CHANNEL_WAIT_COUNT (20000) +#define R8126_CHANNEL_WAIT_TIME (1) // 1us +#define R8126_CHANNEL_EXIT_DELAY_TIME (20) //20us + +#ifdef ENABLE_LIB_SUPPORT +#define R8126_MULTI_RX_Q(tp) 0 +#else +#define R8126_MULTI_RX_Q(tp) (tp->num_rx_rings > 1) +#endif + +#define NODE_ADDRESS_SIZE 6 + +#define SHORT_PACKET_PADDING_BUF_SIZE 256 + +#define RTK_MAGIC_DEBUG_VALUE 0x0badbeef + +/* write/read MMIO register */ +#define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) +#define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) +#define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg)) +#define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg)) +#define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg)) +#define RTL_R32(tp, reg) ((unsigned long) readl(tp->mmio_addr + (reg))) + +#ifndef DMA_64BIT_MASK +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#endif + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 /* driver took care of packet */ +#endif + +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ +#endif + +#ifndef NETDEV_TX_LOCKED +#define NETDEV_TX_LOCKED -1t /* driver tx lock was already taken */ +#endif + +#ifndef ADVERTISED_Pause +#define ADVERTISED_Pause (1 << 13) +#endif + +#ifndef ADVERTISED_Asym_Pause +#define ADVERTISED_Asym_Pause (1 << 14) +#endif + +#ifndef ADVERTISE_PAUSE_CAP +#define ADVERTISE_PAUSE_CAP 0x400 +#endif + +#ifndef ADVERTISE_PAUSE_ASYM +#define ADVERTISE_PAUSE_ASYM 0x800 +#endif + +#ifndef MII_CTRL1000 +#define MII_CTRL1000 0x09 +#endif + +#ifndef ADVERTISE_1000FULL +#define ADVERTISE_1000FULL 0x200 +#endif + +#ifndef ADVERTISE_1000HALF +#define ADVERTISE_1000HALF 0x100 +#endif + +#ifndef ADVERTISED_2500baseX_Full +#define ADVERTISED_2500baseX_Full 0x8000 +#endif +#define RTK_ADVERTISED_5000baseX_Full BIT(48) + +#define RTK_ADVERTISE_2500FULL 0x80 +#define RTK_ADVERTISE_5000FULL 0x100 +#define RTK_ADVERTISE_10000FULL 0x1000 +#define RTK_LPA_ADVERTISE_2500FULL 0x20 +#define RTK_LPA_ADVERTISE_5000FULL 0x40 +#define RTK_LPA_ADVERTISE_10000FULL 0x800 + +#define RTK_EEE_ADVERTISE_2500FULL BIT(0) +#define RTK_EEE_ADVERTISE_5000FULL BIT(1) +#define RTK_LPA_EEE_ADVERTISE_2500FULL BIT(0) +#define RTK_LPA_EEE_ADVERTISE_5000FULL BIT(1) + +/* Tx NO CLOSE */ +#define MAX_TX_NO_CLOSE_DESC_PTR_V2 0x10000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2 0xFFFF +#define MAX_TX_NO_CLOSE_DESC_PTR_V3 0x100000000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3 0xFFFFFFFF +#define MAX_TX_NO_CLOSE_DESC_PTR_V4 0x80000000 +#define MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4 0x7FFFFFFF +#define TX_NO_CLOSE_SW_PTR_MASK_V2 0x1FFFF + +#ifndef ETH_MIN_MTU +#define ETH_MIN_MTU 68 +#endif + +#define D0_SPEED_UP_SPEED_DISABLE 0 +#define D0_SPEED_UP_SPEED_1000 1 +#define D0_SPEED_UP_SPEED_2500 2 +#define D0_SPEED_UP_SPEED_5000 3 + +#define RTL8126_MAC_MCU_PAGE_SIZE 256 //256 words + +#ifndef WRITE_ONCE +#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) +#endif +#ifndef READ_ONCE +#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) +#endif + +#ifndef SPEED_5000 +#define SPEED_5000 5000 +#endif + +/*****************************************************************************/ + +//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) +#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \ + (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \ + ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ))) +/* copied from linux kernel 2.6.20 include/linux/netdev.h */ +#define NETDEV_ALIGN 32 +#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) + +static inline void *netdev_priv(struct net_device *dev) +{ + return (char *)dev + ((sizeof(struct net_device) + + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define RTLDEV tp +#else +#define RTLDEV dev +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +typedef struct net_device *napi_ptr; +typedef int *napi_budget; + +#define napi dev +#define RTL_NAPI_CONFIG(ndev, priv, function, weig) ndev->poll=function; \ + ndev->weight=weig; +#define RTL_NAPI_QUOTA(budget, ndev) min(*budget, ndev->quota) +#define RTL_GET_PRIV(stuct_ptr, priv_struct) netdev_priv(stuct_ptr) +#define RTL_GET_NETDEV(priv_ptr) +#define RTL_RX_QUOTA(budget) *budget +#define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) *budget -= work_done; \ + ndev->quota -= work_done; +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev) +#define RTL_NAPI_RETURN_VALUE work_done >= work_to_do +#define RTL_NAPI_ENABLE(dev, napi) netif_poll_enable(dev) +#define RTL_NAPI_DISABLE(dev, napi) netif_poll_disable(dev) +#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#else +typedef struct napi_struct *napi_ptr; +typedef int napi_budget; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) +#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight) +#else +#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) +#define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) +#define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) +#define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; +#define RTL_RX_QUOTA(budget) budget +#define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev, napi) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev, napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev, napi) +#endif +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(napi) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(napi) +#endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete_done(napi, work_done) +#else +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete(napi) +#endif +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) napi_schedule_prep(napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __napi_schedule(napi) +#endif +#define RTL_NAPI_RETURN_VALUE work_done +#define RTL_NAPI_ENABLE(dev, napi) napi_enable(napi) +#define RTL_NAPI_DISABLE(dev, napi) napi_disable(napi) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#define RTL_NAPI_DEL(priv) +#else +#define RTL_NAPI_DEL(priv) netif_napi_del(&priv->napi) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + +/*****************************************************************************/ +#ifdef CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) napi_consume_skb(skb, budget) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#else //CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif +#endif //CONFIG_R8126_NAPI + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) +#ifdef __CHECKER__ +#define __iomem __attribute__((noderef, address_space(2))) +extern void __chk_io_ptr(void __iomem *); +#define __bitwise __attribute__((bitwise)) +#else +#define __iomem +#define __chk_io_ptr(x) (void)0 +#define __bitwise +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#else +#define __force +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) + +#ifndef module_param +#define module_param(v,t,p) MODULE_PARM(v, "i"); +#endif + +#ifndef PCI_DEVICE +#define PCI_DEVICE(vend,dev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID +#endif + +/*****************************************************************************/ +/* 2.5.28 => 2.4.23 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) + +static inline void _kc_synchronize_irq(void) +{ + synchronize_irq(); +} +#undef synchronize_irq +#define synchronize_irq(X) _kc_synchronize_irq() + +#include +#define work_struct tq_struct +#undef INIT_WORK +#define INIT_WORK(a,b,c) INIT_TQUEUE(a,(void (*)(void *))b,c) +#undef container_of +#define container_of list_entry +#define schedule_work schedule_task +#define flush_scheduled_work flush_scheduled_tasks +#endif /* 2.5.28 => 2.4.17 */ + +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +#define MODULE_VERSION(_version) MODULE_INFO(version, _version) +#endif /* 2.6.4 => 2.6.0 */ +/*****************************************************************************/ +/* 2.6.0 => 2.5.28 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#define MODULE_INFO(version, _version) +#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT +#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 +#endif + +#define pci_set_consistent_dma_mask(dev,mask) 1 + +#undef dev_put +#define dev_put(dev) __dev_put(dev) + +#ifndef skb_fill_page_desc +#define skb_fill_page_desc _kc_skb_fill_page_desc +extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size); +#endif + +#ifndef pci_dma_mapping_error +#define pci_dma_mapping_error _kc_pci_dma_mapping_error +static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) +{ + return dma_addr == 0; +} +#endif + +#undef ALIGN +#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) + +#endif /* 2.6.0 => 2.5.28 */ + +/*****************************************************************************/ +/* 2.4.22 => 2.4.17 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) +#define pci_name(x) ((x)->slot_name) +#endif /* 2.4.22 => 2.4.17 */ + +/*****************************************************************************/ +/* 2.6.5 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) +#define pci_dma_sync_single_for_cpu pci_dma_sync_single +#define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu +#endif /* 2.6.5 => 2.6.0 */ + +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +/* + * initialize a work-struct's func and data pointers: + */ +#define PREPARE_WORK(_work, _func, _data) \ + do { \ + (_work)->func = _func; \ + (_work)->data = _data; \ + } while (0) + +#endif +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) && \ + LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4))) +#define ETHTOOL_OPS_COMPAT +#endif /* 2.6.4 => 2.6.0 */ + +/*****************************************************************************/ +/* Installations with ethtool version without eeprom, adapter id, or statistics + * support */ + +#ifndef ETH_GSTRING_LEN +#define ETH_GSTRING_LEN 32 +#endif + +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x1d +#undef ethtool_drvinfo +#define ethtool_drvinfo k_ethtool_drvinfo +struct k_ethtool_drvinfo { + u32 cmd; + char driver[32]; + char version[32]; + char fw_version[32]; + char bus_info[32]; + char reserved1[32]; + char reserved2[16]; + u32 n_stats; + u32 testinfo_len; + u32 eedump_len; + u32 regdump_len; +}; + +struct ethtool_stats { + u32 cmd; + u32 n_stats; + u64 data[0]; +}; +#endif /* ETHTOOL_GSTATS */ + +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x1c +#endif /* ETHTOOL_PHYS_ID */ + +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x1b +enum ethtool_stringset { + ETH_SS_TEST = 0, + ETH_SS_STATS, +}; +struct ethtool_gstrings { + u32 cmd; /* ETHTOOL_GSTRINGS */ + u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ + u32 len; /* number of strings in the string set */ + u8 data[0]; +}; +#endif /* ETHTOOL_GSTRINGS */ + +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x1a +enum ethtool_test_flags { + ETH_TEST_FL_OFFLINE = (1 << 0), + ETH_TEST_FL_FAILED = (1 << 1), +}; +struct ethtool_test { + u32 cmd; + u32 flags; + u32 reserved; + u32 len; + u64 data[0]; +}; +#endif /* ETHTOOL_TEST */ + +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0xb +#undef ETHTOOL_GREGS +struct ethtool_eeprom { + u32 cmd; + u32 magic; + u32 offset; + u32 len; + u8 data[0]; +}; + +struct ethtool_value { + u32 cmd; + u32 data; +}; +#endif /* ETHTOOL_GEEPROM */ + +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0xa +#endif /* ETHTOOL_GLINK */ + +#ifndef ETHTOOL_GREGS +#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */ +#define ethtool_regs _kc_ethtool_regs +/* for passing big chunks of data */ +struct _kc_ethtool_regs { + u32 cmd; + u32 version; /* driver-specific, indicates different chips/revs */ + u32 len; /* bytes */ + u8 data[0]; +}; +#endif /* ETHTOOL_GREGS */ + +#ifndef ETHTOOL_GMSGLVL +#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ +#endif +#ifndef ETHTOOL_SMSGLVL +#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ +#endif +#ifndef ETHTOOL_NWAY_RST +#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */ +#endif +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0x0000000a /* Get link status */ +#endif +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ +#endif +#ifndef ETHTOOL_SEEPROM +#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ +#endif +#ifndef ETHTOOL_GCOALESCE +#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ +/* for configuring coalescing parameters of chip */ +#define ethtool_coalesce _kc_ethtool_coalesce +struct _kc_ethtool_coalesce { + u32 cmd; /* ETHTOOL_{G,S}COALESCE */ + + /* How many usecs to delay an RX interrupt after + * a packet arrives. If 0, only rx_max_coalesced_frames + * is used. + */ + u32 rx_coalesce_usecs; + + /* How many packets to delay an RX interrupt after + * a packet arrives. If 0, only rx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause RX interrupts to never be + * generated. + */ + u32 rx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 rx_coalesce_usecs_irq; + u32 rx_max_coalesced_frames_irq; + + /* How many usecs to delay a TX interrupt after + * a packet is sent. If 0, only tx_max_coalesced_frames + * is used. + */ + u32 tx_coalesce_usecs; + + /* How many packets to delay a TX interrupt after + * a packet is sent. If 0, only tx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause TX interrupts to never be + * generated. + */ + u32 tx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 tx_coalesce_usecs_irq; + u32 tx_max_coalesced_frames_irq; + + /* How many usecs to delay in-memory statistics + * block updates. Some drivers do not have an in-memory + * statistic block, and in such cases this value is ignored. + * This value must not be zero. + */ + u32 stats_block_coalesce_usecs; + + /* Adaptive RX/TX coalescing is an algorithm implemented by + * some drivers to improve latency under low packet rates and + * improve throughput under high packet rates. Some drivers + * only implement one of RX or TX adaptive coalescing. Anything + * not implemented by the driver causes these values to be + * silently ignored. + */ + u32 use_adaptive_rx_coalesce; + u32 use_adaptive_tx_coalesce; + + /* When the packet rate (measured in packets per second) + * is below pkt_rate_low, the {rx,tx}_*_low parameters are + * used. + */ + u32 pkt_rate_low; + u32 rx_coalesce_usecs_low; + u32 rx_max_coalesced_frames_low; + u32 tx_coalesce_usecs_low; + u32 tx_max_coalesced_frames_low; + + /* When the packet rate is below pkt_rate_high but above + * pkt_rate_low (both measured in packets per second) the + * normal {rx,tx}_* coalescing parameters are used. + */ + + /* When the packet rate is (measured in packets per second) + * is above pkt_rate_high, the {rx,tx}_*_high parameters are + * used. + */ + u32 pkt_rate_high; + u32 rx_coalesce_usecs_high; + u32 rx_max_coalesced_frames_high; + u32 tx_coalesce_usecs_high; + u32 tx_max_coalesced_frames_high; + + /* How often to do adaptive coalescing packet rate sampling, + * measured in seconds. Must not be zero. + */ + u32 rate_sample_interval; +}; +#endif /* ETHTOOL_GCOALESCE */ + +#ifndef ETHTOOL_SCOALESCE +#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ +#endif +#ifndef ETHTOOL_GRINGPARAM +#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ +/* for configuring RX/TX ring parameters */ +#define ethtool_ringparam _kc_ethtool_ringparam +struct _kc_ethtool_ringparam { + u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ + + /* Read only attributes. These indicate the maximum number + * of pending RX/TX ring entries the driver will allow the + * user to set. + */ + u32 rx_max_pending; + u32 rx_mini_max_pending; + u32 rx_jumbo_max_pending; + u32 tx_max_pending; + + /* Values changeable by the user. The valid values are + * in the range 1 to the "*_max_pending" counterpart above. + */ + u32 rx_pending; + u32 rx_mini_pending; + u32 rx_jumbo_pending; + u32 tx_pending; +}; +#endif /* ETHTOOL_GRINGPARAM */ + +#ifndef ETHTOOL_SRINGPARAM +#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ +#endif +#ifndef ETHTOOL_GPAUSEPARAM +#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ +/* for configuring link flow control parameters */ +#define ethtool_pauseparam _kc_ethtool_pauseparam +struct _kc_ethtool_pauseparam { + u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ + + /* If the link is being auto-negotiated (via ethtool_cmd.autoneg + * being true) the user may set 'autonet' here non-zero to have the + * pause parameters be auto-negotiated too. In such a case, the + * {rx,tx}_pause values below determine what capabilities are + * advertised. + * + * If 'autoneg' is zero or the link is not being auto-negotiated, + * then {rx,tx}_pause force the driver to use/not-use pause + * flow control. + */ + u32 autoneg; + u32 rx_pause; + u32 tx_pause; +}; +#endif /* ETHTOOL_GPAUSEPARAM */ + +#ifndef ETHTOOL_SPAUSEPARAM +#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ +#endif +#ifndef ETHTOOL_GRXCSUM +#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_SRXCSUM +#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GTXCSUM +#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STXCSUM +#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GSG +#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable +* (ethtool_value) */ +#endif +#ifndef ETHTOOL_SSG +#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable +* (ethtool_value). */ +#endif +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ +#endif +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ +#endif +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ +#endif +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ +#endif +#ifndef ETHTOOL_GTSO +#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STSO +#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ +#endif + +#ifndef ETHTOOL_BUSINFO_LEN +#define ETHTOOL_BUSINFO_LEN 32 +#endif + +/*****************************************************************************/ + +enum RTL8126_registers { + MAC0 = 0x00, /* Ethernet hardware address. */ + MAC4 = 0x04, + MAR0 = 0x08, /* Multicast filter. */ + CounterAddrLow = 0x10, + CounterAddrHigh = 0x14, + CustomLED = 0x18, + TxDescStartAddrLow = 0x20, + TxDescStartAddrHigh = 0x24, + TxHDescStartAddrLow = 0x28, + TxHDescStartAddrHigh = 0x2c, + FLASH = 0x30, + INT_CFG0_8125 = 0x34, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, + IntrMask = 0x3C, + IntrStatus = 0x3E, + TxConfig = 0x40, + RxConfig = 0x44, + TCTR = 0x48, + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, + TDFNR = 0x57, + TimeInt0 = 0x58, + TimeInt1 = 0x5C, + PHYAR = 0x60, + CSIDR = 0x64, + CSIAR = 0x68, + PHYstatus = 0x6C, + MACDBG = 0x6D, + GPIO = 0x6E, + PMCH = 0x6F, + ERIDR = 0x70, + ERIAR = 0x74, + INT_CFG1_8125 = 0x7A, + EPHY_RXER_NUM = 0x7C, + EPHYAR = 0x80, + TimeInt2 = 0x8C, + OCPDR = 0xB0, + MACOCP = 0xB0, + OCPAR = 0xB4, + SecMAC0 = 0xB4, + SecMAC4 = 0xB8, + PHYOCP = 0xB8, + DBG_reg = 0xD1, + TwiCmdReg = 0xD2, + MCUCmd_reg = 0xD3, + RxMaxSize = 0xDA, + EFUSEAR = 0xDC, + CPlusCmd = 0xE0, + IntrMitigate = 0xE2, + RxDescAddrLow = 0xE4, + RxDescAddrHigh = 0xE8, + MTPS = 0xEC, + FuncEvent = 0xF0, + PPSW = 0xF2, + FuncEventMask = 0xF4, + TimeInt3 = 0xF4, + FuncPresetState = 0xF8, + CMAC_IBCR0 = 0xF8, + CMAC_IBCR2 = 0xF9, + CMAC_IBIMR0 = 0xFA, + CMAC_IBISR0 = 0xFB, + FuncForceEvent = 0xFC, + //8125 + IMR0_8125 = 0x38, + ISR0_8125 = 0x3C, + TPPOLL_8125 = 0x90, + IMR1_8125 = 0x800, + ISR1_8125 = 0x802, + IMR2_8125 = 0x804, + ISR2_8125 = 0x806, + IMR3_8125 = 0x808, + ISR3_8125 = 0x80A, + BACKUP_ADDR0_8125 = 0x19E0, + BACKUP_ADDR1_8125 = 0X19E4, + TCTR0_8125 = 0x0048, + TCTR1_8125 = 0x004C, + TCTR2_8125 = 0x0088, + TCTR3_8125 = 0x001C, + TIMER_INT0_8125 = 0x0058, + TIMER_INT1_8125 = 0x005C, + TIMER_INT2_8125 = 0x008C, + TIMER_INT3_8125 = 0x00F4, + INT_MITI_V2_0_RX = 0x0A00, + INT_MITI_V2_0_TX = 0x0A02, + INT_MITI_V2_1_RX = 0x0A08, + INT_MITI_V2_1_TX = 0x0A0A, + IMR_V2_CLEAR_REG_8125 = 0x0D00, + ISR_V2_8125 = 0x0D04, + IMR_V2_SET_REG_8125 = 0x0D0C, + TDU_STA_8125 = 0x0D08, + RDU_STA_8125 = 0x0D0A, + IMR_V4_L2_CLEAR_REG_8125 = 0x0D10, + IMR_V4_L2_SET_REG_8125 = 0x0D18, + ISR_V4_L2_8125 = 0x0D14, + SW_TAIL_PTR0_8125BP = 0x0D30, + SW_TAIL_PTR1_8125BP = 0x0D38, + HW_CLO_PTR0_8125BP = 0x0D34, + HW_CLO_PTR1_8125BP = 0x0D3C, + DOUBLE_VLAN_CONFIG = 0x1000, + TX_NEW_CTRL = 0x203E, + TNPDS_Q1_LOW_8125 = 0x2100, + PLA_TXQ0_IDLE_CREDIT = 0x2500, + PLA_TXQ1_IDLE_CREDIT = 0x2504, + SW_TAIL_PTR0_8125 = 0x2800, + HW_CLO_PTR0_8125 = 0x2802, + SW_TAIL_PTR0_8126 = 0x2800, + HW_CLO_PTR0_8126 = 0x2800, + RDSAR_Q1_LOW_8125 = 0x4000, + RSS_CTRL_8125 = 0x4500, + Q_NUM_CTRL_8125 = 0x4800, + RSS_KEY_8125 = 0x4600, + RSS_INDIRECTION_TBL_8125_V2 = 0x4700, + EEE_TXIDLE_TIMER_8125 = 0x6048, + PTP_CTRL_8125 = 0x6800, + PTP_STATUS_8125 = 0x6802, + PTP_ISR_8125 = 0x6804, + PTP_IMR_8125 = 0x6805, + PTP_TIME_CORRECT_CMD_8125 = 0x6806, + PTP_SOFT_CONFIG_Time_NS_8125 = 0x6808, + PTP_SOFT_CONFIG_Time_S_8125 = 0x680C, + PTP_SOFT_CONFIG_Time_Sign = 0x6812, + PTP_LOCAL_Time_SUB_NS_8125 = 0x6814, + PTP_LOCAL_Time_NS_8125 = 0x6818, + PTP_LOCAL_Time_S_8125 = 0x681C, + PTP_Time_SHIFTER_S_8125 = 0x6856, + PPS_RISE_TIME_NS_8125 = 0x68A0, + PPS_RISE_TIME_S_8125 = 0x68A4, + PTP_EGRESS_TIME_BASE_NS_8125 = 0XCF20, + PTP_EGRESS_TIME_BASE_S_8125 = 0XCF24, + + //TCAM + TCAM_NOTVALID_ADDR = 0xA000, + TCAM_VALID_ADDR = 0xA800, + TCAM_MAC_ADDR = 448, + TCAM_VLAN_TAG = 496, + //TCAM V2 + TCAM_NOTVALID_ADDR_V2 = 0xA000, + TCAM_VALID_ADDR_V2 = 0xB000, + TCAM_MAC_ADDR_V2 = 0x00, + TCAM_VLAN_TAG_V2 = 0x03, +}; + +enum RTL8126_register_content { + /* InterruptStatusBits */ + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x0080, + RxFIFOOver = 0x0040, + LinkChg = 0x0020, + RxDescUnavail = 0x0010, + TxErr = 0x0008, + TxOK = 0x0004, + RxErr = 0x0002, + RxOK = 0x0001, + RxDU1 = 0x0002, + RxOK1 = 0x0001, + + /* RxStatusDesc */ + RxRWT = (1 << 22), + RxRES = (1 << 21), + RxRUNT = (1 << 20), + RxCRC = (1 << 19), + + RxRWT_V3 = (1 << 18), + RxRES_V3 = (1 << 20), + RxRUNT_V3 = (1 << 19), + RxCRC_V3 = (1 << 17), + + /* ChipCmdBits */ + StopReq = 0x80, + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, + + /* Cfg9346Bits */ + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xC0, + Cfg9346_EEDO = (1 << 0), + Cfg9346_EEDI = (1 << 1), + Cfg9346_EESK = (1 << 2), + Cfg9346_EECS = (1 << 3), + Cfg9346_EEM0 = (1 << 6), + Cfg9346_EEM1 = (1 << 7), + + /* rx_mode_bits */ + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, + + /* Transmit Priority Polling*/ + HPQ = 0x80, + NPQ = 0x40, + FSWInt = 0x01, + + /* RxConfigBits */ + Reserved2_shift = 13, + RxCfgDMAShift = 8, + EnableRxDescV3 = (1 << 24), + EnableOuterVlan = (1 << 23), + EnableInnerVlan = (1 << 22), + RxCfg_128_int_en = (1 << 15), + RxCfg_fet_multi_en = (1 << 14), + RxCfg_half_refetch = (1 << 13), + RxCfg_pause_slot_en = (1 << 11), + RxCfg_9356SEL = (1 << 6), + EnableRxDescV4_0 = (1 << 1), //not in rcr + + /* TxConfigBits */ + TxInterFrameGapShift = 24, + TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ + TxMACLoopBack = (1 << 17), /* MAC loopback */ + + /* Config1 register */ + LEDS1 = (1 << 7), + LEDS0 = (1 << 6), + Speed_down = (1 << 4), + MEMMAP = (1 << 3), + IOMAP = (1 << 2), + VPD = (1 << 1), + PMEnable = (1 << 0), /* Power Management Enable */ + + /* Config2 register */ + PMSTS_En = (1 << 5), + + /* Config3 register */ + Isolate_en = (1 << 12), /* Isolate enable */ + MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ + LinkUp = (1 << 4), /* This bit is reserved in RTL8125B.*/ + /* Wake up when the cable connection is re-established */ + ECRCEN = (1 << 3), /* This bit is reserved in RTL8125B*/ + Jumbo_En0 = (1 << 2), /* This bit is reserved in RTL8125B*/ + RDY_TO_L23 = (1 << 1), /* This bit is reserved in RTL8125B*/ + Beacon_en = (1 << 0), /* This bit is reserved in RTL8125B*/ + + /* Config4 register */ + Jumbo_En1 = (1 << 1), /* This bit is reserved in RTL8125B*/ + + /* Config5 register */ + BWF = (1 << 6), /* Accept Broadcast wakeup frame */ + MWF = (1 << 5), /* Accept Multicast wakeup frame */ + UWF = (1 << 4), /* Accept Unicast wakeup frame */ + LanWake = (1 << 1), /* LanWake enable/disable */ + PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + + /* CPlusCmd */ + EnableBist = (1 << 15), + Macdbgo_oe = (1 << 14), + Normal_mode = (1 << 13), + Force_halfdup = (1 << 12), + Force_rxflow_en = (1 << 11), + Force_txflow_en = (1 << 10), + Cxpl_dbg_sel = (1 << 9),//This bit is reserved in RTL8125B + ASF = (1 << 8),//This bit is reserved in RTL8125C + PktCntrDisable = (1 << 7), + RxVlan = (1 << 6), + RxChkSum = (1 << 5), + Macdbgo_sel = 0x001C, + INTT_0 = 0x0000, + INTT_1 = 0x0001, + INTT_2 = 0x0002, + INTT_3 = 0x0003, + + /* rtl8126_PHYstatus */ + PowerSaveStatus = 0x80, + _5000bpsF = 0x1000, + _2500bpsF = 0x400, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, + + /* DBG_reg */ + Fix_Nak_1 = (1 << 4), + Fix_Nak_2 = (1 << 3), + DBGPIN_E2 = (1 << 0), + + /* ResetCounterCommand */ + CounterReset = 0x1, + /* DumpCounterCommand */ + CounterDump = 0x8, + + /* PHY access */ + PHYAR_Flag = 0x80000000, + PHYAR_Write = 0x80000000, + PHYAR_Read = 0x00000000, + PHYAR_Reg_Mask = 0x1f, + PHYAR_Reg_shift = 16, + PHYAR_Data_Mask = 0xffff, + + /* EPHY access */ + EPHYAR_Flag = 0x80000000, + EPHYAR_Write = 0x80000000, + EPHYAR_Read = 0x00000000, + EPHYAR_Reg_Mask = 0x3f, + EPHYAR_Reg_Mask_v2 = 0x7f, + EPHYAR_Reg_shift = 16, + EPHYAR_Data_Mask = 0xffff, + + /* CSI access */ + CSIAR_Flag = 0x80000000, + CSIAR_Write = 0x80000000, + CSIAR_Read = 0x00000000, + CSIAR_ByteEn = 0x0f, + CSIAR_ByteEn_shift = 12, + CSIAR_Addr_Mask = 0x0fff, + + /* ERI access */ + ERIAR_Flag = 0x80000000, + ERIAR_Write = 0x80000000, + ERIAR_Read = 0x00000000, + ERIAR_Addr_Align = 4, /* ERI access register address must be 4 byte alignment */ + ERIAR_ExGMAC = 0, + ERIAR_MSIX = 1, + ERIAR_ASF = 2, + ERIAR_OOB = 2, + ERIAR_Type_shift = 16, + ERIAR_ByteEn = 0x0f, + ERIAR_ByteEn_shift = 12, + + /* OCP GPHY access */ + OCPDR_Write = 0x80000000, + OCPDR_Read = 0x00000000, + OCPDR_Reg_Mask = 0xFF, + OCPDR_Data_Mask = 0xFFFF, + OCPDR_GPHY_Reg_shift = 16, + OCPAR_Flag = 0x80000000, + OCPAR_GPHY_Write = 0x8000F060, + OCPAR_GPHY_Read = 0x0000F060, + OCPR_Write = 0x80000000, + OCPR_Read = 0x00000000, + OCPR_Addr_Reg_shift = 16, + OCPR_Flag = 0x80000000, + OCP_STD_PHY_BASE_PAGE = 0x0A40, + + /* MCU Command */ + Now_is_oob = (1 << 7), + Txfifo_empty = (1 << 5), + Rxfifo_empty = (1 << 4), + + /* E-FUSE access */ + EFUSE_WRITE = 0x80000000, + EFUSE_WRITE_OK = 0x00000000, + EFUSE_READ = 0x00000000, + EFUSE_READ_OK = 0x80000000, + EFUSE_WRITE_V3 = 0x40000000, + EFUSE_WRITE_OK_V3 = 0x00000000, + EFUSE_READ_V3 = 0x80000000, + EFUSE_READ_OK_V3 = 0x00000000, + EFUSE_Reg_Mask = 0x03FF, + EFUSE_Reg_Shift = 8, + EFUSE_Check_Cnt = 300, + EFUSE_READ_FAIL = 0xFF, + EFUSE_Data_Mask = 0x000000FF, + + /* GPIO */ + GPIO_en = (1 << 0), + + /* PTP */ + PTP_ISR_TOK = (1 << 1), + PTP_ISR_TER = (1 << 2), + PTP_EXEC_CMD = (1 << 7), + PTP_ADJUST_TIME_NS_NEGATIVE = (1 << 30), + PTP_ADJUST_TIME_S_NEGATIVE = (1ULL << 48), + PTP_SOFT_CONFIG_TIME_NS_NEGATIVE = (1 << 30), + PTP_SOFT_CONFIG_TIME_S_NEGATIVE = (1ULL << 48), + + /* New Interrupt Bits */ + INT_CFG0_ENABLE_8125 = (1 << 0), + INT_CFG0_TIMEOUT0_BYPASS_8125 = (1 << 1), + INT_CFG0_MITIGATION_BYPASS_8125 = (1 << 2), + INT_CFG0_RDU_BYPASS_8126 = (1 << 4), + INT_CFG0_MSIX_ENTRY_NUM_MODE = (1 << 5), + ISRIMR_V2_ROK_Q0 = (1 << 0), + ISRIMR_TOK_Q0 = (1 << 16), + ISRIMR_TOK_Q1 = (1 << 18), + ISRIMR_V2_LINKCHG = (1 << 21), + + ISRIMR_V4_ROK_Q0 = (1 << 0), + ISRIMR_V4_LINKCHG = (1 << 29), + + ISRIMR_V5_ROK_Q0 = (1 << 0), + ISRIMR_V5_TOK_Q0 = (1 << 16), + ISRIMR_V5_TOK_Q1 = (1 << 17), + ISRIMR_V5_LINKCHG = (1 << 18), + + /* Magic Number */ + RTL8126_MAGIC_NUMBER = 0x0badbadbadbadbadull, +}; + +enum _DescStatusBit { + DescOwn = (1 << 31), /* Descriptor is owned by NIC */ + RingEnd = (1 << 30), /* End of descriptor ring */ + FirstFrag = (1 << 29), /* First segment of a packet */ + LastFrag = (1 << 28), /* Final segment of a packet */ + + DescOwn_V3 = (DescOwn), /* Descriptor is owned by NIC */ + RingEnd_V3 = (RingEnd), /* End of descriptor ring */ + FirstFrag_V3 = (1 << 25), /* First segment of a packet */ + LastFrag_V3 = (1 << 24), /* Final segment of a packet */ + + /* Tx private */ + /*------ offset 0 of tx descriptor ------*/ + LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ + GiantSendv4 = (1 << 26), /* TCP Giant Send Offload V4 (GSOv4) */ + GiantSendv6 = (1 << 25), /* TCP Giant Send Offload V6 (GSOv6) */ + LargeSend_DP = (1 << 16), /* TCP Large Send Offload (TSO) */ + MSSShift = 16, /* MSS value position */ + MSSMask = 0x7FFU, /* MSS value 11 bits */ + TxIPCS = (1 << 18), /* Calculate IP checksum */ + TxUDPCS = (1 << 17), /* Calculate UDP/IP checksum */ + TxTCPCS = (1 << 16), /* Calculate TCP/IP checksum */ + TxVlanTag = (1 << 17), /* Add VLAN tag */ + + /*@@@@@@ offset 4 of tx descriptor => bits for RTL8125 only begin @@@@@@*/ + TxUDPCS_C = (1 << 31), /* Calculate UDP/IP checksum */ + TxTCPCS_C = (1 << 30), /* Calculate TCP/IP checksum */ + TxIPCS_C = (1 << 29), /* Calculate IP checksum */ + TxIPV6F_C = (1 << 28), /* Indicate it is an IPv6 packet */ + /*@@@@@@ offset 4 of tx descriptor => bits for RTL8125 only end @@@@@@*/ + + + /* Rx private */ + /*------ offset 0 of rx descriptor ------*/ + PID1 = (1 << 18), /* Protocol ID bit 1/2 */ + PID0 = (1 << 17), /* Protocol ID bit 2/2 */ + +#define RxProtoUDP (PID1) +#define RxProtoTCP (PID0) +#define RxProtoIP (PID1 | PID0) +#define RxProtoMask RxProtoIP + + RxIPF = (1 << 16), /* IP checksum failed */ + RxUDPF = (1 << 15), /* UDP/IP checksum failed */ + RxTCPF = (1 << 14), /* TCP/IP checksum failed */ + RxVlanTag = (1 << 16), /* VLAN tag available */ + + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxUDPT = (1 << 18), + RxTCPT = (1 << 17), + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxV6F = (1 << 31), + RxV4F = (1 << 30), + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + + PID1_v3 = (1 << 29), /* Protocol ID bit 1/2 */ + PID0_v3 = (1 << 28), /* Protocol ID bit 2/2 */ + +#define RxProtoUDP_v3 (PID1_v3) +#define RxProtoTCP_v3 (PID0_v3) +#define RxProtoIP_v3 (PID1_v3 | PID0_v3) +#define RxProtoMask_v3 RxProtoIP_v3 + + RxIPF_v3 = (1 << 26), /* IP checksum failed */ + RxUDPF_v3 = (1 << 25), /* UDP/IP checksum failed */ + RxTCPF_v3 = (1 << 24), /* TCP/IP checksum failed */ + RxSCTPF_v3 = (1 << 23), /* TCP/IP checksum failed */ + RxVlanTag_v3 = (RxVlanTag), /* VLAN tag available */ + + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxUDPT_v3 = (1 << 29), + RxTCPT_v3 = (1 << 28), + RxSCTP_v3 = (1 << 27), + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxV6F_v3 = (RxV6F), + RxV4F_v3 = (RxV4F), + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/ +}; + +enum features { +// RTL_FEATURE_WOL = (1 << 0), + RTL_FEATURE_MSI = (1 << 1), + RTL_FEATURE_MSIX = (1 << 2), +}; + +enum wol_capability { + WOL_DISABLED = 0, + WOL_ENABLED = 1 +}; + +enum bits { + BIT_0 = (1 << 0), + BIT_1 = (1 << 1), + BIT_2 = (1 << 2), + BIT_3 = (1 << 3), + BIT_4 = (1 << 4), + BIT_5 = (1 << 5), + BIT_6 = (1 << 6), + BIT_7 = (1 << 7), + BIT_8 = (1 << 8), + BIT_9 = (1 << 9), + BIT_10 = (1 << 10), + BIT_11 = (1 << 11), + BIT_12 = (1 << 12), + BIT_13 = (1 << 13), + BIT_14 = (1 << 14), + BIT_15 = (1 << 15), + BIT_16 = (1 << 16), + BIT_17 = (1 << 17), + BIT_18 = (1 << 18), + BIT_19 = (1 << 19), + BIT_20 = (1 << 20), + BIT_21 = (1 << 21), + BIT_22 = (1 << 22), + BIT_23 = (1 << 23), + BIT_24 = (1 << 24), + BIT_25 = (1 << 25), + BIT_26 = (1 << 26), + BIT_27 = (1 << 27), + BIT_28 = (1 << 28), + BIT_29 = (1 << 29), + BIT_30 = (1 << 30), + BIT_31 = (1 << 31) +}; + +#define RTL8126_CP_NUM 4 +#define RTL8126_MAX_SUPPORT_CP_LEN 110 + +enum rtl8126_cp_status { + rtl8126_cp_normal = 0, + rtl8126_cp_short, + rtl8126_cp_open, + rtl8126_cp_mismatch, + rtl8126_cp_unknown +}; + +enum efuse { + EFUSE_NOT_SUPPORT = 0, + EFUSE_SUPPORT_V1, + EFUSE_SUPPORT_V2, + EFUSE_SUPPORT_V3, + EFUSE_SUPPORT_V4, +}; +#define RsvdMask 0x3fffc000 +#define RsvdMaskV3 0x3fff8000 + +struct TxDesc { + u32 opts1; + u32 opts2; + u64 addr; + u32 reserved0; + u32 reserved1; + u32 reserved2; + u32 reserved3; +}; + +struct RxDesc { + u32 opts1; + u32 opts2; + u64 addr; +}; + +struct RxDescV3 { + union { + struct { + u32 rsv1; + u32 rsv2; + } RxDescDDWord1; + }; + + union { + struct { + u32 RSSResult; + u16 HeaderBufferLen; + u16 HeaderInfo; + } RxDescNormalDDWord2; + + struct { + u32 rsv5; + u32 rsv6; + } RxDescDDWord2; + }; + + union { + u64 addr; + + struct { + u32 TimeStampLow; + u32 TimeStampHigh; + } RxDescTimeStamp; + + struct { + u32 rsv8; + u32 rsv9; + } RxDescDDWord3; + }; + + union { + struct { + u32 opts2; + u32 opts1; + } RxDescNormalDDWord4; + + struct { + u16 TimeStampHHigh; + u16 rsv11; + u32 opts1; + } RxDescPTPDDWord4; + }; +}; + +enum rxdesc_type { + RXDESC_TYPE_NORMAL=0, + RXDESC_TYPE_NEXT, + RXDESC_TYPE_PTP, + RXDESC_TYPE_MAX +}; + +//Rx Desc Type +enum rx_desc_ring_type { + RX_DESC_RING_TYPE_UNKNOWN=0, + RX_DESC_RING_TYPE_1, + RX_DESC_RING_TYPE_2, + RX_DESC_RING_TYPE_3, + RX_DESC_RING_TYPE_4, + RX_DESC_RING_TYPE_MAX +}; + +enum rx_desc_len { + RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)), + RX_DESC_LEN_TYPE_3 = (sizeof(struct RxDescV3)) +}; + +struct ring_info { + struct sk_buff *skb; + u32 len; + unsigned int bytecount; + unsigned short gso_segs; + u8 __pad[sizeof(void *) - sizeof(u32)]; +}; + +struct pci_resource { + u8 cmd; + u8 cls; + u16 io_base_h; + u16 io_base_l; + u16 mem_base_h; + u16 mem_base_l; + u8 ilr; + u16 resv_0x1c_h; + u16 resv_0x1c_l; + u16 resv_0x20_h; + u16 resv_0x20_l; + u16 resv_0x24_h; + u16 resv_0x24_l; + u16 resv_0x2c_h; + u16 resv_0x2c_l; + u32 pci_sn_l; + u32 pci_sn_h; +}; + +enum r8126_flag { + R8126_FLAG_DOWN = 0, + R8126_FLAG_TASK_RESET_PENDING, + R8126_FLAG_TASK_ESD_CHECK_PENDING, + R8126_FLAG_TASK_LINKCHG_CHECK_PENDING, + R8126_FLAG_MAX +}; + +enum r8126_sysfs_flag { + R8126_SYSFS_RTL_ADV = 0, + R8126_SYSFS_FLAG_MAX +}; + +struct rtl8126_tx_ring { + void* priv; + struct net_device *netdev; + u32 index; + u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + u32 dirty_tx; + u32 num_tx_desc; /* Number of Tx descriptor registers */ + struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ + dma_addr_t TxPhyAddr; + u32 TxDescAllocSize; + struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ + + u32 NextHwDesCloPtr; + u32 BeginHwDesCloPtr; + + u16 hw_clo_ptr_reg; + u16 sw_tail_ptr_reg; + + u16 tdsar_reg; /* Transmit Descriptor Start Address */ +}; + +struct rtl8126_rx_buffer { + struct page *page; + u32 page_offset; + dma_addr_t dma; + void* data; + struct sk_buff *skb; +}; + +struct rtl8126_rx_ring { + void* priv; + struct net_device *netdev; + u32 index; + u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + u32 dirty_rx; + u32 num_rx_desc; /* Number of Rx descriptor registers */ + struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ + u32 RxDescAllocSize; + u64 RxDescPhyAddr[MAX_NUM_RX_DESC]; /* Rx desc physical address*/ + dma_addr_t RxPhyAddr; +#ifdef ENABLE_PAGE_REUSE + struct rtl8126_rx_buffer rx_buffer[MAX_NUM_RX_DESC]; + u16 rx_offset; +#else + struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ +#endif //ENABLE_PAGE_REUSE + + u16 rdsar_reg; /* Receive Descriptor Start Address */ +}; + +struct r8126_napi { +#ifdef CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + struct napi_struct napi; +#endif +#endif + void* priv; + int index; +}; + +struct r8126_irq { + irq_handler_t handler; + unsigned int vector; + u8 requested; + char name[IFNAMSIZ + 10]; +}; + +#pragma pack(1) +struct rtl8126_regs { + //00 + u8 mac_id[6]; + u16 reg_06; + u8 mar[8]; + //10 + u64 dtccr; + u16 ledsel0; + u16 legreg; + u32 tctr3; + //20 + u32 txq0_dsc_st_addr_0; + u32 txq0_dsc_st_addr_2; + u64 reg_28; + //30 + u16 rit; + u16 ritc; + u16 reg_34; + u8 reg_36; + u8 command; + u32 imr0; + u32 isr0; + //40 + u32 tcr; + u32 rcr; + u32 tctr0; + u32 tctr1; + //50 + u8 cr93c46; + u8 config0; + u8 config1; + u8 config2; + u8 config3; + u8 config4; + u8 config5; + u8 tdfnr; + u32 timer_int0; + u32 timer_int1; + //60 + u32 gphy_mdcmdio; + u32 csidr; + u32 csiar; + u16 phy_status; + u8 config6; + u8 pmch; + //70 + u32 eridr; + u32 eriar; + u16 config7; + u16 reg_7a; + u32 ephy_rxerr_cnt; + //80 + u32 ephy_mdcmdio; + u16 ledsel2; + u16 ledsel1; + u32 tctr2; + u32 timer_int2; + //90 + u8 tppoll0; + u8 reg_91; + u16 reg_92; + u16 led_feature; + u16 ledsel3; + u16 eee_led_config; + u16 reg_9a; + u32 reg_9c; + //a0 + u32 reg_a0; + u32 reg_a4; + u32 reg_a8; + u32 reg_ac; + //b0 + u32 patch_dbg; + u32 reg_b4; + u32 gphy_ocp; + u32 reg_bc; + //c0 + u32 reg_c0; + u32 reg_c4; + u32 reg_c8; + u16 otp_cmd; + u16 otp_pg_config; + //d0 + u16 phy_pwr; + u8 twsi_ctrl; + u8 oob_ctrl; + u16 mac_dbgo; + u16 mac_dbg; + u16 reg_d8; + u16 rms; + u32 efuse_data; + //e0 + u16 cplus_cmd; + u16 reg_e2; + u32 rxq0_dsc_st_addr_0; + u32 rxq0_dsc_st_addr_2; + u16 reg_ec; + u16 tx10midle_cnt; + //f0 + u16 misc0; + u16 misc1; + u32 timer_int3; + u32 cmac_ib; + u16 reg_fc; + u16 sw_rst; +}; +#pragma pack() + +struct rtl8126_regs_save { + union { + u8 mac_io[R8126_MAC_REGS_SIZE]; + + struct rtl8126_regs mac_reg; + }; + u16 pcie_phy[R8126_EPHY_REGS_SIZE/2]; + u16 eth_phy[R8126_PHY_REGS_SIZE/2]; + u32 eri_reg[R8126_ERI_REGS_SIZE/4]; + u32 pci_reg[R8126_PCI_REGS_SIZE/4]; + u16 sw_tail_ptr_reg[R8126_MAX_TX_QUEUES]; + u16 hw_clo_ptr_reg[R8126_MAX_TX_QUEUES]; + + //ktime_t begin_ktime; + //ktime_t end_ktime; + //u64 duration_ns; + + u16 sw0_tail_ptr; + u16 next_hwq0_clo_ptr; + u16 sw1_tail_ptr; + u16 next_hwq1_clo_ptr; + + u16 int_miti_rxq0; + u16 int_miti_txq0; + u16 int_miti_rxq1; + u16 int_miti_txq1; + u8 int_config; + u32 imr_new; + u32 isr_new; + + u8 tdu_status; + u16 rdu_status; + + u16 tc_mode; + + u32 txq1_dsc_st_addr_0; + u32 txq1_dsc_st_addr_2; + + u32 pla_tx_q0_idle_credit; + u32 pla_tx_q1_idle_credit; + + u32 rxq1_dsc_st_addr_0; + u32 rxq1_dsc_st_addr_2; + + u32 rss_ctrl; + u8 rss_key[RTL8126_RSS_KEY_SIZE]; + u8 rss_i_table[RTL8126_MAX_INDIRECTION_TABLE_ENTRIES]; + u16 rss_queue_num_sel_r; +}; + +struct rtl8126_counters { + /* legacy */ + u64 tx_packets; + u64 rx_packets; + u64 tx_errors; + u32 rx_errors; + u16 rx_missed; + u16 align_errors; + u32 tx_one_collision; + u32 tx_multi_collision; + u64 rx_unicast; + u64 rx_broadcast; + u32 rx_multicast; + u16 tx_aborted; + u16 tx_underrun; + + /* extended */ + u64 tx_octets; + u64 rx_octets; + u64 rx_multicast64; + u64 tx_unicast64; + u64 tx_broadcast64; + u64 tx_multicast64; + u32 tx_pause_on; + u32 tx_pause_off; + u32 tx_pause_all; + u32 tx_deferred; + u32 tx_late_collision; + u32 tx_all_collision; + u32 tx_aborted32; + u32 align_errors32; + u32 rx_frame_too_long; + u32 rx_runt; + u32 rx_pause_on; + u32 rx_pause_off; + u32 rx_pause_all; + u32 rx_unknown_opcode; + u32 rx_mac_error; + u32 tx_underrun32; + u32 rx_mac_missed; + u32 rx_tcam_dropped; + u32 tdu; + u32 rdu; +}; + +/* Flow Control Settings */ +enum rtl8126_fc_mode { + rtl8126_fc_none = 0, + rtl8126_fc_rx_pause, + rtl8126_fc_tx_pause, + rtl8126_fc_full, + rtl8126_fc_default +}; + +enum rtl8126_state_t { + __RTL8126_TESTING = 0, + __RTL8126_RESETTING, + __RTL8126_DOWN, + __RTL8126_PTP_TX_IN_PROGRESS, +}; + +struct rtl8126_private { + void __iomem *mmio_addr; /* memory map physical address */ + struct pci_dev *pci_dev; /* Index of PCI device */ + struct net_device *dev; + struct r8126_napi r8126napi[R8126_MAX_MSIX_VEC]; + struct r8126_irq irq_tbl[R8126_MAX_MSIX_VEC]; + unsigned int irq_nvecs; + unsigned int max_irq_nvecs; + unsigned int min_irq_nvecs; + unsigned int hw_supp_irq_nvecs; + //struct msix_entry msix_entries[R8126_MAX_MSIX_VEC]; + struct net_device_stats stats; /* statistics of net device */ + unsigned long state; + + u32 msg_enable; + u32 tx_tcp_csum_cmd; + u32 tx_udp_csum_cmd; + u32 tx_ip_csum_cmd; + u32 tx_ipv6_csum_cmd; + int max_jumbo_frame_size; + int chipset; + u32 mcfg; + //u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + //u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + //u32 dirty_rx; + //u32 dirty_tx; + //struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ + //struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ + //dma_addr_t TxPhyAddr; + //dma_addr_t RxPhyAddr; + //struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ + //struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ + unsigned rx_buf_sz; +#ifdef ENABLE_PAGE_REUSE + unsigned rx_buf_page_order; + unsigned rx_buf_page_size; + u32 page_reuse_fail_cnt; +#endif //ENABLE_PAGE_REUSE + u16 HwSuppNumTxQueues; + u16 HwSuppNumRxQueues; + unsigned int num_tx_rings; + unsigned int num_rx_rings; + struct rtl8126_tx_ring tx_ring[R8126_MAX_TX_QUEUES]; + struct rtl8126_rx_ring rx_ring[R8126_MAX_RX_QUEUES]; +#ifdef ENABLE_LIB_SUPPORT + struct blocking_notifier_head lib_nh; + struct rtl8126_ring lib_tx_ring[R8126_MAX_TX_QUEUES]; + struct rtl8126_ring lib_rx_ring[R8126_MAX_RX_QUEUES]; +#endif + //struct timer_list esd_timer; + //struct timer_list link_timer; + struct pci_resource pci_cfg_space; + unsigned int esd_flag; + unsigned int pci_cfg_is_read; + unsigned int rtl8126_rx_config; + u16 rms; + u16 cp_cmd; + u32 intr_mask; + u32 timer_intr_mask; + u16 isr_reg[R8126_MAX_QUEUES]; + u16 imr_reg[R8126_MAX_QUEUES]; + int phy_auto_nego_reg; + int phy_1000_ctrl_reg; + int phy_2500_ctrl_reg; + u8 org_mac_addr[NODE_ADDRESS_SIZE]; + struct rtl8126_counters *tally_vaddr; + dma_addr_t tally_paddr; + +#ifdef CONFIG_R8126_VLAN + struct vlan_group *vlgrp; +#endif + u8 wol_enabled; + u32 wol_opts; + u8 efuse_ver; + u8 eeprom_type; + u8 autoneg; + u8 duplex; + u32 speed; + u64 advertising; + enum rtl8126_fc_mode fcpause; + u32 HwSuppMaxPhyLinkSpeed; + u16 eeprom_len; + u16 cur_page; + u32 bios_setting; + + int (*set_speed)(struct net_device *, u8 autoneg, u32 speed, u8 duplex, u64 adv); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + void (*get_settings)(struct net_device *, struct ethtool_cmd *); +#else + void (*get_settings)(struct net_device *, struct ethtool_link_ksettings *); +#endif + void (*phy_reset_enable)(struct net_device *); + unsigned int (*phy_reset_pending)(struct net_device *); + unsigned int (*link_ok)(struct net_device *); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + struct work_struct reset_task; + struct work_struct esd_task; + struct work_struct linkchg_task; +#else + struct delayed_work reset_task; + struct delayed_work esd_task; + struct delayed_work linkchg_task; +#endif + DECLARE_BITMAP(task_flags, R8126_FLAG_MAX); + unsigned features; + + u8 org_pci_offset_99; + u8 org_pci_offset_180; + u8 issue_offset_99_event; + + u8 org_pci_offset_80; + u8 org_pci_offset_81; + u8 use_timer_interrupt; + + u32 keep_intr_cnt; + + u8 HwIcVerUnknown; + u8 NotWrRamCodeToMicroP; + u8 NotWrMcuPatchCode; + u8 HwHasWrRamCodeToMicroP; + + u16 sw_ram_code_ver; + u16 hw_ram_code_ver; + + u8 rtk_enable_diag; + + u8 ShortPacketSwChecksum; + + u8 UseSwPaddingShortPkt; + + u8 RequireAdcBiasPatch; + u16 AdcBiasPatchIoffset; + + u8 RequireAdjustUpsTxLinkPulseTiming; + u16 SwrCnt1msIni; + + u8 HwSuppNowIsOobVer; + + u8 RequiredSecLanDonglePatch; + + u8 RequirePhyMdiSwapPatch; + + u32 HwFiberModeVer; + u32 HwFiberStat; + u8 HwSwitchMdiToFiber; + + u16 NicCustLedValue; + + u8 HwSuppMagicPktVer; + + u8 HwSuppLinkChgWakeUpVer; + + u8 HwSuppCheckPhyDisableModeVer; + + u8 random_mac; + + u16 phy_reg_aner; + u16 phy_reg_anlpar; + u16 phy_reg_gbsr; + u16 phy_reg_status_2500; + + u32 HwPcieSNOffset; + + u32 MaxTxDescPtrMask; + u8 HwSuppTxNoCloseVer; + u8 EnableTxNoClose; + + u8 HwSuppIsrVer; + u8 HwCurrIsrVer; + + u8 HwSuppIntMitiVer; + + u8 HwSuppExtendTallyCounterVer; + + u8 check_keep_link_speed; + u8 resume_not_chg_speed; + + u8 HwSuppD0SpeedUpVer; + u8 D0SpeedUpSpeed; + + u8 ring_lib_enabled; + + const char *fw_name; + struct rtl8126_fw *rtl_fw; + u32 ocp_base; + + //Dash+++++++++++++++++ + u8 HwSuppDashVer; + u8 DASH; + u8 dash_printer_enabled; + u8 HwPkgDet; + u8 AllowAccessDashOcp; + void __iomem *mapped_cmac_ioaddr; /* mapped cmac memory map physical address */ + void __iomem *cmac_ioaddr; /* cmac memory map physical address */ + +#ifdef ENABLE_DASH_SUPPORT + u16 AfterRecvFromFwBufLen; + u8 AfterRecvFromFwBuf[RECV_FROM_FW_BUF_SIZE]; + u16 AfterSendToFwBufLen; + u8 AfterSendToFwBuf[SEND_TO_FW_BUF_SIZE]; + u16 SendToFwBufferLen; + u32 SizeOfSendToFwBuffer; + u32 SizeOfSendToFwBufferMemAlloc; + u32 NumOfSendToFwBuffer; + + u8 OobReq; + u8 OobAck; + u32 OobReqComplete; + u32 OobAckComplete; + + u8 RcvFwReqSysOkEvt; + u8 RcvFwDashOkEvt; + u8 SendFwHostOkEvt; + + u8 DashFwDisableRx; + + void *UnalignedSendToFwBufferVa; + void *SendToFwBuffer; + u64 SendToFwBufferPhy; + u8 SendingToFw; + dma_addr_t UnalignedSendToFwBufferPa; + PTX_DASH_SEND_FW_DESC TxDashSendFwDesc; + u64 TxDashSendFwDescPhy; + u8 *UnalignedTxDashSendFwDescVa; + u32 SizeOfTxDashSendFwDescMemAlloc; + u32 SizeOfTxDashSendFwDesc; + u32 NumTxDashSendFwDesc; + u32 CurrNumTxDashSendFwDesc; + u32 LastSendNumTxDashSendFwDesc; + dma_addr_t UnalignedTxDashSendFwDescPa; + + u32 NumRecvFromFwBuffer; + u32 SizeOfRecvFromFwBuffer; + u32 SizeOfRecvFromFwBufferMemAlloc; + void *RecvFromFwBuffer; + u64 RecvFromFwBufferPhy; + + void *UnalignedRecvFromFwBufferVa; + dma_addr_t UnalignedRecvFromFwBufferPa; + PRX_DASH_FROM_FW_DESC RxDashRecvFwDesc; + u64 RxDashRecvFwDescPhy; + u8 *UnalignedRxDashRecvFwDescVa; + u32 SizeOfRxDashRecvFwDescMemAlloc; + u32 SizeOfRxDashRecvFwDesc; + u32 NumRxDashRecvFwDesc; + u32 CurrNumRxDashRecvFwDesc; + dma_addr_t UnalignedRxDashRecvFwDescPa; + u8 DashReqRegValue; + u16 HostReqValue; + + u32 CmacResetIsrCounter; + u8 CmacResetIntr; + u8 CmacResetting; + u8 CmacOobIssueCmacReset; + u32 CmacResetbyFwCnt; + +#if defined(ENABLE_DASH_PRINTER_SUPPORT) + struct completion fw_ack; + struct completion fw_req; + struct completion fw_host_ok; +#endif + //Dash----------------- +#endif //ENABLE_DASH_SUPPORT + + //Realwow++++++++++++++ + u8 HwSuppKCPOffloadVer; + + u8 EnableDhcpTimeoutWake; + u8 EnableTeredoOffload; + u8 EnableKCPOffload; +#ifdef ENABLE_REALWOW_SUPPORT + u32 DhcpTimeout; + MP_KCP_INFO MpKCPInfo; + //Realwow-------------- +#endif //ENABLE_REALWOW_SUPPORT + + struct ethtool_eee eee; + +#ifdef ENABLE_R8126_PROCFS + //Procfs support + struct proc_dir_entry *proc_dir; + struct proc_dir_entry *proc_dir_debug; + struct proc_dir_entry *proc_dir_test; +#endif +#ifdef ENABLE_R8126_SYSFS + //sysfs support + DECLARE_BITMAP(sysfs_flag, R8126_SYSFS_FLAG_MAX); + u32 testmode; +#endif + u8 InitRxDescType; + u16 RxDescLength; //V1 16 Byte V2 32 Bytes + + u8 HwSuppPtpVer; + u8 EnablePtp; + u8 ptp_master_mode; +#ifdef ENABLE_PTP_SUPPORT + u32 tx_hwtstamp_timeouts; + u32 tx_hwtstamp_skipped; + struct work_struct ptp_tx_work; + struct sk_buff *ptp_tx_skb; + struct hwtstamp_config hwtstamp_config; + unsigned long ptp_tx_start; + struct ptp_clock_info ptp_clock_info; + struct ptp_clock *ptp_clock; +#endif + + u8 HwSuppRssVer; + u8 EnableRss; + u16 HwSuppIndirTblEntries; +#ifdef ENABLE_RSS_SUPPORT + u32 rss_flags; + /* Receive Side Scaling settings */ + u8 rss_key[RTL8126_RSS_KEY_SIZE]; + u8 rss_indir_tbl[RTL8126_MAX_INDIRECTION_TABLE_ENTRIES]; + u32 rss_options; +#endif + + u8 HwSuppMacMcuVer; + u16 MacMcuPageSize; + + u8 HwSuppTcamVer; + + u16 TcamNotValidReg; + u16 TcamValidReg; + u16 TcamMaAddrcOffset; + u16 TcamVlanTagOffset; +}; + +#ifdef ENABLE_LIB_SUPPORT +static inline unsigned int +rtl8126_num_lib_tx_rings(struct rtl8126_private *tp) +{ + int count, i; + + for (count = 0, i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) + if(tp->lib_tx_ring[i].enabled) + count++; + + return count; +} + +static inline unsigned int +rtl8126_num_lib_rx_rings(struct rtl8126_private *tp) +{ + int count, i; + + for (count = 0, i = tp->num_rx_rings; i < tp->HwSuppNumRxQueues; i++) + if(tp->lib_rx_ring[i].enabled) + count++; + + return count; +} + +#else +static inline unsigned int +rtl8126_num_lib_tx_rings(struct rtl8126_private *tp) +{ + return 0; +} + +static inline unsigned int +rtl8126_num_lib_rx_rings(struct rtl8126_private *tp) +{ + return 0; +} +#endif + +static inline unsigned int +rtl8126_tot_tx_rings(struct rtl8126_private *tp) +{ + return tp->num_tx_rings + rtl8126_num_lib_tx_rings(tp); +} + +static inline unsigned int +rtl8126_tot_rx_rings(struct rtl8126_private *tp) +{ + return tp->num_rx_rings + rtl8126_num_lib_rx_rings(tp); +} + +static inline struct netdev_queue *txring_txq(const struct rtl8126_tx_ring *ring) +{ + return netdev_get_tx_queue(ring->netdev, ring->index); +} + +enum eetype { + EEPROM_TYPE_NONE=0, + EEPROM_TYPE_93C46, + EEPROM_TYPE_93C56, + EEPROM_TWSI +}; + +enum mcfg { + CFG_METHOD_1=1, + CFG_METHOD_2, + CFG_METHOD_3, + CFG_METHOD_DEFAULT, + CFG_METHOD_MAX +}; + +#define LSO_32K 32000 +#define LSO_64K 64000 + +#define NIC_MIN_PHYS_BUF_COUNT (2) +#define NIC_MAX_PHYS_BUF_COUNT_LSO_64K (24) +#define NIC_MAX_PHYS_BUF_COUNT_LSO2 (16*4) + +#define GTTCPHO_SHIFT 18 +#define GTTCPHO_MAX 0x70U +#define GTPKTSIZE_MAX 0x3ffffU +#define TCPHO_SHIFT 18 +#define TCPHO_MAX 0x3ffU +#define LSOPKTSIZE_MAX 0xffffU +#define MSS_MAX 0x07ffu /* MSS value */ + +#define OOB_CMD_RESET 0x00 +#define OOB_CMD_DRIVER_START 0x05 +#define OOB_CMD_DRIVER_STOP 0x06 +#define OOB_CMD_SET_IPMAC 0x41 + +#define WAKEUP_MAGIC_PACKET_NOT_SUPPORT (0) +#define WAKEUP_MAGIC_PACKET_V1 (1) +#define WAKEUP_MAGIC_PACKET_V2 (2) +#define WAKEUP_MAGIC_PACKET_V3 (3) + +//Ram Code Version +#define NIC_RAMCODE_VERSION_CFG_METHOD_1 (0x0023) +#define NIC_RAMCODE_VERSION_CFG_METHOD_2 (0x0033) +#define NIC_RAMCODE_VERSION_CFG_METHOD_3 (0x0048) + +//hwoptimize +#define HW_PATCH_SOC_LAN (BIT_0) +#define HW_PATCH_SAMSUNG_LAN_DONGLE (BIT_2) + +static const u16 other_q_intr_mask = (RxOK1 | RxDU1); + +void rtl8126_mdio_write(struct rtl8126_private *tp, u16 RegAddr, u16 value); +void rtl8126_mdio_prot_write(struct rtl8126_private *tp, u32 RegAddr, u32 value); +void rtl8126_mdio_prot_direct_write_phy_ocp(struct rtl8126_private *tp, u32 RegAddr, u32 value); +u32 rtl8126_mdio_read(struct rtl8126_private *tp, u16 RegAddr); +u32 rtl8126_mdio_prot_read(struct rtl8126_private *tp, u32 RegAddr); +u32 rtl8126_mdio_prot_direct_read_phy_ocp(struct rtl8126_private *tp, u32 RegAddr); +void rtl8126_ephy_write(struct rtl8126_private *tp, int RegAddr, int value); +void rtl8126_mac_ocp_write(struct rtl8126_private *tp, u16 reg_addr, u16 value); +u16 rtl8126_mac_ocp_read(struct rtl8126_private *tp, u16 reg_addr); +void rtl8126_clear_eth_phy_bit(struct rtl8126_private *tp, u8 addr, u16 mask); +void rtl8126_set_eth_phy_bit(struct rtl8126_private *tp, u8 addr, u16 mask); +void rtl8126_ocp_write(struct rtl8126_private *tp, u16 addr, u8 len, u32 data); +void rtl8126_oob_notify(struct rtl8126_private *tp, u8 cmd); +void rtl8126_init_ring_indexes(struct rtl8126_private *tp); +void rtl8126_oob_mutex_lock(struct rtl8126_private *tp); +u32 rtl8126_ocp_read(struct rtl8126_private *tp, u16 addr, u8 len); +u32 rtl8126_ocp_read_with_oob_base_address(struct rtl8126_private *tp, u16 addr, u8 len, u32 base_address); +u32 rtl8126_ocp_write_with_oob_base_address(struct rtl8126_private *tp, u16 addr, u8 len, u32 value, u32 base_address); +u32 rtl8126_eri_read(struct rtl8126_private *tp, int addr, int len, int type); +u32 rtl8126_eri_read_with_oob_base_address(struct rtl8126_private *tp, int addr, int len, int type, u32 base_address); +int rtl8126_eri_write(struct rtl8126_private *tp, int addr, int len, u32 value, int type); +int rtl8126_eri_write_with_oob_base_address(struct rtl8126_private *tp, int addr, int len, u32 value, int type, u32 base_address); +u16 rtl8126_ephy_read(struct rtl8126_private *tp, int RegAddr); +void rtl8126_wait_txrx_fifo_empty(struct net_device *dev); +void rtl8126_enable_now_is_oob(struct rtl8126_private *tp); +void rtl8126_disable_now_is_oob(struct rtl8126_private *tp); +void rtl8126_oob_mutex_unlock(struct rtl8126_private *tp); +void rtl8126_dash2_disable_tx(struct rtl8126_private *tp); +void rtl8126_dash2_enable_tx(struct rtl8126_private *tp); +void rtl8126_dash2_disable_rx(struct rtl8126_private *tp); +void rtl8126_dash2_enable_rx(struct rtl8126_private *tp); +void rtl8126_hw_disable_mac_mcu_bps(struct net_device *dev); +void rtl8126_mark_to_asic(struct rtl8126_private *tp, struct RxDesc *desc, u32 rx_buf_sz); + +static inline void +rtl8126_make_unusable_by_asic(struct rtl8126_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) { + ((struct RxDescV3 *)desc)->addr = RTL8126_MAGIC_NUMBER; + ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1 &= ~cpu_to_le32(DescOwn | RsvdMaskV3); + } else { + desc->addr = RTL8126_MAGIC_NUMBER; + desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); + } +} + +static inline struct RxDesc* +rtl8126_get_rxdesc(struct rtl8126_private *tp, struct RxDesc *RxDescBase, u32 const cur_rx) +{ + return (struct RxDesc*)((u8*)RxDescBase + (cur_rx * tp->RxDescLength)); +} + +static inline void +rtl8126_disable_hw_interrupt_v2(struct rtl8126_private *tp, + u32 message_id) +{ + RTL_W32(tp, IMR_V2_CLEAR_REG_8125, BIT(message_id)); +} + +static inline void +rtl8126_enable_hw_interrupt_v2(struct rtl8126_private *tp, u32 message_id) +{ + RTL_W32(tp, IMR_V2_SET_REG_8125, BIT(message_id)); +} + +int rtl8126_open(struct net_device *dev); +int rtl8126_close(struct net_device *dev); +void rtl8126_hw_config(struct net_device *dev); +void rtl8126_hw_set_timer_int_8125(struct rtl8126_private *tp, u32 message_id, u8 timer_intmiti_val); +void rtl8126_set_rx_q_num(struct rtl8126_private *tp, unsigned int num_rx_queues); +void rtl8126_set_tx_q_num(struct rtl8126_private *tp, unsigned int num_tx_queues); +void rtl8126_enable_mcu(struct rtl8126_private *tp, bool enable); +void rtl8126_hw_start(struct net_device *dev); +void rtl8126_hw_reset(struct net_device *dev); +void rtl8126_tx_clear(struct rtl8126_private *tp); +void rtl8126_rx_clear(struct rtl8126_private *tp); +int rtl8126_init_ring(struct net_device *dev); +void rtl8126_hw_set_rx_packet_filter(struct net_device *dev); +void rtl8126_enable_hw_linkchg_interrupt(struct rtl8126_private *tp); +int rtl8126_dump_tally_counter(struct rtl8126_private *tp, dma_addr_t paddr); +void rtl8126_enable_napi(struct rtl8126_private *tp); +void _rtl8126_wait_for_quiescence(struct net_device *dev); + +#ifndef ENABLE_LIB_SUPPORT +static inline void rtl8126_lib_reset_prepare(struct rtl8126_private *tp) { } +static inline void rtl8126_lib_reset_complete(struct rtl8126_private *tp) { } +#endif + +#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0 ) +#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0) +#define HW_SUPPORT_D0_SPEED_UP(_M) ((_M)->HwSuppD0SpeedUpVer > 0) +#define HW_SUPPORT_MAC_MCU(_M) ((_M)->HwSuppMacMcuVer > 0) +#define HW_SUPPORT_TCAM(_M) ((_M)->HwSuppTcamVer > 0) + +#define HW_SUPP_PHY_LINK_SPEED_GIGA(_M) ((_M)->HwSuppMaxPhyLinkSpeed >= 1000) +#define HW_SUPP_PHY_LINK_SPEED_2500M(_M) ((_M)->HwSuppMaxPhyLinkSpeed >= 2500) +#define HW_SUPP_PHY_LINK_SPEED_5000M(_M) ((_M)->HwSuppMaxPhyLinkSpeed >= 5000) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#define netdev_mc_count(dev) ((dev)->mc_count) +#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) +#define netdev_for_each_mc_addr(mclist, dev) \ + for (mclist = dev->mc_list; mclist; mclist = mclist->next) +#endif + +#endif /* __R8126_H */ diff --git a/package/lean/r8126/src/r8126_dash.h b/package/lean/r8126/src/r8126_dash.h new file mode 100644 index 000000000..b0a2f11fa --- /dev/null +++ b/package/lean/r8126/src/r8126_dash.h @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8126_DASH_H +#define _LINUX_R8126_DASH_H + +#include + +#define SIOCDEVPRIVATE_RTLDASH SIOCDEVPRIVATE+2 + +enum rtl_dash_cmd { + RTL_DASH_ARP_NS_OFFLOAD = 0, + RTL_DASH_SET_OOB_IPMAC, + RTL_DASH_NOTIFY_OOB, + + RTL_DASH_SEND_BUFFER_DATA_TO_DASH_FW, + RTL_DASH_CHECK_SEND_BUFFER_TO_DASH_FW_COMPLETE, + RTL_DASH_GET_RCV_FROM_FW_BUFFER_DATA, + RTL_DASH_OOB_REQ, + RTL_DASH_OOB_ACK, + RTL_DASH_DETACH_OOB_REQ, + RTL_DASH_DETACH_OOB_ACK, + + RTL_FW_SET_IPV4 = 0x10, + RTL_FW_GET_IPV4, + RTL_FW_SET_IPV6, + RTL_FW_GET_IPV6, + RTL_FW_SET_EXT_SNMP, + RTL_FW_GET_EXT_SNMP, + RTL_FW_SET_WAKEUP_PATTERN, + RTL_FW_GET_WAKEUP_PATTERN, + RTL_FW_DEL_WAKEUP_PATTERN, + + RTLT_DASH_COMMAND_INVALID, +}; + +struct rtl_dash_ip_mac { + struct sockaddr ifru_addr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; +}; + +struct rtl_dash_ioctl_struct { + __u32 cmd; + __u32 offset; + __u32 len; + union { + __u32 data; + void *data_buffer; + }; +}; + +struct settings_ipv4 { + __u32 IPv4addr; + __u32 IPv4mask; + __u32 IPv4Gateway; +}; + +struct settings_ipv6 { + __u32 reserved; + __u32 prefixLen; + __u16 IPv6addr[8]; + __u16 IPv6Gateway[8]; +}; + +struct settings_ext_snmp { + __u16 index; + __u16 oid_get_len; + __u8 oid_for_get[24]; + __u8 reserved0[26]; + __u16 value_len; + __u8 value[256]; + __u8 supported; + __u8 reserved1[27]; +}; + +struct wakeup_pattern { + __u8 index; + __u8 valid; + __u8 start; + __u8 length; + __u8 name[36]; + __u8 mask[16]; + __u8 pattern[128]; + __u32 reserved[2]; +}; + +typedef struct _RX_DASH_FROM_FW_DESC { + u16 length; + u8 statusLowByte; + u8 statusHighByte; + u32 resv; + u64 BufferAddress; +} +RX_DASH_FROM_FW_DESC, *PRX_DASH_FROM_FW_DESC; + +typedef struct _TX_DASH_SEND_FW_DESC { + u16 length; + u8 statusLowByte; + u8 statusHighByte; + u32 resv; + u64 BufferAddress; +} +TX_DASH_SEND_FW_DESC, *PTX_DASH_SEND_FW_DESC; + +typedef struct _OSOOBHdr { + u32 len; + u8 type; + u8 flag; + u8 hostReqV; + u8 res; +} +OSOOBHdr, *POSOOBHdr; + +typedef struct _RX_DASH_BUFFER_TYPE_2 { + OSOOBHdr oobhdr; + u8 RxDataBuffer[0]; +} +RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; + +#define ALIGN_8 (0x7) +#define ALIGN_16 (0xf) +#define ALIGN_32 (0x1f) +#define ALIGN_64 (0x3f) +#define ALIGN_256 (0xff) +#define ALIGN_4096 (0xfff) + +#define OCP_REG_CONFIG0 (0x10) +#define OCP_REG_CONFIG0_REV_F (0xB8) +#define OCP_REG_DASH_POLL (0x30) +#define OCP_REG_HOST_REQ (0x34) +#define OCP_REG_DASH_REQ (0x35) +#define OCP_REG_CR (0x36) +#define OCP_REG_DMEMSTA (0x38) +#define OCP_REG_GPHYAR (0x60) + + +#define OCP_REG_CONFIG0_DASHEN BIT_15 +#define OCP_REG_CONFIG0_OOBRESET BIT_14 +#define OCP_REG_CONFIG0_APRDY BIT_13 +#define OCP_REG_CONFIG0_FIRMWARERDY BIT_12 +#define OCP_REG_CONFIG0_DRIVERRDY BIT_11 +#define OCP_REG_CONFIG0_OOB_WDT BIT_9 +#define OCP_REG_CONFIG0_DRV_WAIT_OOB BIT_8 +#define OCP_REG_CONFIG0_TLSEN BIT_7 + +#define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0 ) +#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1 ) +#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2 ) +#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3 ) + +#define RECV_FROM_FW_BUF_SIZE (1520) +#define SEND_TO_FW_BUF_SIZE (1520) + +#define RX_DASH_FROM_FW_OWN BIT_15 +#define TX_DASH_SEND_FW_OWN BIT_15 +#define TX_DASH_SEND_FW_OWN_HIGHBYTE BIT_7 + +#define TXS_CC3_0 (BIT_0|BIT_1|BIT_2|BIT_3) +#define TXS_EXC BIT_4 +#define TXS_LNKF BIT_5 +#define TXS_OWC BIT_6 +#define TXS_TES BIT_7 +#define TXS_UNF BIT_9 +#define TXS_LGSEN BIT_11 +#define TXS_LS BIT_12 +#define TXS_FS BIT_13 +#define TXS_EOR BIT_14 +#define TXS_OWN BIT_15 + +#define TPPool_HRDY 0x20 + +#define HostReqReg (0xC0) +#define SystemMasterDescStartAddrLow (0xF0) +#define SystemMasterDescStartAddrHigh (0xF4) +#define SystemSlaveDescStartAddrLow (0xF8) +#define SystemSlaveDescStartAddrHigh (0xFC) + +//DASH Request Type +#define WSMANREG 0x01 +#define OSPUSHDATA 0x02 + +#define RXS_OWN BIT_15 +#define RXS_EOR BIT_14 +#define RXS_FS BIT_13 +#define RXS_LS BIT_12 + +#define ISRIMR_DP_DASH_OK BIT_15 +#define ISRIMR_DP_HOST_OK BIT_13 +#define ISRIMR_DP_REQSYS_OK BIT_11 + +#define ISRIMR_DASH_INTR_EN BIT_12 +#define ISRIMR_DASH_INTR_CMAC_RESET BIT_15 + +#define ISRIMR_DASH_TYPE2_ROK BIT_0 +#define ISRIMR_DASH_TYPE2_RDU BIT_1 +#define ISRIMR_DASH_TYPE2_TOK BIT_2 +#define ISRIMR_DASH_TYPE2_TDU BIT_3 +#define ISRIMR_DASH_TYPE2_TX_FIFO_FULL BIT_4 +#define ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE BIT_5 +#define ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE BIT_6 + +#define CMAC_OOB_STOP 0x25 +#define CMAC_OOB_INIT 0x26 +#define CMAC_OOB_RESET 0x2a + +#define NO_BASE_ADDRESS 0x00000000 +#define RTL8168FP_OOBMAC_BASE 0xBAF70000 +#define RTL8168FP_CMAC_IOBASE 0xBAF20000 +#define RTL8168FP_KVM_BASE 0xBAF80400 +#define CMAC_SYNC_REG 0x20 +#define CMAC_RXDESC_OFFSET 0x90 //RX: 0x90 - 0x98 +#define CMAC_TXDESC_OFFSET 0x98 //TX: 0x98 - 0x9F + +/* cmac write/read MMIO register */ +#define RTL_CMAC_W8(tp, reg, val8) writeb ((val8), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_W16(tp, reg, val16) writew ((val16), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_W32(tp, reg, val32) writel ((val32), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R8(tp, reg) readb (tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R16(tp, reg) readw (tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg))) + +int rtl8126_dash_ioctl(struct net_device *dev, struct ifreq *ifr); +void HandleDashInterrupt(struct net_device *dev); +int AllocateDashShareMemory(struct net_device *dev); +void FreeAllocatedDashShareMemory(struct net_device *dev); +void DashHwInit(struct net_device *dev); + + +#endif /* _LINUX_R8126_DASH_H */ diff --git a/package/lean/r8126/src/r8126_firmware.c b/package/lean/r8126/src/r8126_firmware.c new file mode 100644 index 000000000..a7b13cbcb --- /dev/null +++ b/package/lean/r8126/src/r8126_firmware.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include + +#include "r8126_firmware.h" + +enum rtl_fw_opcode { + PHY_READ = 0x0, + PHY_DATA_OR = 0x1, + PHY_DATA_AND = 0x2, + PHY_BJMPN = 0x3, + PHY_MDIO_CHG = 0x4, + PHY_CLEAR_READCOUNT = 0x7, + PHY_WRITE = 0x8, + PHY_READCOUNT_EQ_SKIP = 0x9, + PHY_COMP_EQ_SKIPN = 0xa, + PHY_COMP_NEQ_SKIPN = 0xb, + PHY_WRITE_PREVIOUS = 0xc, + PHY_SKIPN = 0xd, + PHY_DELAY_MS = 0xe, +}; + +struct fw_info { + u32 magic; + char version[RTL8126_VER_SIZE]; + __le32 fw_start; + __le32 fw_len; + u8 chksum; +} __packed; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0) +#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) +#endif +#define FW_OPCODE_SIZE sizeof_field(struct rtl8126_fw_phy_action, code[0]) + +static bool rtl8126_fw_format_ok(struct rtl8126_fw *rtl_fw) +{ + const struct firmware *fw = rtl_fw->fw; + struct fw_info *fw_info = (struct fw_info *)fw->data; + struct rtl8126_fw_phy_action *pa = &rtl_fw->phy_action; + + if (fw->size < FW_OPCODE_SIZE) + return false; + + if (!fw_info->magic) { + size_t i, size, start; + u8 checksum = 0; + + if (fw->size < sizeof(*fw_info)) + return false; + + for (i = 0; i < fw->size; i++) + checksum += fw->data[i]; + if (checksum != 0) + return false; + + start = le32_to_cpu(fw_info->fw_start); + if (start > fw->size) + return false; + + size = le32_to_cpu(fw_info->fw_len); + if (size > (fw->size - start) / FW_OPCODE_SIZE) + return false; + + strscpy(rtl_fw->version, fw_info->version, RTL8126_VER_SIZE); + + pa->code = (__le32 *)(fw->data + start); + pa->size = size; + } else { + if (fw->size % FW_OPCODE_SIZE) + return false; + + strscpy(rtl_fw->version, rtl_fw->fw_name, RTL8126_VER_SIZE); + + pa->code = (__le32 *)fw->data; + pa->size = fw->size / FW_OPCODE_SIZE; + } + + return true; +} + +static bool rtl8126_fw_data_ok(struct rtl8126_fw *rtl_fw) +{ + struct rtl8126_fw_phy_action *pa = &rtl_fw->phy_action; + size_t index; + + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); + u32 val = action & 0x0000ffff; + u32 regno = (action & 0x0fff0000) >> 16; + + switch (action >> 28) { + case PHY_READ: + case PHY_DATA_OR: + case PHY_DATA_AND: + case PHY_CLEAR_READCOUNT: + case PHY_WRITE: + case PHY_WRITE_PREVIOUS: + case PHY_DELAY_MS: + break; + + case PHY_MDIO_CHG: + if (val > 1) + goto out; + break; + + case PHY_BJMPN: + if (regno > index) + goto out; + break; + case PHY_READCOUNT_EQ_SKIP: + if (index + 2 >= pa->size) + goto out; + break; + case PHY_COMP_EQ_SKIPN: + case PHY_COMP_NEQ_SKIPN: + case PHY_SKIPN: + if (index + 1 + regno >= pa->size) + goto out; + break; + + default: + dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action); + return false; + } + } + + return true; +out: + dev_err(rtl_fw->dev, "Out of range of firmware\n"); + return false; +} + +void rtl8126_fw_write_firmware(struct rtl8126_private *tp, struct rtl8126_fw *rtl_fw) +{ + struct rtl8126_fw_phy_action *pa = &rtl_fw->phy_action; + rtl8126_fw_write_t fw_write = rtl_fw->phy_write; + rtl8126_fw_read_t fw_read = rtl_fw->phy_read; + int predata = 0, count = 0; + size_t index; + + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); + u32 data = action & 0x0000ffff; + u32 regno = (action & 0x0fff0000) >> 16; + enum rtl_fw_opcode opcode = action >> 28; + + if (!action) + break; + + switch (opcode) { + case PHY_READ: + predata = fw_read(tp, regno); + count++; + break; + case PHY_DATA_OR: + predata |= data; + break; + case PHY_DATA_AND: + predata &= data; + break; + case PHY_BJMPN: + index -= (regno + 1); + break; + case PHY_MDIO_CHG: + if (data) { + fw_write = rtl_fw->mac_mcu_write; + fw_read = rtl_fw->mac_mcu_read; + } else { + fw_write = rtl_fw->phy_write; + fw_read = rtl_fw->phy_read; + } + + break; + case PHY_CLEAR_READCOUNT: + count = 0; + break; + case PHY_WRITE: + fw_write(tp, regno, data); + break; + case PHY_READCOUNT_EQ_SKIP: + if (count == data) + index++; + break; + case PHY_COMP_EQ_SKIPN: + if (predata == data) + index += regno; + break; + case PHY_COMP_NEQ_SKIPN: + if (predata != data) + index += regno; + break; + case PHY_WRITE_PREVIOUS: + fw_write(tp, regno, predata); + break; + case PHY_SKIPN: + index += regno; + break; + case PHY_DELAY_MS: + mdelay(data); + break; + } + } +} + +void rtl8126_fw_release_firmware(struct rtl8126_fw *rtl_fw) +{ + release_firmware(rtl_fw->fw); +} + +int rtl8126_fw_request_firmware(struct rtl8126_fw *rtl_fw) +{ + int rc; + + rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); + if (rc < 0) + goto out; + + if (!rtl8126_fw_format_ok(rtl_fw) || !rtl8126_fw_data_ok(rtl_fw)) { + release_firmware(rtl_fw->fw); + rc = -EINVAL; + goto out; + } + + return 0; +out: + dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n", + rtl_fw->fw_name, rc); + return rc; +} diff --git a/package/lean/r8126/src/r8126_firmware.h b/package/lean/r8126/src/r8126_firmware.h new file mode 100644 index 000000000..5ae6f936a --- /dev/null +++ b/package/lean/r8126/src/r8126_firmware.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8126_FIRMWARE_H +#define _LINUX_R8126_FIRMWARE_H + +#include +#include + +struct rtl8126_private; +typedef void (*rtl8126_fw_write_t)(struct rtl8126_private *tp, u16 reg, u16 val); +typedef u32 (*rtl8126_fw_read_t)(struct rtl8126_private *tp, u16 reg); + +#define RTL8126_VER_SIZE 32 + +struct rtl8126_fw { + rtl8126_fw_write_t phy_write; + rtl8126_fw_read_t phy_read; + rtl8126_fw_write_t mac_mcu_write; + rtl8126_fw_read_t mac_mcu_read; + const struct firmware *fw; + const char *fw_name; + struct device *dev; + + char version[RTL8126_VER_SIZE]; + + struct rtl8126_fw_phy_action { + __le32 *code; + size_t size; + } phy_action; +}; + +int rtl8126_fw_request_firmware(struct rtl8126_fw *rtl_fw); +void rtl8126_fw_release_firmware(struct rtl8126_fw *rtl_fw); +void rtl8126_fw_write_firmware(struct rtl8126_private *tp, struct rtl8126_fw *rtl_fw); + +#endif /* _LINUX_R8126_FIRMWARE_H */ diff --git a/package/lean/r8126/src/r8126_n.c b/package/lean/r8126/src/r8126_n.c new file mode 100644 index 000000000..d01c7ef94 --- /dev/null +++ b/package/lean/r8126/src/r8126_n.c @@ -0,0 +1,17425 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +/* + * This driver is modified from r8169.c in Linux kernel 2.6.18 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#include +#include +#endif +#include +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +#include +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#define dev_printk(A,B,fmt,args...) printk(A fmt,##args) +#else +#include +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10) +#include +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10) */ + +#include +#include + +#include "r8126.h" +#include "rtl_eeprom.h" +#include "rtltool.h" +#include "r8126_firmware.h" + +#ifdef ENABLE_R8126_PROCFS +#include +#include +#endif + +#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw" +#define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw" + +static const struct { + const char *name; + const char *fw_name; +} rtl_chip_fw_infos[] = { + /* PCI-E devices. */ + [CFG_METHOD_1] = {"RTL8126A", }, + [CFG_METHOD_2] = {"RTL8126A", FIRMWARE_8126A_2}, + [CFG_METHOD_3] = {"RTL8126A", FIRMWARE_8126A_3}, + [CFG_METHOD_DEFAULT] = {"Unknown", }, +}; + +#define _R(NAME,MAC,RCR,MASK,JumFrameSz) \ + { .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz } + +static const struct { + const char *name; + u8 mcfg; + u32 RCR_Cfg; + u32 RxConfigMask; /* Clears the bits supported by this chip */ + u32 jumbo_frame_sz; +} rtl_chip_info[] = { + _R("RTL8126A", + CFG_METHOD_1, + Rx_Fetch_Number_8 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST_unlimited << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8126A", + CFG_METHOD_2, + Rx_Fetch_Number_8 | Rx_Close_Multiple | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST_512 << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8126A", + CFG_METHOD_3, + Rx_Fetch_Number_8 | Rx_Close_Multiple | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST_512 << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("Unknown", + CFG_METHOD_DEFAULT, + (RX_DMA_BURST_unlimited << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_1k) +}; +#undef _R + + +#ifndef PCI_VENDOR_ID_DLINK +#define PCI_VENDOR_ID_DLINK 0x1186 +#endif + +static struct pci_device_id rtl8126_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8126), }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5000), }, + {0,}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8126_pci_tbl); + +static int use_dac = 1; +static int timer_count = 0x2600; +static int timer_count_v2 = (0x2600 / 0x100); + +static struct { + u32 msg_enable; +} debug = { -1 }; + +static unsigned int speed_mode = SPEED_5000; +static unsigned int duplex_mode = DUPLEX_FULL; +static unsigned int autoneg_mode = AUTONEG_ENABLE; +#ifdef CONFIG_ASPM +static int aspm = 1; +#else +static int aspm = 0; +#endif +#ifdef ENABLE_S5WOL +static int s5wol = 1; +#else +static int s5wol = 0; +#endif +#ifdef ENABLE_S5_KEEP_CURR_MAC +static int s5_keep_curr_mac = 1; +#else +static int s5_keep_curr_mac = 0; +#endif +#ifdef ENABLE_EEE +static int eee_enable = 1; +#else +static int eee_enable = 0; +#endif +#ifdef CONFIG_SOC_LAN +static ulong hwoptimize = HW_PATCH_SOC_LAN; +#else +static ulong hwoptimize = 0; +#endif +#ifdef ENABLE_S0_MAGIC_PACKET +static int s0_magic_packet = 1; +#else +static int s0_magic_packet = 0; +#endif +#ifdef ENABLE_TX_NO_CLOSE +static int tx_no_close_enable = 1; +#else +static int tx_no_close_enable = 0; +#endif +#ifdef ENABLE_PTP_MASTER_MODE +static int enable_ptp_master_mode = 1; +#else +static int enable_ptp_master_mode = 0; +#endif +#ifdef DISABLE_WOL_SUPPORT +static int disable_wol_support = 1; +#else +static int disable_wol_support = 0; +#endif + +#ifdef ENABLE_DOUBLE_VLAN +static int enable_double_vlan = 1; +#else +static int enable_double_vlan = 0; +#endif + +MODULE_AUTHOR("Realtek and the Linux r8126 crew "); +MODULE_DESCRIPTION("Realtek r8126 Ethernet controller driver"); + +module_param(speed_mode, uint, 0); +MODULE_PARM_DESC(speed_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(duplex_mode, uint, 0); +MODULE_PARM_DESC(duplex_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(autoneg_mode, uint, 0); +MODULE_PARM_DESC(autoneg_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(aspm, int, 0); +MODULE_PARM_DESC(aspm, "Enable ASPM."); + +module_param(s5wol, int, 0); +MODULE_PARM_DESC(s5wol, "Enable Shutdown Wake On Lan."); + +module_param(s5_keep_curr_mac, int, 0); +MODULE_PARM_DESC(s5_keep_curr_mac, "Enable Shutdown Keep Current MAC Address."); + +module_param(use_dac, int, 0); +MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); + +module_param(timer_count, int, 0); +MODULE_PARM_DESC(timer_count, "Timer Interrupt Interval."); + +module_param(eee_enable, int, 0); +MODULE_PARM_DESC(eee_enable, "Enable Energy Efficient Ethernet."); + +module_param(hwoptimize, ulong, 0); +MODULE_PARM_DESC(hwoptimize, "Enable HW optimization function."); + +module_param(s0_magic_packet, int, 0); +MODULE_PARM_DESC(s0_magic_packet, "Enable S0 Magic Packet."); + +module_param(tx_no_close_enable, int, 0); +MODULE_PARM_DESC(tx_no_close_enable, "Enable TX No Close."); + +module_param(enable_ptp_master_mode, int, 0); +MODULE_PARM_DESC(enable_ptp_master_mode, "Enable PTP Master Mode."); + +module_param(disable_wol_support, int, 0); +MODULE_PARM_DESC(disable_wol_support, "Disable PM support."); + +module_param(enable_double_vlan, int, 0); +MODULE_PARM_DESC(enable_double_vlan, "Enable Double VLAN."); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +module_param_named(debug, debug.msg_enable, int, 0); +MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); +#endif//LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + +MODULE_LICENSE("GPL"); +#ifdef ENABLE_USE_FIRMWARE_FILE +MODULE_FIRMWARE(FIRMWARE_8126A_2); +MODULE_FIRMWARE(FIRMWARE_8126A_3); +#endif + +MODULE_VERSION(RTL8126_VERSION); + +/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +static void rtl8126_esd_timer(unsigned long __opaque); +#else +static void rtl8126_esd_timer(struct timer_list *t); +#endif +*/ +/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +static void rtl8126_link_timer(unsigned long __opaque); +#else +static void rtl8126_link_timer(struct timer_list *t); +#endif +*/ + +static netdev_tx_t rtl8126_start_xmit(struct sk_buff *skb, struct net_device *dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8126_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8126_interrupt(int irq, void *dev_instance); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8126_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8126_interrupt_msix(int irq, void *dev_instance); +#endif +static void rtl8126_set_rx_mode(struct net_device *dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static void rtl8126_tx_timeout(struct net_device *dev, unsigned int txqueue); +#else +static void rtl8126_tx_timeout(struct net_device *dev); +#endif +static int rtl8126_rx_interrupt(struct net_device *, struct rtl8126_private *, struct rtl8126_rx_ring *, napi_budget); +static int rtl8126_tx_interrupt(struct rtl8126_tx_ring *ring, int budget); +static int rtl8126_tx_interrupt_with_vector(struct rtl8126_private *tp, const int message_id, int budget); +static void rtl8126_wait_for_quiescence(struct net_device *dev); +static int rtl8126_change_mtu(struct net_device *dev, int new_mtu); +static void rtl8126_down(struct net_device *dev); + +static int rtl8126_set_mac_address(struct net_device *dev, void *p); +static void rtl8126_rar_set(struct rtl8126_private *tp, const u8 *addr); +static void rtl8126_desc_addr_fill(struct rtl8126_private *); +static void rtl8126_tx_desc_init(struct rtl8126_private *tp); +static void rtl8126_rx_desc_init(struct rtl8126_private *tp); + +static void rtl8126_mdio_direct_write_phy_ocp(struct rtl8126_private *tp, u16 RegAddr,u16 value); +static u32 rtl8126_mdio_direct_read_phy_ocp(struct rtl8126_private *tp, u16 RegAddr); +static void rtl8126_clear_and_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 clearmask, u16 setmask); +static void rtl8126_clear_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask); +static void rtl8126_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask); +static u16 rtl8126_get_hw_phy_mcu_code_ver(struct rtl8126_private *tp); +static void rtl8126_phy_power_up(struct net_device *dev); +static void rtl8126_phy_power_down(struct net_device *dev); +static int rtl8126_set_speed(struct net_device *dev, u8 autoneg, u32 speed, u8 duplex, u64 adv); +static bool rtl8126_set_phy_mcu_patch_request(struct rtl8126_private *tp); +static bool rtl8126_clear_phy_mcu_patch_request(struct rtl8126_private *tp); + +#ifdef CONFIG_R8126_NAPI +static int rtl8126_poll(napi_ptr napi, napi_budget budget); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8126_reset_task(void *_data); +static void rtl8126_esd_task(void *_data); +static void rtl8126_linkchg_task(void *_data); +#else +static void rtl8126_reset_task(struct work_struct *work); +static void rtl8126_esd_task(struct work_struct *work); +static void rtl8126_linkchg_task(struct work_struct *work); +#endif +static void rtl8126_schedule_reset_work(struct rtl8126_private *tp); +static void rtl8126_schedule_esd_work(struct rtl8126_private *tp); +static void rtl8126_schedule_linkchg_work(struct rtl8126_private *tp); +static void rtl8126_init_all_schedule_work(struct rtl8126_private *tp); +static void rtl8126_cancel_all_schedule_work(struct rtl8126_private *tp); + +static inline struct device *tp_to_dev(struct rtl8126_private *tp) +{ + return &tp->pci_dev->dev; +} + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) && \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,00))) +void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, + u32 legacy_u32) +{ + bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); + dst[0] = legacy_u32; +} + +bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, + const unsigned long *src) +{ + bool retval = true; + + /* TODO: following test will soon always be true */ + if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) { + __ETHTOOL_DECLARE_LINK_MODE_MASK(ext); + + bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS); + bitmap_fill(ext, 32); + bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS); + if (bitmap_intersects(ext, src, + __ETHTOOL_LINK_MODE_MASK_NBITS)) { + /* src mask goes beyond bit 31 */ + retval = false; + } + } + *legacy_u32 = src[0]; + return retval; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + +#ifndef LPA_1000FULL +#define LPA_1000FULL 0x0800 +#endif + +#ifndef LPA_1000HALF +#define LPA_1000HALF 0x0400 +#endif + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) +static inline void eth_hw_addr_random(struct net_device *dev) +{ + random_ether_addr(dev->dev_addr); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#undef ethtool_ops +#define ethtool_ops _kc_ethtool_ops + +struct _kc_ethtool_ops { + int (*get_settings)(struct net_device *, struct ethtool_cmd *); + int (*set_settings)(struct net_device *, struct ethtool_cmd *); + void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); + int (*get_regs_len)(struct net_device *); + void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); + void (*get_wol)(struct net_device *, struct ethtool_wolinfo *); + int (*set_wol)(struct net_device *, struct ethtool_wolinfo *); + u32 (*get_msglevel)(struct net_device *); + void (*set_msglevel)(struct net_device *, u32); + int (*nway_reset)(struct net_device *); + u32 (*get_link)(struct net_device *); + int (*get_eeprom_len)(struct net_device *); + int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *); + int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *); + void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *); + int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *); + void (*get_pauseparam)(struct net_device *, + struct ethtool_pauseparam*); + int (*set_pauseparam)(struct net_device *, + struct ethtool_pauseparam*); + u32 (*get_rx_csum)(struct net_device *); + int (*set_rx_csum)(struct net_device *, u32); + u32 (*get_tx_csum)(struct net_device *); + int (*set_tx_csum)(struct net_device *, u32); + u32 (*get_sg)(struct net_device *); + int (*set_sg)(struct net_device *, u32); + u32 (*get_tso)(struct net_device *); + int (*set_tso)(struct net_device *, u32); + int (*self_test_count)(struct net_device *); + void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); + void (*get_strings)(struct net_device *, u32 stringset, u8 *); + int (*phys_id)(struct net_device *, u32); + int (*get_stats_count)(struct net_device *); + void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, + u64 *); +} *ethtool_ops = NULL; + +#undef SET_ETHTOOL_OPS +#define SET_ETHTOOL_OPS(netdev, ops) (ethtool_ops = (ops)) + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) +#ifndef SET_ETHTOOL_OPS +#define SET_ETHTOOL_OPS(netdev,ops) \ + ( (netdev)->ethtool_ops = (ops) ) +#endif //SET_ETHTOOL_OPS +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) + +//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) +#ifndef netif_msg_init +#define netif_msg_init _kc_netif_msg_init +/* copied from linux kernel 2.6.20 include/linux/netdevice.h */ +static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) +{ + /* use default */ + if (debug_value < 0 || debug_value >= (sizeof(u32) * 8)) + return default_msg_enable_bits; + if (debug_value == 0) /* no output */ + return 0; + /* set low N bits */ + return (1 << debug_value) - 1; +} + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) +static inline void eth_copy_and_sum (struct sk_buff *dest, + const unsigned char *src, + int len, int base) +{ + skb_copy_to_linear_data(dest, src, len); +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) +/* copied from linux kernel 2.6.20 /include/linux/time.h */ +/* Parameters used to convert the timespec values: */ +#define MSEC_PER_SEC 1000L + +/* copied from linux kernel 2.6.20 /include/linux/jiffies.h */ +/* + * Change timeval to jiffies, trying to avoid the + * most obvious overflows.. + * + * And some not so obvious. + * + * Note that we don't want to return MAX_LONG, because + * for various timeout reasons we often end up having + * to wait "jiffies+1" in order to guarantee that we wait + * at _least_ "jiffies" - so "jiffies+1" had better still + * be positive. + */ +#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1) + +/* + * Convert jiffies to milliseconds and back. + * + * Avoid unnecessary multiplications/divisions in the + * two most common HZ cases: + */ +static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (MSEC_PER_SEC / HZ) * j; +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); +#else + return (j * MSEC_PER_SEC) / HZ; +#endif +} + +static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m) +{ + if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return m * (HZ / MSEC_PER_SEC); +#else + return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; +#endif +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + +/* copied from linux kernel 2.6.12.6 /include/linux/pm.h */ +typedef int __bitwise pci_power_t; + +/* copied from linux kernel 2.6.12.6 /include/linux/pci.h */ +typedef u32 __bitwise pm_message_t; + +#define PCI_D0 ((pci_power_t __force) 0) +#define PCI_D1 ((pci_power_t __force) 1) +#define PCI_D2 ((pci_power_t __force) 2) +#define PCI_D3hot ((pci_power_t __force) 3) +#define PCI_D3cold ((pci_power_t __force) 4) +#define PCI_POWER_ERROR ((pci_power_t __force) -1) + +/* copied from linux kernel 2.6.12.6 /drivers/pci/pci.c */ +/** + * pci_choose_state - Choose the power state of a PCI device + * @dev: PCI device to be suspended + * @state: target sleep state for the whole system. This is the value + * that is passed to suspend() function. + * + * Returns PCI power state suitable for given device and given system + * message. + */ + +pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) +{ + if (!pci_find_capability(dev, PCI_CAP_ID_PM)) + return PCI_D0; + + switch (state) { + case 0: + return PCI_D0; + case 3: + return PCI_D3hot; + default: + printk("They asked me for state %d\n", state); +// BUG(); + } + return PCI_D0; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) +/** + * msleep_interruptible - sleep waiting for waitqueue interruptions + * @msecs: Time in milliseconds to sleep for + */ +#define msleep_interruptible _kc_msleep_interruptible +unsigned long _kc_msleep_interruptible(unsigned int msecs) +{ + unsigned long timeout = _kc_msecs_to_jiffies(msecs); + + while (timeout && !signal_pending(current)) { + set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return _kc_jiffies_to_msecs(timeout); +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) +/* copied from linux kernel 2.6.20 include/linux/sched.h */ +#ifndef __sched +#define __sched __attribute__((__section__(".sched.text"))) +#endif + +/* copied from linux kernel 2.6.20 kernel/timer.c */ +signed long __sched schedule_timeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_timeout(timeout); +} + +/* copied from linux kernel 2.6.20 include/linux/mii.h */ +#undef if_mii +#define if_mii _kc_if_mii +static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) +{ + return (struct mii_ioctl_data *) &rq->ifr_ifru; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + +static u32 rtl8126_read_thermal_sensor(struct rtl8126_private *tp) +{ + u16 ts_digout; + + switch (tp->mcfg) { + default: + ts_digout = 0xffff; + break; + } + + return ts_digout; +} + +int rtl8126_dump_tally_counter(struct rtl8126_private *tp, dma_addr_t paddr) +{ + u32 cmd; + u32 WaitCnt; + int retval = -1; + + RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); + cmd = (u64)paddr & DMA_BIT_MASK(32); + RTL_W32(tp, CounterAddrLow, cmd); + RTL_W32(tp, CounterAddrLow, cmd | CounterDump); + + WaitCnt = 0; + while (RTL_R32(tp, CounterAddrLow) & CounterDump) { + udelay(10); + + WaitCnt++; + if (WaitCnt > 20) + break; + } + + if (WaitCnt <= 20) + retval = 0; + + return retval; +} + +static u32 +rtl8126_get_hw_clo_ptr(struct rtl8126_tx_ring *ring) +{ + struct rtl8126_private *tp = ring->priv; + + switch (tp->HwSuppTxNoCloseVer) { + case 3: + return RTL_R16(tp, ring->hw_clo_ptr_reg); + case 4: + case 5: + case 6: + return RTL_R32(tp, ring->hw_clo_ptr_reg); + default: +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + WARN_ON(1); +#endif + return 0; + } +} + +static u32 +rtl8126_get_sw_tail_ptr(struct rtl8126_tx_ring *ring) +{ + struct rtl8126_private *tp = ring->priv; + + switch (tp->HwSuppTxNoCloseVer) { + case 3: + return RTL_R16(tp, ring->sw_tail_ptr_reg); + case 4: + case 5: + case 6: + return RTL_R32(tp, ring->sw_tail_ptr_reg); + default: +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + WARN_ON(1); +#endif + return 0; + } +} + +static bool +rtl8126_sysfs_testmode_on(struct rtl8126_private *tp) +{ +#ifdef ENABLE_R8126_SYSFS + return !!tp->testmode; +#else + return 1; +#endif +} + +static u32 rtl8126_convert_link_speed(u16 status) +{ + u32 speed = SPEED_UNKNOWN; + + if (status & LinkStatus) { + if (status & _5000bpsF) + speed = SPEED_5000; + else if (status & _2500bpsF) + speed = SPEED_2500; + else if (status & _1000bpsF) + speed = SPEED_1000; + else if (status & _100bps) + speed = SPEED_100; + else if (status & _10bps) + speed = SPEED_10; + } + + return speed; +} + +static void rtl8126_mdi_swap(struct rtl8126_private *tp) +{ + int i; + u16 reg, val, mdi_reverse; + u16 tps_p0, tps_p1, tps_p2, tps_p3, tps_p3_p0; + + switch (tp->mcfg) { + default: + return; + }; + + tps_p3_p0 = rtl8126_mac_ocp_read(tp, 0xD440) & 0xF000; + tps_p3 = !!(tps_p3_p0 & BIT_15); + tps_p2 = !!(tps_p3_p0 & BIT_14); + tps_p1 = !!(tps_p3_p0 & BIT_13); + tps_p0 = !!(tps_p3_p0 & BIT_12); + mdi_reverse = rtl8126_mac_ocp_read(tp, 0xD442); + + if ((mdi_reverse & BIT_5) && tps_p3_p0 == 0xA000) + return; + + if (!(mdi_reverse & BIT_5)) + val = tps_p0 << 8 | + tps_p1 << 9 | + tps_p2 << 10 | + tps_p3 << 11; + else + val = tps_p3 << 8 | + tps_p2 << 9 | + tps_p1 << 10 | + tps_p0 << 11; + + for (i=8; i<12; i++) { + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, reg); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + BIT(i), + val & BIT(i)); + } +} + +static int rtl8126_vcd_test(struct rtl8126_private *tp) +{ + u16 val; + u32 wait_cnt; + int ret = -1; + + rtl8126_mdi_swap(tp); + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA422, BIT(0)); + rtl8126_set_eth_phy_ocp_bit(tp, 0xA422, 0x00F0); + rtl8126_set_eth_phy_ocp_bit(tp, 0xA422, BIT(0)); + + wait_cnt = 0; + do { + mdelay(1); + val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA422); + wait_cnt++; + } while (!(val & BIT_15) && (wait_cnt < 5000)); + + if (wait_cnt == 5000) + goto exit; + + ret = 0; + +exit: + return ret; +} + +static void rtl8126_get_cp_len(struct rtl8126_private *tp, + int cp_len[RTL8126_CP_NUM]) +{ + int i; + u16 status; + int tmp_cp_len; + + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus) { + if (status & _10bps) { + tmp_cp_len = -1; + } else if (status & (_100bps | _1000bpsF)) { + rtl8126_mdio_write(tp, 0x1f, 0x0a88); + tmp_cp_len = rtl8126_mdio_read(tp, 0x10); + } else if (status & _2500bpsF) { + switch (tp->mcfg) { + default: + rtl8126_mdio_write(tp, 0x1f, 0x0acb); + tmp_cp_len = rtl8126_mdio_read(tp, 0x15); + tmp_cp_len >>= 2; + break; + } + } else + tmp_cp_len = 0; + } else + tmp_cp_len = 0; + + if (tmp_cp_len > 0) + tmp_cp_len &= 0xff; + for (i=0; i RTL8126_MAX_SUPPORT_CP_LEN) + cp_len[i] = RTL8126_MAX_SUPPORT_CP_LEN; + + return; +} + +static int __rtl8126_get_cp_status(u16 val) +{ + switch (val) { + case 0x0060: + return rtl8126_cp_normal; + case 0x0048: + return rtl8126_cp_open; + case 0x0050: + return rtl8126_cp_short; + case 0x0042: + case 0x0044: + return rtl8126_cp_mismatch; + default: + return rtl8126_cp_normal; + } +} + +static int _rtl8126_get_cp_status(struct rtl8126_private *tp, u8 pair_num) +{ + u16 val; + int cp_status = rtl8126_cp_unknown; + + if (pair_num > 3) + goto exit; + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8027 + 4 * pair_num); + val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA438); + + cp_status = __rtl8126_get_cp_status(val); + +exit: + return cp_status; +} + +static const char * rtl8126_get_cp_status_string(int cp_status) +{ + switch(cp_status) { + case rtl8126_cp_normal: + return "normal "; + case rtl8126_cp_short: + return "short "; + case rtl8126_cp_open: + return "open "; + case rtl8126_cp_mismatch: + return "mismatch"; + default: + return "unknown "; + } +} + +static u16 rtl8126_get_cp_pp(struct rtl8126_private *tp, u8 pair_num) +{ + u16 pp = 0; + + if (pair_num > 3) + goto exit; + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8029 + 4 * pair_num); + pp = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA438); + + pp &= 0x3fff; + pp /= 80; + +exit: + return pp; +} + +static void rtl8126_get_cp_status(struct rtl8126_private *tp, + int cp_status[RTL8126_CP_NUM], + bool poe_mode) +{ + u16 status; + int i; + + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus && !(status & (_10bps | _100bps))) { + for (i=0; i= KERNEL_VERSION(3,10,0) +static int proc_get_driver_variable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Driver Variable\n"); + + rtnl_lock(); + + seq_puts(m, "Variable\tValue\n----------\t-----\n"); + seq_printf(m, "MODULENAME\t%s\n", MODULENAME); + seq_printf(m, "driver version\t%s\n", RTL8126_VERSION); + seq_printf(m, "mcfg\t%d\n", tp->mcfg); + seq_printf(m, "chipset\t%d\n", tp->chipset); + seq_printf(m, "chipset_name\t%s\n", rtl_chip_info[tp->chipset].name); + seq_printf(m, "mtu\t%d\n", dev->mtu); + seq_printf(m, "NUM_RX_DESC\t0x%x\n", tp->rx_ring[0].num_rx_desc); + seq_printf(m, "cur_rx0\t0x%x\n", tp->rx_ring[0].cur_rx); + seq_printf(m, "dirty_rx0\t0x%x\n", tp->rx_ring[0].dirty_rx); + seq_printf(m, "cur_rx1\t0x%x\n", tp->rx_ring[1].cur_rx); + seq_printf(m, "dirty_rx1\t0x%x\n", tp->rx_ring[1].dirty_rx); + seq_printf(m, "cur_rx2\t0x%x\n", tp->rx_ring[2].cur_rx); + seq_printf(m, "dirty_rx2\t0x%x\n", tp->rx_ring[2].dirty_rx); + seq_printf(m, "cur_rx3\t0x%x\n", tp->rx_ring[3].cur_rx); + seq_printf(m, "dirty_rx3\t0x%x\n", tp->rx_ring[3].dirty_rx); + seq_printf(m, "NUM_TX_DESC\t0x%x\n", tp->tx_ring[0].num_tx_desc); + seq_printf(m, "cur_tx0\t0x%x\n", tp->tx_ring[0].cur_tx); + seq_printf(m, "dirty_tx0\t0x%x\n", tp->tx_ring[0].dirty_tx); + seq_printf(m, "cur_tx1\t0x%x\n", tp->tx_ring[1].cur_tx); + seq_printf(m, "dirty_tx1\t0x%x\n", tp->tx_ring[1].dirty_tx); + seq_printf(m, "rx_buf_sz\t0x%x\n", tp->rx_buf_sz); +#ifdef ENABLE_PAGE_REUSE + seq_printf(m, "rx_buf_page_order\t0x%x\n", tp->rx_buf_page_order); + seq_printf(m, "rx_buf_page_size\t0x%x\n", tp->rx_buf_page_size); + seq_printf(m, "page_reuse_fail_cnt\t0x%x\n", tp->page_reuse_fail_cnt); +#endif //ENABLE_PAGE_REUSE + seq_printf(m, "esd_flag\t0x%x\n", tp->esd_flag); + seq_printf(m, "pci_cfg_is_read\t0x%x\n", tp->pci_cfg_is_read); + seq_printf(m, "rtl8126_rx_config\t0x%x\n", tp->rtl8126_rx_config); + seq_printf(m, "cp_cmd\t0x%x\n", tp->cp_cmd); + seq_printf(m, "intr_mask\t0x%x\n", tp->intr_mask); + seq_printf(m, "timer_intr_mask\t0x%x\n", tp->timer_intr_mask); + seq_printf(m, "wol_enabled\t0x%x\n", tp->wol_enabled); + seq_printf(m, "wol_opts\t0x%x\n", tp->wol_opts); + seq_printf(m, "efuse_ver\t0x%x\n", tp->efuse_ver); + seq_printf(m, "eeprom_type\t0x%x\n", tp->eeprom_type); + seq_printf(m, "autoneg\t0x%x\n", tp->autoneg); + seq_printf(m, "duplex\t0x%x\n", tp->duplex); + seq_printf(m, "speed\t%d\n", tp->speed); + seq_printf(m, "advertising\t0x%llx\n", tp->advertising); + seq_printf(m, "eeprom_len\t0x%x\n", tp->eeprom_len); + seq_printf(m, "cur_page\t0x%x\n", tp->cur_page); + seq_printf(m, "features\t0x%x\n", tp->features); + seq_printf(m, "org_pci_offset_99\t0x%x\n", tp->org_pci_offset_99); + seq_printf(m, "org_pci_offset_180\t0x%x\n", tp->org_pci_offset_180); + seq_printf(m, "issue_offset_99_event\t0x%x\n", tp->issue_offset_99_event); + seq_printf(m, "org_pci_offset_80\t0x%x\n", tp->org_pci_offset_80); + seq_printf(m, "org_pci_offset_81\t0x%x\n", tp->org_pci_offset_81); + seq_printf(m, "use_timer_interrupt\t0x%x\n", tp->use_timer_interrupt); + seq_printf(m, "HwIcVerUnknown\t0x%x\n", tp->HwIcVerUnknown); + seq_printf(m, "NotWrRamCodeToMicroP\t0x%x\n", tp->NotWrRamCodeToMicroP); + seq_printf(m, "NotWrMcuPatchCode\t0x%x\n", tp->NotWrMcuPatchCode); + seq_printf(m, "HwHasWrRamCodeToMicroP\t0x%x\n", tp->HwHasWrRamCodeToMicroP); + seq_printf(m, "sw_ram_code_ver\t0x%x\n", tp->sw_ram_code_ver); + seq_printf(m, "hw_ram_code_ver\t0x%x\n", tp->hw_ram_code_ver); + seq_printf(m, "rtk_enable_diag\t0x%x\n", tp->rtk_enable_diag); + seq_printf(m, "ShortPacketSwChecksum\t0x%x\n", tp->ShortPacketSwChecksum); + seq_printf(m, "UseSwPaddingShortPkt\t0x%x\n", tp->UseSwPaddingShortPkt); + seq_printf(m, "RequireAdcBiasPatch\t0x%x\n", tp->RequireAdcBiasPatch); + seq_printf(m, "AdcBiasPatchIoffset\t0x%x\n", tp->AdcBiasPatchIoffset); + seq_printf(m, "RequireAdjustUpsTxLinkPulseTiming\t0x%x\n", tp->RequireAdjustUpsTxLinkPulseTiming); + seq_printf(m, "SwrCnt1msIni\t0x%x\n", tp->SwrCnt1msIni); + seq_printf(m, "HwSuppNowIsOobVer\t0x%x\n", tp->HwSuppNowIsOobVer); + seq_printf(m, "HwFiberModeVer\t0x%x\n", tp->HwFiberModeVer); + seq_printf(m, "HwFiberStat\t0x%x\n", tp->HwFiberStat); + seq_printf(m, "HwSwitchMdiToFiber\t0x%x\n", tp->HwSwitchMdiToFiber); + seq_printf(m, "NicCustLedValue\t0x%x\n", tp->NicCustLedValue); + seq_printf(m, "RequiredSecLanDonglePatch\t0x%x\n", tp->RequiredSecLanDonglePatch); + seq_printf(m, "HwSuppDashVer\t0x%x\n", tp->HwSuppDashVer); + seq_printf(m, "DASH\t0x%x\n", tp->DASH); + seq_printf(m, "dash_printer_enabled\t0x%x\n", tp->dash_printer_enabled); + seq_printf(m, "HwSuppKCPOffloadVer\t0x%x\n", tp->HwSuppKCPOffloadVer); + seq_printf(m, "speed_mode\t0x%x\n", speed_mode); + seq_printf(m, "duplex_mode\t0x%x\n", duplex_mode); + seq_printf(m, "autoneg_mode\t0x%x\n", autoneg_mode); + seq_printf(m, "aspm\t0x%x\n", aspm); + seq_printf(m, "s5wol\t0x%x\n", s5wol); + seq_printf(m, "s5_keep_curr_mac\t0x%x\n", s5_keep_curr_mac); + seq_printf(m, "eee_enable\t0x%x\n", tp->eee.eee_enabled); + seq_printf(m, "hwoptimize\t0x%lx\n", hwoptimize); + seq_printf(m, "proc_init_num\t0x%x\n", proc_init_num); + seq_printf(m, "s0_magic_packet\t0x%x\n", s0_magic_packet); + seq_printf(m, "disable_wol_support\t0x%x\n", disable_wol_support); + seq_printf(m, "enable_double_vlan\t0x%x\n", enable_double_vlan); + seq_printf(m, "HwSuppMagicPktVer\t0x%x\n", tp->HwSuppMagicPktVer); + seq_printf(m, "HwSuppLinkChgWakeUpVer\t0x%x\n", tp->HwSuppLinkChgWakeUpVer); + seq_printf(m, "HwSuppD0SpeedUpVer\t0x%x\n", tp->HwSuppD0SpeedUpVer); + seq_printf(m, "D0SpeedUpSpeed\t0x%x\n", tp->D0SpeedUpSpeed); + seq_printf(m, "HwSuppCheckPhyDisableModeVer\t0x%x\n", tp->HwSuppCheckPhyDisableModeVer); + seq_printf(m, "HwPkgDet\t0x%x\n", tp->HwPkgDet); + seq_printf(m, "HwSuppTxNoCloseVer\t0x%x\n", tp->HwSuppTxNoCloseVer); + seq_printf(m, "EnableTxNoClose\t0x%x\n", tp->EnableTxNoClose); + seq_printf(m, "NextHwDesCloPtr0\t0x%x\n", tp->tx_ring[0].NextHwDesCloPtr); + seq_printf(m, "BeginHwDesCloPtr0\t0x%x\n", tp->tx_ring[0].BeginHwDesCloPtr); + seq_printf(m, "hw_clo_ptr_reg0\t0x%x\n", rtl8126_get_hw_clo_ptr(&tp->tx_ring[0])); + seq_printf(m, "sw_tail_ptr_reg0\t0x%x\n", rtl8126_get_sw_tail_ptr(&tp->tx_ring[0])); + seq_printf(m, "NextHwDesCloPtr1\t0x%x\n", tp->tx_ring[1].NextHwDesCloPtr); + seq_printf(m, "BeginHwDesCloPtr1\t0x%x\n", tp->tx_ring[1].BeginHwDesCloPtr); + seq_printf(m, "hw_clo_ptr_reg1\t0x%x\n", rtl8126_get_hw_clo_ptr(&tp->tx_ring[1])); + seq_printf(m, "sw_tail_ptr_reg1\t0x%x\n", rtl8126_get_sw_tail_ptr(&tp->tx_ring[1])); + seq_printf(m, "InitRxDescType\t0x%x\n", tp->InitRxDescType); + seq_printf(m, "RxDescLength\t0x%x\n", tp->RxDescLength); + seq_printf(m, "num_rx_rings\t0x%x\n", tp->num_rx_rings); + seq_printf(m, "num_tx_rings\t0x%x\n", tp->num_tx_rings); + seq_printf(m, "tot_rx_rings\t0x%x\n", rtl8126_tot_rx_rings(tp)); + seq_printf(m, "tot_tx_rings\t0x%x\n", rtl8126_tot_tx_rings(tp)); + seq_printf(m, "HwSuppNumRxQueues\t0x%x\n", tp->HwSuppNumRxQueues); + seq_printf(m, "HwSuppNumTxQueues\t0x%x\n", tp->HwSuppNumTxQueues); + seq_printf(m, "EnableRss\t0x%x\n", tp->EnableRss); + seq_printf(m, "EnablePtp\t0x%x\n", tp->EnablePtp); + seq_printf(m, "ptp_master_mode\t0x%x\n", tp->ptp_master_mode); + seq_printf(m, "min_irq_nvecs\t0x%x\n", tp->min_irq_nvecs); + seq_printf(m, "irq_nvecs\t0x%x\n", tp->irq_nvecs); + seq_printf(m, "hw_supp_irq_nvecs\t0x%x\n", tp->hw_supp_irq_nvecs); + seq_printf(m, "ring_lib_enabled\t0x%x\n", tp->ring_lib_enabled); + seq_printf(m, "HwSuppIsrVer\t0x%x\n", tp->HwSuppIsrVer); + seq_printf(m, "HwCurrIsrVer\t0x%x\n", tp->HwCurrIsrVer); +#ifdef ENABLE_PTP_SUPPORT + seq_printf(m, "tx_hwtstamp_timeouts\t0x%x\n", tp->tx_hwtstamp_timeouts); + seq_printf(m, "tx_hwtstamp_skipped\t0x%x\n", tp->tx_hwtstamp_skipped); +#endif + seq_printf(m, "random_mac\t0x%x\n", tp->random_mac); + seq_printf(m, "org_mac_addr\t%pM\n", tp->org_mac_addr); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + seq_printf(m, "perm_addr\t%pM\n", dev->perm_addr); +#endif + seq_printf(m, "dev_addr\t%pM\n", dev->dev_addr); + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_tally_counter(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + struct rtl8126_counters *counters; + dma_addr_t paddr; + + seq_puts(m, "\nDump Tally Counter\n"); + + rtnl_lock(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) { + seq_puts(m, "\nDump Tally Counter Fail\n"); + goto out_unlock; + } + + rtl8126_dump_tally_counter(tp, paddr); + + seq_puts(m, "Statistics\tValue\n----------\t-----\n"); + seq_printf(m, "tx_packets\t%lld\n", le64_to_cpu(counters->tx_packets)); + seq_printf(m, "rx_packets\t%lld\n", le64_to_cpu(counters->rx_packets)); + seq_printf(m, "tx_errors\t%lld\n", le64_to_cpu(counters->tx_errors)); + seq_printf(m, "rx_errors\t%d\n", le32_to_cpu(counters->rx_errors)); + seq_printf(m, "rx_missed\t%d\n", le16_to_cpu(counters->rx_missed)); + seq_printf(m, "align_errors\t%d\n", le16_to_cpu(counters->align_errors)); + seq_printf(m, "tx_one_collision\t%d\n", le32_to_cpu(counters->tx_one_collision)); + seq_printf(m, "tx_multi_collision\t%d\n", le32_to_cpu(counters->tx_multi_collision)); + seq_printf(m, "rx_unicast\t%lld\n", le64_to_cpu(counters->rx_unicast)); + seq_printf(m, "rx_broadcast\t%lld\n", le64_to_cpu(counters->rx_broadcast)); + seq_printf(m, "rx_multicast\t%d\n", le32_to_cpu(counters->rx_multicast)); + seq_printf(m, "tx_aborted\t%d\n", le16_to_cpu(counters->tx_aborted)); + seq_printf(m, "tx_underrun\t%d\n", le16_to_cpu(counters->tx_underrun)); + + seq_printf(m, "tx_octets\t%lld\n", le64_to_cpu(counters->tx_octets)); + seq_printf(m, "rx_octets\t%lld\n", le64_to_cpu(counters->rx_octets)); + seq_printf(m, "rx_multicast64\t%lld\n", le64_to_cpu(counters->rx_multicast64)); + seq_printf(m, "tx_unicast64\t%lld\n", le64_to_cpu(counters->tx_unicast64)); + seq_printf(m, "tx_broadcast64\t%lld\n", le64_to_cpu(counters->tx_broadcast64)); + seq_printf(m, "tx_multicast64\t%lld\n", le64_to_cpu(counters->tx_multicast64)); + seq_printf(m, "tx_pause_on\t%d\n", le32_to_cpu(counters->tx_pause_on)); + seq_printf(m, "tx_pause_off\t%d\n", le32_to_cpu(counters->tx_pause_off)); + seq_printf(m, "tx_pause_all\t%d\n", le32_to_cpu(counters->tx_pause_all)); + seq_printf(m, "tx_deferred\t%d\n", le32_to_cpu(counters->tx_deferred)); + seq_printf(m, "tx_late_collision\t%d\n", le32_to_cpu(counters->tx_late_collision)); + seq_printf(m, "tx_all_collision\t%d\n", le32_to_cpu(counters->tx_all_collision)); + seq_printf(m, "tx_aborted32\t%d\n", le32_to_cpu(counters->tx_aborted32)); + seq_printf(m, "align_errors32\t%d\n", le32_to_cpu(counters->align_errors32)); + seq_printf(m, "rx_frame_too_long\t%d\n", le32_to_cpu(counters->rx_frame_too_long)); + seq_printf(m, "rx_runt\t%d\n", le32_to_cpu(counters->rx_runt)); + seq_printf(m, "rx_pause_on\t%d\n", le32_to_cpu(counters->rx_pause_on)); + seq_printf(m, "rx_pause_off\t%d\n", le32_to_cpu(counters->rx_pause_off)); + seq_printf(m, "rx_pause_all\t%d\n", le32_to_cpu(counters->rx_pause_all)); + seq_printf(m, "rx_unknown_opcode\t%d\n", le32_to_cpu(counters->rx_unknown_opcode)); + seq_printf(m, "rx_mac_error\t%d\n", le32_to_cpu(counters->rx_mac_error)); + seq_printf(m, "tx_underrun32\t%d\n", le32_to_cpu(counters->tx_underrun32)); + seq_printf(m, "rx_mac_missed\t%d\n", le32_to_cpu(counters->rx_mac_missed)); + seq_printf(m, "rx_tcam_dropped\t%d\n", le32_to_cpu(counters->rx_tcam_dropped)); + seq_printf(m, "tdu\t%d\n", le32_to_cpu(counters->tdu)); + seq_printf(m, "rdu\t%d\n", le32_to_cpu(counters->rdu)); + + seq_putc(m, '\n'); + +out_unlock: + rtnl_unlock(); + + return 0; +} + +static int proc_get_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8126_MAC_REGS_SIZE; + u8 byte_rd; + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + + seq_puts(m, "\nDump MAC Registers\n"); + seq_puts(m, "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%04x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + max = 0xB00; + for (n = 0xA00; n < max;) { + seq_printf(m, "\n0x%04x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + max = 0xD40; + for (n = 0xD00; n < max;) { + seq_printf(m, "\n0x%04x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + max = 0x2840; + for (n = 0x2800; n < max;) { + seq_printf(m, "\n0x%04x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_all_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max; + u8 byte_rd; + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + + seq_puts(m, "\nDump All MAC Registers\n"); + seq_puts(m, "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + max = pci_resource_len(pdev, 2); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%04x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + rtnl_unlock(); + + seq_printf(m, "\nTotal length:0x%X", max); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_pcie_phy(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8126_EPHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8126_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump PCIE PHY\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8126_ephy_read(tp, n); + seq_printf(m, "%04x ", word_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_eth_phy(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8126_PHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8126_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Ethernet PHY\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + seq_puts(m, "\n####################page 0##################\n "); + rtl8126_mdio_write(tp, 0x1f, 0x0000); + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8126_mdio_read(tp, n); + seq_printf(m, "%04x ", word_rd); + } + } + + seq_puts(m, "\n####################extra reg##################\n "); + n = 0xA400; + seq_printf(m, "\n0x%02x:\t", n); + for (i = 0; i < 8; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + } + + n = 0xA410; + seq_printf(m, "\n0x%02x:\t", n); + for (i = 0; i < 3; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + } + + n = 0xA434; + seq_printf(m, "\n0x%02x:\t", n); + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + + n = 0xA5D0; + seq_printf(m, "\n0x%02x:\t", n); + for (i = 0; i < 4; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + } + + n = 0xA61A; + seq_printf(m, "\n0x%02x:\t", n); + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + + n = 0xA6D0; + seq_printf(m, "\n0x%02x:\t", n); + for (i = 0; i < 3; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + seq_printf(m, "%04x ", word_rd); + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_extended_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8126_ERI_REGS_SIZE; + u32 dword_rd; + struct rtl8126_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Extended Registers\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + dword_rd = rtl8126_eri_read(tp, n, 4, ERIAR_ExGMAC); + seq_printf(m, "%08x ", dword_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_pci_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8126_PCI_REGS_SIZE; + u32 dword_rd; + struct rtl8126_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump PCI Registers\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%03x:\t", n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "%08x ", dword_rd); + } + } + + n = 0x110; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "\n0x%03x:\t%08x ", n, dword_rd); + n = 0x70c; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "\n0x%03x:\t%08x ", n, dword_rd); + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_temperature(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + u16 ts_digout, tj, fah; + + switch (tp->mcfg) { + default: + return -EOPNOTSUPP; + } + + rtnl_lock(); + + if (!rtl8126_sysfs_testmode_on(tp)) { + seq_puts(m, "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + rtnl_unlock(); + return 0; + } + + netif_testing_on(dev); + ts_digout = rtl8126_read_thermal_sensor(tp); + netif_testing_off(dev); + + rtnl_unlock(); + + tj = ts_digout / 2; + if (ts_digout <= 512) { + tj = ts_digout / 2; + seq_printf(m, "Cel:%d\n", tj); + fah = tj * (9/5) + 32; + seq_printf(m, "Fah:%d\n", fah); + } else { + tj = (512 - ((ts_digout / 2) - 512)) / 2; + seq_printf(m, "Cel:-%d\n", tj); + fah = tj * (9/5) + 32; + seq_printf(m, "Fah:-%d\n", fah); + } + + seq_putc(m, '\n'); + return 0; +} + +static int _proc_get_cable_info(struct seq_file *m, void *v, bool poe_mode) +{ + int i; + u16 status; + int cp_status[RTL8126_CP_NUM]; + int cp_len[RTL8126_CP_NUM] = {0}; + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + const char *pair_str[RTL8126_CP_NUM] = {"1-2", "3-6", "4-5", "7-8"}; + int ret; + + switch (tp->mcfg) { + default: + ret = -EOPNOTSUPP; + goto error_out; + } + + rtnl_lock(); + + if (!rtl8126_sysfs_testmode_on(tp)) { + seq_puts(m, "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + ret = 0; + goto error_unlock; + } + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + if (rtl8126_mdio_read(tp, MII_BMCR) & BMCR_PDOWN) { + ret = -EIO; + goto error_unlock; + } + + netif_testing_on(dev); + + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus) + seq_printf(m, "\nlink speed:%d", + rtl8126_convert_link_speed(status)); + else + seq_puts(m, "\nlink status:off"); + + rtl8126_get_cp_len(tp, cp_len); + + rtl8126_get_cp_status(tp, cp_status, poe_mode); + + seq_puts(m, "\npair\tlength\tstatus \tpp\n"); + + for (i=0; iprivate; + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + rtnl_lock(); + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + + if (!ring) + continue; + + seq_printf(m, "\ndump rx %d desc:%d\n", i, ring->num_rx_desc); + + _proc_dump_desc(m, (void*)ring->RxDescArray, ring->RxDescAllocSize); + } + +#ifdef ENABLE_LIB_SUPPORT + if (rtl8126_num_lib_rx_rings(tp) > 0) { + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8126_ring *lib_ring = &tp->lib_rx_ring[i]; + if (lib_ring->enabled) { + seq_printf(m, "\ndump lib rx %d desc:%d\n", i, + lib_ring->ring_size); + _proc_dump_desc(m, (void*)lib_ring->desc_addr, + lib_ring->desc_size); + } + } + } +#endif //ENABLE_LIB_SUPPORT + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_dump_tx_desc(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + rtnl_lock(); + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + + if (!ring) + continue; + + seq_printf(m, "\ndump tx %d desc:%d\n", i, ring->num_tx_desc); + + _proc_dump_desc(m, (void*)ring->TxDescArray, ring->TxDescAllocSize); + } + +#ifdef ENABLE_LIB_SUPPORT + if (rtl8126_num_lib_tx_rings(tp) > 0) { + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8126_ring *lib_ring = &tp->lib_tx_ring[i]; + if (lib_ring->enabled) { + seq_printf(m, "\ndump lib tx %d desc:%d\n", i, + lib_ring->ring_size); + _proc_dump_desc(m, (void*)lib_ring->desc_addr, + lib_ring->desc_size); + } + } + } +#endif //ENABLE_LIB_SUPPORT + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_dump_msix_tbl(struct seq_file *m, void *v) +{ + int i, j; + void __iomem *ioaddr; + struct net_device *dev = m->private; + struct rtl8126_private *tp = netdev_priv(dev); + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(tp->pci_dev, 4), pci_resource_len(tp->pci_dev, 4)); + if (!ioaddr) + return -EFAULT; + + rtnl_lock(); + + seq_printf(m, "\ndump MSI-X Table. Total Entry %d. \n", tp->hw_supp_irq_nvecs); + + for (i=0; ihw_supp_irq_nvecs; i++) { + seq_printf(m, "\n%04x ", i); + for (j=0; j<4; j++) + seq_printf(m, "%08x ", + readl(ioaddr + i*0x10 + 4*j)); + } + + rtnl_unlock(); + + iounmap(ioaddr); + + seq_putc(m, '\n'); + return 0; +} + +#else //LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + +static int proc_get_driver_variable(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8126_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Driver Driver\n"); + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "Variable\tValue\n----------\t-----\n"); + + len += snprintf(page + len, count - len, + "MODULENAME\t%s\n" + "driver version\t%s\n" + "mcfg\t%d\n" + "chipset\t%d\n" + "chipset_name\t%s\n" + "mtu\t%d\n" + "NUM_RX_DESC\t0x%x\n" + "cur_rx0\t0x%x\n" + "dirty_rx0\t0x%x\n" + "cur_rx1\t0x%x\n" + "dirty_rx1\t0x%x\n" + "cur_rx2\t0x%x\n" + "dirty_rx2\t0x%x\n" + "cur_rx3\t0x%x\n" + "dirty_rx3\t0x%x\n" + "NUM_TX_DESC\t0x%x\n" + "cur_tx0\t0x%x\n" + "dirty_tx0\t0x%x\n" + "cur_tx1\t0x%x\n" + "dirty_tx1\t0x%x\n" + "rx_buf_sz\t0x%x\n" +#ifdef ENABLE_PAGE_REUSE + "rx_buf_page_order\t0x%x\n" + "rx_buf_page_size\t0x%x\n" + "page_reuse_fail_cnt\t0x%x\n" +#endif //ENABLE_PAGE_REUSE + "esd_flag\t0x%x\n" + "pci_cfg_is_read\t0x%x\n" + "rtl8126_rx_config\t0x%x\n" + "cp_cmd\t0x%x\n" + "intr_mask\t0x%x\n" + "timer_intr_mask\t0x%x\n" + "wol_enabled\t0x%x\n" + "wol_opts\t0x%x\n" + "efuse_ver\t0x%x\n" + "eeprom_type\t0x%x\n" + "autoneg\t0x%x\n" + "duplex\t0x%x\n" + "speed\t%d\n" + "advertising\t0x%llx\n" + "eeprom_len\t0x%x\n" + "cur_page\t0x%x\n" + "features\t0x%x\n" + "org_pci_offset_99\t0x%x\n" + "org_pci_offset_180\t0x%x\n" + "issue_offset_99_event\t0x%x\n" + "org_pci_offset_80\t0x%x\n" + "org_pci_offset_81\t0x%x\n" + "use_timer_interrupt\t0x%x\n" + "HwIcVerUnknown\t0x%x\n" + "NotWrRamCodeToMicroP\t0x%x\n" + "NotWrMcuPatchCode\t0x%x\n" + "HwHasWrRamCodeToMicroP\t0x%x\n" + "sw_ram_code_ver\t0x%x\n" + "hw_ram_code_ver\t0x%x\n" + "rtk_enable_diag\t0x%x\n" + "ShortPacketSwChecksum\t0x%x\n" + "UseSwPaddingShortPkt\t0x%x\n" + "RequireAdcBiasPatch\t0x%x\n" + "AdcBiasPatchIoffset\t0x%x\n" + "RequireAdjustUpsTxLinkPulseTiming\t0x%x\n" + "SwrCnt1msIni\t0x%x\n" + "HwSuppNowIsOobVer\t0x%x\n" + "HwFiberModeVer\t0x%x\n" + "HwFiberStat\t0x%x\n" + "HwSwitchMdiToFiber\t0x%x\n" + "NicCustLedValue\t0x%x\n" + "RequiredSecLanDonglePatch\t0x%x\n" + "HwSuppDashVer\t0x%x\n" + "DASH\t0x%x\n" + "dash_printer_enabled\t0x%x\n" + "HwSuppKCPOffloadVer\t0x%x\n" + "speed_mode\t0x%x\n" + "duplex_mode\t0x%x\n" + "autoneg_mode\t0x%x\n" + "aspm\t0x%x\n" + "s5wol\t0x%x\n" + "s5_keep_curr_mac\t0x%x\n" + "eee_enable\t0x%x\n" + "hwoptimize\t0x%lx\n" + "proc_init_num\t0x%x\n" + "s0_magic_packet\t0x%x\n" + "disable_wol_support\t0x%x\n" + "enable_double_vlan\t0x%x\n" + "HwSuppMagicPktVer\t0x%x\n" + "HwSuppLinkChgWakeUpVer\t0x%x\n" + "HwSuppD0SpeedUpVer\t0x%x\n" + "D0SpeedUpSpeed\t0x%x\n" + "HwSuppCheckPhyDisableModeVer\t0x%x\n" + "HwPkgDet\t0x%x\n" + "HwSuppTxNoCloseVer\t0x%x\n" + "EnableTxNoClose\t0x%x\n" + "NextHwDesCloPtr0\t0x%x\n" + "BeginHwDesCloPtr0\t0x%x\n" + "hw_clo_ptr_reg0\t0x%x\n" + "sw_tail_ptr_reg0\t0x%x\n" + "NextHwDesCloPtr1\t0x%x\n" + "BeginHwDesCloPtr1\t0x%x\n" + "hw_clo_ptr_reg1\t0x%x\n" + "sw_tail_ptr_reg1\t0x%x\n" + "InitRxDescType\t0x%x\n" + "RxDescLength\t0x%x\n" + "num_rx_rings\t0x%x\n" + "num_tx_rings\t0x%x\n" + "tot_rx_rings\t0x%x\n" + "tot_tx_rings\t0x%x\n" + "HwSuppNumRxQueues\t0x%x\n" + "HwSuppNumTxQueues\t0x%x\n" + "EnableRss\t0x%x\n" + "EnablePtp\t0x%x\n" + "ptp_master_mode\t0x%x\n" + "min_irq_nvecs\t0x%x\n" + "irq_nvecs\t0x%x\n" + "hw_supp_irq_nvecs\t0x%x\n" + "ring_lib_enabled\t0x%x\n" + "HwSuppIsrVer\t0x%x\n" + "HwCurrIsrVer\t0x%x\n" +#ifdef ENABLE_PTP_SUPPORT + "tx_hwtstamp_timeouts\t0x%x\n" + "tx_hwtstamp_skipped\t0x%x\n" +#endif + "random_mac\t0x%x\n" + "org_mac_addr\t%pM\n" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + "perm_addr\t%pM\n" +#endif + "dev_addr\t%pM\n", + MODULENAME, + RTL8126_VERSION, + tp->mcfg, + tp->chipset, + rtl_chip_info[tp->chipset].name, + dev->mtu, + tp->rx_ring[0].num_rx_desc, + tp->rx_ring[0].cur_rx, + tp->rx_ring[0].dirty_rx, + tp->rx_ring[1].cur_rx, + tp->rx_ring[1].dirty_rx, + tp->rx_ring[2].cur_rx, + tp->rx_ring[2].dirty_rx, + tp->rx_ring[3].cur_rx, + tp->rx_ring[3].dirty_rx, + tp->tx_ring[0].num_tx_desc, + tp->tx_ring[0].cur_tx, + tp->tx_ring[0].dirty_tx, + tp->tx_ring[1].cur_tx, + tp->tx_ring[1].dirty_tx, + tp->rx_buf_sz, +#ifdef ENABLE_PAGE_REUSE + tp->rx_buf_page_order, + tp->rx_buf_page_size, + tp->page_reuse_fail_cnt, +#endif //ENABLE_PAGE_REUSE + tp->esd_flag, + tp->pci_cfg_is_read, + tp->rtl8126_rx_config, + tp->cp_cmd, + tp->intr_mask, + tp->timer_intr_mask, + tp->wol_enabled, + tp->wol_opts, + tp->efuse_ver, + tp->eeprom_type, + tp->autoneg, + tp->duplex, + tp->speed, + tp->advertising, + tp->eeprom_len, + tp->cur_page, + tp->features, + tp->org_pci_offset_99, + tp->org_pci_offset_180, + tp->issue_offset_99_event, + tp->org_pci_offset_80, + tp->org_pci_offset_81, + tp->use_timer_interrupt, + tp->HwIcVerUnknown, + tp->NotWrRamCodeToMicroP, + tp->NotWrMcuPatchCode, + tp->HwHasWrRamCodeToMicroP, + tp->sw_ram_code_ver, + tp->hw_ram_code_ver, + tp->rtk_enable_diag, + tp->ShortPacketSwChecksum, + tp->UseSwPaddingShortPkt, + tp->RequireAdcBiasPatch, + tp->AdcBiasPatchIoffset, + tp->RequireAdjustUpsTxLinkPulseTiming, + tp->SwrCnt1msIni, + tp->HwSuppNowIsOobVer, + tp->HwFiberModeVer, + tp->HwFiberStat, + tp->HwSwitchMdiToFiber, + tp->NicCustLedValue, + tp->RequiredSecLanDonglePatch, + tp->HwSuppDashVer, + tp->DASH, + tp->dash_printer_enabled, + tp->HwSuppKCPOffloadVer, + speed_mode, + duplex_mode, + autoneg_mode, + aspm, + s5wol, + s5_keep_curr_mac, + tp->eee.eee_enabled, + hwoptimize, + proc_init_num, + s0_magic_packet, + disable_wol_support, + enable_double_vlan, + tp->HwSuppMagicPktVer, + tp->HwSuppLinkChgWakeUpVer, + tp->HwSuppD0SpeedUpVer, + tp->D0SpeedUpSpeed, + tp->HwSuppCheckPhyDisableModeVer, + tp->HwPkgDet, + tp->HwSuppTxNoCloseVer, + tp->EnableTxNoClose, + tp->tx_ring[0].NextHwDesCloPtr, + tp->tx_ring[0].BeginHwDesCloPtr, + rtl8126_get_hw_clo_ptr(&tp->tx_ring[0]), + rtl8126_get_sw_tail_ptr(&tp->tx_ring[0]), + tp->tx_ring[1].NextHwDesCloPtr, + tp->tx_ring[1].BeginHwDesCloPtr, + rtl8126_get_hw_clo_ptr(&tp->tx_ring[1]), + rtl8126_get_sw_tail_ptr(&tp->tx_ring[1]), + tp->InitRxDescType, + tp->RxDescLength, + tp->num_rx_rings, + tp->num_tx_rings, + rtl8126_tot_rx_rings(tp), + rtl8126_tot_tx_rings(tp), + tp->HwSuppNumRxQueues, + tp->HwSuppNumTxQueues, + tp->EnableRss, + tp->EnablePtp, + tp->ptp_master_mode, + tp->min_irq_nvecs, + tp->irq_nvecs, + tp->hw_supp_irq_nvecs, + tp->ring_lib_enabled, + tp->HwSuppIsrVer, + tp->HwCurrIsrVer, +#ifdef ENABLE_PTP_SUPPORT + tp->tx_hwtstamp_timeouts, + tp->tx_hwtstamp_skipped, +#endif + tp->random_mac, + tp->org_mac_addr, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + dev->perm_addr, +#endif + dev->dev_addr + ); + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_tally_counter(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8126_private *tp = netdev_priv(dev); + struct rtl8126_counters *counters; + dma_addr_t paddr; + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Tally Counter\n"); + + rtnl_lock(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) { + len += snprintf(page + len, count - len, + "\nDump Tally Counter Fail\n"); + goto out_unlock; + } + + rtl8126_dump_tally_counter(tp, paddr); + + len += snprintf(page + len, count - len, + "Statistics\tValue\n----------\t-----\n"); + + len += snprintf(page + len, count - len, + "tx_packets\t%lld\n" + "rx_packets\t%lld\n" + "tx_errors\t%lld\n" + "rx_errors\t%d\n" + "rx_missed\t%d\n" + "align_errors\t%d\n" + "tx_one_collision\t%d\n" + "tx_multi_collision\t%d\n" + "rx_unicast\t%lld\n" + "rx_broadcast\t%lld\n" + "rx_multicast\t%d\n" + "tx_aborted\t%d\n" + "tx_underrun\t%d\n", + + "tx_octets\t%lld\n", + "rx_octets\t%lld\n", + "rx_multicast64\t%lld\n", + "tx_unicast64\t%lld\n", + "tx_broadcast64\t%lld\n", + "tx_multicast64\t%lld\n", + "tx_pause_on\t%d\n", + "tx_pause_off\t%d\n", + "tx_pause_all\t%d\n", + "tx_deferred\t%d\n", + "tx_late_collision\t%d\n", + "tx_all_collision\t%d\n", + "tx_aborted32\t%d\n", + "align_errors32\t%d\n", + "rx_frame_too_long\t%d\n", + "rx_runt\t%d\n", + "rx_pause_on\t%d\n", + "rx_pause_off\t%d\n", + "rx_pause_all\t%d\n", + "rx_unknown_opcode\t%d\n", + "rx_mac_error\t%d\n", + "tx_underrun32\t%d\n", + "rx_mac_missed\t%d\n", + "rx_tcam_dropped\t%d\n", + "tdu\t%d\n", + "rdu\t%d\n", + le64_to_cpu(counters->tx_packets), + le64_to_cpu(counters->rx_packets), + le64_to_cpu(counters->tx_errors), + le32_to_cpu(counters->rx_errors), + le16_to_cpu(counters->rx_missed), + le16_to_cpu(counters->align_errors), + le32_to_cpu(counters->tx_one_collision), + le32_to_cpu(counters->tx_multi_collision), + le64_to_cpu(counters->rx_unicast), + le64_to_cpu(counters->rx_broadcast), + le32_to_cpu(counters->rx_multicast), + le16_to_cpu(counters->tx_aborted), + le16_to_cpu(counters->tx_underrun), + + le64_to_cpu(counters->tx_octets), + le64_to_cpu(counters->rx_octets), + le64_to_cpu(counters->rx_multicast64), + le64_to_cpu(counters->tx_unicast64), + le64_to_cpu(counters->tx_broadcast64), + le64_to_cpu(counters->tx_multicast64), + le32_to_cpu(counters->tx_pause_on), + le32_to_cpu(counters->tx_pause_off), + le32_to_cpu(counters->tx_pause_all), + le32_to_cpu(counters->tx_deferred), + le32_to_cpu(counters->tx_late_collision), + le32_to_cpu(counters->tx_all_collision), + le32_to_cpu(counters->tx_aborted32), + le32_to_cpu(counters->align_errors32), + le32_to_cpu(counters->rx_frame_too_long), + le32_to_cpu(counters->rx_runt), + le32_to_cpu(counters->rx_pause_on), + le32_to_cpu(counters->rx_pause_off), + le32_to_cpu(counters->rx_pause_all), + le32_to_cpu(counters->rx_unknown_opcode), + le32_to_cpu(counters->rx_mac_error), + le32_to_cpu(counters->tx_underrun32), + le32_to_cpu(counters->rx_mac_missed), + le32_to_cpu(counters->rx_tcam_dropped), + le32_to_cpu(counters->tdu), + le32_to_cpu(counters->rdu), + ); + + len += snprintf(page + len, count - len, "\n"); +out_unlock: + rtnl_unlock(); + + *eof = 1; + return len; +} + +static int proc_get_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8126_MAC_REGS_SIZE; + u8 byte_rd; + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump MAC Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%04x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + max = 0xB00; + for (n = 0xA00; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%04x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + max = 0xD40; + for (n = 0xD00; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%04x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + max = 0x2840; + for (n = 0x2800; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%04x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_all_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max; + u8 byte_rd; + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump All MAC Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + max = pci_resource_len(pdev, 2); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%04x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\nTotal length:0x%X", max); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_pcie_phy(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8126_EPHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8126_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump PCIE PHY\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8126_ephy_read(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_eth_phy(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8126_PHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8126_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Ethernet PHY\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "\n####################page 0##################\n"); + rtl8126_mdio_write(tp, 0x1f, 0x0000); + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8126_mdio_read(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + } + + len += snprintf(page + len, count - len, + "\n####################extra reg##################\n"); + n = 0xA400; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + for (i = 0; i < 8; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + + n = 0xA410; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + for (i = 0; i < 3; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + + n = 0xA434; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + + n = 0xA5D0; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + for (i = 0; i < 4; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + + n = 0xA61A; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + + n = 0xA6D0; + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + for (i = 0; i < 3; i++, n+=2) { + word_rd = rtl8126_mdio_direct_read_phy_ocp(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_extended_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8126_ERI_REGS_SIZE; + u32 dword_rd; + struct rtl8126_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Extended Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + dword_rd = rtl8126_eri_read(tp, n, 4, ERIAR_ExGMAC); + len += snprintf(page + len, count - len, + "%08x ", + dword_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_pci_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8126_PCI_REGS_SIZE; + u32 dword_rd; + struct rtl8126_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump PCI Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%03x:\t", + n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "%08x ", + dword_rd); + } + } + + n = 0x110; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "\n0x%03x:\t%08x ", + n, + dword_rd); + n = 0x70c; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "\n0x%03x:\t%08x ", + n, + dword_rd); + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_temperature(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8126_private *tp = netdev_priv(dev); + u16 ts_digout, tj, fah; + int len = 0; + + switch (tp->mcfg) { + default: + return -EOPNOTSUPP; + } + + rtnl_lock(); + + if (!rtl8126_sysfs_testmode_on(tp)) { + len += snprintf(page + len, count - len, + "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + goto out_unlock; + } + + ts_digout = rtl8126_read_thermal_sensor(tp); + + tj = ts_digout / 2; + if (ts_digout <= 512) { + tj = ts_digout / 2; + len += snprintf(page + len, count - len, + "Cel:%d\n", + tj); + fah = tj * (9/5) + 32; + len += snprintf(page + len, count - len, + "Fah:%d\n", + fah); + + } else { + tj = (512 - ((ts_digout / 2) - 512)) / 2; + len += snprintf(page + len, count - len, + "Cel:-%d\n", + tj); + fah = tj * (9/5) + 32; + len += snprintf(page + len, count - len, + "Fah:-%d\n", + fah); + } + + len += snprintf(page + len, count - len, "\n"); + +out_unlock: + rtnl_unlock(); + + *eof = 1; + return len; +} + +static int proc_get_cable_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data, + bool poe_mode) +{ + int i; + u16 status; + int len = 0; + struct net_device *dev = data; + int cp_status[RTL8126_CP_NUM] = {0}; + int cp_len[RTL8126_CP_NUM] = {0}; + struct rtl8126_private *tp = netdev_priv(dev); + const char *pair_str[RTL8126_CP_NUM] = {"1-2", "3-6", "4-5", "7-8"}; + + switch (tp->mcfg) { + default: + return -EOPNOTSUPP; + } + + rtnl_lock(); + + if (!rtl8126_sysfs_testmode_on(tp)) { + len += snprintf(page + len, count - len, + "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + goto out_unlock; + } + + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus) + len += snprintf(page + len, count - len, + "\nlink speed:%d", + rtl8126_convert_link_speed(status)); + else + len += snprintf(page + len, count - len, + "\nlink status:off"); + + rtl8126_get_cp_len(tp, cp_len); + + rtl8126_get_cp_status(tp, cp_status, poe_mode); + + len += snprintf(page + len, count - len, + "\npair\tlength\tstatus \tpp\n"); + + for (i=0; inum_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + + if (!ring) + continue; + + len += snprintf(page + len, count - len, + "\ndump rx &d desc:%d", + i, ring->num_rx_desc); + + _proc_dump_desc(page, &len, &count, + ring->RxDescArray, + ring->RxDescAllocSize); + } + +#ifdef ENABLE_LIB_SUPPORT + if (rtl8126_num_lib_rx_rings(tp) > 0) { + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8126_ring *lib_ring = &tp->lib_rx_ring[i]; + if (lib_ring->enabled) { + len += snprintf(page + len, count - len, + "\ndump lib rx %d desc:%d", + i, + ring->ring_size); + _proc_dump_desc(page, &len, &count, + (void*)lib_ring->desc_addr, + lib_ring->desc_size); + } + } + } +#endif //ENABLE_LIB_SUPPORT + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + + return len; +} + +static int proc_dump_tx_desc(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + int len = 0; + struct net_device *dev = data; + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + rtnl_lock(); + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + + if (!ring) + continue; + + len += snprintf(page + len, count - len, + "\ndump tx desc:%d", + ring->num_tx_desc); + + _proc_dump_desc(page, &len, &count, + ring->TxDescArray, + ring->TxDescAllocSize); + } + +#ifdef ENABLE_LIB_SUPPORT + if (rtl8126_num_lib_tx_rings(tp) > 0) { + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8126_ring *lib_ring = &tp->lib_tx_ring[i]; + if (lib_ring->enabled) { + len += snprintf(page + len, count - len, + "\ndump lib tx %d desc:%d", + i, + ring->ring_size); + _proc_dump_desc(page, &len, &count, + (void*)lib_ring->desc_addr, + lib_ring->desc_size); + } + } + } +#endif //ENABLE_LIB_SUPPORT + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + + return len; +} + +static int proc_dump_msix_tbl(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + int i, j; + int len = 0; + void __iomem *ioaddr; + struct net_device *dev = data; + struct rtl8126_private *tp = netdev_priv(dev); + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(tp->pci_dev, 4), pci_resource_len(tp->pci_dev, 4)); + if (!ioaddr) + return -EFAULT; + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "\ndump MSI-X Table. Total Entry %d. \n", + tp->hw_supp_irq_nvecs); + + for (i=0; ihw_supp_irq_nvecs; i++) { + len += snprintf(page + len, count - len, + "\n%04x ", i); + for (j=0; j<4; j++) + len += snprintf(page + len, count - len, "%08x ", + readl(ioaddr + i*0x10 + 4*j)); + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return 0; +} + +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + +static void rtl8126_proc_module_init(void) +{ + //create /proc/net/r8126 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + rtl8126_proc = proc_mkdir(MODULENAME, init_net.proc_net); +#else + rtl8126_proc = proc_mkdir(MODULENAME, proc_net); +#endif + if (!rtl8126_proc) + dprintk("cannot create %s proc entry \n", MODULENAME); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +/* + * seq_file wrappers for procfile show routines. + */ +static int rtl8126_proc_open(struct inode *inode, struct file *file) +{ + struct net_device *dev = proc_get_parent_data(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + int (*show)(struct seq_file *, void *) = pde_data(inode); +#else + int (*show)(struct seq_file *, void *) = PDE_DATA(inode); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + + return single_open(file, show, dev); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static const struct proc_ops rtl8126_proc_fops = { + .proc_open = rtl8126_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; +#else +static const struct file_operations rtl8126_proc_fops = { + .open = rtl8126_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +#endif + +/* + * Table of proc files we need to create. + */ +struct rtl8126_proc_file { + char name[16]; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + int (*show)(struct seq_file *, void *); +#else + int (*show)(char *, char **, off_t, int, int *, void *); +#endif +}; + +static const struct rtl8126_proc_file rtl8126_debug_proc_files[] = { + { "driver_var", &proc_get_driver_variable }, + { "tally", &proc_get_tally_counter }, + { "registers", &proc_get_registers }, + { "registers2", &proc_get_all_registers }, + { "pcie_phy", &proc_get_pcie_phy }, + { "eth_phy", &proc_get_eth_phy }, + { "ext_regs", &proc_get_extended_registers }, + { "pci_regs", &proc_get_pci_registers }, + { "tx_desc", &proc_dump_tx_desc }, + { "rx_desc", &proc_dump_rx_desc }, + { "msix_tbl", &proc_dump_msix_tbl }, + { "", NULL } +}; + +static const struct rtl8126_proc_file rtl8126_test_proc_files[] = { + { "temp", &proc_get_temperature }, + { "cdt", &proc_get_cable_info }, + { "cdt_poe", &proc_get_poe_cable_info }, + { "", NULL } +}; + +#define R8126_PROC_DEBUG_DIR "debug" +#define R8126_PROC_TEST_DIR "test" + +static void rtl8126_proc_init(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + const struct rtl8126_proc_file *f; + struct proc_dir_entry *dir; + + if (!rtl8126_proc) + return; + + if (tp->proc_dir_debug || tp->proc_dir_test) + return; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + dir = proc_mkdir_data(dev->name, 0, rtl8126_proc, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; + } + tp->proc_dir = dir; + proc_init_num++; + + /* create debug entry */ + dir = proc_mkdir_data(R8126_PROC_DEBUG_DIR, 0, tp->proc_dir, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_DEBUG_DIR); + return; + } + + tp->proc_dir_debug = dir; + for (f = rtl8126_debug_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8126_proc_fops, f->show)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_DEBUG_DIR, + f->name); + return; + } + } + + /* create test entry */ + dir = proc_mkdir_data(R8126_PROC_TEST_DIR, 0, tp->proc_dir, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_TEST_DIR); + return; + } + + tp->proc_dir_test = dir; + for (f = rtl8126_test_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8126_proc_fops, f->show)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_TEST_DIR, + f->name); + return; + } + } +#else + dir = proc_mkdir(dev->name, rtl8126_proc); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; + } + + tp->proc_dir = dir; + proc_init_num++; + + /* create debug entry */ + dir = proc_mkdir(R8126_PROC_DEBUG_DIR, tp->proc_dir); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_DEBUG_DIR); + return; + } + + tp->proc_dir_debug = dir; + for (f = rtl8126_debug_proc_files; f->name[0]; f++) { + if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, + dir, f->show, dev)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_DEBUG_DIR, + f->name); + return; + } + } + + /* create test entry */ + dir = proc_mkdir(R8126_PROC_TEST_DIR, tp->proc_dir); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_TEST_DIR); + return; + } + + tp->proc_dir_test = dir; + for (f = rtl8126_test_proc_files; f->name[0]; f++) { + if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, + dir, f->show, dev)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8126_PROC_TEST_DIR, + f->name); + return; + } + } +#endif +} + +static void rtl8126_proc_remove(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->proc_dir) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + remove_proc_subtree(dev->name, rtl8126_proc); +#else + const struct rtl8126_proc_file *f; + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->proc_dir_debug) { + for (f = rtl8126_debug_proc_files; f->name[0]; f++) + remove_proc_entry(f->name, tp->proc_dir_debug); + remove_proc_entry(R8126_PROC_DEBUG_DIR, tp->proc_dir); + } + + if (tp->proc_dir_test) { + for (f = rtl8126_test_proc_files; f->name[0]; f++) + remove_proc_entry(f->name, tp->proc_dir_test); + remove_proc_entry(R8126_PROC_TEST_DIR, tp->proc_dir); + } + + remove_proc_entry(dev->name, rtl8126_proc); +#endif + proc_init_num--; + + tp->proc_dir_debug = NULL; + tp->proc_dir_test = NULL; + tp->proc_dir = NULL; + } +} + +#endif //ENABLE_R8126_PROCFS + +#ifdef ENABLE_R8126_SYSFS +/**************************************************************************** +* -----------------------------SYSFS STUFF------------------------- +***************************************************************************** +*/ +static ssize_t testmode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct net_device *netdev = to_net_dev(dev); + struct rtl8126_private *tp = netdev_priv(netdev); + + sprintf(buf, "%u\n", tp->testmode); + + return strlen(buf); +} + +static ssize_t testmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *netdev = to_net_dev(dev); + struct rtl8126_private *tp = netdev_priv(netdev); + u32 testmode; + + if (sscanf(buf, "%u\n", &testmode) != 1) + return -EINVAL; + + if (tp->testmode != testmode) { + rtnl_lock(); + tp->testmode = testmode; + rtnl_unlock(); + } + + return count; +} + +static DEVICE_ATTR_RW(testmode); + +static struct attribute *rtk_adv_attrs[] = { + &dev_attr_testmode.attr, + NULL +}; + +static struct attribute_group rtk_adv_grp = { + .name = "rtl_adv", + .attrs = rtk_adv_attrs, +}; + +static void rtl8126_sysfs_init(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret; + + /* init rtl_adv */ +#ifdef ENABLE_LIB_SUPPORT + tp->testmode = 0; +#else + tp->testmode = 1; +#endif //ENABLE_LIB_SUPPORT + + ret = sysfs_create_group(&dev->dev.kobj, &rtk_adv_grp); + if (ret < 0) + netif_warn(tp, probe, dev, "create rtk_adv_grp fail\n"); + else + set_bit(R8126_SYSFS_RTL_ADV, tp->sysfs_flag); +} + +static void rtl8126_sysfs_remove(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (test_and_clear_bit(R8126_SYSFS_RTL_ADV, tp->sysfs_flag)) + sysfs_remove_group(&dev->dev.kobj, &rtk_adv_grp); +} +#endif //ENABLE_R8126_SYSFS + +static inline u16 map_phy_ocp_addr(u16 PageNum, u8 RegNum) +{ + u16 OcpPageNum = 0; + u8 OcpRegNum = 0; + u16 OcpPhyAddress = 0; + + if (PageNum == 0) { + OcpPageNum = OCP_STD_PHY_BASE_PAGE + (RegNum / 8); + OcpRegNum = 0x10 + (RegNum % 8); + } else { + OcpPageNum = PageNum; + OcpRegNum = RegNum; + } + + OcpPageNum <<= 4; + + if (OcpRegNum < 16) { + OcpPhyAddress = 0; + } else { + OcpRegNum -= 16; + OcpRegNum <<= 1; + + OcpPhyAddress = OcpPageNum + OcpRegNum; + } + + + return OcpPhyAddress; +} + +static void mdio_real_direct_write_phy_ocp(struct rtl8126_private *tp, + u16 RegAddr, + u16 value) +{ + u32 data32; + int i; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(RegAddr % 2); +#endif + data32 = RegAddr/2; + data32 <<= OCPR_Addr_Reg_shift; + data32 |= OCPR_Write | value; + + RTL_W32(tp, PHYOCP, data32); + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + if (!(RTL_R32(tp, PHYOCP) & OCPR_Flag)) + break; + } +} + +static void rtl8126_mdio_direct_write_phy_ocp(struct rtl8126_private *tp, + u16 RegAddr, + u16 value) +{ + if (tp->rtk_enable_diag) + return; + + mdio_real_direct_write_phy_ocp(tp, RegAddr, value); +} + +/* +static void rtl8126_mdio_write_phy_ocp(struct rtl8126_private *tp, + u16 PageNum, + u32 RegAddr, + u32 value) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + rtl8126_mdio_direct_write_phy_ocp(tp, ocp_addr, value); +} +*/ + +static void rtl8126_mdio_real_write_phy_ocp(struct rtl8126_private *tp, + u16 PageNum, + u32 RegAddr, + u32 value) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + mdio_real_direct_write_phy_ocp(tp, ocp_addr, value); +} + +static void mdio_real_write(struct rtl8126_private *tp, + u16 RegAddr, + u16 value) +{ + if (RegAddr == 0x1F) { + tp->cur_page = value; + return; + } + rtl8126_mdio_real_write_phy_ocp(tp, tp->cur_page, RegAddr, value); +} + +void rtl8126_mdio_write(struct rtl8126_private *tp, + u16 RegAddr, + u16 value) +{ + if (tp->rtk_enable_diag) + return; + + mdio_real_write(tp, RegAddr, value); +} + +void rtl8126_mdio_prot_write(struct rtl8126_private *tp, + u32 RegAddr, + u32 value) +{ + mdio_real_write(tp, RegAddr, value); +} + +void rtl8126_mdio_prot_direct_write_phy_ocp(struct rtl8126_private *tp, + u32 RegAddr, + u32 value) +{ + mdio_real_direct_write_phy_ocp(tp, RegAddr, value); +} + +static u32 mdio_real_direct_read_phy_ocp(struct rtl8126_private *tp, + u16 RegAddr) +{ + u32 data32; + int i, value = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(RegAddr % 2); +#endif + data32 = RegAddr/2; + data32 <<= OCPR_Addr_Reg_shift; + + RTL_W32(tp, PHYOCP, data32); + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + if (RTL_R32(tp, PHYOCP) & OCPR_Flag) + break; + } + value = RTL_R32(tp, PHYOCP) & OCPDR_Data_Mask; + + return value; +} + +static u32 rtl8126_mdio_direct_read_phy_ocp(struct rtl8126_private *tp, + u16 RegAddr) +{ + if (tp->rtk_enable_diag) + return 0xffffffff; + + return mdio_real_direct_read_phy_ocp(tp, RegAddr); +} + +/* +static u32 rtl8126_mdio_read_phy_ocp(struct rtl8126_private *tp, + u16 PageNum, + u32 RegAddr) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + return rtl8126_mdio_direct_read_phy_ocp(tp, ocp_addr); +} +*/ + +static u32 rtl8126_mdio_real_read_phy_ocp(struct rtl8126_private *tp, + u16 PageNum, + u32 RegAddr) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + return mdio_real_direct_read_phy_ocp(tp, ocp_addr); +} + +static u32 mdio_real_read(struct rtl8126_private *tp, + u16 RegAddr) +{ + return rtl8126_mdio_real_read_phy_ocp(tp, tp->cur_page, RegAddr); +} + +u32 rtl8126_mdio_read(struct rtl8126_private *tp, + u16 RegAddr) +{ + if (tp->rtk_enable_diag) + return 0xffffffff; + + return mdio_real_read(tp, RegAddr); +} + +u32 rtl8126_mdio_prot_read(struct rtl8126_private *tp, + u32 RegAddr) +{ + return mdio_real_read(tp, RegAddr); +} + +u32 rtl8126_mdio_prot_direct_read_phy_ocp(struct rtl8126_private *tp, + u32 RegAddr) +{ + return mdio_real_direct_read_phy_ocp(tp, RegAddr); +} + +static void rtl8126_clear_and_set_eth_phy_bit(struct rtl8126_private *tp, u8 addr, u16 clearmask, u16 setmask) +{ + u16 PhyRegValue; + + PhyRegValue = rtl8126_mdio_read(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + rtl8126_mdio_write(tp, addr, PhyRegValue); +} + +void rtl8126_clear_eth_phy_bit(struct rtl8126_private *tp, u8 addr, u16 mask) +{ + rtl8126_clear_and_set_eth_phy_bit(tp, + addr, + mask, + 0); +} + +void rtl8126_set_eth_phy_bit(struct rtl8126_private *tp, u8 addr, u16 mask) +{ + rtl8126_clear_and_set_eth_phy_bit(tp, + addr, + 0, + mask); +} + +static void rtl8126_clear_and_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 clearmask, u16 setmask) +{ + u16 PhyRegValue; + + PhyRegValue = rtl8126_mdio_direct_read_phy_ocp(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + rtl8126_mdio_direct_write_phy_ocp(tp, addr, PhyRegValue); +} + +static void rtl8126_clear_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask) +{ + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + addr, + mask, + 0); +} + +static void rtl8126_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask) +{ + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + addr, + 0, + mask); +} + +void rtl8126_mac_ocp_write(struct rtl8126_private *tp, u16 reg_addr, u16 value) +{ + u32 data32; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(reg_addr % 2); +#endif + + data32 = reg_addr/2; + data32 <<= OCPR_Addr_Reg_shift; + data32 += value; + data32 |= OCPR_Write; + + RTL_W32(tp, MACOCP, data32); +} + +u16 rtl8126_mac_ocp_read(struct rtl8126_private *tp, u16 reg_addr) +{ + u32 data32; + u16 data16 = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(reg_addr % 2); +#endif + + data32 = reg_addr/2; + data32 <<= OCPR_Addr_Reg_shift; + + RTL_W32(tp, MACOCP, data32); + data16 = (u16)RTL_R32(tp, MACOCP); + + return data16; +} + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void mac_mcu_write(struct rtl8126_private *tp, u16 reg, u16 value) +{ + if (reg == 0x1f) { + tp->ocp_base = value << 4; + return; + } + + rtl8126_mac_ocp_write(tp, tp->ocp_base + reg, value); +} + +static u32 mac_mcu_read(struct rtl8126_private *tp, u16 reg) +{ + return rtl8126_mac_ocp_read(tp, tp->ocp_base + reg); +} +#endif + +static void +rtl8126_clear_set_mac_ocp_bit( + struct rtl8126_private *tp, + u16 addr, + u16 clearmask, + u16 setmask +) +{ + u16 PhyRegValue; + + PhyRegValue = rtl8126_mac_ocp_read(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + rtl8126_mac_ocp_write(tp, addr, PhyRegValue); +} + +static void +rtl8126_clear_mac_ocp_bit( + struct rtl8126_private *tp, + u16 addr, + u16 mask +) +{ + rtl8126_clear_set_mac_ocp_bit(tp, + addr, + mask, + 0); +} + +static void +rtl8126_set_mac_ocp_bit( + struct rtl8126_private *tp, + u16 addr, + u16 mask +) +{ + rtl8126_clear_set_mac_ocp_bit(tp, + addr, + 0, + mask); +} + +u32 rtl8126_ocp_read_with_oob_base_address(struct rtl8126_private *tp, u16 addr, u8 len, const u32 base_address) +{ + return rtl8126_eri_read_with_oob_base_address(tp, addr, len, ERIAR_OOB, base_address); +} + +u32 rtl8126_ocp_read(struct rtl8126_private *tp, u16 addr, u8 len) +{ + u32 value = 0; + + if (!tp->AllowAccessDashOcp) + return 0xffffffff; + + if (HW_DASH_SUPPORT_TYPE_2(tp)) + value = rtl8126_ocp_read_with_oob_base_address(tp, addr, len, NO_BASE_ADDRESS); + else if (HW_DASH_SUPPORT_TYPE_3(tp)) + value = rtl8126_ocp_read_with_oob_base_address(tp, addr, len, RTL8168FP_OOBMAC_BASE); + + return value; +} + +u32 rtl8126_ocp_write_with_oob_base_address(struct rtl8126_private *tp, u16 addr, u8 len, u32 value, const u32 base_address) +{ + return rtl8126_eri_write_with_oob_base_address(tp, addr, len, value, ERIAR_OOB, base_address); +} + +void rtl8126_ocp_write(struct rtl8126_private *tp, u16 addr, u8 len, u32 value) +{ + if (!tp->AllowAccessDashOcp) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp)) + rtl8126_ocp_write_with_oob_base_address(tp, addr, len, value, NO_BASE_ADDRESS); + else if (HW_DASH_SUPPORT_TYPE_3(tp)) + rtl8126_ocp_write_with_oob_base_address(tp, addr, len, value, RTL8168FP_OOBMAC_BASE); +} + +void rtl8126_oob_mutex_lock(struct rtl8126_private *tp) +{ + u8 reg_16, reg_a0; + u32 wait_cnt_0, wait_Cnt_1; + u16 ocp_reg_mutex_ib; + u16 ocp_reg_mutex_oob; + u16 ocp_reg_mutex_prio; + + if (!tp->DASH) + return; + + switch (tp->mcfg) { + default: + return; + } + + rtl8126_ocp_write(tp, ocp_reg_mutex_ib, 1, BIT_0); + reg_16 = rtl8126_ocp_read(tp, ocp_reg_mutex_oob, 1); + wait_cnt_0 = 0; + while(reg_16) { + reg_a0 = rtl8126_ocp_read(tp, ocp_reg_mutex_prio, 1); + if (reg_a0) { + rtl8126_ocp_write(tp, ocp_reg_mutex_ib, 1, 0x00); + reg_a0 = rtl8126_ocp_read(tp, ocp_reg_mutex_prio, 1); + wait_Cnt_1 = 0; + while(reg_a0) { + reg_a0 = rtl8126_ocp_read(tp, ocp_reg_mutex_prio, 1); + + wait_Cnt_1++; + + if (wait_Cnt_1 > 2000) + break; + }; + rtl8126_ocp_write(tp, ocp_reg_mutex_ib, 1, BIT_0); + + } + reg_16 = rtl8126_ocp_read(tp, ocp_reg_mutex_oob, 1); + + wait_cnt_0++; + + if (wait_cnt_0 > 2000) + break; + }; +} + +void rtl8126_oob_mutex_unlock(struct rtl8126_private *tp) +{ + //u16 ocp_reg_mutex_ib; + //u16 ocp_reg_mutex_oob; + //u16 ocp_reg_mutex_prio; + + if (!tp->DASH) + return; + + switch (tp->mcfg) { + default: + return; + } + + //rtl8126_ocp_write(tp, ocp_reg_mutex_prio, 1, BIT_0); + //rtl8126_ocp_write(tp, ocp_reg_mutex_ib, 1, 0x00); +} + +static bool +rtl8126_is_allow_access_dash_ocp(struct rtl8126_private *tp) +{ + bool allow_access = false; + + if (!HW_DASH_SUPPORT_DASH(tp)) + goto exit; + + allow_access = true; + switch (tp->mcfg) { + default: + goto exit; + } +exit: + return allow_access; +} + +static int rtl8126_check_dash(struct rtl8126_private *tp) +{ + if (!tp->AllowAccessDashOcp) + return 0; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + if (rtl8126_ocp_read(tp, 0x128, 1) & BIT_0) + return 1; + } + + return 0; +} + +void rtl8126_dash2_disable_tx(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + u16 WaitCnt; + u8 TmpUchar; + + //Disable oob Tx + RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) & ~(BIT_0)); + WaitCnt = 0; + + //wait oob tx disable + do { + TmpUchar = RTL_CMAC_R8(tp, CMAC_IBISR0); + + if (TmpUchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE) { + break; + } + + udelay(50); + WaitCnt++; + } while(WaitCnt < 2000); + + //Clear ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE + RTL_CMAC_W8(tp, CMAC_IBISR0, RTL_CMAC_R8(tp, CMAC_IBISR0) | ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE); + } +} + +void rtl8126_dash2_enable_tx(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) | BIT_0); + } +} + +void rtl8126_dash2_disable_rx(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) & ~(BIT_0)); + } +} + +void rtl8126_dash2_enable_rx(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) | BIT_0); + } +} + +static void rtl8126_dash2_disable_txrx(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + rtl8126_dash2_disable_tx(tp); + rtl8126_dash2_disable_rx(tp); + } +} + +static int rtl8126_wait_dash_fw_ready(struct rtl8126_private *tp) +{ + int rc = -1; + int timeout; + + if (HW_DASH_SUPPORT_TYPE_2(tp) == FALSE && + HW_DASH_SUPPORT_TYPE_3(tp) == FALSE) + goto out; + + if (!tp->DASH) + goto out; + + for (timeout = 0; timeout < 10; timeout++) { + mdelay(10); + if (rtl8126_ocp_read(tp, 0x124, 1) & BIT_0) { + rc = 1; + goto out; + } + } + + rc = 0; + +out: + return rc; +} + +static void rtl8126_driver_start(struct rtl8126_private *tp) +{ + u32 tmp_value; + + if (HW_DASH_SUPPORT_TYPE_2(tp) == FALSE && + HW_DASH_SUPPORT_TYPE_3(tp) == FALSE) + return; + + if (!tp->AllowAccessDashOcp) + return; + + rtl8126_ocp_write(tp, 0x180, 1, OOB_CMD_DRIVER_START); + tmp_value = rtl8126_ocp_read(tp, 0x30, 1); + tmp_value |= BIT_0; + rtl8126_ocp_write(tp, 0x30, 1, tmp_value); + + rtl8126_wait_dash_fw_ready(tp); +} + +static void rtl8126_driver_stop(struct rtl8126_private *tp) +{ + u32 tmp_value; + struct net_device *dev = tp->dev; + + if (HW_DASH_SUPPORT_TYPE_2(tp) == FALSE && + HW_DASH_SUPPORT_TYPE_3(tp) == FALSE) + return; + + if (!tp->AllowAccessDashOcp) + return; + + rtl8126_dash2_disable_txrx(dev); + + rtl8126_ocp_write(tp, 0x180, 1, OOB_CMD_DRIVER_STOP); + tmp_value = rtl8126_ocp_read(tp, 0x30, 1); + tmp_value |= BIT_0; + rtl8126_ocp_write(tp, 0x30, 1, tmp_value); + + rtl8126_wait_dash_fw_ready(tp); +} + +void rtl8126_ephy_write(struct rtl8126_private *tp, int RegAddr, int value) +{ + int i; + + RTL_W32(tp, EPHYAR, + EPHYAR_Write | + (RegAddr & EPHYAR_Reg_Mask_v2) << EPHYAR_Reg_shift | + (value & EPHYAR_Data_Mask)); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed EPHY write */ + if (!(RTL_R32(tp, EPHYAR) & EPHYAR_Flag)) + break; + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); +} + +u16 rtl8126_ephy_read(struct rtl8126_private *tp, int RegAddr) +{ + int i; + u16 value = 0xffff; + + RTL_W32(tp, EPHYAR, + EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask_v2) << EPHYAR_Reg_shift); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed EPHY read */ + if (RTL_R32(tp, EPHYAR) & EPHYAR_Flag) { + value = (u16) (RTL_R32(tp, EPHYAR) & EPHYAR_Data_Mask); + break; + } + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); + + return value; +} + +/* +static void ClearAndSetPCIePhyBit(struct rtl8126_private *tp, u8 addr, u16 clearmask, u16 setmask) +{ + u16 EphyValue; + + EphyValue = rtl8126_ephy_read(tp, addr); + EphyValue &= ~clearmask; + EphyValue |= setmask; + rtl8126_ephy_write(tp, addr, EphyValue); +} + +static void ClearPCIePhyBit(struct rtl8126_private *tp, u8 addr, u16 mask) +{ + ClearAndSetPCIePhyBit(tp, + addr, + mask, + 0); +} + +static void SetPCIePhyBit(struct rtl8126_private *tp, u8 addr, u16 mask) +{ + ClearAndSetPCIePhyBit(tp, + addr, + 0, + mask); +} +*/ + +static u32 +rtl8126_csi_other_fun_read(struct rtl8126_private *tp, + u8 multi_fun_sel_bit, + u32 addr) +{ + u32 cmd; + int i; + u32 value = 0xffffffff; + + cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + multi_fun_sel_bit = 0; + + if (multi_fun_sel_bit > 7) + goto exit; + + cmd |= multi_fun_sel_bit << 16; + + RTL_W32(tp, CSIAR, cmd); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed CSI read */ + if (RTL_R32(tp, CSIAR) & CSIAR_Flag) { + value = (u32)RTL_R32(tp, CSIDR); + break; + } + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); + +exit: + return value; +} + +static void +rtl8126_csi_other_fun_write(struct rtl8126_private *tp, + u8 multi_fun_sel_bit, + u32 addr, + u32 value) +{ + u32 cmd; + int i; + + RTL_W32(tp, CSIDR, value); + cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); + if (tp->mcfg == CFG_METHOD_DEFAULT) + multi_fun_sel_bit = 0; + + if (multi_fun_sel_bit > 7) + return; + + cmd |= multi_fun_sel_bit << 16; + + RTL_W32(tp, CSIAR, cmd); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed CSI write */ + if (!(RTL_R32(tp, CSIAR) & CSIAR_Flag)) + break; + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); +} + +static u32 +rtl8126_csi_read(struct rtl8126_private *tp, + u32 addr) +{ + u8 multi_fun_sel_bit; + + multi_fun_sel_bit = 0; + + return rtl8126_csi_other_fun_read(tp, multi_fun_sel_bit, addr); +} + +static void +rtl8126_csi_write(struct rtl8126_private *tp, + u32 addr, + u32 value) +{ + u8 multi_fun_sel_bit; + + multi_fun_sel_bit = 0; + + rtl8126_csi_other_fun_write(tp, multi_fun_sel_bit, addr, value); +} + +static u8 +rtl8126_csi_fun0_read_byte(struct rtl8126_private *tp, + u32 addr) +{ + u8 RetVal = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT) { + struct pci_dev *pdev = tp->pci_dev; + + pci_read_config_byte(pdev, addr, &RetVal); + } else { + u32 TmpUlong; + u16 RegAlignAddr; + u8 ShiftByte; + + RegAlignAddr = addr & ~(0x3); + ShiftByte = addr & (0x3); + TmpUlong = rtl8126_csi_other_fun_read(tp, 0, RegAlignAddr); + TmpUlong >>= (8*ShiftByte); + RetVal = (u8)TmpUlong; + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); + + return RetVal; +} + +static void +rtl8126_csi_fun0_write_byte(struct rtl8126_private *tp, + u32 addr, + u8 value) +{ + if (tp->mcfg == CFG_METHOD_DEFAULT) { + struct pci_dev *pdev = tp->pci_dev; + + pci_write_config_byte(pdev, addr, value); + } else { + u32 TmpUlong; + u16 RegAlignAddr; + u8 ShiftByte; + + RegAlignAddr = addr & ~(0x3); + ShiftByte = addr & (0x3); + TmpUlong = rtl8126_csi_other_fun_read(tp, 0, RegAlignAddr); + TmpUlong &= ~(0xFF << (8*ShiftByte)); + TmpUlong |= (value << (8*ShiftByte)); + rtl8126_csi_other_fun_write(tp, 0, RegAlignAddr, TmpUlong); + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); +} + +u32 rtl8126_eri_read_with_oob_base_address(struct rtl8126_private *tp, int addr, int len, int type, const u32 base_address) +{ + int i, val_shift, shift = 0; + u32 value1 = 0, value2 = 0, mask; + u32 eri_cmd; + const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | (base_address & 0x000FFF); + + if (len > 4 || len <= 0) + return -1; + + while (len > 0) { + val_shift = addr % ERIAR_Addr_Align; + addr = addr & ~0x3; + + eri_cmd = ERIAR_Read | + transformed_base_address | + type << ERIAR_Type_shift | + ERIAR_ByteEn << ERIAR_ByteEn_shift | + (addr & 0x0FFF); + if (addr & 0xF000) { + u32 tmp; + + tmp = addr & 0xF000; + tmp >>= 12; + eri_cmd |= (tmp << 20) & 0x00F00000; + } + + RTL_W32(tp, ERIAR, eri_cmd); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed ERI read */ + if (RTL_R32(tp, ERIAR) & ERIAR_Flag) + break; + } + + if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + + value1 = RTL_R32(tp, ERIDR) & mask; + value2 |= (value1 >> val_shift * 8) << shift * 8; + + if (len <= 4 - val_shift) { + len = 0; + } else { + len -= (4 - val_shift); + shift = 4 - val_shift; + addr += 4; + } + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); + + return value2; +} + +u32 rtl8126_eri_read(struct rtl8126_private *tp, int addr, int len, int type) +{ + return rtl8126_eri_read_with_oob_base_address(tp, addr, len, type, 0); +} + +int rtl8126_eri_write_with_oob_base_address(struct rtl8126_private *tp, int addr, int len, u32 value, int type, const u32 base_address) +{ + int i, val_shift, shift = 0; + u32 value1 = 0, mask; + u32 eri_cmd; + const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | (base_address & 0x000FFF); + + if (len > 4 || len <= 0) + return -1; + + while (len > 0) { + val_shift = addr % ERIAR_Addr_Align; + addr = addr & ~0x3; + + if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + + value1 = rtl8126_eri_read_with_oob_base_address(tp, addr, 4, type, base_address) & ~mask; + value1 |= ((value << val_shift * 8) >> shift * 8); + + RTL_W32(tp, ERIDR, value1); + + eri_cmd = ERIAR_Write | + transformed_base_address | + type << ERIAR_Type_shift | + ERIAR_ByteEn << ERIAR_ByteEn_shift | + (addr & 0x0FFF); + if (addr & 0xF000) { + u32 tmp; + + tmp = addr & 0xF000; + tmp >>= 12; + eri_cmd |= (tmp << 20) & 0x00F00000; + } + + RTL_W32(tp, ERIAR, eri_cmd); + + for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) { + udelay(R8126_CHANNEL_WAIT_TIME); + + /* Check if the RTL8125 has completed ERI write */ + if (!(RTL_R32(tp, ERIAR) & ERIAR_Flag)) + break; + } + + if (len <= 4 - val_shift) { + len = 0; + } else { + len -= (4 - val_shift); + shift = 4 - val_shift; + addr += 4; + } + } + + udelay(R8126_CHANNEL_EXIT_DELAY_TIME); + + return 0; +} + +int rtl8126_eri_write(struct rtl8126_private *tp, int addr, int len, u32 value, int type) +{ + return rtl8126_eri_write_with_oob_base_address(tp, addr, len, value, type, NO_BASE_ADDRESS); +} + +static void +rtl8126_enable_rxdvgate(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) | BIT_3); + mdelay(2); + break; + } +} + +static void +rtl8126_disable_rxdvgate(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_3); + mdelay(2); + break; + } +} + +static u8 +rtl8126_is_gpio_low(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u8 gpio_low = FALSE; + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + if (!(rtl8126_mac_ocp_read(tp, 0xDC04) & BIT_13)) + gpio_low = TRUE; + break; + } + + if (gpio_low) + dprintk("gpio is low.\n"); + + return gpio_low; +} + +static u8 +rtl8126_is_phy_disable_mode_enabled(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u8 phy_disable_mode_enabled = FALSE; + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + if (RTL_R8(tp, 0xF2) & BIT_5) + phy_disable_mode_enabled = TRUE; + break; + } + + if (phy_disable_mode_enabled) + dprintk("phy disable mode enabled.\n"); + + return phy_disable_mode_enabled; +} + +static u8 +rtl8126_is_in_phy_disable_mode(struct net_device *dev) +{ + u8 in_phy_disable_mode = FALSE; + + if (rtl8126_is_phy_disable_mode_enabled(dev) && rtl8126_is_gpio_low(dev)) + in_phy_disable_mode = TRUE; + + if (in_phy_disable_mode) + dprintk("Hardware is in phy disable mode.\n"); + + return in_phy_disable_mode; +} + +static bool +rtl8126_stop_all_request(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); + + return 1; +} + +void +rtl8126_wait_txrx_fifo_empty(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_stop_all_request(dev); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + for (i = 0; i < 3000; i++) { + udelay(50); + if ((RTL_R8(tp, MCUCmd_reg) & (Txfifo_empty | Rxfifo_empty)) == (Txfifo_empty | Rxfifo_empty)) + break; + } + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + for (i = 0; i < 3000; i++) { + udelay(50); + if ((RTL_R16(tp, IntrMitigate) & (BIT_0 | BIT_1 | BIT_8)) == (BIT_0 | BIT_1 | BIT_8)) + break; + } + break; + } +} + +#ifdef ENABLE_DASH_SUPPORT + +static inline void +rtl8126_enable_dash2_interrupt(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, (ISRIMR_DASH_TYPE2_ROK | ISRIMR_DASH_TYPE2_TOK | ISRIMR_DASH_TYPE2_TDU | ISRIMR_DASH_TYPE2_RDU | ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE)); + } +} + +static inline void +rtl8126_disable_dash2_interrupt(struct rtl8126_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, 0); + } +} +#endif + +void +rtl8126_enable_hw_linkchg_interrupt(struct rtl8126_private *tp) +{ + switch (tp->HwCurrIsrVer) { + case 5: + RTL_W32(tp, IMR_V2_SET_REG_8125, ISRIMR_V5_LINKCHG); + break; + case 4: + RTL_W32(tp, IMR_V2_SET_REG_8125, ISRIMR_V4_LINKCHG); + break; + case 2: + case 3: + RTL_W32(tp, IMR_V2_SET_REG_8125, ISRIMR_V2_LINKCHG); + break; + case 1: + RTL_W32(tp, tp->imr_reg[0], LinkChg | RTL_R32(tp, tp->imr_reg[0])); + break; + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8126_enable_dash2_interrupt(tp); +#endif +} + +static inline void +rtl8126_enable_hw_interrupt(struct rtl8126_private *tp) +{ + switch (tp->HwCurrIsrVer) { + case 2: + case 3: + case 4: + case 5: + RTL_W32(tp, IMR_V2_SET_REG_8125, tp->intr_mask); + break; + case 1: + RTL_W32(tp, tp->imr_reg[0], tp->intr_mask); + + if (R8126_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->imr_reg[i], other_q_intr_mask); + } + break; + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8126_enable_dash2_interrupt(tp); +#endif +} + +static inline void rtl8126_clear_hw_isr_v2(struct rtl8126_private *tp, + u32 message_id) +{ + RTL_W32(tp, ISR_V2_8125, BIT(message_id)); +} + +static inline void +rtl8126_disable_hw_interrupt(struct rtl8126_private *tp) +{ + if (tp->HwCurrIsrVer > 1) { + RTL_W32(tp, IMR_V2_CLEAR_REG_8125, 0xFFFFFFFF); + if (tp->HwCurrIsrVer > 3) + RTL_W32(tp, IMR_V4_L2_CLEAR_REG_8125, 0xFFFFFFFF); + } else { + RTL_W32(tp, tp->imr_reg[0], 0x0000); + + if (R8126_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->imr_reg[i], 0); + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8126_disable_dash2_interrupt(tp); +#endif + } +} + +static inline void +rtl8126_switch_to_hw_interrupt(struct rtl8126_private *tp) +{ + RTL_W32(tp, TIMER_INT0_8125, 0x0000); + + rtl8126_enable_hw_interrupt(tp); +} + +static inline void +rtl8126_switch_to_timer_interrupt(struct rtl8126_private *tp) +{ + if (tp->use_timer_interrupt) { + RTL_W32(tp, TIMER_INT0_8125, timer_count); + RTL_W32(tp, TCTR0_8125, timer_count); + RTL_W32(tp, tp->imr_reg[0], tp->timer_intr_mask); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8126_enable_dash2_interrupt(tp); +#endif + } else { + rtl8126_switch_to_hw_interrupt(tp); + } +} + +static void +rtl8126_irq_mask_and_ack(struct rtl8126_private *tp) +{ + rtl8126_disable_hw_interrupt(tp); + + if (tp->HwCurrIsrVer > 1) { + RTL_W32(tp, ISR_V2_8125, 0xFFFFFFFF); + if (tp->HwCurrIsrVer > 3) + RTL_W32(tp, ISR_V4_L2_8125, 0xFFFFFFFF); + } else { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (tp->dash_printer_enabled) { + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0]) & + ~(ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET)); + } else { + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBISR0, RTL_CMAC_R8(tp, CMAC_IBISR0)); + } + } + } else { + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0])); + } +#else + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0])); +#endif + if (R8126_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->isr_reg[i], RTL_R16(tp, tp->isr_reg[i])); + } + } +} + +static void +rtl8126_disable_rx_packet_filter(struct rtl8126_private *tp) +{ + + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & + ~(AcceptErr | AcceptRunt |AcceptBroadcast | AcceptMulticast | + AcceptMyPhys | AcceptAllPhys)); +} + +static void +rtl8126_nic_reset(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + rtl8126_disable_rx_packet_filter(tp); + + rtl8126_enable_rxdvgate(dev); + + rtl8126_stop_all_request(dev); + + rtl8126_wait_txrx_fifo_empty(dev); + + mdelay(2); + + /* Soft reset the chip. */ + RTL_W8(tp, ChipCmd, CmdReset); + + /* Check that the chip has finished the reset. */ + for (i = 100; i > 0; i--) { + udelay(100); + if ((RTL_R8(tp, ChipCmd) & CmdReset) == 0) + break; + } + + /* reset rcr */ + RTL_W32(tp, RxConfig, (RX_DMA_BURST_512 << RxCfgDMAShift)); +} + +static void +rtl8126_hw_set_interrupt_type(struct rtl8126_private *tp, u8 isr_ver) +{ + u8 tmp; + + if (tp->HwSuppIsrVer < 2) + return; + + tmp = RTL_R8(tp, INT_CFG0_8125); + + switch (tp->HwSuppIsrVer) { + case 4: + case 5: + tmp &= ~INT_CFG0_MSIX_ENTRY_NUM_MODE; + fallthrough; + case 2: + case 3: + tmp &= ~(INT_CFG0_ENABLE_8125); + if (isr_ver > 1) + tmp |= INT_CFG0_ENABLE_8125; + break; + default: + return; + } + + RTL_W8(tp, INT_CFG0_8125, tmp); +} + +static void +rtl8126_hw_clear_timer_int(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W32(tp, TIMER_INT0_8125, 0x0000); + RTL_W32(tp, TIMER_INT1_8125, 0x0000); + RTL_W32(tp, TIMER_INT2_8125, 0x0000); + RTL_W32(tp, TIMER_INT3_8125, 0x0000); + break; + } +} + +static void +rtl8126_hw_clear_int_miti(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + switch (tp->HwSuppIntMitiVer) { + case 3: + case 6: + //IntMITI_0-IntMITI_31 + for (i=0xA00; i<0xB00; i+=4) + RTL_W32(tp, i, 0x0000); + break; + case 4: + case 5: + //IntMITI_0-IntMITI_15 + for (i = 0xA00; i < 0xA80; i += 4) + RTL_W32(tp, i, 0x0000); + + if (tp->HwSuppIntMitiVer == 5) + RTL_W8(tp, INT_CFG0_8125, RTL_R8(tp, INT_CFG0_8125) & + ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | + INT_CFG0_MITIGATION_BYPASS_8125 | + INT_CFG0_RDU_BYPASS_8126)); + else + RTL_W8(tp, INT_CFG0_8125, RTL_R8(tp, INT_CFG0_8125) & + ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | INT_CFG0_MITIGATION_BYPASS_8125)); + + RTL_W16(tp, INT_CFG1_8125, 0x0000); + break; + } +} + +void +rtl8126_hw_set_timer_int_8125(struct rtl8126_private *tp, + u32 message_id, + u8 timer_intmiti_val) +{ + switch (tp->HwSuppIntMitiVer) { + case 4: +#ifdef ENABLE_LIB_SUPPORT + if (message_id < R8126_MAX_RX_QUEUES_VEC_V3) + timer_intmiti_val = 0; +#else + if ((tp->HwCurrIsrVer == 2) && (message_id < R8126_MAX_RX_QUEUES_VEC_V3)) + timer_intmiti_val = 0; +#endif //ENABLE_LIB_SUPPORT + if (message_id < R8126_MAX_RX_QUEUES_VEC_V3) //ROK + RTL_W8(tp,INT_MITI_V2_0_RX + 8 * message_id, timer_intmiti_val); + if (message_id == 16) //TOK + RTL_W8(tp,INT_MITI_V2_0_TX, timer_intmiti_val); + if (message_id == 18 && tp->num_tx_rings > 0) //TOK + RTL_W8(tp,INT_MITI_V2_1_TX, timer_intmiti_val); + break; + case 5: + case 6: + if (message_id < R8126_MAX_RX_QUEUES_VEC_V3) //ROK + RTL_W8(tp,INT_MITI_V2_0_RX + 8 * message_id, timer_intmiti_val); + if (message_id == 0) //TOK + RTL_W8(tp,INT_MITI_V2_0_TX, timer_intmiti_val); + if (message_id == 1 && tp->num_tx_rings > 0) //TOK + RTL_W8(tp,INT_MITI_V2_1_TX, timer_intmiti_val); + break; + } +} + +void +rtl8126_hw_reset(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_lib_reset_prepare(tp); + + /* Disable interrupts */ + rtl8126_irq_mask_and_ack(tp); + + rtl8126_hw_clear_timer_int(dev); + + rtl8126_nic_reset(dev); +} + +static unsigned int +rtl8126_xmii_reset_pending(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + unsigned int retval; + + rtl8126_mdio_write(tp, 0x1f, 0x0000); + retval = rtl8126_mdio_read(tp, MII_BMCR) & BMCR_RESET; + + return retval; +} + +static unsigned int +rtl8126_xmii_link_ok(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u16 status; + + status = RTL_R16(tp, PHYstatus); + if (status == 0xffff) + return 0; + + return (status & LinkStatus) ? 1 : 0; +} + +static int +rtl8126_wait_phy_reset_complete(struct rtl8126_private *tp) +{ + int i, val; + + for (i = 0; i < 2500; i++) { + val = rtl8126_mdio_read(tp, MII_BMCR) & BMCR_RESET; + if (!val) + return 0; + + mdelay(1); + } + + return -1; +} + +static void +rtl8126_xmii_reset_enable(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (rtl8126_is_in_phy_disable_mode(dev)) + return; + + rtl8126_mdio_write(tp, 0x1f, 0x0000); + rtl8126_mdio_write(tp, MII_ADVERTISE, rtl8126_mdio_read(tp, MII_ADVERTISE) & + ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL)); + rtl8126_mdio_write(tp, MII_CTRL1000, rtl8126_mdio_read(tp, MII_CTRL1000) & + ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL)); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA5D4, rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D4) & + ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL)); + rtl8126_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); + + if (rtl8126_wait_phy_reset_complete(tp) == 0) + return; + + if (netif_msg_link(tp)) + printk(KERN_ERR "%s: PHY reset failed.\n", dev->name); +} + +void +rtl8126_init_ring_indexes(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + ring->dirty_tx = ring->cur_tx = 0; + ring->NextHwDesCloPtr = 0; + ring->BeginHwDesCloPtr = 0; + ring->index = i; + ring->priv = tp; + ring->netdev = tp->dev; + + /* reset BQL for queue */ + netdev_tx_reset_queue(txring_txq(ring)); + } + + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + ring->dirty_rx = ring->cur_rx = 0; + ring->index = i; + ring->priv = tp; + ring->netdev = tp->dev; + } + +#ifdef ENABLE_LIB_SUPPORT + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8126_ring *ring = &tp->lib_tx_ring[i]; + ring->direction = RTL8126_CH_DIR_TX; + ring->queue_num = i; + ring->private = tp; + } + + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8126_ring *ring = &tp->lib_rx_ring[i]; + ring->direction = RTL8126_CH_DIR_RX; + ring->queue_num = i; + ring->private = tp; + } +#endif +} + +static void +rtl8126_issue_offset_99_event(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xE09A, rtl8126_mac_ocp_read(tp, 0xE09A) | BIT_0); + break; + } +} + +#ifdef ENABLE_DASH_SUPPORT +static void +NICChkTypeEnableDashInterrupt(struct rtl8126_private *tp) +{ + if (tp->DASH) { + // + // even disconnected, enable 3 dash interrupt mask bits for in-band/out-band communication + // + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + rtl8126_enable_dash2_interrupt(tp); + RTL_W16(tp, IntrMask, (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET)); + } + } +} +#endif + +static int rtl8126_enable_eee_plus(struct rtl8126_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xE080, rtl8126_mac_ocp_read(tp, 0xE080)|BIT_1); + break; + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEEPlus\n"); + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static int rtl8126_disable_eee_plus(struct rtl8126_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xE080, rtl8126_mac_ocp_read(tp, 0xE080)&~BIT_1); + break; + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEEPlus\n"); + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static void rtl8126_enable_double_vlan(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W16(tp, DOUBLE_VLAN_CONFIG, 0xf002); + break; + default: + break; + } +} + +static void rtl8126_disable_double_vlan(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W16(tp, DOUBLE_VLAN_CONFIG, 0); + break; + default: + break; + } +} + +static void +rtl8126_link_on_patch(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_hw_config(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + if (RTL_R8(tp, PHYstatus) & _10bps) + rtl8126_enable_eee_plus(tp); + break; + default: + break; + } + + rtl8126_hw_start(dev); + + netif_carrier_on(dev); + + netif_tx_wake_all_queues(dev); + + tp->phy_reg_aner = rtl8126_mdio_read(tp, MII_EXPANSION); + tp->phy_reg_anlpar = rtl8126_mdio_read(tp, MII_LPA); + tp->phy_reg_gbsr = rtl8126_mdio_read(tp, MII_STAT1000); + tp->phy_reg_status_2500 = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D6); +} + +static void +rtl8126_link_down_patch(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + tp->phy_reg_aner = 0; + tp->phy_reg_anlpar = 0; + tp->phy_reg_gbsr = 0; + tp->phy_reg_status_2500 = 0; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_disable_eee_plus(tp); + break; + default: + break; + } + + netif_carrier_off(dev); + + netif_tx_disable(dev); + + rtl8126_hw_reset(dev); + + rtl8126_tx_clear(tp); + + rtl8126_rx_clear(tp); + + rtl8126_init_ring(dev); + + rtl8126_enable_hw_linkchg_interrupt(tp); + + //rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + NICChkTypeEnableDashInterrupt(tp); + } +#endif +} + +static void +_rtl8126_check_link_status(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->link_ok(dev)) { + rtl8126_link_on_patch(dev); + + if (netif_msg_ifup(tp)) + printk(KERN_INFO PFX "%s: link up\n", dev->name); + } else { + if (netif_msg_ifdown(tp)) + printk(KERN_INFO PFX "%s: link down\n", dev->name); + + rtl8126_link_down_patch(dev); + } +} + +static void +rtl8126_check_link_status(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + _rtl8126_check_link_status(dev); + + tp->resume_not_chg_speed = 0; +} + +static bool +rtl8126_is_autoneg_mode_valid(u32 autoneg) +{ + switch(autoneg) { + case AUTONEG_ENABLE: + case AUTONEG_DISABLE: + return true; + default: + return false; + } +} + +static bool +rtl8126_is_speed_mode_valid(u32 speed) +{ + switch(speed) { + case SPEED_5000: + case SPEED_2500: + case SPEED_1000: + case SPEED_100: + case SPEED_10: + return true; + default: + return false; + } +} + +static bool +rtl8126_is_duplex_mode_valid(u8 duplex) +{ + switch(duplex) { + case DUPLEX_FULL: + case DUPLEX_HALF: + return true; + default: + return false; + } +} + +static void +rtl8126_set_link_option(struct rtl8126_private *tp, + u8 autoneg, + u32 speed, + u8 duplex, + enum rtl8126_fc_mode fc) +{ + u64 adv; + + if (!rtl8126_is_speed_mode_valid(speed)) + speed = SPEED_5000; + + if (!rtl8126_is_duplex_mode_valid(duplex)) + duplex = DUPLEX_FULL; + + if (!rtl8126_is_autoneg_mode_valid(autoneg)) + autoneg = AUTONEG_ENABLE; + + speed = min(speed, tp->HwSuppMaxPhyLinkSpeed); + + adv = 0; + switch(speed) { + case SPEED_5000: + adv |= RTK_ADVERTISED_5000baseX_Full; + fallthrough; + case SPEED_2500: + adv |= ADVERTISED_2500baseX_Full; + fallthrough; + default: + adv |= (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); + break; + } + + tp->autoneg = autoneg; + tp->speed = speed; + tp->duplex = duplex; + tp->advertising = adv; + tp->fcpause = fc; +} + +static void +rtl8126_wait_ll_share_fifo_ready(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + for (i = 0; i < 10; i++) { + udelay(100); + if (RTL_R16(tp, 0xD2) & BIT_9) + break; + } +} + +static void +rtl8126_disable_pci_offset_99(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xE032, rtl8126_mac_ocp_read(tp, 0xE032) & ~(BIT_0 | BIT_1)); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_csi_fun0_write_byte(tp, 0x99, 0x00); + break; + } +} + +static void +rtl8126_enable_pci_offset_99(struct rtl8126_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_csi_fun0_write_byte(tp, 0x99, tp->org_pci_offset_99); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE032); + csi_tmp &= ~(BIT_0 | BIT_1); + if (tp->org_pci_offset_99 & (BIT_5 | BIT_6)) + csi_tmp |= BIT_1; + if (tp->org_pci_offset_99 & BIT_2) + csi_tmp |= BIT_0; + rtl8126_mac_ocp_write(tp, 0xE032, csi_tmp); + break; + } +} + +static void +rtl8126_init_pci_offset_99(struct rtl8126_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + rtl8126_mac_ocp_write(tp, 0xCDD0, 0x9003); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE034); + csi_tmp |= (BIT_15 | BIT_14); + rtl8126_mac_ocp_write(tp, 0xE034, csi_tmp); + rtl8126_mac_ocp_write(tp, 0xCDD2, 0x889C); + rtl8126_mac_ocp_write(tp, 0xCDD8, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDD4, 0x8C30); + rtl8126_mac_ocp_write(tp, 0xCDDA, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDD6, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDDC, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDE8, 0x883E); + rtl8126_mac_ocp_write(tp, 0xCDEA, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDEC, 0x889C); + rtl8126_mac_ocp_write(tp, 0xCDEE, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDF0, 0x8C09); + rtl8126_mac_ocp_write(tp, 0xCDF2, 0x9003); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE032); + csi_tmp |= (BIT_14); + rtl8126_mac_ocp_write(tp, 0xE032, csi_tmp); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE0A2); + csi_tmp |= (BIT_0); + rtl8126_mac_ocp_write(tp, 0xE0A2, csi_tmp); + break; + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xCDD0, 0x9003); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE034); + csi_tmp |= (BIT_15 | BIT_14); + rtl8126_mac_ocp_write(tp, 0xE034, csi_tmp); + rtl8126_mac_ocp_write(tp, 0xCDD2, 0x8A71); + rtl8126_mac_ocp_write(tp, 0xCDD8, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDD4, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDDA, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDD6, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDDC, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDE8, 0x88FA); + rtl8126_mac_ocp_write(tp, 0xCDEA, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDEC, 0x89F4); + rtl8126_mac_ocp_write(tp, 0xCDEE, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDF0, 0x8C27); + rtl8126_mac_ocp_write(tp, 0xCDF2, 0x9003); + rtl8126_mac_ocp_write(tp, 0xCDF4, 0x887D); + rtl8126_mac_ocp_write(tp, 0xCDF6, 0x9003); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE032); + csi_tmp |= (BIT_14); + rtl8126_mac_ocp_write(tp, 0xE032, csi_tmp); + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE0A2); + csi_tmp |= (BIT_0); + rtl8126_mac_ocp_write(tp, 0xE0A2, csi_tmp); + break; + } + + rtl8126_enable_pci_offset_99(tp); +} + +static void +rtl8126_disable_pci_offset_180(struct rtl8126_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE092); + csi_tmp &= 0xFF00; + rtl8126_mac_ocp_write(tp, 0xE092, csi_tmp); + break; + } +} + +static void +rtl8126_enable_pci_offset_180(struct rtl8126_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE094); + csi_tmp &= 0x00FF; + rtl8126_mac_ocp_write(tp, 0xE094, csi_tmp); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + csi_tmp = rtl8126_mac_ocp_read(tp, 0xE092); + csi_tmp &= 0xFF00; + csi_tmp |= BIT_2; + rtl8126_mac_ocp_write(tp, 0xE092, csi_tmp); + break; + } +} + +static void +rtl8126_init_pci_offset_180(struct rtl8126_private *tp) +{ + rtl8126_enable_pci_offset_180(tp); +} + +static void +rtl8126_set_pci_99_180_exit_driver_para(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + if (tp->org_pci_offset_99 & BIT_2) + rtl8126_issue_offset_99_event(tp); + rtl8126_disable_pci_offset_99(tp); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_disable_pci_offset_180(tp); + break; + } +} + +static void +rtl8126_enable_cfg9346_write(struct rtl8126_private *tp) +{ + RTL_W8(tp, Cfg9346, RTL_R8(tp, Cfg9346) | Cfg9346_Unlock); +} + +static void +rtl8126_disable_cfg9346_write(struct rtl8126_private *tp) +{ + RTL_W8(tp, Cfg9346, RTL_R8(tp, Cfg9346) & ~Cfg9346_Unlock); +} + +static void +rtl8126_enable_exit_l1_mask(struct rtl8126_private *tp) +{ + //(1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b111111, L1 Mask + rtl8126_set_mac_ocp_bit(tp, 0xC0AC, (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12)); +} + +static void +rtl8126_disable_exit_l1_mask(struct rtl8126_private *tp) +{ + //(1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b000000, L1 Mask + rtl8126_clear_mac_ocp_bit(tp, 0xC0AC, (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12)); +} + +static void +rtl8126_enable_extend_tally_couter(struct rtl8126_private *tp) +{ + switch (tp->HwSuppExtendTallyCounterVer) { + case 1: + rtl8126_set_mac_ocp_bit(tp, 0xEA84, (BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8126_disable_extend_tally_couter(struct rtl8126_private *tp) +{ + switch (tp->HwSuppExtendTallyCounterVer) { + case 1: + rtl8126_clear_mac_ocp_bit(tp, 0xEA84, (BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8126_enable_force_clkreq(struct rtl8126_private *tp, bool enable) +{ + if (enable) + RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) | BIT_7); + else + RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) & ~BIT_7); +} + +static void +rtl8126_enable_aspm_clkreq_lock(struct rtl8126_private *tp, bool enable) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + rtl8126_enable_cfg9346_write(tp); + if (enable) { + RTL_W8(tp, Config2, RTL_R8(tp, Config2) | BIT_7); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) | BIT_0); + } else { + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + } + rtl8126_disable_cfg9346_write(tp); + break; + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_cfg9346_write(tp); + if (enable) { + RTL_W8(tp, INT_CFG0_8125, RTL_R8(tp, INT_CFG0_8125) | BIT_3); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) | BIT_0); + } else { + RTL_W8(tp, INT_CFG0_8125, RTL_R8(tp, INT_CFG0_8125) & ~BIT_3); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + } + rtl8126_disable_cfg9346_write(tp); + break; + } +} + +static void +rtl8126_hw_d3_para(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + RTL_W16(tp, RxMaxSize, RX_BUF_SIZE); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_force_clkreq(tp, 0); + rtl8126_enable_aspm_clkreq_lock(tp, 0); + break; + } + + rtl8126_disable_exit_l1_mask(tp); + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8126_set_realwow_d3_para(dev); +#endif + + rtl8126_set_pci_99_180_exit_driver_para(dev); + + rtl8126_disable_rxdvgate(dev); + + rtl8126_disable_extend_tally_couter(tp); +} + +static void +rtl8126_enable_magic_packet(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + rtl8126_mac_ocp_write(tp, 0xC0B6, rtl8126_mac_ocp_read(tp, 0xC0B6) | BIT_0); + break; + } +} +static void +rtl8126_disable_magic_packet(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + rtl8126_mac_ocp_write(tp, 0xC0B6, rtl8126_mac_ocp_read(tp, 0xC0B6) & ~BIT_0); + break; + } +} + +static void +rtl8126_enable_linkchg_wakeup(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + RTL_W8(tp, Config3, RTL_R8(tp, Config3) | LinkUp); + rtl8126_clear_set_mac_ocp_bit(tp, 0xE0C6, (BIT_5 | BIT_3 | BIT_2), (BIT_4 | BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8126_disable_linkchg_wakeup(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~LinkUp); + rtl8126_clear_mac_ocp_bit(tp, 0xE0C6, (BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0)); + break; + } +} + +#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) + +static u32 +rtl8126_get_hw_wol(struct rtl8126_private *tp) +{ + u8 options; + u32 csi_tmp; + u32 wol_opts = 0; + + if (disable_wol_support) + goto out; + + options = RTL_R8(tp, Config1); + if (!(options & PMEnable)) + goto out; + + options = RTL_R8(tp, Config3); + if (options & LinkUp) + wol_opts |= WAKE_PHY; + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + csi_tmp = rtl8126_mac_ocp_read(tp, 0xC0B6); + if (csi_tmp & BIT_0) + wol_opts |= WAKE_MAGIC; + break; + } + + options = RTL_R8(tp, Config5); + if (options & UWF) + wol_opts |= WAKE_UCAST; + if (options & BWF) + wol_opts |= WAKE_BCAST; + if (options & MWF) + wol_opts |= WAKE_MCAST; + +out: + return wol_opts; +} + +static void +rtl8126_enable_d0_speedup(struct rtl8126_private *tp) +{ + u16 clearmask; + u16 setmask; + + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) + return; + + if (tp->D0SpeedUpSpeed == D0_SPEED_UP_SPEED_DISABLE) + return; + + if (tp->HwSuppD0SpeedUpVer == 1 || tp->HwSuppD0SpeedUpVer == 2) { + //speed up speed + clearmask = (BIT_10 | BIT_9 | BIT_8 | BIT_7); + if (tp->D0SpeedUpSpeed == D0_SPEED_UP_SPEED_2500) + setmask = BIT_7; + else if (tp->D0SpeedUpSpeed == D0_SPEED_UP_SPEED_5000) + setmask = BIT_8; + else + setmask = 0; + rtl8126_clear_set_mac_ocp_bit(tp, 0xE10A, clearmask, setmask); + + //speed up flowcontrol + clearmask = (BIT_15 | BIT_14); + if (tp->HwSuppD0SpeedUpVer == 2) + clearmask |= BIT_13; + + if (tp->fcpause == rtl8126_fc_full) { + setmask = (BIT_15 | BIT_14); + if (tp->HwSuppD0SpeedUpVer == 2) + setmask |= BIT_13; + } else + setmask = 0; + rtl8126_clear_set_mac_ocp_bit(tp, 0xE860, clearmask, setmask); + } + + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_3); +} + +static void +rtl8126_disable_d0_speedup(struct rtl8126_private *tp) +{ + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) + return; + + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) & ~BIT_3); +} + +static void +rtl8126_set_hw_wol(struct net_device *dev, u32 wolopts) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i,tmp; + static struct { + u32 opt; + u16 reg; + u8 mask; + } cfg[] = { + { WAKE_PHY, Config3, LinkUp }, + { WAKE_UCAST, Config5, UWF }, + { WAKE_BCAST, Config5, BWF }, + { WAKE_MCAST, Config5, MWF }, + { WAKE_ANY, Config5, LanWake }, + { WAKE_MAGIC, Config3, MagicPacket }, + }; + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + default: + tmp = ARRAY_SIZE(cfg) - 1; + + if (wolopts & WAKE_MAGIC) + rtl8126_enable_magic_packet(dev); + else + rtl8126_disable_magic_packet(dev); + break; + } + + rtl8126_enable_cfg9346_write(tp); + + for (i = 0; i < tmp; i++) { + u8 options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; + if (wolopts & cfg[i].opt) + options |= cfg[i].mask; + RTL_W8(tp, cfg[i].reg, options); + } + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + if (wolopts & WAKE_PHY) + rtl8126_enable_linkchg_wakeup(dev); + else + rtl8126_disable_linkchg_wakeup(dev); + break; + } + + rtl8126_disable_cfg9346_write(tp); +} + +static void +rtl8126_phy_restart_nway(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (rtl8126_is_in_phy_disable_mode(dev)) + return; + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + rtl8126_mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); +} + +static void +rtl8126_phy_setup_force_mode(struct net_device *dev, u32 speed, u8 duplex) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u16 bmcr_true_force = 0; + + if (rtl8126_is_in_phy_disable_mode(dev)) + return; + + if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) { + bmcr_true_force = BMCR_SPEED10; + } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) { + bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX; + } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) { + bmcr_true_force = BMCR_SPEED100; + } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) { + bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX; + } else { + netif_err(tp, drv, dev, "Failed to set phy force mode!\n"); + return; + } + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + rtl8126_mdio_write(tp, MII_BMCR, bmcr_true_force); +} + +static void +rtl8126_set_pci_pme(struct rtl8126_private *tp, int set) +{ + struct pci_dev *pdev = tp->pci_dev; + u16 pmc; + + if (!pdev->pm_cap) + return; + + pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &pmc); + pmc |= PCI_PM_CTRL_PME_STATUS; + if (set) + pmc |= PCI_PM_CTRL_PME_ENABLE; + else + pmc &= ~PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, pmc); +} + +static void +rtl8126_set_wol_link_speed(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int auto_nego; + int giga_ctrl; + int ctrl_2500; + u64 adv; + u16 anlpar; + u16 gbsr; + u16 status_2500; + u16 aner; + + if (tp->autoneg != AUTONEG_ENABLE) + goto exit; + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + + auto_nego = rtl8126_mdio_read(tp, MII_ADVERTISE); + auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL + | ADVERTISE_100HALF | ADVERTISE_100FULL); + + giga_ctrl = rtl8126_mdio_read(tp, MII_CTRL1000); + giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); + + ctrl_2500 = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D4); + ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL); + + aner = tp->phy_reg_aner; + anlpar = tp->phy_reg_anlpar; + gbsr = tp->phy_reg_gbsr; + status_2500 = tp->phy_reg_status_2500; + if (tp->link_ok(dev)) { + aner = rtl8126_mdio_read(tp, MII_EXPANSION); + anlpar = rtl8126_mdio_read(tp, MII_LPA); + gbsr = rtl8126_mdio_read(tp, MII_STAT1000); + status_2500 = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D6); + } + + adv = tp->advertising; + if ((aner | anlpar | gbsr | status_2500) == 0) { + int auto_nego_tmp = 0; + if (adv & ADVERTISED_10baseT_Half) + auto_nego_tmp |= ADVERTISE_10HALF; + if (adv & ADVERTISED_10baseT_Full) + auto_nego_tmp |= ADVERTISE_10FULL; + if (adv & ADVERTISED_100baseT_Half) + auto_nego_tmp |= ADVERTISE_100HALF; + if (adv & ADVERTISED_100baseT_Full) + auto_nego_tmp |= ADVERTISE_100FULL; + + if (auto_nego_tmp == 0) + goto exit; + + auto_nego |= auto_nego_tmp; + goto skip_check_lpa; + } + if (!(aner & EXPANSION_NWAY)) + goto exit; + + if ((adv & ADVERTISED_10baseT_Half) && (anlpar & LPA_10HALF)) + auto_nego |= ADVERTISE_10HALF; + else if ((adv & ADVERTISED_10baseT_Full) && (anlpar & LPA_10FULL)) + auto_nego |= ADVERTISE_10FULL; + else if ((adv & ADVERTISED_100baseT_Half) && (anlpar & LPA_100HALF)) + auto_nego |= ADVERTISE_100HALF; + else if ((adv & ADVERTISED_100baseT_Full) && (anlpar & LPA_100FULL)) + auto_nego |= ADVERTISE_100FULL; + else if (adv & ADVERTISED_1000baseT_Half && (gbsr & LPA_1000HALF)) + giga_ctrl |= ADVERTISE_1000HALF; + else if (adv & ADVERTISED_1000baseT_Full && (gbsr & LPA_1000FULL)) + giga_ctrl |= ADVERTISE_1000FULL; + else if (adv & ADVERTISED_2500baseX_Full && (status_2500 & RTK_LPA_ADVERTISE_2500FULL)) + ctrl_2500 |= RTK_ADVERTISE_2500FULL; + else if (adv & RTK_ADVERTISED_5000baseX_Full && (status_2500 & RTK_LPA_ADVERTISE_5000FULL)) + ctrl_2500 |= RTK_ADVERTISE_5000FULL; + else + goto exit; + +skip_check_lpa: + if (tp->DASH) + auto_nego |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10HALF | ADVERTISE_10FULL); + +#ifdef CONFIG_DOWN_SPEED_100 + auto_nego |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10HALF | ADVERTISE_10FULL); +#endif + + rtl8126_mdio_write(tp, MII_ADVERTISE, auto_nego); + rtl8126_mdio_write(tp, MII_CTRL1000, giga_ctrl); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA5D4, ctrl_2500); + + rtl8126_phy_restart_nway(dev); + +exit: + return; +} + +static bool +rtl8126_keep_wol_link_speed(struct net_device *dev, u8 from_suspend) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if ((from_suspend && !tp->link_ok(dev)) || + (!from_suspend && tp->resume_not_chg_speed)) + return 1; + + return 0; +} +static void +rtl8126_powerdown_pll(struct net_device *dev, u8 from_suspend) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + tp->check_keep_link_speed = 0; + if (tp->wol_enabled == WOL_ENABLED || tp->DASH || tp->EnableKCPOffload) { + rtl8126_set_hw_wol(dev, tp->wol_opts); + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + rtl8126_enable_cfg9346_write(tp); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) | PMSTS_En); + rtl8126_disable_cfg9346_write(tp); + break; + default: + break; + }; + + /* Enable the PME and clear the status */ + rtl8126_set_pci_pme(tp, 1); + + if (rtl8126_keep_wol_link_speed(dev, from_suspend)) { + if (tp->wol_opts & WAKE_PHY) + tp->check_keep_link_speed = 1; + } else { + if (HW_SUPPORT_D0_SPEED_UP(tp)) { + rtl8126_enable_d0_speedup(tp); + tp->check_keep_link_speed = 1; + } + + rtl8126_set_wol_link_speed(dev); + } + + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + + return; + } + + if (tp->DASH) + return; + + rtl8126_phy_power_down(dev); + + if (!tp->HwIcVerUnknown) { + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~BIT_7); + break; + } + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_6); + break; + } +} + +static void rtl8126_powerup_pll(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | BIT_7 | BIT_6); + break; + } + + if (tp->resume_not_chg_speed) + return; + + rtl8126_phy_power_up(dev); +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static void +rtl8126_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u8 options; + + wol->wolopts = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT || disable_wol_support) { + wol->supported = 0; + return; + } else { + wol->supported = WAKE_ANY; + } + + options = RTL_R8(tp, Config1); + if (!(options & PMEnable)) + return; + + wol->wolopts = tp->wol_opts; +} + +static int +rtl8126_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT || disable_wol_support) + return -EOPNOTSUPP; + + tp->wol_opts = wol->wolopts; + + tp->wol_enabled = (tp->wol_opts) ? WOL_ENABLED : WOL_DISABLED; + + device_set_wakeup_enable(tp_to_dev(tp), wol->wolopts); + + return 0; +} + +static void +rtl8126_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct rtl8126_fw *rtl_fw = tp->rtl_fw; + + strscpy(info->driver, MODULENAME, sizeof(info->driver)); + strscpy(info->version, RTL8126_VERSION, sizeof(info->version)); + strscpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); + info->regdump_len = R8126_REGS_DUMP_SIZE; + info->eedump_len = tp->eeprom_len; + BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); + if (rtl_fw) + strscpy(info->fw_version, rtl_fw->version, + sizeof(info->fw_version)); +} + +static int +rtl8126_get_regs_len(struct net_device *dev) +{ + return R8126_REGS_DUMP_SIZE; +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static void +rtl8126_set_d0_speedup_speed(struct rtl8126_private *tp) +{ + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) + return; + + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_DISABLE; + if (tp->autoneg == AUTONEG_ENABLE) { + if (tp->speed == SPEED_5000) + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_5000; + else if (tp->speed == SPEED_2500) + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_2500; + else if (tp->speed == SPEED_1000) + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_1000; + } +} + +static int +rtl8126_set_speed_xmii(struct net_device *dev, + u8 autoneg, + u32 speed, + u8 duplex, + u64 adv) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int auto_nego = 0; + int giga_ctrl = 0; + int ctrl_2500 = 0; + int rc = -EINVAL; + + //Disable Giga Lite + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA428, BIT_9); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA5EA, BIT_0); + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA5EA, BIT_1); + + if (!rtl8126_is_speed_mode_valid(speed)) { + speed = SPEED_5000; + duplex = DUPLEX_FULL; + adv |= tp->advertising; + } + + giga_ctrl = rtl8126_mdio_read(tp, MII_CTRL1000); + giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); + ctrl_2500 = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D4); + ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL); + + if (autoneg == AUTONEG_ENABLE) { + /*n-way force*/ + auto_nego = rtl8126_mdio_read(tp, MII_ADVERTISE); + auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL | + ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + + if (adv & ADVERTISED_10baseT_Half) + auto_nego |= ADVERTISE_10HALF; + if (adv & ADVERTISED_10baseT_Full) + auto_nego |= ADVERTISE_10FULL; + if (adv & ADVERTISED_100baseT_Half) + auto_nego |= ADVERTISE_100HALF; + if (adv & ADVERTISED_100baseT_Full) + auto_nego |= ADVERTISE_100FULL; + if (adv & ADVERTISED_1000baseT_Half) + giga_ctrl |= ADVERTISE_1000HALF; + if (adv & ADVERTISED_1000baseT_Full) + giga_ctrl |= ADVERTISE_1000FULL; + if (adv & ADVERTISED_2500baseX_Full) + ctrl_2500 |= RTK_ADVERTISE_2500FULL; + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) { + if (adv & RTK_ADVERTISED_5000baseX_Full) + ctrl_2500 |= RTK_ADVERTISE_5000FULL; + } + + //flow control + if (tp->fcpause == rtl8126_fc_full) + auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + + tp->phy_auto_nego_reg = auto_nego; + tp->phy_1000_ctrl_reg = giga_ctrl; + + tp->phy_2500_ctrl_reg = ctrl_2500; + + rtl8126_mdio_write(tp, 0x1f, 0x0000); + rtl8126_mdio_write(tp, MII_ADVERTISE, auto_nego); + rtl8126_mdio_write(tp, MII_CTRL1000, giga_ctrl); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA5D4, ctrl_2500); + rtl8126_phy_restart_nway(dev); + mdelay(20); + } else { + /*true force*/ + if (speed == SPEED_10 || speed == SPEED_100) + rtl8126_phy_setup_force_mode(dev, speed, duplex); + else + goto out; + } + + tp->autoneg = autoneg; + tp->speed = speed; + tp->duplex = duplex; + tp->advertising = adv; + + rtl8126_set_d0_speedup_speed(tp); + + rc = 0; +out: + return rc; +} + +static int +rtl8126_set_speed(struct net_device *dev, + u8 autoneg, + u32 speed, + u8 duplex, + u64 adv) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret; + + if (tp->resume_not_chg_speed) + return 0; + + ret = tp->set_speed(dev, autoneg, speed, duplex, adv); + + return ret; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int +rtl8126_set_settings(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + const struct ethtool_link_ksettings *cmd +#endif + ) +{ + int ret; + u8 autoneg; + u32 speed; + u8 duplex; + u64 supported = 0, advertising = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + autoneg = cmd->autoneg; + speed = cmd->speed; + duplex = cmd->duplex; + supported = cmd->supported; + advertising = cmd->advertising; +#else + struct rtl8126_private *tp = netdev_priv(dev); + const struct ethtool_link_settings *base = &cmd->base; + autoneg = base->autoneg; + speed = base->speed; + duplex = base->duplex; + ethtool_convert_link_mode_to_legacy_u32((u32*)&supported, + cmd->link_modes.supported); + ethtool_convert_link_mode_to_legacy_u32((u32*)&advertising, + cmd->link_modes.advertising); + if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.supported)) + supported |= ADVERTISED_2500baseX_Full; + if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.advertising)) + advertising |= ADVERTISED_2500baseX_Full; + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) { + if (test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.supported)) + supported |= RTK_ADVERTISED_5000baseX_Full; + if (test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.advertising)) + advertising |= RTK_ADVERTISED_5000baseX_Full; + } +#endif + if (advertising & ~supported) + return -EINVAL; + + ret = rtl8126_set_speed(dev, autoneg, speed, duplex, advertising); + + return ret; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +static u32 +rtl8126_get_tx_csum(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 ret; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + ret = ((dev->features & NETIF_F_IP_CSUM) != 0); +#else + ret = ((dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) != 0); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + + return ret; +} + +static u32 +rtl8126_get_rx_csum(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 ret; + + ret = tp->cp_cmd & RxChkSum; + + return ret; +} + +static int +rtl8126_set_tx_csum(struct net_device *dev, + u32 data) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; +#else + if (data) + dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + else + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + + return 0; +} + +static int +rtl8126_set_rx_csum(struct net_device *dev, + u32 data) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + + if (data) + tp->cp_cmd |= RxChkSum; + else + tp->cp_cmd &= ~RxChkSum; + + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + + return 0; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static u32 +rtl8126_rx_desc_opts1(struct rtl8126_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1; + else + return desc->opts1; +} + +static u32 +rtl8126_rx_desc_opts2(struct rtl8126_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts2; + else + return desc->opts2; +} + +#ifdef CONFIG_R8126_VLAN + +static void +rtl8126_clear_rx_desc_opts2(struct rtl8126_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts2 = 0; + else + desc->opts2 = 0; +} + +static inline u32 +rtl8126_tx_vlan_tag(struct rtl8126_private *tp, + struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + return (tp->vlgrp && vlan_tx_tag_present(skb)) ? + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) + return (vlan_tx_tag_present(skb)) ? + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; +#else + return (skb_vlan_tag_present(skb)) ? + TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00; +#endif + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + +static void +rtl8126_vlan_rx_register(struct net_device *dev, + struct vlan_group *grp) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + tp->vlgrp = grp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + if (tp->vlgrp) { + tp->rtl8126_rx_config |= (EnableInnerVlan | EnableOuterVlan); + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | (EnableInnerVlan | EnableOuterVlan)) + } else { + tp->rtl8126_rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~(EnableInnerVlan | EnableOuterVlan)) + } + break; + } +} + +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +static void +rtl8126_vlan_rx_kill_vid(struct net_device *dev, + unsigned short vid) +{ + struct rtl8126_private *tp = netdev_priv(dev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) + if (tp->vlgrp) + tp->vlgrp->vlan_devices[vid] = NULL; +#else + vlan_group_set_device(tp->vlgrp, vid, NULL); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + +static int +rtl8126_rx_vlan_skb(struct rtl8126_private *tp, + struct RxDesc *desc, + struct sk_buff *skb) +{ + u32 opts2 = le32_to_cpu(rtl8126_rx_desc_opts2(tp, desc)); + int ret = -1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + if (tp->vlgrp && (opts2 & RxVlanTag)) { + rtl8126_rx_hwaccel_skb(skb, tp->vlgrp, + swab16(opts2 & 0xffff)); + ret = 0; + } +#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); +#else + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff)); +#endif + + rtl8126_clear_rx_desc_opts2(tp, desc); + return ret; +} + +#else /* !CONFIG_R8126_VLAN */ + +static inline u32 +rtl8126_tx_vlan_tag(struct rtl8126_private *tp, + struct sk_buff *skb) +{ + return 0; +} + +static int +rtl8126_rx_vlan_skb(struct rtl8126_private *tp, + struct RxDesc *desc, + struct sk_buff *skb) +{ + return -1; +} + +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + +static netdev_features_t rtl8126_fix_features(struct net_device *dev, + netdev_features_t features) +{ + if (dev->mtu > MSS_MAX) + features &= ~NETIF_F_ALL_TSO; + if (dev->mtu > ETH_DATA_LEN) { + features &= ~NETIF_F_ALL_TSO; + features &= ~NETIF_F_ALL_CSUM; + } +#ifndef CONFIG_R8126_VLAN + features &= ~NETIF_F_ALL_CSUM; +#endif + + return features; +} + +static int rtl8126_hw_set_features(struct net_device *dev, + netdev_features_t features) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 rx_config; + + rx_config = RTL_R32(tp, RxConfig); + if (features & NETIF_F_RXALL) { + tp->rtl8126_rx_config |= (AcceptErr | AcceptRunt); + rx_config |= (AcceptErr | AcceptRunt); + } else { + tp->rtl8126_rx_config &= ~(AcceptErr | AcceptRunt); + rx_config &= ~(AcceptErr | AcceptRunt); + } + + if (features & NETIF_F_HW_VLAN_RX) { + tp->rtl8126_rx_config |= (EnableInnerVlan | EnableOuterVlan); + rx_config |= (EnableInnerVlan | EnableOuterVlan); + } else { + tp->rtl8126_rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + } + + RTL_W32(tp, RxConfig, rx_config); + + if (features & NETIF_F_RXCSUM) + tp->cp_cmd |= RxChkSum; + else + tp->cp_cmd &= ~RxChkSum; + + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + RTL_R16(tp, CPlusCmd); + + return 0; +} + +static int rtl8126_set_features(struct net_device *dev, + netdev_features_t features) +{ + features &= NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; + + rtl8126_hw_set_features(dev, features); + + return 0; +} + +#endif + +static u8 rtl8126_get_mdi_status(struct rtl8126_private *tp) +{ + if (!tp->link_ok(tp->dev)) + return ETH_TP_MDI_INVALID; + + if (rtl8126_mdio_direct_read_phy_ocp(tp, 0xA444) & BIT_1) + return ETH_TP_MDI; + else + return ETH_TP_MDI_X; +} + +static void rtl8126_gset_xmii(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + struct ethtool_link_ksettings *cmd +#endif + ) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u16 aner = tp->phy_reg_aner; + u16 anlpar = tp->phy_reg_anlpar; + u16 gbsr = tp->phy_reg_gbsr; + u16 status_2500 = tp->phy_reg_status_2500; + u64 lpa_adv = 0; + u16 status; + u8 autoneg, duplex; + u32 speed = 0; + u16 bmcr; + u64 supported, advertising; + u8 report_lpa = 0; + + supported = SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause; + + if (!HW_SUPP_PHY_LINK_SPEED_2500M(tp)) + supported &= ~SUPPORTED_2500baseX_Full; + + advertising = tp->advertising; + if (tp->phy_auto_nego_reg || tp->phy_1000_ctrl_reg || + tp->phy_2500_ctrl_reg) { + advertising = 0; + if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) + advertising |= ADVERTISED_10baseT_Half; + if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) + advertising |= ADVERTISED_10baseT_Full; + if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) + advertising |= ADVERTISED_100baseT_Half; + if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) + advertising |= ADVERTISED_100baseT_Full; + if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) + advertising |= ADVERTISED_1000baseT_Full; + if (tp->phy_2500_ctrl_reg & RTK_ADVERTISE_2500FULL) + advertising |= ADVERTISED_2500baseX_Full; + if (tp->phy_2500_ctrl_reg & RTK_ADVERTISE_5000FULL) + advertising |= RTK_ADVERTISED_5000baseX_Full; + } + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + bmcr = rtl8126_mdio_read(tp, MII_BMCR); + if (bmcr & BMCR_ANENABLE) { + autoneg = AUTONEG_ENABLE; + advertising |= ADVERTISED_Autoneg; + } else { + autoneg = AUTONEG_DISABLE; + } + + advertising |= ADVERTISED_TP; + + status = RTL_R16(tp, PHYstatus); + if (netif_running(dev) && (status & LinkStatus)) + report_lpa = 1; + + if (report_lpa) { + /*link on*/ + speed = rtl8126_convert_link_speed(status); + + if (status & TxFlowCtrl) + advertising |= ADVERTISED_Asym_Pause; + + if (status & RxFlowCtrl) + advertising |= ADVERTISED_Pause; + + duplex = ((status & (_1000bpsF | _2500bpsF | _5000bpsF)) || + (status & FullDup)) ? + DUPLEX_FULL : DUPLEX_HALF; + + /*link partner*/ + if (aner & EXPANSION_NWAY) + lpa_adv |= ADVERTISED_Autoneg; + if (anlpar & LPA_10HALF) + lpa_adv |= ADVERTISED_10baseT_Half; + if (anlpar & LPA_10FULL) + lpa_adv |= ADVERTISED_10baseT_Full; + if (anlpar & LPA_100HALF) + lpa_adv |= ADVERTISED_100baseT_Half; + if (anlpar & LPA_100FULL) + lpa_adv |= ADVERTISED_100baseT_Full; + if (anlpar & LPA_PAUSE_CAP) + lpa_adv |= ADVERTISED_Pause; + if (anlpar & LPA_PAUSE_ASYM) + lpa_adv |= ADVERTISED_Asym_Pause; + if (gbsr & LPA_1000HALF) + lpa_adv |= ADVERTISED_1000baseT_Half; + if (gbsr & LPA_1000FULL) + lpa_adv |= ADVERTISED_1000baseT_Full; + if (status_2500 & RTK_LPA_ADVERTISE_2500FULL) + lpa_adv |= ADVERTISED_2500baseX_Full; + if (status_2500 & RTK_LPA_ADVERTISE_5000FULL) + lpa_adv |= RTK_ADVERTISED_5000baseX_Full; + } else { + /*link down*/ + speed = SPEED_UNKNOWN; + duplex = DUPLEX_UNKNOWN; + lpa_adv = 0; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + cmd->supported = (u32)supported; + cmd->advertising = (u32)advertising; + cmd->autoneg = autoneg; + cmd->speed = speed; + cmd->duplex = duplex; + cmd->port = PORT_TP; + cmd->lp_advertising = (u32)lpa_adv; + cmd->eth_tp_mdix = rtl8126_get_mdi_status(tp); +#else + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, + supported); + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, + advertising); + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, + lpa_adv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) + if (supported & SUPPORTED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.supported, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.supported, 1); + } + if (advertising & ADVERTISED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.advertising, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.advertising, 1); + } + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.supported, 1); + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.advertising, tp->phy_2500_ctrl_reg & RTK_ADVERTISE_5000FULL); + } + if (report_lpa) { + if (lpa_adv & ADVERTISED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.lp_advertising, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.lp_advertising, 1); + } + if (lpa_adv & RTK_ADVERTISED_5000baseX_Full) + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.lp_advertising, 1); + } +#endif + cmd->base.autoneg = autoneg; + cmd->base.speed = speed; + cmd->base.duplex = duplex; + cmd->base.port = PORT_TP; + cmd->base.eth_tp_mdix = rtl8126_get_mdi_status(tp); +#endif +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int +rtl8126_get_settings(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + struct ethtool_link_ksettings *cmd +#endif + ) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + tp->get_settings(dev, cmd); + + return 0; +} + +static void rtl8126_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + unsigned int i; + u8 *data = p; + + if (regs->len < R8126_REGS_DUMP_SIZE) + return /* -EINVAL */; + + memset(p, 0, regs->len); + + for (i = 0; i < R8126_MAC_REGS_SIZE; i++) + *data++ = readb(ioaddr + i); + data = (u8*)p + 256; + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + for (i = 0; i < R8126_PHY_REGS_SIZE/2; i++) { + *(u16*)data = rtl8126_mdio_read(tp, i); + data += 2; + } + data = (u8*)p + 256 * 2; + + for (i = 0; i < R8126_EPHY_REGS_SIZE/2; i++) { + *(u16*)data = rtl8126_ephy_read(tp, i); + data += 2; + } + data = (u8*)p + 256 * 3; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + default: + for (i = 0; i < R8126_ERI_REGS_SIZE; i+=4) { + *(u32*)data = rtl8126_eri_read(tp, i , 4, ERIAR_ExGMAC); + data += 4; + } + break; + } +} + +static void rtl8126_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + pause->autoneg = (tp->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); + if (tp->fcpause == rtl8126_fc_rx_pause) + pause->rx_pause = 1; + else if (tp->fcpause == rtl8126_fc_tx_pause) + pause->tx_pause = 1; + else if (tp->fcpause == rtl8126_fc_full) { + pause->rx_pause = 1; + pause->tx_pause = 1; + } +} + +static int rtl8126_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct rtl8126_private *tp = netdev_priv(dev); + enum rtl8126_fc_mode newfc; + + if (pause->tx_pause || pause->rx_pause) + newfc = rtl8126_fc_full; + else + newfc = rtl8126_fc_none; + + if (tp->fcpause != newfc) { + tp->fcpause = newfc; + + rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + } + + return 0; + +} + +static u32 +rtl8126_get_msglevel(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + return tp->msg_enable; +} + +static void +rtl8126_set_msglevel(struct net_device *dev, + u32 value) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + tp->msg_enable = value; +} + +static const char rtl8126_gstrings[][ETH_GSTRING_LEN] = { + /* legacy */ + "tx_packets", + "rx_packets", + "tx_errors", + "rx_errors", + "rx_missed", + "align_errors", + "tx_single_collisions", + "tx_multi_collisions", + "unicast", + "broadcast", + "multicast", + "tx_aborted", + "tx_underrun", + + /* extended */ + "tx_octets", + "rx_octets", + "rx_multicast64", + "tx_unicast64", + "tx_broadcast64", + "tx_multicast64", + "tx_pause_on", + "tx_pause_off", + "tx_pause_all", + "tx_deferred", + "tx_late_collision", + "tx_all_collision", + "tx_aborted32", + "align_errors32", + "rx_frame_too_long", + "rx_runt", + "rx_pause_on", + "rx_pause_off", + "rx_pause_all", + "rx_unknown_opcode", + "rx_mac_error", + "tx_underrun32", + "rx_mac_missed", + "rx_tcam_dropped", + "tdu", + "rdu", +}; +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int rtl8126_get_stats_count(struct net_device *dev) +{ + return ARRAY_SIZE(rtl8126_gstrings); +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +#else +static int rtl8126_get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return ARRAY_SIZE(rtl8126_gstrings); + default: + return -EOPNOTSUPP; + } +} +#endif + +static void +rtl8126_set_ring_size(struct rtl8126_private *tp, u32 rx, u32 tx) +{ + int i; + + for (i = 0; i < R8126_MAX_RX_QUEUES; i++) + tp->rx_ring[i].num_rx_desc = rx; + + for (i = 0; i < R8126_MAX_TX_QUEUES; i++) + tp->tx_ring[i].num_tx_desc = tx; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +static void rtl8126_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +#else +static void rtl8126_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + ring->rx_max_pending = MAX_NUM_TX_DESC; + ring->tx_max_pending = MAX_NUM_RX_DESC; + ring->rx_pending = tp->rx_ring[0].num_rx_desc; + ring->tx_pending = tp->tx_ring[0].num_tx_desc; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +static int rtl8126_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +#else +static int rtl8126_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 new_rx_count, new_tx_count; + int rc = 0; + + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + + new_tx_count = clamp_t(u32, ring->tx_pending, + MIN_NUM_TX_DESC, MAX_NUM_TX_DESC); + + new_rx_count = clamp_t(u32, ring->rx_pending, + MIN_NUM_RX_DESC, MAX_NUM_RX_DESC); + + if ((new_rx_count == tp->rx_ring[0].num_rx_desc) && + (new_tx_count == tp->tx_ring[0].num_tx_desc)) { + /* nothing to do */ + return 0; + } + + if (netif_running(dev)) { + rtl8126_wait_for_quiescence(dev); + rtl8126_close(dev); + } + + rtl8126_set_ring_size(tp, new_rx_count, new_tx_count); + + if (netif_running(dev)) + rc = rtl8126_open(dev); + + return rc; +} +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static void +rtl8126_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct rtl8126_counters *counters; + dma_addr_t paddr; + + ASSERT_RTNL(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) + return; + + rtl8126_dump_tally_counter(tp, paddr); + + data[0] = le64_to_cpu(counters->tx_packets); + data[1] = le64_to_cpu(counters->rx_packets); + data[2] = le64_to_cpu(counters->tx_errors); + data[3] = le32_to_cpu(counters->rx_errors); + data[4] = le16_to_cpu(counters->rx_missed); + data[5] = le16_to_cpu(counters->align_errors); + data[6] = le32_to_cpu(counters->tx_one_collision); + data[7] = le32_to_cpu(counters->tx_multi_collision); + data[8] = le64_to_cpu(counters->rx_unicast); + data[9] = le64_to_cpu(counters->rx_broadcast); + data[10] = le32_to_cpu(counters->rx_multicast); + data[11] = le16_to_cpu(counters->tx_aborted); + data[12] = le16_to_cpu(counters->tx_underrun); + + data[13] = le64_to_cpu(counters->tx_octets); + data[14] = le64_to_cpu(counters->rx_octets); + data[15] = le64_to_cpu(counters->rx_multicast64); + data[16] = le64_to_cpu(counters->tx_unicast64); + data[17] = le64_to_cpu(counters->tx_broadcast64); + data[18] = le64_to_cpu(counters->tx_multicast64); + data[19] = le32_to_cpu(counters->tx_pause_on); + data[20] = le32_to_cpu(counters->tx_pause_off); + data[21] = le32_to_cpu(counters->tx_pause_all); + data[22] = le32_to_cpu(counters->tx_deferred); + data[23] = le32_to_cpu(counters->tx_late_collision); + data[24] = le32_to_cpu(counters->tx_all_collision); + data[25] = le32_to_cpu(counters->tx_aborted32); + data[26] = le32_to_cpu(counters->align_errors32); + data[27] = le32_to_cpu(counters->rx_frame_too_long); + data[28] = le32_to_cpu(counters->rx_runt); + data[29] = le32_to_cpu(counters->rx_pause_on); + data[30] = le32_to_cpu(counters->rx_pause_off); + data[31] = le32_to_cpu(counters->rx_pause_all); + data[32] = le32_to_cpu(counters->rx_unknown_opcode); + data[33] = le32_to_cpu(counters->rx_mac_error); + data[34] = le32_to_cpu(counters->tx_underrun32); + data[35] = le32_to_cpu(counters->rx_mac_missed); + data[36] = le32_to_cpu(counters->rx_tcam_dropped); + data[37] = le32_to_cpu(counters->tdu); + data[38] = le32_to_cpu(counters->rdu); +} + +static void +rtl8126_get_strings(struct net_device *dev, + u32 stringset, + u8 *data) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(data, rtl8126_gstrings, sizeof(rtl8126_gstrings)); + break; + } +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static int rtl_get_eeprom_len(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + return tp->eeprom_len; +} + +static int rtl_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *buf) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i,j,ret; + int start_w, end_w; + int VPD_addr, VPD_data; + u32 *eeprom_buff; + u16 tmp; + + if (tp->eeprom_type == EEPROM_TYPE_NONE) { + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Detect none EEPROM\n"); + return -EOPNOTSUPP; + } else if (eeprom->len == 0 || (eeprom->offset+eeprom->len) > tp->eeprom_len) { + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Invalid parameter\n"); + return -EINVAL; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + default: + VPD_addr = 0xD2; + VPD_data = 0xD4; + break; + } + + start_w = eeprom->offset >> 2; + end_w = (eeprom->offset + eeprom->len - 1) >> 2; + + eeprom_buff = kmalloc(sizeof(u32)*(end_w - start_w + 1), GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + rtl8126_enable_cfg9346_write(tp); + ret = -EFAULT; + for (i=start_w; i<=end_w; i++) { + pci_write_config_word(tp->pci_dev, VPD_addr, (u16)i*4); + ret = -EFAULT; + for (j = 0; j < 10; j++) { + udelay(400); + pci_read_config_word(tp->pci_dev, VPD_addr, &tmp); + if (tmp&0x8000) { + ret = 0; + break; + } + } + + if (ret) + break; + + pci_read_config_dword(tp->pci_dev, VPD_data, &eeprom_buff[i-start_w]); + } + rtl8126_disable_cfg9346_write(tp); + + if (!ret) + memcpy(buf, (u8 *)eeprom_buff + (eeprom->offset & 3), eeprom->len); + + kfree(eeprom_buff); + + return ret; +} + +#undef ethtool_op_get_link +#define ethtool_op_get_link _kc_ethtool_op_get_link +static u32 _kc_ethtool_op_get_link(struct net_device *dev) +{ + return netif_carrier_ok(dev) ? 1 : 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#undef ethtool_op_get_sg +#define ethtool_op_get_sg _kc_ethtool_op_get_sg +static u32 _kc_ethtool_op_get_sg(struct net_device *dev) +{ +#ifdef NETIF_F_SG + return (dev->features & NETIF_F_SG) != 0; +#else + return 0; +#endif +} + +#undef ethtool_op_set_sg +#define ethtool_op_set_sg _kc_ethtool_op_set_sg +static int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + +#ifdef NETIF_F_SG + if (data) + dev->features |= NETIF_F_SG; + else + dev->features &= ~NETIF_F_SG; +#endif + + return 0; +} +#endif + +static void +rtl8126_set_eee_lpi_timer(struct rtl8126_private *tp) +{ + u16 dev_lpi_timer; + + dev_lpi_timer = tp->eee.tx_lpi_timer; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + RTL_W16(tp, EEE_TXIDLE_TIMER_8125, dev_lpi_timer); + break; + default: + break; + } +} + +static bool rtl8126_is_adv_eee_enabled(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + if (rtl8126_mdio_direct_read_phy_ocp(tp, 0xA430) & BIT_15) + return true; + break; + default: + break; + } + + return false; +} + +static void rtl8126_disable_adv_eee(struct rtl8126_private *tp) +{ + bool lock; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + break; + default: + return; + } + + if (rtl8126_is_adv_eee_enabled(tp)) + lock = true; + else + lock = false; + + if (lock) + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_clear_mac_ocp_bit(tp, 0xE052, BIT_0); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA442, BIT_12 | BIT_13); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA430, BIT_15); + + if (lock) + rtl8126_clear_phy_mcu_patch_request(tp); +} + +static int rtl8126_enable_eee(struct rtl8126_private *tp) +{ + struct ethtool_eee *eee = &tp->eee; + u16 eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_set_mac_ocp_bit(tp, 0xE040, (BIT_1|BIT_0)); + + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA5D0, + MDIO_EEE_100TX | MDIO_EEE_1000T, + eee_adv_t); + if (eee->advertised & SUPPORTED_2500baseX_Full) + rtl8126_set_eth_phy_ocp_bit(tp, 0xA6D4, MDIO_EEE_2_5GT); + else + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D4, MDIO_EEE_2_5GT); + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D4, MDIO_EEE_5GT); + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D8, BIT_4); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA428, BIT_7); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA4A2, BIT_9); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + /*Advanced EEE*/ + rtl8126_disable_adv_eee(tp); + + return ret; +} + +static int rtl8126_disable_eee(struct rtl8126_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_clear_mac_ocp_bit(tp, 0xE040, (BIT_1|BIT_0)); + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA5D0, (MDIO_EEE_100TX | MDIO_EEE_1000T)); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D4, MDIO_EEE_2_5GT); + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D4, MDIO_EEE_5GT); + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA6D8, BIT_4); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA428, BIT_7); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA4A2, BIT_9); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + /*Advanced EEE*/ + rtl8126_disable_adv_eee(tp); + + return ret; +} + +static int rtl_nway_reset(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret, bmcr; + + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; + + /* if autoneg is off, it's an error */ + rtl8126_mdio_write(tp, 0x1F, 0x0000); + bmcr = rtl8126_mdio_read(tp, MII_BMCR); + + if (bmcr & BMCR_ANENABLE) { + bmcr |= BMCR_ANRESTART; + rtl8126_mdio_write(tp, MII_BMCR, bmcr); + ret = 0; + } else { + ret = -EINVAL; + } + + return ret; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) +static u32 +rtl8126_device_lpi_t_to_ethtool_lpi_t(struct rtl8126_private *tp , u32 lpi_timer) +{ + u32 to_us; + u16 status; + + to_us = lpi_timer * 80; + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus) { + /*link on*/ + if (HW_SUPP_PHY_LINK_SPEED_5000M(tp)) { + //5G : lpi_timer * 12.8ns + //2.5G : lpi_timer * 25.6ns + //Giga: lpi_timer * 8ns + //100M : lpi_timer * 80ns + if (status & (_5000bpsF)) + to_us = (lpi_timer * 128) / 10; + else if (status & _2500bpsF) + to_us = (lpi_timer * 256) / 10; + else if (status & _1000bpsF) + to_us = lpi_timer * 8; + } else { + //2.5G : lpi_timer * 3.2ns + //Giga: lpi_timer * 8ns + //100M : lpi_timer * 80ns + if (status & _2500bpsF) + to_us = (lpi_timer * 32) / 10; + else if (status & _1000bpsF) + to_us = lpi_timer * 8; + } + } + + //ns to us + to_us /= 1000; + + return to_us; +} + +static int +rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8126_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 lp, adv, tx_lpi_timer, supported = 0; + u16 val; + + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; + + /* Get Supported EEE */ + //val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5C4); + //supported = mmd_eee_cap_to_ethtool_sup_t(val); + supported = eee->supported; + + /* Get advertisement EEE */ + adv = eee->advertised; + + /* Get LP advertisement EEE */ + val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA5D2); + lp = mmd_eee_adv_to_ethtool_adv_t(val); + val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA6D0); + if (val & RTK_LPA_EEE_ADVERTISE_2500FULL) + lp |= ADVERTISED_2500baseX_Full; + + /* Get EEE Tx LPI timer*/ + tx_lpi_timer = rtl8126_device_lpi_t_to_ethtool_lpi_t(tp, eee->tx_lpi_timer); + + val = rtl8126_mac_ocp_read(tp, 0xE040); + val &= BIT_1 | BIT_0; + + edata->eee_enabled = !!val; + edata->eee_active = !!(supported & adv & lp); + edata->supported = supported; + edata->advertised = adv; + edata->lp_advertised = lp; + edata->tx_lpi_enabled = edata->eee_enabled; + edata->tx_lpi_timer = tx_lpi_timer; + + return 0; +} + +static int +rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8126_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 advertising; + int rc = 0; + + if (!HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp) || + tp->DASH) + return -EOPNOTSUPP; + + if (unlikely(tp->rtk_enable_diag)) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "Diag Enabled\n"); + rc = -EBUSY; + goto out; + } + + if (tp->autoneg != AUTONEG_ENABLE) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE requires autoneg\n"); + rc = -EINVAL; + goto out; + } + + /* + if (edata->tx_lpi_enabled) { + if (edata->tx_lpi_timer > tp->max_jumbo_frame_size || + edata->tx_lpi_timer < ETH_MIN_MTU) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "Valid LPI timer range is %d to %d. \n", + ETH_MIN_MTU, tp->max_jumbo_frame_size); + rc = -EINVAL; + goto out; + } + } + */ + + advertising = tp->advertising; + if (!edata->advertised) { + edata->advertised = advertising & eee->supported; + } else if (edata->advertised & ~advertising) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of autoneg advertised speeds %x\n", + edata->advertised, advertising); + rc = -EINVAL; + goto out; + } + + if (edata->advertised & ~eee->supported) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of support %x\n", + edata->advertised, eee->supported); + rc = -EINVAL; + goto out; + } + + //tp->eee.eee_enabled = edata->eee_enabled; + //tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(edata->advertised); + + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE tx_lpi_timer %x must be a subset of support %x\n", + edata->tx_lpi_timer, eee->tx_lpi_timer); + + eee->advertised = edata->advertised; + //eee->tx_lpi_enabled = edata->tx_lpi_enabled; + //eee->tx_lpi_timer = edata->tx_lpi_timer; + eee->eee_enabled = edata->eee_enabled; + + if (eee->eee_enabled) + rtl8126_enable_eee(tp); + else + rtl8126_disable_eee(tp); + + rtl_nway_reset(net); + + return rc; + +out: + + return rc; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static const struct ethtool_ops rtl8126_ethtool_ops = { + .get_drvinfo = rtl8126_get_drvinfo, + .get_regs_len = rtl8126_get_regs_len, + .get_link = ethtool_op_get_link, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_ringparam = rtl8126_get_ringparam, + .set_ringparam = rtl8126_set_ringparam, +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + .get_settings = rtl8126_get_settings, + .set_settings = rtl8126_set_settings, +#else + .get_link_ksettings = rtl8126_get_settings, + .set_link_ksettings = rtl8126_set_settings, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_pauseparam = rtl8126_get_pauseparam, + .set_pauseparam = rtl8126_set_pauseparam, +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_msglevel = rtl8126_get_msglevel, + .set_msglevel = rtl8126_set_msglevel, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + .get_rx_csum = rtl8126_get_rx_csum, + .set_rx_csum = rtl8126_set_rx_csum, + .get_tx_csum = rtl8126_get_tx_csum, + .set_tx_csum = rtl8126_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, +#endif //NETIF_F_TSO +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + .get_regs = rtl8126_get_regs, + .get_wol = rtl8126_get_wol, + .set_wol = rtl8126_set_wol, + .get_strings = rtl8126_get_strings, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + .get_stats_count = rtl8126_get_stats_count, +#else + .get_sset_count = rtl8126_get_sset_count, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + .get_ethtool_stats = rtl8126_get_ethtool_stats, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +#ifdef ETHTOOL_GPERMADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif //ETHTOOL_GPERMADDR +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) + .get_eeprom = rtl_get_eeprom, + .get_eeprom_len = rtl_get_eeprom_len, +#ifdef ENABLE_RSS_SUPPORT + .get_rxnfc = rtl8126_get_rxnfc, + .set_rxnfc = rtl8126_set_rxnfc, + .get_rxfh_indir_size = rtl8126_rss_indir_size, + .get_rxfh_key_size = rtl8126_get_rxfh_key_size, + .get_rxfh = rtl8126_get_rxfh, + .set_rxfh = rtl8126_set_rxfh, +#endif //ENABLE_RSS_SUPPORT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#ifdef ENABLE_PTP_SUPPORT + .get_ts_info = rtl8126_get_ts_info, +#else + .get_ts_info = ethtool_op_get_ts_info, +#endif //ENABLE_PTP_SUPPORT +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) + .get_eee = rtl_ethtool_get_eee, + .set_eee = rtl_ethtool_set_eee, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + .nway_reset = rtl_nway_reset, + +}; +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static void rtl8126_get_mac_version(struct rtl8126_private *tp) +{ + u32 reg,val32; + u32 ICVerID; + + val32 = RTL_R32(tp, TxConfig); + reg = val32 & 0x7c800000; + ICVerID = val32 & 0x00700000; + + switch (reg) { + case 0x64800000: + if (ICVerID == 0x00000000) { + tp->mcfg = CFG_METHOD_1; + } else if (ICVerID == 0x100000) { + tp->mcfg = CFG_METHOD_2; + } else if (ICVerID == 0x200000) { + tp->mcfg = CFG_METHOD_3; + } else { + tp->mcfg = CFG_METHOD_3; + tp->HwIcVerUnknown = TRUE; + } + + tp->efuse_ver = EFUSE_SUPPORT_V4; + break; + default: + printk("unknown chip version (%x)\n",reg); + tp->mcfg = CFG_METHOD_DEFAULT; + tp->HwIcVerUnknown = TRUE; + tp->efuse_ver = EFUSE_NOT_SUPPORT; + break; + } +} + +static void +rtl8126_print_mac_version(struct rtl8126_private *tp) +{ + int i; + for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { + if (tp->mcfg == rtl_chip_info[i].mcfg) { + dprintk("Realtek %s Ethernet controller mcfg = %04d\n", + MODULENAME, rtl_chip_info[i].mcfg); + return; + } + } + + dprintk("mac_version == Unknown\n"); +} + +static void +rtl8126_tally_counter_addr_fill(struct rtl8126_private *tp) +{ + if (!tp->tally_paddr) + return; + + RTL_W32(tp, CounterAddrHigh, (u64)tp->tally_paddr >> 32); + RTL_W32(tp, CounterAddrLow, (u64)tp->tally_paddr & (DMA_BIT_MASK(32))); +} + +static void +rtl8126_tally_counter_clear(struct rtl8126_private *tp) +{ + if (!tp->tally_paddr) + return; + + RTL_W32(tp, CounterAddrHigh, (u64)tp->tally_paddr >> 32); + RTL_W32(tp, CounterAddrLow, ((u64)tp->tally_paddr & (DMA_BIT_MASK(32))) | CounterReset); +} + +static void +rtl8126_clear_phy_ups_reg(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA466, BIT_0); + break; + }; + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA468, BIT_3 | BIT_1); +} + +static int +rtl8126_is_ups_resume(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + return (rtl8126_mac_ocp_read(tp, 0xD42C) & BIT_8); + default: + return 0; + }; +} + +static void +rtl8126_clear_ups_resume_bit(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + rtl8126_clear_mac_ocp_bit(tp, 0xD42C, BIT_8); + break; + default: + return; + }; +} + +static u8 +rtl8126_get_phy_state(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + return (rtl8126_mdio_direct_read_phy_ocp(tp, 0xA420) & 0x7); + default: + return 0xff; + }; +} + +static void +rtl8126_wait_phy_ups_resume(struct net_device *dev, u16 PhyState) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + for (i=0; i< 100; i++) { + if (rtl8126_get_phy_state(tp) == PhyState) + break; + else + mdelay(1); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(i == 100); +#endif + break; + default: + break; + }; +} + +void +rtl8126_enable_now_is_oob(struct rtl8126_private *tp) +{ + if (tp->HwSuppNowIsOobVer == 1) + RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) | Now_is_oob); +} + +void +rtl8126_disable_now_is_oob(struct rtl8126_private *tp) +{ + if (tp->HwSuppNowIsOobVer == 1) + RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) & ~Now_is_oob); +} + +static void +rtl8126_exit_oob(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u16 data16; + + rtl8126_disable_rx_packet_filter(tp); + + if (HW_DASH_SUPPORT_DASH(tp)) { + rtl8126_driver_start(tp); + rtl8126_dash2_disable_txrx(dev); +#ifdef ENABLE_DASH_SUPPORT + DashHwInit(dev); +#endif + } + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8126_realwow_hw_init(dev); +#else + //Disable realwow function + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xC0BC, 0x00FF); + break; + } +#endif //ENABLE_REALWOW_SUPPORT + + rtl8126_nic_reset(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_disable_now_is_oob(tp); + + data16 = rtl8126_mac_ocp_read(tp, 0xE8DE) & ~BIT_14; + rtl8126_mac_ocp_write(tp, 0xE8DE, data16); + rtl8126_wait_ll_share_fifo_ready(dev); + + rtl8126_mac_ocp_write(tp, 0xC0AA, 0x07D0); +#ifdef ENABLE_LIB_SUPPORT + rtl8126_mac_ocp_write(tp, 0xC0A6, 0x04E2); +#else + rtl8126_mac_ocp_write(tp, 0xC0A6, 0x01B5); +#endif + rtl8126_mac_ocp_write(tp, 0xC01E, 0x5555); + + rtl8126_wait_ll_share_fifo_ready(dev); + break; + } + + //wait ups resume (phy state 2) + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + if (rtl8126_is_ups_resume(dev)) { + rtl8126_wait_phy_ups_resume(dev, 2); + rtl8126_clear_ups_resume_bit(dev); + rtl8126_clear_phy_ups_reg(dev); + } + break; + }; +} + +void +rtl8126_hw_disable_mac_mcu_bps(struct net_device *dev) +{ + u16 regAddr; + + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_aspm_clkreq_lock(tp, 0); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xFC48, 0x0000); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + for (regAddr = 0xFC28; regAddr < 0xFC48; regAddr += 2) { + rtl8126_mac_ocp_write(tp, regAddr, 0x0000); + } + + mdelay(3); + + rtl8126_mac_ocp_write(tp, 0xFC26, 0x0000); + break; + } +} + +#ifndef ENABLE_USE_FIRMWARE_FILE +static void +rtl8126_switch_mac_mcu_ram_code_page(struct rtl8126_private *tp, u16 page) +{ + u16 tmpUshort; + + page &= (BIT_1 | BIT_0); + tmpUshort = rtl8126_mac_ocp_read(tp, 0xE446); + tmpUshort &= ~(BIT_1 | BIT_0); + tmpUshort |= page; + rtl8126_mac_ocp_write(tp, 0xE446, tmpUshort); +} + +static void +_rtl8126_write_mac_mcu_ram_code(struct rtl8126_private *tp, const u16 *entry, u16 entry_cnt) +{ + u16 i; + + for (i = 0; i < entry_cnt; i++) { + rtl8126_mac_ocp_write(tp, 0xF800 + i * 2, entry[i]); + } +} + +static void +_rtl8126_write_mac_mcu_ram_code_with_page(struct rtl8126_private *tp, const u16 *entry, u16 entry_cnt, u16 page_size) +{ + u16 i; + u16 offset; + + if (page_size == 0) + return; + + for (i = 0; i < entry_cnt; i++) { + offset = i % page_size; + if (offset == 0) { + u16 page = (i / page_size); + rtl8126_switch_mac_mcu_ram_code_page(tp, page); + } + rtl8126_mac_ocp_write(tp, 0xF800 + offset * 2, entry[i]); + } +} + +static void +rtl8126_write_mac_mcu_ram_code(struct rtl8126_private *tp, const u16 *entry, u16 entry_cnt) +{ + if (FALSE == HW_SUPPORT_MAC_MCU(tp)) + return; + + if (entry == NULL || entry_cnt == 0) + return; + + if (tp->MacMcuPageSize > 0) + _rtl8126_write_mac_mcu_ram_code_with_page(tp, entry, entry_cnt, tp->MacMcuPageSize); + else + _rtl8126_write_mac_mcu_ram_code(tp, entry, entry_cnt); +} + +static void +rtl8126_set_mac_mcu_8126a_1(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + static const u16 mcu_patch_code_8126a_1[] = { + 0xE010, 0xE019, 0xE01B, 0xE01D, 0xE01F, 0xE021, 0xE023, 0xE025, 0xE027, + 0xE029, 0xE02B, 0xE02D, 0xE02F, 0xE031, 0xE033, 0xE035, 0x48C0, 0x9C66, + 0x7446, 0x4840, 0x48C1, 0x48C2, 0x9C46, 0xC402, 0xBC00, 0x0AD6, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000 + }; + + rtl8126_hw_disable_mac_mcu_bps(dev); + + rtl8126_write_mac_mcu_ram_code(tp, mcu_patch_code_8126a_1, ARRAY_SIZE(mcu_patch_code_8126a_1)); + + rtl8126_mac_ocp_write(tp, 0xFC26, 0x8000); + + rtl8126_mac_ocp_write(tp, 0xFC28, 0x0AAA); + + rtl8126_mac_ocp_write(tp, 0xFC48, 0x0001); +} + +static void +rtl8126_set_mac_mcu_8126a_2(struct net_device *dev) +{ + rtl8126_hw_disable_mac_mcu_bps(dev); +} + +static void +rtl8126_set_mac_mcu_8126a_3(struct net_device *dev) +{ + rtl8126_hw_disable_mac_mcu_bps(dev); +} + +static void +rtl8126_hw_mac_mcu_config(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->NotWrMcuPatchCode == TRUE) + return; + + switch (tp->mcfg) { + case CFG_METHOD_1: + rtl8126_set_mac_mcu_8126a_1(dev); + break; + case CFG_METHOD_2: + rtl8126_set_mac_mcu_8126a_2(dev); + break; + case CFG_METHOD_3: + rtl8126_set_mac_mcu_8126a_3(dev); + break; + } +} +#endif + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void rtl8126_release_firmware(struct rtl8126_private *tp) +{ + if (tp->rtl_fw) { + rtl8126_fw_release_firmware(tp->rtl_fw); + kfree(tp->rtl_fw); + tp->rtl_fw = NULL; + } +} + +void rtl8126_apply_firmware(struct rtl8126_private *tp) +{ + /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ + if (tp->rtl_fw) { + rtl8126_fw_write_firmware(tp, tp->rtl_fw); + /* At least one firmware doesn't reset tp->ocp_base. */ + tp->ocp_base = OCP_STD_PHY_BASE; + + /* PHY soft reset may still be in progress */ + //phy_read_poll_timeout(tp->phydev, MII_BMCR, val, + // !(val & BMCR_RESET), + // 50000, 600000, true); + rtl8126_wait_phy_reset_complete(tp); + + tp->hw_ram_code_ver = rtl8126_get_hw_phy_mcu_code_ver(tp); + tp->sw_ram_code_ver = tp->hw_ram_code_ver; + tp->HwHasWrRamCodeToMicroP = TRUE; + } +} +#endif + +static void +rtl8126_hw_init(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_aspm_clkreq_lock(tp, 0); + rtl8126_enable_force_clkreq(tp, 0); + break; + } + + //Disable UPS + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xD40A, rtl8126_mac_ocp_read(tp, 0xD40A) & ~(BIT_4)); + break; + } + +#ifndef ENABLE_USE_FIRMWARE_FILE + if (!tp->rtl_fw) + rtl8126_hw_mac_mcu_config(dev); +#endif + + //Set PCIE uncorrectable error status mask pcie 0x108 + csi_tmp = rtl8126_csi_read(tp, 0x108); + csi_tmp |= BIT_20; + rtl8126_csi_write(tp, 0x108, csi_tmp); + + rtl8126_enable_cfg9346_write(tp); + rtl8126_disable_linkchg_wakeup(dev); + rtl8126_disable_cfg9346_write(tp); + rtl8126_disable_magic_packet(dev); + rtl8126_disable_d0_speedup(tp); + rtl8126_set_pci_pme(tp, 0); + if (s0_magic_packet == 1) + rtl8126_enable_magic_packet(dev); + +#ifdef ENABLE_USE_FIRMWARE_FILE + if (tp->rtl_fw && + !tp->resume_not_chg_speed && + !(HW_DASH_SUPPORT_TYPE_3(tp) && + tp->HwPkgDet == 0x06)) + rtl8126_apply_firmware(tp); +#endif +} + +static void +rtl8126_hw_ephy_config(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + /* nothing to do */ + break; + } +} + +static u16 +rtl8126_get_hw_phy_mcu_code_ver(struct rtl8126_private *tp) +{ + u16 hw_ram_code_ver = ~0; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x801E); + hw_ram_code_ver = rtl8126_mdio_direct_read_phy_ocp(tp, 0xA438); + break; + } + + return hw_ram_code_ver; +} + +static int +rtl8126_check_hw_phy_mcu_code_ver(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ram_code_ver_match = 0; + + tp->hw_ram_code_ver = rtl8126_get_hw_phy_mcu_code_ver(tp); + + if (tp->hw_ram_code_ver == tp->sw_ram_code_ver) { + ram_code_ver_match = 1; + tp->HwHasWrRamCodeToMicroP = TRUE; + } + + return ram_code_ver_match; +} + +bool +rtl8126_set_phy_mcu_patch_request(struct rtl8126_private *tp) +{ + u16 gphy_val; + u16 WaitCount; + bool bSuccess = TRUE; + + rtl8126_set_eth_phy_ocp_bit(tp, 0xB820, BIT_4); + + WaitCount = 0; + do { + gphy_val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xB800); + udelay(100); + WaitCount++; + } while (!(gphy_val & BIT_6) && (WaitCount < 1000)); + + if (!(gphy_val & BIT_6) && (WaitCount == 1000)) + bSuccess = FALSE; + + if (!bSuccess) + dprintk("rtl8126_set_phy_mcu_patch_request fail.\n"); + + return bSuccess; +} + +bool +rtl8126_clear_phy_mcu_patch_request(struct rtl8126_private *tp) +{ + u16 gphy_val; + u16 WaitCount; + bool bSuccess = TRUE; + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xB820, BIT_4); + + WaitCount = 0; + do { + gphy_val = rtl8126_mdio_direct_read_phy_ocp(tp, 0xB800); + udelay(100); + WaitCount++; + } while ((gphy_val & BIT_6) && (WaitCount < 1000)); + + if ((gphy_val & BIT_6) && (WaitCount == 1000)) + bSuccess = FALSE; + + if (!bSuccess) + dprintk("rtl8126_clear_phy_mcu_patch_request fail.\n"); + + return bSuccess; +} + +#ifndef ENABLE_USE_FIRMWARE_FILE +static void +rtl8126_write_hw_phy_mcu_code_ver(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x801E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, tp->sw_ram_code_ver); + tp->hw_ram_code_ver = tp->sw_ram_code_ver; + break; + } +} + +static void +rtl8126_set_phy_mcu_ram_code(struct net_device *dev, const u16 *ramcode, u16 codesize) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u16 i; + u16 addr; + u16 val; + + if (ramcode == NULL || codesize % 2) { + goto out; + } + + for (i = 0; i < codesize; i += 2) { + addr = ramcode[i]; + val = ramcode[i + 1]; + if (addr == 0xFFFF && val == 0xFFFF) { + break; + } + rtl8126_mdio_direct_write_phy_ocp(tp, addr, val); + } + +out: + return; +} + +static void +rtl8126_enable_phy_disable_mode(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) | BIT_5); + break; + } + + dprintk("enable phy disable mode.\n"); +} + +static void +rtl8126_disable_phy_disable_mode(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_5); + break; + } + + mdelay(1); + + dprintk("disable phy disable mode.\n"); +} + +static const u16 phy_mcu_ram_code_8126a_1_1[] = { + 0xa436, 0x8023, 0xa438, 0x4900, 0xa436, 0xB82E, 0xa438, 0x0001, + 0xBFBA, 0xE000, 0xBF1A, 0xC1B9, 0xBFA8, 0x10F0, 0xBFB0, 0x0210, + 0xBFB4, 0xE7E4, 0xb820, 0x0090, 0xa436, 0xA016, 0xa438, 0x0000, + 0xa436, 0xA012, 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, + 0xa438, 0x8010, 0xa438, 0x1800, 0xa438, 0x8062, 0xa438, 0x1800, + 0xa438, 0x8069, 0xa438, 0x1800, 0xa438, 0x80e2, 0xa438, 0x1800, + 0xa438, 0x80eb, 0xa438, 0x1800, 0xa438, 0x80f5, 0xa438, 0x1800, + 0xa438, 0x811b, 0xa438, 0x1800, 0xa438, 0x8120, 0xa438, 0xd500, + 0xa438, 0xd049, 0xa438, 0xd1b9, 0xa438, 0xa208, 0xa438, 0x8208, + 0xa438, 0xd503, 0xa438, 0xa104, 0xa438, 0x0c07, 0xa438, 0x0902, + 0xa438, 0xd500, 0xa438, 0xbc10, 0xa438, 0xc484, 0xa438, 0xd503, + 0xa438, 0xcc02, 0xa438, 0xcd0d, 0xa438, 0xaf01, 0xa438, 0xd500, + 0xa438, 0xd703, 0xa438, 0x4531, 0xa438, 0xbd08, 0xa438, 0x1000, + 0xa438, 0x16bb, 0xa438, 0xd75e, 0xa438, 0x5fb3, 0xa438, 0xd503, + 0xa438, 0xd04d, 0xa438, 0xd1c7, 0xa438, 0x0cf0, 0xa438, 0x0e10, + 0xa438, 0xd704, 0xa438, 0x5ffc, 0xa438, 0xd04d, 0xa438, 0xd1c7, + 0xa438, 0x0cf0, 0xa438, 0x0e20, 0xa438, 0xd704, 0xa438, 0x5ffc, + 0xa438, 0xd04d, 0xa438, 0xd1c7, 0xa438, 0x0cf0, 0xa438, 0x0e40, + 0xa438, 0xd704, 0xa438, 0x5ffc, 0xa438, 0xd04d, 0xa438, 0xd1c7, + 0xa438, 0x0cf0, 0xa438, 0x0e80, 0xa438, 0xd704, 0xa438, 0x5ffc, + 0xa438, 0xd07b, 0xa438, 0xd1c5, 0xa438, 0x8ef0, 0xa438, 0xd704, + 0xa438, 0x5ffc, 0xa438, 0x9d08, 0xa438, 0x1000, 0xa438, 0x16bb, + 0xa438, 0xd75e, 0xa438, 0x7fb3, 0xa438, 0x1000, 0xa438, 0x16bb, + 0xa438, 0xd75e, 0xa438, 0x5fad, 0xa438, 0x1000, 0xa438, 0x181f, + 0xa438, 0xd703, 0xa438, 0x3181, 0xa438, 0x8059, 0xa438, 0x60ad, + 0xa438, 0x1000, 0xa438, 0x16bb, 0xa438, 0xd703, 0xa438, 0x5fbb, + 0xa438, 0x1000, 0xa438, 0x16bb, 0xa438, 0xd719, 0xa438, 0x7fa8, + 0xa438, 0xd500, 0xa438, 0xd049, 0xa438, 0xd1b9, 0xa438, 0x1800, + 0xa438, 0x0f0b, 0xa438, 0xd500, 0xa438, 0xd07b, 0xa438, 0xd1b5, + 0xa438, 0xd0f6, 0xa438, 0xd1c5, 0xa438, 0x1800, 0xa438, 0x1049, + 0xa438, 0xd707, 0xa438, 0x4121, 0xa438, 0xd706, 0xa438, 0x40fa, + 0xa438, 0xd099, 0xa438, 0xd1c6, 0xa438, 0x1000, 0xa438, 0x16bb, + 0xa438, 0xd704, 0xa438, 0x5fbc, 0xa438, 0xbc80, 0xa438, 0xc489, + 0xa438, 0xd503, 0xa438, 0xcc08, 0xa438, 0xcd46, 0xa438, 0xaf01, + 0xa438, 0xd500, 0xa438, 0x1000, 0xa438, 0x0903, 0xa438, 0x1000, + 0xa438, 0x16bb, 0xa438, 0xd75e, 0xa438, 0x5f6d, 0xa438, 0x1000, + 0xa438, 0x181f, 0xa438, 0xd504, 0xa438, 0xa210, 0xa438, 0xd500, + 0xa438, 0x1000, 0xa438, 0x16bb, 0xa438, 0xd719, 0xa438, 0x5fbc, + 0xa438, 0xd504, 0xa438, 0x8210, 0xa438, 0xd503, 0xa438, 0xc6d0, + 0xa438, 0xa521, 0xa438, 0xcd49, 0xa438, 0xaf01, 0xa438, 0xd504, + 0xa438, 0xa220, 0xa438, 0xd500, 0xa438, 0x1000, 0xa438, 0x16bb, + 0xa438, 0xd75e, 0xa438, 0x5fad, 0xa438, 0x1000, 0xa438, 0x181f, + 0xa438, 0xd503, 0xa438, 0xa704, 0xa438, 0x0c07, 0xa438, 0x0904, + 0xa438, 0xd504, 0xa438, 0xa102, 0xa438, 0xd500, 0xa438, 0x1000, + 0xa438, 0x16bb, 0xa438, 0xd718, 0xa438, 0x5fab, 0xa438, 0xd503, + 0xa438, 0xc6f0, 0xa438, 0xa521, 0xa438, 0xd505, 0xa438, 0xa404, + 0xa438, 0xd500, 0xa438, 0xd701, 0xa438, 0x6085, 0xa438, 0xd504, + 0xa438, 0xc9f1, 0xa438, 0xf003, 0xa438, 0xd504, 0xa438, 0xc9f0, + 0xa438, 0xd503, 0xa438, 0xcd4a, 0xa438, 0xaf01, 0xa438, 0xd500, + 0xa438, 0xd504, 0xa438, 0xa802, 0xa438, 0xd500, 0xa438, 0x1000, + 0xa438, 0x16bb, 0xa438, 0xd707, 0xa438, 0x5fb1, 0xa438, 0xd707, + 0xa438, 0x5f10, 0xa438, 0xd505, 0xa438, 0xa402, 0xa438, 0xd503, + 0xa438, 0xd707, 0xa438, 0x41a1, 0xa438, 0xd706, 0xa438, 0x60ba, + 0xa438, 0x60fc, 0xa438, 0x0c07, 0xa438, 0x0204, 0xa438, 0xf009, + 0xa438, 0x0c07, 0xa438, 0x0202, 0xa438, 0xf006, 0xa438, 0x0c07, + 0xa438, 0x0206, 0xa438, 0xf003, 0xa438, 0x0c07, 0xa438, 0x0202, + 0xa438, 0xd500, 0xa438, 0xd703, 0xa438, 0x3181, 0xa438, 0x80e0, + 0xa438, 0x616d, 0xa438, 0xd701, 0xa438, 0x6065, 0xa438, 0x1800, + 0xa438, 0x1229, 0xa438, 0x1000, 0xa438, 0x16bb, 0xa438, 0xd707, + 0xa438, 0x6061, 0xa438, 0xd704, 0xa438, 0x5f7c, 0xa438, 0x1800, + 0xa438, 0x124a, 0xa438, 0xd504, 0xa438, 0x8c0f, 0xa438, 0xd505, + 0xa438, 0xa20e, 0xa438, 0xd500, 0xa438, 0x1000, 0xa438, 0x1871, + 0xa438, 0x1800, 0xa438, 0x1899, 0xa438, 0xd70b, 0xa438, 0x60b0, + 0xa438, 0xd05a, 0xa438, 0xd19a, 0xa438, 0x1800, 0xa438, 0x1aef, + 0xa438, 0xd0ef, 0xa438, 0xd19a, 0xa438, 0x1800, 0xa438, 0x1aef, + 0xa438, 0x1000, 0xa438, 0x1d09, 0xa438, 0xd708, 0xa438, 0x3399, + 0xa438, 0x1b63, 0xa438, 0xd709, 0xa438, 0x5f5d, 0xa438, 0xd70b, + 0xa438, 0x6130, 0xa438, 0xd70d, 0xa438, 0x6163, 0xa438, 0xd709, + 0xa438, 0x430b, 0xa438, 0xd71e, 0xa438, 0x62c2, 0xa438, 0xb401, + 0xa438, 0xf014, 0xa438, 0xc901, 0xa438, 0x1000, 0xa438, 0x810e, + 0xa438, 0xf010, 0xa438, 0xc902, 0xa438, 0x1000, 0xa438, 0x810e, + 0xa438, 0xf00c, 0xa438, 0xce04, 0xa438, 0xcf01, 0xa438, 0xd70a, + 0xa438, 0x5fe2, 0xa438, 0xce04, 0xa438, 0xcf02, 0xa438, 0xc900, + 0xa438, 0xd70a, 0xa438, 0x4057, 0xa438, 0xb401, 0xa438, 0x0800, + 0xa438, 0x1800, 0xa438, 0x1b5d, 0xa438, 0xa480, 0xa438, 0xa2b0, + 0xa438, 0xa806, 0xa438, 0x1800, 0xa438, 0x225c, 0xa438, 0xa7e8, + 0xa438, 0xac08, 0xa438, 0x1800, 0xa438, 0x1a4e, 0xa436, 0xA026, + 0xa438, 0x1a4d, 0xa436, 0xA024, 0xa438, 0x225a, 0xa436, 0xA022, + 0xa438, 0x1b53, 0xa436, 0xA020, 0xa438, 0x1aed, 0xa436, 0xA006, + 0xa438, 0x1892, 0xa436, 0xA004, 0xa438, 0x11a4, 0xa436, 0xA002, + 0xa438, 0x103c, 0xa436, 0xA000, 0xa438, 0x0ea6, 0xa436, 0xA008, + 0xa438, 0xff00, 0xa436, 0xA016, 0xa438, 0x0000, 0xa436, 0xA012, + 0xa438, 0x0ff8, 0xa436, 0xA014, 0xa438, 0x0000, 0xa438, 0xD098, + 0xa438, 0xc483, 0xa438, 0xc483, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa436, 0xA152, 0xa438, 0x3fff, + 0xa436, 0xA154, 0xa438, 0x0413, 0xa436, 0xA156, 0xa438, 0x1A32, + 0xa436, 0xA158, 0xa438, 0x1CC0, 0xa436, 0xA15A, 0xa438, 0x3fff, + 0xa436, 0xA15C, 0xa438, 0x3fff, 0xa436, 0xA15E, 0xa438, 0x3fff, + 0xa436, 0xA160, 0xa438, 0x3fff, 0xa436, 0xA150, 0xa438, 0x000E, + 0xa436, 0xA016, 0xa438, 0x0020, 0xa436, 0xA012, 0xa438, 0x0000, + 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, 0xa438, 0x1800, + 0xa438, 0x8021, 0xa438, 0x1800, 0xa438, 0x8037, 0xa438, 0x1800, + 0xa438, 0x803f, 0xa438, 0x1800, 0xa438, 0x8084, 0xa438, 0x1800, + 0xa438, 0x80c5, 0xa438, 0x1800, 0xa438, 0x80cc, 0xa438, 0x1800, + 0xa438, 0x80d5, 0xa438, 0xa00a, 0xa438, 0xa280, 0xa438, 0xa404, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x1800, 0xa438, 0x099b, 0xa438, 0x1000, 0xa438, 0x1021, + 0xa438, 0xd700, 0xa438, 0x5fab, 0xa438, 0xa208, 0xa438, 0x8204, + 0xa438, 0xcb38, 0xa438, 0xaa40, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x1800, 0xa438, 0x0b2a, + 0xa438, 0x82a0, 0xa438, 0x8404, 0xa438, 0xa110, 0xa438, 0xd706, + 0xa438, 0x4041, 0xa438, 0xa180, 0xa438, 0x1800, 0xa438, 0x0e7f, + 0xa438, 0x8190, 0xa438, 0xcb93, 0xa438, 0x1000, 0xa438, 0x0ef4, + 0xa438, 0xd704, 0xa438, 0x7fb8, 0xa438, 0xa008, 0xa438, 0xd706, + 0xa438, 0x4040, 0xa438, 0xa002, 0xa438, 0xd705, 0xa438, 0x4079, + 0xa438, 0x1000, 0xa438, 0x10ad, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x85f0, 0xa438, 0x9503, 0xa438, 0xd705, 0xa438, 0x40d9, + 0xa438, 0xd70c, 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d09, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d0a, 0xa438, 0x0cc0, + 0xa438, 0x0d80, 0xa438, 0x1000, 0xa438, 0x104f, 0xa438, 0x1000, + 0xa438, 0x0ef4, 0xa438, 0x8020, 0xa438, 0xd705, 0xa438, 0x40d9, + 0xa438, 0xd704, 0xa438, 0x609f, 0xa438, 0xd70c, 0xa438, 0x6043, + 0xa438, 0x8504, 0xa438, 0xcb94, 0xa438, 0x1000, 0xa438, 0x0ef4, + 0xa438, 0xd706, 0xa438, 0x7fa2, 0xa438, 0x800a, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x0cf0, 0xa438, 0x05a0, 0xa438, 0x9503, + 0xa438, 0xd705, 0xa438, 0x40b9, 0xa438, 0x0c1f, 0xa438, 0x0d00, + 0xa438, 0x8dc0, 0xa438, 0xf005, 0xa438, 0xa190, 0xa438, 0x0c1f, + 0xa438, 0x0d17, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x104f, + 0xa438, 0xd705, 0xa438, 0x39cc, 0xa438, 0x0c7d, 0xa438, 0x1800, + 0xa438, 0x0e67, 0xa438, 0xcb96, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xab05, 0xa438, 0xac04, 0xa438, 0xac08, 0xa438, 0x9503, + 0xa438, 0x0c1f, 0xa438, 0x0d00, 0xa438, 0x8dc0, 0xa438, 0x1000, + 0xa438, 0x104f, 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd706, + 0xa438, 0x2215, 0xa438, 0x8099, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xae02, 0xa438, 0x9503, 0xa438, 0xd706, 0xa438, 0x6451, + 0xa438, 0xd71f, 0xa438, 0x2e70, 0xa438, 0x0f00, 0xa438, 0xd706, + 0xa438, 0x3290, 0xa438, 0x80be, 0xa438, 0xd704, 0xa438, 0x2e70, + 0xa438, 0x8090, 0xa438, 0xd706, 0xa438, 0x339c, 0xa438, 0x8090, + 0xa438, 0x8718, 0xa438, 0x8910, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xc500, 0xa438, 0x9503, 0xa438, 0x0c1f, 0xa438, 0x0d17, + 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x104f, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x8c04, 0xa438, 0x9503, 0xa438, 0xa00a, + 0xa438, 0xa190, 0xa438, 0xa280, 0xa438, 0xa404, 0xa438, 0x1800, + 0xa438, 0x0f35, 0xa438, 0x1800, 0xa438, 0x0f07, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x8c08, 0xa438, 0x8c04, 0xa438, 0x9503, + 0xa438, 0x1800, 0xa438, 0x0f02, 0xa438, 0x1000, 0xa438, 0x1021, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xaa10, 0xa438, 0x1800, + 0xa438, 0x0c6b, 0xa438, 0x82a0, 0xa438, 0x8406, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xac04, 0xa438, 0x8602, 0xa438, 0x9503, + 0xa438, 0x1800, 0xa438, 0x0e09, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x8308, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xc555, 0xa438, 0x9503, 0xa438, 0xa728, + 0xa438, 0x8440, 0xa438, 0x0c03, 0xa438, 0x0901, 0xa438, 0x8801, + 0xa438, 0xd700, 0xa438, 0x4040, 0xa438, 0xa801, 0xa438, 0xd701, + 0xa438, 0x4052, 0xa438, 0xa810, 0xa438, 0xd701, 0xa438, 0x4054, + 0xa438, 0xa820, 0xa438, 0xd701, 0xa438, 0x4057, 0xa438, 0xa640, + 0xa438, 0xd704, 0xa438, 0x4046, 0xa438, 0xa840, 0xa438, 0xd706, + 0xa438, 0x40b5, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xae20, + 0xa438, 0x9503, 0xa438, 0xd401, 0xa438, 0x1000, 0xa438, 0x0fcf, + 0xa438, 0x1000, 0xa438, 0x0fda, 0xa438, 0x1000, 0xa438, 0x1008, + 0xa438, 0x1000, 0xa438, 0x0fe3, 0xa438, 0xcc00, 0xa438, 0x80c0, + 0xa438, 0x8103, 0xa438, 0x83e0, 0xa438, 0xd71e, 0xa438, 0x2318, + 0xa438, 0x01ae, 0xa438, 0xd704, 0xa438, 0x40bc, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x8302, 0xa438, 0x9503, 0xa438, 0xb801, + 0xa438, 0xd706, 0xa438, 0x2b59, 0xa438, 0x07f8, 0xa438, 0xd700, + 0xa438, 0x2109, 0xa438, 0x04ab, 0xa438, 0xa508, 0xa438, 0xcb15, + 0xa438, 0xd70c, 0xa438, 0x430c, 0xa438, 0x1000, 0xa438, 0x10ca, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa108, 0xa438, 0x9503, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, 0xa438, 0x0f13, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd70c, + 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8f1f, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd70c, + 0xa438, 0x7f33, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c0f, + 0xa438, 0x0d00, 0xa438, 0x0c70, 0xa438, 0x0b00, 0xa438, 0xab08, + 0xa438, 0x9503, 0xa438, 0xd704, 0xa438, 0x3cf1, 0xa438, 0x01f9, + 0xa438, 0x0c1f, 0xa438, 0x0d11, 0xa438, 0xf003, 0xa438, 0x0c1f, + 0xa438, 0x0d0d, 0xa438, 0x0cc0, 0xa438, 0x0d40, 0xa438, 0x1000, + 0xa438, 0x104f, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xab80, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xa940, + 0xa438, 0xd700, 0xa438, 0x5f99, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8b80, 0xa438, 0x9503, 0xa438, 0x8940, 0xa438, 0xd700, + 0xa438, 0x5bbf, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8b08, + 0xa438, 0x9503, 0xa438, 0xba20, 0xa438, 0xd704, 0xa438, 0x4100, + 0xa438, 0xd115, 0xa438, 0xd04f, 0xa438, 0xf001, 0xa438, 0x1000, + 0xa438, 0x1021, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x0c0f, 0xa438, 0x0d00, 0xa438, 0x0c70, + 0xa438, 0x0b10, 0xa438, 0xab08, 0xa438, 0x9503, 0xa438, 0xd704, + 0xa438, 0x3cf1, 0xa438, 0x8178, 0xa438, 0x0c1f, 0xa438, 0x0d11, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d0d, 0xa438, 0x0cc0, + 0xa438, 0x0d40, 0xa438, 0x1000, 0xa438, 0x104f, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xab80, 0xa438, 0x9503, 0xa438, 0x1000, + 0xa438, 0x1021, 0xa438, 0xd706, 0xa438, 0x5fad, 0xa438, 0xd407, + 0xa438, 0x1000, 0xa438, 0x0fcf, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8b88, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1021, + 0xa438, 0xd702, 0xa438, 0x7fa4, 0xa438, 0xd706, 0xa438, 0x61bf, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c30, 0xa438, 0x0110, + 0xa438, 0xa304, 0xa438, 0x9503, 0xa438, 0xd199, 0xa438, 0xd04b, + 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0xd704, 0xa438, 0x3cf1, 0xa438, 0x81a5, 0xa438, 0x0c1f, + 0xa438, 0x0d02, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d01, + 0xa438, 0x0cc0, 0xa438, 0x0d40, 0xa438, 0xa420, 0xa438, 0x8720, + 0xa438, 0x1000, 0xa438, 0x104f, 0xa438, 0x1000, 0xa438, 0x0fda, + 0xa438, 0xd70c, 0xa438, 0x41ac, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8108, 0xa438, 0x9503, 0xa438, 0x0cc0, 0xa438, 0x0040, + 0xa438, 0x0c03, 0xa438, 0x0102, 0xa438, 0x0ce0, 0xa438, 0x03e0, + 0xa438, 0xccce, 0xa438, 0xf008, 0xa438, 0x0cc0, 0xa438, 0x0040, + 0xa438, 0x0c03, 0xa438, 0x0100, 0xa438, 0x0ce0, 0xa438, 0x0380, + 0xa438, 0xcc9c, 0xa438, 0x1000, 0xa438, 0x103f, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xa640, 0xa438, 0x9503, 0xa438, 0xcb16, + 0xa438, 0xd706, 0xa438, 0x6129, 0xa438, 0xd70c, 0xa438, 0x608c, + 0xa438, 0xd17a, 0xa438, 0xd04a, 0xa438, 0xf006, 0xa438, 0xd17a, + 0xa438, 0xd04b, 0xa438, 0xf003, 0xa438, 0xd13d, 0xa438, 0xd04b, + 0xa438, 0x0c1f, 0xa438, 0x0f14, 0xa438, 0xcb17, 0xa438, 0x8fc0, + 0xa438, 0x1000, 0xa438, 0x0fbd, 0xa438, 0xaf40, 0xa438, 0x1000, + 0xa438, 0x0fbd, 0xa438, 0x0cc0, 0xa438, 0x0f80, 0xa438, 0x1000, + 0xa438, 0x0fbd, 0xa438, 0xafc0, 0xa438, 0x1000, 0xa438, 0x0fbd, + 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd701, 0xa438, 0x652e, + 0xa438, 0xd700, 0xa438, 0x5db4, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8640, 0xa438, 0xa702, 0xa438, 0x9503, 0xa438, 0xa720, + 0xa438, 0x1000, 0xa438, 0x0fda, 0xa438, 0xa108, 0xa438, 0x1000, + 0xa438, 0x0fec, 0xa438, 0x8108, 0xa438, 0x1000, 0xa438, 0x0fe3, + 0xa438, 0xa202, 0xa438, 0xa308, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x8308, 0xa438, 0xcb18, + 0xa438, 0x1000, 0xa438, 0x10c2, 0xa438, 0x1000, 0xa438, 0x1021, + 0xa438, 0xd70c, 0xa438, 0x2c60, 0xa438, 0x02bd, 0xa438, 0xff58, + 0xa438, 0x8f1f, 0xa438, 0x1000, 0xa438, 0x1021, 0xa438, 0xd701, + 0xa438, 0x7f8e, 0xa438, 0x1000, 0xa438, 0x0fe3, 0xa438, 0xa130, + 0xa438, 0xaa2f, 0xa438, 0xa2d5, 0xa438, 0xa407, 0xa438, 0xa720, + 0xa438, 0x8310, 0xa438, 0xa308, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x8308, 0xa438, 0x1800, + 0xa438, 0x02d2, 0xa436, 0xA10E, 0xa438, 0x017f, 0xa436, 0xA10C, + 0xa438, 0x0e04, 0xa436, 0xA10A, 0xa438, 0x0c67, 0xa436, 0xA108, + 0xa438, 0x0f13, 0xa436, 0xA106, 0xa438, 0x0eb1, 0xa436, 0xA104, + 0xa438, 0x0e79, 0xa436, 0xA102, 0xa438, 0x0b23, 0xa436, 0xA100, + 0xa438, 0x0908, 0xa436, 0xA110, 0xa438, 0x00ff, 0xa436, 0xb87c, + 0xa438, 0x8ad8, 0xa436, 0xb87e, 0xa438, 0xaf8a, 0xa438, 0xf0af, + 0xa438, 0x8af9, 0xa438, 0xaf8d, 0xa438, 0xdaaf, 0xa438, 0x8e1c, + 0xa438, 0xaf8f, 0xa438, 0x03af, 0xa438, 0x8f06, 0xa438, 0xaf8f, + 0xa438, 0x06af, 0xa438, 0x8f06, 0xa438, 0x0265, 0xa438, 0xa002, + 0xa438, 0x8d78, 0xa438, 0xaf23, 0xa438, 0x47a1, 0xa438, 0x0d06, + 0xa438, 0x028b, 0xa438, 0x05af, 0xa438, 0x225a, 0xa438, 0xaf22, + 0xa438, 0x66f8, 0xa438, 0xe08a, 0xa438, 0x33a0, 0xa438, 0x0005, + 0xa438, 0x028b, 0xa438, 0x21ae, 0xa438, 0x0ea0, 0xa438, 0x0105, + 0xa438, 0x028b, 0xa438, 0xb3ae, 0xa438, 0x06a0, 0xa438, 0x0203, + 0xa438, 0x028c, 0xa438, 0x9dfc, 0xa438, 0x04f8, 0xa438, 0xfbfa, + 0xa438, 0xef69, 0xa438, 0xe080, 0xa438, 0x13ad, 0xa438, 0x267e, + 0xa438, 0xd067, 0xa438, 0xe48a, 0xa438, 0x34e4, 0xa438, 0x8a36, + 0xa438, 0xe48a, 0xa438, 0x38e4, 0xa438, 0x8a3a, 0xa438, 0xd0ae, + 0xa438, 0xe48a, 0xa438, 0x35e4, 0xa438, 0x8a37, 0xa438, 0xe48a, + 0xa438, 0x39e4, 0xa438, 0x8a3b, 0xa438, 0xd000, 0xa438, 0xe48a, + 0xa438, 0x3ce4, 0xa438, 0x8a3d, 0xa438, 0xe48a, 0xa438, 0x3ee4, + 0xa438, 0x8a3f, 0xa438, 0xe48a, 0xa438, 0x40e4, 0xa438, 0x8a41, + 0xa438, 0xe48a, 0xa438, 0x42e4, 0xa438, 0x8a43, 0xa438, 0xe48a, + 0xa438, 0x44d0, 0xa438, 0x02e4, 0xa438, 0x8a45, 0xa438, 0xd00a, + 0xa438, 0xe48a, 0xa438, 0x46d0, 0xa438, 0x16e4, 0xa438, 0x8a47, + 0xa438, 0xd01e, 0xa438, 0xe48a, 0xa438, 0x48d1, 0xa438, 0x02bf, + 0xa438, 0x8dce, 0xa438, 0x026b, 0xa438, 0xd0d1, 0xa438, 0x0abf, + 0xa438, 0x8dd1, 0xa438, 0x026b, 0xa438, 0xd0d1, 0xa438, 0x16bf, + 0xa438, 0x8dd4, 0xa438, 0x026b, 0xa438, 0xd0d1, 0xa438, 0x1ebf, + 0xa438, 0x8dd7, 0xa438, 0x026b, 0xa438, 0xd002, 0xa438, 0x73ab, + 0xa438, 0xef47, 0xa438, 0xe585, 0xa438, 0x5de4, 0xa438, 0x855c, + 0xa438, 0xee8a, 0xa438, 0x3301, 0xa438, 0xae03, 0xa438, 0x0224, + 0xa438, 0x95ef, 0xa438, 0x96fe, 0xa438, 0xfffc, 0xa438, 0x04f8, + 0xa438, 0xf9fa, 0xa438, 0xcefa, 0xa438, 0xef69, 0xa438, 0xfb02, + 0xa438, 0x8dab, 0xa438, 0xad50, 0xa438, 0x2ee1, 0xa438, 0x8a44, + 0xa438, 0xa104, 0xa438, 0x2bee, 0xa438, 0x8a33, 0xa438, 0x02e1, + 0xa438, 0x8a45, 0xa438, 0xbf8d, 0xa438, 0xce02, 0xa438, 0x6bd0, + 0xa438, 0xe18a, 0xa438, 0x46bf, 0xa438, 0x8dd1, 0xa438, 0x026b, + 0xa438, 0xd0e1, 0xa438, 0x8a47, 0xa438, 0xbf8d, 0xa438, 0xd402, + 0xa438, 0x6bd0, 0xa438, 0xe18a, 0xa438, 0x48bf, 0xa438, 0x8dd7, + 0xa438, 0x026b, 0xa438, 0xd0af, 0xa438, 0x8c94, 0xa438, 0xd200, + 0xa438, 0xbe00, 0xa438, 0x0002, 0xa438, 0x8ca5, 0xa438, 0x12a2, + 0xa438, 0x04f6, 0xa438, 0xe18a, 0xa438, 0x44a1, 0xa438, 0x0020, + 0xa438, 0xd129, 0xa438, 0xbf8d, 0xa438, 0xce02, 0xa438, 0x6bd0, + 0xa438, 0xd121, 0xa438, 0xbf8d, 0xa438, 0xd102, 0xa438, 0x6bd0, + 0xa438, 0xd125, 0xa438, 0xbf8d, 0xa438, 0xd402, 0xa438, 0x6bd0, + 0xa438, 0xbf8d, 0xa438, 0xd702, 0xa438, 0x6bd0, 0xa438, 0xae44, + 0xa438, 0xa101, 0xa438, 0x1ed1, 0xa438, 0x31bf, 0xa438, 0x8dce, + 0xa438, 0x026b, 0xa438, 0xd0bf, 0xa438, 0x8dd1, 0xa438, 0x026b, + 0xa438, 0xd0d1, 0xa438, 0x2dbf, 0xa438, 0x8dd4, 0xa438, 0x026b, + 0xa438, 0xd0bf, 0xa438, 0x8dd7, 0xa438, 0x026b, 0xa438, 0xd0ae, + 0xa438, 0x23a1, 0xa438, 0x0220, 0xa438, 0xd139, 0xa438, 0xbf8d, + 0xa438, 0xce02, 0xa438, 0x6bd0, 0xa438, 0xbf8d, 0xa438, 0xd102, + 0xa438, 0x6bd0, 0xa438, 0xd13d, 0xa438, 0xbf8d, 0xa438, 0xd402, + 0xa438, 0x6bd0, 0xa438, 0xd135, 0xa438, 0xbf8d, 0xa438, 0xd702, + 0xa438, 0x6bd0, 0xa438, 0xae00, 0xa438, 0xe18a, 0xa438, 0x4411, + 0xa438, 0xe58a, 0xa438, 0x44d0, 0xa438, 0x00e4, 0xa438, 0x8a3c, + 0xa438, 0xe48a, 0xa438, 0x3de4, 0xa438, 0x8a3e, 0xa438, 0xe48a, + 0xa438, 0x3fe4, 0xa438, 0x8a40, 0xa438, 0xe48a, 0xa438, 0x41e4, + 0xa438, 0x8a42, 0xa438, 0xe48a, 0xa438, 0x4302, 0xa438, 0x73ab, + 0xa438, 0xef47, 0xa438, 0xe585, 0xa438, 0x5de4, 0xa438, 0x855c, + 0xa438, 0xffef, 0xa438, 0x96fe, 0xa438, 0xc6fe, 0xa438, 0xfdfc, + 0xa438, 0x0402, 0xa438, 0x2495, 0xa438, 0xee8a, 0xa438, 0x3300, + 0xa438, 0x04f8, 0xa438, 0xf9fa, 0xa438, 0xfbef, 0xa438, 0x79fb, + 0xa438, 0xcffb, 0xa438, 0xd300, 0xa438, 0xa200, 0xa438, 0x09bf, + 0xa438, 0x8dc2, 0xa438, 0x026b, 0xa438, 0xefaf, 0xa438, 0x8cda, + 0xa438, 0xa201, 0xa438, 0x09bf, 0xa438, 0x8dc5, 0xa438, 0x026b, + 0xa438, 0xefaf, 0xa438, 0x8cda, 0xa438, 0xa202, 0xa438, 0x09bf, + 0xa438, 0x8dc8, 0xa438, 0x026b, 0xa438, 0xefaf, 0xa438, 0x8cda, + 0xa438, 0xbf8d, 0xa438, 0xcb02, 0xa438, 0x6bef, 0xa438, 0xef64, + 0xa438, 0xbf8a, 0xa438, 0x3c1a, 0xa438, 0x921a, 0xa438, 0x92d8, + 0xa438, 0x19d9, 0xa438, 0xef74, 0xa438, 0x0273, 0xa438, 0x93ef, + 0xa438, 0x47bf, 0xa438, 0x8a3c, 0xa438, 0x1a92, 0xa438, 0x1a92, + 0xa438, 0xdc19, 0xa438, 0xddd1, 0xa438, 0x0011, 0xa438, 0xa1ff, + 0xa438, 0xfc13, 0xa438, 0xa310, 0xa438, 0xaf02, 0xa438, 0x8d0e, + 0xa438, 0xffc7, 0xa438, 0xffef, 0xa438, 0x97ff, 0xa438, 0xfefd, + 0xa438, 0xfc04, 0xa438, 0xf8fa, 0xa438, 0xfbef, 0xa438, 0x79fb, + 0xa438, 0xcffb, 0xa438, 0xbf8a, 0xa438, 0x3c1a, 0xa438, 0x921a, + 0xa438, 0x92d8, 0xa438, 0x19d9, 0xa438, 0xef64, 0xa438, 0xbf8a, + 0xa438, 0x341a, 0xa438, 0x921a, 0xa438, 0x92d8, 0xa438, 0x19d9, + 0xa438, 0xef74, 0xa438, 0x0273, 0xa438, 0x78a2, 0xa438, 0x0005, + 0xa438, 0xbe8d, 0xa438, 0xceae, 0xa438, 0x13a2, 0xa438, 0x0105, + 0xa438, 0xbe8d, 0xa438, 0xd1ae, 0xa438, 0x0ba2, 0xa438, 0x0205, + 0xa438, 0xbe8d, 0xa438, 0xd4ae, 0xa438, 0x03be, 0xa438, 0x8dd7, + 0xa438, 0xad50, 0xa438, 0x17bf, 0xa438, 0x8a45, 0xa438, 0x1a92, + 0xa438, 0x0702, 0xa438, 0x6bef, 0xa438, 0x07dd, 0xa438, 0xef46, + 0xa438, 0xbf8a, 0xa438, 0x341a, 0xa438, 0x921a, 0xa438, 0x92dc, + 0xa438, 0x19dd, 0xa438, 0xffc7, 0xa438, 0xffef, 0xa438, 0x97ff, + 0xa438, 0xfefc, 0xa438, 0x04ee, 0xa438, 0x8a33, 0xa438, 0x00ee, + 0xa438, 0x8a32, 0xa438, 0x0404, 0xa438, 0xf8fa, 0xa438, 0xef69, + 0xa438, 0xe080, 0xa438, 0x13ad, 0xa438, 0x2624, 0xa438, 0xd102, + 0xa438, 0xbf8d, 0xa438, 0xce02, 0xa438, 0x6bd0, 0xa438, 0xd10a, + 0xa438, 0xbf8d, 0xa438, 0xd102, 0xa438, 0x6bd0, 0xa438, 0xd116, + 0xa438, 0xbf8d, 0xa438, 0xd402, 0xa438, 0x6bd0, 0xa438, 0xd11e, + 0xa438, 0xbf8d, 0xa438, 0xd702, 0xa438, 0x6bd0, 0xa438, 0xee8a, + 0xa438, 0x3300, 0xa438, 0xef96, 0xa438, 0xfefc, 0xa438, 0x04f8, + 0xa438, 0xfae0, 0xa438, 0x855c, 0xa438, 0xe185, 0xa438, 0x5def, + 0xa438, 0x64d0, 0xa438, 0x00e1, 0xa438, 0x8a32, 0xa438, 0xef74, + 0xa438, 0x0273, 0xa438, 0xc6fe, 0xa438, 0xfc04, 0xa438, 0xf0b2, + 0xa438, 0x02f0, 0xa438, 0xb282, 0xa438, 0xf0b3, 0xa438, 0x02f0, + 0xa438, 0xb382, 0xa438, 0x50ac, 0xa438, 0xd450, 0xa438, 0xacd6, + 0xa438, 0xb6ac, 0xa438, 0xd4b6, 0xa438, 0xacd6, 0xa438, 0xbf8e, + 0xa438, 0x0d02, 0xa438, 0x6bd0, 0xa438, 0xd0ff, 0xa438, 0xd1fe, + 0xa438, 0xbf8e, 0xa438, 0x1002, 0xa438, 0x6bd0, 0xa438, 0xd004, + 0xa438, 0xd14d, 0xa438, 0xbf8e, 0xa438, 0x1302, 0xa438, 0x6bd0, + 0xa438, 0xd0fc, 0xa438, 0xd1c6, 0xa438, 0xbf8e, 0xa438, 0x1602, + 0xa438, 0x6bd0, 0xa438, 0xd009, 0xa438, 0xd146, 0xa438, 0xbf8e, + 0xa438, 0x1902, 0xa438, 0x6bd0, 0xa438, 0xef13, 0xa438, 0xaf2d, + 0xa438, 0xbdf0, 0xa438, 0xac1c, 0xa438, 0xf0ac, 0xa438, 0x2af0, + 0xa438, 0xac2c, 0xa438, 0xf0ac, 0xa438, 0x2ef0, 0xa438, 0xac30, + 0xa438, 0xbf8e, 0xa438, 0xf102, 0xa438, 0x6bef, 0xa438, 0xac28, + 0xa438, 0x70bf, 0xa438, 0x8eeb, 0xa438, 0x026b, 0xa438, 0xefac, + 0xa438, 0x2867, 0xa438, 0xbf8e, 0xa438, 0xee02, 0xa438, 0x6bef, + 0xa438, 0xad28, 0xa438, 0x5bbf, 0xa438, 0x8ff2, 0xa438, 0xd8bf, + 0xa438, 0x8ff3, 0xa438, 0xd9bf, 0xa438, 0x8ef4, 0xa438, 0x026b, + 0xa438, 0xd0bf, 0xa438, 0x8ff0, 0xa438, 0xd8bf, 0xa438, 0x8ff1, + 0xa438, 0xd9bf, 0xa438, 0x8ef7, 0xa438, 0x026b, 0xa438, 0xd0bf, + 0xa438, 0x8fee, 0xa438, 0xd8bf, 0xa438, 0x8fef, 0xa438, 0xd9bf, + 0xa438, 0x8efa, 0xa438, 0x026b, 0xa438, 0xd0bf, 0xa438, 0x8fec, + 0xa438, 0xd8bf, 0xa438, 0x8fed, 0xa438, 0xd9bf, 0xa438, 0x8efd, + 0xa438, 0x026b, 0xa438, 0xd0bf, 0xa438, 0x8fea, 0xa438, 0xd8bf, + 0xa438, 0x8feb, 0xa438, 0xd9bf, 0xa438, 0x8f00, 0xa438, 0x026b, + 0xa438, 0xd0bf, 0xa438, 0x8fe8, 0xa438, 0xd8bf, 0xa438, 0x8fe9, + 0xa438, 0xd9bf, 0xa438, 0x8e0d, 0xa438, 0x026b, 0xa438, 0xd01f, + 0xa438, 0x00e1, 0xa438, 0x86ee, 0xa438, 0x1b64, 0xa438, 0xaf3d, + 0xa438, 0x7abf, 0xa438, 0x8ffe, 0xa438, 0xd8bf, 0xa438, 0x8fff, + 0xa438, 0xd9bf, 0xa438, 0x8ef4, 0xa438, 0x026b, 0xa438, 0xd0bf, + 0xa438, 0x8ffc, 0xa438, 0xd8bf, 0xa438, 0x8ffd, 0xa438, 0xd9bf, + 0xa438, 0x8ef7, 0xa438, 0x026b, 0xa438, 0xd0bf, 0xa438, 0x8ffa, + 0xa438, 0xd8bf, 0xa438, 0x8ffb, 0xa438, 0xd9bf, 0xa438, 0x8efa, + 0xa438, 0x026b, 0xa438, 0xd0bf, 0xa438, 0x8ff8, 0xa438, 0xd8bf, + 0xa438, 0x8ff9, 0xa438, 0xd9bf, 0xa438, 0x8efd, 0xa438, 0x026b, + 0xa438, 0xd0bf, 0xa438, 0x8ff6, 0xa438, 0xd8bf, 0xa438, 0x8ff7, + 0xa438, 0xd9bf, 0xa438, 0x8f00, 0xa438, 0x026b, 0xa438, 0xd0bf, + 0xa438, 0x8ff4, 0xa438, 0xd8bf, 0xa438, 0x8ff5, 0xa438, 0xd9bf, + 0xa438, 0x8e0d, 0xa438, 0x026b, 0xa438, 0xd0ae, 0xa438, 0xa766, + 0xa438, 0xac5c, 0xa438, 0xbbac, 0xa438, 0x5c99, 0xa438, 0xac5c, + 0xa438, 0xf0ac, 0xa438, 0x26f0, 0xa438, 0xac24, 0xa438, 0xf0ac, + 0xa438, 0x22f0, 0xa438, 0xac20, 0xa438, 0xf0ac, 0xa438, 0x1eaf, + 0xa438, 0x44f8, 0xa436, 0xb85e, 0xa438, 0x2344, 0xa436, 0xb860, + 0xa438, 0x2254, 0xa436, 0xb862, 0xa438, 0x2DB5, 0xa436, 0xb864, + 0xa438, 0x3D6C, 0xa436, 0xb886, 0xa438, 0x44ED, 0xa436, 0xb888, + 0xa438, 0xffff, 0xa436, 0xb88a, 0xa438, 0xffff, 0xa436, 0xb88c, + 0xa438, 0xffff, 0xa436, 0xb838, 0xa438, 0x001f, 0xb820, 0x0010, + 0xa436, 0x87ad, 0xa438, 0xaf87, 0xa438, 0xc5af, 0xa438, 0x87e4, + 0xa438, 0xaf8a, 0xa438, 0x3daf, 0xa438, 0x8a62, 0xa438, 0xaf8a, + 0xa438, 0x62af, 0xa438, 0x8a62, 0xa438, 0xaf8a, 0xa438, 0x62af, + 0xa438, 0x8a62, 0xa438, 0x2810, 0xa438, 0x0d01, 0xa438, 0xe484, + 0xa438, 0xbf29, 0xa438, 0x100d, 0xa438, 0x11e5, 0xa438, 0x84c0, + 0xa438, 0x2a10, 0xa438, 0x0d21, 0xa438, 0xe684, 0xa438, 0xc12b, + 0xa438, 0x100d, 0xa438, 0x31e7, 0xa438, 0x84c2, 0xa438, 0xaf3f, + 0xa438, 0x7cf8, 0xa438, 0xe080, 0xa438, 0x4cac, 0xa438, 0x222c, + 0xa438, 0xe080, 0xa438, 0x40ad, 0xa438, 0x2232, 0xa438, 0xbf8a, + 0xa438, 0x2502, 0xa438, 0x6752, 0xa438, 0xad29, 0xa438, 0x0502, + 0xa438, 0x8827, 0xa438, 0xae0d, 0xa438, 0xad28, 0xa438, 0x0502, + 0xa438, 0x8961, 0xa438, 0xae05, 0xa438, 0x0214, 0xa438, 0x04ae, + 0xa438, 0x00e0, 0xa438, 0x8040, 0xa438, 0xac22, 0xa438, 0x1102, + 0xa438, 0x13e1, 0xa438, 0xae0c, 0xa438, 0x0288, 0xa438, 0x7c02, + 0xa438, 0x8a10, 0xa438, 0x0214, 0xa438, 0x2502, 0xa438, 0x1404, + 0xa438, 0xfcaf, 0xa438, 0x13c6, 0xa438, 0xf8f8, 0xa438, 0xccf9, + 0xa438, 0xfaef, 0xa438, 0x69fb, 0xa438, 0xe080, 0xa438, 0x18ad, + 0xa438, 0x223b, 0xa438, 0xbf8a, 0xa438, 0x2b02, 0xa438, 0x6752, + 0xa438, 0xad28, 0xa438, 0x32bf, 0xa438, 0x8a28, 0xa438, 0x026f, + 0xa438, 0x17ee, 0xa438, 0x8ff3, 0xa438, 0x00bf, 0xa438, 0x6854, + 0xa438, 0x0267, 0xa438, 0x52ad, 0xa438, 0x281f, 0xa438, 0xbf68, + 0xa438, 0x5d02, 0xa438, 0x6752, 0xa438, 0xad28, 0xa438, 0x16e0, + 0xa438, 0x8ff4, 0xa438, 0xe18f, 0xa438, 0xf502, 0xa438, 0x8891, + 0xa438, 0xad50, 0xa438, 0x0abf, 0xa438, 0x8a28, 0xa438, 0x026f, + 0xa438, 0x20ee, 0xa438, 0x8ff3, 0xa438, 0x0102, 0xa438, 0x1404, + 0xa438, 0xffef, 0xa438, 0x96fe, 0xa438, 0xfdc4, 0xa438, 0xfcfc, + 0xa438, 0x04f8, 0xa438, 0xf9ef, 0xa438, 0x59e0, 0xa438, 0x8018, + 0xa438, 0xad22, 0xa438, 0x06bf, 0xa438, 0x8a28, 0xa438, 0x026f, + 0xa438, 0x17ef, 0xa438, 0x95fd, 0xa438, 0xfc04, 0xa438, 0xf8f9, + 0xa438, 0xf9ef, 0xa438, 0x59fa, 0xa438, 0xface, 0xa438, 0xe48f, + 0xa438, 0xfee5, 0xa438, 0x8fff, 0xa438, 0xbf6e, 0xa438, 0x1b02, + 0xa438, 0x6f20, 0xa438, 0xbf6e, 0xa438, 0x1802, 0xa438, 0x6f17, + 0xa438, 0xd102, 0xa438, 0xbf6e, 0xa438, 0x1202, 0xa438, 0x6733, + 0xa438, 0xbf6e, 0xa438, 0x1502, 0xa438, 0x6f17, 0xa438, 0xbe00, + 0xa438, 0x00cc, 0xa438, 0xbf69, 0xa438, 0xcb02, 0xa438, 0x6733, + 0xa438, 0xbf69, 0xa438, 0xce02, 0xa438, 0x6f17, 0xa438, 0xbf69, + 0xa438, 0xce02, 0xa438, 0x6f20, 0xa438, 0xbf69, 0xa438, 0xd102, + 0xa438, 0x6752, 0xa438, 0xad28, 0xa438, 0xf70c, 0xa438, 0x81bf, + 0xa438, 0x8ff6, 0xa438, 0x1a98, 0xa438, 0xef59, 0xa438, 0xbf69, + 0xa438, 0xd402, 0xa438, 0x6752, 0xa438, 0xef95, 0xa438, 0xdc19, + 0xa438, 0xdd0d, 0xa438, 0x8118, 0xa438, 0xa800, 0xa438, 0x04c9, + 0xa438, 0xbf69, 0xa438, 0xce02, 0xa438, 0x6f17, 0xa438, 0xe08f, + 0xa438, 0xfce1, 0xa438, 0x8ffd, 0xa438, 0xef74, 0xa438, 0xe08f, + 0xa438, 0xfae1, 0xa438, 0x8ffb, 0xa438, 0xef64, 0xa438, 0x026e, + 0xa438, 0x57ad, 0xa438, 0x5008, 0xa438, 0xe08f, 0xa438, 0xfce1, + 0xa438, 0x8ffd, 0xa438, 0xae06, 0xa438, 0xe08f, 0xa438, 0xfae1, + 0xa438, 0x8ffb, 0xa438, 0xe28f, 0xa438, 0xf8e3, 0xa438, 0x8ff9, + 0xa438, 0xef75, 0xa438, 0xe28f, 0xa438, 0xf6e3, 0xa438, 0x8ff7, + 0xa438, 0xef65, 0xa438, 0x026e, 0xa438, 0x57ad, 0xa438, 0x5008, + 0xa438, 0xe28f, 0xa438, 0xf8e3, 0xa438, 0x8ff9, 0xa438, 0xae06, + 0xa438, 0xe28f, 0xa438, 0xf6e3, 0xa438, 0x8ff7, 0xa438, 0x1b45, + 0xa438, 0xad27, 0xa438, 0x05d7, 0xa438, 0x0000, 0xa438, 0xae0d, + 0xa438, 0xef74, 0xa438, 0xe08f, 0xa438, 0xfee1, 0xa438, 0x8fff, + 0xa438, 0xef64, 0xa438, 0x026e, 0xa438, 0x57c6, 0xa438, 0xfefe, + 0xa438, 0xef95, 0xa438, 0xfdfd, 0xa438, 0xfc04, 0xa438, 0xf8f9, + 0xa438, 0xfaef, 0xa438, 0x69fb, 0xa438, 0xe080, 0xa438, 0x18ac, + 0xa438, 0x2103, 0xa438, 0xaf8a, 0xa438, 0x06bf, 0xa438, 0x8a2b, + 0xa438, 0xac21, 0xa438, 0x03af, 0xa438, 0x8a06, 0xa438, 0xbf8a, + 0xa438, 0x2802, 0xa438, 0x6f17, 0xa438, 0xee8f, 0xa438, 0xee00, + 0xa438, 0xee8f, 0xa438, 0xed00, 0xa438, 0xbf8a, 0xa438, 0x2e02, + 0xa438, 0x6752, 0xa438, 0xad28, 0xa438, 0x03af, 0xa438, 0x8a06, + 0xa438, 0xe28f, 0xa438, 0xefe3, 0xa438, 0x8ff0, 0xa438, 0xbf68, + 0xa438, 0x5102, 0xa438, 0x6752, 0xa438, 0xac28, 0xa438, 0x11e2, + 0xa438, 0x8ff1, 0xa438, 0xe38f, 0xa438, 0xf2bf, 0xa438, 0x6848, + 0xa438, 0x0267, 0xa438, 0x52ac, 0xa438, 0x2802, 0xa438, 0xae53, + 0xa438, 0xbf68, 0xa438, 0x5a02, 0xa438, 0x6752, 0xa438, 0xad28, + 0xa438, 0x0aef, 0xa438, 0x4502, 0xa438, 0x8891, 0xa438, 0xac50, + 0xa438, 0x38ae, 0xa438, 0x40bf, 0xa438, 0x8a31, 0xa438, 0x0267, + 0xa438, 0x52ef, 0xa438, 0x31bf, 0xa438, 0x8a34, 0xa438, 0x0267, + 0xa438, 0x520c, 0xa438, 0x311e, 0xa438, 0x31bf, 0xa438, 0x8a37, + 0xa438, 0x0267, 0xa438, 0x520c, 0xa438, 0x311e, 0xa438, 0x31bf, + 0xa438, 0x8a3a, 0xa438, 0x0267, 0xa438, 0x520c, 0xa438, 0x311e, + 0xa438, 0x31e7, 0xa438, 0x8fee, 0xa438, 0xa30c, 0xa438, 0x02ae, + 0xa438, 0x08a3, 0xa438, 0x0e02, 0xa438, 0xae03, 0xa438, 0xa30d, + 0xa438, 0x0aee, 0xa438, 0x8fed, 0xa438, 0x01bf, 0xa438, 0x8a28, + 0xa438, 0x026f, 0xa438, 0x2002, 0xa438, 0x1404, 0xa438, 0xffef, + 0xa438, 0x96fe, 0xa438, 0xfdfc, 0xa438, 0x04f8, 0xa438, 0xfaef, + 0xa438, 0x69e0, 0xa438, 0x8018, 0xa438, 0xad21, 0xa438, 0x06bf, + 0xa438, 0x8a28, 0xa438, 0x026f, 0xa438, 0x17ef, 0xa438, 0x96fe, + 0xa438, 0xfc04, 0xa438, 0xf8a4, 0xa438, 0xb677, 0xa438, 0xa4b6, + 0xa438, 0x22a4, 0xa438, 0x4222, 0xa438, 0xa668, 0xa438, 0x00b2, + 0xa438, 0x3e00, 0xa438, 0xb2be, 0xa438, 0x00b3, 0xa438, 0x3e00, + 0xa438, 0xb3be, 0xa438, 0xd10f, 0xa438, 0xbf8a, 0xa438, 0x5c02, + 0xa438, 0x6733, 0xa438, 0xbf8a, 0xa438, 0x5f02, 0xa438, 0x6733, + 0xa438, 0xbf8a, 0xa438, 0x5c02, 0xa438, 0x6f17, 0xa438, 0xbf8a, + 0xa438, 0x5f02, 0xa438, 0x6f17, 0xa438, 0x1f00, 0xa438, 0xaf3d, + 0xa438, 0x0c30, 0xa438, 0xa85a, 0xa438, 0xfcad, 0xa438, 0x0e00, + 0xa436, 0xb818, 0xa438, 0x3f31, 0xa436, 0xb81a, 0xa438, 0x13a4, + 0xa436, 0xb81c, 0xa438, 0x3d0a, 0xa436, 0xb81e, 0xa438, 0xffff, + 0xa436, 0xb850, 0xa438, 0xffff, 0xa436, 0xb852, 0xa438, 0xffff, + 0xa436, 0xb878, 0xa438, 0xffff, 0xa436, 0xb884, 0xa438, 0xffff, + 0xa436, 0xb832, 0xa438, 0x0007, 0xa436, 0x84cf, 0xa438, 0x0101, + 0xa466, 0x0002, 0xa436, 0x86a7, 0xa438, 0x0000, 0xa436, 0x0000, + 0xa438, 0x0000, 0xa436, 0xB82E, 0xa438, 0x0000, 0xa436, 0x8023, + 0xa438, 0x0000, 0xa436, 0x801E, 0xa438, 0x0023, 0xb820, 0x0000, + 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8126a_1_2[] = { + 0xB87C, 0x8a32, 0xB87E, 0x0400, 0xB87C, 0x8376, 0xB87E, 0x0300, + 0xce00, 0x6CAF, 0xB87C, 0x8301, 0xB87E, 0x1133, 0xB87C, 0x8105, + 0xB87E, 0xa000, 0xB87C, 0x8148, 0xB87E, 0xa000, 0xa436, 0x81d8, + 0xa438, 0x5865, 0xacf8, 0xCCC0, 0xac90, 0x52B0, 0xad2C, 0x8000, + 0xB87C, 0x83e6, 0xB87E, 0x4A0E, 0xB87C, 0x83d2, 0xB87E, 0x0A0E, + 0xB87C, 0x80a0, 0xB87E, 0xB8B6, 0xB87C, 0x805e, 0xB87E, 0xB8B6, + 0xB87C, 0x8057, 0xB87E, 0x305A, 0xB87C, 0x8099, 0xB87E, 0x305A, + 0xB87C, 0x8052, 0xB87E, 0x3333, 0xB87C, 0x8094, 0xB87E, 0x3333, + 0xB87C, 0x807F, 0xB87E, 0x7975, 0xB87C, 0x803D, 0xB87E, 0x7975, + 0xB87C, 0x8036, 0xB87E, 0x305A, 0xB87C, 0x8078, 0xB87E, 0x305A, + 0xB87C, 0x8031, 0xB87E, 0x3335, 0xB87C, 0x8073, 0xB87E, 0x3335, + 0xa436, 0x81D8, 0xa438, 0x5865, 0xB87C, 0x867c, 0xB87E, 0x0617, + 0xad94, 0x0092, 0xB87C, 0x89B1, 0xB87E, 0x5050, 0xB87C, 0x86E0, + 0xB87E, 0x809A, 0xB87C, 0x86E2, 0xB87E, 0xB34D, 0xB87C, 0x8FD2, + 0xB87E, 0x004B, 0xB87C, 0x8691, 0xB87E, 0x007D, 0xB87E, 0x00AF, + 0xB87E, 0x00E1, 0xB87E, 0x00FF, 0xB87C, 0x867F, 0xB87E, 0x0201, + 0xB87E, 0x0201, 0xB87E, 0x0201, 0xB87E, 0x0201, 0xB87E, 0x0201, + 0xB87E, 0x0201, 0xB87C, 0x86DA, 0xB87E, 0xCDCD, 0xB87E, 0xE6CD, + 0xB87E, 0xCDCD, 0xB87C, 0x8FE8, 0xB87E, 0x0368, 0xB87E, 0x033F, + 0xB87E, 0x1046, 0xB87E, 0x147D, 0xB87E, 0x147D, 0xB87E, 0x147D, + 0xB87E, 0x0368, 0xB87E, 0x033F, 0xB87E, 0x1046, 0xB87E, 0x147D, + 0xB87E, 0x147D, 0xB87E, 0x147D, 0xa436, 0x80dd, 0xa438, 0xf0AB, + 0xa436, 0x80df, 0xa438, 0xC009, 0xa436, 0x80e7, 0xa438, 0x401E, + 0xa436, 0x80e1, 0xa438, 0x120A, 0xa436, 0x86f2, 0xa438, 0x5094, + 0xa436, 0x8701, 0xa438, 0x5094, 0xa436, 0x80f1, 0xa438, 0x30CC, + 0xa436, 0x80f3, 0xa438, 0x0001, 0xa436, 0x80f5, 0xa438, 0x330B, + 0xa436, 0x80f8, 0xa438, 0xCB76, 0xa436, 0x8105, 0xa438, 0xf0D3, + 0xa436, 0x8107, 0xa438, 0x0002, 0xa436, 0x8109, 0xa438, 0xff0B, + 0xa436, 0x810c, 0xa438, 0xC86D, 0xB87C, 0x8a32, 0xB87E, 0x0400, + 0xa6f8, 0x0000, 0xa6f8, 0x0000, 0xa436, 0x81bc, 0xa438, 0x1300, + 0xa846, 0x2410, 0xa86A, 0x0801, 0xa85C, 0x9680, 0xa436, 0x841D, + 0xa438, 0x4A28, 0xa436, 0x8016, 0xa438, 0xBE05, 0xBF9C, 0x004A, + 0xBF96, 0x41FA, 0xBF9A, 0xDC81, 0xa436, 0x8018, 0xa438, 0x0700, + 0xa436, 0x8ff4, 0xa438, 0x01AE, 0xa436, 0x8fef, 0xa438, 0x0172, + 0xa438, 0x00dc, 0xc842, 0x0002, 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8126a_1_3[] = { + 0xb892, 0x0000, 0xB88E, 0xC236, 0xB890, 0x1A1C, 0xB88E, 0xC238, + 0xB890, 0x1C1C, 0xB890, 0x1C1C, 0xB890, 0x2D2D, 0xB890, 0x2D2D, + 0xB890, 0x2D2A, 0xB890, 0x2A2A, 0xB890, 0x2A2A, 0xB890, 0x2A19, + 0xB88E, 0xC272, 0xB890, 0x8484, 0xB890, 0x8484, 0xB890, 0x84B4, + 0xB890, 0xB4B4, 0xB890, 0xB4B4, 0xB890, 0xF8F8, 0xB890, 0xF8F8, + 0xB890, 0xF8F8, 0xB88E, 0xC000, 0xB890, 0x0303, 0xB890, 0x0405, + 0xB890, 0x0608, 0xB890, 0x0A0B, 0xB890, 0x0E11, 0xB890, 0x1519, + 0xB890, 0x2028, 0xB890, 0x3503, 0xB890, 0x0304, 0xB890, 0x0405, + 0xB890, 0x0606, 0xB890, 0x0708, 0xB890, 0x090A, 0xB890, 0x0B0D, + 0xB890, 0x0F11, 0xB890, 0x1315, 0xB890, 0x181A, 0xB890, 0x2029, + 0xB890, 0x2F36, 0xB890, 0x3D43, 0xB890, 0x0101, 0xB890, 0x0102, + 0xB890, 0x0202, 0xB890, 0x0303, 0xB890, 0x0405, 0xB890, 0x0607, + 0xB890, 0x090A, 0xB890, 0x0C0E, 0xB88E, 0xC038, 0xB890, 0x6AE1, + 0xB890, 0x8E6B, 0xB890, 0xA767, 0xB890, 0x01EF, 0xB890, 0x5A63, + 0xB890, 0x2B99, 0xB890, 0x7F5D, 0xB890, 0x361F, 0xB890, 0xA127, + 0xB890, 0xB558, 0xB890, 0x11C3, 0xB890, 0x7D85, 0xB890, 0xBAC5, + 0xB890, 0xE691, 0xB890, 0x8F79, 0xB890, 0x3164, 0xB890, 0x3293, + 0xB890, 0xB80D, 0xB890, 0xE2B7, 0xB890, 0x0D62, 0xB890, 0x4F85, + 0xB890, 0xC919, 0xB890, 0x78F3, 0xB890, 0x77FF, 0xB890, 0xBD9E, + 0xB890, 0x69D6, 0xB890, 0x6DA4, 0xB890, 0x0CC5, 0xB88E, 0xC1D2, + 0xB890, 0x2425, 0xB890, 0x2627, 0xB890, 0x2829, 0xB890, 0x2A2B, + 0xB890, 0x2C2D, 0xB890, 0x2E2F, 0xB890, 0x3031, 0xB890, 0x3233, + 0xB890, 0x2323, 0xB890, 0x2424, 0xB890, 0x2525, 0xB890, 0x2626, + 0xB890, 0x2727, 0xB890, 0x2828, 0xB890, 0x2929, 0xB890, 0x2A2A, + 0xB890, 0x2B2C, 0xB890, 0x2C2D, 0xB890, 0x2D2E, 0xB890, 0x2E2F, + 0xB890, 0x2F30, 0xB890, 0x1A1B, 0xB890, 0x1D1E, 0xB890, 0x1F20, + 0xB890, 0x2123, 0xB890, 0x2425, 0xB890, 0x2628, 0xB890, 0x292A, + 0xB890, 0x2B2C, 0xB890, 0x2E12, 0xB88E, 0xC09A, 0xB890, 0xD3D3, + 0xB890, 0xD3D3, 0xB890, 0xD3D3, 0xB890, 0xD3D3, 0xB890, 0xD3D3, + 0xB890, 0xD3D3, 0xB890, 0xD3D3, 0xB890, 0xD3D3, 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8126a_2_1[] = { + 0xa436, 0x8023, 0xa438, 0x4700, 0xa436, 0xB82E, 0xa438, 0x0001, + 0xb820, 0x0090, 0xa436, 0xA016, 0xa438, 0x0000, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x8025, 0xa438, 0x1800, 0xa438, 0x8033, + 0xa438, 0x1800, 0xa438, 0x8037, 0xa438, 0x1800, 0xa438, 0x803c, + 0xa438, 0x1800, 0xa438, 0x8044, 0xa438, 0x1800, 0xa438, 0x8054, + 0xa438, 0x1800, 0xa438, 0x8059, 0xa438, 0xd504, 0xa438, 0xc9b5, + 0xa438, 0xd500, 0xa438, 0xd707, 0xa438, 0x4070, 0xa438, 0x1800, + 0xa438, 0x107a, 0xa438, 0xd504, 0xa438, 0xc994, 0xa438, 0xd500, + 0xa438, 0xd707, 0xa438, 0x60d0, 0xa438, 0xd701, 0xa438, 0x252d, + 0xa438, 0x8023, 0xa438, 0x1800, 0xa438, 0x1064, 0xa438, 0x1800, + 0xa438, 0x107a, 0xa438, 0x1800, 0xa438, 0x1052, 0xa438, 0xd504, + 0xa438, 0xc9d0, 0xa438, 0xd500, 0xa438, 0xd707, 0xa438, 0x60d0, + 0xa438, 0xd701, 0xa438, 0x252d, 0xa438, 0x8031, 0xa438, 0x1800, + 0xa438, 0x1171, 0xa438, 0x1800, 0xa438, 0x1187, 0xa438, 0x1800, + 0xa438, 0x116a, 0xa438, 0xc0ff, 0xa438, 0xcaff, 0xa438, 0x1800, + 0xa438, 0x00d6, 0xa438, 0xd504, 0xa438, 0xa001, 0xa438, 0xd704, + 0xa438, 0x1800, 0xa438, 0x128b, 0xa438, 0xd707, 0xa438, 0x2005, + 0xa438, 0x8042, 0xa438, 0xd75e, 0xa438, 0x1800, 0xa438, 0x137a, + 0xa438, 0x1800, 0xa438, 0x13ed, 0xa438, 0x61d0, 0xa438, 0xd701, + 0xa438, 0x60a5, 0xa438, 0xd504, 0xa438, 0xc9b2, 0xa438, 0xd500, + 0xa438, 0xf004, 0xa438, 0xd504, 0xa438, 0xc9b1, 0xa438, 0xd500, + 0xa438, 0xd707, 0xa438, 0x6070, 0xa438, 0x1800, 0xa438, 0x10a8, + 0xa438, 0x1800, 0xa438, 0x10bd, 0xa438, 0xd500, 0xa438, 0xc492, + 0xa438, 0xd501, 0xa438, 0x1800, 0xa438, 0x13c1, 0xa438, 0xa980, + 0xa438, 0xd500, 0xa438, 0x1800, 0xa438, 0x143b, 0xa436, 0xA026, + 0xa438, 0x143a, 0xa436, 0xA024, 0xa438, 0x13c0, 0xa436, 0xA022, + 0xa438, 0x10bc, 0xa436, 0xA020, 0xa438, 0x1379, 0xa436, 0xA006, + 0xa438, 0x128a, 0xa436, 0xA004, 0xa438, 0x00d5, 0xa436, 0xA002, + 0xa438, 0x1182, 0xa436, 0xA000, 0xa438, 0x1075, 0xa436, 0xA008, + 0xa438, 0xff00, 0xa436, 0xA016, 0xa438, 0x0010, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x8015, 0xa438, 0x1800, 0xa438, 0x801a, + 0xa438, 0x1800, 0xa438, 0x801e, 0xa438, 0x1800, 0xa438, 0x8027, + 0xa438, 0x1800, 0xa438, 0x8027, 0xa438, 0x1800, 0xa438, 0x8027, + 0xa438, 0x1800, 0xa438, 0x8027, 0xa438, 0x0c0f, 0xa438, 0x0505, + 0xa438, 0xba01, 0xa438, 0x1800, 0xa438, 0x015e, 0xa438, 0x0c0f, + 0xa438, 0x0506, 0xa438, 0xba02, 0xa438, 0x1800, 0xa438, 0x017c, + 0xa438, 0x9910, 0xa438, 0x9a03, 0xa438, 0x1800, 0xa438, 0x02d4, + 0xa438, 0x8580, 0xa438, 0xc090, 0xa438, 0x9a03, 0xa438, 0x1000, + 0xa438, 0x02c9, 0xa438, 0xd700, 0xa438, 0x5fa3, 0xa438, 0x1800, + 0xa438, 0x0067, 0xa436, 0xA08E, 0xa438, 0xffff, 0xa436, 0xA08C, + 0xa438, 0xffff, 0xa436, 0xA08A, 0xa438, 0xffff, 0xa436, 0xA088, + 0xa438, 0xffff, 0xa436, 0xA086, 0xa438, 0x018c, 0xa436, 0xA084, + 0xa438, 0x02d3, 0xa436, 0xA082, 0xa438, 0x017a, 0xa436, 0xA080, + 0xa438, 0x015c, 0xa436, 0xA090, 0xa438, 0x000f, 0xa436, 0xA016, + 0xa438, 0x0020, 0xa436, 0xA012, 0xa438, 0x0000, 0xa436, 0xA014, + 0xa438, 0x1800, 0xa438, 0x8010, 0xa438, 0x1800, 0xa438, 0x8023, + 0xa438, 0x1800, 0xa438, 0x8313, 0xa438, 0x1800, 0xa438, 0x831a, + 0xa438, 0x1800, 0xa438, 0x8489, 0xa438, 0x1800, 0xa438, 0x86b9, + 0xa438, 0x1800, 0xa438, 0x86c1, 0xa438, 0x1800, 0xa438, 0x87ad, + 0xa438, 0x1000, 0xa438, 0x124e, 0xa438, 0x9308, 0xa438, 0xb201, + 0xa438, 0xb301, 0xa438, 0xd701, 0xa438, 0x5fe0, 0xa438, 0xd2ff, + 0xa438, 0xb302, 0xa438, 0xd200, 0xa438, 0xb201, 0xa438, 0xb309, + 0xa438, 0xd701, 0xa438, 0x5fe0, 0xa438, 0xd2ff, 0xa438, 0xb302, + 0xa438, 0xd200, 0xa438, 0x1800, 0xa438, 0x0025, 0xa438, 0xd706, + 0xa438, 0x6069, 0xa438, 0xd700, 0xa438, 0x6421, 0xa438, 0xd70c, + 0xa438, 0x43ab, 0xa438, 0x800a, 0xa438, 0x8190, 0xa438, 0x8204, + 0xa438, 0xa280, 0xa438, 0x8406, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa108, 0xa438, 0x9503, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x0c1f, 0xa438, 0x0f19, 0xa438, 0x9503, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0x1000, + 0xa438, 0x11bd, 0xa438, 0x1800, 0xa438, 0x81aa, 0xa438, 0x8710, + 0xa438, 0xd701, 0xa438, 0x33b1, 0xa438, 0x8051, 0xa438, 0xd701, + 0xa438, 0x60b5, 0xa438, 0xd706, 0xa438, 0x6069, 0xa438, 0x1800, + 0xa438, 0x8056, 0xa438, 0xa00a, 0xa438, 0xa280, 0xa438, 0xa404, + 0xa438, 0x1800, 0xa438, 0x80f3, 0xa438, 0xd173, 0xa438, 0xd04d, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0xd173, 0xa438, 0xd05d, 0xa438, 0xd10d, 0xa438, 0xd049, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0xd700, 0xa438, 0x64f5, 0xa438, 0xd700, 0xa438, 0x5ee7, + 0xa438, 0xb920, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x7fb4, 0xa438, 0x9920, 0xa438, 0xcb3c, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7d94, 0xa438, 0x6045, + 0xa438, 0xfffa, 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd71f, 0xa438, 0x7fa5, 0xa438, 0x9820, 0xa438, 0xcb3d, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x60b5, + 0xa438, 0xd71f, 0xa438, 0x7bb4, 0xa438, 0x61b6, 0xa438, 0xfff8, + 0xa438, 0xbb80, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x5fb4, 0xa438, 0x9b80, 0xa438, 0xd700, 0xa438, 0x60e7, + 0xa438, 0xcb3f, 0xa438, 0x1800, 0xa438, 0x8094, 0xa438, 0xcb3e, + 0xa438, 0x1800, 0xa438, 0x810f, 0xa438, 0x1800, 0xa438, 0x80f3, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xae04, 0xa438, 0x9503, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8e04, 0xa438, 0x9503, 0xa438, 0xd706, 0xa438, 0x65fe, + 0xa438, 0x0c1f, 0xa438, 0x0d04, 0xa438, 0x8dc0, 0xa438, 0x1000, + 0xa438, 0x11bd, 0xa438, 0xd70c, 0xa438, 0x414b, 0xa438, 0x0cc0, + 0xa438, 0x0040, 0xa438, 0x0c03, 0xa438, 0x0102, 0xa438, 0x0ce0, + 0xa438, 0x03e0, 0xa438, 0xccce, 0xa438, 0x1800, 0xa438, 0x80b7, + 0xa438, 0x0cc0, 0xa438, 0x0040, 0xa438, 0x0c03, 0xa438, 0x0100, + 0xa438, 0x0ce0, 0xa438, 0x0380, 0xa438, 0xcc9c, 0xa438, 0x8710, + 0xa438, 0x1000, 0xa438, 0x1118, 0xa438, 0xa104, 0xa438, 0x1000, + 0xa438, 0x112a, 0xa438, 0x8104, 0xa438, 0xa202, 0xa438, 0xa140, + 0xa438, 0x1000, 0xa438, 0x112a, 0xa438, 0x8140, 0xa438, 0x1000, + 0xa438, 0x1121, 0xa438, 0xaa0f, 0xa438, 0xa130, 0xa438, 0xaa2f, + 0xa438, 0xa2d5, 0xa438, 0xa405, 0xa438, 0xa720, 0xa438, 0xa00a, + 0xa438, 0x1800, 0xa438, 0x80f3, 0xa438, 0xd704, 0xa438, 0x3cf1, + 0xa438, 0x80d5, 0xa438, 0x0c1f, 0xa438, 0x0d02, 0xa438, 0x1800, + 0xa438, 0x80d7, 0xa438, 0x0c1f, 0xa438, 0x0d01, 0xa438, 0x0cc0, + 0xa438, 0x0d40, 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x8710, + 0xa438, 0x1000, 0xa438, 0x1118, 0xa438, 0xa108, 0xa438, 0x1000, + 0xa438, 0x112a, 0xa438, 0x8108, 0xa438, 0xa203, 0xa438, 0x8a2f, + 0xa438, 0xa130, 0xa438, 0x8204, 0xa438, 0xa140, 0xa438, 0x1000, + 0xa438, 0x112a, 0xa438, 0x8140, 0xa438, 0x1000, 0xa438, 0x1121, + 0xa438, 0xd17a, 0xa438, 0xd04b, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xa204, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fa7, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fb4, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x6125, 0xa438, 0x6054, 0xa438, 0xfffb, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fa7, 0xa438, 0x1800, + 0xa438, 0x80f7, 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd71f, 0xa438, 0x7fa5, 0xa438, 0x9820, 0xa438, 0x9b01, + 0xa438, 0xd402, 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0xd701, + 0xa438, 0x33b1, 0xa438, 0x811c, 0xa438, 0xd701, 0xa438, 0x60b5, + 0xa438, 0xd706, 0xa438, 0x6069, 0xa438, 0x1800, 0xa438, 0x811e, + 0xa438, 0x1800, 0xa438, 0x8183, 0xa438, 0xd70c, 0xa438, 0x40ab, + 0xa438, 0x800a, 0xa438, 0x8110, 0xa438, 0x8284, 0xa438, 0x8404, + 0xa438, 0xa710, 0xa438, 0x8120, 0xa438, 0x8241, 0xa438, 0x1000, + 0xa438, 0x1118, 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x112a, + 0xa438, 0x8104, 0xa438, 0x1000, 0xa438, 0x1121, 0xa438, 0xaa2f, + 0xa438, 0xd70c, 0xa438, 0x438b, 0xa438, 0xa284, 0xa438, 0xd078, + 0xa438, 0x800a, 0xa438, 0x8110, 0xa438, 0xa284, 0xa438, 0x8404, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa108, 0xa438, 0x9503, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, 0xa438, 0x0f19, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd70c, + 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8f1f, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd70c, + 0xa438, 0x7f33, 0xa438, 0x0c1f, 0xa438, 0x0d06, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x8110, 0xa438, 0xa284, + 0xa438, 0xa404, 0xa438, 0xa00a, 0xa438, 0xd70c, 0xa438, 0x40a1, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xad10, 0xa438, 0x9503, + 0xa438, 0xd70c, 0xa438, 0x414b, 0xa438, 0x0cc0, 0xa438, 0x0080, + 0xa438, 0x0c03, 0xa438, 0x0102, 0xa438, 0x0ce0, 0xa438, 0x0340, + 0xa438, 0xcc52, 0xa438, 0x1800, 0xa438, 0x816b, 0xa438, 0x80c0, + 0xa438, 0x8103, 0xa438, 0x83e0, 0xa438, 0x8cff, 0xa438, 0xd193, + 0xa438, 0xd047, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0xa110, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, 0xa438, 0x1193, + 0xa438, 0xd700, 0xa438, 0x5f6a, 0xa438, 0xa180, 0xa438, 0xd1f5, + 0xa438, 0xd049, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0x8710, + 0xa438, 0xa00a, 0xa438, 0x8190, 0xa438, 0x8204, 0xa438, 0xa280, + 0xa438, 0xa404, 0xa438, 0xbb80, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd71f, 0xa438, 0x5fb4, 0xa438, 0xb920, 0xa438, 0x9b80, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fb4, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xcb33, + 0xa438, 0xd71f, 0xa438, 0x6105, 0xa438, 0x5f74, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fa7, 0xa438, 0x1800, + 0xa438, 0x818e, 0xa438, 0xa710, 0xa438, 0xb820, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7f65, 0xa438, 0x9820, + 0xa438, 0x1800, 0xa438, 0x81f1, 0xa438, 0x0c1f, 0xa438, 0x0d04, + 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0xa00a, + 0xa438, 0x8280, 0xa438, 0xa710, 0xa438, 0xd103, 0xa438, 0xd04c, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x0c1f, 0xa438, 0x0d06, 0xa438, 0x8dc0, 0xa438, 0x1000, + 0xa438, 0x11bd, 0xa438, 0x8710, 0xa438, 0xa190, 0xa438, 0xa204, + 0xa438, 0x8280, 0xa438, 0xa404, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd700, 0xa438, 0x5fa7, 0xa438, 0xa00a, 0xa438, 0xa110, + 0xa438, 0xa284, 0xa438, 0xa404, 0xa438, 0xcb33, 0xa438, 0xd71f, + 0xa438, 0x5f54, 0xa438, 0xb920, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd71f, 0xa438, 0x7fb4, 0xa438, 0x9920, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x6145, 0xa438, 0x6074, + 0xa438, 0x1800, 0xa438, 0x81d3, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd700, 0xa438, 0x5fa7, 0xa438, 0x1800, 0xa438, 0x81cd, + 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x7fa5, 0xa438, 0xa710, 0xa438, 0x9820, 0xa438, 0xbb20, + 0xa438, 0x9308, 0xa438, 0xb210, 0xa438, 0xb301, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd701, 0xa438, 0x5fa4, 0xa438, 0xb302, + 0xa438, 0x9210, 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0xa284, + 0xa438, 0xa404, 0xa438, 0xcb34, 0xa438, 0xd701, 0xa438, 0x33b1, + 0xa438, 0x823f, 0xa438, 0xd706, 0xa438, 0x60a9, 0xa438, 0xd1f5, + 0xa438, 0xd049, 0xa438, 0x1800, 0xa438, 0x8201, 0xa438, 0xd13c, + 0xa438, 0xd04a, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0xd700, + 0xa438, 0x5f2b, 0xa438, 0x0c1f, 0xa438, 0x0d03, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x8190, 0xa438, 0x8204, + 0xa438, 0xa280, 0xa438, 0xa00a, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8304, 0xa438, 0x9503, 0xa438, 0xcb35, 0xa438, 0xd70c, + 0xa438, 0x414b, 0xa438, 0x8280, 0xa438, 0x800a, 0xa438, 0xd411, + 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0x1000, 0xa438, 0x11bd, + 0xa438, 0xa280, 0xa438, 0xa00a, 0xa438, 0xd40a, 0xa438, 0xcb36, + 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0xd706, 0xa438, 0x431b, + 0xa438, 0x800a, 0xa438, 0x8180, 0xa438, 0x8280, 0xa438, 0x8404, + 0xa438, 0xa004, 0xa438, 0x1000, 0xa438, 0x112a, 0xa438, 0x8004, + 0xa438, 0xa001, 0xa438, 0x1000, 0xa438, 0x112a, 0xa438, 0x8001, + 0xa438, 0x0c03, 0xa438, 0x0902, 0xa438, 0xa00a, 0xa438, 0xd14a, + 0xa438, 0xd048, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0x0c1f, + 0xa438, 0x0d06, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x11bd, + 0xa438, 0xd70c, 0xa438, 0x414b, 0xa438, 0x0cc0, 0xa438, 0x0080, + 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x03a0, + 0xa438, 0xccb5, 0xa438, 0x1800, 0xa438, 0x8256, 0xa438, 0x0cc0, + 0xa438, 0x0000, 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0x0ce0, + 0xa438, 0x0320, 0xa438, 0xcc21, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x0c30, 0xa438, 0x0120, 0xa438, 0xa304, 0xa438, 0x9503, + 0xa438, 0xd70c, 0xa438, 0x674b, 0xa438, 0xd704, 0xa438, 0x471a, + 0xa438, 0xa301, 0xa438, 0x800a, 0xa438, 0xa110, 0xa438, 0x8180, + 0xa438, 0xa204, 0xa438, 0x82a0, 0xa438, 0xa404, 0xa438, 0xaa40, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xaa01, 0xa438, 0x9503, + 0xa438, 0xd178, 0xa438, 0xd049, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0x1000, 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, + 0xa438, 0x8301, 0xa438, 0xa00a, 0xa438, 0x8110, 0xa438, 0xa180, + 0xa438, 0xa284, 0xa438, 0x8220, 0xa438, 0xa404, 0xa438, 0xd178, + 0xa438, 0xd048, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0xcb3a, + 0xa438, 0x8301, 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0xa280, + 0xa438, 0x8224, 0xa438, 0xa404, 0xa438, 0xd700, 0xa438, 0x6041, + 0xa438, 0xa402, 0xa438, 0xd178, 0xa438, 0xd049, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0x1000, 0xa438, 0x1193, 0xa438, 0xd700, + 0xa438, 0x5f74, 0xa438, 0x1800, 0xa438, 0x82ab, 0xa438, 0xa00a, + 0xa438, 0xa190, 0xa438, 0xa2a4, 0xa438, 0xa404, 0xa438, 0xd700, + 0xa438, 0x6041, 0xa438, 0xa402, 0xa438, 0xcb37, 0xa438, 0xd706, + 0xa438, 0x60a9, 0xa438, 0xd13d, 0xa438, 0xd04a, 0xa438, 0x1800, + 0xa438, 0x82a7, 0xa438, 0xd13c, 0xa438, 0xd04b, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0x1000, 0xa438, 0x1193, 0xa438, 0xd700, + 0xa438, 0x5f6b, 0xa438, 0x0c1f, 0xa438, 0x0d07, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0xd40d, 0xa438, 0x1000, + 0xa438, 0x110d, 0xa438, 0xa208, 0xa438, 0x8204, 0xa438, 0xaa40, + 0xa438, 0xcb38, 0xa438, 0xd706, 0xa438, 0x6129, 0xa438, 0xd70c, + 0xa438, 0x608b, 0xa438, 0xd17a, 0xa438, 0xd047, 0xa438, 0xf006, + 0xa438, 0xd13d, 0xa438, 0xd04b, 0xa438, 0xf003, 0xa438, 0xd196, + 0xa438, 0xd04b, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0xd704, + 0xa438, 0x35ac, 0xa438, 0x8311, 0xa438, 0x0cc0, 0xa438, 0x0000, + 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x0320, + 0xa438, 0xcc21, 0xa438, 0x0c1f, 0xa438, 0x0d03, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x0cc0, 0xa438, 0x0000, + 0xa438, 0x0c07, 0xa438, 0x0c07, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa280, 0xa438, 0x8780, 0xa438, 0x0c60, 0xa438, 0x0700, + 0xa438, 0x9503, 0xa438, 0xd704, 0xa438, 0x409c, 0xa438, 0xd110, + 0xa438, 0xd04d, 0xa438, 0xf003, 0xa438, 0xd110, 0xa438, 0xd04d, + 0xa438, 0xcb4a, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa240, + 0xa438, 0xa180, 0xa438, 0xa201, 0xa438, 0xa780, 0xa438, 0x9503, + 0xa438, 0xd114, 0xa438, 0xd04a, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0xcb4b, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x1800, + 0xa438, 0x0bc3, 0xa438, 0x1800, 0xa438, 0x0bc3, 0xa438, 0x1000, + 0xa438, 0x110d, 0xa438, 0xd419, 0xa438, 0x1000, 0xa438, 0x110d, + 0xa438, 0x1800, 0xa438, 0x01ae, 0xa438, 0x8110, 0xa438, 0xa180, + 0xa438, 0x8280, 0xa438, 0xa404, 0xa438, 0xa00a, 0xa438, 0x8402, + 0xa438, 0xcb42, 0xa438, 0xd706, 0xa438, 0x3de9, 0xa438, 0x837a, + 0xa438, 0xd704, 0xa438, 0x35ac, 0xa438, 0x8380, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fab, 0xa438, 0x0c1f, + 0xa438, 0x0d06, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x11bd, + 0xa438, 0xd418, 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0x0c1f, + 0xa438, 0x0d03, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x11bd, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa780, 0xa438, 0xa20e, + 0xa438, 0x9503, 0xa438, 0xd704, 0xa438, 0x409c, 0xa438, 0xd114, + 0xa438, 0xd04d, 0xa438, 0xf003, 0xa438, 0xd114, 0xa438, 0xd04d, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa003, 0xa438, 0x9503, + 0xa438, 0xcb4c, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c60, + 0xa438, 0x0720, 0xa438, 0xa220, 0xa438, 0x9503, 0xa438, 0xcb4d, + 0xa438, 0xd704, 0xa438, 0x409c, 0xa438, 0xd128, 0xa438, 0xd04f, + 0xa438, 0xf003, 0xa438, 0xd128, 0xa438, 0xd04f, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0x0c60, 0xa438, 0x0740, 0xa438, 0xa210, + 0xa438, 0x9503, 0xa438, 0xd704, 0xa438, 0x409c, 0xa438, 0xd114, + 0xa438, 0xd04e, 0xa438, 0xf003, 0xa438, 0xd114, 0xa438, 0xd04e, + 0xa438, 0xcb4e, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x0c1f, 0xa438, 0x0d06, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x0cc0, 0xa438, 0x0000, + 0xa438, 0x0c07, 0xa438, 0x0c01, 0xa438, 0xd704, 0xa438, 0x40b5, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa23c, 0xa438, 0x9503, + 0xa438, 0xb920, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x7fb4, 0xa438, 0x8710, 0xa438, 0x9920, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x6105, 0xa438, 0x6054, + 0xa438, 0xfffb, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x5fa7, 0xa438, 0xffef, 0xa438, 0xa710, 0xa438, 0xb820, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fa5, + 0xa438, 0x9820, 0xa438, 0xa00a, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa103, 0xa438, 0x9503, 0xa438, 0xbb20, 0xa438, 0xd706, + 0xa438, 0x60dd, 0xa438, 0x0c1f, 0xa438, 0x0d07, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x0c30, 0xa438, 0x0120, 0xa438, 0xa304, 0xa438, 0x9503, + 0xa438, 0xa190, 0xa438, 0xa2a0, 0xa438, 0xa404, 0xa438, 0xa00a, + 0xa438, 0xa604, 0xa438, 0xd700, 0xa438, 0x6041, 0xa438, 0xa402, + 0xa438, 0xcb43, 0xa438, 0xd17a, 0xa438, 0xd048, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0x1000, 0xa438, 0x1193, 0xa438, 0xd700, + 0xa438, 0x5f74, 0xa438, 0x609d, 0xa438, 0xd417, 0xa438, 0x1000, + 0xa438, 0x110d, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd700, 0xa438, 0x5f7a, 0xa438, 0xd704, + 0xa438, 0x5f36, 0xa438, 0xd706, 0xa438, 0x6089, 0xa438, 0xd40c, + 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0xaa40, 0xa438, 0xbb10, + 0xa438, 0xcb50, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0x1000, + 0xa438, 0x1193, 0xa438, 0xd71f, 0xa438, 0x5f75, 0xa438, 0x8190, + 0xa438, 0x82a0, 0xa438, 0x8402, 0xa438, 0xa404, 0xa438, 0x800a, + 0xa438, 0x8718, 0xa438, 0x9b10, 0xa438, 0x9b20, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fb5, 0xa438, 0xcb51, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x5f94, + 0xa438, 0xd706, 0xa438, 0x6089, 0xa438, 0xd141, 0xa438, 0xd043, + 0xa438, 0xf003, 0xa438, 0xd141, 0xa438, 0xd044, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xd700, + 0xa438, 0x60e5, 0xa438, 0xd704, 0xa438, 0x60be, 0xa438, 0xd706, + 0xa438, 0x29b1, 0xa438, 0x83fb, 0xa438, 0xf002, 0xa438, 0xa880, + 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0x8220, 0xa438, 0xa280, + 0xa438, 0xa404, 0xa438, 0xa620, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xc5aa, 0xa438, 0x9503, 0xa438, 0xd700, 0xa438, 0x6061, + 0xa438, 0xa402, 0xa438, 0xa480, 0xa438, 0xcb52, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fba, 0xa438, 0xd704, + 0xa438, 0x5f76, 0xa438, 0xb920, 0xa438, 0xcb53, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fb4, 0xa438, 0x9920, + 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0xa280, 0xa438, 0x8220, + 0xa438, 0xa404, 0xa438, 0xb580, 0xa438, 0xd700, 0xa438, 0x40a1, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa602, 0xa438, 0x9503, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa310, 0xa438, 0x9503, + 0xa438, 0xcb60, 0xa438, 0xd1c8, 0xa438, 0xd045, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xaa10, + 0xa438, 0xd70c, 0xa438, 0x2833, 0xa438, 0x8434, 0xa438, 0xf003, + 0xa438, 0x1000, 0xa438, 0x1238, 0xa438, 0xd70c, 0xa438, 0x40a6, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa140, 0xa438, 0x9503, + 0xa438, 0xd70c, 0xa438, 0x40a3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xac20, 0xa438, 0x9503, 0xa438, 0xa90c, 0xa438, 0xaa80, + 0xa438, 0x0c1f, 0xa438, 0x0d07, 0xa438, 0x8dc0, 0xa438, 0x1000, + 0xa438, 0x11bd, 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0xa280, + 0xa438, 0x8220, 0xa438, 0xa404, 0xa438, 0xb580, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xc500, 0xa438, 0x9503, 0xa438, 0x83e0, + 0xa438, 0xd700, 0xa438, 0x40c1, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa602, 0xa438, 0x9503, 0xa438, 0x8e01, 0xa438, 0xd14a, + 0xa438, 0xd058, 0xa438, 0xd70c, 0xa438, 0x4063, 0xa438, 0x1000, + 0xa438, 0x11f2, 0xa438, 0xcb62, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd704, 0xa438, 0x2e70, 0xa438, 0x8479, 0xa438, 0xd71f, + 0xa438, 0x626e, 0xa438, 0xd704, 0xa438, 0x3868, 0xa438, 0x847d, + 0xa438, 0xd70c, 0xa438, 0x2f18, 0xa438, 0x8483, 0xa438, 0xd700, + 0xa438, 0x5db5, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xc5aa, + 0xa438, 0x9503, 0xa438, 0x0ce0, 0xa438, 0x0320, 0xa438, 0x1800, + 0xa438, 0x0d6f, 0xa438, 0x1800, 0xa438, 0x0f15, 0xa438, 0x1800, + 0xa438, 0x0dae, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xc5aa, + 0xa438, 0x9503, 0xa438, 0x1800, 0xa438, 0x0fc9, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xc5aa, 0xa438, 0x9503, 0xa438, 0x1800, + 0xa438, 0x0d84, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0xd70c, + 0xa438, 0x5fa4, 0xa438, 0xa706, 0xa438, 0xd70c, 0xa438, 0x408b, + 0xa438, 0xa701, 0xa438, 0xa502, 0xa438, 0xa880, 0xa438, 0x8801, + 0xa438, 0x8e01, 0xa438, 0xca50, 0xa438, 0x1000, 0xa438, 0x852e, + 0xa438, 0xca51, 0xa438, 0xd70e, 0xa438, 0x2210, 0xa438, 0x852c, + 0xa438, 0xd70c, 0xa438, 0x4084, 0xa438, 0xd705, 0xa438, 0x5efd, + 0xa438, 0xf007, 0xa438, 0x1000, 0xa438, 0x16e9, 0xa438, 0xd70c, + 0xa438, 0x5ca2, 0xa438, 0x1800, 0xa438, 0x15b2, 0xa438, 0xd70c, + 0xa438, 0x605a, 0xa438, 0x9a10, 0xa438, 0x8e40, 0xa438, 0x8404, + 0xa438, 0x1000, 0xa438, 0x174e, 0xa438, 0x8e80, 0xa438, 0xca62, + 0xa438, 0xd705, 0xa438, 0x3084, 0xa438, 0x850e, 0xa438, 0xba10, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x1000, 0xa438, 0x8608, + 0xa438, 0x0c03, 0xa438, 0x0100, 0xa438, 0xd702, 0xa438, 0x4638, + 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0x1000, 0xa438, 0x16e5, + 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f7c, + 0xa438, 0x8108, 0xa438, 0x0c1f, 0xa438, 0x0907, 0xa438, 0x8940, + 0xa438, 0x1000, 0xa438, 0x1702, 0xa438, 0xa0c4, 0xa438, 0x8610, + 0xa438, 0x8030, 0xa438, 0x8706, 0xa438, 0x0c07, 0xa438, 0x0b06, + 0xa438, 0x8410, 0xa438, 0xa980, 0xa438, 0xa702, 0xa438, 0xd1c4, + 0xa438, 0xd045, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0x1000, + 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x0c07, + 0xa438, 0x0b06, 0xa438, 0xa030, 0xa438, 0xa610, 0xa438, 0xd700, + 0xa438, 0x6041, 0xa438, 0xa501, 0xa438, 0xa108, 0xa438, 0xd1c4, + 0xa438, 0xd045, 0xa438, 0xca63, 0xa438, 0x1000, 0xa438, 0x16e5, + 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f7c, + 0xa438, 0xd702, 0xa438, 0x6078, 0xa438, 0x9920, 0xa438, 0xf003, + 0xa438, 0xb920, 0xa438, 0xa880, 0xa438, 0x9a10, 0xa438, 0x1000, + 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd71f, + 0xa438, 0x5f73, 0xa438, 0xf011, 0xa438, 0xd70c, 0xa438, 0x409b, + 0xa438, 0x9920, 0xa438, 0x9a10, 0xa438, 0xfff5, 0xa438, 0x80fe, + 0xa438, 0x8610, 0xa438, 0x8501, 0xa438, 0x8980, 0xa438, 0x8702, + 0xa438, 0xa410, 0xa438, 0xa940, 0xa438, 0x81c0, 0xa438, 0xae80, + 0xa438, 0x1800, 0xa438, 0x84b3, 0xa438, 0x8804, 0xa438, 0xa704, + 0xa438, 0x8788, 0xa438, 0xff80, 0xa438, 0xbb08, 0xa438, 0x0c1f, + 0xa438, 0x0907, 0xa438, 0x8940, 0xa438, 0x1000, 0xa438, 0x1702, + 0xa438, 0x8701, 0xa438, 0x8502, 0xa438, 0xa0f4, 0xa438, 0xa610, + 0xa438, 0xd700, 0xa438, 0x6061, 0xa438, 0xa002, 0xa438, 0xa501, + 0xa438, 0x8706, 0xa438, 0x8410, 0xa438, 0xa980, 0xa438, 0xca64, + 0xa438, 0xd110, 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x16e5, + 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f7c, + 0xa438, 0x8804, 0xa438, 0xa706, 0xa438, 0x1800, 0xa438, 0x848d, + 0xa438, 0x1800, 0xa438, 0x1384, 0xa438, 0xd705, 0xa438, 0x405f, + 0xa438, 0xf036, 0xa438, 0xd705, 0xa438, 0x6234, 0xa438, 0xd70c, + 0xa438, 0x41c6, 0xa438, 0xd70d, 0xa438, 0x419d, 0xa438, 0xd70d, + 0xa438, 0x417e, 0xa438, 0xd704, 0xa438, 0x6127, 0xa438, 0x2951, + 0xa438, 0x8543, 0xa438, 0xd70c, 0xa438, 0x4083, 0xa438, 0xd70c, + 0xa438, 0x2e81, 0xa438, 0x8543, 0xa438, 0xf0c5, 0xa438, 0x80fe, + 0xa438, 0x8610, 0xa438, 0x8501, 0xa438, 0x8704, 0xa438, 0x0c30, + 0xa438, 0x0410, 0xa438, 0xa701, 0xa438, 0xac02, 0xa438, 0xa502, + 0xa438, 0x8980, 0xa438, 0xca60, 0xa438, 0xa004, 0xa438, 0xd70c, + 0xa438, 0x6065, 0xa438, 0x1800, 0xa438, 0x8554, 0xa438, 0x8004, + 0xa438, 0xa804, 0xa438, 0x0c0f, 0xa438, 0x0602, 0xa438, 0x0c70, + 0xa438, 0x0730, 0xa438, 0xa708, 0xa438, 0xd704, 0xa438, 0x609c, + 0xa438, 0x0c1f, 0xa438, 0x0912, 0xa438, 0xf003, 0xa438, 0x0c1f, + 0xa438, 0x090e, 0xa438, 0xa940, 0xa438, 0x1000, 0xa438, 0x1702, + 0xa438, 0xa780, 0xa438, 0xf0a2, 0xa438, 0xd704, 0xa438, 0x63eb, + 0xa438, 0xd705, 0xa438, 0x43b1, 0xa438, 0xd702, 0xa438, 0x339c, + 0xa438, 0x8607, 0xa438, 0x8788, 0xa438, 0x8704, 0xa438, 0x0c1f, + 0xa438, 0x0907, 0xa438, 0x8940, 0xa438, 0x1000, 0xa438, 0x1702, + 0xa438, 0x8410, 0xa438, 0xa0f4, 0xa438, 0xa610, 0xa438, 0xd700, + 0xa438, 0x6061, 0xa438, 0xa002, 0xa438, 0xa501, 0xa438, 0xa706, + 0xa438, 0x8804, 0xa438, 0xa980, 0xa438, 0xd70c, 0xa438, 0x6085, + 0xa438, 0x8701, 0xa438, 0x8502, 0xa438, 0x8c02, 0xa438, 0xa701, + 0xa438, 0xa502, 0xa438, 0xf082, 0xa438, 0xd70c, 0xa438, 0x60c5, + 0xa438, 0xd702, 0xa438, 0x6053, 0xa438, 0xf07d, 0xa438, 0x1800, + 0xa438, 0x8604, 0xa438, 0xd70d, 0xa438, 0x4d1b, 0xa438, 0xba10, + 0xa438, 0xae40, 0xa438, 0x0cfc, 0xa438, 0x03b4, 0xa438, 0x0cfc, + 0xa438, 0x05b4, 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0x1000, + 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, + 0xa438, 0x5f7c, 0xa438, 0x8706, 0xa438, 0x8280, 0xa438, 0xace0, + 0xa438, 0xa680, 0xa438, 0xa240, 0xa438, 0x1000, 0xa438, 0x16e5, + 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd702, 0xa438, 0x5f79, + 0xa438, 0x8240, 0xa438, 0xd702, 0xa438, 0x6898, 0xa438, 0xd702, + 0xa438, 0x4957, 0xa438, 0x1800, 0xa438, 0x85f6, 0xa438, 0xa1c0, + 0xa438, 0x0c3f, 0xa438, 0x0220, 0xa438, 0x0cfc, 0xa438, 0x030c, + 0xa438, 0x0cfc, 0xa438, 0x050c, 0xa438, 0x8108, 0xa438, 0x8640, + 0xa438, 0xa120, 0xa438, 0xa640, 0xa438, 0x0c03, 0xa438, 0x0101, + 0xa438, 0xa110, 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0xca84, + 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, + 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0xd702, 0xa438, 0x60fc, + 0xa438, 0x8210, 0xa438, 0x0ce0, 0xa438, 0x0320, 0xa438, 0x0ce0, + 0xa438, 0x0520, 0xa438, 0xf002, 0xa438, 0xa210, 0xa438, 0xd1c4, + 0xa438, 0xd043, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0x1000, + 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x8233, + 0xa438, 0x0cfc, 0xa438, 0x036c, 0xa438, 0x0cfc, 0xa438, 0x056c, + 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0xca85, 0xa438, 0x1000, + 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, + 0xa438, 0x5f7c, 0xa438, 0xa680, 0xa438, 0xa240, 0xa438, 0x1000, + 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd702, + 0xa438, 0x5f79, 0xa438, 0x8240, 0xa438, 0x0cfc, 0xa438, 0x0390, + 0xa438, 0x0cfc, 0xa438, 0x0590, 0xa438, 0xd702, 0xa438, 0x6058, + 0xa438, 0xf002, 0xa438, 0xfec7, 0xa438, 0x81c0, 0xa438, 0x8880, + 0xa438, 0x8706, 0xa438, 0xca61, 0xa438, 0xd1c4, 0xa438, 0xd054, + 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0x1000, 0xa438, 0x170f, + 0xa438, 0xd70c, 0xa438, 0x5f7d, 0xa438, 0xa706, 0xa438, 0xf004, + 0xa438, 0x8788, 0xa438, 0xa404, 0xa438, 0x8702, 0xa438, 0x0800, + 0xa438, 0x8443, 0xa438, 0x8303, 0xa438, 0x8280, 0xa438, 0x9920, + 0xa438, 0x8ce0, 0xa438, 0x8004, 0xa438, 0xa1c0, 0xa438, 0xd70e, + 0xa438, 0x404a, 0xa438, 0xa280, 0xa438, 0xd702, 0xa438, 0x3bd0, + 0xa438, 0x8618, 0xa438, 0x0c3f, 0xa438, 0x0223, 0xa438, 0xf003, + 0xa438, 0x0c3f, 0xa438, 0x0220, 0xa438, 0x0cfc, 0xa438, 0x0308, + 0xa438, 0x0cfc, 0xa438, 0x0508, 0xa438, 0x8108, 0xa438, 0x8640, + 0xa438, 0xa120, 0xa438, 0xa640, 0xa438, 0xd702, 0xa438, 0x6077, + 0xa438, 0x8103, 0xa438, 0xf003, 0xa438, 0x0c03, 0xa438, 0x0101, + 0xa438, 0xa110, 0xa438, 0xd702, 0xa438, 0x6077, 0xa438, 0xa108, + 0xa438, 0xf006, 0xa438, 0xd704, 0xa438, 0x6077, 0xa438, 0x8108, + 0xa438, 0xf002, 0xa438, 0xa108, 0xa438, 0xd193, 0xa438, 0xd045, + 0xa438, 0xca82, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0xd70e, + 0xa438, 0x606a, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, + 0xa438, 0x5f3c, 0xa438, 0xd702, 0xa438, 0x60fc, 0xa438, 0x8210, + 0xa438, 0x0ce0, 0xa438, 0x0320, 0xa438, 0x0ce0, 0xa438, 0x0520, + 0xa438, 0xf002, 0xa438, 0xa210, 0xa438, 0xd1c4, 0xa438, 0xd043, + 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0xd70e, 0xa438, 0x606a, + 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f3c, + 0xa438, 0xd702, 0xa438, 0x3bd0, 0xa438, 0x8656, 0xa438, 0x0c3f, + 0xa438, 0x020c, 0xa438, 0xf002, 0xa438, 0x823f, 0xa438, 0x0cfc, + 0xa438, 0x034c, 0xa438, 0x0cfc, 0xa438, 0x054c, 0xa438, 0xd1c4, + 0xa438, 0xd044, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0xd70e, + 0xa438, 0x606a, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd70c, + 0xa438, 0x5f3c, 0xa438, 0x820c, 0xa438, 0xa360, 0xa438, 0xa560, + 0xa438, 0xd1c4, 0xa438, 0xd043, 0xa438, 0xca83, 0xa438, 0x1000, + 0xa438, 0x16e5, 0xa438, 0xd70e, 0xa438, 0x606a, 0xa438, 0x1000, + 0xa438, 0x170f, 0xa438, 0xd70c, 0xa438, 0x5f3c, 0xa438, 0xd70e, + 0xa438, 0x406a, 0xa438, 0x8680, 0xa438, 0xf002, 0xa438, 0xa680, + 0xa438, 0xa240, 0xa438, 0x0c0f, 0xa438, 0x0604, 0xa438, 0x0c70, + 0xa438, 0x0750, 0xa438, 0xa708, 0xa438, 0xd704, 0xa438, 0x609c, + 0xa438, 0x0c1f, 0xa438, 0x0914, 0xa438, 0xf003, 0xa438, 0x0c1f, + 0xa438, 0x0910, 0xa438, 0xa940, 0xa438, 0x1000, 0xa438, 0x1702, + 0xa438, 0xa780, 0xa438, 0x1000, 0xa438, 0x16e5, 0xa438, 0xd70e, + 0xa438, 0x606a, 0xa438, 0x1000, 0xa438, 0x170f, 0xa438, 0xd702, + 0xa438, 0x399c, 0xa438, 0x8689, 0xa438, 0x8240, 0xa438, 0x8788, + 0xa438, 0xd702, 0xa438, 0x63f8, 0xa438, 0xd705, 0xa438, 0x643c, + 0xa438, 0xa402, 0xa438, 0xf012, 0xa438, 0x8402, 0xa438, 0xd705, + 0xa438, 0x611b, 0xa438, 0xa401, 0xa438, 0xa302, 0xa438, 0xd702, + 0xa438, 0x417d, 0xa438, 0xa440, 0xa438, 0xa280, 0xa438, 0xf008, + 0xa438, 0x8401, 0xa438, 0x8302, 0xa438, 0xd70c, 0xa438, 0x6060, + 0xa438, 0xa301, 0xa438, 0xf002, 0xa438, 0x8301, 0xa438, 0xd70c, + 0xa438, 0x4080, 0xa438, 0xd70e, 0xa438, 0x604a, 0xa438, 0xff5f, + 0xa438, 0xd705, 0xa438, 0x3cdd, 0xa438, 0x86b8, 0xa438, 0xff5b, + 0xa438, 0x0cfc, 0xa438, 0x0390, 0xa438, 0x0cfc, 0xa438, 0x0590, + 0xa438, 0x0800, 0xa438, 0x0c1f, 0xa438, 0x0d00, 0xa438, 0x8dc0, + 0xa438, 0x1000, 0xa438, 0x11bd, 0xa438, 0xa504, 0xa438, 0x1800, + 0xa438, 0x0fd3, 0xa438, 0xd70d, 0xa438, 0x407d, 0xa438, 0xa710, + 0xa438, 0xf002, 0xa438, 0xa710, 0xa438, 0x9580, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xa304, 0xa438, 0x9503, 0xa438, 0x0c1f, + 0xa438, 0x0d07, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x11bd, + 0xa438, 0xcb81, 0xa438, 0xd70c, 0xa438, 0x4882, 0xa438, 0xd706, + 0xa438, 0x407a, 0xa438, 0xd70c, 0xa438, 0x4807, 0xa438, 0xd706, + 0xa438, 0x405a, 0xa438, 0x8910, 0xa438, 0xa210, 0xa438, 0xd704, + 0xa438, 0x611c, 0xa438, 0x0cc0, 0xa438, 0x0080, 0xa438, 0x0c03, + 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x03a0, 0xa438, 0xccb5, + 0xa438, 0x0cc0, 0xa438, 0x0080, 0xa438, 0x0c03, 0xa438, 0x0102, + 0xa438, 0x0ce0, 0xa438, 0x0340, 0xa438, 0xcc52, 0xa438, 0xd706, + 0xa438, 0x42ba, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, + 0xa438, 0x0f1c, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0x8190, 0xa438, 0x8204, + 0xa438, 0xf016, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, + 0xa438, 0x0f1b, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0xd70c, 0xa438, 0x6047, + 0xa438, 0xf002, 0xa438, 0xf00c, 0xa438, 0xd403, 0xa438, 0xcb82, + 0xa438, 0x1000, 0xa438, 0x110d, 0xa438, 0xd40a, 0xa438, 0x1000, + 0xa438, 0x110d, 0xa438, 0xd70c, 0xa438, 0x4247, 0xa438, 0x1000, + 0xa438, 0x1225, 0xa438, 0x8a40, 0xa438, 0x1000, 0xa438, 0x1118, + 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x112a, 0xa438, 0x8104, + 0xa438, 0x1000, 0xa438, 0x1121, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa704, 0xa438, 0x9503, 0xa438, 0xcb88, 0xa438, 0xf012, + 0xa438, 0xa210, 0xa438, 0xa00a, 0xa438, 0xaa40, 0xa438, 0x1000, + 0xa438, 0x1118, 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x112a, + 0xa438, 0x8104, 0xa438, 0x1000, 0xa438, 0x1121, 0xa438, 0xa190, + 0xa438, 0xa284, 0xa438, 0xa404, 0xa438, 0x8a10, 0xa438, 0x8a80, + 0xa438, 0xcb84, 0xa438, 0xd13e, 0xa438, 0xd05a, 0xa438, 0xd13e, + 0xa438, 0xd06b, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x3559, 0xa438, 0x874b, 0xa438, 0xfffb, 0xa438, 0xd700, + 0xa438, 0x604b, 0xa438, 0xcb8a, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd700, 0xa438, 0x3659, 0xa438, 0x8754, 0xa438, 0xfffb, + 0xa438, 0xd700, 0xa438, 0x606b, 0xa438, 0xcb8b, 0xa438, 0x5eeb, + 0xa438, 0xd700, 0xa438, 0x6041, 0xa438, 0xa402, 0xa438, 0xcb8c, + 0xa438, 0xd706, 0xa438, 0x609a, 0xa438, 0xd1f5, 0xa438, 0xd048, + 0xa438, 0xf003, 0xa438, 0xd160, 0xa438, 0xd04b, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xcb8d, + 0xa438, 0x8710, 0xa438, 0xd71f, 0xa438, 0x5fd4, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, 0xa438, 0x7fb4, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd71f, + 0xa438, 0x6105, 0xa438, 0x6054, 0xa438, 0xfffb, 0xa438, 0x1000, + 0xa438, 0x1175, 0xa438, 0xd700, 0xa438, 0x5fab, 0xa438, 0xfff0, + 0xa438, 0xa710, 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd71f, 0xa438, 0x7fa5, 0xa438, 0x9820, 0xa438, 0xd114, + 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd700, + 0xa438, 0x5fba, 0xa438, 0xd704, 0xa438, 0x5f76, 0xa438, 0xd700, + 0xa438, 0x5f34, 0xa438, 0xd700, 0xa438, 0x6081, 0xa438, 0xd706, + 0xa438, 0x405a, 0xa438, 0xa480, 0xa438, 0xcb86, 0xa438, 0xd706, + 0xa438, 0x609a, 0xa438, 0xd1c8, 0xa438, 0xd045, 0xa438, 0xf003, + 0xa438, 0xd17a, 0xa438, 0xd04b, 0xa438, 0x1000, 0xa438, 0x1175, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x0cc0, 0xa438, 0x0000, + 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x0320, + 0xa438, 0xcc29, 0xa438, 0xa208, 0xa438, 0x8204, 0xa438, 0xd114, + 0xa438, 0xd040, 0xa438, 0xd700, 0xa438, 0x5ff4, 0xa438, 0x1800, + 0xa438, 0x0bc3, 0xa438, 0xa00a, 0xa438, 0x9308, 0xa438, 0xb210, + 0xa438, 0xb301, 0xa438, 0x1000, 0xa438, 0x1175, 0xa438, 0xd701, + 0xa438, 0x5fa4, 0xa438, 0xb302, 0xa438, 0x9210, 0xa438, 0x800a, + 0xa438, 0x1800, 0xa438, 0x0573, 0xa436, 0xA10E, 0xa438, 0x0572, + 0xa436, 0xA10C, 0xa438, 0x0e47, 0xa436, 0xA10A, 0xa438, 0x0fd2, + 0xa436, 0xA108, 0xa438, 0x1503, 0xa436, 0xA106, 0xa438, 0x0c0d, + 0xa436, 0xA104, 0xa438, 0x01ac, 0xa436, 0xA102, 0xa438, 0x0956, + 0xa436, 0xA100, 0xa438, 0x001c, 0xa436, 0xA110, 0xa438, 0x00ff, + 0xa436, 0xA016, 0xa438, 0x0020, 0xa436, 0xA012, 0xa438, 0x1ff8, + 0xa436, 0xA014, 0xa438, 0x0000, 0xa438, 0x85f0, 0xa438, 0xa2a0, + 0xa438, 0x8880, 0xa438, 0x0d00, 0xa438, 0xc500, 0xa438, 0x800a, + 0xa438, 0xae01, 0xa436, 0xA164, 0xa438, 0x1013, 0xa436, 0xA166, + 0xa438, 0x1014, 0xa436, 0xA168, 0xa438, 0x0F98, 0xa436, 0xA16A, + 0xa438, 0x0DCA, 0xa436, 0xA16C, 0xa438, 0x109B, 0xa436, 0xA16E, + 0xa438, 0x10A2, 0xa436, 0xA170, 0xa438, 0x0F33, 0xa436, 0xA172, + 0xa438, 0x0F6E, 0xa436, 0xA162, 0xa438, 0x00ff, 0xa436, 0xb87c, + 0xa438, 0x8a45, 0xa436, 0xb87e, 0xa438, 0xaf8a, 0xa438, 0x5daf, + 0xa438, 0x8a63, 0xa438, 0xaf8a, 0xa438, 0x6caf, 0xa438, 0x8a78, + 0xa438, 0xaf8a, 0xa438, 0x87af, 0xa438, 0x8a90, 0xa438, 0xaf8a, + 0xa438, 0x96af, 0xa438, 0x8acf, 0xa438, 0x028a, 0xa438, 0xecaf, + 0xa438, 0x211f, 0xa438, 0x0265, 0xa438, 0xcb02, 0xa438, 0x8fb4, + 0xa438, 0xaf21, 0xa438, 0x6fa1, 0xa438, 0x1903, 0xa438, 0x028f, + 0xa438, 0x3d02, 0xa438, 0x2261, 0xa438, 0xaf21, 0xa438, 0x2ead, + 0xa438, 0x2109, 0xa438, 0xe08f, 0xa438, 0xffac, 0xa438, 0x2503, + 0xa438, 0xaf4b, 0xa438, 0xeeaf, 0xa438, 0x4beb, 0xa438, 0xad35, + 0xa438, 0x03af, 0xa438, 0x421b, 0xa438, 0xaf42, 0xa438, 0x5ce1, + 0xa438, 0x8652, 0xa438, 0xaf49, 0xa438, 0xdcef, 0xa438, 0x31e1, + 0xa438, 0x8ffd, 0xa438, 0xac28, 0xa438, 0x2ebf, 0xa438, 0x6dda, + 0xa438, 0x0274, 0xa438, 0x95ad, 0xa438, 0x2825, 0xa438, 0xe28f, + 0xa438, 0xe4ef, 0xa438, 0x131b, 0xa438, 0x12ac, 0xa438, 0x2f10, + 0xa438, 0xef31, 0xa438, 0x1f44, 0xa438, 0xef13, 0xa438, 0xbf6c, + 0xa438, 0xcf02, 0xa438, 0x7476, 0xa438, 0x1a12, 0xa438, 0xae08, + 0xa438, 0xbf6c, 0xa438, 0xcf02, 0xa438, 0x744a, 0xa438, 0xef13, + 0xa438, 0xaf08, 0xa438, 0x66af, 0xa438, 0x085c, 0xa438, 0xe18f, + 0xa438, 0xe3ad, 0xa438, 0x2706, 0xa438, 0xe58f, 0xa438, 0xe9af, + 0xa438, 0x4091, 0xa438, 0xe08f, 0xa438, 0xe1ac, 0xa438, 0x2002, + 0xa438, 0xae03, 0xa438, 0xe18f, 0xa438, 0xe2e5, 0xa438, 0x8fe9, + 0xa438, 0xaf3f, 0xa438, 0xe5f8, 0xa438, 0xe08f, 0xa438, 0xe7a0, + 0xa438, 0x0005, 0xa438, 0x028b, 0xa438, 0x0dae, 0xa438, 0x13a0, + 0xa438, 0x0105, 0xa438, 0x028b, 0xa438, 0x96ae, 0xa438, 0x0ba0, + 0xa438, 0x0205, 0xa438, 0x028b, 0xa438, 0xc2ae, 0xa438, 0x0302, + 0xa438, 0x8c18, 0xa438, 0xfc04, 0xa438, 0xf8fa, 0xa438, 0xef69, + 0xa438, 0xfafb, 0xa438, 0xe080, 0xa438, 0x15ad, 0xa438, 0x2343, + 0xa438, 0xe08f, 0xa438, 0xfdac, 0xa438, 0x203d, 0xa438, 0xe08f, + 0xa438, 0xe9a0, 0xa438, 0x0002, 0xa438, 0xae35, 0xa438, 0xee8f, + 0xa438, 0xe800, 0xa438, 0x028c, 0xa438, 0xc8bf, 0xa438, 0x8feb, + 0xa438, 0xd819, 0xa438, 0xd9ef, 0xa438, 0x64bf, 0xa438, 0x8fef, + 0xa438, 0xd819, 0xa438, 0xd9ef, 0xa438, 0x7402, 0xa438, 0x73a4, + 0xa438, 0xad50, 0xa438, 0x18ee, 0xa438, 0x8fff, 0xa438, 0x0102, + 0xa438, 0x8e1b, 0xa438, 0x0273, 0xa438, 0xd7ef, 0xa438, 0x47e5, + 0xa438, 0x85a6, 0xa438, 0xe485, 0xa438, 0xa5ee, 0xa438, 0x8fe7, + 0xa438, 0x01ae, 0xa438, 0x33bf, 0xa438, 0x8f87, 0xa438, 0x0274, + 0xa438, 0x4abf, 0xa438, 0x8f8d, 0xa438, 0x0274, 0xa438, 0x4abf, + 0xa438, 0x8f93, 0xa438, 0x0274, 0xa438, 0x4abf, 0xa438, 0x8f99, + 0xa438, 0x0274, 0xa438, 0x4abf, 0xa438, 0x8f84, 0xa438, 0x0274, + 0xa438, 0x53bf, 0xa438, 0x8f8a, 0xa438, 0x0274, 0xa438, 0x53bf, + 0xa438, 0x8f90, 0xa438, 0x0274, 0xa438, 0x53bf, 0xa438, 0x8f96, + 0xa438, 0x0274, 0xa438, 0x5302, 0xa438, 0x2261, 0xa438, 0xfffe, + 0xa438, 0xef96, 0xa438, 0xfefc, 0xa438, 0x04f8, 0xa438, 0xfafb, + 0xa438, 0xe085, 0xa438, 0xa5e1, 0xa438, 0x85a6, 0xa438, 0xef64, + 0xa438, 0xd000, 0xa438, 0xe18f, 0xa438, 0xeaef, 0xa438, 0x7402, + 0xa438, 0x73f2, 0xa438, 0xad50, 0xa438, 0x10e0, 0xa438, 0x8fe8, + 0xa438, 0xac24, 0xa438, 0x06ee, 0xa438, 0x8fe7, 0xa438, 0x02ae, + 0xa438, 0x04ee, 0xa438, 0x8fe7, 0xa438, 0x03ff, 0xa438, 0xfefc, + 0xa438, 0x04f8, 0xa438, 0xf9fa, 0xa438, 0xef69, 0xa438, 0xfb02, + 0xa438, 0x8cc8, 0xa438, 0xbf8f, 0xa438, 0xebd8, 0xa438, 0x19d9, + 0xa438, 0xbf8f, 0xa438, 0xf3e2, 0xa438, 0x8fe8, 0xa438, 0xef32, + 0xa438, 0x4b02, 0xa438, 0x1a93, 0xa438, 0xdc19, 0xa438, 0xdd12, + 0xa438, 0xe68f, 0xa438, 0xe8e3, 0xa438, 0x8fe9, 0xa438, 0x1b23, + 0xa438, 0xad37, 0xa438, 0x07e0, 0xa438, 0x8fff, 0xa438, 0x4802, + 0xa438, 0xae09, 0xa438, 0xee8f, 0xa438, 0xe810, 0xa438, 0x1f00, + 0xa438, 0xe48f, 0xa438, 0xfee4, 0xa438, 0x8fff, 0xa438, 0x028e, + 0xa438, 0x1b02, 0xa438, 0x73d7, 0xa438, 0xef47, 0xa438, 0xe585, + 0xa438, 0xa6e4, 0xa438, 0x85a5, 0xa438, 0xee8f, 0xa438, 0xe701, + 0xa438, 0xffef, 0xa438, 0x96fe, 0xa438, 0xfdfc, 0xa438, 0x04f8, + 0xa438, 0xf9fa, 0xa438, 0xef69, 0xa438, 0xfafb, 0xa438, 0x028c, + 0xa438, 0xc8bf, 0xa438, 0x8feb, 0xa438, 0xd819, 0xa438, 0xd9ef, + 0xa438, 0x64bf, 0xa438, 0x8fef, 0xa438, 0xd819, 0xa438, 0xd9ef, + 0xa438, 0x7402, 0xa438, 0x73a4, 0xa438, 0xad50, 0xa438, 0x27bf, + 0xa438, 0x8fed, 0xa438, 0xd819, 0xa438, 0xd9ef, 0xa438, 0x64bf, + 0xa438, 0x8ff1, 0xa438, 0xd819, 0xa438, 0xd9ef, 0xa438, 0x7402, + 0xa438, 0x73a4, 0xa438, 0xad50, 0xa438, 0x11e2, 0xa438, 0x8fe8, + 0xa438, 0xe38f, 0xa438, 0xe9ef, 0xa438, 0x0258, 0xa438, 0x0f1b, + 0xa438, 0x03ac, 0xa438, 0x2744, 0xa438, 0xae09, 0xa438, 0xe08f, + 0xa438, 0xfee4, 0xa438, 0x8fff, 0xa438, 0x028e, 0xa438, 0x1b02, + 0xa438, 0x2261, 0xa438, 0xee8f, 0xa438, 0xe700, 0xa438, 0xbf8f, + 0xa438, 0x8702, 0xa438, 0x744a, 0xa438, 0xbf8f, 0xa438, 0x8d02, + 0xa438, 0x744a, 0xa438, 0xbf8f, 0xa438, 0x9302, 0xa438, 0x744a, + 0xa438, 0xbf8f, 0xa438, 0x9902, 0xa438, 0x744a, 0xa438, 0xbf8f, + 0xa438, 0x8402, 0xa438, 0x7453, 0xa438, 0xbf8f, 0xa438, 0x8a02, + 0xa438, 0x7453, 0xa438, 0xbf8f, 0xa438, 0x9002, 0xa438, 0x7453, + 0xa438, 0xbf8f, 0xa438, 0x9602, 0xa438, 0x7453, 0xa438, 0xae1f, + 0xa438, 0x12e6, 0xa438, 0x8fe8, 0xa438, 0xe08f, 0xa438, 0xffe4, + 0xa438, 0x8ffe, 0xa438, 0x028d, 0xa438, 0x3e02, 0xa438, 0x8e1b, + 0xa438, 0x0273, 0xa438, 0xd7ef, 0xa438, 0x47e5, 0xa438, 0x85a6, + 0xa438, 0xe485, 0xa438, 0xa5ee, 0xa438, 0x8fe7, 0xa438, 0x01ff, + 0xa438, 0xfeef, 0xa438, 0x96fe, 0xa438, 0xfdfc, 0xa438, 0x04f8, + 0xa438, 0xf9fa, 0xa438, 0xef69, 0xa438, 0xfafb, 0xa438, 0x1f22, + 0xa438, 0xee8f, 0xa438, 0xeb00, 0xa438, 0xee8f, 0xa438, 0xec00, + 0xa438, 0xee8f, 0xa438, 0xed00, 0xa438, 0xee8f, 0xa438, 0xee00, + 0xa438, 0x1f33, 0xa438, 0xee8f, 0xa438, 0xe500, 0xa438, 0xee8f, + 0xa438, 0xe600, 0xa438, 0xbf53, 0xa438, 0x7d02, 0xa438, 0x7662, + 0xa438, 0xef64, 0xa438, 0xbf8f, 0xa438, 0xe5d8, 0xa438, 0x19d9, + 0xa438, 0xef74, 0xa438, 0x0273, 0xa438, 0xbfef, 0xa438, 0x47dd, + 0xa438, 0x89dc, 0xa438, 0xd1ff, 0xa438, 0xb1fe, 0xa438, 0x13ad, + 0xa438, 0x3be0, 0xa438, 0x0d73, 0xa438, 0xbf8f, 0xa438, 0xedd8, + 0xa438, 0x19d9, 0xa438, 0xef64, 0xa438, 0xef47, 0xa438, 0x0273, + 0xa438, 0xa4ad, 0xa438, 0x5003, 0xa438, 0xdd89, 0xa438, 0xdcef, + 0xa438, 0x64bf, 0xa438, 0x8feb, 0xa438, 0xd819, 0xa438, 0xd91a, + 0xa438, 0x46dd, 0xa438, 0x89dc, 0xa438, 0x12ad, 0xa438, 0x32b0, + 0xa438, 0x0d42, 0xa438, 0xdc19, 0xa438, 0xddff, 0xa438, 0xfeef, + 0xa438, 0x96fe, 0xa438, 0xfdfc, 0xa438, 0x04f8, 0xa438, 0xf9fa, + 0xa438, 0xef69, 0xa438, 0xfafb, 0xa438, 0x1f22, 0xa438, 0xd6ff, + 0xa438, 0xffef, 0xa438, 0x03bf, 0xa438, 0x8ff3, 0xa438, 0xef32, + 0xa438, 0x4b02, 0xa438, 0x1a93, 0xa438, 0xef30, 0xa438, 0xd819, + 0xa438, 0xd9ef, 0xa438, 0x7402, 0xa438, 0x73a4, 0xa438, 0xac50, + 0xa438, 0x04ef, 0xa438, 0x32ef, 0xa438, 0x64e0, 0xa438, 0x8fe9, + 0xa438, 0x12ef, 0xa438, 0x121b, 0xa438, 0x10ac, 0xa438, 0x2fd9, + 0xa438, 0xef03, 0xa438, 0xbf8f, 0xa438, 0xf348, 0xa438, 0x021a, + 0xa438, 0x90ec, 0xa438, 0xff19, 0xa438, 0xecff, 0xa438, 0xd001, + 0xa438, 0xae03, 0xa438, 0x0c01, 0xa438, 0x83a3, 0xa438, 0x00fa, + 0xa438, 0xe18f, 0xa438, 0xff1e, 0xa438, 0x10e5, 0xa438, 0x8fff, + 0xa438, 0xfffe, 0xa438, 0xef96, 0xa438, 0xfefd, 0xa438, 0xfc04, + 0xa438, 0x725a, 0xa438, 0x725d, 0xa438, 0x7260, 0xa438, 0x7263, + 0xa438, 0x71fa, 0xa438, 0x71fd, 0xa438, 0x7200, 0xa438, 0x7203, + 0xa438, 0x8f4b, 0xa438, 0x8f4e, 0xa438, 0x8f51, 0xa438, 0x8f54, + 0xa438, 0x8f57, 0xa438, 0x8f5a, 0xa438, 0x8f5d, 0xa438, 0x8f60, + 0xa438, 0x722a, 0xa438, 0x722d, 0xa438, 0x7230, 0xa438, 0x7233, + 0xa438, 0x721e, 0xa438, 0x7221, 0xa438, 0x7224, 0xa438, 0x7227, + 0xa438, 0x7212, 0xa438, 0x7215, 0xa438, 0x7218, 0xa438, 0x721b, + 0xa438, 0x724e, 0xa438, 0x7251, 0xa438, 0x7254, 0xa438, 0x7257, + 0xa438, 0x7242, 0xa438, 0x7245, 0xa438, 0x7248, 0xa438, 0x724b, + 0xa438, 0x7236, 0xa438, 0x7239, 0xa438, 0x723c, 0xa438, 0x723f, + 0xa438, 0x8f84, 0xa438, 0x8f8a, 0xa438, 0x8f90, 0xa438, 0x8f96, + 0xa438, 0x8f9c, 0xa438, 0x8fa2, 0xa438, 0x8fa8, 0xa438, 0x8fae, + 0xa438, 0x8f87, 0xa438, 0x8f8d, 0xa438, 0x8f93, 0xa438, 0x8f99, + 0xa438, 0x8f9f, 0xa438, 0x8fa5, 0xa438, 0x8fab, 0xa438, 0x8fb1, + 0xa438, 0x8f63, 0xa438, 0x8f66, 0xa438, 0x8f69, 0xa438, 0x8f6c, + 0xa438, 0x8f6f, 0xa438, 0x8f72, 0xa438, 0x8f75, 0xa438, 0x8f78, + 0xa438, 0x8f7b, 0xa438, 0xf8f9, 0xa438, 0xfaef, 0xa438, 0x69fa, + 0xa438, 0xfbe2, 0xa438, 0x8fff, 0xa438, 0xad30, 0xa438, 0x06d1, + 0xa438, 0x00d3, 0xa438, 0x00ae, 0xa438, 0x04d1, 0xa438, 0x01d3, + 0xa438, 0x0fbf, 0xa438, 0x8d99, 0xa438, 0xd700, 0xa438, 0x0802, + 0xa438, 0x7677, 0xa438, 0xef13, 0xa438, 0xbf8d, 0xa438, 0xa1d7, + 0xa438, 0x0008, 0xa438, 0x0276, 0xa438, 0x77ad, 0xa438, 0x3106, + 0xa438, 0xd100, 0xa438, 0xd300, 0xa438, 0xae04, 0xa438, 0xd101, + 0xa438, 0xd30f, 0xa438, 0xbf8d, 0xa438, 0xa9d7, 0xa438, 0x0008, + 0xa438, 0x0276, 0xa438, 0x77ef, 0xa438, 0x13bf, 0xa438, 0x8db1, + 0xa438, 0xd700, 0xa438, 0x0802, 0xa438, 0x7677, 0xa438, 0xad32, + 0xa438, 0x06d1, 0xa438, 0x00d3, 0xa438, 0x00ae, 0xa438, 0x04d1, + 0xa438, 0x01d3, 0xa438, 0x03bf, 0xa438, 0x8db9, 0xa438, 0xd700, + 0xa438, 0x1802, 0xa438, 0x7677, 0xa438, 0xef13, 0xa438, 0xbf8d, + 0xa438, 0xd1d7, 0xa438, 0x0018, 0xa438, 0x0276, 0xa438, 0x77ad, + 0xa438, 0x3304, 0xa438, 0xd101, 0xa438, 0xae02, 0xa438, 0xd100, + 0xa438, 0xd300, 0xa438, 0xbf8d, 0xa438, 0xe9d7, 0xa438, 0x0010, + 0xa438, 0x0276, 0xa438, 0x77ef, 0xa438, 0x13bf, 0xa438, 0x8df9, + 0xa438, 0xd700, 0xa438, 0x1002, 0xa438, 0x7677, 0xa438, 0x1f33, + 0xa438, 0xe38f, 0xa438, 0xfdac, 0xa438, 0x3803, 0xa438, 0xaf8f, + 0xa438, 0x35ad, 0xa438, 0x3405, 0xa438, 0xe18f, 0xa438, 0xfbae, + 0xa438, 0x02d1, 0xa438, 0x00bf, 0xa438, 0x8e09, 0xa438, 0xd700, + 0xa438, 0x1202, 0xa438, 0x7677, 0xa438, 0xad35, 0xa438, 0x06d1, + 0xa438, 0x01d3, 0xa438, 0x04ae, 0xa438, 0x04d1, 0xa438, 0x00d3, + 0xa438, 0x00bf, 0xa438, 0x6f8a, 0xa438, 0x0274, 0xa438, 0x76bf, + 0xa438, 0x6bd0, 0xa438, 0x0274, 0xa438, 0x951a, 0xa438, 0x13bf, + 0xa438, 0x6bd0, 0xa438, 0x0274, 0xa438, 0x76bf, 0xa438, 0x6d2c, + 0xa438, 0x0274, 0xa438, 0x95ac, 0xa438, 0x280b, 0xa438, 0xbf6d, + 0xa438, 0x2f02, 0xa438, 0x7495, 0xa438, 0xac28, 0xa438, 0x02ae, + 0xa438, 0x0bad, 0xa438, 0x3504, 0xa438, 0xd101, 0xa438, 0xae0d, + 0xa438, 0xd10f, 0xa438, 0xae09, 0xa438, 0xad35, 0xa438, 0x04d1, + 0xa438, 0x05ae, 0xa438, 0x02d1, 0xa438, 0x0fbf, 0xa438, 0x8f7e, + 0xa438, 0x0274, 0xa438, 0x76e3, 0xa438, 0x8ffc, 0xa438, 0xac38, + 0xa438, 0x05ad, 0xa438, 0x3618, 0xa438, 0xae08, 0xa438, 0xbf71, + 0xa438, 0x9d02, 0xa438, 0x744a, 0xa438, 0xae0e, 0xa438, 0xd102, + 0xa438, 0xbf8f, 0xa438, 0x8102, 0xa438, 0x7476, 0xa438, 0xbf71, + 0xa438, 0x9d02, 0xa438, 0x7476, 0xa438, 0xfffe, 0xa438, 0xef96, + 0xa438, 0xfefd, 0xa438, 0xfc04, 0xa438, 0xf91f, 0xa438, 0x33e3, + 0xa438, 0x8ffd, 0xa438, 0xad38, 0xa438, 0x0302, 0xa438, 0x8e1b, + 0xa438, 0xfd04, 0xa438, 0x55b0, 0xa438, 0x2055, 0xa438, 0xb0a0, + 0xa438, 0x55b1, 0xa438, 0x2055, 0xa438, 0xb1a0, 0xa438, 0xfcb0, + 0xa438, 0x22fc, 0xa438, 0xb0a2, 0xa438, 0xfcb1, 0xa438, 0x22fc, + 0xa438, 0xb1a2, 0xa438, 0xfdad, 0xa438, 0xdaca, 0xa438, 0xadda, + 0xa438, 0x97ad, 0xa438, 0xda64, 0xa438, 0xadda, 0xa438, 0x20ad, + 0xa438, 0xdafd, 0xa438, 0xaddc, 0xa438, 0xcaad, 0xa438, 0xdc97, + 0xa438, 0xaddc, 0xa438, 0x64ad, 0xa438, 0xdca7, 0xa438, 0xbf1e, + 0xa438, 0x20bc, 0xa438, 0x3299, 0xa438, 0xadfe, 0xa438, 0x85ad, + 0xa438, 0xfe44, 0xa438, 0xadfe, 0xa438, 0x30ad, 0xa438, 0xfeff, + 0xa438, 0xae00, 0xa438, 0xebae, 0xa438, 0x00aa, 0xa438, 0xae00, + 0xa438, 0x96ae, 0xa438, 0x00dd, 0xa438, 0xad94, 0xa438, 0xccad, + 0xa438, 0x9499, 0xa438, 0xad94, 0xa438, 0x88ad, 0xa438, 0x94ff, + 0xa438, 0xad94, 0xa438, 0xeead, 0xa438, 0x94bb, 0xa438, 0xad94, + 0xa438, 0xaaad, 0xa438, 0x94f9, 0xa438, 0xe28f, 0xa438, 0xffee, + 0xa438, 0x8fff, 0xa438, 0x00e3, 0xa438, 0x8ffd, 0xa438, 0xee8f, + 0xa438, 0xfd01, 0xa438, 0xee8f, 0xa438, 0xfc01, 0xa438, 0x028e, + 0xa438, 0x1be6, 0xa438, 0x8fff, 0xa438, 0xe78f, 0xa438, 0xfdee, + 0xa438, 0x8ffc, 0xa438, 0x00ee, 0xa438, 0x8fe7, 0xa438, 0x00fd, + 0xa438, 0x0400, 0xa436, 0xb85e, 0xa438, 0x211C, 0xa436, 0xb860, + 0xa438, 0x216C, 0xa436, 0xb862, 0xa438, 0x212B, 0xa436, 0xb864, + 0xa438, 0x4BE8, 0xa436, 0xb886, 0xa438, 0x4209, 0xa436, 0xb888, + 0xa438, 0x49DA, 0xa436, 0xb88a, 0xa438, 0x085A, 0xa436, 0xb88c, + 0xa438, 0x3FDF, 0xa436, 0xb838, 0xa438, 0x00ff, 0xb820, 0x0010, + 0xa466, 0x0003, 0xa436, 0x8528, 0xa438, 0x0000, 0xa436, 0x85f8, + 0xa438, 0xaf86, 0xa438, 0x10af, 0xa438, 0x8622, 0xa438, 0xaf86, + 0xa438, 0x4aaf, 0xa438, 0x8658, 0xa438, 0xaf86, 0xa438, 0x64af, + 0xa438, 0x8685, 0xa438, 0xaf86, 0xa438, 0xc4af, 0xa438, 0x86cf, + 0xa438, 0xa104, 0xa438, 0x0ce0, 0xa438, 0x8394, 0xa438, 0xad20, + 0xa438, 0x03af, 0xa438, 0x2b67, 0xa438, 0xaf2a, 0xa438, 0xf0af, + 0xa438, 0x2b8d, 0xa438, 0xbf6b, 0xa438, 0x7202, 0xa438, 0x72dc, + 0xa438, 0xa106, 0xa438, 0x19e1, 0xa438, 0x8164, 0xa438, 0xbf6d, + 0xa438, 0x5b02, 0xa438, 0x72bd, 0xa438, 0x0d13, 0xa438, 0xbf6d, + 0xa438, 0x5802, 0xa438, 0x72bd, 0xa438, 0x0d13, 0xa438, 0xbf6d, + 0xa438, 0x6a02, 0xa438, 0x72bd, 0xa438, 0x0275, 0xa438, 0x12af, + 0xa438, 0x380d, 0xa438, 0x0d55, 0xa438, 0x5d07, 0xa438, 0xffbf, + 0xa438, 0x8b09, 0xa438, 0x0272, 0xa438, 0x91af, 0xa438, 0x3ee2, + 0xa438, 0x023d, 0xa438, 0xffbf, 0xa438, 0x8b09, 0xa438, 0x0272, + 0xa438, 0x9aaf, 0xa438, 0x41a6, 0xa438, 0x0223, 0xa438, 0x24f8, + 0xa438, 0xfaef, 0xa438, 0x69bf, 0xa438, 0x6b9c, 0xa438, 0x0272, + 0xa438, 0xdce0, 0xa438, 0x8f7a, 0xa438, 0x1f01, 0xa438, 0x9e06, + 0xa438, 0xe58f, 0xa438, 0x7a02, 0xa438, 0x7550, 0xa438, 0xef96, + 0xa438, 0xfefc, 0xa438, 0xaf06, 0xa438, 0x8702, 0xa438, 0x1cac, + 0xa438, 0xf8f9, 0xa438, 0xfaef, 0xa438, 0x69fb, 0xa438, 0xd78f, + 0xa438, 0x97ae, 0xa438, 0x00bf, 0xa438, 0x6d4f, 0xa438, 0x0272, + 0xa438, 0x91d3, 0xa438, 0x00a3, 0xa438, 0x1202, 0xa438, 0xae1b, + 0xa438, 0xbf6d, 0xa438, 0x52ef, 0xa438, 0x1302, 0xa438, 0x72bd, + 0xa438, 0xef97, 0xa438, 0xd9bf, 0xa438, 0x6d55, 0xa438, 0x0272, + 0xa438, 0xbd17, 0xa438, 0x13ae, 0xa438, 0xe6bf, 0xa438, 0x6d4f, + 0xa438, 0x0272, 0xa438, 0x9aff, 0xa438, 0xef96, 0xa438, 0xfefd, + 0xa438, 0xfcaf, 0xa438, 0x1c05, 0xa438, 0x0000, 0xa438, 0x021b, + 0xa438, 0xf202, 0xa438, 0x8700, 0xa438, 0xaf1b, 0xa438, 0x73ad, + 0xa438, 0x2003, 0xa438, 0x0206, 0xa438, 0x6ead, 0xa438, 0x2108, + 0xa438, 0xe280, 0xa438, 0x51f7, 0xa438, 0x30e6, 0xa438, 0x8051, + 0xa438, 0xe180, 0xa438, 0x421e, 0xa438, 0x10e5, 0xa438, 0x8042, + 0xa438, 0xe0ff, 0xa438, 0xeee1, 0xa438, 0x8043, 0xa438, 0x1e10, + 0xa438, 0xe580, 0xa438, 0x43e0, 0xa438, 0xffef, 0xa438, 0xad20, + 0xa438, 0x04ee, 0xa438, 0x804f, 0xa438, 0x1eaf, 0xa438, 0x0661, + 0xa438, 0xf8fa, 0xa438, 0xef69, 0xa438, 0xe080, 0xa438, 0x4fac, + 0xa438, 0x2417, 0xa438, 0xe080, 0xa438, 0x44ad, 0xa438, 0x241a, + 0xa438, 0x0287, 0xa438, 0x2fe0, 0xa438, 0x8044, 0xa438, 0xac24, + 0xa438, 0x11bf, 0xa438, 0x8b0c, 0xa438, 0x0272, 0xa438, 0x9aae, + 0xa438, 0x0902, 0xa438, 0x88c8, 0xa438, 0x028a, 0xa438, 0x9502, + 0xa438, 0x8a8a, 0xa438, 0xef96, 0xa438, 0xfefc, 0xa438, 0x04f8, + 0xa438, 0xe08f, 0xa438, 0x96a0, 0xa438, 0x0005, 0xa438, 0x0288, + 0xa438, 0x6cae, 0xa438, 0x38a0, 0xa438, 0x0105, 0xa438, 0x0287, + 0xa438, 0x75ae, 0xa438, 0x30a0, 0xa438, 0x0205, 0xa438, 0x0287, + 0xa438, 0xb3ae, 0xa438, 0x28a0, 0xa438, 0x0305, 0xa438, 0x0287, + 0xa438, 0xc9ae, 0xa438, 0x20a0, 0xa438, 0x0405, 0xa438, 0x0287, + 0xa438, 0xd6ae, 0xa438, 0x18a0, 0xa438, 0x0505, 0xa438, 0x0288, + 0xa438, 0x1aae, 0xa438, 0x10a0, 0xa438, 0x0605, 0xa438, 0x0288, + 0xa438, 0x27ae, 0xa438, 0x08a0, 0xa438, 0x0705, 0xa438, 0x0288, + 0xa438, 0x48ae, 0xa438, 0x00fc, 0xa438, 0x04f8, 0xa438, 0xfaef, + 0xa438, 0x69e0, 0xa438, 0x8018, 0xa438, 0xad25, 0xa438, 0x2c02, + 0xa438, 0x8a67, 0xa438, 0xe184, 0xa438, 0x5de5, 0xa438, 0x8f92, + 0xa438, 0xe58f, 0xa438, 0x93e5, 0xa438, 0x8f94, 0xa438, 0xe58f, + 0xa438, 0x9502, 0xa438, 0x88e6, 0xa438, 0xe184, 0xa438, 0xf759, + 0xa438, 0x0fe5, 0xa438, 0x8f7b, 0xa438, 0xe58f, 0xa438, 0x7ce5, + 0xa438, 0x8f7d, 0xa438, 0xe58f, 0xa438, 0x7eee, 0xa438, 0x8f96, + 0xa438, 0x02ae, 0xa438, 0x0302, 0xa438, 0x8a8a, 0xa438, 0xef96, + 0xa438, 0xfefc, 0xa438, 0x04f9, 0xa438, 0x0289, 0xa438, 0x19ac, + 0xa438, 0x3009, 0xa438, 0xee8f, 0xa438, 0x9603, 0xa438, 0x0288, + 0xa438, 0x8eae, 0xa438, 0x04ee, 0xa438, 0x8f96, 0xa438, 0x04fd, + 0xa438, 0x04fb, 0xa438, 0x0288, 0xa438, 0x55ad, 0xa438, 0x5004, + 0xa438, 0xee8f, 0xa438, 0x9602, 0xa438, 0xff04, 0xa438, 0xf902, + 0xa438, 0x8943, 0xa438, 0xe28f, 0xa438, 0x920c, 0xa438, 0x245a, + 0xa438, 0xf0e3, 0xa438, 0x84f7, 0xa438, 0x5bf0, 0xa438, 0x1b23, + 0xa438, 0x9e0f, 0xa438, 0x028a, 0xa438, 0x52ee, 0xa438, 0x8f96, + 0xa438, 0x0502, 0xa438, 0x888e, 0xa438, 0x0287, 0xa438, 0xffae, + 0xa438, 0x04ee, 0xa438, 0x8f96, 0xa438, 0x06fd, 0xa438, 0x04f8, + 0xa438, 0xf9fa, 0xa438, 0xef69, 0xa438, 0xfa1f, 0xa438, 0x44d2, + 0xa438, 0x04bf, 0xa438, 0x8f7f, 0xa438, 0xdc19, 0xa438, 0xdd19, + 0xa438, 0x829f, 0xa438, 0xf9fe, 0xa438, 0xef96, 0xa438, 0xfefd, + 0xa438, 0xfc04, 0xa438, 0xfb02, 0xa438, 0x8855, 0xa438, 0xad50, + 0xa438, 0x04ee, 0xa438, 0x8f96, 0xa438, 0x04ff, 0xa438, 0x04f8, + 0xa438, 0xf9fa, 0xa438, 0xef69, 0xa438, 0x0289, 0xa438, 0x19ac, + 0xa438, 0x3009, 0xa438, 0xee8f, 0xa438, 0x9607, 0xa438, 0x0288, + 0xa438, 0x8eae, 0xa438, 0x0702, 0xa438, 0x8a8a, 0xa438, 0xee8f, + 0xa438, 0x9601, 0xa438, 0xef96, 0xa438, 0xfefd, 0xa438, 0xfc04, + 0xa438, 0xfb02, 0xa438, 0x8855, 0xa438, 0xad50, 0xa438, 0x04ee, + 0xa438, 0x8f96, 0xa438, 0x06ff, 0xa438, 0x04f8, 0xa438, 0xfae0, + 0xa438, 0x8457, 0xa438, 0xe184, 0xa438, 0x58ef, 0xa438, 0x64e1, + 0xa438, 0x8f90, 0xa438, 0xd000, 0xa438, 0xef74, 0xa438, 0x0271, + 0xa438, 0xfffe, 0xa438, 0xfc04, 0xa438, 0xf8fa, 0xa438, 0xef69, + 0xa438, 0xee8f, 0xa438, 0x9601, 0xa438, 0xee8f, 0xa438, 0x9004, + 0xa438, 0xee8f, 0xa438, 0x8f40, 0xa438, 0xbf8b, 0xa438, 0x0f02, + 0xa438, 0x72dc, 0xa438, 0xe584, 0xa438, 0x5dee, 0xa438, 0x8f91, + 0xa438, 0x77ef, 0xa438, 0x96fe, 0xa438, 0xfc04, 0xa438, 0xf8fa, + 0xa438, 0xfbef, 0xa438, 0x69e1, 0xa438, 0x8f92, 0xa438, 0xbf8b, + 0xa438, 0x0f02, 0xa438, 0x72bd, 0xa438, 0xe18f, 0xa438, 0x93bf, + 0xa438, 0x8b12, 0xa438, 0x0272, 0xa438, 0xbde1, 0xa438, 0x8f94, + 0xa438, 0xbf8b, 0xa438, 0x1502, 0xa438, 0x72bd, 0xa438, 0xe18f, + 0xa438, 0x95bf, 0xa438, 0x8b18, 0xa438, 0x0272, 0xa438, 0xbd02, + 0xa438, 0x71e4, 0xa438, 0xef47, 0xa438, 0xe484, 0xa438, 0x57e5, + 0xa438, 0x8458, 0xa438, 0xef96, 0xa438, 0xfffe, 0xa438, 0xfc04, + 0xa438, 0xf8e0, 0xa438, 0x8018, 0xa438, 0xad25, 0xa438, 0x15ee, + 0xa438, 0x8f96, 0xa438, 0x00d0, 0xa438, 0x08e4, 0xa438, 0x8f92, + 0xa438, 0xe48f, 0xa438, 0x93e4, 0xa438, 0x8f94, 0xa438, 0xe48f, + 0xa438, 0x9502, 0xa438, 0x888e, 0xa438, 0xfc04, 0xa438, 0xf9e2, + 0xa438, 0x845d, 0xa438, 0xe38f, 0xa438, 0x910d, 0xa438, 0x345b, + 0xa438, 0x0f1a, 0xa438, 0x32ac, 0xa438, 0x3c09, 0xa438, 0x0c34, + 0xa438, 0x5bf0, 0xa438, 0xe784, 0xa438, 0xf7ae, 0xa438, 0x04ee, + 0xa438, 0x84f7, 0xa438, 0xf0e3, 0xa438, 0x8f91, 0xa438, 0x5b0f, + 0xa438, 0x1b23, 0xa438, 0xac37, 0xa438, 0x0ae3, 0xa438, 0x84f7, + 0xa438, 0x1e32, 0xa438, 0xe784, 0xa438, 0xf7ae, 0xa438, 0x00fd, + 0xa438, 0x04f8, 0xa438, 0xfaef, 0xa438, 0x69fa, 0xa438, 0xfbd2, + 0xa438, 0x01d3, 0xa438, 0x04d6, 0xa438, 0x8f92, 0xa438, 0xd78f, + 0xa438, 0x7bef, 0xa438, 0x97d9, 0xa438, 0xef96, 0xa438, 0xd81b, + 0xa438, 0x109e, 0xa438, 0x0480, 0xa438, 0xdcd2, 0xa438, 0x0016, + 0xa438, 0x1783, 0xa438, 0x9fed, 0xa438, 0xfffe, 0xa438, 0xef96, + 0xa438, 0xfefc, 0xa438, 0x04f8, 0xa438, 0xf9fa, 0xa438, 0xfbef, + 0xa438, 0x79fb, 0xa438, 0xcffb, 0xa438, 0xd200, 0xa438, 0xbe00, + 0xa438, 0x00ef, 0xa438, 0x1229, 0xa438, 0x40d0, 0xa438, 0x041c, + 0xa438, 0x081a, 0xa438, 0x10bf, 0xa438, 0x8b27, 0xa438, 0x0272, + 0xa438, 0xbd02, 0xa438, 0x89ee, 0xa438, 0xbf8f, 0xa438, 0x7fef, + 0xa438, 0x1249, 0xa438, 0x021a, 0xa438, 0x91d8, 0xa438, 0x19d9, + 0xa438, 0xef74, 0xa438, 0x0271, 0xa438, 0xccef, 0xa438, 0x47dd, + 0xa438, 0x89dc, 0xa438, 0x18a8, 0xa438, 0x0002, 0xa438, 0xd202, + 0xa438, 0x8990, 0xa438, 0x12a2, 0xa438, 0x04c8, 0xa438, 0xffc7, + 0xa438, 0xffef, 0xa438, 0x97ff, 0xa438, 0xfefd, 0xa438, 0xfc04, + 0xa438, 0xf8f9, 0xa438, 0xfafb, 0xa438, 0xef79, 0xa438, 0xfbbf, + 0xa438, 0x8f7f, 0xa438, 0xef12, 0xa438, 0x4902, 0xa438, 0x1a91, + 0xa438, 0xd819, 0xa438, 0xd9ef, 0xa438, 0x64bf, 0xa438, 0x8f87, + 0xa438, 0xef12, 0xa438, 0x4902, 0xa438, 0x1a91, 0xa438, 0xd819, + 0xa438, 0xd9ef, 0xa438, 0x7489, 0xa438, 0x0271, 0xa438, 0xb1ad, + 0xa438, 0x502c, 0xa438, 0xef46, 0xa438, 0xdc19, 0xa438, 0xdda2, + 0xa438, 0x0006, 0xa438, 0xbf8b, 0xa438, 0x0f02, 0xa438, 0x72dc, + 0xa438, 0xa201, 0xa438, 0x06bf, 0xa438, 0x8b12, 0xa438, 0x0272, + 0xa438, 0xdca2, 0xa438, 0x0206, 0xa438, 0xbf8b, 0xa438, 0x1502, + 0xa438, 0x72dc, 0xa438, 0xbf8b, 0xa438, 0x1802, 0xa438, 0x72dc, + 0xa438, 0xbf8f, 0xa438, 0x7b1a, 0xa438, 0x92dd, 0xa438, 0xffef, + 0xa438, 0x97ff, 0xa438, 0xfefd, 0xa438, 0xfc04, 0xa438, 0xf9f8, + 0xa438, 0xfbef, 0xa438, 0x79fb, 0xa438, 0x028a, 0xa438, 0xa0bf, + 0xa438, 0x8b1b, 0xa438, 0x0272, 0xa438, 0x9a16, 0xa438, 0xbf8b, + 0xa438, 0x1e02, 0xa438, 0x72dc, 0xa438, 0xac28, 0xa438, 0x02ae, + 0xa438, 0xf4d6, 0xa438, 0x0000, 0xa438, 0xbf8b, 0xa438, 0x1b02, + 0xa438, 0x7291, 0xa438, 0xae03, 0xa438, 0x028a, 0xa438, 0x8ad2, + 0xa438, 0x00d7, 0xa438, 0x0000, 0xa438, 0xe18f, 0xa438, 0x8f1b, + 0xa438, 0x12a1, 0xa438, 0x0004, 0xa438, 0xef67, 0xa438, 0xae1d, + 0xa438, 0xef12, 0xa438, 0xbf8b, 0xa438, 0x2102, 0xa438, 0x72bd, + 0xa438, 0x12bf, 0xa438, 0x8b24, 0xa438, 0x0272, 0xa438, 0xdcef, + 0xa438, 0x64ad, 0xa438, 0x4f04, 0xa438, 0x7eff, 0xa438, 0xff16, + 0xa438, 0x0271, 0xa438, 0xccae, 0xa438, 0xd7bf, 0xa438, 0x8b2d, + 0xa438, 0x0272, 0xa438, 0x91ff, 0xa438, 0xef97, 0xa438, 0xfffc, + 0xa438, 0xfd04, 0xa438, 0xf8fa, 0xa438, 0xef69, 0xa438, 0xd104, + 0xa438, 0xbf8f, 0xa438, 0x92d8, 0xa438, 0x10dc, 0xa438, 0x1981, + 0xa438, 0x9ff9, 0xa438, 0xef96, 0xa438, 0xfefc, 0xa438, 0x04f8, + 0xa438, 0xfbfa, 0xa438, 0xef69, 0xa438, 0xbf8f, 0xa438, 0x87d0, + 0xa438, 0x08d1, 0xa438, 0xff02, 0xa438, 0x8a7c, 0xa438, 0xef96, + 0xa438, 0xfeff, 0xa438, 0xfc04, 0xa438, 0xf8fa, 0xa438, 0xef69, + 0xa438, 0xdd19, 0xa438, 0x809f, 0xa438, 0xfbef, 0xa438, 0x96fe, + 0xa438, 0xfc04, 0xa438, 0xf8e0, 0xa438, 0x8044, 0xa438, 0xf624, + 0xa438, 0xe480, 0xa438, 0x44fc, 0xa438, 0x04f8, 0xa438, 0xe080, + 0xa438, 0x4ff6, 0xa438, 0x24e4, 0xa438, 0x804f, 0xa438, 0xfc04, + 0xa438, 0xf8fa, 0xa438, 0xfbef, 0xa438, 0x79fb, 0xa438, 0xbf8b, + 0xa438, 0x2a02, 0xa438, 0x7291, 0xa438, 0xbf8b, 0xa438, 0x3302, + 0xa438, 0x7291, 0xa438, 0xd68b, 0xa438, 0x2dd7, 0xa438, 0x8b30, + 0xa438, 0x0116, 0xa438, 0xad50, 0xa438, 0x0cbf, 0xa438, 0x8b2a, + 0xa438, 0x0272, 0xa438, 0x9abf, 0xa438, 0x8b33, 0xa438, 0x0272, + 0xa438, 0x9aff, 0xa438, 0xef97, 0xa438, 0xfffe, 0xa438, 0xfc04, + 0xa438, 0xf8f9, 0xa438, 0xfaef, 0xa438, 0x49f8, 0xa438, 0xccf8, + 0xa438, 0xef96, 0xa438, 0x0272, 0xa438, 0x9a1f, 0xa438, 0x22c7, + 0xa438, 0xbd02, 0xa438, 0x72dc, 0xa438, 0xac28, 0xa438, 0x16ac, + 0xa438, 0x3008, 0xa438, 0x0271, 0xa438, 0xe4ef, 0xa438, 0x6712, + 0xa438, 0xaeee, 0xa438, 0xd700, 0xa438, 0x0202, 0xa438, 0x71ff, + 0xa438, 0xac50, 0xa438, 0x05ae, 0xa438, 0xe3d7, 0xa438, 0x0000, + 0xa438, 0xfcc4, 0xa438, 0xfcef, 0xa438, 0x94fe, 0xa438, 0xfdfc, + 0xa438, 0x04cc, 0xa438, 0xc010, 0xa438, 0x44ac, 0xa438, 0x0030, + 0xa438, 0xbce0, 0xa438, 0x74bc, 0xa438, 0xe0b8, 0xa438, 0xbce0, + 0xa438, 0xfcbc, 0xa438, 0xe011, 0xa438, 0xacb4, 0xa438, 0xddac, + 0xa438, 0xb6fa, 0xa438, 0xacb4, 0xa438, 0xf0ac, 0xa438, 0xba92, + 0xa438, 0xacb4, 0xa438, 0xffac, 0xa438, 0x5600, 0xa438, 0xacb4, + 0xa438, 0xccac, 0xa438, 0xb6ff, 0xa438, 0xb034, 0xa436, 0xb818, + 0xa438, 0x2ae4, 0xa436, 0xb81a, 0xa438, 0x380A, 0xa436, 0xb81c, + 0xa438, 0x3EDD, 0xa436, 0xb81e, 0xa438, 0x41A3, 0xa436, 0xb850, + 0xa438, 0x0684, 0xa436, 0xb852, 0xa438, 0x1C02, 0xa436, 0xb878, + 0xa438, 0x1B70, 0xa436, 0xb884, 0xa438, 0x0633, 0xa436, 0xb832, + 0xa438, 0x00ff, 0xa436, 0xacfc, 0xa438, 0x0100, 0xa436, 0xacfe, + 0xa438, 0x8000, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0x3c67, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x000f, 0xa436, 0xad00, + 0xa438, 0x47ff, 0xa436, 0xad02, 0xa438, 0x3e67, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x000f, 0xa436, 0xad00, 0xa438, 0x67ff, 0xa436, 0xad02, + 0xa438, 0x3067, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x000f, 0xa436, 0xad00, + 0xa438, 0x87ff, 0xa436, 0xad02, 0xa438, 0x3267, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x000f, 0xa436, 0xad00, 0xa438, 0xa7ff, 0xa436, 0xad02, + 0xa438, 0x3467, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x000f, 0xa436, 0xad00, + 0xa438, 0xcfff, 0xa436, 0xad02, 0xa438, 0x3667, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x000f, 0xa436, 0xad00, 0xa438, 0xefff, 0xa436, 0xad02, + 0xa438, 0x3867, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x000f, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x3a67, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x000f, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x3ce7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x4fff, 0xa436, 0xad02, 0xa438, 0x3ee7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x6fff, 0xa436, 0xad02, + 0xa438, 0x30e7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x8fff, 0xa436, 0xad02, 0xa438, 0x32e7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xafff, 0xa436, 0xad02, + 0xa438, 0x34e7, 0xa436, 0xad04, 0xa438, 0x1008, 0xa436, 0xad06, + 0xa438, 0xfff4, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x36ff, 0xa436, 0xad04, + 0xa438, 0x1048, 0xa436, 0xad06, 0xa438, 0xfff5, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x38ff, 0xa436, 0xad04, 0xa438, 0x1088, 0xa436, 0xad06, + 0xa438, 0xfff6, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x3aff, 0xa436, 0xad04, + 0xa438, 0x10c8, 0xa436, 0xad06, 0xa438, 0xf417, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0x1109, 0xa436, 0xad06, + 0xa438, 0xf434, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0207, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x1149, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x2227, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x1189, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x4247, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x11c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x6267, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x1209, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x0007, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x1249, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x2027, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x1289, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x4047, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x12c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x6067, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x1309, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x8087, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x1349, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xa0a7, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x1389, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xc0c7, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x13c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xe0e7, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x140b, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x0107, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x144b, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x2127, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x148b, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x4147, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x14cb, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x6167, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x5109, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x8287, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x5149, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xa2a7, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x5189, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xc2c7, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x51c9, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xe2e7, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x5009, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x0a0f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x5049, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x2a2f, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x5089, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x4a4f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x50c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x6a6f, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x5209, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x080f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x5249, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x282f, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x5289, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x484f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x52c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x686f, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x5309, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x888f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x5349, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xa8af, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x5389, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xc8cf, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x53c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xe8ef, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x550b, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x090f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x554b, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x292f, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x558b, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x494f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x55cb, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x696f, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x9209, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x8a8f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x9249, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xaaaf, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x9289, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xcacf, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x92c9, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xeaef, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x9009, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x1217, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x9049, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x3237, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x9089, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x5257, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x90c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x7277, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x9109, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x1017, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x9149, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x3037, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x9189, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x5057, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x91c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x7077, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x9309, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x9097, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x9349, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xb0b7, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x9389, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd0d7, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0x93c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xf0f7, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0x960b, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x1117, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x964b, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x3137, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x968b, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x5157, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x96cb, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x7177, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xd309, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x9297, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0xd349, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xb2b7, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0xd389, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd2d7, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0xd3c9, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xf2f7, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0xd009, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x1a1f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0xd049, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x3a3f, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0xd089, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x5a5f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0xd0c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x7a7f, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0xd109, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x181f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0xd149, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x383f, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0xd189, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x585f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0xd1c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x787f, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0xd209, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x989f, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0xd249, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xb8bf, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0xd289, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd8df, 0xa436, 0xad02, 0xa438, 0xffe0, 0xa436, 0xad04, + 0xa438, 0xd2c9, 0xa436, 0xad06, 0xa438, 0x2517, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xf8ff, 0xa436, 0xad02, + 0xa438, 0xffe0, 0xa436, 0xad04, 0xa438, 0xd70b, 0xa436, 0xad06, + 0xa438, 0x3534, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x191f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xd74b, 0xa436, 0xad06, 0xa438, 0x0555, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x393f, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xd78b, 0xa436, 0xad06, + 0xa438, 0x1576, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x595f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xd7cb, 0xa436, 0xad06, 0xa438, 0x2417, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0x797f, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x000d, 0xa436, 0xad06, + 0xa438, 0x3434, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x9a9f, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x004d, 0xa436, 0xad06, 0xa438, 0x0455, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xbabf, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x008d, 0xa436, 0xad06, + 0xa438, 0x1476, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xdadf, 0xa436, 0xad02, 0xa438, 0xffe2, 0xa436, 0xad04, + 0xa438, 0x00cd, 0xa436, 0xad06, 0xa438, 0x2c17, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xfaf8, 0xa436, 0xad02, + 0xa438, 0xffe2, 0xa436, 0xad04, 0xa438, 0x400d, 0xa436, 0xad06, + 0xa438, 0x3c34, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x8187, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x404d, 0xa436, 0xad06, 0xa438, 0x0c55, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xa1a7, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x408d, 0xa436, 0xad06, + 0xa438, 0x1c76, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xc1c7, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x40cd, 0xa436, 0xad06, 0xa438, 0x2c97, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xe1e7, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x800d, 0xa436, 0xad06, + 0xa438, 0x3cb4, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x898f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x804d, 0xa436, 0xad06, 0xa438, 0x0cd5, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xa9af, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0x808d, 0xa436, 0xad06, + 0xa438, 0x1cf6, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xc9cf, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0x80cd, 0xa436, 0xad06, 0xa438, 0x2d17, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xe9ef, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xc00d, 0xa436, 0xad06, + 0xa438, 0x3d34, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x9197, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xc04d, 0xa436, 0xad06, 0xa438, 0x0d55, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xb1b7, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xc08d, 0xa436, 0xad06, + 0xa438, 0x1d76, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd1d7, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xc0cd, 0xa436, 0xad06, 0xa438, 0x2d97, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xf1f7, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x3dbf, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0x999f, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x0ddf, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xb9bf, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x1dff, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd9df, 0xa436, 0xad02, 0xa438, 0xffe1, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x2fff, 0xa436, 0xad08, + 0xa438, 0x0002, 0xa436, 0xad00, 0xa438, 0xf9ff, 0xa436, 0xad02, + 0xa438, 0xffe1, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x3fff, 0xa436, 0xad08, 0xa438, 0x0002, 0xa436, 0xad00, + 0xa438, 0xd7ff, 0xa436, 0xad02, 0xa438, 0xffe7, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xf7ff, 0xa436, 0xad02, + 0xa438, 0xffe7, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0xffe7, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x3d67, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x57ff, 0xa436, 0xad02, 0xa438, 0x3f67, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x77ff, 0xa436, 0xad02, + 0xa438, 0x3167, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x97ff, 0xa436, 0xad02, 0xa438, 0x3367, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xb7ff, 0xa436, 0xad02, + 0xa438, 0x3567, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xdfff, 0xa436, 0xad02, 0xa438, 0x3767, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x3967, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x3b67, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x3de7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x5fff, 0xa436, 0xad02, 0xa438, 0x3fe7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x7fff, 0xa436, 0xad02, + 0xa438, 0x31e7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x9fff, 0xa436, 0xad02, 0xa438, 0x33e7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xbfff, 0xa436, 0xad02, + 0xa438, 0x35e7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0x37e6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0x39e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x47ff, 0xa436, 0xad02, 0xa438, 0x3be6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x67ff, 0xa436, 0xad02, + 0xa438, 0x2066, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0x2264, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0x2464, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x47ff, 0xa436, 0xad02, 0xa438, 0x2664, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x67ff, 0xa436, 0xad02, + 0xa438, 0x0064, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x87ff, 0xa436, 0xad02, 0xa438, 0x0264, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xa7ff, 0xa436, 0xad02, + 0xa438, 0x0464, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xc7ff, 0xa436, 0xad02, 0xa438, 0x0664, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xe7ff, 0xa436, 0xad02, + 0xa438, 0x0864, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0x0a65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0x0c65, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x47ff, 0xa436, 0xad02, 0xa438, 0x0e65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x67ff, 0xa436, 0xad02, + 0xa438, 0x1065, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x87ff, 0xa436, 0xad02, 0xa438, 0x1266, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xa7ff, 0xa436, 0xad02, + 0xa438, 0x1466, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xc7ff, 0xa436, 0xad02, 0xa438, 0x1666, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xe7ff, 0xa436, 0xad02, + 0xa438, 0x2866, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x2a66, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x2c66, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x4fff, 0xa436, 0xad02, 0xa438, 0x2e66, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x6fff, 0xa436, 0xad02, + 0xa438, 0x20e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x22e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x24e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x4fff, 0xa436, 0xad02, 0xa438, 0x26e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x6fff, 0xa436, 0xad02, + 0xa438, 0x00e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x8fff, 0xa436, 0xad02, 0xa438, 0x02e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xafff, 0xa436, 0xad02, + 0xa438, 0x04e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xcfff, 0xa436, 0xad02, 0xa438, 0x06e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xefff, 0xa436, 0xad02, + 0xa438, 0x08e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x0ae5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x0ce5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x4fff, 0xa436, 0xad02, 0xa438, 0x0ee5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x6fff, 0xa436, 0xad02, + 0xa438, 0x10e5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x8fff, 0xa436, 0xad02, 0xa438, 0x12e6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xafff, 0xa436, 0xad02, + 0xa438, 0x14e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xcfff, 0xa436, 0xad02, 0xa438, 0x16e6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xefff, 0xa436, 0xad02, + 0xa438, 0x28e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0x2ae6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x2ce6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x57ff, 0xa436, 0xad02, 0xa438, 0x2ee6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x77ff, 0xa436, 0xad02, + 0xa438, 0x2166, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0x2364, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x2564, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x57ff, 0xa436, 0xad02, 0xa438, 0x2764, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x77ff, 0xa436, 0xad02, + 0xa438, 0x0164, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x97ff, 0xa436, 0xad02, 0xa438, 0x0364, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xb7ff, 0xa436, 0xad02, + 0xa438, 0x0564, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xd7ff, 0xa436, 0xad02, 0xa438, 0x0764, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xf7ff, 0xa436, 0xad02, + 0xa438, 0x0964, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0x0b65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x0d65, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x57ff, 0xa436, 0xad02, 0xa438, 0x0f65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x77ff, 0xa436, 0xad02, + 0xa438, 0x1165, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x97ff, 0xa436, 0xad02, 0xa438, 0x1366, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xb7ff, 0xa436, 0xad02, + 0xa438, 0x1566, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xd7ff, 0xa436, 0xad02, 0xa438, 0x1766, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xf7ff, 0xa436, 0xad02, + 0xa438, 0x2966, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x2b66, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x2d66, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x5fff, 0xa436, 0xad02, 0xa438, 0x2f66, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x7fff, 0xa436, 0xad02, + 0xa438, 0x21e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x23e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x25e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x5fff, 0xa436, 0xad02, 0xa438, 0x27e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x7fff, 0xa436, 0xad02, + 0xa438, 0x01e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x9fff, 0xa436, 0xad02, 0xa438, 0x03e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xbfff, 0xa436, 0xad02, + 0xa438, 0x05e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xdfff, 0xa436, 0xad02, 0xa438, 0x07e4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x09e4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x0be5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x0de5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x5fff, 0xa436, 0xad02, 0xa438, 0x0fe5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x7fff, 0xa436, 0xad02, + 0xa438, 0x11e5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x9fff, 0xa436, 0xad02, 0xa438, 0x13e6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xbfff, 0xa436, 0xad02, + 0xa438, 0x15e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xdfff, 0xa436, 0xad02, 0xa438, 0x17e6, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x29e6, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x87ff, 0xa436, 0xad02, 0xa438, 0x2be5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xa7ff, 0xa436, 0xad02, + 0xa438, 0x2de5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xc7ff, 0xa436, 0xad02, 0xa438, 0x2fe5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xe7ff, 0xa436, 0xad02, + 0xa438, 0x1865, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x8fff, 0xa436, 0xad02, 0xa438, 0x1a65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xafff, 0xa436, 0xad02, + 0xa438, 0x1c65, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xcfff, 0xa436, 0xad02, 0xa438, 0x1e65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xefff, 0xa436, 0xad02, + 0xa438, 0x18e5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x97ff, 0xa436, 0xad02, 0xa438, 0x1ae5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xb7ff, 0xa436, 0xad02, + 0xa438, 0x1ce5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xd7ff, 0xa436, 0xad02, 0xa438, 0x1ee5, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xf7ff, 0xa436, 0xad02, + 0xa438, 0x1965, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x9fff, 0xa436, 0xad02, 0xa438, 0x1b65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xbfff, 0xa436, 0xad02, + 0xa438, 0x1d65, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xdfff, 0xa436, 0xad02, 0xa438, 0x1f65, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x19e5, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0x1b9c, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0x1d9c, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x1f9c, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x589c, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0x5c9c, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x599c, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x5d9c, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x5a9c, 0xa436, 0xad04, 0xa438, 0x100e, 0xa436, 0xad06, + 0xa438, 0xfff6, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x5eff, 0xa436, 0xad04, + 0xa438, 0x104e, 0xa436, 0xad06, 0xa438, 0xfff7, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x5bff, 0xa436, 0xad04, 0xa438, 0x110e, 0xa436, 0xad06, + 0xa438, 0xfff6, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x5fff, 0xa436, 0xad04, + 0xa438, 0x114e, 0xa436, 0xad06, 0xa438, 0xf817, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0x120f, 0xa436, 0xad06, + 0xa438, 0xf836, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xc3c7, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x124f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xe3e7, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x130f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x0307, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x134f, 0xa436, 0xad06, 0xa438, 0x4917, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x2327, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x510f, 0xa436, 0xad06, + 0xa438, 0x5936, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x4347, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x514f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x6367, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x500f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x8387, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x504f, 0xa436, 0xad06, 0xa438, 0x4817, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xa3a7, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x520f, 0xa436, 0xad06, + 0xa438, 0x5836, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0xcbcf, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x524f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xebef, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x530f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x0b0f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x534f, 0xa436, 0xad06, 0xa438, 0x4917, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x2b2f, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x920f, 0xa436, 0xad06, + 0xa438, 0x5936, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x4b4f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x924f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x6b6f, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x900f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x8b8f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x904f, 0xa436, 0xad06, 0xa438, 0x4817, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xabaf, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x910f, 0xa436, 0xad06, + 0xa438, 0x5836, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0xd3d7, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x914f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xf3f7, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0x930f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x1317, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0x934f, 0xa436, 0xad06, 0xa438, 0x4917, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x3337, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xd30f, 0xa436, 0xad06, + 0xa438, 0x5936, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x5357, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xd34f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x7377, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xd00f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x9397, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xd04f, 0xa436, 0xad06, 0xa438, 0x4817, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xb3b7, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xd10f, 0xa436, 0xad06, + 0xa438, 0x5836, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0xdbdf, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xd14f, 0xa436, 0xad06, 0xa438, 0x0997, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xfbff, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xd20f, 0xa436, 0xad06, + 0xa438, 0x19b6, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x1b1f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xd24f, 0xa436, 0xad06, 0xa438, 0x4917, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x3b3f, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x593f, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x5b5f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x099f, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0x7b7f, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x19bf, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x9b9f, 0xa436, 0xad02, 0xa438, 0xffe3, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x4fff, 0xa436, 0xad08, + 0xa438, 0x0004, 0xa436, 0xad00, 0xa438, 0xbbbf, 0xa436, 0xad02, + 0xa438, 0xffe3, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x5fff, 0xa436, 0xad08, 0xa438, 0x0004, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0xffa4, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x27ff, 0xa436, 0xad02, + 0xa438, 0xffa4, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x47ff, 0xa436, 0xad02, 0xa438, 0xffa4, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x67ff, 0xa436, 0xad02, + 0xa438, 0x58a4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x0fff, 0xa436, 0xad02, 0xa438, 0x5ca4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x2fff, 0xa436, 0xad02, + 0xa438, 0x50a4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x4fff, 0xa436, 0xad02, 0xa438, 0x54a4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x6fff, 0xa436, 0xad02, + 0xa438, 0x59a4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x17ff, 0xa436, 0xad02, 0xa438, 0x5da4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x37ff, 0xa436, 0xad02, + 0xa438, 0x51a4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x57ff, 0xa436, 0xad02, 0xa438, 0x55a4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x77ff, 0xa436, 0xad02, + 0xa438, 0x5aa4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x1fff, 0xa436, 0xad02, 0xa438, 0x5ea4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x3fff, 0xa436, 0xad02, + 0xa438, 0x52a4, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0x5fff, 0xa436, 0xad02, 0xa438, 0x56a4, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0x7fff, 0xa436, 0xad02, + 0xa438, 0x5ba4, 0xa436, 0xad04, 0xa438, 0x2a06, 0xa436, 0xad06, + 0xa438, 0xfff6, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x5fff, 0xa436, 0xad04, + 0xa438, 0x2b06, 0xa436, 0xad06, 0xa438, 0xfff7, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0x53ff, 0xa436, 0xad04, 0xa438, 0x2a06, 0xa436, 0xad06, + 0xa438, 0xfff4, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0x57ff, 0xa436, 0xad04, + 0xa438, 0x2b06, 0xa436, 0xad06, 0xa438, 0xf615, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xf63f, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x069f, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x16bf, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x4fff, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xd0ff, 0xa436, 0xad04, 0xa438, 0x6a46, 0xa436, 0xad06, + 0xa438, 0x5ff6, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xd4ff, 0xa436, 0xad04, + 0xa438, 0x6b46, 0xa436, 0xad06, 0xa438, 0xfff7, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xd8ff, 0xa436, 0xad04, 0xa438, 0x6a46, 0xa436, 0xad06, + 0xa438, 0xfff4, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xdcff, 0xa436, 0xad04, + 0xa438, 0x6b46, 0xa436, 0xad06, 0xa438, 0xf615, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xf63f, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x069f, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x16bf, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x4fff, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xd1ff, 0xa436, 0xad04, 0xa438, 0xaa86, 0xa436, 0xad06, + 0xa438, 0x5ff6, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xd5ff, 0xa436, 0xad04, + 0xa438, 0xab86, 0xa436, 0xad06, 0xa438, 0xfff7, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xd9ff, 0xa436, 0xad04, 0xa438, 0xaa86, 0xa436, 0xad06, + 0xa438, 0xfff4, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xddff, 0xa436, 0xad04, + 0xa438, 0xab86, 0xa436, 0xad06, 0xa438, 0xf615, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xf63f, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x069f, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x16bf, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x4fff, 0xa436, 0xad08, + 0xa438, 0x0003, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xd2ff, 0xa436, 0xad04, 0xa438, 0xeac6, 0xa436, 0xad06, + 0xa438, 0x5ff6, 0xa436, 0xad08, 0xa438, 0x0003, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xd6ff, 0xa436, 0xad04, + 0xa438, 0xebc6, 0xa436, 0xad06, 0xa438, 0xfff7, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xdaff, 0xa436, 0xad04, 0xa438, 0xeac6, 0xa436, 0xad06, + 0xa438, 0xfff4, 0xa436, 0xad08, 0xa438, 0x0007, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xdeff, 0xa436, 0xad04, + 0xa438, 0xebc6, 0xa436, 0xad06, 0xa438, 0xf615, 0xa436, 0xad08, + 0xa438, 0x0007, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0xf63f, 0xa436, 0xad08, 0xa438, 0x0017, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x069f, 0xa436, 0xad08, + 0xa438, 0x0013, 0xa436, 0xad00, 0xa438, 0xffff, 0xa436, 0xad02, + 0xa438, 0xffff, 0xa436, 0xad04, 0xa438, 0xffff, 0xa436, 0xad06, + 0xa438, 0x16bf, 0xa436, 0xad08, 0xa438, 0x0013, 0xa436, 0xad00, + 0xa438, 0xffff, 0xa436, 0xad02, 0xa438, 0xffff, 0xa436, 0xad04, + 0xa438, 0xffff, 0xa436, 0xad06, 0xa438, 0x4fff, 0xa436, 0xad08, + 0xa438, 0x0013, 0xa436, 0xad00, 0xa438, 0xfffa, 0xa436, 0xad02, + 0xa438, 0xd3ff, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0x5fff, 0xa436, 0xad08, 0xa438, 0x0013, 0xa436, 0xad00, + 0xa438, 0xc7ff, 0xa436, 0xad02, 0xa438, 0xd7e7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0017, 0xa436, 0xad00, 0xa438, 0xe7ff, 0xa436, 0xad02, + 0xa438, 0xdbe7, 0xa436, 0xad04, 0xa438, 0xfffe, 0xa436, 0xad06, + 0xa438, 0xffff, 0xa436, 0xad08, 0xa438, 0x0017, 0xa436, 0xad00, + 0xa438, 0x07ff, 0xa436, 0xad02, 0xa438, 0xdfe7, 0xa436, 0xad04, + 0xa438, 0xfffe, 0xa436, 0xad06, 0xa438, 0xffff, 0xa436, 0xad08, + 0xa438, 0x0017, 0xa436, 0xacfc, 0xa438, 0x0000, 0xa436, 0xaccc, + 0xa438, 0x2000, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x2001, 0xa436, 0xacce, 0xa438, 0x6008, 0xa436, 0xaccc, + 0xa438, 0x2002, 0xa436, 0xacce, 0xa438, 0x6010, 0xa436, 0xaccc, + 0xa438, 0x2003, 0xa436, 0xacce, 0xa438, 0x6020, 0xa436, 0xaccc, + 0xa438, 0x2004, 0xa436, 0xacce, 0xa438, 0x6060, 0xa436, 0xaccc, + 0xa438, 0x2005, 0xa436, 0xacce, 0xa438, 0x60a0, 0xa436, 0xaccc, + 0xa438, 0x2006, 0xa436, 0xacce, 0xa438, 0x60e0, 0xa436, 0xaccc, + 0xa438, 0x2007, 0xa436, 0xacce, 0xa438, 0x6128, 0xa436, 0xaccc, + 0xa438, 0x2008, 0xa436, 0xacce, 0xa438, 0x6178, 0xa436, 0xaccc, + 0xa438, 0x2009, 0xa436, 0xacce, 0xa438, 0x61a8, 0xa436, 0xaccc, + 0xa438, 0x200a, 0xa436, 0xacce, 0xa438, 0x61f0, 0xa436, 0xaccc, + 0xa438, 0x200b, 0xa436, 0xacce, 0xa438, 0x6248, 0xa436, 0xaccc, + 0xa438, 0x200c, 0xa436, 0xacce, 0xa438, 0x6258, 0xa436, 0xaccc, + 0xa438, 0x200d, 0xa436, 0xacce, 0xa438, 0x6268, 0xa436, 0xaccc, + 0xa438, 0x200e, 0xa436, 0xacce, 0xa438, 0x6270, 0xa436, 0xaccc, + 0xa438, 0x200f, 0xa436, 0xacce, 0xa438, 0x6274, 0xa436, 0xaccc, + 0xa438, 0x2010, 0xa436, 0xacce, 0xa438, 0x627c, 0xa436, 0xaccc, + 0xa438, 0x2011, 0xa436, 0xacce, 0xa438, 0x6284, 0xa436, 0xaccc, + 0xa438, 0x2012, 0xa436, 0xacce, 0xa438, 0x6294, 0xa436, 0xaccc, + 0xa438, 0x2013, 0xa436, 0xacce, 0xa438, 0x629c, 0xa436, 0xaccc, + 0xa438, 0x2014, 0xa436, 0xacce, 0xa438, 0x62ac, 0xa436, 0xaccc, + 0xa438, 0x2015, 0xa436, 0xacce, 0xa438, 0x62bc, 0xa436, 0xaccc, + 0xa438, 0x2016, 0xa436, 0xacce, 0xa438, 0x62c4, 0xa436, 0xaccc, + 0xa438, 0x2017, 0xa436, 0xacce, 0xa438, 0x7000, 0xa436, 0xaccc, + 0xa438, 0x2018, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x2019, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201a, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201b, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201c, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201d, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201e, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xaccc, + 0xa438, 0x201f, 0xa436, 0xacce, 0xa438, 0x6000, 0xa436, 0xacce, + 0xa438, 0x0000, 0xa436, 0x0000, 0xa438, 0x0000, 0xb82e, 0x0000, + 0xa436, 0x8023, 0xa438, 0x0000, 0xa436, 0x801E, 0xa438, 0x0027, + 0xB820, 0x0000, 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8126a_2_3[] = { + 0xb892, 0x0000, 0xb88e, 0xC15C, 0xb890, 0x0303, 0xb890, 0x0506, + 0xb890, 0x0807, 0xb890, 0x090B, 0xb890, 0x0E12, 0xb890, 0x1617, + 0xb890, 0x1C24, 0xb890, 0x2B37, 0xb890, 0x0203, 0xb890, 0x0304, + 0xb890, 0x0504, 0xb890, 0x0506, 0xb890, 0x0708, 0xb890, 0x090A, + 0xb890, 0x0B0E, 0xb890, 0x1013, 0xb890, 0x1519, 0xb890, 0x1D22, + 0xb890, 0x282E, 0xb890, 0x363E, 0xb890, 0x474B, 0xb88e, 0xC196, + 0xb890, 0x3F5E, 0xb890, 0xF834, 0xb890, 0x6C01, 0xb890, 0xA67F, + 0xb890, 0xA06C, 0xb890, 0x043B, 0xb890, 0x6190, 0xb890, 0x88DB, + 0xb890, 0x9ECD, 0xb890, 0x4DBC, 0xb890, 0x6E0E, 0xb890, 0x9F2D, + 0xb890, 0x2C18, 0xb890, 0x5E8C, 0xb890, 0x5BFE, 0xb890, 0x183C, + 0xb890, 0x23C9, 0xb890, 0x3E84, 0xb890, 0x3C20, 0xb890, 0xCC56, + 0xb890, 0x3480, 0xb890, 0x0040, 0xb88e, 0xC00F, 0xb890, 0x3502, + 0xb890, 0x0203, 0xb890, 0x0303, 0xb890, 0x0404, 0xb890, 0x0506, + 0xb890, 0x0607, 0xb890, 0x080A, 0xb890, 0x0B0D, 0xb890, 0x0E10, + 0xb890, 0x1114, 0xb890, 0x171B, 0xb890, 0x1F22, 0xb890, 0x2832, + 0xb890, 0x0101, 0xb890, 0x0101, 0xb890, 0x0202, 0xb890, 0x0303, + 0xb890, 0x0404, 0xb890, 0x0506, 0xb890, 0x0709, 0xb890, 0x0A0D, + 0xb88e, 0xC047, 0xb890, 0x365F, 0xb890, 0xBE10, 0xb890, 0x84E4, + 0xb890, 0x60E9, 0xb890, 0xA86A, 0xb890, 0xF1E3, 0xb890, 0xF73F, + 0xb890, 0x5C02, 0xb890, 0x9547, 0xb890, 0xC30C, 0xb890, 0xB064, + 0xb890, 0x079A, 0xb890, 0x1E23, 0xb890, 0x1B5D, 0xb890, 0x92E7, + 0xb890, 0x4BAF, 0xb890, 0x2386, 0xb890, 0x01B6, 0xb890, 0x6F82, + 0xb890, 0xDC1C, 0xb890, 0x8C92, 0xb88e, 0xC110, 0xb890, 0x0C7F, + 0xb890, 0x1014, 0xb890, 0x231D, 0xb890, 0x2023, 0xb890, 0x2628, + 0xb890, 0x2A2D, 0xb890, 0x2D2C, 0xb890, 0x2C2E, 0xb890, 0x320D, + 0xb88e, 0xC186, 0xb890, 0x0306, 0xb890, 0x0804, 0xb890, 0x0406, + 0xb890, 0x0707, 0xb890, 0x0709, 0xb890, 0x0B0F, 0xb890, 0x161D, + 0xb890, 0x202A, 0xb890, 0x3F5E, 0xb88e, 0xC1C1, 0xb890, 0x0040, + 0xb890, 0x5920, 0xb890, 0x88CD, 0xb890, 0x1CA1, 0xb890, 0x3D20, + 0xb890, 0x3AE4, 0xb890, 0x6A43, 0xb890, 0x30AF, 0xb890, 0xDD16, + 0xb88e, 0xC283, 0xb890, 0x1611, 0xb890, 0x161C, 0xb890, 0x2127, + 0xb890, 0x2C32, 0xb890, 0x373D, 0xb890, 0x4247, 0xb890, 0x4D52, + 0xb890, 0x585A, 0xb890, 0x0004, 0xb890, 0x080C, 0xb890, 0x1014, + 0xb890, 0x181B, 0xb890, 0x1F23, 0xb890, 0x272B, 0xb890, 0x2F33, + 0xb890, 0x363A, 0xb890, 0x3E42, 0xb890, 0x464A, 0xb890, 0x4D51, + 0xb890, 0x5559, 0xb890, 0x5D65, 0xb890, 0xE769, 0xb890, 0xEB56, + 0xb890, 0xC04B, 0xb890, 0xD502, 0xb890, 0x2FB1, 0xb890, 0x33B5, + 0xb890, 0x37F8, 0xb890, 0xBB98, 0xb890, 0x7450, 0xb890, 0x4C48, + 0xb890, 0x12DC, 0xb890, 0xDCDC, 0xb890, 0x934A, 0xb890, 0x3E33, + 0xb890, 0xE496, 0xb890, 0x724E, 0xb890, 0x2B07, 0xb890, 0xE4C0, + 0xb890, 0x9C79, 0xb890, 0x5512, 0xb88e, 0xC212, 0xb890, 0x2020, + 0xb890, 0x2020, 0xb890, 0x2020, 0xb890, 0x2020, 0xb890, 0x2020, + 0xb890, 0x2019, 0xb88e, 0xC24D, 0xb890, 0x8400, 0xb890, 0x0000, + 0xb890, 0x0000, 0xb890, 0x0000, 0xb890, 0x0000, 0xb890, 0x0000, + 0xb88e, 0xC2D3, 0xb890, 0x5524, 0xb890, 0x2526, 0xb890, 0x2728, + 0xb88e, 0xC2E3, 0xb890, 0x3323, 0xb890, 0x2324, 0xb890, 0x2425, + 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8126a_3_1[] = { + 0xa436, 0x8023, 0xa438, 0x4701, 0xa436, 0xB82E, 0xa438, 0x0001, + 0xb820, 0x0090, 0xa436, 0xA016, 0xa438, 0x0000, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x801a, 0xa438, 0x1800, 0xa438, 0x802a, + 0xa438, 0x1800, 0xa438, 0x8032, 0xa438, 0x1800, 0xa438, 0x803a, + 0xa438, 0x1800, 0xa438, 0x803e, 0xa438, 0x1800, 0xa438, 0x8044, + 0xa438, 0x1800, 0xa438, 0x804b, 0xa438, 0xd504, 0xa438, 0xc9b5, + 0xa438, 0xd500, 0xa438, 0xd707, 0xa438, 0x4070, 0xa438, 0x1800, + 0xa438, 0x1082, 0xa438, 0xd504, 0xa438, 0x1800, 0xa438, 0x107a, + 0xa438, 0x61d0, 0xa438, 0xd701, 0xa438, 0x60a5, 0xa438, 0xd504, + 0xa438, 0xc9b2, 0xa438, 0xd500, 0xa438, 0xf004, 0xa438, 0xd504, + 0xa438, 0xc9b1, 0xa438, 0xd500, 0xa438, 0xd707, 0xa438, 0x6070, + 0xa438, 0x1800, 0xa438, 0x10b0, 0xa438, 0x1800, 0xa438, 0x10c5, + 0xa438, 0xd707, 0xa438, 0x2005, 0xa438, 0x8030, 0xa438, 0xd75e, + 0xa438, 0x1800, 0xa438, 0x138c, 0xa438, 0x1800, 0xa438, 0x13ff, + 0xa438, 0xc504, 0xa438, 0xce20, 0xa438, 0xcf01, 0xa438, 0xd70a, + 0xa438, 0x4005, 0xa438, 0xcf02, 0xa438, 0x1800, 0xa438, 0x1b99, + 0xa438, 0xa980, 0xa438, 0xd500, 0xa438, 0x1800, 0xa438, 0x144d, + 0xa438, 0x907f, 0xa438, 0x91a3, 0xa438, 0x9306, 0xa438, 0xb118, + 0xa438, 0x1800, 0xa438, 0x2147, 0xa438, 0x907f, 0xa438, 0x9209, + 0xa438, 0x91a3, 0xa438, 0x9306, 0xa438, 0xb118, 0xa438, 0x1800, + 0xa438, 0x203c, 0xa436, 0xA026, 0xa438, 0xffff, 0xa436, 0xA024, + 0xa438, 0x2033, 0xa436, 0xA022, 0xa438, 0x213f, 0xa436, 0xA020, + 0xa438, 0x144c, 0xa436, 0xA006, 0xa438, 0x1b98, 0xa436, 0xA004, + 0xa438, 0x138b, 0xa436, 0xA002, 0xa438, 0x10c4, 0xa436, 0xA000, + 0xa438, 0x1079, 0xa436, 0xA008, 0xa438, 0x7f00, 0xa436, 0xA016, + 0xa438, 0x0000, 0xa436, 0xA012, 0xa438, 0x0ff8, 0xa436, 0xA014, + 0xa438, 0xd04d, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa436, 0xA152, 0xa438, 0x12dc, 0xa436, 0xA154, 0xa438, 0x3fff, + 0xa436, 0xA156, 0xa438, 0x3fff, 0xa436, 0xA158, 0xa438, 0x3fff, + 0xa436, 0xA15A, 0xa438, 0x3fff, 0xa436, 0xA15C, 0xa438, 0x3fff, + 0xa436, 0xA15E, 0xa438, 0x3fff, 0xa436, 0xA160, 0xa438, 0x3fff, + 0xa436, 0xA150, 0xa438, 0x0001, 0xa436, 0xA016, 0xa438, 0x0020, + 0xa436, 0xA012, 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, + 0xa438, 0x8010, 0xa438, 0x1800, 0xa438, 0x801a, 0xa438, 0x1800, + 0xa438, 0x801a, 0xa438, 0x1800, 0xa438, 0x810a, 0xa438, 0x1800, + 0xa438, 0x8111, 0xa438, 0x1800, 0xa438, 0x8341, 0xa438, 0x1800, + 0xa438, 0x8349, 0xa438, 0x1800, 0xa438, 0x83df, 0xa438, 0xd706, + 0xa438, 0x60a9, 0xa438, 0xd700, 0xa438, 0x60a1, 0xa438, 0x1800, + 0xa438, 0x0962, 0xa438, 0x1800, 0xa438, 0x0962, 0xa438, 0x1800, + 0xa438, 0x0982, 0xa438, 0xd70d, 0xa438, 0x40fd, 0xa438, 0xd702, + 0xa438, 0x40a0, 0xa438, 0xd70c, 0xa438, 0x4066, 0xa438, 0x8710, + 0xa438, 0xf002, 0xa438, 0xa710, 0xa438, 0x9580, 0xa438, 0x0c03, + 0xa438, 0x1502, 0xa438, 0xa304, 0xa438, 0x9503, 0xa438, 0x0c1f, + 0xa438, 0x0d07, 0xa438, 0x8dc0, 0xa438, 0x1000, 0xa438, 0x12b5, + 0xa438, 0xcb81, 0xa438, 0xd70c, 0xa438, 0x4882, 0xa438, 0xd706, + 0xa438, 0x407a, 0xa438, 0xd70c, 0xa438, 0x4807, 0xa438, 0xd706, + 0xa438, 0x405a, 0xa438, 0x8910, 0xa438, 0xa210, 0xa438, 0xd704, + 0xa438, 0x611c, 0xa438, 0x0cc0, 0xa438, 0x0080, 0xa438, 0x0c03, + 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x03a0, 0xa438, 0xccb5, + 0xa438, 0x0cc0, 0xa438, 0x0080, 0xa438, 0x0c03, 0xa438, 0x0102, + 0xa438, 0x0ce0, 0xa438, 0x0340, 0xa438, 0xcc52, 0xa438, 0xd706, + 0xa438, 0x42ba, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, + 0xa438, 0x0f1c, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0x8190, 0xa438, 0x8204, + 0xa438, 0xf016, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, + 0xa438, 0x0f1b, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0xd70c, 0xa438, 0x6047, + 0xa438, 0xf002, 0xa438, 0xf00c, 0xa438, 0xd403, 0xa438, 0xcb82, + 0xa438, 0x1000, 0xa438, 0x1203, 0xa438, 0xd40a, 0xa438, 0x1000, + 0xa438, 0x1203, 0xa438, 0xd70c, 0xa438, 0x4247, 0xa438, 0x1000, + 0xa438, 0x131d, 0xa438, 0x8a40, 0xa438, 0x1000, 0xa438, 0x120e, + 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x1220, 0xa438, 0x8104, + 0xa438, 0x1000, 0xa438, 0x1217, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa704, 0xa438, 0x9503, 0xa438, 0xcb88, 0xa438, 0xf012, + 0xa438, 0xa210, 0xa438, 0xa00a, 0xa438, 0xaa40, 0xa438, 0x1000, + 0xa438, 0x120e, 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x1220, + 0xa438, 0x8104, 0xa438, 0x1000, 0xa438, 0x1217, 0xa438, 0xa190, + 0xa438, 0xa284, 0xa438, 0xa404, 0xa438, 0x8a10, 0xa438, 0x8a80, + 0xa438, 0xcb84, 0xa438, 0xd13e, 0xa438, 0xd05a, 0xa438, 0xd13e, + 0xa438, 0xd06b, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd700, + 0xa438, 0x3559, 0xa438, 0x80a8, 0xa438, 0xfffb, 0xa438, 0xd700, + 0xa438, 0x604b, 0xa438, 0xcb8a, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd700, 0xa438, 0x3659, 0xa438, 0x80b1, 0xa438, 0xfffb, + 0xa438, 0xd700, 0xa438, 0x606b, 0xa438, 0xcb8b, 0xa438, 0x5eeb, + 0xa438, 0xd700, 0xa438, 0x6041, 0xa438, 0xa402, 0xa438, 0xcb8c, + 0xa438, 0xd706, 0xa438, 0x609a, 0xa438, 0xd1b7, 0xa438, 0xd049, + 0xa438, 0xf003, 0xa438, 0xd160, 0xa438, 0xd04b, 0xa438, 0x1000, + 0xa438, 0x126b, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xcb8d, + 0xa438, 0x8710, 0xa438, 0xd71f, 0xa438, 0x5fd4, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd71f, 0xa438, 0x7fb4, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd71f, + 0xa438, 0x6105, 0xa438, 0x6054, 0xa438, 0xfffb, 0xa438, 0x1000, + 0xa438, 0x126b, 0xa438, 0xd700, 0xa438, 0x5fab, 0xa438, 0xfff0, + 0xa438, 0xa710, 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd71f, 0xa438, 0x7fa5, 0xa438, 0x9820, 0xa438, 0xd114, + 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd700, + 0xa438, 0x5fba, 0xa438, 0xd704, 0xa438, 0x5f76, 0xa438, 0xd700, + 0xa438, 0x5f34, 0xa438, 0xd700, 0xa438, 0x6081, 0xa438, 0xd706, + 0xa438, 0x405a, 0xa438, 0xa480, 0xa438, 0xcb86, 0xa438, 0xd706, + 0xa438, 0x609a, 0xa438, 0xd1c8, 0xa438, 0xd045, 0xa438, 0xf003, + 0xa438, 0xd17a, 0xa438, 0xd04b, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x0cc0, 0xa438, 0x0000, + 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0x0ce0, 0xa438, 0x0320, + 0xa438, 0xcc29, 0xa438, 0xa208, 0xa438, 0x8204, 0xa438, 0xd114, + 0xa438, 0xd040, 0xa438, 0xd700, 0xa438, 0x5ff4, 0xa438, 0x1800, + 0xa438, 0x0c3e, 0xa438, 0xd706, 0xa438, 0x609d, 0xa438, 0xd417, + 0xa438, 0x1000, 0xa438, 0x1203, 0xa438, 0x1800, 0xa438, 0x0d2e, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0xd70c, 0xa438, 0x5fa4, + 0xa438, 0xa706, 0xa438, 0xd70c, 0xa438, 0x408b, 0xa438, 0xa701, + 0xa438, 0xa502, 0xa438, 0xa880, 0xa438, 0x8801, 0xa438, 0x8e01, + 0xa438, 0xca50, 0xa438, 0x1000, 0xa438, 0x81b6, 0xa438, 0xca51, + 0xa438, 0xd70e, 0xa438, 0x2210, 0xa438, 0x81b4, 0xa438, 0xd70c, + 0xa438, 0x4084, 0xa438, 0xd705, 0xa438, 0x5efd, 0xa438, 0xf007, + 0xa438, 0x1000, 0xa438, 0x17c2, 0xa438, 0xd70c, 0xa438, 0x5ca2, + 0xa438, 0x1800, 0xa438, 0x1692, 0xa438, 0xd70c, 0xa438, 0x605a, + 0xa438, 0x9a10, 0xa438, 0x8e40, 0xa438, 0x8404, 0xa438, 0x1000, + 0xa438, 0x1827, 0xa438, 0x8e80, 0xa438, 0xca62, 0xa438, 0xd705, + 0xa438, 0x3084, 0xa438, 0x8196, 0xa438, 0xba10, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x1000, 0xa438, 0x8290, 0xa438, 0x0c03, + 0xa438, 0x0100, 0xa438, 0xd702, 0xa438, 0x4638, 0xa438, 0xd1c4, + 0xa438, 0xd044, 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, + 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x8108, + 0xa438, 0x0c1f, 0xa438, 0x0907, 0xa438, 0x8940, 0xa438, 0x1000, + 0xa438, 0x17db, 0xa438, 0xa0c4, 0xa438, 0x8610, 0xa438, 0x8030, + 0xa438, 0x8706, 0xa438, 0x0c07, 0xa438, 0x0b06, 0xa438, 0x8410, + 0xa438, 0xa980, 0xa438, 0xa702, 0xa438, 0xd1c4, 0xa438, 0xd045, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, 0xa438, 0x17e8, + 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x0c07, 0xa438, 0x0b06, + 0xa438, 0xa030, 0xa438, 0xa610, 0xa438, 0xd700, 0xa438, 0x6041, + 0xa438, 0xa501, 0xa438, 0xa108, 0xa438, 0xd1c4, 0xa438, 0xd045, + 0xa438, 0xca63, 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, + 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0xd702, + 0xa438, 0x6078, 0xa438, 0x9920, 0xa438, 0xf003, 0xa438, 0xb920, + 0xa438, 0xa880, 0xa438, 0x9a10, 0xa438, 0x1000, 0xa438, 0x17be, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd71f, 0xa438, 0x5f73, + 0xa438, 0xf011, 0xa438, 0xd70c, 0xa438, 0x409b, 0xa438, 0x9920, + 0xa438, 0x9a10, 0xa438, 0xfff5, 0xa438, 0x80fe, 0xa438, 0x8610, + 0xa438, 0x8501, 0xa438, 0x8980, 0xa438, 0x8702, 0xa438, 0xa410, + 0xa438, 0xa940, 0xa438, 0x81c0, 0xa438, 0xae80, 0xa438, 0x1800, + 0xa438, 0x813b, 0xa438, 0x8804, 0xa438, 0xa704, 0xa438, 0x8788, + 0xa438, 0xff80, 0xa438, 0xbb08, 0xa438, 0x0c1f, 0xa438, 0x0907, + 0xa438, 0x8940, 0xa438, 0x1000, 0xa438, 0x17db, 0xa438, 0x8701, + 0xa438, 0x8502, 0xa438, 0xa0f4, 0xa438, 0xa610, 0xa438, 0xd700, + 0xa438, 0x6061, 0xa438, 0xa002, 0xa438, 0xa501, 0xa438, 0x8706, + 0xa438, 0x8410, 0xa438, 0xa980, 0xa438, 0xca64, 0xa438, 0xd110, + 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, + 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x8804, + 0xa438, 0xa706, 0xa438, 0x1800, 0xa438, 0x8115, 0xa438, 0x1800, + 0xa438, 0x147c, 0xa438, 0xd705, 0xa438, 0x405f, 0xa438, 0xf036, + 0xa438, 0xd705, 0xa438, 0x6234, 0xa438, 0xd70c, 0xa438, 0x41c6, + 0xa438, 0xd70d, 0xa438, 0x419d, 0xa438, 0xd70d, 0xa438, 0x417e, + 0xa438, 0xd704, 0xa438, 0x6127, 0xa438, 0x2951, 0xa438, 0x81cb, + 0xa438, 0xd70c, 0xa438, 0x4083, 0xa438, 0xd70c, 0xa438, 0x2e81, + 0xa438, 0x81cb, 0xa438, 0xf0c5, 0xa438, 0x80fe, 0xa438, 0x8610, + 0xa438, 0x8501, 0xa438, 0x8704, 0xa438, 0x0c30, 0xa438, 0x0410, + 0xa438, 0xa701, 0xa438, 0xac02, 0xa438, 0xa502, 0xa438, 0x8980, + 0xa438, 0xca60, 0xa438, 0xa004, 0xa438, 0xd70c, 0xa438, 0x6065, + 0xa438, 0x1800, 0xa438, 0x81dc, 0xa438, 0x8004, 0xa438, 0xa804, + 0xa438, 0x0c0f, 0xa438, 0x0602, 0xa438, 0x0c70, 0xa438, 0x0730, + 0xa438, 0xa708, 0xa438, 0xd704, 0xa438, 0x609c, 0xa438, 0x0c1f, + 0xa438, 0x0912, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x090e, + 0xa438, 0xa940, 0xa438, 0x1000, 0xa438, 0x17db, 0xa438, 0xa780, + 0xa438, 0xf0a2, 0xa438, 0xd704, 0xa438, 0x63eb, 0xa438, 0xd705, + 0xa438, 0x43b1, 0xa438, 0xd702, 0xa438, 0x339c, 0xa438, 0x828f, + 0xa438, 0x8788, 0xa438, 0x8704, 0xa438, 0x0c1f, 0xa438, 0x0907, + 0xa438, 0x8940, 0xa438, 0x1000, 0xa438, 0x17db, 0xa438, 0x8410, + 0xa438, 0xa0f4, 0xa438, 0xa610, 0xa438, 0xd700, 0xa438, 0x6061, + 0xa438, 0xa002, 0xa438, 0xa501, 0xa438, 0xa706, 0xa438, 0x8804, + 0xa438, 0xa980, 0xa438, 0xd70c, 0xa438, 0x6085, 0xa438, 0x8701, + 0xa438, 0x8502, 0xa438, 0x8c02, 0xa438, 0xa701, 0xa438, 0xa502, + 0xa438, 0xf082, 0xa438, 0xd70c, 0xa438, 0x60c5, 0xa438, 0xd702, + 0xa438, 0x6053, 0xa438, 0xf07d, 0xa438, 0x1800, 0xa438, 0x828c, + 0xa438, 0xd70d, 0xa438, 0x4d1b, 0xa438, 0xba10, 0xa438, 0xae40, + 0xa438, 0x0cfc, 0xa438, 0x03b4, 0xa438, 0x0cfc, 0xa438, 0x05b4, + 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0x1000, 0xa438, 0x17be, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f7c, + 0xa438, 0x8706, 0xa438, 0x8280, 0xa438, 0xace0, 0xa438, 0xa680, + 0xa438, 0xa240, 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, + 0xa438, 0x17e8, 0xa438, 0xd702, 0xa438, 0x5f79, 0xa438, 0x8240, + 0xa438, 0xd702, 0xa438, 0x6898, 0xa438, 0xd702, 0xa438, 0x4957, + 0xa438, 0x1800, 0xa438, 0x827e, 0xa438, 0xa1c0, 0xa438, 0x0c3f, + 0xa438, 0x0220, 0xa438, 0x0cfc, 0xa438, 0x030c, 0xa438, 0x0cfc, + 0xa438, 0x050c, 0xa438, 0x8108, 0xa438, 0x8640, 0xa438, 0xa120, + 0xa438, 0xa640, 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0xa110, + 0xa438, 0xd1c4, 0xa438, 0xd044, 0xa438, 0xca84, 0xa438, 0x1000, + 0xa438, 0x17be, 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, + 0xa438, 0x5f7c, 0xa438, 0xd702, 0xa438, 0x60fc, 0xa438, 0x8210, + 0xa438, 0x0ce0, 0xa438, 0x0320, 0xa438, 0x0ce0, 0xa438, 0x0520, + 0xa438, 0xf002, 0xa438, 0xa210, 0xa438, 0xd1c4, 0xa438, 0xd043, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0x1000, 0xa438, 0x17e8, + 0xa438, 0xd70c, 0xa438, 0x5f7c, 0xa438, 0x8233, 0xa438, 0x0cfc, + 0xa438, 0x036c, 0xa438, 0x0cfc, 0xa438, 0x056c, 0xa438, 0xd1c4, + 0xa438, 0xd044, 0xa438, 0xca85, 0xa438, 0x1000, 0xa438, 0x17be, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f7c, + 0xa438, 0xa680, 0xa438, 0xa240, 0xa438, 0x1000, 0xa438, 0x17be, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd702, 0xa438, 0x5f79, + 0xa438, 0x8240, 0xa438, 0x0cfc, 0xa438, 0x0390, 0xa438, 0x0cfc, + 0xa438, 0x0590, 0xa438, 0xd702, 0xa438, 0x6058, 0xa438, 0xf002, + 0xa438, 0xfec7, 0xa438, 0x81c0, 0xa438, 0x8880, 0xa438, 0x8706, + 0xa438, 0xca61, 0xa438, 0xd1c4, 0xa438, 0xd054, 0xa438, 0x1000, + 0xa438, 0x17be, 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, + 0xa438, 0x5f7d, 0xa438, 0xa706, 0xa438, 0xf004, 0xa438, 0x8788, + 0xa438, 0xa404, 0xa438, 0x8702, 0xa438, 0x0800, 0xa438, 0x8443, + 0xa438, 0x8303, 0xa438, 0x8280, 0xa438, 0x9920, 0xa438, 0x8ce0, + 0xa438, 0x8004, 0xa438, 0xa1c0, 0xa438, 0xd70e, 0xa438, 0x404a, + 0xa438, 0xa280, 0xa438, 0xd702, 0xa438, 0x3bd0, 0xa438, 0x82a0, + 0xa438, 0x0c3f, 0xa438, 0x0223, 0xa438, 0xf003, 0xa438, 0x0c3f, + 0xa438, 0x0220, 0xa438, 0x0cfc, 0xa438, 0x0308, 0xa438, 0x0cfc, + 0xa438, 0x0508, 0xa438, 0x8108, 0xa438, 0x8640, 0xa438, 0xa120, + 0xa438, 0xa640, 0xa438, 0xd702, 0xa438, 0x6077, 0xa438, 0x8103, + 0xa438, 0xf003, 0xa438, 0x0c03, 0xa438, 0x0101, 0xa438, 0xa110, + 0xa438, 0xd702, 0xa438, 0x6077, 0xa438, 0xa108, 0xa438, 0xf006, + 0xa438, 0xd704, 0xa438, 0x6077, 0xa438, 0x8108, 0xa438, 0xf002, + 0xa438, 0xa108, 0xa438, 0xd193, 0xa438, 0xd045, 0xa438, 0xca82, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0xd70e, 0xa438, 0x606a, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f3c, + 0xa438, 0xd702, 0xa438, 0x60fc, 0xa438, 0x8210, 0xa438, 0x0ce0, + 0xa438, 0x0320, 0xa438, 0x0ce0, 0xa438, 0x0520, 0xa438, 0xf002, + 0xa438, 0xa210, 0xa438, 0xd1c4, 0xa438, 0xd043, 0xa438, 0x1000, + 0xa438, 0x17be, 0xa438, 0xd70e, 0xa438, 0x606a, 0xa438, 0x1000, + 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f3c, 0xa438, 0xd702, + 0xa438, 0x3bd0, 0xa438, 0x82de, 0xa438, 0x0c3f, 0xa438, 0x020c, + 0xa438, 0xf002, 0xa438, 0x823f, 0xa438, 0x0cfc, 0xa438, 0x034c, + 0xa438, 0x0cfc, 0xa438, 0x054c, 0xa438, 0xd1c4, 0xa438, 0xd044, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0xd70e, 0xa438, 0x606a, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd70c, 0xa438, 0x5f3c, + 0xa438, 0x820c, 0xa438, 0xa360, 0xa438, 0xa560, 0xa438, 0xd1c4, + 0xa438, 0xd043, 0xa438, 0xca83, 0xa438, 0x1000, 0xa438, 0x17be, + 0xa438, 0xd70e, 0xa438, 0x606a, 0xa438, 0x1000, 0xa438, 0x17e8, + 0xa438, 0xd70c, 0xa438, 0x5f3c, 0xa438, 0xd70e, 0xa438, 0x406a, + 0xa438, 0x8680, 0xa438, 0xf002, 0xa438, 0xa680, 0xa438, 0xa240, + 0xa438, 0x0c0f, 0xa438, 0x0604, 0xa438, 0x0c70, 0xa438, 0x0750, + 0xa438, 0xa708, 0xa438, 0xd704, 0xa438, 0x609c, 0xa438, 0x0c1f, + 0xa438, 0x0914, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0910, + 0xa438, 0xa940, 0xa438, 0x1000, 0xa438, 0x17db, 0xa438, 0xa780, + 0xa438, 0x1000, 0xa438, 0x17be, 0xa438, 0xd70e, 0xa438, 0x606a, + 0xa438, 0x1000, 0xa438, 0x17e8, 0xa438, 0xd702, 0xa438, 0x399c, + 0xa438, 0x8311, 0xa438, 0x8240, 0xa438, 0x8788, 0xa438, 0xd702, + 0xa438, 0x63f8, 0xa438, 0xd705, 0xa438, 0x643c, 0xa438, 0xa402, + 0xa438, 0xf012, 0xa438, 0x8402, 0xa438, 0xd705, 0xa438, 0x611b, + 0xa438, 0xa401, 0xa438, 0xa302, 0xa438, 0xd702, 0xa438, 0x417d, + 0xa438, 0xa440, 0xa438, 0xa280, 0xa438, 0xf008, 0xa438, 0x8401, + 0xa438, 0x8302, 0xa438, 0xd70c, 0xa438, 0x6060, 0xa438, 0xa301, + 0xa438, 0xf002, 0xa438, 0x8301, 0xa438, 0xd70c, 0xa438, 0x4080, + 0xa438, 0xd70e, 0xa438, 0x604a, 0xa438, 0xff5f, 0xa438, 0xd705, + 0xa438, 0x3cdd, 0xa438, 0x8340, 0xa438, 0xff5b, 0xa438, 0x0cfc, + 0xa438, 0x0390, 0xa438, 0x0cfc, 0xa438, 0x0590, 0xa438, 0x0800, + 0xa438, 0xcb50, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0xa310, + 0xa438, 0x9503, 0xa438, 0xcb5f, 0xa438, 0x1800, 0xa438, 0x0d3e, + 0xa438, 0xcb13, 0xa438, 0xd706, 0xa438, 0x6089, 0xa438, 0xd1b8, + 0xa438, 0xd04a, 0xa438, 0xf003, 0xa438, 0xd11c, 0xa438, 0xd04b, + 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd701, 0xa438, 0x67d5, + 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0xd70c, 0xa438, 0x610c, + 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd700, 0xa438, 0x6846, + 0xa438, 0xd706, 0xa438, 0x647b, 0xa438, 0xfffa, 0xa438, 0x1000, + 0xa438, 0x1330, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x0c1f, + 0xa438, 0x0f16, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x5fb3, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0x8f1f, 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd70c, 0xa438, 0x7f33, 0xa438, 0x1000, 0xa438, 0x12b5, + 0xa438, 0x0c07, 0xa438, 0x0c02, 0xa438, 0x0cc0, 0xa438, 0x0080, + 0xa438, 0xd14a, 0xa438, 0xd048, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x1800, 0xa438, 0x8359, + 0xa438, 0x800a, 0xa438, 0x1000, 0xa438, 0x120e, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x1220, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x1220, 0xa438, 0x8001, 0xa438, 0x1000, + 0xa438, 0x1217, 0xa438, 0x0c03, 0xa438, 0x0902, 0xa438, 0x1800, + 0xa438, 0x04ed, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd71f, + 0xa438, 0x5fab, 0xa438, 0xba08, 0xa438, 0x1000, 0xa438, 0x126b, + 0xa438, 0xd71f, 0xa438, 0x7f8b, 0xa438, 0x9a08, 0xa438, 0x1800, + 0xa438, 0x0581, 0xa438, 0x800a, 0xa438, 0xd702, 0xa438, 0x6555, + 0xa438, 0x1000, 0xa438, 0x120e, 0xa438, 0xa004, 0xa438, 0x1000, + 0xa438, 0x1220, 0xa438, 0x8004, 0xa438, 0xa001, 0xa438, 0x1000, + 0xa438, 0x1220, 0xa438, 0x8001, 0xa438, 0x1000, 0xa438, 0x1217, + 0xa438, 0xa00a, 0xa438, 0xa780, 0xa438, 0xcb14, 0xa438, 0xd1b8, + 0xa438, 0xd04a, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x6286, 0xa438, 0xd706, 0xa438, 0x5f5b, + 0xa438, 0x800a, 0xa438, 0x1000, 0xa438, 0x120e, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x1220, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x1220, 0xa438, 0x8001, 0xa438, 0x1000, + 0xa438, 0x1217, 0xa438, 0x0c03, 0xa438, 0x0902, 0xa438, 0x1800, + 0xa438, 0x83a1, 0xa438, 0xa00a, 0xa438, 0x9308, 0xa438, 0xb210, + 0xa438, 0xb301, 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd701, + 0xa438, 0x5fa4, 0xa438, 0xb302, 0xa438, 0x9210, 0xa438, 0xd409, + 0xa438, 0x1000, 0xa438, 0x1203, 0xa438, 0xd103, 0xa438, 0xd04c, + 0xa438, 0x1000, 0xa438, 0x126b, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x1800, 0xa438, 0x0581, 0xa438, 0xd70c, 0xa438, 0x60b3, + 0xa438, 0x1800, 0xa438, 0x83e3, 0xa438, 0x1800, 0xa438, 0x001a, + 0xa438, 0x1800, 0xa438, 0x12cb, 0xa436, 0xA10E, 0xa438, 0x12cf, + 0xa436, 0xA10C, 0xa438, 0x04f8, 0xa436, 0xA10A, 0xa438, 0x0d3d, + 0xa436, 0xA108, 0xa438, 0x15fb, 0xa436, 0xA106, 0xa438, 0x0d2b, + 0xa436, 0xA104, 0xa438, 0x0ecb, 0xa436, 0xA102, 0xa438, 0x09ca, + 0xa436, 0xA100, 0xa438, 0x0960, 0xa436, 0xA110, 0xa438, 0x00ff, + 0xa436, 0xA016, 0xa438, 0x0020, 0xa436, 0xA012, 0xa438, 0x1ff8, + 0xa436, 0xA014, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa436, 0xA164, 0xa438, 0x3fff, 0xa436, 0xA166, + 0xa438, 0x3fff, 0xa436, 0xA168, 0xa438, 0x3fff, 0xa436, 0xA16A, + 0xa438, 0x3fff, 0xa436, 0xA16C, 0xa438, 0x3fff, 0xa436, 0xA16E, + 0xa438, 0x3fff, 0xa436, 0xA170, 0xa438, 0x3fff, 0xa436, 0xA172, + 0xa438, 0x3fff, 0xa436, 0xA162, 0xa438, 0x0000, 0xa436, 0xb87c, + 0xa438, 0x8a63, 0xa436, 0xb87e, 0xa438, 0xaf8a, 0xa438, 0x7baf, + 0xa438, 0x8ab6, 0xa438, 0xaf8a, 0xa438, 0xd6af, 0xa438, 0x8ae4, + 0xa438, 0xaf8a, 0xa438, 0xf2af, 0xa438, 0x8b07, 0xa438, 0xaf8b, + 0xa438, 0x07af, 0xa438, 0x8b07, 0xa438, 0xad35, 0xa438, 0x27bf, + 0xa438, 0x7308, 0xa438, 0x027b, 0xa438, 0x07ac, 0xa438, 0x280d, + 0xa438, 0xbf73, 0xa438, 0x0b02, 0xa438, 0x7b07, 0xa438, 0xac28, + 0xa438, 0x04d0, 0xa438, 0x05ae, 0xa438, 0x02d0, 0xa438, 0x01d1, + 0xa438, 0x01d3, 0xa438, 0x04ee, 0xa438, 0x8640, 0xa438, 0x00ee, + 0xa438, 0x8641, 0xa438, 0x00af, 0xa438, 0x6aa6, 0xa438, 0xd100, + 0xa438, 0xd300, 0xa438, 0xee86, 0xa438, 0x4001, 0xa438, 0xee86, + 0xa438, 0x4124, 0xa438, 0xd00f, 0xa438, 0xaf6a, 0xa438, 0xa6bf, + 0xa438, 0x739e, 0xa438, 0x027b, 0xa438, 0x07ad, 0xa438, 0x280b, + 0xa438, 0xe18f, 0xa438, 0xfdad, 0xa438, 0x2805, 0xa438, 0xe08f, + 0xa438, 0xfeae, 0xa438, 0x03e0, 0xa438, 0x8fff, 0xa438, 0xe489, + 0xa438, 0xe7e0, 0xa438, 0x89e7, 0xa438, 0xaf67, 0xa438, 0x9fa0, + 0xa438, 0x9402, 0xa438, 0xae03, 0xa438, 0xa0b5, 0xa438, 0x03af, + 0xa438, 0x0d89, 0xa438, 0xaf0d, 0xa438, 0xafa0, 0xa438, 0x9402, + 0xa438, 0xae03, 0xa438, 0xa0b5, 0xa438, 0x03af, 0xa438, 0x0c64, + 0xa438, 0xaf0c, 0xa438, 0xcce0, 0xa438, 0x8013, 0xa438, 0x026b, + 0xa438, 0xa4ad, 0xa438, 0x2109, 0xa438, 0x0264, 0xa438, 0x47bf, + 0xa438, 0x769b, 0xa438, 0x027a, 0xa438, 0xbcaf, 0xa438, 0x6562, + 0xa436, 0xb85e, 0xa438, 0x6A7F, 0xa436, 0xb860, 0xa438, 0x679C, + 0xa436, 0xb862, 0xa438, 0x0d86, 0xa436, 0xb864, 0xa438, 0x0c61, + 0xa436, 0xb886, 0xa438, 0x6553, 0xa436, 0xb888, 0xa438, 0xffff, + 0xa436, 0xb88a, 0xa438, 0xffff, 0xa436, 0xb88c, 0xa438, 0xffff, + 0xa436, 0xb838, 0xa438, 0x001f, 0xb820, 0x0010, 0xa436, 0x8629, + 0xa438, 0xaf86, 0xa438, 0x41af, 0xa438, 0x8644, 0xa438, 0xaf88, + 0xa438, 0x0caf, 0xa438, 0x8813, 0xa438, 0xaf88, 0xa438, 0x4baf, + 0xa438, 0x884b, 0xa438, 0xaf88, 0xa438, 0x4baf, 0xa438, 0x884b, + 0xa438, 0xaf1d, 0xa438, 0x8a02, 0xa438, 0x864d, 0xa438, 0x0210, + 0xa438, 0x64af, 0xa438, 0x1063, 0xa438, 0xf8fa, 0xa438, 0xef69, + 0xa438, 0xe080, 0xa438, 0x4cac, 0xa438, 0x2517, 0xa438, 0xe080, + 0xa438, 0x40ad, 0xa438, 0x251a, 0xa438, 0x0286, 0xa438, 0x7ce0, + 0xa438, 0x8040, 0xa438, 0xac25, 0xa438, 0x11bf, 0xa438, 0x87f4, + 0xa438, 0x0277, 0xa438, 0xf6ae, 0xa438, 0x0902, 0xa438, 0x87b3, + 0xa438, 0x0287, 0xa438, 0xe902, 0xa438, 0x87de, 0xa438, 0xef96, + 0xa438, 0xfefc, 0xa438, 0x04f8, 0xa438, 0xe080, 0xa438, 0x18ad, + 0xa438, 0x2611, 0xa438, 0xe08f, 0xa438, 0x9cac, 0xa438, 0x2005, + 0xa438, 0x0286, 0xa438, 0x99ae, 0xa438, 0x0302, 0xa438, 0x8707, + 0xa438, 0x0287, 0xa438, 0x5002, 0xa438, 0x87de, 0xa438, 0xfc04, + 0xa438, 0xf8f9, 0xa438, 0xef79, 0xa438, 0xfbbf, 0xa438, 0x87f7, + 0xa438, 0x0278, 0xa438, 0x385c, 0xa438, 0x2000, 0xa438, 0x0d4d, + 0xa438, 0xa101, 0xa438, 0x51bf, 0xa438, 0x87f7, 0xa438, 0x0278, + 0xa438, 0x385c, 0xa438, 0x07ff, 0xa438, 0xe38f, 0xa438, 0x9d1b, + 0xa438, 0x319f, 0xa438, 0x410d, 0xa438, 0x48e3, 0xa438, 0x8f9e, + 0xa438, 0x1b31, 0xa438, 0x9f38, 0xa438, 0xbf87, 0xa438, 0xfa02, + 0xa438, 0x7838, 0xa438, 0x5c07, 0xa438, 0xffe3, 0xa438, 0x8f9f, + 0xa438, 0x1b31, 0xa438, 0x9f28, 0xa438, 0x0d48, 0xa438, 0xe38f, + 0xa438, 0xa01b, 0xa438, 0x319f, 0xa438, 0x1fbf, 0xa438, 0x87fd, + 0xa438, 0x0278, 0xa438, 0x385c, 0xa438, 0x07ff, 0xa438, 0xe38f, + 0xa438, 0xa11b, 0xa438, 0x319f, 0xa438, 0x0f0d, 0xa438, 0x48e3, + 0xa438, 0x8fa2, 0xa438, 0x1b31, 0xa438, 0x9f06, 0xa438, 0xee8f, + 0xa438, 0x9c01, 0xa438, 0xae04, 0xa438, 0xee8f, 0xa438, 0x9c00, + 0xa438, 0xffef, 0xa438, 0x97fd, 0xa438, 0xfc04, 0xa438, 0xf8f9, + 0xa438, 0xef79, 0xa438, 0xfbbf, 0xa438, 0x87f7, 0xa438, 0x0278, + 0xa438, 0x385c, 0xa438, 0x2000, 0xa438, 0x0d4d, 0xa438, 0xa100, + 0xa438, 0x20bf, 0xa438, 0x87f7, 0xa438, 0x0278, 0xa438, 0x385c, + 0xa438, 0x0600, 0xa438, 0x0d49, 0xa438, 0xe38f, 0xa438, 0xa31b, + 0xa438, 0x319f, 0xa438, 0x0ebf, 0xa438, 0x8800, 0xa438, 0x0277, + 0xa438, 0xf6bf, 0xa438, 0x8806, 0xa438, 0x0277, 0xa438, 0xf6ae, + 0xa438, 0x0cbf, 0xa438, 0x8800, 0xa438, 0x0277, 0xa438, 0xedbf, + 0xa438, 0x8806, 0xa438, 0x0277, 0xa438, 0xedee, 0xa438, 0x8f9c, + 0xa438, 0x00ff, 0xa438, 0xef97, 0xa438, 0xfdfc, 0xa438, 0x04f8, + 0xa438, 0xf9ef, 0xa438, 0x79fb, 0xa438, 0xbf87, 0xa438, 0xf702, + 0xa438, 0x7838, 0xa438, 0x5c20, 0xa438, 0x000d, 0xa438, 0x4da1, + 0xa438, 0x014a, 0xa438, 0xbf87, 0xa438, 0xf702, 0xa438, 0x7838, + 0xa438, 0x5c07, 0xa438, 0xffe3, 0xa438, 0x8fa4, 0xa438, 0x1b31, + 0xa438, 0x9f3a, 0xa438, 0x0d48, 0xa438, 0xe38f, 0xa438, 0xa51b, + 0xa438, 0x319f, 0xa438, 0x31bf, 0xa438, 0x87fa, 0xa438, 0x0278, + 0xa438, 0x38e3, 0xa438, 0x8fa6, 0xa438, 0x1b31, 0xa438, 0x9f24, + 0xa438, 0x0d48, 0xa438, 0xe38f, 0xa438, 0xa71b, 0xa438, 0x319f, + 0xa438, 0x1bbf, 0xa438, 0x87fd, 0xa438, 0x0278, 0xa438, 0x38e3, + 0xa438, 0x8fa8, 0xa438, 0x1b31, 0xa438, 0x9f0e, 0xa438, 0xbf88, + 0xa438, 0x0302, 0xa438, 0x77f6, 0xa438, 0xbf88, 0xa438, 0x0902, + 0xa438, 0x77f6, 0xa438, 0xae00, 0xa438, 0xffef, 0xa438, 0x97fd, + 0xa438, 0xfc04, 0xa438, 0xf8ef, 0xa438, 0x79fb, 0xa438, 0xe080, + 0xa438, 0x18ad, 0xa438, 0x261c, 0xa438, 0xee8f, 0xa438, 0x9c00, + 0xa438, 0xbf88, 0xa438, 0x0002, 0xa438, 0x77ed, 0xa438, 0xbf88, + 0xa438, 0x0602, 0xa438, 0x77ed, 0xa438, 0xbf88, 0xa438, 0x0302, + 0xa438, 0x77ed, 0xa438, 0xbf88, 0xa438, 0x0902, 0xa438, 0x77ed, + 0xa438, 0xffef, 0xa438, 0x97fc, 0xa438, 0x04f8, 0xa438, 0xe080, + 0xa438, 0x40f6, 0xa438, 0x25e4, 0xa438, 0x8040, 0xa438, 0xfc04, + 0xa438, 0xf8e0, 0xa438, 0x804c, 0xa438, 0xf625, 0xa438, 0xe480, + 0xa438, 0x4cfc, 0xa438, 0x0455, 0xa438, 0xa4ba, 0xa438, 0xf0a6, + 0xa438, 0x4af0, 0xa438, 0xa64c, 0xa438, 0xf0a6, 0xa438, 0x4e66, + 0xa438, 0xa4b6, 0xa438, 0x55a4, 0xa438, 0xb600, 0xa438, 0xac56, + 0xa438, 0x11ac, 0xa438, 0x56ee, 0xa438, 0x804c, 0xa438, 0x3aaf, + 0xa438, 0x0627, 0xa438, 0xbf88, 0xa438, 0x4802, 0xa438, 0x77ed, + 0xa438, 0xd203, 0xa438, 0xe083, 0xa438, 0x8a0d, 0xa438, 0x01f6, + 0xa438, 0x271b, 0xa438, 0x03aa, 0xa438, 0x0182, 0xa438, 0xe083, + 0xa438, 0x890d, 0xa438, 0x01f6, 0xa438, 0x271b, 0xa438, 0x03aa, + 0xa438, 0x0182, 0xa438, 0xe083, 0xa438, 0x880d, 0xa438, 0x01f6, + 0xa438, 0x271b, 0xa438, 0x03aa, 0xa438, 0x0782, 0xa438, 0xbf88, + 0xa438, 0x4802, 0xa438, 0x77f6, 0xa438, 0xaf16, 0xa438, 0x1500, + 0xa438, 0xa86a, 0xa436, 0xb818, 0xa438, 0x1D84, 0xa436, 0xb81a, + 0xa438, 0x1060, 0xa436, 0xb81c, 0xa438, 0x0623, 0xa436, 0xb81e, + 0xa438, 0x15ef, 0xa436, 0xb850, 0xa438, 0xffff, 0xa436, 0xb852, + 0xa438, 0xffff, 0xa436, 0xb878, 0xa438, 0xffff, 0xa436, 0xb884, + 0xa438, 0xffff, 0xa436, 0xb832, 0xa438, 0x000f, 0xa436, 0x0000, + 0xa438, 0x0000, 0xB82E, 0x0000, 0xa436, 0x8023, 0xa438, 0x0000, + 0xB820, 0x0000, 0xFFFF, 0xFFFF +}; + +static void +rtl8126_real_set_phy_mcu_8126a_1_1(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_1_1, + ARRAY_SIZE(phy_mcu_ram_code_8126a_1_1)); +} + +static void +rtl8126_real_set_phy_mcu_8126a_1_2(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_1_2, + ARRAY_SIZE(phy_mcu_ram_code_8126a_1_2)); +} + +static void +rtl8126_real_set_phy_mcu_8126a_1_3(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_1_3, + ARRAY_SIZE(phy_mcu_ram_code_8126a_1_3)); +} + +static void +rtl8126_set_phy_mcu_8126a_1(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_1_1(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_1_2(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_1_3(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8126_real_set_phy_mcu_8126a_2_1(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_2_1, + ARRAY_SIZE(phy_mcu_ram_code_8126a_2_1)); +} + +static void +rtl8126_real_set_phy_mcu_8126a_2_3(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_2_3, + ARRAY_SIZE(phy_mcu_ram_code_8126a_2_3)); +} + +static void +rtl8126_set_phy_mcu_8126a_2(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_2_1(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_2_3(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8126_real_set_phy_mcu_8126a_3_1(struct net_device *dev) +{ + rtl8126_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8126a_3_1, + ARRAY_SIZE(phy_mcu_ram_code_8126a_3_1)); +} + +static void +rtl8126_set_phy_mcu_8126a_3(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_real_set_phy_mcu_8126a_3_1(dev); + + rtl8126_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8126_init_hw_phy_mcu(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u8 require_disable_phy_disable_mode = FALSE; + + if (tp->NotWrRamCodeToMicroP == TRUE) + return; + + if (rtl8126_check_hw_phy_mcu_code_ver(dev)) + return; + + if (HW_SUPPORT_CHECK_PHY_DISABLE_MODE(tp) && rtl8126_is_in_phy_disable_mode(dev)) + require_disable_phy_disable_mode = TRUE; + + if (require_disable_phy_disable_mode) + rtl8126_disable_phy_disable_mode(dev); + + switch (tp->mcfg) { + case CFG_METHOD_1: + rtl8126_set_phy_mcu_8126a_1(dev); + break; + case CFG_METHOD_2: + rtl8126_set_phy_mcu_8126a_2(dev); + break; + case CFG_METHOD_3: + rtl8126_set_phy_mcu_8126a_3(dev); + break; + } + + if (require_disable_phy_disable_mode) + rtl8126_enable_phy_disable_mode(dev); + + rtl8126_write_hw_phy_mcu_code_ver(dev); + + rtl8126_mdio_write(tp,0x1F, 0x0000); + + tp->HwHasWrRamCodeToMicroP = TRUE; +} +#endif + +static void +rtl8126_enable_phy_aldps(struct rtl8126_private *tp) +{ + //enable aldps + //GPHY OCP 0xA430 bit[2] = 0x1 (en_aldps) + rtl8126_set_eth_phy_ocp_bit(tp, 0xA430, BIT_2); +} + +static void +rtl8126_hw_phy_config_8126a_1(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_eth_phy_ocp_bit(tp, 0xA442, BIT_11); + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8126_enable_phy_aldps(tp); + } + } +} + +static void +rtl8126_hw_phy_config_8126a_2(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_eth_phy_ocp_bit(tp, 0xA442, BIT_11); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80BF); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0xED00); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80CD); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x1000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80D1); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0xC800); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80D4); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0xC800); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80E1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x10CC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x80E5); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x4F0C); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8387); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x4700); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA80C, + BIT_7 | BIT_6, + BIT_7); + + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAC90, BIT_4); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAD2C, BIT_15); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8321); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1100); + rtl8126_set_eth_phy_ocp_bit(tp, 0xACF8, (BIT_3 | BIT_2)); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8183); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x5900); + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD94, BIT_5); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA654, BIT_11); + rtl8126_set_eth_phy_ocp_bit(tp, 0xB648, BIT_14); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x839E); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x2F00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83F2); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0800); + rtl8126_set_eth_phy_ocp_bit(tp, 0xADA0, BIT_1); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80F3); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x9900); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8126); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0xC100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x893A); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x8080); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8647); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0xE600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x862C); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1200); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x864A); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0xE600); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80A0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0xBCBC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x805E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0xBCBC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8056); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x3077); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8058); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x5A00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8098); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x3077); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x809A); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x5A00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8052); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x3733); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8094); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x3733); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x807F); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C75); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x803D); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C75); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8036); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8078); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8031); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3300); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8073); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3300); + + + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xAE06, + 0xFC00, + 0x7C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x89D1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0004); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FBD); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x0A00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FBE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0D09); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x89CD); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0F0F); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x89CF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0F0F); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83A4); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83A6); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6601); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83C0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83C2); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6601); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8414); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8416); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6601); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83F8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x83FA); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6601); + + + rtl8126_set_phy_mcu_patch_request(tp); + + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xBD96, + 0x1F00, + 0x1000); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xBF1C, + 0x0007, + 0x0007); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xBFBE, BIT_15); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xBF40, + 0x0380, + 0x0280); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xBF90, + BIT_7, + (BIT_6 | BIT_5)); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xBF90, + BIT_4, + BIT_3 | BIT_2); + + rtl8126_clear_phy_mcu_patch_request(tp); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x843B); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x2000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x843D); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x2000); + + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xB516, 0x7F); + + + rtl8126_clear_eth_phy_ocp_bit(tp, 0xBF80, (BIT_5 | BIT_4)); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8188); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0044); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00A8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00D6); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00EC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00F6); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00BC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0058); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x002A); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8015); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0800); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFD); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFF); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x7F00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFB); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FE9); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0002); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FEF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x00A5); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FF1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0106); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FE1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0102); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FE3); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0400); + + + rtl8126_set_eth_phy_ocp_bit(tp, 0xA654, BIT_11); + rtl8126_clear_eth_phy_ocp_bit(tp, 0XA65A, (BIT_1 | BIT_0)); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xAC3A, 0x5851); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0XAC3C, + BIT_15 | BIT_14 | BIT_12, + BIT_13); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xAC42, + BIT_9, + BIT_8 | BIT_7 | BIT_6); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAC3E, BIT_15 | BIT_14 | BIT_13); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAC42, BIT_5 | BIT_4 | BIT_3); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xAC42, + BIT_1, + BIT_2 | BIT_0); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xAC1A, 0x00DB); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xADE4, 0x01B5); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAD9C, BIT_11 | BIT_10); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814B); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814D); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814F); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0B00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8142); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8144); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8150); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8118); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0700); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811A); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0700); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811C); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0500); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x810F); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8111); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811D); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + + rtl8126_set_eth_phy_ocp_bit(tp, 0xAC36, BIT_12); + rtl8126_clear_eth_phy_ocp_bit(tp, 0xAD1C, BIT_8); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xADE8, + 0xFFC0, + 0x1400); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x864B); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x9D00); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8F97); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x003F); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x3F02); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x023C); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x3B0A); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x1C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + + + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD9C, BIT_5); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8122); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0C00); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x82C8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0009); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000B); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0021); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F7); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03B8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0049); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0049); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03B8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F7); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0021); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000B); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0009); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80EF); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x82A0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0006); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x001A); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03D8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0023); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0054); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0322); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x00DD); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03AB); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03DC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0027); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E5); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F9); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0012); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0001); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F1); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8018); + rtl8126_set_eth_phy_ocp_bit(tp, 0xA438, BIT_13); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FE4); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0000); + + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB54C, + 0xFFC0, + 0x3700); + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8126_enable_phy_aldps(tp); + } + } +} + +static void +rtl8126_hw_phy_config_8126a_3(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_set_eth_phy_ocp_bit(tp, 0xA442, BIT_11); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8183); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x5900); + rtl8126_set_eth_phy_ocp_bit(tp, 0xA654, BIT_11); + rtl8126_set_eth_phy_ocp_bit(tp, 0xB648, BIT_14); + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD2C, BIT_15); + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD94, BIT_5); + rtl8126_set_eth_phy_ocp_bit(tp, 0xADA0, BIT_1); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xAE06, + BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10, + BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8647); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0xE600); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8036); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8078); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x3000); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x89E9); + rtl8126_set_eth_phy_ocp_bit(tp, 0xB87E, 0xFF00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFD); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFE); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0200); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFF); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0400); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8018); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x7700); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8F9C); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0005); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x00ED); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0502); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0B00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0xD401); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FA8); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xA438, + 0xFF00, + 0x2900); + + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814B); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814D); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814F); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0B00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8142); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8144); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8150); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8118); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0700); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811A); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0700); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811C); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0500); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x810F); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8111); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x811D); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0100); + + + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD1C, BIT_8); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xADE8, + BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6, + BIT_12 | BIT_10); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x864B); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x9D00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x862C); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x1200); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA436, 0x8566); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x003F); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x3F02); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x023C); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x3B0A); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x1C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + + + rtl8126_set_eth_phy_ocp_bit(tp, 0xAD9C, BIT_5); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8122); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x82C8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0009); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000B); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0021); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F7); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03B8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0049); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0049); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03B8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F7); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0021); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000B); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0009); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FF); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80EF); + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB87E, + 0xFF00, + 0x0C00); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87C, 0x82A0); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03FE); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03ED); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0006); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x001A); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F1); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03D8); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0023); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0054); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0322); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x00DD); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03AB); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03DC); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0027); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x000E); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03E5); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F9); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0012); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0001); + rtl8126_mdio_direct_write_phy_ocp(tp, 0xB87E, 0x03F1); + + + rtl8126_set_eth_phy_ocp_bit(tp, 0xA430, BIT_1 | BIT_0); + + + rtl8126_clear_and_set_eth_phy_ocp_bit(tp, + 0xB54C, + 0xFFC0, + 0x3700); + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8126_enable_phy_aldps(tp); + } + } +} + +static void +rtl8126_hw_phy_config(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (tp->resume_not_chg_speed) + return; + + tp->phy_reset_enable(dev); + + if (HW_DASH_SUPPORT_TYPE_3(tp) && tp->HwPkgDet == 0x06) + return; + +#ifndef ENABLE_USE_FIRMWARE_FILE + if (!tp->rtl_fw) + rtl8126_init_hw_phy_mcu(dev); +#endif + + switch (tp->mcfg) { + case CFG_METHOD_1: + rtl8126_hw_phy_config_8126a_1(dev); + break; + case CFG_METHOD_2: + rtl8126_hw_phy_config_8126a_2(dev); + break; + case CFG_METHOD_3: + rtl8126_hw_phy_config_8126a_3(dev); + break; + } + + //legacy force mode(Chap 22) + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + default: + rtl8126_clear_eth_phy_ocp_bit(tp, 0xA5B4, BIT_15); + break; + } + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + if (tp->eee.eee_enabled) + rtl8126_enable_eee(tp); + else + rtl8126_disable_eee(tp); + } +} + +static void +rtl8126_up(struct net_device *dev) +{ + rtl8126_hw_init(dev); + rtl8126_hw_reset(dev); + rtl8126_powerup_pll(dev); + rtl8126_hw_ephy_config(dev); + rtl8126_hw_phy_config(dev); + rtl8126_hw_config(dev); +} + +/* +static inline void rtl8126_delete_esd_timer(struct net_device *dev, struct timer_list *timer) +{ + del_timer_sync(timer); +} + +static inline void rtl8126_request_esd_timer(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->esd_timer; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + setup_timer(timer, rtl8126_esd_timer, (unsigned long)dev); +#else + timer_setup(timer, rtl8126_esd_timer, 0); +#endif + mod_timer(timer, jiffies + RTL8126_ESD_TIMEOUT); +} +*/ + +/* +static inline void rtl8126_delete_link_timer(struct net_device *dev, struct timer_list *timer) +{ + del_timer_sync(timer); +} + +static inline void rtl8126_request_link_timer(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->link_timer; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + setup_timer(timer, rtl8126_link_timer, (unsigned long)dev); +#else + timer_setup(timer, rtl8126_link_timer, 0); +#endif + mod_timer(timer, jiffies + RTL8126_LINK_TIMEOUT); +} +*/ + +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void +rtl8126_netpoll(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + for (i = 0; i < tp->irq_nvecs; i++) { + struct r8126_irq *irq = &tp->irq_tbl[i]; + struct r8126_napi *r8126napi = &tp->r8126napi[i]; + + disable_irq(irq->vector); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) + irq->handler(irq->vector, r8126napi); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + irq->handler(irq->vector, r8126napi, NULL); +#else + irq->handler(irq->vector, r8126napi); +#endif + + enable_irq(irq->vector); + } +} +#endif //CONFIG_NET_POLL_CONTROLLER + +static void +rtl8126_setup_interrupt_mask(struct rtl8126_private *tp) +{ + int i; + + if (tp->HwCurrIsrVer == 5) { + tp->intr_mask = ISRIMR_V5_LINKCHG | ISRIMR_V5_TOK_Q0; + if (tp->num_tx_rings > 1) + tp->intr_mask |= ISRIMR_V5_TOK_Q1; + for (i = 0; i < tp->num_rx_rings; i++) + tp->intr_mask |= ISRIMR_V5_ROK_Q0 << i; + } else if (tp->HwCurrIsrVer == 4) { + tp->intr_mask = ISRIMR_V4_LINKCHG; + for (i = 0; i < tp->num_rx_rings; i++) + tp->intr_mask |= ISRIMR_V4_ROK_Q0 << i; + } else if (tp->HwCurrIsrVer == 3) { + tp->intr_mask = ISRIMR_V2_LINKCHG; + for (i = 0; i < max(tp->num_tx_rings, tp->num_rx_rings); i++) + tp->intr_mask |= ISRIMR_V2_ROK_Q0 << i; + } else if (tp->HwCurrIsrVer == 2) { + tp->intr_mask = ISRIMR_V2_LINKCHG | ISRIMR_TOK_Q0; + if (tp->num_tx_rings > 1) + tp->intr_mask |= ISRIMR_TOK_Q1; + + for (i = 0; i < tp->num_rx_rings; i++) + tp->intr_mask |= ISRIMR_V2_ROK_Q0 << i; + } else { + tp->intr_mask = LinkChg | RxDescUnavail | TxOK | RxOK | SWInt; + tp->timer_intr_mask = LinkChg | PCSTimeout; + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + tp->timer_intr_mask |= (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + tp->intr_mask |= (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + } + } +#endif + } +} + +static void +rtl8126_setup_mqs_reg(struct rtl8126_private *tp) +{ + u16 hw_clo_ptr0_reg, sw_tail_ptr0_reg; + u16 reg_len; + int i; + + //tx + tp->tx_ring[0].tdsar_reg = TxDescStartAddrLow; + for (i = 1; i < R8126_MAX_TX_QUEUES; i++) { + tp->tx_ring[i].tdsar_reg = (u16)(TNPDS_Q1_LOW_8125 + (i - 1) * 8); + } + + switch (tp->HwSuppTxNoCloseVer) { + case 4: + case 5: + hw_clo_ptr0_reg = HW_CLO_PTR0_8126; + sw_tail_ptr0_reg = SW_TAIL_PTR0_8126; + reg_len = 4; + break; + case 6: + hw_clo_ptr0_reg = HW_CLO_PTR0_8125BP; + sw_tail_ptr0_reg = SW_TAIL_PTR0_8125BP; + reg_len = 8; + break; + default: + hw_clo_ptr0_reg = HW_CLO_PTR0_8125; + sw_tail_ptr0_reg = SW_TAIL_PTR0_8125; + reg_len = 4; + break; + } + + for (i = 0; i < R8126_MAX_TX_QUEUES; i++) { + tp->tx_ring[i].hw_clo_ptr_reg = (u16)(hw_clo_ptr0_reg + i * reg_len); + tp->tx_ring[i].sw_tail_ptr_reg = (u16)(sw_tail_ptr0_reg + i * reg_len); + } + + //rx + tp->rx_ring[0].rdsar_reg = RxDescAddrLow; + for (i = 1; i < R8126_MAX_RX_QUEUES; i++) { + tp->rx_ring[i].rdsar_reg = (u16)(RDSAR_Q1_LOW_8125 + (i - 1) * 8); + } + + tp->isr_reg[0] = ISR0_8125; + for (i = 1; i < R8126_MAX_QUEUES; i++) { + tp->isr_reg[i] = (u16)(ISR1_8125 + (i - 1) * 4); + } + + tp->imr_reg[0] = IMR0_8125; + for (i = 1; i < R8126_MAX_QUEUES; i++) { + tp->imr_reg[i] = (u16)(IMR1_8125 + (i - 1) * 4); + } +} + +static void +rtl8126_init_software_variable(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + +#ifdef ENABLE_LIB_SUPPORT + tp->ring_lib_enabled = 1; +#endif + + switch (tp->mcfg) { + default: + tp->HwSuppDashVer = 0; + break; + } + tp->AllowAccessDashOcp = rtl8126_is_allow_access_dash_ocp(tp); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwPkgDet = rtl8126_mac_ocp_read(tp, 0xDC00); + tp->HwPkgDet = (tp->HwPkgDet >> 3) & 0x07; + break; + } + + if (HW_DASH_SUPPORT_TYPE_3(tp) && tp->HwPkgDet == 0x06) + eee_enable = 0; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppNowIsOobVer = 1; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwPcieSNOffset = 0x174; + break; + } + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8126_get_realwow_hw_version(dev); +#endif //ENABLE_REALWOW_SUPPORT + + if (HW_DASH_SUPPORT_DASH(tp) && rtl8126_check_dash(tp)) + tp->DASH = 1; + else + tp->DASH = 0; + + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + u64 CmacMemPhysAddress; + void __iomem *cmac_ioaddr = NULL; + + //map CMAC IO space + CmacMemPhysAddress = rtl8126_csi_other_fun_read(tp, 0, 0x18); + if (!(CmacMemPhysAddress & BIT_0)) { + if (CmacMemPhysAddress & BIT_2) + CmacMemPhysAddress |= (u64)rtl8126_csi_other_fun_read(tp, 0, 0x1C) << 32; + + CmacMemPhysAddress &= 0xFFFFFFF0; + /* ioremap MMIO region */ + cmac_ioaddr = ioremap(CmacMemPhysAddress, R8126_REGS_SIZE); + } + + if (cmac_ioaddr == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "cannot remap CMAC MMIO, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + } + + if (cmac_ioaddr == NULL) { + tp->DASH = 0; + } else { + tp->mapped_cmac_ioaddr = cmac_ioaddr; + } + } + + eee_enable = 0; + } + + if (HW_DASH_SUPPORT_TYPE_3(tp)) + tp->cmac_ioaddr = tp->mapped_cmac_ioaddr; + + if (aspm) { + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->org_pci_offset_99 = rtl8126_csi_fun0_read_byte(tp, 0x99); + tp->org_pci_offset_99 &= ~(BIT_5|BIT_6); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->org_pci_offset_180 = rtl8126_csi_fun0_read_byte(tp, 0x22c); + break; + } + } + + pci_read_config_byte(pdev, 0x80, &tp->org_pci_offset_80); + pci_read_config_byte(pdev, 0x81, &tp->org_pci_offset_81); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + default: + tp->use_timer_interrupt = TRUE; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + default: + tp->HwSuppMaxPhyLinkSpeed = 5000; + break; + } + + if (timer_count == 0 || tp->mcfg == CFG_METHOD_DEFAULT) + tp->use_timer_interrupt = FALSE; + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->ShortPacketSwChecksum = TRUE; + tp->UseSwPaddingShortPkt = TRUE; + break; + default: + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_V3; + break; + default: + tp->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_NOT_SUPPORT; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppLinkChgWakeUpVer = 3; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppD0SpeedUpVer = 1; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppCheckPhyDisableModeVer = 3; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + tp->HwSuppTxNoCloseVer = 4; + break; + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppTxNoCloseVer = 5; + break; + } + + switch (tp->HwSuppTxNoCloseVer) { + case 5: + case 6: + tp->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4; + break; + case 4: + tp->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3; + break; + case 3: + tp->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2; + break; + default: + tx_no_close_enable = 0; + break; + } + + if (tp->HwSuppTxNoCloseVer > 0 && tx_no_close_enable == 1) + tp->EnableTxNoClose = TRUE; + + switch (tp->mcfg) { + case CFG_METHOD_1: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_1; + break; + case CFG_METHOD_2: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_2; + break; + case CFG_METHOD_3: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_3; + break; + } + + if (tp->HwIcVerUnknown) { + tp->NotWrRamCodeToMicroP = TRUE; + tp->NotWrMcuPatchCode = TRUE; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppMacMcuVer = 2; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->MacMcuPageSize = RTL8126_MAC_MCU_PAGE_SIZE; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppNumTxQueues = 2; + tp->HwSuppNumRxQueues = 4; + break; + default: + tp->HwSuppNumTxQueues = 1; + tp->HwSuppNumRxQueues = 1; + break; + } + +#ifdef ENABLE_PTP_SUPPORT + if (tp->HwSuppPtpVer > 0) + tp->EnablePtp = 1; +#endif + + //init interrupt + switch (tp->mcfg) { + case CFG_METHOD_1: + tp->HwSuppIsrVer = 2; + break; + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppIsrVer = 3; + break; + default: + tp->HwSuppIsrVer = 1; + break; + } + + tp->HwCurrIsrVer = tp->HwSuppIsrVer; + if (tp->HwCurrIsrVer > 1) { + if (!(tp->features & RTL_FEATURE_MSIX) || + tp->irq_nvecs < tp->min_irq_nvecs) + tp->HwCurrIsrVer = 1; + } + + tp->num_tx_rings = 1; +#ifdef ENABLE_MULTIPLE_TX_QUEUE +#ifndef ENABLE_LIB_SUPPORT + tp->num_tx_rings = tp->HwSuppNumTxQueues; +#endif +#endif + if (tp->HwCurrIsrVer < 2 || + (tp->HwCurrIsrVer == 2 && tp->irq_nvecs < 19)) + tp->num_tx_rings = 1; + + //RSS + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppRssVer = 5; + tp->HwSuppIndirTblEntries = 128; + break; + } + + tp->num_rx_rings = 1; +#ifdef ENABLE_RSS_SUPPORT +#ifdef ENABLE_LIB_SUPPORT + if (tp->HwSuppRssVer > 0) + tp->EnableRss = 1; +#else + if (tp->HwSuppRssVer > 0 && tp->HwCurrIsrVer > 1) { + u8 rss_queue_num = netif_get_num_default_rss_queues(); + tp->num_rx_rings = (tp->HwSuppNumRxQueues > rss_queue_num)? + rss_queue_num : tp->HwSuppNumRxQueues; + + if (!(tp->num_rx_rings >= 2 && tp->irq_nvecs >= tp->num_rx_rings)) + tp->num_rx_rings = 1; + + if (tp->num_rx_rings >= 2) + tp->EnableRss = 1; + } +#endif +#endif + + //interrupt mask + rtl8126_setup_interrupt_mask(tp); + + rtl8126_setup_mqs_reg(tp); + + rtl8126_set_ring_size(tp, NUM_RX_DESC, NUM_TX_DESC); + + switch (tp->mcfg) { + case CFG_METHOD_1: + tp->HwSuppIntMitiVer = 4; + break; + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppIntMitiVer = 5; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppTcamVer = 2; + + tp->TcamNotValidReg = TCAM_NOTVALID_ADDR_V2; + tp->TcamValidReg = TCAM_VALID_ADDR_V2; + tp->TcamMaAddrcOffset = TCAM_MAC_ADDR_V2; + tp->TcamVlanTagOffset = TCAM_VLAN_TAG_V2; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->HwSuppExtendTallyCounterVer = 1; + break; + } + + timer_count_v2 = (timer_count / 0x100); + + tp->InitRxDescType = RX_DESC_RING_TYPE_1; + if (tp->EnableRss || tp->EnablePtp) + tp->InitRxDescType = RX_DESC_RING_TYPE_3; + + tp->RxDescLength = RX_DESC_LEN_TYPE_1; + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + tp->RxDescLength = RX_DESC_LEN_TYPE_3; + + tp->rtl8126_rx_config = rtl_chip_info[tp->chipset].RCR_Cfg; + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + tp->rtl8126_rx_config |= EnableRxDescV3; + + tp->NicCustLedValue = RTL_R16(tp, CustomLED); + + tp->wol_opts = rtl8126_get_hw_wol(tp); + tp->wol_enabled = (tp->wol_opts) ? WOL_ENABLED : WOL_DISABLED; + + rtl8126_set_link_option(tp, autoneg_mode, speed_mode, duplex_mode, + rtl8126_fc_full); + + tp->max_jumbo_frame_size = rtl_chip_info[tp->chipset].jumbo_frame_sz; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + /* MTU range: 60 - hw-specific max */ + dev->min_mtu = ETH_MIN_MTU; + dev->max_mtu = tp->max_jumbo_frame_size; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + + if (tp->mcfg != CFG_METHOD_DEFAULT) { + struct ethtool_eee *eee = &tp->eee; + + eee->eee_enabled = eee_enable; + eee->supported = SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full; + eee->advertised = mmd_eee_adv_to_ethtool_adv_t(MDIO_EEE_1000T | MDIO_EEE_100TX); + switch (tp->mcfg) { + default: + if (HW_SUPP_PHY_LINK_SPEED_2500M(tp)) { + eee->supported |= SUPPORTED_2500baseX_Full; + eee->advertised |= SUPPORTED_2500baseX_Full; + } + break; + } + eee->tx_lpi_enabled = eee_enable; + eee->tx_lpi_timer = dev->mtu + ETH_HLEN + 0x20; + } + + tp->ptp_master_mode = enable_ptp_master_mode; + +#ifdef ENABLE_RSS_SUPPORT + if (tp->EnableRss) + rtl8126_init_rss(tp); +#endif +} + +static void +rtl8126_release_board(struct pci_dev *pdev, + struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + + rtl8126_rar_set(tp, tp->org_mac_addr); + tp->wol_enabled = WOL_DISABLED; + + if (!tp->DASH) + rtl8126_phy_power_down(dev); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + FreeAllocatedDashShareMemory(dev); +#endif + + if (tp->mapped_cmac_ioaddr != NULL) + iounmap(tp->mapped_cmac_ioaddr); + + iounmap(ioaddr); + pci_release_regions(pdev); + pci_clear_mwi(pdev); + pci_disable_device(pdev); + free_netdev(dev); +} + +static void +rtl8126_hw_address_set(struct net_device *dev, u8 mac_addr[MAC_ADDR_LEN]) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + eth_hw_addr_set(dev, mac_addr); +#else + memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +} + +static int +rtl8126_get_mac_address(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + u8 mac_addr[MAC_ADDR_LEN]; + + for (i = 0; i < MAC_ADDR_LEN; i++) + mac_addr[i] = RTL_R8(tp, MAC0 + i); + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + *(u32*)&mac_addr[0] = RTL_R32(tp, BACKUP_ADDR0_8125); + *(u16*)&mac_addr[4] = RTL_R16(tp, BACKUP_ADDR1_8125); + break; + default: + break; + }; + + if (!is_valid_ether_addr(mac_addr)) { + netif_err(tp, probe, dev, "Invalid ether addr %pM\n", + mac_addr); + eth_random_addr(mac_addr); + dev->addr_assign_type = NET_ADDR_RANDOM; + netif_info(tp, probe, dev, "Random ether addr %pM\n", + mac_addr); + tp->random_mac = 1; + } + + rtl8126_hw_address_set(dev, mac_addr); + rtl8126_rar_set(tp, mac_addr); + + /* keep the original MAC address */ + memcpy(tp->org_mac_addr, dev->dev_addr, MAC_ADDR_LEN); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + memcpy(dev->perm_addr, dev->dev_addr, MAC_ADDR_LEN); +#endif + return 0; +} + +/** + * rtl8126_set_mac_address - Change the Ethernet Address of the NIC + * @dev: network interface device structure + * @p: pointer to an address structure + * + * Return 0 on success, negative on failure + **/ +static int +rtl8126_set_mac_address(struct net_device *dev, + void *p) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + rtl8126_hw_address_set(dev, addr->sa_data); + + rtl8126_rar_set(tp, dev->dev_addr); + + return 0; +} + +/****************************************************************************** + * rtl8126_rar_set - Puts an ethernet address into a receive address register. + * + * tp - The private data structure for driver + * addr - Address to put into receive address register + *****************************************************************************/ +void +rtl8126_rar_set(struct rtl8126_private *tp, + const u8 *addr) +{ + uint32_t rar_low = 0; + uint32_t rar_high = 0; + + rar_low = ((uint32_t) addr[0] | + ((uint32_t) addr[1] << 8) | + ((uint32_t) addr[2] << 16) | + ((uint32_t) addr[3] << 24)); + + rar_high = ((uint32_t) addr[4] | + ((uint32_t) addr[5] << 8)); + + rtl8126_enable_cfg9346_write(tp); + RTL_W32(tp, MAC0, rar_low); + RTL_W32(tp, MAC4, rar_high); + + rtl8126_disable_cfg9346_write(tp); +} + +#ifdef ETHTOOL_OPS_COMPAT +static int ethtool_get_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + int err; + + if (!ethtool_ops->get_settings) + return -EOPNOTSUPP; + + err = ethtool_ops->get_settings(dev, &cmd); + if (err < 0) + return err; + + if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; +} + +static int ethtool_set_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd; + + if (!ethtool_ops->set_settings) + return -EOPNOTSUPP; + + if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + return ethtool_ops->set_settings(dev, &cmd); +} + +static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) +{ + struct ethtool_drvinfo info; + struct ethtool_ops *ops = ethtool_ops; + + if (!ops->get_drvinfo) + return -EOPNOTSUPP; + + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + ops->get_drvinfo(dev, &info); + + if (ops->self_test_count) + info.testinfo_len = ops->self_test_count(dev); + if (ops->get_stats_count) + info.n_stats = ops->get_stats_count(dev); + if (ops->get_regs_len) + info.regdump_len = ops->get_regs_len(dev); + if (ops->get_eeprom_len) + info.eedump_len = ops->get_eeprom_len(dev); + + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int ethtool_get_regs(struct net_device *dev, char *useraddr) +{ + struct ethtool_regs regs; + struct ethtool_ops *ops = ethtool_ops; + void *regbuf; + int reglen, ret; + + if (!ops->get_regs || !ops->get_regs_len) + return -EOPNOTSUPP; + + if (copy_from_user(®s, useraddr, sizeof(regs))) + return -EFAULT; + + reglen = ops->get_regs_len(dev); + if (regs.len > reglen) + regs.len = reglen; + + regbuf = kmalloc(reglen, GFP_USER); + if (!regbuf) + return -ENOMEM; + + ops->get_regs(dev, ®s, regbuf); + + ret = -EFAULT; + if (copy_to_user(useraddr, ®s, sizeof(regs))) + goto out; + useraddr += offsetof(struct ethtool_regs, data); + if (copy_to_user(useraddr, regbuf, reglen)) + goto out; + ret = 0; + +out: + kfree(regbuf); + return ret; +} + +static int ethtool_get_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; + + if (!ethtool_ops->get_wol) + return -EOPNOTSUPP; + + ethtool_ops->get_wol(dev, &wol); + + if (copy_to_user(useraddr, &wol, sizeof(wol))) + return -EFAULT; + return 0; +} + +static int ethtool_set_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol; + + if (!ethtool_ops->set_wol) + return -EOPNOTSUPP; + + if (copy_from_user(&wol, useraddr, sizeof(wol))) + return -EFAULT; + + return ethtool_ops->set_wol(dev, &wol); +} + +static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + + if (!ethtool_ops->get_msglevel) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_msglevel(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_msglevel) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + ethtool_ops->set_msglevel(dev, edata.data); + return 0; +} + +static int ethtool_nway_reset(struct net_device *dev) +{ + if (!ethtool_ops->nway_reset) + return -EOPNOTSUPP; + + return ethtool_ops->nway_reset(dev); +} + +static int ethtool_get_link(struct net_device *dev, void *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + + if (!ethtool_ops->get_link) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_link(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->get_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + /* Check for wrap and zero */ + if (eeprom.offset + eeprom.len <= eeprom.offset) + return -EINVAL; + + /* Check for exceeding total eeprom len */ + if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) + return -EINVAL; + + data = kmalloc(eeprom.len, GFP_USER); + if (!data) + return -ENOMEM; + + ret = -EFAULT; + if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) + goto out; + + ret = ops->get_eeprom(dev, &eeprom, data); + if (ret) + goto out; + + ret = -EFAULT; + if (copy_to_user(useraddr, &eeprom, sizeof(eeprom))) + goto out; + if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->set_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + /* Check for wrap and zero */ + if (eeprom.offset + eeprom.len <= eeprom.offset) + return -EINVAL; + + /* Check for exceeding total eeprom len */ + if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) + return -EINVAL; + + data = kmalloc(eeprom.len, GFP_USER); + if (!data) + return -ENOMEM; + + ret = -EFAULT; + if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) + goto out; + + ret = ops->set_eeprom(dev, &eeprom, data); + if (ret) + goto out; + + if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) + ret = -EFAULT; + +out: + kfree(data); + return ret; +} + +static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; + + if (!ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + ethtool_ops->get_coalesce(dev, &coalesce); + + if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) + return -EFAULT; + return 0; +} + +static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce; + + if (!ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) + return -EFAULT; + + return ethtool_ops->set_coalesce(dev, &coalesce); +} + +static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; + + if (!ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + ethtool_ops->get_ringparam(dev, &ringparam); + + if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam; + + if (!ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) + return -EFAULT; + + return ethtool_ops->set_ringparam(dev, &ringparam); +} + +static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + + if (!ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + ethtool_ops->get_pauseparam(dev, &pauseparam); + + if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam; + + if (!ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) + return -EFAULT; + + return ethtool_ops->set_pauseparam(dev, &pauseparam); +} + +static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + + if (!ethtool_ops->get_rx_csum) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_rx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_rx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + ethtool_ops->set_rx_csum(dev, edata.data); + return 0; +} + +static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + + if (!ethtool_ops->get_tx_csum) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_tx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_tx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_tx_csum(dev, edata.data); +} + +static int ethtool_get_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GSG }; + + if (!ethtool_ops->get_sg) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_sg(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_sg) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_sg(dev, edata.data); +} + +static int ethtool_get_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTSO }; + + if (!ethtool_ops->get_tso) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_tso(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_tso) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_tso(dev, edata.data); +} + +static int ethtool_self_test(struct net_device *dev, char *useraddr) +{ + struct ethtool_test test; + struct ethtool_ops *ops = ethtool_ops; + u64 *data; + int ret; + + if (!ops->self_test || !ops->self_test_count) + return -EOPNOTSUPP; + + if (copy_from_user(&test, useraddr, sizeof(test))) + return -EFAULT; + + test.len = ops->self_test_count(dev); + data = kmalloc(test.len * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->self_test(dev, &test, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &test, sizeof(test))) + goto out; + useraddr += sizeof(test); + if (copy_to_user(useraddr, data, test.len * sizeof(u64))) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_get_strings(struct net_device *dev, void *useraddr) +{ + struct ethtool_gstrings gstrings; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->get_strings) + return -EOPNOTSUPP; + + if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) + return -EFAULT; + + switch (gstrings.string_set) { + case ETH_SS_TEST: + if (!ops->self_test_count) + return -EOPNOTSUPP; + gstrings.len = ops->self_test_count(dev); + break; + case ETH_SS_STATS: + if (!ops->get_stats_count) + return -EOPNOTSUPP; + gstrings.len = ops->get_stats_count(dev); + break; + default: + return -EINVAL; + } + + data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_strings(dev, gstrings.string_set, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) + goto out; + useraddr += sizeof(gstrings); + if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_phys_id(struct net_device *dev, void *useraddr) +{ + struct ethtool_value id; + + if (!ethtool_ops->phys_id) + return -EOPNOTSUPP; + + if (copy_from_user(&id, useraddr, sizeof(id))) + return -EFAULT; + + return ethtool_ops->phys_id(dev, id.data); +} + +static int ethtool_get_stats(struct net_device *dev, void *useraddr) +{ + struct ethtool_stats stats; + struct ethtool_ops *ops = ethtool_ops; + u64 *data; + int ret; + + if (!ops->get_ethtool_stats || !ops->get_stats_count) + return -EOPNOTSUPP; + + if (copy_from_user(&stats, useraddr, sizeof(stats))) + return -EFAULT; + + stats.n_stats = ops->get_stats_count(dev); + data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_ethtool_stats(dev, &stats, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &stats, sizeof(stats))) + goto out; + useraddr += sizeof(stats); + if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_ioctl(struct ifreq *ifr) +{ + struct net_device *dev = __dev_get_by_name(ifr->ifr_name); + void *useraddr = (void *) ifr->ifr_data; + u32 ethcmd; + + /* + * XXX: This can be pushed down into the ethtool_* handlers that + * need it. Keep existing behaviour for the moment. + */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!dev || !netif_device_present(dev)) + return -ENODEV; + + if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GSET: + return ethtool_get_settings(dev, useraddr); + case ETHTOOL_SSET: + return ethtool_set_settings(dev, useraddr); + case ETHTOOL_GDRVINFO: + return ethtool_get_drvinfo(dev, useraddr); + case ETHTOOL_GREGS: + return ethtool_get_regs(dev, useraddr); + case ETHTOOL_GWOL: + return ethtool_get_wol(dev, useraddr); + case ETHTOOL_SWOL: + return ethtool_set_wol(dev, useraddr); + case ETHTOOL_GMSGLVL: + return ethtool_get_msglevel(dev, useraddr); + case ETHTOOL_SMSGLVL: + return ethtool_set_msglevel(dev, useraddr); + case ETHTOOL_NWAY_RST: + return ethtool_nway_reset(dev); + case ETHTOOL_GLINK: + return ethtool_get_link(dev, useraddr); + case ETHTOOL_GEEPROM: + return ethtool_get_eeprom(dev, useraddr); + case ETHTOOL_SEEPROM: + return ethtool_set_eeprom(dev, useraddr); + case ETHTOOL_GCOALESCE: + return ethtool_get_coalesce(dev, useraddr); + case ETHTOOL_SCOALESCE: + return ethtool_set_coalesce(dev, useraddr); + case ETHTOOL_GRINGPARAM: + return ethtool_get_ringparam(dev, useraddr); + case ETHTOOL_SRINGPARAM: + return ethtool_set_ringparam(dev, useraddr); + case ETHTOOL_GPAUSEPARAM: + return ethtool_get_pauseparam(dev, useraddr); + case ETHTOOL_SPAUSEPARAM: + return ethtool_set_pauseparam(dev, useraddr); + case ETHTOOL_GRXCSUM: + return ethtool_get_rx_csum(dev, useraddr); + case ETHTOOL_SRXCSUM: + return ethtool_set_rx_csum(dev, useraddr); + case ETHTOOL_GTXCSUM: + return ethtool_get_tx_csum(dev, useraddr); + case ETHTOOL_STXCSUM: + return ethtool_set_tx_csum(dev, useraddr); + case ETHTOOL_GSG: + return ethtool_get_sg(dev, useraddr); + case ETHTOOL_SSG: + return ethtool_set_sg(dev, useraddr); + case ETHTOOL_GTSO: + return ethtool_get_tso(dev, useraddr); + case ETHTOOL_STSO: + return ethtool_set_tso(dev, useraddr); + case ETHTOOL_TEST: + return ethtool_self_test(dev, useraddr); + case ETHTOOL_GSTRINGS: + return ethtool_get_strings(dev, useraddr); + case ETHTOOL_PHYS_ID: + return ethtool_phys_id(dev, useraddr); + case ETHTOOL_GSTATS: + return ethtool_get_stats(dev, useraddr); + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} +#endif //ETHTOOL_OPS_COMPAT + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0) +static int rtl8126_siocdevprivate(struct net_device *dev, struct ifreq *ifr, + void __user *data, int cmd) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret = 0; + + switch (cmd) { +#ifdef ENABLE_DASH_SUPPORT + case SIOCDEVPRIVATE_RTLDASH: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8126_dash_ioctl(dev, ifr); + break; +#endif + +#ifdef ENABLE_REALWOW_SUPPORT + case SIOCDEVPRIVATE_RTLREALWOW: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + + ret = rtl8126_realwow_ioctl(dev, ifr); + break; +#endif + + case SIOCRTLTOOL: + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8126_tool_ioctl(tp, ifr); + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0) + +static int +rtl8126_do_ioctl(struct net_device *dev, + struct ifreq *ifr, + int cmd) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(ifr); + int ret = 0; + + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = 32; /* Internal PHY */ + break; + + case SIOCGMIIREG: + rtl8126_mdio_write(tp, 0x1F, 0x0000); + data->val_out = rtl8126_mdio_read(tp, data->reg_num); + break; + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + rtl8126_mdio_write(tp, 0x1F, 0x0000); + rtl8126_mdio_write(tp, data->reg_num, data->val_in); + break; + +#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + ret = ethtool_ioctl(ifr); + break; +#endif + +#ifdef ENABLE_PTP_SUPPORT + case SIOCSHWTSTAMP: + case SIOCGHWTSTAMP: + if (tp->EnablePtp) + ret = rtl8126_ptp_ioctl(dev, ifr, cmd); + else + ret = -EOPNOTSUPP; + break; +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) +#ifdef ENABLE_DASH_SUPPORT + case SIOCDEVPRIVATE_RTLDASH: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8126_dash_ioctl(dev, ifr); + break; +#endif + +#ifdef ENABLE_REALWOW_SUPPORT + case SIOCDEVPRIVATE_RTLREALWOW: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8126_realwow_ioctl(dev, ifr); + break; +#endif + + case SIOCRTLTOOL: + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8126_tool_ioctl(tp, ifr); + break; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static void +rtl8126_phy_power_up(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (rtl8126_is_in_phy_disable_mode(dev)) + return; + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + rtl8126_mdio_write(tp, MII_BMCR, BMCR_ANENABLE); + + //wait ups resume (phy state 3) + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_wait_phy_ups_resume(dev, 3); + break; + }; +} + +static void +rtl8126_phy_power_down(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + rtl8126_mdio_write(tp, 0x1F, 0x0000); + rtl8126_mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); +} + +static int __devinit +rtl8126_init_board(struct pci_dev *pdev, + struct net_device **dev_out, + void __iomem **ioaddr_out) +{ + void __iomem *ioaddr; + struct net_device *dev; + struct rtl8126_private *tp; + int rc = -ENOMEM, i, pm_cap; + + assert(ioaddr_out != NULL); + + /* dev zeroed in alloc_etherdev */ + dev = alloc_etherdev_mq(sizeof (*tp), R8126_MAX_QUEUES); + if (dev == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_drv(&debug)) + dev_err(&pdev->dev, "unable to alloc new ethernet\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out; + } + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + tp = netdev_priv(dev); + tp->dev = dev; + tp->pci_dev = pdev; + tp->msg_enable = netif_msg_init(debug.msg_enable, R8126_MSG_DEFAULT); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + if (!aspm) + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); +#endif + + /* enable device (incl. PCI PM wakeup and hotplug setup) */ + rc = pci_enable_device(pdev); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "enable failure\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_free_dev; + } + + if (pci_set_mwi(pdev) < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_drv(&debug)) + dev_info(&pdev->dev, "Mem-Wr-Inval unavailable.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + } + + /* save power state before pci_enable_device overwrites it */ + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pm_cap) { + u16 pwr_command; + + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); + } else { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) { + dev_err(&pdev->dev, "PowerManagement capability not found.\n"); + } +#else + printk("PowerManagement capability not found.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + } + + /* make sure PCI base addr 1 is MMIO */ + if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -ENODEV; + goto err_out_mwi; + } + /* check for weird/broken PCI region reporting */ + if (pci_resource_len(pdev, 2) < R8126_REGS_SIZE) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -ENODEV; + goto err_out_mwi; + } + + rc = pci_request_regions(pdev, MODULENAME); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "could not request regions.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_mwi; + } + + if ((sizeof(dma_addr_t) > 4) && + use_dac && + !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { + dev->features |= NETIF_F_HIGHDMA; + } else { + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "DMA configuration failed.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_free_res; + } + } + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); + if (ioaddr == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -EIO; + goto err_out_free_res; + } + + tp->mmio_addr = ioaddr; + + /* Identify chip attached to board */ + rtl8126_get_mac_version(tp); + + rtl8126_print_mac_version(tp); + + for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { + if (tp->mcfg == rtl_chip_info[i].mcfg) + break; + } + + if (i < 0) { + /* Unknown chip: assume array element #0, original RTL-8125 */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_printk(KERN_DEBUG, &pdev->dev, "unknown chip version, assuming %s\n", rtl_chip_info[0].name); +#else + printk("Realtek unknown chip version, assuming %s\n", rtl_chip_info[0].name); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + i++; + } + + tp->chipset = i; + + *ioaddr_out = ioaddr; + *dev_out = dev; +out: + return rc; + +err_out_free_res: + pci_release_regions(pdev); +err_out_mwi: + pci_clear_mwi(pdev); + pci_disable_device(pdev); +err_out_free_dev: + free_netdev(dev); +err_out: + *ioaddr_out = NULL; + *dev_out = NULL; + goto out; +} + +static void +rtl8126_esd_checker(struct rtl8126_private *tp) +{ + struct net_device *dev = tp->dev; + struct pci_dev *pdev = tp->pci_dev; + u8 cmd; + u16 io_base_l; + u16 mem_base_l; + u16 mem_base_h; + u8 ilr; + u16 resv_0x1c_h; + u16 resv_0x1c_l; + u16 resv_0x20_l; + u16 resv_0x20_h; + u16 resv_0x24_l; + u16 resv_0x24_h; + u16 resv_0x2c_h; + u16 resv_0x2c_l; + u32 pci_sn_l; + u32 pci_sn_h; + + if (unlikely(tp->rtk_enable_diag)) + goto exit; + + tp->esd_flag = 0; + + pci_read_config_byte(pdev, PCI_COMMAND, &cmd); + if (cmd != tp->pci_cfg_space.cmd) { + printk(KERN_ERR "%s: cmd = 0x%02x, should be 0x%02x \n.", dev->name, cmd, tp->pci_cfg_space.cmd); + pci_write_config_byte(pdev, PCI_COMMAND, tp->pci_cfg_space.cmd); + tp->esd_flag |= BIT_0; + + pci_read_config_byte(pdev, PCI_COMMAND, &cmd); + if (cmd == 0xff) { + printk(KERN_ERR "%s: pci link is down \n.", dev->name); + goto exit; + } + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &io_base_l); + if (io_base_l != tp->pci_cfg_space.io_base_l) { + printk(KERN_ERR "%s: io_base_l = 0x%04x, should be 0x%04x \n.", dev->name, io_base_l, tp->pci_cfg_space.io_base_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_0, tp->pci_cfg_space.io_base_l); + tp->esd_flag |= BIT_1; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &mem_base_l); + if (mem_base_l != tp->pci_cfg_space.mem_base_l) { + printk(KERN_ERR "%s: mem_base_l = 0x%04x, should be 0x%04x \n.", dev->name, mem_base_l, tp->pci_cfg_space.mem_base_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_2, tp->pci_cfg_space.mem_base_l); + tp->esd_flag |= BIT_2; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &mem_base_h); + if (mem_base_h!= tp->pci_cfg_space.mem_base_h) { + printk(KERN_ERR "%s: mem_base_h = 0x%04x, should be 0x%04x \n.", dev->name, mem_base_h, tp->pci_cfg_space.mem_base_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, tp->pci_cfg_space.mem_base_h); + tp->esd_flag |= BIT_3; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3, &resv_0x1c_l); + if (resv_0x1c_l != tp->pci_cfg_space.resv_0x1c_l) { + printk(KERN_ERR "%s: resv_0x1c_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x1c_l, tp->pci_cfg_space.resv_0x1c_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_3, tp->pci_cfg_space.resv_0x1c_l); + tp->esd_flag |= BIT_4; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, &resv_0x1c_h); + if (resv_0x1c_h != tp->pci_cfg_space.resv_0x1c_h) { + printk(KERN_ERR "%s: resv_0x1c_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x1c_h, tp->pci_cfg_space.resv_0x1c_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, tp->pci_cfg_space.resv_0x1c_h); + tp->esd_flag |= BIT_5; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &resv_0x20_l); + if (resv_0x20_l != tp->pci_cfg_space.resv_0x20_l) { + printk(KERN_ERR "%s: resv_0x20_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x20_l, tp->pci_cfg_space.resv_0x20_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_4, tp->pci_cfg_space.resv_0x20_l); + tp->esd_flag |= BIT_6; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &resv_0x20_h); + if (resv_0x20_h != tp->pci_cfg_space.resv_0x20_h) { + printk(KERN_ERR "%s: resv_0x20_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x20_h, tp->pci_cfg_space.resv_0x20_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, tp->pci_cfg_space.resv_0x20_h); + tp->esd_flag |= BIT_7; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &resv_0x24_l); + if (resv_0x24_l != tp->pci_cfg_space.resv_0x24_l) { + printk(KERN_ERR "%s: resv_0x24_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x24_l, tp->pci_cfg_space.resv_0x24_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_5, tp->pci_cfg_space.resv_0x24_l); + tp->esd_flag |= BIT_8; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &resv_0x24_h); + if (resv_0x24_h != tp->pci_cfg_space.resv_0x24_h) { + printk(KERN_ERR "%s: resv_0x24_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x24_h, tp->pci_cfg_space.resv_0x24_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, tp->pci_cfg_space.resv_0x24_h); + tp->esd_flag |= BIT_9; + } + + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ilr); + if (ilr != tp->pci_cfg_space.ilr) { + printk(KERN_ERR "%s: ilr = 0x%02x, should be 0x%02x \n.", dev->name, ilr, tp->pci_cfg_space.ilr); + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, tp->pci_cfg_space.ilr); + tp->esd_flag |= BIT_10; + } + + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &resv_0x2c_l); + if (resv_0x2c_l != tp->pci_cfg_space.resv_0x2c_l) { + printk(KERN_ERR "%s: resv_0x2c_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x2c_l, tp->pci_cfg_space.resv_0x2c_l); + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, tp->pci_cfg_space.resv_0x2c_l); + tp->esd_flag |= BIT_11; + } + + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, &resv_0x2c_h); + if (resv_0x2c_h != tp->pci_cfg_space.resv_0x2c_h) { + printk(KERN_ERR "%s: resv_0x2c_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x2c_h, tp->pci_cfg_space.resv_0x2c_h); + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, tp->pci_cfg_space.resv_0x2c_h); + tp->esd_flag |= BIT_12; + } + + if (tp->HwPcieSNOffset > 0) { + pci_sn_l = rtl8126_csi_read(tp, tp->HwPcieSNOffset); + if (pci_sn_l != tp->pci_cfg_space.pci_sn_l) { + printk(KERN_ERR "%s: pci_sn_l = 0x%08x, should be 0x%08x \n.", dev->name, pci_sn_l, tp->pci_cfg_space.pci_sn_l); + rtl8126_csi_write(tp, tp->HwPcieSNOffset, tp->pci_cfg_space.pci_sn_l); + tp->esd_flag |= BIT_13; + } + + pci_sn_h = rtl8126_csi_read(tp, tp->HwPcieSNOffset + 4); + if (pci_sn_h != tp->pci_cfg_space.pci_sn_h) { + printk(KERN_ERR "%s: pci_sn_h = 0x%08x, should be 0x%08x \n.", dev->name, pci_sn_h, tp->pci_cfg_space.pci_sn_h); + rtl8126_csi_write(tp, tp->HwPcieSNOffset + 4, tp->pci_cfg_space.pci_sn_h); + tp->esd_flag |= BIT_14; + } + } + + if (tp->esd_flag != 0) { + printk(KERN_ERR "%s: esd_flag = 0x%04x\n.\n", dev->name, tp->esd_flag); + netif_carrier_off(dev); + netif_tx_disable(dev); + rtl8126_hw_reset(dev); + rtl8126_tx_clear(tp); + rtl8126_rx_clear(tp); + rtl8126_init_ring(dev); + rtl8126_up(dev); + rtl8126_enable_hw_linkchg_interrupt(tp); + rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + tp->esd_flag = 0; + } +exit: + return; +} +/* +static void +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +rtl8126_esd_timer(unsigned long __opaque) +#else +rtl8126_esd_timer(struct timer_list *t) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8126_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->esd_timer; +#else + struct rtl8126_private *tp = from_timer(tp, t, esd_timer); + //struct net_device *dev = tp->dev; + struct timer_list *timer = t; +#endif + rtl8126_esd_checker(tp); + + mod_timer(timer, jiffies + timeout); +} +*/ + +/* +static void +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +rtl8126_link_timer(unsigned long __opaque) +#else +rtl8126_link_timer(struct timer_list *t) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8126_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->link_timer; +#else + struct rtl8126_private *tp = from_timer(tp, t, link_timer); + struct net_device *dev = tp->dev; + struct timer_list *timer = t; +#endif + rtl8126_check_link_status(dev); + + mod_timer(timer, jiffies + RTL8126_LINK_TIMEOUT); +} +*/ + +int +rtl8126_enable_msix(struct rtl8126_private *tp) +{ + int i, nvecs = 0; + struct msix_entry msix_ent[R8126_MAX_MSIX_VEC]; + //struct net_device *dev = tp->dev; + //const int len = sizeof(tp->irq_tbl[0].name); + + for (i = 0; i < R8126_MAX_MSIX_VEC; i++) { + msix_ent[i].entry = i; + msix_ent[i].vector = 0; + } + + nvecs = pci_enable_msix_range(tp->pci_dev, msix_ent, + tp->min_irq_nvecs, tp->max_irq_nvecs); + if (nvecs < 0) + goto out; + + for (i = 0; i < nvecs; i++) { + struct r8126_irq *irq = &tp->irq_tbl[i]; + irq->vector = msix_ent[i].vector; + //snprintf(irq->name, len, "%s-%d", dev->name, i); + //irq->handler = rtl8126_interrupt_msix; + } + +out: + return nvecs; +} + +/* Cfg9346_Unlock assumed. */ +static int rtl8126_try_msi(struct rtl8126_private *tp) +{ + struct pci_dev *pdev = tp->pci_dev; + unsigned int hw_supp_irq_nvecs; + unsigned msi = 0; + int nvecs = 1; + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + hw_supp_irq_nvecs = R8126_MAX_MSIX_VEC_8125B; + break; + default: + hw_supp_irq_nvecs = 1; + break; + } + tp->hw_supp_irq_nvecs = clamp_val(hw_supp_irq_nvecs, 1, + R8126_MAX_MSIX_VEC); + + tp->max_irq_nvecs = 1; + tp->min_irq_nvecs = 1; +#ifndef DISABLE_MULTI_MSIX_VECTOR + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + tp->max_irq_nvecs = tp->hw_supp_irq_nvecs; + tp->min_irq_nvecs = R8126_MIN_MSIX_VEC_8125B; + break; + } +#endif + +#if defined(RTL_USE_NEW_INTR_API) + if ((nvecs = pci_alloc_irq_vectors(pdev, tp->min_irq_nvecs, tp->max_irq_nvecs, PCI_IRQ_MSIX)) > 0) + msi |= RTL_FEATURE_MSIX; + else if ((nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES)) > 0 && + pci_dev_msi_enabled(pdev)) + msi |= RTL_FEATURE_MSI; +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + if ((nvecs = rtl8126_enable_msix(tp)) > 0) + msi |= RTL_FEATURE_MSIX; + else if (!pci_enable_msi(pdev)) + msi |= RTL_FEATURE_MSI; +#endif + if (!(msi & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))) + dev_info(&pdev->dev, "no MSI/MSI-X. Back to INTx.\n"); + + if (!(msi & RTL_FEATURE_MSIX) || nvecs < 1) + nvecs = 1; + + tp->irq_nvecs = nvecs; + + tp->features |= msi; + + return nvecs; +} + +static void rtl8126_disable_msi(struct pci_dev *pdev, struct rtl8126_private *tp) +{ +#if defined(RTL_USE_NEW_INTR_API) + if (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) + pci_free_irq_vectors(pdev); +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + if (tp->features & (RTL_FEATURE_MSIX)) + pci_disable_msix(pdev); + else if (tp->features & (RTL_FEATURE_MSI)) + pci_disable_msi(pdev); +#endif + tp->features &= ~(RTL_FEATURE_MSI | RTL_FEATURE_MSIX); +} + +static int rtl8126_get_irq(struct pci_dev *pdev) +{ +#if defined(RTL_USE_NEW_INTR_API) + return pci_irq_vector(pdev, 0); +#else + return pdev->irq; +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static void +rtl8126_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct rtl8126_counters *counters = tp->tally_vaddr; + dma_addr_t paddr = tp->tally_paddr; + + if (!counters) + return; + + netdev_stats_to_stats64(stats, &dev->stats); + dev_fetch_sw_netstats(stats, dev->tstats); + + /* + * Fetch additional counter values missing in stats collected by driver + * from tally counters. + */ + rtl8126_dump_tally_counter(tp, paddr); + + stats->tx_errors = le64_to_cpu(counters->tx_errors); + stats->collisions = le32_to_cpu(counters->tx_multi_collision); + stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) ; + stats->rx_missed_errors = le16_to_cpu(counters->rx_missed); +} +#else +/** + * rtl8126_get_stats - Get rtl8126 read/write statistics + * @dev: The Ethernet Device to get statistics for + * + * Get TX/RX statistics for rtl8126 + */ +static struct +net_device_stats *rtl8126_get_stats(struct net_device *dev) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + struct rtl8126_private *tp = netdev_priv(dev); +#endif + return &RTLDEV->stats; +} +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static const struct net_device_ops rtl8126_netdev_ops = { + .ndo_open = rtl8126_open, + .ndo_stop = rtl8126_close, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) + .ndo_get_stats64 = rtl8126_get_stats64, +#else + .ndo_get_stats = rtl8126_get_stats, +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) + .ndo_start_xmit = rtl8126_start_xmit, + .ndo_tx_timeout = rtl8126_tx_timeout, + .ndo_change_mtu = rtl8126_change_mtu, + .ndo_set_mac_address = rtl8126_set_mac_address, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) + .ndo_do_ioctl = rtl8126_do_ioctl, +#else + .ndo_siocdevprivate = rtl8126_siocdevprivate, + .ndo_eth_ioctl = rtl8126_do_ioctl, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) + .ndo_set_multicast_list = rtl8126_set_rx_mode, +#else + .ndo_set_rx_mode = rtl8126_set_rx_mode, +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) +#ifdef CONFIG_R8126_VLAN + .ndo_vlan_rx_register = rtl8126_vlan_rx_register, +#endif +#else + .ndo_fix_features = rtl8126_fix_features, + .ndo_set_features = rtl8126_set_features, +#endif +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = rtl8126_netpoll, +#endif +}; +#endif + + +#ifdef CONFIG_R8126_NAPI + +static int rtl8126_poll(napi_ptr napi, napi_budget budget) +{ + struct r8126_napi *r8126napi = RTL_GET_PRIV(napi, struct r8126_napi); + struct rtl8126_private *tp = r8126napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) + rtl8126_tx_interrupt(&tp->tx_ring[i], budget); + + for (i = 0; i < tp->num_rx_rings; i++) + work_done += rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[i], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + HandleDashInterrupt(tp->dev); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) + return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8126_switch_to_timer_interrupt(tp); + } + + return RTL_NAPI_RETURN_VALUE; +} + +static int rtl8126_poll_msix_ring(napi_ptr napi, napi_budget budget) +{ + struct r8126_napi *r8126napi = RTL_GET_PRIV(napi, struct r8126_napi); + struct rtl8126_private *tp = r8126napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8126napi->index; + + rtl8126_tx_interrupt_with_vector(tp, message_id, budget); + + work_done += rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH && message_id == 0) + HandleDashInterrupt(tp->dev); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) + return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8126_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} + +static int rtl8126_poll_msix_tx(napi_ptr napi, napi_budget budget) +{ + struct r8126_napi *r8126napi = RTL_GET_PRIV(napi, struct r8126_napi); + struct rtl8126_private *tp = r8126napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8126napi->index; + + //suppress unused variable + (void)(dev); + + rtl8126_tx_interrupt_with_vector(tp, message_id, budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) + return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8126_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} + +static int rtl8126_poll_msix_other(napi_ptr napi, napi_budget budget) +{ + struct r8126_napi *r8126napi = RTL_GET_PRIV(napi, struct r8126_napi); + struct rtl8126_private *tp = r8126napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + const int message_id = r8126napi->index; + + //suppress unused variable + (void)(dev); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + RTL_NETIF_RX_COMPLETE(dev, napi, work_to_do); +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_to_do); +#endif + + rtl8126_enable_hw_interrupt_v2(tp, message_id); + + return 1; +} + +static int rtl8126_poll_msix_rx(napi_ptr napi, napi_budget budget) +{ + struct r8126_napi *r8126napi = RTL_GET_PRIV(napi, struct r8126_napi); + struct rtl8126_private *tp = r8126napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8126napi->index; + + work_done += rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) + return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8126_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} + +void rtl8126_enable_napi(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_ENABLE(tp->dev, &tp->r8126napi[i].napi); +#endif +} + +static void rtl8126_disable_napi(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_DISABLE(tp->dev, &tp->r8126napi[i].napi); +#endif +} + +static void rtl8126_del_napi(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_DEL((&tp->r8126napi[i])); +#endif +} +#endif //CONFIG_R8126_NAPI + +static void rtl8126_init_napi(struct rtl8126_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8126_napi *r8126napi = &tp->r8126napi[i]; +#ifdef CONFIG_R8126_NAPI + int (*poll)(struct napi_struct *, int); + + poll = rtl8126_poll; + if (tp->features & RTL_FEATURE_MSIX) { + switch (tp->HwCurrIsrVer) { + case 5: + if (i < R8126_MAX_RX_QUEUES_VEC_V3) + poll = rtl8126_poll_msix_rx; + else if (i == 16 || i == 17) + poll = rtl8126_poll_msix_tx; + else + poll = rtl8126_poll_msix_other; + break; + case 2: + if (i < R8126_MAX_RX_QUEUES_VEC_V3) + poll = rtl8126_poll_msix_rx; + else if (i == 16 || i == 18) + poll = rtl8126_poll_msix_tx; + else + poll = rtl8126_poll_msix_other; + break; + case 3: + case 4: + if (i < R8126_MAX_RX_QUEUES_VEC_V3) + poll = rtl8126_poll_msix_ring; + else + poll = rtl8126_poll_msix_other; + break; + } + } + + RTL_NAPI_CONFIG(tp->dev, r8126napi, poll, R8126_NAPI_WEIGHT); +#endif + + r8126napi->priv = tp; + r8126napi->index = i; + } +} + +static int +rtl8126_set_real_num_queue(struct rtl8126_private *tp) +{ + int retval = 0; + + retval = netif_set_real_num_tx_queues(tp->dev, tp->num_tx_rings); + if (retval < 0) + goto exit; + + retval = netif_set_real_num_rx_queues(tp->dev, tp->num_rx_rings); + if (retval < 0) + goto exit; + +exit: + return retval; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) +void netdev_sw_irq_coalesce_default_on(struct net_device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0) + WARN_ON(dev->reg_state == NETREG_REGISTERED); + + dev->gro_flush_timeout = 20000; + dev->napi_defer_hard_irqs = 1; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0) +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) + +static int __devinit +rtl8126_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev = NULL; + struct rtl8126_private *tp; + void __iomem *ioaddr = NULL; + static int board_idx = -1; + + int rc; + + assert(pdev != NULL); + assert(ent != NULL); + + board_idx++; + + if (netif_msg_drv(&debug)) + printk(KERN_INFO "%s Ethernet controller driver %s loaded\n", + MODULENAME, RTL8126_VERSION); + + rc = rtl8126_init_board(pdev, &dev, &ioaddr); + if (rc) + goto out; + + tp = netdev_priv(dev); + assert(ioaddr != NULL); + + tp->set_speed = rtl8126_set_speed_xmii; + tp->get_settings = rtl8126_gset_xmii; + tp->phy_reset_enable = rtl8126_xmii_reset_enable; + tp->phy_reset_pending = rtl8126_xmii_reset_pending; + tp->link_ok = rtl8126_xmii_link_ok; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) + dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev, + struct pcpu_sw_netstats); + if (!dev->tstats) + goto err_out_1; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) + + rc = rtl8126_try_msi(tp); + if (rc < 0) { + dev_err(&pdev->dev, "Can't allocate interrupt\n"); + goto err_out_1; + } + + rtl8126_init_software_variable(dev); + + RTL_NET_DEVICE_OPS(rtl8126_netdev_ops); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + SET_ETHTOOL_OPS(dev, &rtl8126_ethtool_ops); +#endif + + dev->watchdog_timeo = RTL8126_TX_TIMEOUT; + dev->irq = rtl8126_get_irq(pdev); + dev->base_addr = (unsigned long) ioaddr; + + rtl8126_init_napi(tp); + +#ifdef CONFIG_R8126_VLAN + if (tp->mcfg != CFG_METHOD_DEFAULT) { + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + dev->vlan_rx_kill_vid = rtl8126_vlan_rx_kill_vid; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + } +#endif + + /* There has been a number of reports that using SG/TSO results in + * tx timeouts. However for a lot of people SG/TSO works fine. + * Therefore disable both features by default, but allow users to + * enable them. Use at own risk! + */ + tp->cp_cmd |= RTL_R16(tp, CPlusCmd); + if (tp->mcfg != CFG_METHOD_DEFAULT) { + dev->features |= NETIF_F_IP_CSUM; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + tp->cp_cmd |= RxChkSum; +#else + dev->features |= NETIF_F_RXCSUM; + switch (tp->mcfg) { + default: + dev->features |= NETIF_F_SG | NETIF_F_TSO; + break; + }; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HIGHDMA; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) + dev->hw_features |= NETIF_F_RXALL; + dev->hw_features |= NETIF_F_RXFCS; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + dev->features |= NETIF_F_IPV6_CSUM; + switch (tp->mcfg) { + default: + dev->features |= NETIF_F_TSO6; + break; + }; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) + netif_set_tso_max_size(dev, LSO_64K); + netif_set_tso_max_segs(dev, NIC_MAX_PHYS_BUF_COUNT_LSO2); +#else //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) + netif_set_gso_max_size(dev, LSO_64K); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) + dev->gso_max_segs = NIC_MAX_PHYS_BUF_COUNT_LSO2; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) + dev->gso_min_segs = NIC_MIN_PHYS_BUF_COUNT; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) + +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + +#ifdef ENABLE_RSS_SUPPORT + if (tp->EnableRss) { + dev->hw_features |= NETIF_F_RXHASH; + dev->features |= NETIF_F_RXHASH; + } +#endif + } + + netdev_sw_irq_coalesce_default_on(dev); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + AllocateDashShareMemory(dev); +#endif + +#ifdef ENABLE_LIB_SUPPORT + BLOCKING_INIT_NOTIFIER_HEAD(&tp->lib_nh); +#endif + rtl8126_init_all_schedule_work(tp); + + rc = rtl8126_set_real_num_queue(tp); + if (rc < 0) + goto err_out; + + rtl8126_exit_oob(dev); + + rtl8126_powerup_pll(dev); + + rtl8126_hw_init(dev); + + rtl8126_hw_reset(dev); + + /* Get production from EEPROM */ + rtl8126_eeprom_type(tp); + + if (tp->eeprom_type == EEPROM_TYPE_93C46 || tp->eeprom_type == EEPROM_TYPE_93C56) + rtl8126_set_eeprom_sel_low(tp); + + rtl8126_get_mac_address(dev); + + tp->fw_name = rtl_chip_fw_infos[tp->mcfg].fw_name; + + tp->tally_vaddr = dma_alloc_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), + &tp->tally_paddr, GFP_KERNEL); + if (!tp->tally_vaddr) { + rc = -ENOMEM; + goto err_out; + } + + rtl8126_tally_counter_clear(tp); + + pci_set_drvdata(pdev, dev); + + rc = register_netdev(dev); + if (rc) + goto err_out; + + printk(KERN_INFO "%s: This product is covered by one or more of the following patents: US6,570,884, US6,115,776, and US6,327,625.\n", MODULENAME); + + rtl8126_disable_rxdvgate(dev); + + device_set_wakeup_enable(&pdev->dev, tp->wol_enabled); + + netif_carrier_off(dev); + + rtl8126_sysfs_init(dev); + + printk("%s", GPL_CLAIM); + +out: + return rc; + +err_out: + if (tp->tally_vaddr != NULL) { + dma_free_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), tp->tally_vaddr, + tp->tally_paddr); + + tp->tally_vaddr = NULL; + } +#ifdef CONFIG_R8126_NAPI + rtl8126_del_napi(tp); +#endif + rtl8126_disable_msi(pdev, tp); + +err_out_1: + rtl8126_release_board(pdev, dev); + + goto out; +} + +static void __devexit +rtl8126_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8126_private *tp = netdev_priv(dev); + + assert(dev != NULL); + assert(tp != NULL); + + set_bit(R8126_FLAG_DOWN, tp->task_flags); + + rtl8126_cancel_all_schedule_work(tp); + +#ifdef CONFIG_R8126_NAPI + rtl8126_del_napi(tp); +#endif + if (HW_DASH_SUPPORT_DASH(tp)) + rtl8126_driver_stop(tp); + +#ifdef ENABLE_R8126_SYSFS + rtl8126_sysfs_remove(dev); +#endif //ENABLE_R8126_SYSFS + + unregister_netdev(dev); + rtl8126_disable_msi(pdev, tp); +#ifdef ENABLE_R8126_PROCFS + rtl8126_proc_remove(dev); +#endif + if (tp->tally_vaddr != NULL) { + dma_free_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), tp->tally_vaddr, tp->tally_paddr); + tp->tally_vaddr = NULL; + } + + rtl8126_release_board(pdev, dev); + +#ifdef ENABLE_USE_FIRMWARE_FILE + rtl8126_release_firmware(tp); +#endif + + pci_set_drvdata(pdev, NULL); +} + +#ifdef ENABLE_PAGE_REUSE +static inline unsigned int rtl8126_rx_page_order(unsigned rx_buf_sz, unsigned page_size) +{ + unsigned truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + + SKB_DATA_ALIGN(rx_buf_sz + R8126_RX_ALIGN); + + return get_order(truesize * 2); +} +#endif //ENABLE_PAGE_REUSE + +static void +rtl8126_set_rxbufsize(struct rtl8126_private *tp, + struct net_device *dev) +{ + unsigned int mtu = dev->mtu; + + tp->rms = (mtu > ETH_DATA_LEN) ? + mtu + ETH_HLEN + RT_VALN_HLEN + ETH_FCS_LEN: + RX_BUF_SIZE; + tp->rx_buf_sz = tp->rms; +#ifdef ENABLE_RX_PACKET_FRAGMENT + tp->rx_buf_sz = SKB_DATA_ALIGN(RX_BUF_SIZE); +#endif //ENABLE_RX_PACKET_FRAGMENT +#ifdef ENABLE_PAGE_REUSE + tp->rx_buf_page_order = rtl8126_rx_page_order(tp->rx_buf_sz, PAGE_SIZE); + tp->rx_buf_page_size = rtl8126_rx_page_size(tp->rx_buf_page_order); +#endif //ENABLE_PAGE_REUSE +} + +static void rtl8126_free_irq(struct rtl8126_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8126_irq *irq = &tp->irq_tbl[i]; + struct r8126_napi *r8126napi = &tp->r8126napi[i]; + + if (irq->requested) { + irq->requested = 0; +#if defined(RTL_USE_NEW_INTR_API) + pci_free_irq(tp->pci_dev, i, r8126napi); +#else + free_irq(irq->vector, r8126napi); +#endif + } + } +} + +static int rtl8126_alloc_irq(struct rtl8126_private *tp) +{ + struct net_device *dev = tp->dev; + int rc = 0; + struct r8126_irq *irq; + struct r8126_napi *r8126napi; + int i = 0; + const int len = sizeof(tp->irq_tbl[0].name); + +#if defined(RTL_USE_NEW_INTR_API) + for (i=0; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + if (tp->features & RTL_FEATURE_MSIX && + tp->HwCurrIsrVer > 1) + irq->handler = rtl8126_interrupt_msix; + else + irq->handler = rtl8126_interrupt; + + r8126napi = &tp->r8126napi[i]; + snprintf(irq->name, len, "%s-%d", dev->name, i); + rc = pci_request_irq(tp->pci_dev, i, irq->handler, NULL, r8126napi, + irq->name); + if (rc) + break; + + irq->vector = pci_irq_vector(tp->pci_dev, i); + irq->requested = 1; + } +#else + unsigned long irq_flags = 0; +#ifdef ENABLE_LIB_SUPPORT + irq_flags |= IRQF_NO_SUSPEND; +#endif + if (tp->features & RTL_FEATURE_MSIX && + tp->HwCurrIsrVer > 1) { + for (i=0; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + irq->handler = rtl8126_interrupt_msix; + r8126napi = &tp->r8126napi[i]; + snprintf(irq->name, len, "%s-%d", dev->name, i); + rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8126napi); + + if (rc) + break; + + irq->requested = 1; + } + } else { + irq = &tp->irq_tbl[0]; + irq->handler = rtl8126_interrupt; + r8126napi = &tp->r8126napi[0]; + snprintf(irq->name, len, "%s-0", dev->name); + if (!(tp->features & RTL_FEATURE_MSIX)) + irq->vector = dev->irq; + irq_flags |= (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) ? 0 : SA_SHIRQ; + rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8126napi); + + if (rc == 0) + irq->requested = 1; + } +#endif + if (rc) + rtl8126_free_irq(tp); + + return rc; +} + +static int rtl8126_alloc_tx_desc(struct rtl8126_private *tp) +{ + struct rtl8126_tx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + ring = &tp->tx_ring[i]; + ring->TxDescAllocSize = (ring->num_tx_desc + 1) * sizeof(struct TxDesc); + ring->TxDescArray = dma_alloc_coherent(&pdev->dev, + ring->TxDescAllocSize, + &ring->TxPhyAddr, + GFP_KERNEL); + + if (!ring->TxDescArray) + return -1; + } + + return 0; +} + +static int rtl8126_alloc_rx_desc(struct rtl8126_private *tp) +{ + struct rtl8126_rx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + ring = &tp->rx_ring[i]; + ring->RxDescAllocSize = (ring->num_rx_desc + 1) * tp->RxDescLength; + ring->RxDescArray = dma_alloc_coherent(&pdev->dev, + ring->RxDescAllocSize, + &ring->RxPhyAddr, + GFP_KERNEL); + + if (!ring->RxDescArray) + return -1; + } + + return 0; +} + +static void rtl8126_free_tx_desc(struct rtl8126_private *tp) +{ + struct rtl8126_tx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + ring = &tp->tx_ring[i]; + if (ring->TxDescArray) { + dma_free_coherent(&pdev->dev, + ring->TxDescAllocSize, + ring->TxDescArray, + ring->TxPhyAddr); + ring->TxDescArray = NULL; + } + } +} + +static void rtl8126_free_rx_desc(struct rtl8126_private *tp) +{ + struct rtl8126_rx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + ring = &tp->rx_ring[i]; + if (ring->RxDescArray) { + dma_free_coherent(&pdev->dev, + ring->RxDescAllocSize, + ring->RxDescArray, + ring->RxPhyAddr); + ring->RxDescArray = NULL; + } + } +} + +static void rtl8126_free_alloc_resources(struct rtl8126_private *tp) +{ + rtl8126_free_rx_desc(tp); + + rtl8126_free_tx_desc(tp); +} + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void rtl8126_request_firmware(struct rtl8126_private *tp) +{ + struct rtl8126_fw *rtl_fw; + + /* firmware loaded already or no firmware available */ + if (tp->rtl_fw || !tp->fw_name) + return; + + rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); + if (!rtl_fw) + return; + + rtl_fw->phy_write = rtl8126_mdio_write; + rtl_fw->phy_read = rtl8126_mdio_read; + rtl_fw->mac_mcu_write = mac_mcu_write; + rtl_fw->mac_mcu_read = mac_mcu_read; + rtl_fw->fw_name = tp->fw_name; + rtl_fw->dev = tp_to_dev(tp); + + if (rtl8126_fw_request_firmware(rtl_fw)) + kfree(rtl_fw); + else + tp->rtl_fw = rtl_fw; +} +#endif + +int rtl8126_open(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int retval; + + retval = -ENOMEM; + +#ifdef ENABLE_R8126_PROCFS + rtl8126_proc_init(dev); +#endif + rtl8126_set_rxbufsize(tp, dev); + /* + * Rx and Tx descriptors needs 256 bytes alignment. + * pci_alloc_consistent provides more. + */ + if (rtl8126_alloc_tx_desc(tp) < 0 || rtl8126_alloc_rx_desc(tp) < 0) + goto err_free_all_allocated_mem; + + retval = rtl8126_init_ring(dev); + if (retval < 0) + goto err_free_all_allocated_mem; + + retval = rtl8126_alloc_irq(tp); + if (retval < 0) + goto err_free_all_allocated_mem; + + if (netif_msg_probe(tp)) { + printk(KERN_INFO "%s: 0x%lx, " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "IRQ %d\n", + dev->name, + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], dev->irq); + } + +#ifdef ENABLE_USE_FIRMWARE_FILE + rtl8126_request_firmware(tp); +#endif + pci_set_master(tp->pci_dev); + +#ifdef CONFIG_R8126_NAPI + rtl8126_enable_napi(tp); +#endif + + rtl8126_exit_oob(dev); + + rtl8126_up(dev); + +#ifdef ENABLE_PTP_SUPPORT + if (tp->EnablePtp) + rtl8126_ptp_init(tp); +#endif + clear_bit(R8126_FLAG_DOWN, tp->task_flags); + + if (tp->resume_not_chg_speed) + rtl8126_check_link_status(dev); + else + rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + + if (tp->esd_flag == 0) { + //rtl8126_request_esd_timer(dev); + + rtl8126_schedule_esd_work(tp); + } + + //rtl8126_request_link_timer(dev); + + rtl8126_enable_hw_linkchg_interrupt(tp); + +out: + + return retval; + +err_free_all_allocated_mem: + rtl8126_free_alloc_resources(tp); + + goto out; +} + +static void +set_offset70F(struct rtl8126_private *tp, u8 setting) +{ + u32 csi_tmp; + u32 temp = (u32)setting; + temp = temp << 24; + /*set PCI configuration space offset 0x70F to setting*/ + /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/ + + csi_tmp = rtl8126_csi_read(tp, 0x70c) & 0x00ffffff; + rtl8126_csi_write(tp, 0x70c, csi_tmp | temp); +} + +static void +set_offset79(struct rtl8126_private *tp, u8 setting) +{ + //Set PCI configuration space offset 0x79 to setting + + struct pci_dev *pdev = tp->pci_dev; + u8 device_control; + + if (hwoptimize & HW_PATCH_SOC_LAN) + return; + + pci_read_config_byte(pdev, 0x79, &device_control); + device_control &= ~0x70; + device_control |= setting; + pci_write_config_byte(pdev, 0x79, device_control); +} + +static void +rtl8126_disable_l1_timeout(struct rtl8126_private *tp) +{ + rtl8126_csi_write(tp, 0x890, rtl8126_csi_read(tp, 0x890) & ~BIT(0)); +} + +void +rtl8126_hw_set_rx_packet_filter(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + u32 mc_filter[2]; /* Multicast hash filter */ + int rx_mode; + u32 tmp = 0; + + if (dev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ + if (netif_msg_link(tp)) + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", + dev->name); + + rx_mode = + AcceptBroadcast | AcceptMulticast | AcceptMyPhys | + AcceptAllPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else if (dev->flags & IFF_ALLMULTI) { + /* accept all multicasts. */ + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) + struct dev_mc_list *mclist; + unsigned int i; + + rx_mode = AcceptBroadcast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } +#else + struct netdev_hw_addr *ha; + + rx_mode = AcceptBroadcast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; + netdev_for_each_mc_addr(ha, dev) { + int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } +#endif + } + + if (dev->features & NETIF_F_RXALL) + rx_mode |= (AcceptErr | AcceptRunt); + + tmp = mc_filter[0]; + mc_filter[0] = swab32(mc_filter[1]); + mc_filter[1] = swab32(tmp); + + tmp = tp->rtl8126_rx_config | rx_mode | (RTL_R32(tp, RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + + RTL_W32(tp, RxConfig, tmp); + RTL_W32(tp, MAR0 + 0, mc_filter[0]); + RTL_W32(tp, MAR0 + 4, mc_filter[1]); +} + +static void +rtl8126_set_rx_mode(struct net_device *dev) +{ + rtl8126_hw_set_rx_packet_filter(dev); +} + +void +rtl8126_set_rx_q_num(struct rtl8126_private *tp, + unsigned int num_rx_queues) +{ + u16 q_ctrl; + u16 rx_q_num; + + rx_q_num = (u16)ilog2(num_rx_queues); + rx_q_num &= (BIT_0 | BIT_1 | BIT_2); + rx_q_num <<= 2; + q_ctrl = RTL_R16(tp, Q_NUM_CTRL_8125); + q_ctrl &= ~(BIT_2 | BIT_3 | BIT_4); + q_ctrl |= rx_q_num; + RTL_W16(tp, Q_NUM_CTRL_8125, q_ctrl); +} + +void +rtl8126_set_tx_q_num(struct rtl8126_private *tp, + unsigned int num_tx_queues) +{ + u16 mac_ocp_data; + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xE63E); + mac_ocp_data &= ~(BIT_11 | BIT_10); + mac_ocp_data |= ((ilog2(num_tx_queues) & 0x03) << 10); + rtl8126_mac_ocp_write(tp, 0xE63E, mac_ocp_data); +} + +void +rtl8126_enable_mcu(struct rtl8126_private *tp, bool enable) +{ + if (FALSE == HW_SUPPORT_MAC_MCU(tp)) + return; + + if (enable) + rtl8126_set_mac_ocp_bit(tp, 0xC0B4, BIT_0); + else + rtl8126_clear_mac_ocp_bit(tp, 0xC0B4, BIT_0); +} + +static void +rtl8126_clear_tcam_entries(struct rtl8126_private *tp) +{ + if (FALSE == HW_SUPPORT_TCAM(tp)) + return; + + rtl8126_set_mac_ocp_bit(tp, 0xEB54, BIT_0); + udelay(1); + rtl8126_clear_mac_ocp_bit(tp, 0xEB54, BIT_0); +} + +static u8 +rtl8126_get_l1off_cap_bits(struct rtl8126_private *tp) +{ + u8 l1offCapBits = 0; + + l1offCapBits = (BIT_0 | BIT_1); + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + l1offCapBits |= (BIT_2 | BIT_3); + default: + break; + } + + return l1offCapBits; +} + +void +rtl8126_hw_config(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + u16 mac_ocp_data; + + rtl8126_disable_rx_packet_filter(tp); + + rtl8126_hw_reset(dev); + + rtl8126_enable_cfg9346_write(tp); + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_force_clkreq(tp, 0); + rtl8126_enable_aspm_clkreq_lock(tp, 0); + break; + } + + rtl8126_set_eee_lpi_timer(tp); + + //keep magic packet only + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xC0B6); + mac_ocp_data &= BIT_0; + rtl8126_mac_ocp_write(tp, 0xC0B6, mac_ocp_data); + break; + } + + rtl8126_tally_counter_addr_fill(tp); + + rtl8126_enable_extend_tally_couter(tp); + + rtl8126_desc_addr_fill(tp); + + /* Set DMA burst size and Interframe Gap Time */ + RTL_W32(tp, TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) | + (InterFrameGap << TxInterFrameGapShift)); + + if (tp->EnableTxNoClose) + RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | BIT_6)); + + if (enable_double_vlan) + rtl8126_enable_double_vlan(tp); + else + rtl8126_disable_double_vlan(tp); + + if (tp->mcfg == CFG_METHOD_1 || + tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3) { + set_offset70F(tp, 0x27); + set_offset79(tp, 0x40); + + rtl8126_disable_l1_timeout(tp); + +#ifdef ENABLE_RSS_SUPPORT + rtl8126_config_rss(tp); +#else + RTL_W32(tp, RSS_CTRL_8125, 0x00); +#endif + rtl8126_set_rx_q_num(tp, rtl8126_tot_rx_rings(tp)); + + RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); + + rtl8126_mac_ocp_write(tp, 0xC140, 0xFFFF); + rtl8126_mac_ocp_write(tp, 0xC142, 0xFFFF); + + //new tx desc format + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xEB58); + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3) + mac_ocp_data &= ~(BIT_0 | BIT_1); + mac_ocp_data |= (BIT_0); + rtl8126_mac_ocp_write(tp, 0xEB58, mac_ocp_data); + + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3) + RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~BIT_1); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xE614); + mac_ocp_data &= ~(BIT_10 | BIT_9 | BIT_8); + if (tp->mcfg == CFG_METHOD_1 || tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3) + mac_ocp_data |= ((4 & 0x07) << 8); + else + mac_ocp_data |= ((3 & 0x07) << 8); + rtl8126_mac_ocp_write(tp, 0xE614, mac_ocp_data); + + rtl8126_set_tx_q_num(tp, rtl8126_tot_tx_rings(tp)); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xE63E); + mac_ocp_data &= ~(BIT_5 | BIT_4); + if (tp->mcfg == CFG_METHOD_1 || tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3) + mac_ocp_data |= ((0x02 & 0x03) << 4); + rtl8126_mac_ocp_write(tp, 0xE63E, mac_ocp_data); + + rtl8126_enable_mcu(tp, 0); + rtl8126_enable_mcu(tp, 1); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xC0B4); + mac_ocp_data |= (BIT_3 | BIT_2); + rtl8126_mac_ocp_write(tp, 0xC0B4, mac_ocp_data); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xEB6A); + mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); + mac_ocp_data |= (BIT_5 | BIT_4 | BIT_1 | BIT_0); + rtl8126_mac_ocp_write(tp, 0xEB6A, mac_ocp_data); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xEB50); + mac_ocp_data &= ~(BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5); + mac_ocp_data |= (BIT_6); + rtl8126_mac_ocp_write(tp, 0xEB50, mac_ocp_data); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xE056); + mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4); + //mac_ocp_data |= (BIT_4 | BIT_5); + rtl8126_mac_ocp_write(tp, 0xE056, mac_ocp_data); + + RTL_W8(tp, TDFNR, 0x10); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xE040); + mac_ocp_data &= ~(BIT_12); + rtl8126_mac_ocp_write(tp, 0xE040, mac_ocp_data); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xEA1C); + mac_ocp_data &= ~(BIT_1 | BIT_0); + mac_ocp_data |= (BIT_0); + rtl8126_mac_ocp_write(tp, 0xEA1C, mac_ocp_data); + + rtl8126_mac_ocp_write(tp, 0xE0C0, 0x4000); + + rtl8126_set_mac_ocp_bit(tp, 0xE052, (BIT_6 | BIT_5)); + rtl8126_clear_mac_ocp_bit(tp, 0xE052, BIT_3 | BIT_7); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xD430); + mac_ocp_data &= ~(BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); + mac_ocp_data |= 0x45F; + rtl8126_mac_ocp_write(tp, 0xD430, mac_ocp_data); + + //rtl8126_mac_ocp_write(tp, 0xE0C0, 0x4F87); + if (!tp->DASH) + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_6 | BIT_7); + else + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) & ~(BIT_6 | BIT_7)); + + rtl8126_disable_eee_plus(tp); + + mac_ocp_data = rtl8126_mac_ocp_read(tp, 0xEA1C); + mac_ocp_data &= ~(BIT_2); + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3) + mac_ocp_data &= ~(BIT_9 | BIT_8); + rtl8126_mac_ocp_write(tp, 0xEA1C, mac_ocp_data); + + rtl8126_clear_tcam_entries(tp); + + RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~(BIT_4 | BIT_5)); + } + + /* csum offload command for RTL8125 */ + tp->tx_tcp_csum_cmd = TxTCPCS_C; + tp->tx_udp_csum_cmd = TxUDPCS_C; + tp->tx_ip_csum_cmd = TxIPCS_C; + tp->tx_ipv6_csum_cmd = TxIPV6F_C; + + /* config interrupt type for RTL8125B */ + if (tp->HwSuppIsrVer > 1) + rtl8126_hw_set_interrupt_type(tp, tp->HwCurrIsrVer); + + //other hw parameters + rtl8126_hw_clear_timer_int(dev); + + rtl8126_hw_clear_int_miti(dev); + + if (tp->use_timer_interrupt && + (tp->HwCurrIsrVer > 1) && + (tp->HwSuppIntMitiVer > 3) && + (tp->features & RTL_FEATURE_MSIX)) { + int i; + for (i = 0; i < tp->irq_nvecs; i++) + rtl8126_hw_set_timer_int_8125(tp, i, timer_count_v2); + } + + rtl8126_enable_exit_l1_mask(tp); + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_mac_ocp_write(tp, 0xE098, 0xC302); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_disable_pci_offset_99(tp); + if (aspm) { + if (tp->org_pci_offset_99 & (BIT_2 | BIT_5 | BIT_6)) + rtl8126_init_pci_offset_99(tp); + } + break; + } + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_disable_pci_offset_180(tp); + if (aspm) { + if (tp->org_pci_offset_180 & rtl8126_get_l1off_cap_bits(tp)) + rtl8126_init_pci_offset_180(tp); + } + break; + } + + tp->cp_cmd &= ~(EnableBist | Macdbgo_oe | Force_halfdup | + Force_rxflow_en | Force_txflow_en | Cxpl_dbg_sel | + ASF | Macdbgo_sel); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + RTL_W16(tp, CPlusCmd, tp->cp_cmd); +#else + rtl8126_hw_set_features(dev, dev->features); +#endif + RTL_W16(tp, RxMaxSize, tp->rms); + + rtl8126_disable_rxdvgate(dev); + + if (!tp->pci_cfg_is_read) { + pci_read_config_byte(pdev, PCI_COMMAND, &tp->pci_cfg_space.cmd); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &tp->pci_cfg_space.io_base_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0 + 2, &tp->pci_cfg_space.io_base_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &tp->pci_cfg_space.mem_base_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &tp->pci_cfg_space.mem_base_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3, &tp->pci_cfg_space.resv_0x1c_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, &tp->pci_cfg_space.resv_0x1c_h); + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tp->pci_cfg_space.ilr); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &tp->pci_cfg_space.resv_0x20_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &tp->pci_cfg_space.resv_0x20_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &tp->pci_cfg_space.resv_0x24_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &tp->pci_cfg_space.resv_0x24_h); + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &tp->pci_cfg_space.resv_0x2c_l); + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, &tp->pci_cfg_space.resv_0x2c_h); + if (tp->HwPcieSNOffset > 0) { + tp->pci_cfg_space.pci_sn_l = rtl8126_csi_read(tp, tp->HwPcieSNOffset); + tp->pci_cfg_space.pci_sn_h = rtl8126_csi_read(tp, tp->HwPcieSNOffset + 4); + } + + tp->pci_cfg_is_read = 1; + } + + /* Set Rx packet filter */ + rtl8126_hw_set_rx_packet_filter(dev); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH && !tp->dash_printer_enabled) + NICChkTypeEnableDashInterrupt(tp); +#endif + + switch (tp->mcfg) { + case CFG_METHOD_1: + case CFG_METHOD_2: + case CFG_METHOD_3: + rtl8126_enable_aspm_clkreq_lock(tp, aspm ? 1 : 0); + break; + } + + rtl8126_disable_cfg9346_write(tp); + + udelay(10); +} + +void +rtl8126_hw_start(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + +#ifdef ENABLE_LIB_SUPPORT + rtl8126_init_lib_ring(tp); +#endif + + RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); + + rtl8126_enable_hw_interrupt(tp); + + rtl8126_lib_reset_complete(tp); +} + +static int +rtl8126_change_mtu(struct net_device *dev, + int new_mtu) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + if (new_mtu < ETH_MIN_MTU) + return -EINVAL; + else if (new_mtu > tp->max_jumbo_frame_size) + new_mtu = tp->max_jumbo_frame_size; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + + dev->mtu = new_mtu; + + tp->eee.tx_lpi_timer = dev->mtu + ETH_HLEN + 0x20; + + if (!netif_running(dev)) + goto out; + + rtl8126_down(dev); + + rtl8126_set_rxbufsize(tp, dev); + + ret = rtl8126_init_ring(dev); + + if (ret < 0) + goto err_out; + +#ifdef CONFIG_R8126_NAPI + rtl8126_enable_napi(tp); +#endif//CONFIG_R8126_NAPI + + if (tp->link_ok(dev)) + rtl8126_link_on_patch(dev); + else + rtl8126_link_down_patch(dev); + + //mod_timer(&tp->esd_timer, jiffies + RTL8126_ESD_TIMEOUT); + //mod_timer(&tp->link_timer, jiffies + RTL8126_LINK_TIMEOUT); +out: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + netdev_update_features(dev); +#endif + +err_out: + return ret; +} + +static inline void +rtl8126_set_desc_dma_addr(struct rtl8126_private *tp, + struct RxDesc *desc, + dma_addr_t mapping) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + ((struct RxDescV3 *)desc)->addr = cpu_to_le64(mapping); + else + desc->addr = cpu_to_le64(mapping); +} + +static inline void +rtl8126_mark_to_asic_v3(struct RxDescV3 *descv3, + u32 rx_buf_sz) +{ + u32 eor = le32_to_cpu(descv3->RxDescNormalDDWord4.opts1) & RingEnd; + + WRITE_ONCE(descv3->RxDescNormalDDWord4.opts1, cpu_to_le32(DescOwn | eor | rx_buf_sz)); +} + +void +rtl8126_mark_to_asic(struct rtl8126_private *tp, + struct RxDesc *desc, + u32 rx_buf_sz) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8126_mark_to_asic_v3((struct RxDescV3 *)desc, rx_buf_sz); + else { + u32 eor = le32_to_cpu(desc->opts1) & RingEnd; + + WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | rx_buf_sz)); + } +} + +static inline void +rtl8126_map_to_asic(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct RxDesc *desc, + dma_addr_t mapping, + u32 rx_buf_sz, + const u32 cur_rx) +{ + ring->RxDescPhyAddr[cur_rx] = mapping; + rtl8126_set_desc_dma_addr(tp, desc, mapping); + wmb(); + rtl8126_mark_to_asic(tp, desc, rx_buf_sz); +} + +#ifdef ENABLE_PAGE_REUSE + +static int +rtl8126_alloc_rx_page(struct rtl8126_private *tp, struct rtl8126_rx_ring *ring, + struct rtl8126_rx_buffer *rxb) +{ + struct page *page; + dma_addr_t dma; + unsigned int order = tp->rx_buf_page_order; + + //get free page + page = dev_alloc_pages(order); + + if (unlikely(!page)) + return -ENOMEM; + + dma = dma_map_page_attrs(&tp->pci_dev->dev, page, 0, + tp->rx_buf_page_size, + DMA_FROM_DEVICE, + (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)); + + if (unlikely(dma_mapping_error(&tp->pci_dev->dev, dma))) { + __free_pages(page, order); + return -ENOMEM; + } + + rxb->page = page; + rxb->data = page_address(page); + rxb->page_offset = ring->rx_offset; + rxb->dma = dma; + + //after page alloc, page refcount already = 1 + + return 0; +} + +static void +rtl8126_free_rx_page(struct rtl8126_private *tp, struct rtl8126_rx_buffer *rxb) +{ + if (!rxb->page) + return; + + dma_unmap_page_attrs(&tp->pci_dev->dev, rxb->dma, + tp->rx_buf_page_size, + DMA_FROM_DEVICE, + (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)); + __free_pages(rxb->page, tp->rx_buf_page_order); + rxb->page = NULL; +} + +static void +_rtl8126_rx_clear(struct rtl8126_private *tp, struct rtl8126_rx_ring *ring) +{ + int i; + struct rtl8126_rx_buffer *rxb; + + for (i = 0; i < ring->num_rx_desc; i++) { + rxb = &ring->rx_buffer[i]; + if (rxb->skb) { + dev_kfree_skb(rxb->skb); + rxb->skb = NULL; + } + rtl8126_free_rx_page(tp, rxb); + } +} + +static u32 +rtl8126_rx_fill(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct net_device *dev, + u32 start, + u32 end, + u8 in_intr) +{ + u32 cur; + struct rtl8126_rx_buffer *rxb; + + for (cur = start; end - cur > 0; cur++) { + int ret, i = cur % ring->num_rx_desc; + + rxb = &ring->rx_buffer[i]; + if (rxb->page) + continue; + + ret = rtl8126_alloc_rx_page(tp, ring, rxb); + if (ret) + break; + + dma_sync_single_range_for_device(tp_to_dev(tp), + rxb->dma, + rxb->page_offset, + tp->rx_buf_sz, + DMA_FROM_DEVICE); + + rtl8126_map_to_asic(tp, ring, + rtl8126_get_rxdesc(tp, ring->RxDescArray, i), + rxb->dma + rxb->page_offset, + tp->rx_buf_sz, i); + } + return cur - start; +} + +#else //ENABLE_PAGE_REUSE + +static void +rtl8126_free_rx_skb(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct sk_buff **sk_buff, + struct RxDesc *desc, + const u32 cur_rx) +{ + struct pci_dev *pdev = tp->pci_dev; + + dma_unmap_single(&pdev->dev, ring->RxDescPhyAddr[cur_rx], tp->rx_buf_sz, + DMA_FROM_DEVICE); + dev_kfree_skb(*sk_buff); + *sk_buff = NULL; + rtl8126_make_unusable_by_asic(tp, desc); +} + +static int +rtl8126_alloc_rx_skb(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct sk_buff **sk_buff, + struct RxDesc *desc, + int rx_buf_sz, + const u32 cur_rx, + u8 in_intr) +{ + struct sk_buff *skb; + dma_addr_t mapping; + int ret = 0; + + if (in_intr) + skb = RTL_ALLOC_SKB_INTR(&tp->r8126napi[ring->index].napi, rx_buf_sz + R8126_RX_ALIGN); + else + skb = dev_alloc_skb(rx_buf_sz + R8126_RX_ALIGN); + + if (unlikely(!skb)) + goto err_out; + + if (!in_intr || !R8126_USE_NAPI_ALLOC_SKB) + skb_reserve(skb, R8126_RX_ALIGN); + + mapping = dma_map_single(tp_to_dev(tp), skb->data, rx_buf_sz, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n"); + goto err_out; + } + + *sk_buff = skb; + rtl8126_map_to_asic(tp, ring, desc, mapping, rx_buf_sz, cur_rx); +out: + return ret; + +err_out: + if (skb) + dev_kfree_skb(skb); + ret = -ENOMEM; + rtl8126_make_unusable_by_asic(tp, desc); + goto out; +} + +static void +_rtl8126_rx_clear(struct rtl8126_private *tp, struct rtl8126_rx_ring *ring) +{ + int i; + + for (i = 0; i < ring->num_rx_desc; i++) { + if (ring->Rx_skbuff[i]) { + rtl8126_free_rx_skb(tp, + ring, + ring->Rx_skbuff + i, + rtl8126_get_rxdesc(tp, ring->RxDescArray, i), + i); + ring->Rx_skbuff[i] = NULL; + } + } +} + +static u32 +rtl8126_rx_fill(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct net_device *dev, + u32 start, + u32 end, + u8 in_intr) +{ + u32 cur; + + for (cur = start; end - cur > 0; cur++) { + int ret, i = cur % ring->num_rx_desc; + + if (ring->Rx_skbuff[i]) + continue; + + ret = rtl8126_alloc_rx_skb(tp, + ring, + ring->Rx_skbuff + i, + rtl8126_get_rxdesc(tp, ring->RxDescArray, i), + tp->rx_buf_sz, + i, + in_intr); + if (ret < 0) + break; + } + return cur - start; +} + +#endif //ENABLE_PAGE_REUSE + +void +rtl8126_rx_clear(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + + _rtl8126_rx_clear(tp, ring); + } +} + +static inline void +rtl8126_mark_as_last_descriptor_8125(struct RxDescV3 *descv3) +{ + descv3->RxDescNormalDDWord4.opts1 |= cpu_to_le32(RingEnd); +} + +static inline void +rtl8126_mark_as_last_descriptor(struct rtl8126_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8126_mark_as_last_descriptor_8125((struct RxDescV3 *)desc); + else + desc->opts1 |= cpu_to_le32(RingEnd); +} + +static void +rtl8126_desc_addr_fill(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + RTL_W32(tp, ring->tdsar_reg, ((u64)ring->TxPhyAddr & DMA_BIT_MASK(32))); + RTL_W32(tp, ring->tdsar_reg + 4, ((u64)ring->TxPhyAddr >> 32)); + } + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + RTL_W32(tp, ring->rdsar_reg, ((u64)ring->RxPhyAddr & DMA_BIT_MASK(32))); + RTL_W32(tp, ring->rdsar_reg + 4, ((u64)ring->RxPhyAddr >> 32)); + } +} + +static void +rtl8126_tx_desc_init(struct rtl8126_private *tp) +{ + int i = 0; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + memset(ring->TxDescArray, 0x0, ring->TxDescAllocSize); + + ring->TxDescArray[ring->num_tx_desc - 1].opts1 = cpu_to_le32(RingEnd); + } +} + +static void +rtl8126_rx_desc_init(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; + memset(ring->RxDescArray, 0x0, ring->RxDescAllocSize); + } +} + +int +rtl8126_init_ring(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + + rtl8126_init_ring_indexes(tp); + + rtl8126_tx_desc_init(tp); + rtl8126_rx_desc_init(tp); + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + memset(ring->tx_skb, 0x0, sizeof(ring->tx_skb)); + } + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring = &tp->rx_ring[i]; +#ifdef ENABLE_PAGE_REUSE + ring->rx_offset = R8126_RX_ALIGN; +#else + memset(ring->Rx_skbuff, 0x0, sizeof(ring->Rx_skbuff)); +#endif //ENABLE_PAGE_REUSE + if (rtl8126_rx_fill(tp, ring, dev, 0, ring->num_rx_desc, 0) != ring->num_rx_desc) + goto err_out; + + rtl8126_mark_as_last_descriptor(tp, rtl8126_get_rxdesc(tp, ring->RxDescArray, ring->num_rx_desc - 1)); + } + + return 0; + +err_out: + rtl8126_rx_clear(tp); + return -ENOMEM; +} + +static void +rtl8126_unmap_tx_skb(struct pci_dev *pdev, + struct ring_info *tx_skb, + struct TxDesc *desc) +{ + unsigned int len = tx_skb->len; + + dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE); + + desc->opts1 = cpu_to_le32(RTK_MAGIC_DEBUG_VALUE); + desc->opts2 = 0x00; + desc->addr = RTL8126_MAGIC_NUMBER; + tx_skb->len = 0; +} + +static void +rtl8126_tx_clear_range(struct rtl8126_private *tp, + struct rtl8126_tx_ring *ring, + u32 start, + unsigned int n) +{ + unsigned int i; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct net_device *dev = tp->dev; +#endif + + for (i = 0; i < n; i++) { + unsigned int entry = (start + i) % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; + unsigned int len = tx_skb->len; + + if (len) { + struct sk_buff *skb = tx_skb->skb; + + rtl8126_unmap_tx_skb(tp->pci_dev, tx_skb, + ring->TxDescArray + entry); + if (skb) { + RTLDEV->stats.tx_dropped++; + dev_kfree_skb_any(skb); + tx_skb->skb = NULL; + } + } + } +} + +void +rtl8126_tx_clear(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8126_tx_ring *ring = &tp->tx_ring[i]; + rtl8126_tx_clear_range(tp, ring, ring->dirty_tx, ring->num_tx_desc); + ring->cur_tx = ring->dirty_tx = 0; + } +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8126_schedule_reset_work(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8126_FLAG_TASK_RESET_PENDING, tp->task_flags); + schedule_delayed_work(&tp->reset_task, 4); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +static void rtl8126_schedule_esd_work(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8126_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->esd_task, RTL8126_ESD_TIMEOUT); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +static void rtl8126_schedule_linkchg_work(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8126_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->linkchg_task, 4); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +#define rtl8126_cancel_schedule_reset_work(a) +#define rtl8126_cancel_schedule_esd_work(a) +#define rtl8126_cancel_schedule_linkchg_work(a) + +#else +static void rtl8126_schedule_reset_work(struct rtl8126_private *tp) +{ + set_bit(R8126_FLAG_TASK_RESET_PENDING, tp->task_flags); + schedule_delayed_work(&tp->reset_task, 4); +} + +static void rtl8126_cancel_schedule_reset_work(struct rtl8126_private *tp) +{ + struct work_struct *work = &tp->reset_task.work; + + if (!work->func) + return; + + cancel_delayed_work_sync(&tp->reset_task); +} + +static void rtl8126_schedule_esd_work(struct rtl8126_private *tp) +{ + set_bit(R8126_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->esd_task, RTL8126_ESD_TIMEOUT); +} + +static void rtl8126_cancel_schedule_esd_work(struct rtl8126_private *tp) +{ + struct work_struct *work = &tp->esd_task.work; + + if (!work->func) + return; + + cancel_delayed_work_sync(&tp->esd_task); +} + +static void rtl8126_schedule_linkchg_work(struct rtl8126_private *tp) +{ + set_bit(R8126_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->linkchg_task, 4); +} + +static void rtl8126_cancel_schedule_linkchg_work(struct rtl8126_private *tp) +{ + struct work_struct *work = &tp->linkchg_task.work; + + if (!work->func) + return; + + cancel_delayed_work_sync(&tp->linkchg_task); +} +#endif + +static void rtl8126_init_all_schedule_work(struct rtl8126_private *tp) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + INIT_WORK(&tp->reset_task, rtl8126_reset_task, dev); + INIT_WORK(&tp->esd_task, rtl8126_esd_task, dev); + INIT_WORK(&tp->linkchg_task, rtl8126_linkchg_task, dev); +#else + INIT_DELAYED_WORK(&tp->reset_task, rtl8126_reset_task); + INIT_DELAYED_WORK(&tp->esd_task, rtl8126_esd_task); + INIT_DELAYED_WORK(&tp->linkchg_task, rtl8126_linkchg_task); +#endif +} + +static void rtl8126_cancel_all_schedule_work(struct rtl8126_private *tp) +{ + rtl8126_cancel_schedule_reset_work(tp); + rtl8126_cancel_schedule_esd_work(tp); + rtl8126_cancel_schedule_linkchg_work(tp); +} + +static void +rtl8126_wait_for_irq_complete(struct rtl8126_private *tp) +{ + if (tp->features & RTL_FEATURE_MSIX) { + int i; + for (i = 0; i < tp->irq_nvecs; i++) + synchronize_irq(tp->irq_tbl[i].vector); + } else { + synchronize_irq(tp->dev->irq); + } +} + +void +_rtl8126_wait_for_quiescence(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + /* Wait for any pending NAPI task to complete */ +#ifdef CONFIG_R8126_NAPI + rtl8126_disable_napi(tp); +#endif//CONFIG_R8126_NAPI + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,67) + /* Give a racing hard_start_xmit a few cycles to complete. */ + synchronize_net(); +#endif + + rtl8126_irq_mask_and_ack(tp); + + rtl8126_wait_for_irq_complete(tp); +} + +static void +rtl8126_wait_for_quiescence(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + //suppress unused variable + (void)(tp); + + _rtl8126_wait_for_quiescence(dev); + +#ifdef CONFIG_R8126_NAPI + rtl8126_enable_napi(tp); +#endif//CONFIG_R8126_NAPI +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8126_reset_task(void *_data) +{ + struct net_device *dev = _data; + struct rtl8126_private *tp = netdev_priv(dev); +#else +static void rtl8126_reset_task(struct work_struct *work) +{ + struct rtl8126_private *tp = + container_of(work, struct rtl8126_private, reset_task.work); + struct net_device *dev = tp->dev; +#endif + int i; + + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8126_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8126_FLAG_TASK_RESET_PENDING, tp->task_flags)) + goto out_unlock; + + netdev_err(dev, "Device reseting!\n"); + + netif_carrier_off(dev); + netif_tx_disable(dev); + _rtl8126_wait_for_quiescence(dev); + rtl8126_hw_reset(dev); + + rtl8126_tx_clear(tp); + + rtl8126_init_ring_indexes(tp); + + rtl8126_tx_desc_init(tp); + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8126_rx_ring *ring; + u32 entry; + + ring = &tp->rx_ring[i]; + for (entry = 0; entry < ring->num_rx_desc; entry++) { + struct RxDesc *desc; + + desc = rtl8126_get_rxdesc(tp, ring->RxDescArray, entry); + rtl8126_mark_to_asic(tp, desc, tp->rx_buf_sz); + } + } + +#ifdef ENABLE_PTP_SUPPORT + rtl8126_ptp_reset(tp); +#endif + +#ifdef CONFIG_R8126_NAPI + rtl8126_enable_napi(tp); +#endif //CONFIG_R8126_NAPI + + if (tp->resume_not_chg_speed) { + _rtl8126_check_link_status(dev); + + tp->resume_not_chg_speed = 0; + } else { + rtl8126_enable_hw_linkchg_interrupt(tp); + + rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + } + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8126_esd_task(void *_data) +{ + struct net_device *dev = _data; + struct rtl8126_private *tp = netdev_priv(dev); +#else +static void rtl8126_esd_task(struct work_struct *work) +{ + struct rtl8126_private *tp = + container_of(work, struct rtl8126_private, esd_task.work); + struct net_device *dev = tp->dev; +#endif + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8126_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8126_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags)) + goto out_unlock; + + rtl8126_esd_checker(tp); + + rtl8126_schedule_esd_work(tp); + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8126_linkchg_task(void *_data) +{ + struct net_device *dev = _data; + //struct rtl8126_private *tp = netdev_priv(dev); +#else +static void rtl8126_linkchg_task(struct work_struct *work) +{ + struct rtl8126_private *tp = + container_of(work, struct rtl8126_private, linkchg_task.work); + struct net_device *dev = tp->dev; +#endif + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8126_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8126_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags)) + goto out_unlock; + + rtl8126_check_link_status(dev); + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static void +rtl8126_tx_timeout(struct net_device *dev, unsigned int txqueue) +#else +static void +rtl8126_tx_timeout(struct net_device *dev) +#endif +{ + struct rtl8126_private *tp = netdev_priv(dev); + + netdev_err(dev, "Transmit timeout reset Device!\n"); + + /* Let's wait a bit while any (async) irq lands on */ + rtl8126_schedule_reset_work(tp); +} + +static u32 +rtl8126_get_txd_opts1(struct rtl8126_tx_ring *ring, + u32 opts1, + u32 len, + unsigned int entry) +{ + u32 status = opts1 | len; + + if (entry == ring->num_tx_desc - 1) + status |= RingEnd; + + return status; +} + +static int +rtl8126_xmit_frags(struct rtl8126_private *tp, + struct rtl8126_tx_ring *ring, + struct sk_buff *skb, + const u32 *opts) +{ + struct skb_shared_info *info = skb_shinfo(skb); + unsigned int cur_frag, entry; + struct TxDesc *txd = NULL; + const unsigned char nr_frags = info->nr_frags; + unsigned long PktLenCnt = 0; + bool LsoPatchEnabled = FALSE; + + entry = ring->cur_tx; + for (cur_frag = 0; cur_frag < nr_frags; cur_frag++) { + skb_frag_t *frag = info->frags + cur_frag; + dma_addr_t mapping; + u32 status, len; + void *addr; + + entry = (entry + 1) % ring->num_tx_desc; + + txd = ring->TxDescArray + entry; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) + len = frag->size; + addr = ((void *) page_address(frag->page)) + frag->page_offset; +#else + len = skb_frag_size(frag); + addr = skb_frag_address(frag); +#endif + mapping = dma_map_single(tp_to_dev(tp), addr, len, DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, tp->dev, + "Failed to map TX fragments DMA!\n"); + goto err_out; + } + + /* anti gcc 2.95.3 bugware (sic) */ + status = rtl8126_get_txd_opts1(ring, opts[0], len, entry); + if (cur_frag == (nr_frags - 1) || LsoPatchEnabled == TRUE) + status |= LastFrag; + + txd->addr = cpu_to_le64(mapping); + + ring->tx_skb[entry].len = len; + + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); + txd->opts1 = cpu_to_le32(status); + + PktLenCnt += len; + } + + return cur_frag; + +err_out: + rtl8126_tx_clear_range(tp, ring, ring->cur_tx + 1, cur_frag); + return -EIO; +} + +static inline +__be16 get_protocol(struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) + return vlan_get_protocol(skb); +#else + __be16 protocol; + + if (skb->protocol == htons(ETH_P_8021Q)) + protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + return protocol; +#endif +} + +static inline +u8 rtl8126_get_l4_protocol(struct sk_buff *skb) +{ + int no = skb_network_offset(skb); + struct ipv6hdr *i6h, _i6h; + struct iphdr *ih, _ih; + u8 ip_protocol = IPPROTO_RAW; + + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih); + if (ih) + ip_protocol = ih->protocol; + break; + case __constant_htons(ETH_P_IPV6): + i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h); + if (i6h) + ip_protocol = i6h->nexthdr; + break; + } + + return ip_protocol; +} + +static bool rtl8126_skb_pad_with_len(struct sk_buff *skb, unsigned int len) +{ + if (skb_padto(skb, len)) + return false; + skb_put(skb, len - skb->len); + return true; +} + +static bool rtl8126_skb_pad(struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) + return rtl8126_skb_pad_with_len(skb, ETH_ZLEN); +#else + return !eth_skb_pad(skb); +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +/* msdn_giant_send_check() + * According to the document of microsoft, the TCP Pseudo Header excludes the + * packet length for IPv6 TCP large packets. + */ +static int msdn_giant_send_check(struct sk_buff *skb) +{ + const struct ipv6hdr *ipv6h; + struct tcphdr *th; + int ret; + + ret = skb_cow_head(skb, 0); + if (ret) + return ret; + + ipv6h = ipv6_hdr(skb); + th = tcp_hdr(skb); + + th->check = 0; + th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0); + + return ret; +} +#endif + +static bool rtl8126_require_pad_ptp_pkt(struct rtl8126_private *tp) +{ + switch (tp->mcfg) { + default: + return false; + } +} + +#define MIN_PATCH_LEN (47) +static u32 +rtl8126_get_patch_pad_len(struct rtl8126_private *tp, + struct sk_buff *skb) +{ + u32 pad_len = 0; + int trans_data_len; + u32 hdr_len; + u32 pkt_len = skb->len; + u8 ip_protocol; + bool has_trans = skb_transport_header_was_set(skb); + + if (!rtl8126_require_pad_ptp_pkt(tp)) + goto no_padding; + + if (!(has_trans && (pkt_len < 175))) //128 + MIN_PATCH_LEN + goto no_padding; + + ip_protocol = rtl8126_get_l4_protocol(skb); + if (!(ip_protocol == IPPROTO_TCP || ip_protocol == IPPROTO_UDP)) + goto no_padding; + + trans_data_len = pkt_len - + (skb->transport_header - + skb_headroom(skb)); + if (ip_protocol == IPPROTO_UDP) { + if (trans_data_len > 3 && trans_data_len < MIN_PATCH_LEN) { + u16 dest_port = 0; + + skb_copy_bits(skb, skb->transport_header - skb_headroom(skb) + 2, &dest_port, 2); + dest_port = ntohs(dest_port); + + if (dest_port == 0x13f || + dest_port == 0x140) { + pad_len = MIN_PATCH_LEN - trans_data_len; + goto out; + } + } + } + + hdr_len = 0; + if (ip_protocol == IPPROTO_TCP) + hdr_len = 20; + else if (ip_protocol == IPPROTO_UDP) + hdr_len = 8; + if (trans_data_len < hdr_len) + pad_len = hdr_len - trans_data_len; + +out: + if ((pkt_len + pad_len) < ETH_ZLEN) + pad_len = ETH_ZLEN - pkt_len; + + return pad_len; + +no_padding: + + return 0; +} + +static bool +rtl8126_tso_csum(struct sk_buff *skb, + struct net_device *dev, + u32 *opts, + unsigned int *bytecount, + unsigned short *gso_segs) +{ + struct rtl8126_private *tp = netdev_priv(dev); + unsigned long large_send = 0; + u32 csum_cmd = 0; + u8 sw_calc_csum = false; + u8 check_patch_required = true; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + u32 mss = skb_shinfo(skb)->tso_size; +#else + u32 mss = skb_shinfo(skb)->gso_size; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + + /* TCP Segmentation Offload (or TCP Large Send) */ + if (mss) { + union { + struct iphdr *v4; + struct ipv6hdr *v6; + unsigned char *hdr; + } ip; + union { + struct tcphdr *tcp; + struct udphdr *udp; + unsigned char *hdr; + } l4; + u32 l4_offset, hdr_len; + + ip.hdr = skb_network_header(skb); + l4.hdr = skb_checksum_start(skb); + + l4_offset = skb_transport_offset(skb); + assert((l4_offset%2) == 0); + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + if (l4_offset <= GTTCPHO_MAX) { + opts[0] |= GiantSendv4; + opts[0] |= l4_offset << GTTCPHO_SHIFT; + opts[1] |= min(mss, MSS_MAX) << 18; + large_send = 1; + } + break; + case __constant_htons(ETH_P_IPV6): +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) + if (msdn_giant_send_check(skb)) + return false; +#endif + if (l4_offset <= GTTCPHO_MAX) { + opts[0] |= GiantSendv6; + opts[0] |= l4_offset << GTTCPHO_SHIFT; + opts[1] |= min(mss, MSS_MAX) << 18; + large_send = 1; + } + break; + default: + if (unlikely(net_ratelimit())) + dprintk("tso proto=%x!\n", skb->protocol); + break; + } + + if (large_send == 0) + return false; + + + /* compute length of segmentation header */ + hdr_len = (l4.tcp->doff * 4) + l4_offset; + /* update gso size and bytecount with header size */ + *gso_segs = skb_shinfo(skb)->gso_segs; + *bytecount += (*gso_segs - 1) * hdr_len; + + return true; + } + } +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + if (skb->ip_summed == CHECKSUM_PARTIAL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + const struct iphdr *ip = skb->nh.iph; + + if (dev->features & NETIF_F_IP_CSUM) { + if (ip->protocol == IPPROTO_TCP) + csum_cmd = tp->tx_ip_csum_cmd | tp->tx_tcp_csum_cmd; + else if (ip->protocol == IPPROTO_UDP) + csum_cmd = tp->tx_ip_csum_cmd | tp->tx_udp_csum_cmd; + else if (ip->protocol == IPPROTO_IP) + csum_cmd = tp->tx_ip_csum_cmd; + } +#else + u8 ip_protocol = IPPROTO_RAW; + + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + if (dev->features & NETIF_F_IP_CSUM) { + ip_protocol = ip_hdr(skb)->protocol; + csum_cmd = tp->tx_ip_csum_cmd; + } + break; + case __constant_htons(ETH_P_IPV6): + if (dev->features & NETIF_F_IPV6_CSUM) { + if (skb_transport_offset(skb) > 0 && skb_transport_offset(skb) <= TCPHO_MAX) { + ip_protocol = ipv6_hdr(skb)->nexthdr; + csum_cmd = tp->tx_ipv6_csum_cmd; + csum_cmd |= skb_transport_offset(skb) << TCPHO_SHIFT; + } + } + break; + default: + if (unlikely(net_ratelimit())) + dprintk("checksum_partial proto=%x!\n", skb->protocol); + break; + } + + if (ip_protocol == IPPROTO_TCP) + csum_cmd |= tp->tx_tcp_csum_cmd; + else if (ip_protocol == IPPROTO_UDP) + csum_cmd |= tp->tx_udp_csum_cmd; +#endif + if (csum_cmd == 0) { + sw_calc_csum = true; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + WARN_ON(1); /* we need a WARN() */ +#endif + } + + if (ip_protocol == IPPROTO_TCP) + check_patch_required = false; + } + + if (check_patch_required) { + u32 pad_len = rtl8126_get_patch_pad_len(tp, skb); + + if (pad_len > 0) { + if (!rtl8126_skb_pad_with_len(skb, skb->len + pad_len)) + return false; + + if (csum_cmd != 0) + sw_calc_csum = true; + } + } + + if (skb->len < ETH_ZLEN) { + if (tp->UseSwPaddingShortPkt || + (tp->ShortPacketSwChecksum && csum_cmd != 0)) { + if (!rtl8126_skb_pad(skb)) + return false; + + if (csum_cmd != 0) + sw_calc_csum = true; + } + } + + if (sw_calc_csum) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) + skb_checksum_help(&skb, 0); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + skb_checksum_help(skb, 0); +#else + skb_checksum_help(skb); +#endif + } else + opts[1] |= csum_cmd; + + return true; +} + +static bool rtl8126_tx_slots_avail(struct rtl8126_private *tp, + struct rtl8126_tx_ring *ring) +{ + unsigned int slots_avail = READ_ONCE(ring->dirty_tx) + ring->num_tx_desc + - READ_ONCE(ring->cur_tx); + + /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ + return slots_avail > MAX_SKB_FRAGS; +} + +static inline u32 +rtl8126_fast_mod_mask(const u32 input, const u32 mask) +{ + return input > mask ? input & mask : input; +} + +static void rtl8126_doorbell(struct rtl8126_private *tp, + struct rtl8126_tx_ring *ring) +{ + if (tp->EnableTxNoClose) { + if (tp->HwSuppTxNoCloseVer > 3) + RTL_W32(tp, ring->sw_tail_ptr_reg, ring->cur_tx); + else + RTL_W16(tp, ring->sw_tail_ptr_reg, ring->cur_tx); + } else + RTL_W16(tp, TPPOLL_8125, BIT(ring->index)); /* set polling bit */ +} + +static netdev_tx_t +rtl8126_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + unsigned int bytecount; + unsigned short gso_segs; + struct ring_info *last; + unsigned int last_entry; + unsigned int entry; + struct TxDesc *txd; + dma_addr_t mapping; + u32 len; + u32 opts[2]; + netdev_tx_t ret = NETDEV_TX_OK; + int frags; + u8 EnableTxNoClose = tp->EnableTxNoClose; + const u16 queue_mapping = skb_get_queue_mapping(skb); + struct rtl8126_tx_ring *ring; + bool stop_queue; + + assert(queue_mapping < tp->num_tx_rings); + + ring = &tp->tx_ring[queue_mapping]; + + if (unlikely(!rtl8126_tx_slots_avail(tp, ring))) { + if (netif_msg_drv(tp)) { + printk(KERN_ERR + "%s: BUG! Tx Ring[%d] full when queue awake!\n", + dev->name, + queue_mapping); + } + goto err_stop; + } + + entry = ring->cur_tx % ring->num_tx_desc; + txd = ring->TxDescArray + entry; + + if (!EnableTxNoClose) { + if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) { + if (netif_msg_drv(tp)) { + printk(KERN_ERR + "%s: BUG! Tx Desc is own by hardware!\n", + dev->name); + } + goto err_stop; + } + } + + bytecount = skb->len; + gso_segs = 1; + + opts[0] = DescOwn; + opts[1] = rtl8126_tx_vlan_tag(tp, skb); + + if (unlikely(!rtl8126_tso_csum(skb, dev, opts, &bytecount, &gso_segs))) + goto err_dma_0; + + frags = rtl8126_xmit_frags(tp, ring, skb, opts); + if (unlikely(frags < 0)) + goto err_dma_0; + if (frags) { + len = skb_headlen(skb); + opts[0] |= FirstFrag; + } else { + len = skb->len; + opts[0] |= FirstFrag | LastFrag; + } + + opts[0] = rtl8126_get_txd_opts1(ring, opts[0], len, entry); + mapping = dma_map_single(tp_to_dev(tp), skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, dev, "Failed to map TX DMA!\n"); + goto err_dma_1; + } + +#ifdef ENABLE_PTP_SUPPORT + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + if (!test_and_set_bit_lock(__RTL8126_PTP_TX_IN_PROGRESS, &tp->state)) { + if (tp->hwtstamp_config.tx_type == HWTSTAMP_TX_ON && + !tp->ptp_tx_skb) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + tp->ptp_tx_skb = skb_get(skb); + tp->ptp_tx_start = jiffies; + schedule_work(&tp->ptp_tx_work); + } else + tp->tx_hwtstamp_skipped++; + } + } +#endif + /* set first fragment's length */ + ring->tx_skb[entry].len = len; + + /* set skb to last fragment */ + last_entry = (entry + frags) % ring->num_tx_desc; + last = &ring->tx_skb[last_entry]; + last->skb = skb; + last->gso_segs = gso_segs; + last->bytecount = bytecount; + + txd->addr = cpu_to_le64(mapping); + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); + txd->opts1 = cpu_to_le32(opts[0]); + + netdev_tx_sent_queue(txring_txq(ring), bytecount); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + dev->trans_start = jiffies; +#else + skb_tx_timestamp(skb); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + + /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */ + smp_wmb(); + + WRITE_ONCE(ring->cur_tx, ring->cur_tx + frags + 1); + + stop_queue = !rtl8126_tx_slots_avail(tp, ring); + if (unlikely(stop_queue)) { + /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must + * not miss a ring update when it notices a stopped queue. + */ + smp_wmb(); + netif_stop_subqueue(dev, queue_mapping); + } + + if (netif_xmit_stopped(txring_txq(ring)) || !netdev_xmit_more()) + rtl8126_doorbell(tp, ring); + + if (unlikely(stop_queue)) { + /* Sync with rtl_tx: + * - publish queue status and cur_tx ring index (write barrier) + * - refresh dirty_tx ring index (read barrier). + * May the current thread have a pessimistic view of the ring + * status and forget to wake up queue, a racing rtl_tx thread + * can't. + */ + smp_mb(); + if (rtl8126_tx_slots_avail(tp, ring)) + netif_start_subqueue(dev, queue_mapping); + } +out: + return ret; +err_dma_1: + rtl8126_tx_clear_range(tp, ring, ring->cur_tx + 1, frags); +err_dma_0: + RTLDEV->stats.tx_dropped++; + dev_kfree_skb_any(skb); + ret = NETDEV_TX_OK; + goto out; +err_stop: + netif_stop_subqueue(dev, queue_mapping); + ret = NETDEV_TX_BUSY; + RTLDEV->stats.tx_dropped++; + goto out; +} + +/* recycle tx no close desc*/ +static int +rtl8126_tx_interrupt_noclose(struct rtl8126_tx_ring *ring, int budget) +{ + unsigned int total_bytes = 0, total_packets = 0; + struct rtl8126_private *tp = ring->priv; + struct net_device *dev = tp->dev; + unsigned int dirty_tx, tx_left; + unsigned int tx_desc_closed; + unsigned int count = 0; + + dirty_tx = ring->dirty_tx; + ring->NextHwDesCloPtr = rtl8126_get_hw_clo_ptr(ring); + tx_desc_closed = rtl8126_fast_mod_mask(ring->NextHwDesCloPtr - + ring->BeginHwDesCloPtr, + tp->MaxTxDescPtrMask); + tx_left = min((READ_ONCE(ring->cur_tx) - dirty_tx), tx_desc_closed); + ring->BeginHwDesCloPtr += tx_left; + + while (tx_left > 0) { + unsigned int entry = dirty_tx % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; + + rtl8126_unmap_tx_skb(tp->pci_dev, + tx_skb, + ring->TxDescArray + entry); + + if (tx_skb->skb != NULL) { + /* update the statistics for this packet */ + total_bytes += tx_skb->bytecount; + total_packets += tx_skb->gso_segs; + + RTL_NAPI_CONSUME_SKB_ANY(tx_skb->skb, budget); + tx_skb->skb = NULL; + } + dirty_tx++; + tx_left--; + } + + if (total_packets) { + netdev_tx_completed_queue(txring_txq(ring), + total_packets, total_bytes); + + RTLDEV->stats.tx_bytes += total_bytes; + RTLDEV->stats.tx_packets+= total_packets; + } + + if (ring->dirty_tx != dirty_tx) { + count = dirty_tx - ring->dirty_tx; + WRITE_ONCE(ring->dirty_tx, dirty_tx); + smp_wmb(); + if (__netif_subqueue_stopped(dev, ring->index) && + (rtl8126_tx_slots_avail(tp, ring))) { + netif_start_subqueue(dev, ring->index); + } + } + + return count; +} + +/* recycle tx close desc*/ +static int +rtl8126_tx_interrupt_close(struct rtl8126_tx_ring *ring, int budget) +{ + unsigned int total_bytes = 0, total_packets = 0; + struct rtl8126_private *tp = ring->priv; + struct net_device *dev = tp->dev; + unsigned int dirty_tx, tx_left; + unsigned int count = 0; + + dirty_tx = ring->dirty_tx; + tx_left = READ_ONCE(ring->cur_tx) - dirty_tx; + + while (tx_left > 0) { + unsigned int entry = dirty_tx % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; + + if (le32_to_cpu(ring->TxDescArray[entry].opts1) & DescOwn) + break; + + rtl8126_unmap_tx_skb(tp->pci_dev, + tx_skb, + ring->TxDescArray + entry); + + if (tx_skb->skb != NULL) { + /* update the statistics for this packet */ + total_bytes += tx_skb->bytecount; + total_packets += tx_skb->gso_segs; + + RTL_NAPI_CONSUME_SKB_ANY(tx_skb->skb, budget); + tx_skb->skb = NULL; + } + dirty_tx++; + tx_left--; + } + + if (total_packets) { + netdev_tx_completed_queue(txring_txq(ring), + total_packets, total_bytes); + + RTLDEV->stats.tx_bytes += total_bytes; + RTLDEV->stats.tx_packets+= total_packets; + } + + if (ring->dirty_tx != dirty_tx) { + count = dirty_tx - ring->dirty_tx; + WRITE_ONCE(ring->dirty_tx, dirty_tx); + smp_wmb(); + if (__netif_subqueue_stopped(dev, ring->index) && + (rtl8126_tx_slots_avail(tp, ring))) { + netif_start_subqueue(dev, ring->index); + } + + if (ring->cur_tx != dirty_tx) + rtl8126_doorbell(tp, ring); + } + + return count; +} + +static int +rtl8126_tx_interrupt(struct rtl8126_tx_ring *ring, int budget) +{ + struct rtl8126_private *tp = ring->priv; + + if (tp->EnableTxNoClose) + return rtl8126_tx_interrupt_noclose(ring, budget); + else + return rtl8126_tx_interrupt_close(ring, budget); +} + +static int +rtl8126_tx_interrupt_with_vector(struct rtl8126_private *tp, + const int message_id, + int budget) +{ + int count = 0; + + switch (tp->HwCurrIsrVer) { + case 3: + case 4: + if (message_id < tp->num_tx_rings) + count += rtl8126_tx_interrupt(&tp->tx_ring[message_id], budget); + break; + case 5: + if (message_id == 16) + count += rtl8126_tx_interrupt(&tp->tx_ring[0], budget); +#ifdef ENABLE_MULTIPLE_TX_QUEUE + else if (message_id == 17) + count += rtl8126_tx_interrupt(&tp->tx_ring[1], budget); +#endif + break; + default: + if (message_id == 16) + count += rtl8126_tx_interrupt(&tp->tx_ring[0], budget); +#ifdef ENABLE_MULTIPLE_TX_QUEUE + else if (message_id == 18) + count += rtl8126_tx_interrupt(&tp->tx_ring[1], budget); +#endif + break; + } + + return count; +} + +static inline int +rtl8126_fragmented_frame(struct rtl8126_private *tp, u32 status) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return (status & (FirstFrag_V3 | LastFrag_V3)) != (FirstFrag_V3 | LastFrag_V3); + else + return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); +} + +static inline int +rtl8126_is_non_eop(struct rtl8126_private *tp, u32 status) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return !(status & LastFrag_V3); + else + return !(status & LastFrag); +} + +static inline int +rtl8126_rx_desc_type(u32 status) +{ + return ((status >> 26) & 0x0F); +} + +static inline void +rtl8126_rx_v3_csum(struct rtl8126_private *tp, + struct sk_buff *skb, + struct RxDescV3 *descv3) +{ + u32 opts2 = le32_to_cpu(descv3->RxDescNormalDDWord4.opts2); + + /* rx csum offload for RTL8125 */ + if (((opts2 & RxTCPT_v3) && !(opts2 & RxTCPF_v3)) || + ((opts2 & RxUDPT_v3) && !(opts2 & RxUDPF_v3))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb_checksum_none_assert(skb); +} + +static inline void +rtl8126_rx_csum(struct rtl8126_private *tp, + struct sk_buff *skb, + struct RxDesc *desc, + u32 opts1) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8126_rx_v3_csum(tp, skb, (struct RxDescV3 *)desc); + else { + /* rx csum offload for RTL8125 */ + if (((opts1 & RxTCPT) && !(opts1 & RxTCPF)) || + ((opts1 & RxUDPT) && !(opts1 & RxUDPF))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb_checksum_none_assert(skb); + } +} + +/* +static inline int +rtl8126_try_rx_copy(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + struct sk_buff **sk_buff, + int pkt_size, + struct RxDesc *desc, + int rx_buf_sz) +{ + int ret = -1; + + struct sk_buff *skb; + + skb = RTL_ALLOC_SKB_INTR(&tp->r8126napi[ring->index].napi, pkt_size + R8126_RX_ALIGN); + if (skb) { + u8 *data; + + data = sk_buff[0]->data; + if (!R8126_USE_NAPI_ALLOC_SKB) + skb_reserve(skb, R8126_RX_ALIGN); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) + prefetch(data - R8126_RX_ALIGN); +#endif + eth_copy_and_sum(skb, data, pkt_size, 0); + *sk_buff = skb; + rtl8126_mark_to_asic(tp, desc, rx_buf_sz); + ret = 0; + } + + return ret; +} +*/ + +static inline void +rtl8126_rx_skb(struct rtl8126_private *tp, + struct sk_buff *skb, + u32 ring_index) +{ +#ifdef CONFIG_R8126_NAPI +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + netif_receive_skb(skb); +#else + napi_gro_receive(&tp->r8126napi[ring_index].napi, skb); +#endif +#else + netif_rx(skb); +#endif +} + +static int +rtl8126_check_rx_desc_error(struct net_device *dev, + struct rtl8126_private *tp, + u32 status) +{ + int ret = 0; + + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) { + if (unlikely(status & RxRES_V3)) { + if (status & (RxRWT_V3 | RxRUNT_V3)) + RTLDEV->stats.rx_length_errors++; + if (status & RxCRC_V3) + RTLDEV->stats.rx_crc_errors++; + + ret = -1; + } + } else { + if (unlikely(status & RxRES)) { + if (status & (RxRWT | RxRUNT)) + RTLDEV->stats.rx_length_errors++; + if (status & RxCRC) + RTLDEV->stats.rx_crc_errors++; + + ret = -1; + } + } + + return ret; +} + +#ifdef ENABLE_PAGE_REUSE + +static inline bool +rtl8126_reuse_rx_ok(struct page *page) +{ + /* avoid re-using remote pages */ + if (!dev_page_is_reusable(page)) { + //printk(KERN_INFO "r8126 page pfmemalloc, can't reuse!\n"); + return false; + } + /* if we are only owner of page we can reuse it */ + if (unlikely(page_ref_count(page) != 1)) { + //printk(KERN_INFO "r8126 page refcnt %d, can't reuse!\n", page_ref_count(page)); + return false; + } + + return true; +} + +static void +rtl8126_reuse_rx_buffer(struct rtl8126_private *tp, struct rtl8126_rx_ring *ring, u32 cur_rx, struct rtl8126_rx_buffer *rxb) +{ + struct page *page = rxb->page; + + u32 dirty_rx = ring->dirty_rx; + u32 entry = dirty_rx % ring->num_rx_desc; + struct rtl8126_rx_buffer *nrxb = &ring->rx_buffer[entry]; + + u32 noffset; + + //the page gonna be shared by us and kernel, keep page ref = 2 + page_ref_inc(page); + + //flip the buffer in page to use next + noffset = rxb->page_offset ^ (tp->rx_buf_page_size / 2); //one page, two buffer, ping-pong + + nrxb->dma = rxb->dma; + nrxb->page_offset = noffset; + nrxb->data = rxb->data; + + if (cur_rx != dirty_rx) { + //move the buffer to other slot + nrxb->page = page; + rxb->page = NULL; + } +} + +static void rtl8126_put_rx_buffer(struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + u32 cur_rx, + struct rtl8126_rx_buffer *rxb) +{ + struct rtl8126_rx_buffer *nrxb; + struct page *page = rxb->page; + u32 entry; + + entry = ring->dirty_rx % ring->num_rx_desc; + nrxb = &ring->rx_buffer[entry]; + if (likely(rtl8126_reuse_rx_ok(page))) { + /* hand second half of page back to the ring */ + rtl8126_reuse_rx_buffer(tp, ring, cur_rx, rxb); + } else { + tp->page_reuse_fail_cnt++; + + dma_unmap_page_attrs(&tp->pci_dev->dev, rxb->dma, + tp->rx_buf_page_size, + DMA_FROM_DEVICE, + (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)); + //the page ref is kept 1, uniquely owned by kernel now + rxb->page = NULL; + + return; + } + + dma_sync_single_range_for_device(tp_to_dev(tp), + nrxb->dma, + nrxb->page_offset, + tp->rx_buf_sz, + DMA_FROM_DEVICE); + + rtl8126_map_to_asic(tp, ring, + rtl8126_get_rxdesc(tp, ring->RxDescArray, entry), + nrxb->dma + nrxb->page_offset, + tp->rx_buf_sz, entry); + + ring->dirty_rx++; +} + +#endif //ENABLE_PAGE_REUSE + +static int +rtl8126_rx_interrupt(struct net_device *dev, + struct rtl8126_private *tp, + struct rtl8126_rx_ring *ring, + napi_budget budget) +{ + unsigned int cur_rx, rx_left; + unsigned int delta, count = 0; + unsigned int entry; + struct RxDesc *desc; + struct sk_buff *skb; + u32 status; + u32 rx_quota; + u32 ring_index = ring->index; +#ifdef ENABLE_PAGE_REUSE + struct rtl8126_rx_buffer *rxb; +#else //ENABLE_PAGE_REUSE + u64 rx_buf_phy_addr; +#endif //ENABLE_PAGE_REUSE + unsigned int total_rx_multicast_packets = 0; + unsigned int total_rx_bytes = 0, total_rx_packets = 0; + + assert(dev != NULL); + assert(tp != NULL); + + if (ring->RxDescArray == NULL) + goto rx_out; + + rx_quota = RTL_RX_QUOTA(budget); + cur_rx = ring->cur_rx; + rx_left = ring->num_rx_desc + ring->dirty_rx - cur_rx; + rx_left = rtl8126_rx_quota(rx_left, (u32)rx_quota); + + for (; rx_left > 0; rx_left--, cur_rx++) { +#ifdef ENABLE_PTP_SUPPORT + u8 desc_type = RXDESC_TYPE_NORMAL; + struct RxDescV3 ptp_desc; +#endif //ENABLE_PTP_SUPPORT +#ifndef ENABLE_PAGE_REUSE + const void *rx_buf; +#endif //!ENABLE_PAGE_REUSE + u32 pkt_size; + + entry = cur_rx % ring->num_rx_desc; + desc = rtl8126_get_rxdesc(tp, ring->RxDescArray, entry); + status = le32_to_cpu(rtl8126_rx_desc_opts1(tp, desc)); + + if (status & DescOwn) + break; + + rmb(); + + if (unlikely(rtl8126_check_rx_desc_error(dev, tp, status) < 0)) { + if (netif_msg_rx_err(tp)) { + printk(KERN_INFO + "%s: Rx ERROR. status = %08x\n", + dev->name, status); + } + + RTLDEV->stats.rx_errors++; + + if (!(dev->features & NETIF_F_RXALL)) + goto release_descriptor; + } + pkt_size = status & 0x00003fff; + if (likely(!(dev->features & NETIF_F_RXFCS))) { +#ifdef ENABLE_RX_PACKET_FRAGMENT + if (rtl8126_is_non_eop(tp, status) && + pkt_size == tp->rx_buf_sz) { + struct RxDesc *desc_next; + unsigned int entry_next; + int pkt_size_next; + u32 status_next; + + entry_next = (cur_rx + 1) % ring->num_rx_desc; + desc_next = rtl8126_get_rxdesc(tp, ring->RxDescArray, entry_next); + status_next = le32_to_cpu(rtl8126_rx_desc_opts1(tp, desc_next)); + if (!(status_next & DescOwn)) { + pkt_size_next = status_next & 0x00003fff; + if (pkt_size_next < ETH_FCS_LEN) + pkt_size -= (ETH_FCS_LEN - pkt_size_next); + } + } +#endif //ENABLE_RX_PACKET_FRAGMENT + if (!rtl8126_is_non_eop(tp, status)) { + if (pkt_size < ETH_FCS_LEN) { +#ifdef ENABLE_RX_PACKET_FRAGMENT + pkt_size = 0; +#else + goto drop_packet; +#endif //ENABLE_RX_PACKET_FRAGMENT + } else + pkt_size -= ETH_FCS_LEN; + } + } + + if (unlikely(pkt_size > tp->rx_buf_sz)) + goto drop_packet; + +#if !defined(ENABLE_RX_PACKET_FRAGMENT) || !defined(ENABLE_PAGE_REUSE) + /* + * The driver does not support incoming fragmented + * frames. They are seen as a symptom of over-mtu + * sized frames. + */ + if (unlikely(rtl8126_fragmented_frame(tp, status))) + goto drop_packet; +#endif //!ENABLE_RX_PACKET_FRAGMENT || !ENABLE_PAGE_REUSE + +#ifdef ENABLE_PTP_SUPPORT + if (tp->EnablePtp) { + desc_type = rtl8126_rx_desc_type(status); + if (desc_type == RXDESC_TYPE_NEXT && rx_left > 0) { + u32 status_next; + struct RxDescV3 *desc_next; + unsigned int entry_next; + + cur_rx++; + rx_left--; + entry_next = cur_rx % ring->num_rx_desc; + desc_next = (struct RxDescV3 *)rtl8126_get_rxdesc(tp, ring->RxDescArray, entry_next); + status_next = le32_to_cpu(desc_next->RxDescNormalDDWord4.opts1); + if (unlikely(status_next & DescOwn)) { + udelay(1); + status_next = le32_to_cpu(desc_next->RxDescNormalDDWord4.opts1); + if (unlikely(status_next & DescOwn)) { + if (netif_msg_rx_err(tp)) { + printk(KERN_ERR + "%s: Rx Next Desc ERROR. status = %08x\n", + dev->name, status_next); + } + rtl8126_set_desc_dma_addr(tp, (struct RxDesc *)desc_next, + ring->RxDescPhyAddr[entry_next]); + wmb(); + rtl8126_mark_to_asic(tp, (struct RxDesc *)desc_next, tp->rx_buf_sz); + goto drop_packet; + } + } + + rmb(); + + desc_type = rtl8126_rx_desc_type(status_next); + if (desc_type == RXDESC_TYPE_PTP) { + ptp_desc = *desc_next; + rmb(); + rtl8126_set_desc_dma_addr(tp, (struct RxDesc *)desc_next, + ring->RxDescPhyAddr[entry_next]); + wmb(); + rtl8126_mark_to_asic(tp, (struct RxDesc *)desc_next, tp->rx_buf_sz); + } else { + WARN_ON(1); + rtl8126_set_desc_dma_addr(tp, (struct RxDesc *)desc_next, + ring->RxDescPhyAddr[entry_next]); + wmb(); + rtl8126_mark_to_asic(tp, (struct RxDesc *)desc_next, tp->rx_buf_sz); + goto drop_packet; + } + } else + WARN_ON(desc_type != RXDESC_TYPE_NORMAL); + } +#endif +#ifdef ENABLE_PAGE_REUSE + rxb = &ring->rx_buffer[entry]; + skb = rxb->skb; + rxb->skb = NULL; + if (!skb) { + skb = RTL_BUILD_SKB_INTR(rxb->data + rxb->page_offset - ring->rx_offset, tp->rx_buf_page_size / 2); + if (!skb) { + //netdev_err(tp->dev, "Failed to allocate RX skb!\n"); + goto drop_packet; + } + + skb->dev = dev; + if (!R8126_USE_NAPI_ALLOC_SKB) + skb_reserve(skb, R8126_RX_ALIGN); + skb_put(skb, pkt_size); + } else + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rxb->page, + rxb->page_offset, pkt_size, tp->rx_buf_page_size / 2); +#ifdef ENABLE_PTP_SUPPORT + if (desc_type == RXDESC_TYPE_PTP) + rtl8126_rx_ptp_pktstamp(tp, skb, &ptp_desc); +#endif //ENABLE_PTP_SUPPORT + //recycle desc + rtl8126_put_rx_buffer(tp, ring, cur_rx, rxb); + + dma_sync_single_range_for_cpu(tp_to_dev(tp), + rxb->dma, + rxb->page_offset, + tp->rx_buf_sz, + DMA_FROM_DEVICE); +#else //ENABLE_PAGE_REUSE + skb = RTL_ALLOC_SKB_INTR(&tp->r8126napi[ring->index].napi, pkt_size + R8126_RX_ALIGN); + if (!skb) { + //netdev_err(tp->dev, "Failed to allocate RX skb!\n"); + goto drop_packet; + } + + skb->dev = dev; + if (!R8126_USE_NAPI_ALLOC_SKB) + skb_reserve(skb, R8126_RX_ALIGN); + skb_put(skb, pkt_size); +#ifdef ENABLE_PTP_SUPPORT + if (desc_type == RXDESC_TYPE_PTP) + rtl8126_rx_ptp_pktstamp(tp, skb, &ptp_desc); +#endif //ENABLE_PTP_SUPPORT + rx_buf_phy_addr = ring->RxDescPhyAddr[entry]; + dma_sync_single_for_cpu(tp_to_dev(tp), + rx_buf_phy_addr, tp->rx_buf_sz, + DMA_FROM_DEVICE); + rx_buf = ring->Rx_skbuff[entry]->data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) + prefetch(rx_buf - R8126_RX_ALIGN); +#endif + eth_copy_and_sum(skb, rx_buf, pkt_size, 0); + + dma_sync_single_for_device(tp_to_dev(tp), rx_buf_phy_addr, + tp->rx_buf_sz, DMA_FROM_DEVICE); +#endif //ENABLE_PAGE_REUSE + +#ifdef ENABLE_RX_PACKET_FRAGMENT + if (rtl8126_is_non_eop(tp, status)) { + unsigned int entry_next; + entry_next = (entry + 1) % ring->num_rx_desc; + rxb = &ring->rx_buffer[entry_next]; + rxb->skb = skb; + continue; + } +#endif //ENABLE_RX_PACKET_FRAGMENT + +#ifdef ENABLE_RSS_SUPPORT + rtl8126_rx_hash(tp, (struct RxDescV3 *)desc, skb); +#endif + rtl8126_rx_csum(tp, skb, desc, status); + + skb->protocol = eth_type_trans(skb, dev); + + total_rx_bytes += skb->len; + + if (skb->pkt_type == PACKET_MULTICAST) + total_rx_multicast_packets++; + + if (rtl8126_rx_vlan_skb(tp, desc, skb) < 0) + rtl8126_rx_skb(tp, skb, ring_index); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) + dev->last_rx = jiffies; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) + total_rx_packets++; + +#ifdef ENABLE_PAGE_REUSE + rxb->skb = NULL; + continue; +#endif + +release_descriptor: + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) { + rtl8126_set_desc_dma_addr(tp, desc, + ring->RxDescPhyAddr[entry]); + wmb(); + } + rtl8126_mark_to_asic(tp, desc, tp->rx_buf_sz); + continue; +drop_packet: + RTLDEV->stats.rx_dropped++; + RTLDEV->stats.rx_length_errors++; + goto release_descriptor; + } + + count = cur_rx - ring->cur_rx; + ring->cur_rx = cur_rx; + + delta = rtl8126_rx_fill(tp, ring, dev, ring->dirty_rx, ring->cur_rx, 1); + if (!delta && count && netif_msg_intr(tp)) + printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); + ring->dirty_rx += delta; + + RTLDEV->stats.rx_bytes += total_rx_bytes; + RTLDEV->stats.rx_packets += total_rx_packets; + RTLDEV->stats.multicast += total_rx_multicast_packets; + + /* + * FIXME: until there is periodic timer to try and refill the ring, + * a temporary shortage may definitely kill the Rx process. + * - disable the asic to try and avoid an overflow and kick it again + * after refill ? + * - how do others driver handle this condition (Uh oh...). + */ + if ((ring->dirty_rx + ring->num_rx_desc == ring->cur_rx) && netif_msg_intr(tp)) + printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name); + +rx_out: + return total_rx_packets; +} + +static bool +rtl8126_linkchg_interrupt(struct rtl8126_private *tp, u32 status) +{ + switch (tp->HwCurrIsrVer) { + case 2: + case 3: + return status & ISRIMR_V2_LINKCHG; + case 4: + return status & ISRIMR_V4_LINKCHG; + case 5: + return status & ISRIMR_V5_LINKCHG; + default: + return status & LinkChg; + } +} + +static u32 +rtl8126_get_linkchg_message_id(struct rtl8126_private *tp) +{ + switch (tp->HwCurrIsrVer) { + case 4: + return 29; + case 5: + return 18; + default: + return 21; + } +} + +/* + *The interrupt handler does all of the Rx thread work and cleans up after + *the Tx thread. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8126_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8126_interrupt(int irq, void *dev_instance) +#endif +{ + struct r8126_napi *r8126napi = dev_instance; + struct rtl8126_private *tp = r8126napi->priv; + struct net_device *dev = tp->dev; + u32 status; + int handled = 0; + + do { + status = RTL_R32(tp, tp->isr_reg[0]); + + if (!(tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))) { + /* hotplug/major error/no more work/shared irq */ + if (!status) + break; + + if (status == 0xFFFFFFFF) + break; + + if (!(status & (tp->intr_mask | tp->timer_intr_mask))) + break; + } + + handled = 1; + +#if defined(RTL_USE_NEW_INTR_API) + if (!tp->irq_tbl[0].requested) + break; +#endif + rtl8126_disable_hw_interrupt(tp); + + RTL_W32(tp, tp->isr_reg[0], status&~RxFIFOOver); + + if (rtl8126_linkchg_interrupt(tp, status)) + rtl8126_schedule_linkchg_work(tp); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + u8 DashIntType2Status; + + if (status & ISRIMR_DASH_INTR_CMAC_RESET) + tp->CmacResetIntr = TRUE; + + DashIntType2Status = RTL_CMAC_R8(tp, CMAC_IBISR0); + if (DashIntType2Status & ISRIMR_DASH_TYPE2_ROK) { + tp->RcvFwDashOkEvt = TRUE; + } + if (DashIntType2Status & ISRIMR_DASH_TYPE2_TOK) { + tp->SendFwHostOkEvt = TRUE; + } + if (DashIntType2Status & ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE) { + tp->DashFwDisableRx = TRUE; + } + + RTL_CMAC_W8(tp, CMAC_IBISR0, DashIntType2Status); + } + } +#endif + +#ifdef CONFIG_R8126_NAPI + if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) { + if (status & tp->intr_mask) + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + + if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &tp->r8126napi[0].napi))) + __RTL_NETIF_RX_SCHEDULE(dev, &tp->r8126napi[0].napi); + else if (netif_msg_intr(tp)) + printk(KERN_INFO "%s: interrupt %04x in poll\n", + dev->name, status); + } else { + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + rtl8126_switch_to_hw_interrupt(tp); + } +#else + if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) { + u32 budget = ~(u32)0; + int i; + + if (status & tp->intr_mask) + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + + for (i = 0; i < tp->num_tx_rings; i++) + rtl8126_tx_interrupt(&tp->tx_ring[i], ~(u32)0); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[0], &budget); +#else + rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[0], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + struct net_device *dev = tp->dev; + + HandleDashInterrupt(dev); + } +#endif + + rtl8126_switch_to_timer_interrupt(tp); + } else { + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + rtl8126_switch_to_hw_interrupt(tp); + } +#endif + } while (false); + + return IRQ_RETVAL(handled); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8126_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8126_interrupt_msix(int irq, void *dev_instance) +#endif +{ + struct r8126_napi *r8126napi = dev_instance; + struct rtl8126_private *tp = r8126napi->priv; + struct net_device *dev = tp->dev; + int message_id = r8126napi->index; +#ifndef CONFIG_R8126_NAPI + u32 budget = ~(u32)0; +#endif + + do { +#if defined(RTL_USE_NEW_INTR_API) + if (!tp->irq_tbl[message_id].requested) + break; +#endif + //link change + if (message_id == rtl8126_get_linkchg_message_id(tp)) { + rtl8126_disable_hw_interrupt_v2(tp, message_id); + rtl8126_clear_hw_isr_v2(tp, message_id); + rtl8126_schedule_linkchg_work(tp); + break; + } + +#ifdef CONFIG_R8126_NAPI + if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &r8126napi->napi))) { + rtl8126_disable_hw_interrupt_v2(tp, message_id); + __RTL_NETIF_RX_SCHEDULE(dev, &r8126napi->napi); + } else if (netif_msg_intr(tp)) + printk(KERN_INFO "%s: interrupt message id %d in poll_msix\n", + dev->name, message_id); + rtl8126_clear_hw_isr_v2(tp, message_id); +#else + rtl8126_tx_interrupt_with_vector(tp, message_id, ~(u32)0); + + if (message_id < tp->num_rx_rings) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[message_id], &budget); +#else + rtl8126_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + } + + rtl8126_enable_hw_interrupt_v2(tp, message_id); +#endif + + } while (false); + + return IRQ_HANDLED; +} + +static void rtl8126_down(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + //rtl8126_delete_esd_timer(dev, &tp->esd_timer); + + //rtl8126_delete_link_timer(dev, &tp->link_timer); + + netif_carrier_off(dev); + + netif_tx_disable(dev); + + _rtl8126_wait_for_quiescence(dev); + + rtl8126_hw_reset(dev); + + rtl8126_tx_clear(tp); + + rtl8126_rx_clear(tp); +} + +static int rtl8126_resource_freed(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) + if (tp->tx_ring[i].TxDescArray) + return 0; + + for (i = 0; i < tp->num_rx_rings; i++) + if (tp->rx_ring[i].RxDescArray) + return 0; + + return 1; +} + +int rtl8126_close(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + if (!rtl8126_resource_freed(tp)) { + set_bit(R8126_FLAG_DOWN, tp->task_flags); + + rtl8126_down(dev); + + pci_clear_master(tp->pci_dev); + +#ifdef ENABLE_PTP_SUPPORT + rtl8126_ptp_stop(tp); +#endif + rtl8126_hw_d3_para(dev); + + rtl8126_powerdown_pll(dev, 0); + + rtl8126_free_irq(tp); + + rtl8126_free_alloc_resources(tp); + } else { + rtl8126_hw_d3_para(dev); + + rtl8126_powerdown_pll(dev, 0); + } + + return 0; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) +static void rtl8126_shutdown(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8126_private *tp = netdev_priv(dev); + + rtnl_lock(); + + if (HW_DASH_SUPPORT_DASH(tp)) + rtl8126_driver_stop(tp); + + if (s5_keep_curr_mac == 0 && tp->random_mac == 0) + rtl8126_rar_set(tp, tp->org_mac_addr); + + if (s5wol == 0) + tp->wol_enabled = WOL_DISABLED; + + rtl8126_close(dev); + rtl8126_disable_msi(pdev, tp); + + rtnl_unlock(); + + if (system_state == SYSTEM_POWER_OFF) { + pci_clear_master(tp->pci_dev); + pci_wake_from_d3(pdev, tp->wol_enabled); + pci_set_power_state(pdev, PCI_D3hot); + } +} +#endif + +#ifdef CONFIG_PM + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static int +rtl8126_suspend(struct pci_dev *pdev, u32 state) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static int +rtl8126_suspend(struct device *device) +#else +static int +rtl8126_suspend(struct pci_dev *pdev, pm_message_t state) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *dev = pci_get_drvdata(pdev); +#else + struct net_device *dev = pci_get_drvdata(pdev); +#endif + struct rtl8126_private *tp = netdev_priv(dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + u32 pci_pm_state = pci_choose_state(pdev, state); +#endif + if (!netif_running(dev)) + goto out; + + //rtl8126_cancel_all_schedule_work(tp); + + //rtl8126_delete_esd_timer(dev, &tp->esd_timer); + + //rtl8126_delete_link_timer(dev, &tp->link_timer); + + rtnl_lock(); + + set_bit(R8126_FLAG_DOWN, tp->task_flags); + + netif_carrier_off(dev); + + netif_tx_disable(dev); + + netif_device_detach(dev); + +#ifdef ENABLE_PTP_SUPPORT + rtl8126_ptp_suspend(tp); +#endif + rtl8126_hw_reset(dev); + + pci_clear_master(pdev); + + rtl8126_hw_d3_para(dev); + + rtl8126_powerdown_pll(dev, 1); + + if (HW_DASH_SUPPORT_DASH(tp)) + rtl8126_driver_stop(tp); + + rtnl_unlock(); +out: + + pci_disable_device(pdev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + pci_save_state(pdev, &pci_pm_state); +#else + pci_save_state(pdev); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled); +#endif + + pci_prepare_to_sleep(pdev); + + return 0; +} + +static int +rtl8126_hw_d3_not_power_off(struct net_device *dev) +{ + return rtl8126_check_hw_phy_mcu_code_ver(dev); +} + +static int rtl8126_wait_phy_nway_complete_sleep(struct rtl8126_private *tp) +{ + int i, val; + + for (i = 0; i < 30; i++) { + val = rtl8126_mdio_read(tp, MII_BMSR) & BMSR_ANEGCOMPLETE; + if (val) + return 0; + + msleep(100); + } + + return -1; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +static int +rtl8126_resume(struct pci_dev *pdev) +#else +static int +rtl8126_resume(struct device *device) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *dev = pci_get_drvdata(pdev); +#else + struct net_device *dev = pci_get_drvdata(pdev); +#endif + struct rtl8126_private *tp = netdev_priv(dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + u32 pci_pm_state = PCI_D0; +#endif + u32 err; + + rtnl_lock(); + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); + goto out_unlock; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + pci_restore_state(pdev, &pci_pm_state); +#else + pci_restore_state(pdev); +#endif + pci_enable_wake(pdev, PCI_D0, 0); + + /* restore last modified mac address */ + rtl8126_rar_set(tp, dev->dev_addr); + + tp->resume_not_chg_speed = 0; + if (tp->check_keep_link_speed && + //tp->link_ok(dev) && + rtl8126_hw_d3_not_power_off(dev) && + rtl8126_wait_phy_nway_complete_sleep(tp) == 0) + tp->resume_not_chg_speed = 1; + + if (!netif_running(dev)) + goto out_unlock; + + pci_set_master(pdev); + + rtl8126_exit_oob(dev); + + rtl8126_up(dev); + + clear_bit(R8126_FLAG_DOWN, tp->task_flags); + + rtl8126_schedule_reset_work(tp); + + rtl8126_schedule_esd_work(tp); + + //mod_timer(&tp->esd_timer, jiffies + RTL8126_ESD_TIMEOUT); + //mod_timer(&tp->link_timer, jiffies + RTL8126_LINK_TIMEOUT); +out_unlock: + netif_device_attach(dev); + + rtnl_unlock(); + + return err; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + +static struct dev_pm_ops rtl8126_pm_ops = { + .suspend = rtl8126_suspend, + .resume = rtl8126_resume, + .freeze = rtl8126_suspend, + .thaw = rtl8126_resume, + .poweroff = rtl8126_suspend, + .restore = rtl8126_resume, +}; + +#define RTL8126_PM_OPS (&rtl8126_pm_ops) + +#endif + +#else /* !CONFIG_PM */ + +#define RTL8126_PM_OPS NULL + +#endif /* CONFIG_PM */ + +static struct pci_driver rtl8126_pci_driver = { + .name = MODULENAME, + .id_table = rtl8126_pci_tbl, + .probe = rtl8126_init_one, + .remove = __devexit_p(rtl8126_remove_one), +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) + .shutdown = rtl8126_shutdown, +#endif +#ifdef CONFIG_PM +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + .suspend = rtl8126_suspend, + .resume = rtl8126_resume, +#else + .driver.pm = RTL8126_PM_OPS, +#endif +#endif +}; + +static int __init +rtl8126_init_module(void) +{ + int ret = 0; +#ifdef ENABLE_R8126_PROCFS + rtl8126_proc_module_init(); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + ret = pci_register_driver(&rtl8126_pci_driver); +#else + ret = pci_module_init(&rtl8126_pci_driver); +#endif + + return ret; +} + +static void __exit +rtl8126_cleanup_module(void) +{ + pci_unregister_driver(&rtl8126_pci_driver); + +#ifdef ENABLE_R8126_PROCFS + if (rtl8126_proc) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + remove_proc_subtree(MODULENAME, init_net.proc_net); +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + remove_proc_entry(MODULENAME, init_net.proc_net); +#else + remove_proc_entry(MODULENAME, proc_net); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + rtl8126_proc = NULL; + } +#endif +} + +module_init(rtl8126_init_module); +module_exit(rtl8126_cleanup_module); diff --git a/package/lean/r8126/src/r8126_ptp.c b/package/lean/r8126/src/r8126_ptp.c new file mode 100644 index 000000000..8743f5e62 --- /dev/null +++ b/package/lean/r8126/src/r8126_ptp.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "r8126.h" +#include "r8126_ptp.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) +{ + return *(const struct timespec *)&ts64; +} + +static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) +{ + return *(const struct timespec64 *)&ts; +} +#endif + +static int _rtl8126_phc_gettime(struct rtl8126_private *tp, struct timespec64 *ts64) +{ + //get local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_LATCHED_LOCAL_TIME | PTP_EXEC_CMD)); + + /* nanoseconds */ + //0x6808[29:0] + ts64->tv_nsec = (RTL_R32(tp, PTP_SOFT_CONFIG_Time_NS_8125) & 0x3fffffff); + + /* seconds */ + //0x680C[47:0] + ts64->tv_sec = RTL_R16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4); + ts64->tv_sec <<= 32; + ts64->tv_sec |= RTL_R32(tp, PTP_SOFT_CONFIG_Time_S_8125); + + return 0; +} + +static int _rtl8126_phc_settime(struct rtl8126_private *tp, const struct timespec64 *ts64) +{ + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, (ts64->tv_nsec & 0x3fffffff)); + + /* seconds */ + //0x680C[47:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, ts64->tv_sec); + RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (ts64->tv_sec >> 32)); + + //set local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} + +static int _rtl8126_phc_adjtime(struct rtl8126_private *tp, s64 delta) +{ + struct timespec64 d; + bool negative = false; + u64 tohw; + u32 nsec; + u64 sec; + + if (delta < 0) { + negative = true; + tohw = -delta; + } else { + tohw = delta; + } + + d = ns_to_timespec64(tohw); + + nsec = d.tv_nsec; + sec = d.tv_sec; + + if (negative) { + nsec = -nsec; + sec = -sec; + } + + nsec &= 0x3fffffff; + sec &= 0x0000ffffffffffff; + + if (negative) { + nsec |= PTP_SOFT_CONFIG_TIME_NS_NEGATIVE; + sec |= PTP_SOFT_CONFIG_TIME_S_NEGATIVE; + } + + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, nsec); + + /* seconds */ + //0x680C[47:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, sec); + RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (sec >> 32)); + + //adjust local time + //RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD)); + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} + +static int rtl8126_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + int ret; + + //netif_info(tp, drv, tp->dev, "phc adjust time\n"); + + rtnl_lock(); + ret = _rtl8126_phc_adjtime(tp, delta); + rtnl_unlock(); + + return ret; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) +/* +1ppm means every 125MHz plus 125Hz. It also means every 8ns minus 8ns*10^(-6) + +1ns=2^30 sub_ns + +8ns*10^(-6) = 8 * 2^30 sub_ns * 10^(-6) = 2^33 sub_ns * 10^(-6) = 8590 = 0x218E sub_ns + +1ppb means every 125MHz plus 0.125Hz. It also means every 8ns minus 8ns*10^(-9) + +1ns=2^30 sub_ns + +8ns*10^(-9) = 8 * 2^30 sub_ns * 10^(-9) = 2^33 sub_ns * 10^(-9) = 8.59 sub_ns = 9 sub_ns +*/ +static int _rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + bool negative = false; + u32 sub_ns; + + if (ppb < 0) { + negative = true; + ppb = -ppb; + } + + sub_ns = ppb * 9; + if (negative) { + sub_ns = -sub_ns; + sub_ns &= 0x3fffffff; + sub_ns |= PTP_ADJUST_TIME_NS_NEGATIVE; + } else + sub_ns &= 0x3fffffff; + + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, sub_ns); + + //adjust local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD)); + //RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} + +static int rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) +{ + //struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + + //netif_info(tp, drv, tp->dev, "phc adjust freq\n"); + + if (delta > ptp->max_adj || delta < -ptp->max_adj) + return -EINVAL; + + _rtl8126_phc_adjfreq(ptp, delta); + + return 0; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) + +static int rtl8126_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts64) +{ + struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + int ret; + + //netif_info(tp, drv, tp->dev, "phc get ts\n"); + + rtnl_lock(); + ret = _rtl8126_phc_gettime(tp, ts64); + rtnl_unlock(); + + return ret; +} + +static int rtl8126_phc_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts64) +{ + struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + int ret; + + //netif_info(tp, drv, tp->dev, "phc set ts\n"); + + rtnl_lock(); + ret = _rtl8126_phc_settime(tp, ts64); + rtnl_unlock(); + + return ret; +} + +static int rtl8126_phc_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info); + u16 ptp_ctrl; + + //netif_info(tp, drv, tp->dev, "phc enable type %x on %d\n", rq->type, on); + + switch (rq->type) { + case PTP_CLK_REQ_PPS: + rtnl_lock(); + ptp_ctrl = RTL_R16(tp, PTP_CTRL_8125); + ptp_ctrl &= ~BIT_15; + if (on) + ptp_ctrl |= BIT_14; + else + ptp_ctrl &= ~BIT_14; + RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl); + rtnl_unlock(); + return 0; + default: + return -EOPNOTSUPP; + } +} + +int rtl8126_get_ts_info(struct net_device *netdev, + struct ethtool_ts_info *info) +{ + struct rtl8126_private *tp = netdev_priv(netdev); + + /* we always support timestamping disabled */ + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + + if (tp->HwSuppPtpVer == 0) + return ethtool_op_get_ts_info(netdev, info); + + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (tp->ptp_clock) + info->phc_index = ptp_clock_index(tp->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); + + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ); + + return 0; +} + +static const struct ptp_clock_info rtl_ptp_clock_info = { + .owner = THIS_MODULE, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, + .n_pins = 0, + .pps = 1, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) + .adjfreq = rtl8126_phc_adjfreq, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) + .adjtime = rtl8126_phc_adjtime, + .gettime64 = rtl8126_phc_gettime, + .settime64 = rtl8126_phc_settime, + .enable = rtl8126_phc_enable, +}; + +static int rtl8126_ptp_egresstime(struct rtl8126_private *tp, struct timespec64 *ts64, u32 regnum) +{ + /* nanoseconds */ + //[29:0] + ts64->tv_nsec = rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_NS_8125 + regnum * 16 + 2); + ts64->tv_nsec <<= 16; + ts64->tv_nsec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_NS_8125 + regnum * 16); + ts64->tv_nsec &= 0x3fffffff; + + /* seconds */ + //[47:0] + ts64->tv_sec = rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16 + 4); + ts64->tv_sec <<= 16; + ts64->tv_sec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16 + 2); + ts64->tv_sec <<= 16; + ts64->tv_sec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16); + ts64->tv_sec &= 0x0000ffffffffffff; + + return 0; +} + +static void rtl8126_ptp_tx_hwtstamp(struct rtl8126_private *tp) +{ + struct sk_buff *skb = tp->ptp_tx_skb; + struct skb_shared_hwtstamps shhwtstamps = {0}; + struct timespec64 ts64; + u32 regnum; + + RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER); + + //IO 0x2302 bit 10~11 WR_PTR + regnum = RTL_R16(tp, 0x2032) & 0x0C00; + regnum >>= 10; + regnum = (regnum + 3) % 4; + + rtnl_lock(); + rtl8126_ptp_egresstime(tp, &ts64, regnum); + rtnl_unlock(); + + /* Upper 32 bits contain s, lower 32 bits contain ns. */ + shhwtstamps.hwtstamp = ktime_set(ts64.tv_sec, + ts64.tv_nsec); + + /* Clear the lock early before calling skb_tstamp_tx so that + * applications are not woken up before the lock bit is clear. We use + * a copy of the skb pointer to ensure other threads can't change it + * while we're notifying the stack. + */ + tp->ptp_tx_skb = NULL; + clear_bit_unlock(__RTL8126_PTP_TX_IN_PROGRESS, &tp->state); + + /* Notify the stack and free the skb after we've unlocked */ + skb_tstamp_tx(skb, &shhwtstamps); + dev_kfree_skb_any(skb); +} + +#define RTL8126_PTP_TX_TIMEOUT (HZ * 15) +static void rtl8126_ptp_tx_work(struct work_struct *work) +{ + struct rtl8126_private *tp = container_of(work, struct rtl8126_private, + ptp_tx_work); + + if (!tp->ptp_tx_skb) + return; + + if (time_is_before_jiffies(tp->ptp_tx_start + + RTL8126_PTP_TX_TIMEOUT)) { + dev_kfree_skb_any(tp->ptp_tx_skb); + tp->ptp_tx_skb = NULL; + clear_bit_unlock(__RTL8126_PTP_TX_IN_PROGRESS, &tp->state); + tp->tx_hwtstamp_timeouts++; + /* Clear the tx valid bit in TSYNCTXCTL register to enable + * interrupt + */ + RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER); + return; + } + + if (RTL_R8(tp, PTP_ISR_8125) & (PTP_ISR_TOK)) + rtl8126_ptp_tx_hwtstamp(tp); + else + /* reschedule to check later */ + schedule_work(&tp->ptp_tx_work); + +} + +static int rtl8126_hwtstamp_enable(struct rtl8126_private *tp, bool enable) +{ + RTL_W16(tp, PTP_CTRL_8125, 0); + if (enable) { + u16 ptp_ctrl; + struct timespec64 ts64; + + //clear ptp isr + RTL_W8(tp, PTP_ISR_8125, 0xff); + //ptp source 0:gphy 1:mac + rtl8126_mac_ocp_write(tp, 0xDC00, rtl8126_mac_ocp_read(tp, 0xDC00) | BIT_6); + //enable ptp + ptp_ctrl = (BIT_0 | BIT_3 | BIT_4 | BIT_6 | BIT_10 | BIT_12); + if (tp->ptp_master_mode) + ptp_ctrl |= BIT_1; + RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl); + + //set system time + /* + if (ktime_to_timespec64_cond(ktime_get_real(), &ts64)) + _rtl8126_phc_settime(tp, timespec64_to_timespec(ts64)); + */ + ktime_get_real_ts64(&ts64); + _rtl8126_phc_settime(tp, &ts64); + } + + return 0; +} + +static long rtl8126_ptp_create_clock(struct rtl8126_private *tp) +{ + struct net_device *netdev = tp->dev; + long err; + + if (!IS_ERR_OR_NULL(tp->ptp_clock)) + return 0; + + if (tp->HwSuppPtpVer == 0) { + tp->ptp_clock = NULL; + return -EOPNOTSUPP; + } + + tp->ptp_clock_info = rtl_ptp_clock_info; + snprintf(tp->ptp_clock_info.name, sizeof(tp->ptp_clock_info.name), + "%pm", tp->dev->dev_addr); + tp->ptp_clock_info.max_adj = 119304647; + tp->ptp_clock = ptp_clock_register(&tp->ptp_clock_info, &tp->pci_dev->dev); + if (IS_ERR(tp->ptp_clock)) { + err = PTR_ERR(tp->ptp_clock); + tp->ptp_clock = NULL; + netif_err(tp, drv, tp->dev, "ptp_clock_register failed\n"); + return err; + } else + netif_info(tp, drv, tp->dev, "registered PHC device on %s\n", netdev->name); + + return 0; +} + +void rtl8126_ptp_reset(struct rtl8126_private *tp) +{ + if (!tp->ptp_clock) + return; + + netif_info(tp, drv, tp->dev, "reset PHC clock\n"); + + rtl8126_hwtstamp_enable(tp, false); +} + +void rtl8126_ptp_init(struct rtl8126_private *tp) +{ + /* obtain a PTP device, or re-use an existing device */ + if (rtl8126_ptp_create_clock(tp)) + return; + + /* we have a clock so we can initialize work now */ + INIT_WORK(&tp->ptp_tx_work, rtl8126_ptp_tx_work); + + /* reset the PTP related hardware bits */ + rtl8126_ptp_reset(tp); + + return; +} + +void rtl8126_ptp_suspend(struct rtl8126_private *tp) +{ + if (!tp->ptp_clock) + return; + + netif_info(tp, drv, tp->dev, "suspend PHC clock\n"); + + rtl8126_hwtstamp_enable(tp, false); + + /* ensure that we cancel any pending PTP Tx work item in progress */ + cancel_work_sync(&tp->ptp_tx_work); +} + +void rtl8126_ptp_stop(struct rtl8126_private *tp) +{ + struct net_device *netdev = tp->dev; + + netif_info(tp, drv, tp->dev, "stop PHC clock\n"); + + /* first, suspend PTP activity */ + rtl8126_ptp_suspend(tp); + + /* disable the PTP clock device */ + if (tp->ptp_clock) { + ptp_clock_unregister(tp->ptp_clock); + tp->ptp_clock = NULL; + netif_info(tp, drv, tp->dev, "removed PHC on %s\n", + netdev->name); + } +} + +static int rtl8126_set_tstamp(struct net_device *netdev, struct ifreq *ifr) +{ + struct rtl8126_private *tp = netdev_priv(netdev); + struct hwtstamp_config config; + bool hwtstamp = 0; + + //netif_info(tp, drv, tp->dev, "ptp set ts\n"); + + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) + return -EFAULT; + + if (config.flags) + return -EINVAL; + + switch (config.tx_type) { + case HWTSTAMP_TX_ON: + hwtstamp = 1; + case HWTSTAMP_TX_OFF: + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + hwtstamp = 1; + case HWTSTAMP_FILTER_NONE: + break; + default: + return -ERANGE; + } + + if (tp->hwtstamp_config.tx_type != config.tx_type || + tp->hwtstamp_config.rx_filter != config.rx_filter) { + tp->hwtstamp_config = config; + rtl8126_hwtstamp_enable(tp, hwtstamp); + } + + return copy_to_user(ifr->ifr_data, &config, + sizeof(config)) ? -EFAULT : 0; +} + +static int rtl8126_get_tstamp(struct net_device *netdev, struct ifreq *ifr) +{ + struct rtl8126_private *tp = netdev_priv(netdev); + + //netif_info(tp, drv, tp->dev, "ptp get ts\n"); + + return copy_to_user(ifr->ifr_data, &tp->hwtstamp_config, + sizeof(tp->hwtstamp_config)) ? -EFAULT : 0; +} + +int rtl8126_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + int ret; + + //netif_info(tp, drv, tp->dev, "ptp ioctl\n"); + + switch (cmd) { +#ifdef ENABLE_PTP_SUPPORT + case SIOCSHWTSTAMP: + ret = rtl8126_set_tstamp(netdev, ifr); + break; + case SIOCGHWTSTAMP: + ret = rtl8126_get_tstamp(netdev, ifr); + break; +#endif + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +void rtl8126_rx_ptp_pktstamp(struct rtl8126_private *tp, struct sk_buff *skb, + struct RxDescV3 *descv3) +{ + time64_t tv_sec; + long tv_nsec; + + tv_sec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampHigh) + + ((u64)le32_to_cpu(descv3->RxDescPTPDDWord4.TimeStampHHigh) << 32); + tv_nsec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampLow); + + skb_hwtstamps(skb)->hwtstamp = ktime_set(tv_sec, tv_nsec); +} diff --git a/package/lean/r8126/src/r8126_ptp.h b/package/lean/r8126/src/r8126_ptp.h new file mode 100644 index 000000000..37b72b0df --- /dev/null +++ b/package/lean/r8126/src/r8126_ptp.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8126_PTP_H +#define _LINUX_R8126_PTP_H + +#include +#include +#include +#include +#include + +struct rtl8126_ptp_info { + s64 time_sec; + u32 time_ns; + u16 ts_info; +}; + +#ifndef _STRUCT_TIMESPEC +#define _STRUCT_TIMESPEC +struct timespec { + __kernel_old_time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +enum PTP_CMD_TYPE { + PTP_CMD_SET_LOCAL_TIME = 0, + PTP_CMD_DRIFT_LOCAL_TIME, + PTP_CMD_LATCHED_LOCAL_TIME, +}; + + +struct rtl8126_private; +struct RxDescV3; + +int rtl8126_get_ts_info(struct net_device *netdev, + struct ethtool_ts_info *info); + +void rtl8126_ptp_reset(struct rtl8126_private *tp); +void rtl8126_ptp_init(struct rtl8126_private *tp); +void rtl8126_ptp_suspend(struct rtl8126_private *tp); +void rtl8126_ptp_stop(struct rtl8126_private *tp); + +int rtl8126_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); + +void rtl8126_rx_ptp_pktstamp(struct rtl8126_private *tp, struct sk_buff *skb, + struct RxDescV3 *descv3); + +#endif /* _LINUX_R8126_PTP_H */ diff --git a/package/lean/r8126/src/r8126_realwow.h b/package/lean/r8126/src/r8126_realwow.h new file mode 100644 index 000000000..8d8998ee3 --- /dev/null +++ b/package/lean/r8126/src/r8126_realwow.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8126_REALWOW_H +#define _LINUX_R8126_REALWOW_H + +#define SIOCDEVPRIVATE_RTLREALWOW SIOCDEVPRIVATE+3 + +#define MAX_RealWoW_KCP_SIZE (100) +#define MAX_RealWoW_Payload (64) + +#define KA_TX_PACKET_SIZE (100) +#define KA_WAKEUP_PATTERN_SIZE (120) + +//HwSuppKeepAliveOffloadVer +#define HW_SUPPORT_KCP_OFFLOAD(_M) ((_M)->HwSuppKCPOffloadVer > 0) + +enum rtl_realwow_cmd { + + RTL_REALWOW_SET_KCP_DISABLE=0, + RTL_REALWOW_SET_KCP_INFO, + RTL_REALWOW_SET_KCP_CONTENT, + + RTL_REALWOW_SET_KCP_ACKPKTINFO, + RTL_REALWOW_SET_KCP_WPINFO, + RTL_REALWOW_SET_KCPDHCP_TIMEOUT, + + RTLT_REALWOW_COMMAND_INVALID +}; + +struct rtl_realwow_ioctl_struct { + __u32 cmd; + __u32 offset; + __u32 len; + union { + __u32 data; + void *data_buffer; + }; +}; + +typedef struct _MP_KCPInfo { + u8 DIPv4[4]; + u8 MacID[6]; + u16 UdpPort[2]; + u8 PKTLEN[2]; + + u16 ackLostCnt; + u8 KCP_WakePattern[MAX_RealWoW_Payload]; + u8 KCP_AckPacket[MAX_RealWoW_Payload]; + u32 KCP_interval; + u8 KCP_WakePattern_Len; + u8 KCP_AckPacket_Len; + u8 KCP_TxPacket[2][KA_TX_PACKET_SIZE]; +} MP_KCP_INFO, *PMP_KCP_INFO; + +typedef struct _KCPInfo { + u32 nId; // = id + u8 DIPv4[4]; + u8 MacID[6]; + u16 UdpPort; + u16 PKTLEN; +} KCPInfo, *PKCPInfo; + +typedef struct _KCPContent { + u32 id; // = id + u32 mSec; // = msec + u32 size; // =size + u8 bPacket[MAX_RealWoW_KCP_SIZE]; // put packet here +} KCPContent, *PKCPContent; + +typedef struct _RealWoWAckPktInfo { + u16 ackLostCnt; + u16 patterntSize; + u8 pattern[MAX_RealWoW_Payload]; +} RealWoWAckPktInfo,*PRealWoWAckPktInfo; + +typedef struct _RealWoWWPInfo { + u16 patterntSize; + u8 pattern[MAX_RealWoW_Payload]; +} RealWoWWPInfo,*PRealWoWWPInfo; + +int rtl8126_realwow_ioctl(struct net_device *dev, struct ifreq *ifr); +void rtl8126_realwow_hw_init(struct net_device *dev); +void rtl8126_get_realwow_hw_version(struct net_device *dev); +void rtl8126_set_realwow_d3_para(struct net_device *dev); + +#endif /* _LINUX_R8126_REALWOW_H */ diff --git a/package/lean/r8126/src/r8126_rss.c b/package/lean/r8126/src/r8126_rss.c new file mode 100644 index 000000000..666e24e10 --- /dev/null +++ b/package/lean/r8126/src/r8126_rss.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include "r8126.h" + +enum rtl8126_rss_register_content { + /* RSS */ + RSS_CTRL_TCP_IPV4_SUPP = (1 << 0), + RSS_CTRL_IPV4_SUPP = (1 << 1), + RSS_CTRL_TCP_IPV6_SUPP = (1 << 2), + RSS_CTRL_IPV6_SUPP = (1 << 3), + RSS_CTRL_IPV6_EXT_SUPP = (1 << 4), + RSS_CTRL_TCP_IPV6_EXT_SUPP = (1 << 5), + RSS_HALF_SUPP = (1 << 7), + RSS_CTRL_UDP_IPV4_SUPP = (1 << 11), + RSS_CTRL_UDP_IPV6_SUPP = (1 << 12), + RSS_CTRL_UDP_IPV6_EXT_SUPP = (1 << 13), + RSS_QUAD_CPU_EN = (1 << 16), + RSS_HQ_Q_SUP_R = (1 << 31), +}; + +static int rtl8126_get_rss_hash_opts(struct rtl8126_private *tp, + struct ethtool_rxnfc *cmd) +{ + cmd->data = 0; + + /* Report default options for RSS */ + switch (cmd->flow_type) { + case TCP_V4_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case UDP_V4_FLOW: + if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case IPV4_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case UDP_V6_FLOW: + if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + fallthrough; + case IPV6_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + return -EINVAL; + } + + return 0; +} + +int rtl8126_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + netif_info(tp, drv, tp->dev, "rss get rxnfc\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return ret; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = rtl8126_tot_rx_rings(tp); + ret = 0; + break; + case ETHTOOL_GRXFH: + ret = rtl8126_get_rss_hash_opts(tp, cmd); + break; + default: + break; + } + + return ret; +} + +u32 rtl8126_rss_indir_tbl_entries(struct rtl8126_private *tp) +{ + return tp->HwSuppIndirTblEntries; +} + +#define RSS_MASK_BITS_OFFSET (8) +#define RSS_CPU_NUM_OFFSET (16) +#define RTL8126_UDP_RSS_FLAGS (RTL_8125_RSS_FLAG_HASH_UDP_IPV4 | \ + RTL_8125_RSS_FLAG_HASH_UDP_IPV6) +static int _rtl8126_set_rss_hash_opt(struct rtl8126_private *tp) +{ + u32 rss_flags = tp->rss_flags; + u32 hash_mask_len; + u32 rss_ctrl; + + rss_ctrl = ilog2(rtl8126_tot_rx_rings(tp)); + rss_ctrl &= (BIT_0 | BIT_1 | BIT_2); + rss_ctrl <<= RSS_CPU_NUM_OFFSET; + + /* Perform hash on these packet types */ + rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP + | RSS_CTRL_IPV4_SUPP + | RSS_CTRL_IPV6_SUPP + | RSS_CTRL_IPV6_EXT_SUPP + | RSS_CTRL_TCP_IPV6_SUPP + | RSS_CTRL_TCP_IPV6_EXT_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + rss_ctrl |= RSS_CTRL_UDP_IPV4_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + rss_ctrl |= RSS_CTRL_UDP_IPV6_SUPP | + RSS_CTRL_UDP_IPV6_EXT_SUPP; + + hash_mask_len = ilog2(rtl8126_rss_indir_tbl_entries(tp)); + hash_mask_len &= (BIT_0 | BIT_1 | BIT_2); + rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET; + + RTL_W32(tp, RSS_CTRL_8125, rss_ctrl); + + return 0; +} + +static int rtl8126_set_rss_hash_opt(struct rtl8126_private *tp, + struct ethtool_rxnfc *nfc) +{ + u32 rss_flags = tp->rss_flags; + + netif_info(tp, drv, tp->dev, "rss set hash\n"); + + /* + * RSS does not support anything other than hashing + * to queues on src and dst IPs and ports + */ + if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) + return -EINVAL; + + switch (nfc->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + !(nfc->data & RXH_L4_B_0_1) || + !(nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + case UDP_V4_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + rss_flags &= ~RTL_8125_RSS_FLAG_HASH_UDP_IPV4; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + rss_flags |= RTL_8125_RSS_FLAG_HASH_UDP_IPV4; + break; + default: + return -EINVAL; + } + break; + case UDP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + rss_flags &= ~RTL_8125_RSS_FLAG_HASH_UDP_IPV6; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + rss_flags |= RTL_8125_RSS_FLAG_HASH_UDP_IPV6; + break; + default: + return -EINVAL; + } + break; + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IP_USER_FLOW: + case ETHER_FLOW: + /* RSS is not supported for these protocols */ + if (nfc->data) { + netif_err(tp, drv, tp->dev, "Command parameters not supported\n"); + return -EINVAL; + } + return 0; + break; + default: + return -EINVAL; + } + + /* if we changed something we need to update flags */ + if (rss_flags != tp->rss_flags) { + u32 rss_ctrl = RTL_R32(tp, RSS_CTRL_8125); + + if ((rss_flags & RTL8126_UDP_RSS_FLAGS) && + !(tp->rss_flags & RTL8126_UDP_RSS_FLAGS)) + netdev_warn(tp->dev, + "enabling UDP RSS: fragmented packets may " + "arrive out of order to the stack above\n"); + + tp->rss_flags = rss_flags; + + /* Perform hash on these packet types */ + rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP + | RSS_CTRL_IPV4_SUPP + | RSS_CTRL_IPV6_SUPP + | RSS_CTRL_IPV6_EXT_SUPP + | RSS_CTRL_TCP_IPV6_SUPP + | RSS_CTRL_TCP_IPV6_EXT_SUPP; + + rss_ctrl &= ~(RSS_CTRL_UDP_IPV4_SUPP | + RSS_CTRL_UDP_IPV6_SUPP | + RSS_CTRL_UDP_IPV6_EXT_SUPP); + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + rss_ctrl |= RSS_CTRL_UDP_IPV4_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + rss_ctrl |= RSS_CTRL_UDP_IPV6_SUPP | + RSS_CTRL_UDP_IPV6_EXT_SUPP; + + RTL_W32(tp, RSS_CTRL_8125, rss_ctrl); + } + + return 0; +} + +int rtl8126_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + netif_info(tp, drv, tp->dev, "rss set rxnfc\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return ret; + + switch (cmd->cmd) { + case ETHTOOL_SRXFH: + ret = rtl8126_set_rss_hash_opt(tp, cmd); + break; + default: + break; + } + + return ret; +} + +static u32 _rtl8126_get_rxfh_key_size(struct rtl8126_private *tp) +{ + return sizeof(tp->rss_key); +} + +u32 rtl8126_get_rxfh_key_size(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get key size\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return 0; + + return _rtl8126_get_rxfh_key_size(tp); +} + +u32 rtl8126_rss_indir_size(struct net_device *dev) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get indir tbl size\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return 0; + + return rtl8126_rss_indir_tbl_entries(tp); +} + +static void rtl8126_get_reta(struct rtl8126_private *tp, u32 *indir) +{ + int i, reta_size = rtl8126_rss_indir_tbl_entries(tp); + + for (i = 0; i < reta_size; i++) + indir[i] = tp->rss_indir_tbl[i]; +} + +int rtl8126_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, + u8 *hfunc) +{ + struct rtl8126_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get rxfh\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return -EOPNOTSUPP; + + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; + + if (indir) + rtl8126_get_reta(tp, indir); + + if (key) + memcpy(key, tp->rss_key, RTL8126_RSS_KEY_SIZE); + + return 0; +} + +static u32 rtl8126_rss_key_reg(struct rtl8126_private *tp) +{ + return RSS_KEY_8125; +} + +static u32 rtl8126_rss_indir_tbl_reg(struct rtl8126_private *tp) +{ + return RSS_INDIRECTION_TBL_8125_V2; +} + +static void rtl8126_store_reta(struct rtl8126_private *tp) +{ + u16 indir_tbl_reg = rtl8126_rss_indir_tbl_reg(tp); + u32 i, reta_entries = rtl8126_rss_indir_tbl_entries(tp); + u32 reta = 0; + u8 *indir_tbl = tp->rss_indir_tbl; + + /* Write redirection table to HW */ + for (i = 0; i < reta_entries; i++) { + reta |= indir_tbl[i] << (i & 0x3) * 8; + if ((i & 3) == 3) { + RTL_W32(tp, indir_tbl_reg, reta); + + indir_tbl_reg += 4; + reta = 0; + } + } +} + +static void rtl8126_store_rss_key(struct rtl8126_private *tp) +{ + const u16 rss_key_reg = rtl8126_rss_key_reg(tp); + u32 i, rss_key_size = _rtl8126_get_rxfh_key_size(tp); + u32 *rss_key = (u32*)tp->rss_key; + + /* Write redirection table to HW */ + for (i = 0; i < rss_key_size; i+=4) + RTL_W32(tp, rss_key_reg + i, *rss_key++); +} + +int rtl8126_set_rxfh(struct net_device *dev, const u32 *indir, + const u8 *key, const u8 hfunc) +{ + struct rtl8126_private *tp = netdev_priv(dev); + int i; + u32 reta_entries = rtl8126_rss_indir_tbl_entries(tp); + + netif_info(tp, drv, tp->dev, "rss set rxfh\n"); + + /* We require at least one supported parameter to be changed and no + * change in any of the unsupported parameters + */ + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + /* Fill out the redirection table */ + if (indir) { + int max_queues = tp->num_rx_rings; + + /* Verify user input. */ + for (i = 0; i < reta_entries; i++) + if (indir[i] >= max_queues) + return -EINVAL; + + for (i = 0; i < reta_entries; i++) + tp->rss_indir_tbl[i] = indir[i]; + } + + /* Fill out the rss hash key */ + if (key) + memcpy(tp->rss_key, key, RTL8126_RSS_KEY_SIZE); + + rtl8126_store_reta(tp); + + rtl8126_store_rss_key(tp); + + return 0; +} + +static u32 rtl8126_get_rx_desc_hash(struct rtl8126_private *tp, + struct RxDescV3 *descv3) +{ + return le32_to_cpu(descv3->RxDescNormalDDWord2.RSSResult); +} + +#define RXS_8125B_RSS_UDP BIT(9) +#define RXS_8125_RSS_IPV4 BIT(10) +#define RXS_8125_RSS_IPV6 BIT(12) +#define RXS_8125_RSS_TCP BIT(13) +#define RTL8126_RXS_RSS_L3_TYPE_MASK (RXS_8125_RSS_IPV4 | RXS_8125_RSS_IPV6) +#define RTL8126_RXS_RSS_L4_TYPE_MASK (RXS_8125_RSS_TCP | RXS_8125B_RSS_UDP) +void rtl8126_rx_hash(struct rtl8126_private *tp, + struct RxDescV3 *descv3, + struct sk_buff *skb) +{ + u16 rss_header_info; + + if (!(tp->dev->features & NETIF_F_RXHASH)) + return; + + rss_header_info = le16_to_cpu(descv3->RxDescNormalDDWord2.HeaderInfo); + + if (!(rss_header_info & RTL8126_RXS_RSS_L3_TYPE_MASK)) + return; + + skb_set_hash(skb, rtl8126_get_rx_desc_hash(tp, descv3), + (RTL8126_RXS_RSS_L4_TYPE_MASK & rss_header_info) ? + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); +} + +void rtl8126_disable_rss(struct rtl8126_private *tp) +{ + RTL_W32(tp, RSS_CTRL_8125, 0x00); +} + +void _rtl8126_config_rss(struct rtl8126_private *tp) +{ + _rtl8126_set_rss_hash_opt(tp); + + rtl8126_store_reta(tp); + + rtl8126_store_rss_key(tp); +} + +void rtl8126_config_rss(struct rtl8126_private *tp) +{ + if (!tp->EnableRss) { + rtl8126_disable_rss(tp); + return; + } + + _rtl8126_config_rss(tp); +} + +void rtl8126_init_rss(struct rtl8126_private *tp) +{ + int i; + + for (i = 0; i < rtl8126_rss_indir_tbl_entries(tp); i++) + tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings); + + netdev_rss_key_fill(tp->rss_key, RTL8126_RSS_KEY_SIZE); +} diff --git a/package/lean/r8126/src/r8126_rss.h b/package/lean/r8126/src/r8126_rss.h new file mode 100644 index 000000000..0d6062dba --- /dev/null +++ b/package/lean/r8126/src/r8126_rss.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8126_RSS_H +#define _LINUX_R8126_RSS_H + +#include +#include + +#define RTL8126_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ +#define RTL8126_MAX_INDIRECTION_TABLE_ENTRIES 128 + +enum rtl8126_rss_flag { + RTL_8125_RSS_FLAG_HASH_UDP_IPV4 = (1 << 0), + RTL_8125_RSS_FLAG_HASH_UDP_IPV6 = (1 << 1), +}; + +struct rtl8126_private; + +int rtl8126_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs); +int rtl8126_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd); +u32 rtl8126_get_rxfh_key_size(struct net_device *netdev); +u32 rtl8126_rss_indir_size(struct net_device *netdev); +int rtl8126_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc); +int rtl8126_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key, const u8 hfunc); +void rtl8126_rx_hash(struct rtl8126_private *tp, + struct RxDescV3 *descv3, + struct sk_buff *skb); +void _rtl8126_config_rss(struct rtl8126_private *tp); +void rtl8126_config_rss(struct rtl8126_private *tp); +void rtl8126_init_rss(struct rtl8126_private *tp); +u32 rtl8126_rss_indir_tbl_entries(struct rtl8126_private *tp); +void rtl8126_disable_rss(struct rtl8126_private *tp); + +#endif /* _LINUX_R8126_RSS_H */ diff --git a/package/lean/r8126/src/rtl_eeprom.c b/package/lean/r8126/src/rtl_eeprom.c new file mode 100644 index 000000000..6421df4bb --- /dev/null +++ b/package/lean/r8126/src/rtl_eeprom.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "r8126.h" +#include "rtl_eeprom.h" + +//------------------------------------------------------------------- +//rtl8126_eeprom_type(): +// tell the eeprom type +//return value: +// 0: the eeprom type is 93C46 +// 1: the eeprom type is 93C56 or 93C66 +//------------------------------------------------------------------- +void rtl8126_eeprom_type(struct rtl8126_private *tp) +{ + u16 magic = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT) + goto out_no_eeprom; + + if(RTL_R8(tp, 0xD2)&0x04) { + //not support + //tp->eeprom_type = EEPROM_TWSI; + //tp->eeprom_len = 256; + goto out_no_eeprom; + } else if(RTL_R32(tp, RxConfig) & RxCfg_9356SEL) { + tp->eeprom_type = EEPROM_TYPE_93C56; + tp->eeprom_len = 256; + } else { + tp->eeprom_type = EEPROM_TYPE_93C46; + tp->eeprom_len = 128; + } + + magic = rtl8126_eeprom_read_sc(tp, 0); + +out_no_eeprom: + if ((magic != 0x8129) && (magic != 0x8128)) { + tp->eeprom_type = EEPROM_TYPE_NONE; + tp->eeprom_len = 0; + } +} + +void rtl8126_eeprom_cleanup(struct rtl8126_private *tp) +{ + u8 x; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EECS); + + RTL_W8(tp, Cfg9346, x); + + rtl8126_raise_clock(tp, &x); + rtl8126_lower_clock(tp, &x); +} + +int rtl8126_eeprom_cmd_done(struct rtl8126_private *tp) +{ + u8 x; + int i; + + rtl8126_stand_by(tp); + + for (i = 0; i < 50000; i++) { + x = RTL_R8(tp, Cfg9346); + + if (x & Cfg9346_EEDO) { + udelay(RTL_CLOCK_RATE * 2 * 3); + return 0; + } + udelay(1); + } + + return -1; +} + +//------------------------------------------------------------------- +//rtl8126_eeprom_read_sc(): +// read one word from eeprom +//------------------------------------------------------------------- +u16 rtl8126_eeprom_read_sc(struct rtl8126_private *tp, u16 reg) +{ + int addr_sz = 6; + u8 x; + u16 data; + + if(tp->eeprom_type == EEPROM_TYPE_NONE) { + return -1; + } + + if (tp->eeprom_type==EEPROM_TYPE_93C46) + addr_sz = 6; + else if (tp->eeprom_type==EEPROM_TYPE_93C56) + addr_sz = 8; + + x = Cfg9346_EEM1 | Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); + + rtl8126_shift_out_bits(tp, RTL_EEPROM_READ_OPCODE, 3); + rtl8126_shift_out_bits(tp, reg, addr_sz); + + data = rtl8126_shift_in_bits(tp); + + rtl8126_eeprom_cleanup(tp); + + RTL_W8(tp, Cfg9346, 0); + + return data; +} + +//------------------------------------------------------------------- +//rtl8126_eeprom_write_sc(): +// write one word to a specific address in the eeprom +//------------------------------------------------------------------- +void rtl8126_eeprom_write_sc(struct rtl8126_private *tp, u16 reg, u16 data) +{ + u8 x; + int addr_sz = 6; + int w_dummy_addr = 4; + + if(tp->eeprom_type == EEPROM_TYPE_NONE) { + return ; + } + + if (tp->eeprom_type==EEPROM_TYPE_93C46) { + addr_sz = 6; + w_dummy_addr = 4; + } else if (tp->eeprom_type==EEPROM_TYPE_93C56) { + addr_sz = 8; + w_dummy_addr = 6; + } + + x = Cfg9346_EEM1 | Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); + + rtl8126_shift_out_bits(tp, RTL_EEPROM_EWEN_OPCODE, 5); + rtl8126_shift_out_bits(tp, reg, w_dummy_addr); + rtl8126_stand_by(tp); + + rtl8126_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3); + rtl8126_shift_out_bits(tp, reg, addr_sz); + if (rtl8126_eeprom_cmd_done(tp) < 0) { + return; + } + rtl8126_stand_by(tp); + + rtl8126_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3); + rtl8126_shift_out_bits(tp, reg, addr_sz); + rtl8126_shift_out_bits(tp, data, 16); + if (rtl8126_eeprom_cmd_done(tp) < 0) { + return; + } + rtl8126_stand_by(tp); + + rtl8126_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5); + rtl8126_shift_out_bits(tp, reg, w_dummy_addr); + + rtl8126_eeprom_cleanup(tp); + RTL_W8(tp, Cfg9346, 0); +} + +void rtl8126_raise_clock(struct rtl8126_private *tp, u8 *x) +{ + *x = *x | Cfg9346_EESK; + RTL_W8(tp, Cfg9346, *x); + udelay(RTL_CLOCK_RATE); +} + +void rtl8126_lower_clock(struct rtl8126_private *tp, u8 *x) +{ + + *x = *x & ~Cfg9346_EESK; + RTL_W8(tp, Cfg9346, *x); + udelay(RTL_CLOCK_RATE); +} + +void rtl8126_shift_out_bits(struct rtl8126_private *tp, int data, int count) +{ + u8 x; + int mask; + + mask = 0x01 << (count - 1); + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); + + do { + if (data & mask) + x |= Cfg9346_EEDI; + else + x &= ~Cfg9346_EEDI; + + RTL_W8(tp, Cfg9346, x); + udelay(RTL_CLOCK_RATE); + rtl8126_raise_clock(tp, &x); + rtl8126_lower_clock(tp, &x); + mask = mask >> 1; + } while(mask); + + x &= ~Cfg9346_EEDI; + RTL_W8(tp, Cfg9346, x); +} + +u16 rtl8126_shift_in_bits(struct rtl8126_private *tp) +{ + u8 x; + u16 d, i; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); + + d = 0; + + for (i = 0; i < 16; i++) { + d = d << 1; + rtl8126_raise_clock(tp, &x); + + x = RTL_R8(tp, Cfg9346); + x &= ~Cfg9346_EEDI; + + if (x & Cfg9346_EEDO) + d |= 1; + + rtl8126_lower_clock(tp, &x); + } + + return d; +} + +void rtl8126_stand_by(struct rtl8126_private *tp) +{ + u8 x; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EECS | Cfg9346_EESK); + RTL_W8(tp, Cfg9346, x); + udelay(RTL_CLOCK_RATE); + + x |= Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); +} + +void rtl8126_set_eeprom_sel_low(struct rtl8126_private *tp) +{ + RTL_W8(tp, Cfg9346, Cfg9346_EEM1); + RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK); + + udelay(20); + + RTL_W8(tp, Cfg9346, Cfg9346_EEM1); +} diff --git a/package/lean/r8126/src/rtl_eeprom.h b/package/lean/r8126/src/rtl_eeprom.h new file mode 100644 index 000000000..1e4b56874 --- /dev/null +++ b/package/lean/r8126/src/rtl_eeprom.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_RTLEEPROM_H +#define _LINUX_RTLEEPROM_H + +//EEPROM opcodes +#define RTL_EEPROM_READ_OPCODE 06 +#define RTL_EEPROM_WRITE_OPCODE 05 +#define RTL_EEPROM_ERASE_OPCODE 07 +#define RTL_EEPROM_EWEN_OPCODE 19 +#define RTL_EEPROM_EWDS_OPCODE 16 + +#define RTL_CLOCK_RATE 3 + +void rtl8126_eeprom_type(struct rtl8126_private *tp); +void rtl8126_eeprom_cleanup(struct rtl8126_private *tp); +u16 rtl8126_eeprom_read_sc(struct rtl8126_private *tp, u16 reg); +void rtl8126_eeprom_write_sc(struct rtl8126_private *tp, u16 reg, u16 data); +void rtl8126_shift_out_bits(struct rtl8126_private *tp, int data, int count); +u16 rtl8126_shift_in_bits(struct rtl8126_private *tp); +void rtl8126_raise_clock(struct rtl8126_private *tp, u8 *x); +void rtl8126_lower_clock(struct rtl8126_private *tp, u8 *x); +void rtl8126_stand_by(struct rtl8126_private *tp); +void rtl8126_set_eeprom_sel_low(struct rtl8126_private *tp); + +#endif /* _LINUX_RTLEEPROM_H */ diff --git a/package/lean/r8126/src/rtltool.c b/package/lean/r8126/src/rtltool.c new file mode 100644 index 000000000..c4b7d52fc --- /dev/null +++ b/package/lean/r8126/src/rtltool.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "r8126.h" +#include "rtl_eeprom.h" +#include "rtltool.h" + +int rtl8126_tool_ioctl(struct rtl8126_private *tp, struct ifreq *ifr) +{ + struct rtltool_cmd my_cmd; + int ret; + + if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd))) + return -EFAULT; + + ret = 0; + switch (my_cmd.cmd) { + case RTLTOOL_READ_MAC: + if (my_cmd.len==1) + my_cmd.data = readb(tp->mmio_addr+my_cmd.offset); + else if (my_cmd.len==2) + my_cmd.data = readw(tp->mmio_addr+(my_cmd.offset&~1)); + else if (my_cmd.len==4) + my_cmd.data = readl(tp->mmio_addr+(my_cmd.offset&~3)); + else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTLTOOL_WRITE_MAC: + if (my_cmd.len==1) + writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); + else if (my_cmd.len==2) + writew(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~1)); + else if (my_cmd.len==4) + writel(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~3)); + else { + ret = -EOPNOTSUPP; + break; + } + + break; + + case RTLTOOL_READ_PHY: + my_cmd.data = rtl8126_mdio_prot_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_PHY: + rtl8126_mdio_prot_write(tp, my_cmd.offset, my_cmd.data); + break; + + case RTLTOOL_READ_EPHY: + my_cmd.data = rtl8126_ephy_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_EPHY: + rtl8126_ephy_write(tp, my_cmd.offset, my_cmd.data); + break; + + case RTLTOOL_READ_ERI: + my_cmd.data = 0; + if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { + my_cmd.data = rtl8126_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC); + } else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_ERI: + if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { + rtl8126_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC); + } else { + ret = -EOPNOTSUPP; + break; + } + break; + + case RTLTOOL_READ_PCI: + my_cmd.data = 0; + if (my_cmd.len==1) + pci_read_config_byte(tp->pci_dev, my_cmd.offset, + (u8 *)&my_cmd.data); + else if (my_cmd.len==2) + pci_read_config_word(tp->pci_dev, my_cmd.offset, + (u16 *)&my_cmd.data); + else if (my_cmd.len==4) + pci_read_config_dword(tp->pci_dev, my_cmd.offset, + &my_cmd.data); + else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTLTOOL_WRITE_PCI: + if (my_cmd.len==1) + pci_write_config_byte(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else if (my_cmd.len==2) + pci_write_config_word(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else if (my_cmd.len==4) + pci_write_config_dword(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else { + ret = -EOPNOTSUPP; + break; + } + + break; + + case RTLTOOL_READ_EEPROM: + my_cmd.data = rtl8126_eeprom_read_sc(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_EEPROM: + rtl8126_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data); + break; + + case RTL_READ_OOB_MAC: + rtl8126_oob_mutex_lock(tp); + my_cmd.data = rtl8126_ocp_read(tp, my_cmd.offset, 4); + rtl8126_oob_mutex_unlock(tp); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTL_WRITE_OOB_MAC: + if (my_cmd.len == 0 || my_cmd.len > 4) + return -EOPNOTSUPP; + + rtl8126_oob_mutex_lock(tp); + rtl8126_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data); + rtl8126_oob_mutex_unlock(tp); + break; + + case RTL_ENABLE_PCI_DIAG: + tp->rtk_enable_diag = 1; + + dprintk("enable rtk diag\n"); + break; + + case RTL_DISABLE_PCI_DIAG: + tp->rtk_enable_diag = 0; + + dprintk("disable rtk diag\n"); + break; + + case RTL_READ_MAC_OCP: + if (my_cmd.offset % 2) + return -EOPNOTSUPP; + + my_cmd.data = rtl8126_mac_ocp_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTL_WRITE_MAC_OCP: + if ((my_cmd.offset % 2) || (my_cmd.len != 2)) + return -EOPNOTSUPP; + + rtl8126_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data); + break; + + case RTL_DIRECT_READ_PHY_OCP: + my_cmd.data = rtl8126_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTL_DIRECT_WRITE_PHY_OCP: + rtl8126_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data); + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} diff --git a/package/lean/r8126/src/rtltool.h b/package/lean/r8126/src/rtltool.h new file mode 100644 index 000000000..1ae1b219b --- /dev/null +++ b/package/lean/r8126/src/rtltool.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8126 is the Linux device driver released for Realtek 5 Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_RTLTOOL_H +#define _LINUX_RTLTOOL_H + +#define SIOCRTLTOOL SIOCDEVPRIVATE+1 + +enum rtl_cmd { + RTLTOOL_READ_MAC=0, + RTLTOOL_WRITE_MAC, + RTLTOOL_READ_PHY, + RTLTOOL_WRITE_PHY, + RTLTOOL_READ_EPHY, + RTLTOOL_WRITE_EPHY, + RTLTOOL_READ_ERI, + RTLTOOL_WRITE_ERI, + RTLTOOL_READ_PCI, + RTLTOOL_WRITE_PCI, + RTLTOOL_READ_EEPROM, + RTLTOOL_WRITE_EEPROM, + + RTL_READ_OOB_MAC, + RTL_WRITE_OOB_MAC, + + RTL_ENABLE_PCI_DIAG, + RTL_DISABLE_PCI_DIAG, + + RTL_READ_MAC_OCP, + RTL_WRITE_MAC_OCP, + + RTL_DIRECT_READ_PHY_OCP, + RTL_DIRECT_WRITE_PHY_OCP, + + RTLTOOL_INVALID +}; + +struct rtltool_cmd { + __u32 cmd; + __u32 offset; + __u32 len; + __u32 data; +}; + +enum mode_access { + MODE_NONE=0, + MODE_READ, + MODE_WRITE +}; + +#ifdef __KERNEL__ +int rtl8126_tool_ioctl(struct rtl8126_private *tp, struct ifreq *ifr); +#endif + +#endif /* _LINUX_RTLTOOL_H */ diff --git a/package/lean/r8168/Makefile b/package/lean/r8168/Makefile index c1e59280a..1760cc50b 100644 --- a/package/lean/r8168/Makefile +++ b/package/lean/r8168/Makefile @@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=r8168 -PKG_VERSION:=8.052.01 +PKG_VERSION:=8.053.00 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/mtorromeo/r8168/tar.gz/$(PKG_VERSION)? -PKG_HASH:=cd8ee58a260e9b654080d39e3a42e3a3fb821041ee79e631b4647d84120aa999 +PKG_HASH:=7c00cc13f17c45e1d1002e4c390f118204b04d42caba9d04d8ae95e953770857 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/package/lean/r8168/patches/100-add-LED-configuration-from-OF.patch b/package/lean/r8168/patches/100-add-LED-configuration-from-OF.patch index 62e2e56b8..6b556e961 100644 --- a/package/lean/r8168/patches/100-add-LED-configuration-from-OF.patch +++ b/package/lean/r8168/patches/100-add-LED-configuration-from-OF.patch @@ -8,7 +8,7 @@ #include #include #include -@@ -25852,6 +25853,22 @@ rtl8168_setup_mqs_reg(struct rtl8168_pri +@@ -25945,6 +25946,22 @@ rtl8168_setup_mqs_reg(struct rtl8168_pri tp->imr_reg[3] = IntrMask3; } @@ -31,7 +31,7 @@ static void rtl8168_init_software_variable(struct net_device *dev) { -@@ -26547,6 +26564,8 @@ err1: +@@ -26640,6 +26657,8 @@ err1: if (tp->InitRxDescType == RX_DESC_RING_TYPE_2) tp->RxDescLength = RX_DESC_LEN_TYPE_2; diff --git a/package/lean/vsftpd-alt/Makefile b/package/lean/vsftpd-alt/Makefile index db88e30c5..0d3cded03 100644 --- a/package/lean/vsftpd-alt/Makefile +++ b/package/lean/vsftpd-alt/Makefile @@ -9,12 +9,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=vsftpd-alt PKG_VERSION:=3.0.5 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=vsftpd-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://security.appspot.com/downloads/ PKG_HASH:=26b602ae454b0ba6d99ef44a09b6b9e0dfa7f67228106736df1f278c70bc91d3 PKG_LICENSE:=GPLv2 +PKG_CPE_ID:=cpe:/a:vsftpd_project:vsftpd BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/vsftpd-$(PKG_VERSION) @@ -48,6 +49,7 @@ endef ifneq ($(CONFIG_USE_MUSL),) NLSSTRING:=-lcrypt + TARGET_CFLAGS += -D_LARGEFILE64_SOURCE else ifneq ($(CONFIG_USE_GLIBC),) NLSSTRING:=-lcrypt else @@ -64,7 +66,7 @@ define Build/Compile $(SED) 's/-lcrypt -lnsl/$(NLSSTRING)/' $(PKG_BUILD_DIR)/Makefile $(MAKE) -C $(PKG_BUILD_DIR) \ CC="$(TARGET_CC)" \ - CFLAGS="$(TARGET_CFLAGS)" \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ LDFLAGS="$(TARGET_LDFLAGS)" \ vsftpd endef diff --git a/package/libs/elfutils/Makefile b/package/libs/elfutils/Makefile index d4e5d994e..94b01d73b 100644 --- a/package/libs/elfutils/Makefile +++ b/package/libs/elfutils/Makefile @@ -83,6 +83,11 @@ CONFIGURE_VARS += \ TARGET_CFLAGS += -D_GNU_SOURCE -Wno-unused-result -Wno-format-nonliteral +ifneq ($(filter $(GCC_MAJOR_VERSION),12 13),) +TARGET_CFLAGS += \ + -Wno-error=use-after-free +endif + define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/ diff --git a/package/libs/gettext-full/Makefile b/package/libs/gettext-full/Makefile index 2319401ba..55164644e 100644 --- a/package/libs/gettext-full/Makefile +++ b/package/libs/gettext-full/Makefile @@ -64,6 +64,7 @@ HOST_CONFIGURE_ARGS += \ --disable-rpath \ --disable-java \ --disable-openmp \ + --disable-curses \ --without-emacs \ --without-libxml2-prefix diff --git a/package/libs/gettext-full/patches/020-fix_clang.patch b/package/libs/gettext-full/patches/020-fix_clang.patch new file mode 100644 index 000000000..284b5ab9f --- /dev/null +++ b/package/libs/gettext-full/patches/020-fix_clang.patch @@ -0,0 +1,11 @@ +--- a/libtextstyle/lib/iconv-ostream.c ++++ b/libtextstyle/lib/iconv-ostream.c +@@ -231,7 +231,7 @@ iconv_ostream__write_mem (iconv_ostream_t stream, const void *data, size_t len) + } + + static void +-iconv_ostream__flush (iconv_ostream_t stream) ++iconv_ostream__flush (iconv_ostream_t stream, ostream_flush_scope_t scope) + { + abort (); + } diff --git a/package/libs/libjson-c/Makefile b/package/libs/libjson-c/Makefile index 2c312f200..063cf2644 100644 --- a/package/libs/libjson-c/Makefile +++ b/package/libs/libjson-c/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=json-c -PKG_VERSION:=0.16 -PKG_RELEASE:=2 +PKG_VERSION:=0.17 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-nodoc.tar.gz PKG_SOURCE_URL:=https://s3.amazonaws.com/json-c_releases/releases/ -PKG_HASH:=ac8a3dd6820daaca579b23fbc74664310fbc3d67f52f6707cda67d21dde5570f +PKG_HASH:=8df3b66597333dd365762cab2de2ff68e41e3808a04b692e696e0550648eefaa PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=MIT diff --git a/package/libs/libjson-c/patches/001-dont-build-docs.patch b/package/libs/libjson-c/patches/001-dont-build-docs.patch index f35da8072..1de420f8b 100644 --- a/package/libs/libjson-c/patches/001-dont-build-docs.patch +++ b/package/libs/libjson-c/patches/001-dont-build-docs.patch @@ -1,6 +1,6 @@ --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -433,8 +433,6 @@ configure_file(json.h.cmakein ${PROJECT_ +@@ -451,8 +451,6 @@ configure_file(json.h.cmakein ${PROJECT_ include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_BINARY_DIR}) diff --git a/package/libs/libnl-tiny/Makefile b/package/libs/libnl-tiny/Makefile index 4f09861ed..048c3e793 100644 --- a/package/libs/libnl-tiny/Makefile +++ b/package/libs/libnl-tiny/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libnl-tiny.git -PKG_SOURCE_DATE:=2022-11-01 -PKG_SOURCE_VERSION:=db3b2cdbca5277723326a2720024a59fb821ae36 -PKG_MIRROR_HASH:=f6f9e2cb5366cda3be6d27a6320aa6cf3681c0b10df07b29ab4e4005e9f04f1c +PKG_SOURCE_DATE:=2023-07-01 +PKG_SOURCE_VERSION:=d433990c00e804593f253cc709b8fe901492b530 +PKG_MIRROR_HASH:=fffb2782c7ed2ebabc7d57e5513f52ac53d1828014bc9a8ea131f50eab093086 CMAKE_INSTALL:=1 PKG_LICENSE:=LGPL-2.1 diff --git a/package/libs/libubox/Makefile b/package/libs/libubox/Makefile index a987304ba..e19a97cbb 100644 --- a/package/libs/libubox/Makefile +++ b/package/libs/libubox/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libubox.git -PKG_MIRROR_HASH:=071139fed757bea240d4ba8f55a0ff5a81862d23e16b39fc871ae07da78ae6a4 -PKG_SOURCE_DATE:=2024-01-26 -PKG_SOURCE_VERSION:=c1be505732e6d254464973bdeacb955214c76c46 +PKG_MIRROR_HASH:=400bef38b8c0f382e4e595a50bb52dfbdb8da820eb80f3447b9bd7be3f5499a5 +PKG_SOURCE_DATE:=2022-09-27 +PKG_SOURCE_VERSION:=ea56013409d5823001b47a9bba6f74055a6d76a5 PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) CMAKE_INSTALL:=1 @@ -105,14 +105,6 @@ CMAKE_HOST_OPTIONS += \ -DCMAKE_MACOSX_RPATH=1 \ -DCMAKE_INSTALL_RPATH="${STAGING_DIR_HOST}/lib" \ -ifeq ($(HOST_OS),Darwin) - define Host/Install - $(Host/Install/Default) - $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/lib - cd "$(STAGING_DIR_HOSTPKG)/lib" && ln -sf ../../host/lib/libubox.* . - endef -endif - $(eval $(call BuildPackage,libubox)) $(eval $(call BuildPackage,libblobmsg-json)) $(eval $(call BuildPackage,jshn)) diff --git a/package/libs/libusb/Makefile b/package/libs/libusb/Makefile index 0c6de7cb6..65c624409 100644 --- a/package/libs/libusb/Makefile +++ b/package/libs/libusb/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libusb PKG_VERSION:=1.0.26 -PKG_RELEASE:=3 +PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=\ diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 4f49375b1..0067723ed 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl -PKG_VERSION:=3.0.13 +PKG_VERSION:=3.0.14 PKG_RELEASE:=1 PKG_USE_MIPS16:=0 PKG_BUILD_FLAGS:=gc-sections no-lto @@ -27,7 +27,7 @@ PKG_SOURCE_URL:= \ ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \ ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/old/$(PKG_BASE)/ -PKG_HASH:=88525753f79d3bec27d2fa7c66aa0b92b3aa9498dafd93d7cfa4b3780cdae313 +PKG_HASH:=eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile index 6e99960ec..087ef5d0f 100644 --- a/package/network/config/firewall/Makefile +++ b/package/network/config/firewall/Makefile @@ -28,7 +28,9 @@ define Package/firewall SECTION:=net CATEGORY:=Base system TITLE:=OpenWrt C Firewall - DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat +iptables-mod-fullconenat + DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +iptables-mod-conntrack-extra +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat +iptables-mod-fullconenat + PROVIDES:=uci-firewall + CONFLICTS:=firewall4 endef define Package/firewall/description diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index 42e3f27df..42f6f6aa3 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -3,7 +3,7 @@ config defaults option input ACCEPT option output ACCEPT option forward REJECT - option fullcone 0 + option fullcone 0 # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 diff --git a/package/network/config/firewall/files/firewall.init b/package/network/config/firewall/files/firewall.init index 8fc8c6b07..2d641d049 100755 --- a/package/network/config/firewall/files/firewall.init +++ b/package/network/config/firewall/files/firewall.init @@ -69,8 +69,8 @@ stop_service() { } reload_service() { - unset_lock - set_lock + unset_lock + set_lock reload_config firewall fw3 reload unset_lock diff --git a/package/network/ipv6/ipip6/Makefile b/package/network/ipv6/ipip6/Makefile new file mode 100644 index 000000000..4f1469610 --- /dev/null +++ b/package/network/ipv6/ipip6/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (C) 2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ipip6 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/ipip6 + SECTION:=net + CATEGORY:=Network + DEPENDS:=@IPV6 +kmod-ip6-tunnel +resolveip + TITLE:=IPv4 over IPv6 (ipip6) configuration support + MAINTAINER:=Missing + PKGARCH:=all +endef + +define Package/ipip6/description +Provides support for IPv4 over IPv6 (ipip6) in /etc/config/network. +endef + +define Build/Compile +endef + +define Build/Configure +endef + +define Package/ipip6/install + $(INSTALL_DIR) $(1)/lib/netifd/proto + $(INSTALL_BIN) ./files/ipip6.sh $(1)/lib/netifd/proto/ipip6.sh +endef + +$(eval $(call BuildPackage,ipip6)) diff --git a/package/network/ipv6/ipip6/files/ipip6.sh b/package/network/ipv6/ipip6/files/ipip6.sh new file mode 100755 index 000000000..6653b29a7 --- /dev/null +++ b/package/network/ipv6/ipip6/files/ipip6.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# ipip6.sh - ipip6 tunnel backend +# Copyright (c) 2013 OpenWrt.org + +[ -n "$INCLUDE_ONLY" ] || { + . /lib/functions.sh + . /lib/functions/network.sh + . ../netifd-proto.sh + init_proto "$@" +} + +proto_ipip6_setup() { + local cfg="$1" + local iface="$2" + local link="ipip6-$cfg" + local remoteip6 + + local mtu ttl peeraddr ip6addr tunlink zone weakif encaplimit ip4ifaddr + json_get_vars mtu ttl peeraddr ip6addr tunlink zone weakif encaplimit ip4ifaddr + + [ -z "$peeraddr" ] && { + proto_notify_error "$cfg" "MISSING_ADDRESS" + proto_block_restart "$cfg" + return + } + + ( proto_add_host_dependency "$cfg" "::" "$tunlink" ) + + remoteip6=$(resolveip -6 "$peeraddr") + if [ -z "$remoteip6" ]; then + sleep 3 + remoteip6=$(resolveip -6 "$peeraddr") + if [ -z "$remoteip6" ]; then + proto_notify_error "$cfg" "AFTR_DNS_FAIL" + return + fi + fi + + for ip6 in $remoteip6; do + peeraddr=$ip6 + break + done + + [ -z "$ip6addr" ] && { + local wanif="$tunlink" + if [ -z "$wanif" ] && ! network_find_wan6 wanif; then + proto_notify_error "$cfg" "NO_WAN_LINK" + return + fi + + if ! network_get_ipaddr6 ip6addr "$wanif"; then + [ -z "$weakif" ] && weakif="lan" + if ! network_get_ipaddr6 ip6addr "$weakif"; then + proto_notify_error "$cfg" "NO_WAN_LINK" + return + fi + fi + } + + proto_init_update "$link" 1 + proto_add_ipv4_route "0.0.0.0" 0 + proto_add_ipv4_address "$ip4ifaddr" "" "" "0.0.0.0" + + proto_add_tunnel + json_add_string mode ipip6 + json_add_int mtu "${mtu:-1280}" + json_add_int ttl "${ttl:-64}" + json_add_string local "$ip6addr" + json_add_string remote "$peeraddr" + [ -n "$tunlink" ] && json_add_string link "$tunlink" + json_add_object "data" + [ -n "$encaplimit" ] && json_add_string encaplimit "$encaplimit" + json_close_object + proto_close_tunnel + + proto_add_data + [ -n "$zone" ] && json_add_string zone "$zone" + + proto_close_data + + proto_send_update "$cfg" +} + +proto_ipip6_teardown() { + local cfg="$1" +} + +proto_ipip6_init_config() { + no_device=1 + available=1 + + proto_config_add_string "ip6addr" + proto_config_add_string "peeraddr" + proto_config_add_string "tunlink" + proto_config_add_int "mtu" + proto_config_add_int "ttl" + proto_config_add_string "encaplimit" + proto_config_add_string "zone" + proto_config_add_string "weakif" + proto_config_add_string "ip4ifaddr" +} + +[ -n "$INCLUDE_ONLY" ] || { + add_protocol ipip6 +} diff --git a/package/network/ipv6/map/Makefile b/package/network/ipv6/map/Makefile index f73b5eefb..cb2b5c579 100644 --- a/package/network/ipv6/map/Makefile +++ b/package/network/ipv6/map/Makefile @@ -17,7 +17,7 @@ include $(INCLUDE_DIR)/cmake.mk define Package/map SECTION:=net CATEGORY:=Network - DEPENDS:=@IPV6 +kmod-ip6-tunnel +libubox +libubus +iptables-mod-conntrack-extra +kmod-nat46 + DEPENDS:=@IPV6 +kmod-ip6-tunnel +libubox +libubus +kmod-nat46 TITLE:=MAP-E/MAP-T and Lightweight 4over6 configuration support MAINTAINER:=Hans Dedecker PROVIDES:=map-t diff --git a/package/network/services/bridger/Makefile b/package/network/services/bridger/Makefile index f8f21be4d..e228de517 100644 --- a/package/network/services/bridger/Makefile +++ b/package/network/services/bridger/Makefile @@ -10,15 +10,17 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bridger PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/nbd168/bridger -PKG_SOURCE_DATE:=2023-01-03 -PKG_SOURCE_VERSION:=978c1f9eed07504cc0b84f72ee7384aab722386a -PKG_MIRROR_HASH:=2a019b188d8de2fdc95453529d1820b0a7a5576adf161bd19e182c9c1c2b2c85 +PKG_SOURCE_DATE:=2023-05-12 +PKG_SOURCE_VERSION:=d0f79a16c749ad310d79e1c31f593860619f99eb +PKG_MIRROR_HASH:=bee35594767cbcd13764f5c95e4837a4fc73171a91fcdae73aaefe00f4e8f8fa PKG_LICENSE:=GPL-2.0 PKG_MAINTAINER:=Felix Fietkau PKG_BUILD_DEPENDS:=bpf-headers +PKG_BUILD_PARALLEL:=1 + include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk include $(INCLUDE_DIR)/bpf.mk diff --git a/package/network/services/dnsmasq/files/dhcp.conf b/package/network/services/dnsmasq/files/dhcp.conf index 9865eb696..3f054f5fe 100644 --- a/package/network/services/dnsmasq/files/dhcp.conf +++ b/package/network/services/dnsmasq/files/dhcp.conf @@ -31,7 +31,6 @@ config dhcp lan option start 100 option limit 150 option leasetime 12h - option force 1 config dhcp wan option interface wan diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init index 25f670a90..7fa50803f 100755 --- a/package/network/services/dnsmasq/files/dnsmasq.init +++ b/package/network/services/dnsmasq/files/dnsmasq.init @@ -1285,4 +1285,4 @@ stop_service() { else config_foreach dnsmasq_stop dnsmasq fi -} \ No newline at end of file +} diff --git a/package/network/services/fullconenat/Makefile b/package/network/services/fullconenat/Makefile index 94383510d..151b2b70f 100644 --- a/package/network/services/fullconenat/Makefile +++ b/package/network/services/fullconenat/Makefile @@ -28,7 +28,7 @@ define Package/iptables-mod-fullconenat SECTION:=net CATEGORY:=Network TITLE:=FULLCONENAT iptables extension - DEPENDS:=+iptables +kmod-ipt-fullconenat + DEPENDS:=+libxtables +kmod-ipt-fullconenat endef define Package/iptables-mod-fullconenat/install @@ -44,6 +44,7 @@ define KernelPackage/ipt-fullconenat CONFIG_NF_CONNTRACK_EVENTS=y \ CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y FILES:=$(PKG_BUILD_DIR)/xt_FULLCONENAT.ko + AUTOLOAD:=$(call AutoProbe,xt_FULLCONENAT) endef include $(INCLUDE_DIR)/kernel-defaults.mk diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in index 87ad7e093..8f28eb2bd 100644 --- a/package/network/services/hostapd/Config.in +++ b/package/network/services/hostapd/Config.in @@ -73,6 +73,11 @@ config WPA_WOLFSSL select WOLFSSL_HAS_SESSION_TICKET select WOLFSSL_HAS_WPAS +config DRIVER_WEXT_SUPPORT + bool + select KERNEL_WIRELESS_EXT + default n + config DRIVER_11AC_SUPPORT bool default n diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index dc2967048..d91ba3dbe 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=1.2 +PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE_URL:=http://w1.fi/hostap.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-03-29 -PKG_SOURCE_VERSION:=bb945b98fefc64887dffb40773a19d77585cee42 -PKG_MIRROR_HASH:=1da8a39c7c81ce257994874402a86d00080a6145b5eb5c5fc44b2fae1853fe8d +PKG_SOURCE_DATE:=2022-07-29 +PKG_SOURCE_VERSION:=b704dc72ef824dfdd96674b90179b274d1d38105 +PKG_MIRROR_HASH:=6c9dd359ef5a4595b6576e07928566d6864957c4af6466d641d6c3f7717f4689 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=BSD-3-Clause @@ -27,6 +27,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_hostapd-basic \ CONFIG_PACKAGE_hostapd-mini \ CONFIG_WPA_RFKILL_SUPPORT \ + CONFIG_DRIVER_WEXT_SUPPORT \ CONFIG_DRIVER_11AC_SUPPORT \ CONFIG_DRIVER_11AX_SUPPORT \ CONFIG_WPA_ENABLE_WEP @@ -86,6 +87,7 @@ DRIVER_MAKEOPTS= \ CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ + CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ CONFIG_MBO=$(CONFIG_WPA_MBO_SUPPORT) ifeq ($(SSL_VARIANT),openssl) @@ -139,7 +141,7 @@ ifneq ($(LOCAL_TYPE),hostapd) endif endif -DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +kmod-cfg80211 define Package/hostapd/Default diff --git a/package/network/services/hostapd/README.md b/package/network/services/hostapd/README.md deleted file mode 100644 index 215086330..000000000 --- a/package/network/services/hostapd/README.md +++ /dev/null @@ -1,419 +0,0 @@ -# UBUS methods - hostapd - -## bss_mgmt_enable -Enable 802.11k/v features. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| neighbor_report | bool | no | enable 802.11k neighbor reports | -| beacon_report | bool | no | enable 802.11k beacon reports | -| link_measurements | bool | no | enable 802.11k link measurements | -| bss_transition | bool | no | enable 802.11v BSS transition support | - -### example -`ubus call hostapd.wl5-fb bss_mgmt_enable '{ "neighbor_report": true, "beacon_report": true, "link_measurements": true, "bss_transition": true -}'` - - -## bss_transition_request -Initiate an 802.11v transition request. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| addr | string | yes | client MAC address | -| disassociation_imminent | bool | no | set Disassociation Imminent bit | -| disassociation_timer | int32 | no | disassociate client if it doesn't roam after this time | -| validity_period | int32 | no | validity of the BSS Transition Candiate List | -| neighbors | array | no | BSS Transition Candidate List | -| abridged | bool | no | prefer APs in the BSS Transition Candidate List | -| dialog_token | int32 | no | identifier for the request/report transaction | -| mbo_reason | int32 | no | MBO Transition Reason Code Attribute | -| cell_pref | int32 | no | MBO Cellular Data Connection Preference Attribute | -| reassoc_delay | int32 | no | MBO Re-association retry delay | - -### example -`ubus call hostapd.wl5-fb bss_transition_request '{ "addr": "68:2F:67:8B:98:ED", "disassociation_imminent": false, "disassociation_timer": 0, "validity_period": 30, "neighbors": ["b6a7b9cbeebabf5900008064090603026a00"], "abridged": 1 }'` - - -## config_add -Dynamically load a BSS configuration from a file. This is used by netifd's mac80211 support script to configure BSSes on multiple PHYs in a single hostapd instance. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| iface | string | yes | WiFi interface name | -| config | string | yes | path to hostapd config file | - - -## config_remove -Dynamically remove a BSS configuration. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| iface | string | yes | WiFi interface name | - - -## del_client -Kick a client off the network. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| addr | string | yes | client MAC address | -| reason | int32 | no | 802.11 reason code | -| deauth | bool | no | deauthenticates client instead of disassociating | -| ban_time | int32 | no | ban client for N milliseconds | - -### example -`ubus call hostapd.wl5-fb del_client '{ "addr": "68:2f:67:8b:98:ed", "reason": 5, "deauth": true, "ban_time": 10000 }'` - - -## get_clients -Show associated clients. - -### example -`ubus call hostapd.wl5-fb get_clients` - -### output -```json -{ - "freq": 5260, - "clients": { - "68:2f:67:8b:98:ed": { - "auth": true, - "assoc": true, - "authorized": true, - "preauth": false, - "wds": false, - "wmm": true, - "ht": true, - "vht": true, - "he": false, - "wps": false, - "mfp": true, - "rrm": [ - 0, - 0, - 0, - 0, - 0 - ], - "extended_capabilities": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 64 - ], - "aid": 3, - "signature": "wifi4|probe:0,1,45,127,107,191,221(0017f2,10),221(001018,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,extcap:0000008000000040|assoc:0,1,33,36,48,45,127,191,221(0017f2,10),221(001018,2),221(0050f2,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,txpow:14f9,extcap:0000000000000040", - "bytes": { - "rx": 1933667, - "tx": 746805 - }, - "airtime": { - "rx": 208863, - "tx": 9037883 - }, - "packets": { - "rx": 3587, - "tx": 2185 - }, - "rate": { - "rx": 866700, - "tx": 866700 - }, - "signal": -50, - "capabilities": { - "vht": { - "su_beamformee": true, - "mu_beamformee": false, - "mcs_map": { - "rx": { - "1ss": 9, - "2ss": 9, - "3ss": 9, - "4ss": -1, - "5ss": -1, - "6ss": -1, - "7ss": -1, - "8ss": -1 - }, - "tx": { - "1ss": 9, - "2ss": 9, - "3ss": 9, - "4ss": -1, - "5ss": -1, - "6ss": -1, - "7ss": -1, - "8ss": -1 - } - } - } - } - } - } -} -``` - - -## get_features -Show HT/VHT support. - -### example -`ubus call hostapd.wl5-fb get_features` - -### output -```json -{ - "ht_supported": true, - "vht_supported": true -} -``` - - -## get_status -Get BSS status. - -### example -`ubus call hostapd.wl5-fb get_status` - -### output -```json -{ - "status": "ENABLED", - "bssid": "b6:a7:b9:cb:ee:bc", - "ssid": "fb", - "freq": 5260, - "channel": 52, - "op_class": 128, - "beacon_interval": 100, - "phy": "wl5-lan", - "rrm": { - "neighbor_report_tx": 0 - }, - "wnm": { - "bss_transition_query_rx": 0, - "bss_transition_request_tx": 0, - "bss_transition_response_rx": 0 - }, - "airtime": { - "time": 259561738, - "time_busy": 2844249, - "utilization": 0 - }, - "dfs": { - "cac_seconds": 60, - "cac_active": false, - "cac_seconds_left": 0 - } -} -``` - - -## link_measurement_req -Initiate an 802.11k Link Measurement Request. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| addr | string | yes | client MAC address | -| tx-power-used | int32 | no | transmit power used to transmit the Link Measurement Request frame | -| tx-power-max | int32 | no | upper limit of transmit power to be used by the client | - - -## list_bans -List banned clients. - -### example -`ubus call hostapd.wl5-fb list_bans` - -### output -```json -{ - "clients": [ - "68:2f:67:8b:98:ed" - ] -} -``` - - -## notify_response -When enabled, hostapd will send a ubus notification and wait for a response before responding to various requests. This is used by e.g. usteer to make it possible to ignore probe requests. - -:warning: enabling this will cause hostapd to stop responding to probe requests unless a ubus subscriber responds to the ubus notifications. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| notify_response | int32 | yes | disable (0) or enable (!0) | - -### example -`ubus call hostapd.wl5-fb notify_response '{ "notify_response": 1 }'` - -## reload -Reload BSS configuration. - -:warning: this can cause problems for certain configurations: - -``` -Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 -Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 -Mon May 16 16:09:08 2022 daemon.err hostapd: Wrong coupling between HT and VHT/HE channel setting -``` - -### example -`ubus call hostapd.wl5-fb reload` - - -## rrm_beacon_req -Send a Beacon Measurement Request to a client. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| addr | string | yes | client MAC address | -| op_class | int32 | yes | the Regulatory Class for which this Measurement Request applies | -| channel | int32 | yes | channel to measure | -| duration | int32 | yes | compile Beacon Measurement Report after N TU | -| mode | int32 | yes | mode to be used for measurement (0: passive, 1: active, 2: beacon table) | -| bssid | string | no | filter BSSes in Beacon Measurement Report by BSSID | -| ssid | string | no | filter BSSes in Beacon Measurement Report by SSID| - - -## rrm_nr_get_own -Show Neighbor Report Element for this BSS. - -### example -`ubus call hostapd.wl5-fb rrm_nr_get_own` - -### output -```json -{ - "value": [ - "b6:a7:b9:cb:ee:bc", - "fb", - "b6a7b9cbeebcaf5900008095090603029b00" - ] -} -``` - - -## rrm_nr_list -Show Neighbor Report Elements for other BSSes in this ESS. - -### example -`ubus call hostapd.wl5-fb rrm_nr_list` - -### output -```json -{ - "list": [ - [ - "b6:a7:b9:cb:ee:ba", - "fb", - "b6a7b9cbeebabf5900008064090603026a00" - ] - ] -} -``` - -## rrm_nr_set -Set the Neighbor Report Elements. An element for the node on which this command is executed will always be added. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| list | array | yes | array of Neighbor Report Elements in the format of the rrm_nr_list output | - -### example -`ubus call hostapd.wl5-fb rrm_nr_set '{ "list": [ [ "b6:a7:b9:cb:ee:ba", "fb", "b6a7b9cbeebabf5900008064090603026a00" ] ] }'` - - -## set_vendor_elements -Configure Vendor-specific Information Elements for BSS. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| vendor_elements | string | yes | Vendor-specific Information Elements as hex string | - -### example -`ubus call hostapd.wl5-fb set_vendor_elements '{ "vendor_elements": "dd054857dd6662" }'` - - -## switch_chan -Initiate a channel switch. - -:warning: trying to switch to the channel that is currently in use will fail: `Command failed: Operation not supported` - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| freq | int32 | yes | frequency in MHz to switch to | -| bcn_count | int32 | no | count in Beacon frames (TBTT) to perform the switch | -| center_freq1 | int32 | no | segment 0 center frequency in MHz (valid for HT and VHT) | -| center_freq2 | int32 | no | segment 1 center frequency in MHz (valid only for 80 MHz channel width and an 80+80 channel) | -| bandwidth | int32 | no | channel width to use | -| sec_channel_offset| int32 | no | secondary channel offset for HT40 (0 = disabled, 1 = HT40+, -1 = HT40-) | -| ht | bool | no | enable 802.11n | -| vht | bool | no | enable 802.11ac | -| he | bool | no | enable 802.11ax | -| block_tx | bool | no | block transmission during CSA period | -| csa_force | bool | no | restart the interface in case the CSA fails | - -## example -`ubus call hostapd.wl5-fb switch_chan '{ "freq": 5180, "bcn_count": 10, "center_freq1": 5210, "bandwidth": 80, "he": 1, "block_tx": 1, "csa_force": 0 }'` - - -## update_airtime -Set dynamic airtime weight for client. - -### arguments -| Name | Type | Required | Description | -|---|---|---|---| -| sta | string | yes | client MAC address | -| weight | int32 | yes | airtime weight | - - -## update_beacon -Force beacon frame content to be updated and to start beaconing on an interface that uses start_disabled=1. - -### example -`ubus call hostapd.wl5-fb update_beacon` - - -## wps_status -Get WPS status for BSS. - -### example -`ubus call hostapd.wl5-fb wps_status` - -### output -```json -{ - "pbc_status": "Disabled", - "last_wps_result": "None" -} -``` - - -## wps_cancel -Cancel WPS Push Button Configuration. - -### example -`ubus call hostapd.wl5-fb wps_cancel` - - -## wps_start -Start WPS Push Button Configuration. - -### example -`ubus call hostapd.wl5-fb wps_start` diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index bf3625c92..a714356e0 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -116,12 +116,12 @@ hostapd_common_add_device_config() { config_add_int rssi_reject_assoc_rssi config_add_int rssi_ignore_probe_request config_add_int maxassoc + config_add_boolean vendor_vht config_add_string acs_chan_bias config_add_array hostapd_options config_add_int airtime_mode - config_add_int mbssid hostapd_add_log_config } @@ -135,7 +135,7 @@ hostapd_prepare_device_config() { json_get_vars country country3 country_ie beacon_int:100 doth require_mode legacy_rates \ acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \ - mbssid:0 + vendor_vht hostapd_set_log_options base_cfg @@ -204,6 +204,7 @@ hostapd_prepare_device_config() { set_default rate_list "24000 36000 48000 54000" set_default basic_rate_list "24000" fi + [ -n "$vendor_vht" ] && append base_cfg "vendor_vht=$vendor_vht" "$N" ;; a) if [ "$cell_density" -eq 1 ]; then @@ -236,7 +237,6 @@ hostapd_prepare_device_config() { [ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N" [ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N" [ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N" - [ "$mbssid" -gt 0 ] && [ "$mbssid" -le 2 ] && append base_cfg "mbssid=$mbssid" "$N" json_get_values opts hostapd_options for val in $opts; do diff --git a/package/network/services/hostapd/files/wpa_supplicant-basic.config b/package/network/services/hostapd/files/wpa_supplicant-basic.config index 944b4d928..6abd8e233 100644 --- a/package/network/services/hostapd/files/wpa_supplicant-basic.config +++ b/package/network/services/hostapd/files/wpa_supplicant-basic.config @@ -26,7 +26,7 @@ # replacement for WEXT and its use allows wpa_supplicant to properly control # the driver to improve existing functionality like roaming and to support new # functionality. -#CONFIG_DRIVER_WEXT=y +CONFIG_DRIVER_WEXT=y # Driver interface for Linux drivers using the nl80211 kernel interface CONFIG_DRIVER_NL80211=y diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config index b39dabca0..d24fbbb01 100644 --- a/package/network/services/hostapd/files/wpa_supplicant-full.config +++ b/package/network/services/hostapd/files/wpa_supplicant-full.config @@ -26,7 +26,7 @@ # replacement for WEXT and its use allows wpa_supplicant to properly control # the driver to improve existing functionality like roaming and to support new # functionality. -#CONFIG_DRIVER_WEXT=y +CONFIG_DRIVER_WEXT=y # Driver interface for Linux drivers using the nl80211 kernel interface CONFIG_DRIVER_NL80211=y diff --git a/package/network/services/hostapd/files/wpa_supplicant-mini.config b/package/network/services/hostapd/files/wpa_supplicant-mini.config index 2a3f8fb69..9eb1111e5 100644 --- a/package/network/services/hostapd/files/wpa_supplicant-mini.config +++ b/package/network/services/hostapd/files/wpa_supplicant-mini.config @@ -26,7 +26,7 @@ # replacement for WEXT and its use allows wpa_supplicant to properly control # the driver to improve existing functionality like roaming and to support new # functionality. -#CONFIG_DRIVER_WEXT=y +CONFIG_DRIVER_WEXT=y # Driver interface for Linux drivers using the nl80211 kernel interface CONFIG_DRIVER_NL80211=y diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config index 7f5140622..0dcc88e64 100644 --- a/package/network/services/hostapd/files/wpa_supplicant-p2p.config +++ b/package/network/services/hostapd/files/wpa_supplicant-p2p.config @@ -26,7 +26,7 @@ # replacement for WEXT and its use allows wpa_supplicant to properly control # the driver to improve existing functionality like roaming and to support new # functionality. -#CONFIG_DRIVER_WEXT=y +CONFIG_DRIVER_WEXT=y # Driver interface for Linux drivers using the nl80211 kernel interface CONFIG_DRIVER_NL80211=y diff --git a/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch b/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch index 761fe368c..6bc48abfb 100644 --- a/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch +++ b/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch @@ -14,7 +14,7 @@ Signed-off-by: Peter Oh --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -2621,7 +2621,7 @@ static int drv_supports_vht(struct wpa_s +@@ -2436,7 +2436,7 @@ static int drv_supports_vht(struct wpa_s } @@ -23,7 +23,7 @@ Signed-off-by: Peter Oh { int i; -@@ -2630,7 +2630,10 @@ static bool ibss_mesh_is_80mhz_avail(int +@@ -2445,7 +2445,10 @@ static bool ibss_mesh_is_80mhz_avail(int chan = hw_get_channel_chan(mode, i, NULL); if (!chan || @@ -35,16 +35,16 @@ Signed-off-by: Peter Oh return false; } -@@ -2757,7 +2760,7 @@ static void ibss_mesh_select_40mhz(struc - const struct wpa_ssid *ssid, - struct hostapd_hw_modes *mode, - struct hostapd_freq_params *freq, -- int obss_scan) { -+ int obss_scan, bool dfs_enabled) { - int chan_idx; - struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; - int i, res; -@@ -2781,8 +2784,11 @@ static void ibss_mesh_select_40mhz(struc +@@ -2474,6 +2477,8 @@ void ibss_mesh_setup_freq(struct wpa_sup + int chwidth, seg0, seg1; + u32 vht_caps = 0; + bool is_24ghz, is_6ghz; ++ bool dfs_enabled = wpa_s->conf->country[0] && ++ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); + + freq->freq = ssid->frequency; + +@@ -2570,8 +2575,11 @@ void ibss_mesh_setup_freq(struct wpa_sup return; /* Check primary channel flags */ @@ -55,9 +55,9 @@ Signed-off-by: Peter Oh + if (!dfs_enabled) + return; - #ifdef CONFIG_HT_OVERRIDES - if (ssid->disable_ht40) -@@ -2808,8 +2814,11 @@ static void ibss_mesh_select_40mhz(struc + freq->channel = pri_chan->chan; + +@@ -2604,8 +2612,11 @@ void ibss_mesh_setup_freq(struct wpa_sup return; /* Check secondary channel flags */ @@ -70,34 +70,25 @@ Signed-off-by: Peter Oh if (ht40 == -1) { if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) -@@ -2863,7 +2872,7 @@ static bool ibss_mesh_select_80_160mhz(s - const struct wpa_ssid *ssid, - struct hostapd_hw_modes *mode, - struct hostapd_freq_params *freq, -- int ieee80211_mode, bool is_6ghz) { -+ int ieee80211_mode, bool is_6ghz, bool dfs_enabled) { - static const int bw80[] = { - 5180, 5260, 5500, 5580, 5660, 5745, 5825, - 5955, 6035, 6115, 6195, 6275, 6355, 6435, -@@ -2908,7 +2917,7 @@ static bool ibss_mesh_select_80_160mhz(s - goto skip_80mhz; +@@ -2694,7 +2705,7 @@ skip_to_6ghz: + return; - /* Use 40 MHz if channel not usable */ + /* Back to HT configuration if channel not usable */ - if (!ibss_mesh_is_80mhz_avail(channel, mode)) + if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled)) - goto skip_80mhz; + return; chwidth = CONF_OPER_CHWIDTH_80MHZ; -@@ -2922,7 +2931,7 @@ static bool ibss_mesh_select_80_160mhz(s - if ((mode->he_capab[ieee80211_mode].phy_cap[ - HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & - HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz && -- ibss_mesh_is_80mhz_avail(channel + 16, mode)) { -+ ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) { +@@ -2708,7 +2719,7 @@ skip_to_6ghz: + * above; check the remaining four 20 MHz channels for the total + * of 160 MHz bandwidth. + */ +- if (!ibss_mesh_is_80mhz_avail(channel + 16, mode)) ++ if (!ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) + return; + for (j = 0; j < ARRAY_SIZE(bw160); j++) { - if (freq->freq == bw160[j]) { - chwidth = CONF_OPER_CHWIDTH_160MHZ; -@@ -2950,10 +2959,12 @@ static bool ibss_mesh_select_80_160mhz(s +@@ -2738,10 +2749,12 @@ skip_to_6ghz: if (!chan) continue; @@ -113,23 +104,3 @@ Signed-off-by: Peter Oh /* Found a suitable second segment for 80+80 */ chwidth = CONF_OPER_CHWIDTH_80P80MHZ; -@@ -3008,6 +3019,7 @@ void ibss_mesh_setup_freq(struct wpa_sup - int i, obss_scan = 1; - u8 channel; - bool is_6ghz; -+ bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); - - freq->freq = ssid->frequency; - -@@ -3053,9 +3065,9 @@ void ibss_mesh_setup_freq(struct wpa_sup - freq->channel = channel; - /* Setup higher BW only for 5 GHz */ - if (mode->mode == HOSTAPD_MODE_IEEE80211A) { -- ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan); -+ ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); - if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq, -- ieee80211_mode, is_6ghz)) -+ ieee80211_mode, is_6ghz, dfs_enabled)) - freq->he_enabled = freq->vht_enabled = false; - } - diff --git a/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch b/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch index 20a8bee07..32a447914 100644 --- a/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch +++ b/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch @@ -29,7 +29,7 @@ Signed-off-by: Markus Theil enum dfs_channel_type { -@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa +@@ -515,9 +516,14 @@ dfs_get_valid_channel(struct hostapd_ifa int num_available_chandefs; int chan_idx, chan_idx2; int sec_chan_idx_80p80 = -1; @@ -44,7 +44,7 @@ Signed-off-by: Markus Theil wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); *secondary_channel = 0; *oper_centr_freq_seg0_idx = 0; -@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa +@@ -537,8 +543,20 @@ dfs_get_valid_channel(struct hostapd_ifa if (num_available_chandefs == 0) return NULL; @@ -68,7 +68,7 @@ Signed-off-by: Markus Theil if (!chan) { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -10739,6 +10739,10 @@ static int nl80211_switch_channel(void * +@@ -9948,6 +9948,10 @@ static int nl80211_switch_channel(void * if (ret) goto error; diff --git a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch index 827e122ba..80b23bdfc 100644 --- a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch +++ b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch @@ -1,6 +1,6 @@ --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -4168,6 +4168,13 @@ static int add_associated_sta(struct hos +@@ -4963,6 +4963,13 @@ static int add_associated_sta(struct hos * drivers to accept the STA parameter configuration. Since this is * after a new FT-over-DS exchange, a new TK has been derived, so key * reinstallation is not a concern for this case. @@ -14,7 +14,7 @@ */ wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", -@@ -4181,7 +4188,8 @@ static int add_associated_sta(struct hos +@@ -4976,7 +4983,8 @@ static int add_associated_sta(struct hos (!(sta->flags & WLAN_STA_AUTHORIZED) || (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && diff --git a/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch b/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch index f4f56f510..25801da33 100644 --- a/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch +++ b/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -3562,7 +3562,7 @@ static int hostapd_change_config_freq(st +@@ -3453,7 +3453,7 @@ static int hostapd_change_config_freq(st struct hostapd_freq_params *old_params) { int channel; diff --git a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch index c02d4b497..988fbbc6f 100644 --- a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch +++ b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -5590,26 +5587,29 @@ fail: +@@ -5344,26 +5341,29 @@ fail: static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) { @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau if (err < 0) { wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " MACSTR " ifindex=%d failed: %s", MAC2STR(addr), -@@ -5619,9 +5619,8 @@ static void rtnl_neigh_delete_fdb_entry( +@@ -5373,9 +5373,8 @@ static void rtnl_neigh_delete_fdb_entry( MACSTR, MAC2STR(addr)); } @@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau } -@@ -8275,7 +8274,6 @@ static void *i802_init(struct hostapd_da +@@ -7763,7 +7762,6 @@ static void *i802_init(struct hostapd_da (params->num_bridge == 0 || !params->bridge[0])) add_ifidx(drv, br_ifindex, drv->ifindex); @@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau if (bss->added_if_into_bridge || bss->already_in_bridge) { int err; -@@ -8292,7 +8290,6 @@ static void *i802_init(struct hostapd_da +@@ -7780,7 +7778,6 @@ static void *i802_init(struct hostapd_da goto failed; } } @@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { wpa_printf(MSG_DEBUG, -@@ -11605,13 +11602,14 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10813,13 +10810,14 @@ static int wpa_driver_br_add_ip_neigh(vo const u8 *ipaddr, int prefixlen, const u8 *addr) { @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau int res; if (!ipaddr || prefixlen == 0 || !addr) -@@ -11630,85 +11628,66 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10838,85 +10836,66 @@ static int wpa_driver_br_add_ip_neigh(vo } if (version == 4) { @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau addrsize = 16; } else { return -EINVAL; -@@ -11726,41 +11705,30 @@ static int wpa_driver_br_delete_ip_neigh +@@ -10934,41 +10913,30 @@ static int wpa_driver_br_delete_ip_neigh return -1; } diff --git a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch index 179d47ecc..6b34cd435 100644 --- a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch +++ b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -2948,15 +2948,6 @@ static void handle_auth(struct hostapd_d +@@ -3781,15 +3781,6 @@ static void handle_auth(struct hostapd_d seq_ctrl); return; } diff --git a/package/network/services/hostapd/patches/050-build_fix.patch b/package/network/services/hostapd/patches/050-build_fix.patch index 8680b07c6..c9268f59e 100644 --- a/package/network/services/hostapd/patches/050-build_fix.patch +++ b/package/network/services/hostapd/patches/050-build_fix.patch @@ -10,7 +10,7 @@ CFLAGS += -DCONFIG_FILS_SK_PFS --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -331,6 +331,7 @@ endif +@@ -320,6 +320,7 @@ endif ifdef CONFIG_FILS CFLAGS += -DCONFIG_FILS NEED_SHA384=y diff --git a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch index 22107944d..01af14b71 100644 --- a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch +++ b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch @@ -273,7 +273,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_RADIUS_SERVER CFLAGS += -DRADIUS_SERVER -@@ -1329,7 +1414,9 @@ NOBJS += ../src/utils/trace.o +@@ -1327,7 +1412,9 @@ NOBJS += ../src/utils/trace.o endif HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o @@ -283,7 +283,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_AES HOBJS += ../src/crypto/aes-internal.o HOBJS += ../src/crypto/aes-internal-enc.o -@@ -1352,13 +1439,17 @@ SOBJS += ../src/common/sae.o +@@ -1350,13 +1437,17 @@ SOBJS += ../src/common/sae.o SOBJS += ../src/common/sae_pk.o SOBJS += ../src/common/dragonfly.o SOBJS += $(AESOBJS) @@ -7765,7 +7765,7 @@ Signed-off-by: Glenn Strauss CONFIG_SIM_SIMULATOR=y --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1163,6 +1163,29 @@ endif +@@ -1149,6 +1149,29 @@ endif CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" endif @@ -7795,7 +7795,7 @@ Signed-off-by: Glenn Strauss ifeq ($(CONFIG_TLS), gnutls) ifndef CONFIG_CRYPTO # default to libgcrypt -@@ -1355,9 +1378,11 @@ endif +@@ -1341,9 +1364,11 @@ endif ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -7807,7 +7807,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP # Seems to be needed at least with BoringSSL NEED_INTERNAL_AES_WRAP=y -@@ -1371,9 +1396,11 @@ endif +@@ -1357,9 +1382,11 @@ endif ifdef NEED_INTERNAL_AES_WRAP ifneq ($(CONFIG_TLS), linux) @@ -7819,7 +7819,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_EAX AESOBJS += ../src/crypto/aes-eax.o NEED_AES_CTR=y -@@ -1383,35 +1410,45 @@ AESOBJS += ../src/crypto/aes-siv.o +@@ -1369,35 +1396,45 @@ AESOBJS += ../src/crypto/aes-siv.o NEED_AES_CTR=y endif ifdef NEED_AES_CTR @@ -7865,7 +7865,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_AES_ENC ifdef CONFIG_INTERNAL_AES AESOBJS += ../src/crypto/aes-internal-enc.o -@@ -1426,12 +1463,16 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1412,12 +1449,16 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -7882,7 +7882,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA1 SHA1OBJS += ../src/crypto/sha1-internal.o ifdef NEED_FIPS186_2_PRF -@@ -1443,29 +1484,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 +@@ -1429,29 +1470,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 else ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) @@ -7920,7 +7920,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_MD5 ifdef CONFIG_INTERNAL_MD5 MD5OBJS += ../src/crypto/md5-internal.o -@@ -1520,12 +1569,17 @@ ifneq ($(CONFIG_TLS), openssl) +@@ -1506,12 +1555,17 @@ ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), linux) ifneq ($(CONFIG_TLS), gnutls) ifneq ($(CONFIG_TLS), wolfssl) @@ -7938,7 +7938,7 @@ Signed-off-by: Glenn Strauss ifdef CONFIG_INTERNAL_SHA256 SHA256OBJS += ../src/crypto/sha256-internal.o endif -@@ -1538,50 +1592,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 +@@ -1524,50 +1578,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 SHA256OBJS += ../src/crypto/sha512-internal.o endif ifdef NEED_TLS_PRF_SHA256 @@ -8007,7 +8007,7 @@ Signed-off-by: Glenn Strauss ifdef NEED_ASN1 OBJS += ../src/tls/asn1.o -@@ -1756,10 +1828,12 @@ ifdef CONFIG_FIPS +@@ -1742,10 +1814,12 @@ ifdef CONFIG_FIPS CFLAGS += -DCONFIG_FIPS ifneq ($(CONFIG_TLS), openssl) ifneq ($(CONFIG_TLS), wolfssl) diff --git a/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch b/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch index a48725264..a0d287086 100644 --- a/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch +++ b/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch @@ -101,7 +101,7 @@ Signed-off-by: Glenn Strauss --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1174,10 +1174,6 @@ endif +@@ -1160,10 +1160,6 @@ endif OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o diff --git a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch index 148c268f9..9e9e88c1e 100644 --- a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch +++ b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch @@ -727,7 +727,7 @@ Signed-off-by: Glenn Strauss def check_ec_support(dev): tls = dev.request("GET tls_library") -@@ -1595,7 +1638,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma +@@ -1625,7 +1668,7 @@ def test_ap_wpa2_eap_ttls_pap_subject_ma eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP", @@ -736,7 +736,7 @@ Signed-off-by: Glenn Strauss altsubject_match="EMAIL:noone@example.com;DNS:server.w1.fi;URI:http://example.com/") eap_reauth(dev[0], "TTLS") -@@ -2830,6 +2873,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc +@@ -2860,6 +2903,7 @@ def test_ap_wpa2_eap_tls_neg_domain_matc def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): """WPA2-Enterprise negative test - subject mismatch""" @@ -744,7 +744,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", -@@ -2890,6 +2934,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat +@@ -2920,6 +2964,7 @@ def test_ap_wpa2_eap_tls_neg_subject_mat def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): """WPA2-Enterprise negative test - altsubject mismatch""" @@ -752,7 +752,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hostapd.add_ap(apdev[0], params) -@@ -3430,7 +3475,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde +@@ -3460,7 +3505,7 @@ def test_ap_wpa2_eap_ikev2_oom(dev, apde dev[0].request("REMOVE_NETWORK all") tls = dev[0].request("GET tls_library") @@ -761,7 +761,7 @@ Signed-off-by: Glenn Strauss tests = [(1, "os_get_random;dh_init")] else: tests = [(1, "crypto_dh_init;dh_init")] -@@ -4744,7 +4789,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4774,7 +4819,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca params["private_key"] = "auth_serv/iCA-server/server.key" hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -770,7 +770,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4810,6 +4855,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4840,6 +4885,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, "-sha1") def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md): @@ -778,7 +778,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["ca_cert"] = "auth_serv/iCA-server/ca-and-root.pem" params["server_cert"] = "auth_serv/iCA-server/server.pem" -@@ -4819,7 +4865,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -4849,7 +4895,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -787,7 +787,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4855,7 +4901,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ +@@ -4885,7 +4931,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -796,7 +796,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4905,7 +4951,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -4935,7 +4981,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca try: hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -805,7 +805,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -4972,7 +5018,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca +@@ -5002,7 +5048,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca hostapd.add_ap(apdev[0], params) tls = dev[0].request("GET tls_library") @@ -814,7 +814,7 @@ Signed-off-by: Glenn Strauss ca_cert = "auth_serv/iCA-user/ca-and-root.pem" client_cert = "auth_serv/iCA-user/user_and_ica.pem" else: -@@ -5230,6 +5276,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek +@@ -5260,6 +5306,7 @@ def test_ap_wpa2_eap_ttls_server_cert_ek def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" @@ -822,7 +822,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5242,6 +5289,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( +@@ -5272,6 +5319,7 @@ def test_ap_wpa2_eap_ttls_server_pkcs12( def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): """EAP-TTLS and server PKCS#12 file with extra certs""" @@ -830,7 +830,7 @@ Signed-off-by: Glenn Strauss skip_with_fips(dev[0]) params = int_eap_server_params() del params["server_cert"] -@@ -5264,6 +5312,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv +@@ -5294,6 +5342,7 @@ def test_ap_wpa2_eap_ttls_dh_params_serv def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" @@ -838,7 +838,7 @@ Signed-off-by: Glenn Strauss params = int_eap_server_params() params["dh_file"] = "auth_serv/dsaparam.pem" hapd = hostapd.add_ap(apdev[0], params) -@@ -5575,8 +5624,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 +@@ -5605,8 +5654,8 @@ def test_ap_wpa2_eap_non_ascii_identity2 def test_openssl_cipher_suite_config_wpas(dev, apdev): """OpenSSL cipher suite configuration on wpa_supplicant""" tls = dev[0].request("GET tls_library") @@ -849,7 +849,7 @@ Signed-off-by: Glenn Strauss params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") hapd = hostapd.add_ap(apdev[0], params) eap_connect(dev[0], hapd, "TTLS", "pap user", -@@ -5602,14 +5651,14 @@ def test_openssl_cipher_suite_config_wpa +@@ -5632,14 +5681,14 @@ def test_openssl_cipher_suite_config_wpa def test_openssl_cipher_suite_config_hapd(dev, apdev): """OpenSSL cipher suite configuration on hostapd""" tls = dev[0].request("GET tls_library") @@ -868,7 +868,7 @@ Signed-off-by: Glenn Strauss eap_connect(dev[0], hapd, "TTLS", "pap user", anonymous_identity="ttls", password="password", ca_cert="auth_serv/ca.pem", phase2="auth=PAP") -@@ -6051,13 +6100,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a +@@ -6081,13 +6130,17 @@ def test_ap_wpa2_eap_tls_versions(dev, a check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") @@ -891,7 +891,7 @@ Signed-off-by: Glenn Strauss if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls: check_tls_ver(dev[0], hapd, "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3") -@@ -6079,6 +6132,11 @@ def test_ap_wpa2_eap_tls_versions_server +@@ -6109,6 +6162,11 @@ def test_ap_wpa2_eap_tls_versions_server tests = [("TLSv1", "[ENABLE-TLSv1.0][DISABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.1", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][DISABLE-TLSv1.2][DISABLE-TLSv1.3]"), ("TLSv1.2", "[ENABLE-TLSv1.0][ENABLE-TLSv1.1][ENABLE-TLSv1.2][DISABLE-TLSv1.3]")] @@ -903,7 +903,7 @@ Signed-off-by: Glenn Strauss for exp, flags in tests: hapd.disable() hapd.set("tls_flags", flags) -@@ -7115,6 +7173,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde +@@ -7145,6 +7203,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde def test_eap_tls_ext_cert_check(dev, apdev): """EAP-TLS and external server certification validation""" # With internal server certificate chain validation @@ -911,7 +911,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", identity="tls user", ca_cert="auth_serv/ca.pem", -@@ -7127,6 +7186,7 @@ def test_eap_tls_ext_cert_check(dev, apd +@@ -7157,6 +7216,7 @@ def test_eap_tls_ext_cert_check(dev, apd def test_eap_ttls_ext_cert_check(dev, apdev): """EAP-TTLS and external server certification validation""" # Without internal server certificate chain validation @@ -919,7 +919,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="pap user", anonymous_identity="ttls", password="password", phase2="auth=PAP", -@@ -7137,6 +7197,7 @@ def test_eap_ttls_ext_cert_check(dev, ap +@@ -7167,6 +7227,7 @@ def test_eap_ttls_ext_cert_check(dev, ap def test_eap_peap_ext_cert_check(dev, apdev): """EAP-PEAP and external server certification validation""" # With internal server certificate chain validation @@ -927,7 +927,7 @@ Signed-off-by: Glenn Strauss id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", identity="user", anonymous_identity="peap", ca_cert="auth_serv/ca.pem", -@@ -7147,6 +7208,7 @@ def test_eap_peap_ext_cert_check(dev, ap +@@ -7177,6 +7238,7 @@ def test_eap_peap_ext_cert_check(dev, ap def test_eap_fast_ext_cert_check(dev, apdev): """EAP-FAST and external server certification validation""" @@ -935,7 +935,7 @@ Signed-off-by: Glenn Strauss check_eap_capa(dev[0], "FAST") # With internal server certificate chain validation dev[0].request("SET blob fast_pac_auth_ext ") -@@ -7161,10 +7223,6 @@ def test_eap_fast_ext_cert_check(dev, ap +@@ -7191,10 +7253,6 @@ def test_eap_fast_ext_cert_check(dev, ap run_ext_cert_check(dev, apdev, id) def run_ext_cert_check(dev, apdev, net_id): @@ -948,7 +948,7 @@ Signed-off-by: Glenn Strauss --- a/tests/hwsim/test_ap_ft.py +++ b/tests/hwsim/test_ap_ft.py -@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev): +@@ -2347,11 +2347,11 @@ def test_ap_ft_ap_oom5(dev, apdev): # This will fail to roam dev[0].roam(bssid1, check_bssid=False) @@ -992,7 +992,7 @@ Signed-off-by: Glenn Strauss raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) capa = dev.request("GET_CAPABILITY dpp") ver = 1 -@@ -3892,6 +3893,9 @@ def test_dpp_proto_auth_req_no_i_proto_k +@@ -3621,6 +3622,9 @@ def test_dpp_proto_auth_req_no_i_proto_k def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): """DPP protocol testing - invalid I-proto key in Auth Req""" @@ -1002,7 +1002,7 @@ Signed-off-by: Glenn Strauss run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): -@@ -3987,7 +3991,12 @@ def test_dpp_proto_auth_resp_no_r_proto_ +@@ -3716,7 +3720,12 @@ def test_dpp_proto_auth_resp_no_r_proto_ def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): """DPP protocol testing - invalid R-Proto Key in Auth Resp""" @@ -1016,7 +1016,7 @@ Signed-off-by: Glenn Strauss def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): """DPP protocol testing - no R-nonce in Auth Resp""" -@@ -4349,11 +4358,17 @@ def test_dpp_proto_pkex_exchange_resp_in +@@ -4078,11 +4087,17 @@ def test_dpp_proto_pkex_exchange_resp_in def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" @@ -1106,7 +1106,7 @@ Signed-off-by: Glenn Strauss raise HwsimSkip("EC group not supported") --- a/tests/hwsim/test_pmksa_cache.py +++ b/tests/hwsim/test_pmksa_cache.py -@@ -955,7 +955,7 @@ def test_pmksa_cache_preauth_wpas_oom(de +@@ -954,7 +954,7 @@ def test_pmksa_cache_preauth_wpas_oom(de eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", password_hex="0123456789abcdef0123456789abcdef", bssid=apdev[0]['bssid']) @@ -1115,7 +1115,7 @@ Signed-off-by: Glenn Strauss with alloc_fail(dev[0], i, "rsn_preauth_init"): res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip() logger.info("Iteration %d - PREAUTH command results: %s" % (i, res)) -@@ -963,7 +963,7 @@ def test_pmksa_cache_preauth_wpas_oom(de +@@ -962,7 +962,7 @@ def test_pmksa_cache_preauth_wpas_oom(de state = dev[0].request('GET_ALLOC_FAIL') if state.startswith('0:'): break @@ -1138,7 +1138,7 @@ Signed-off-by: Glenn Strauss heavy_groups = [14, 15, 16] suitable_groups = [15, 16, 17, 18, 19, 20, 21] groups = [str(g) for g in sae_groups] -@@ -2188,6 +2193,8 @@ def run_sae_pwe_group(dev, apdev, group) +@@ -2122,6 +2127,8 @@ def run_sae_pwe_group(dev, apdev, group) logger.info("Add Brainpool EC groups since OpenSSL is new enough") elif tls.startswith("wolfSSL"): logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") @@ -1149,7 +1149,7 @@ Signed-off-by: Glenn Strauss start_sae_pwe_ap(apdev[0], group, 2) --- a/tests/hwsim/test_suite_b.py +++ b/tests/hwsim/test_suite_b.py -@@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False +@@ -26,6 +26,8 @@ def check_suite_b_tls_lib(dev, dhe=False return if tls.startswith("wolfSSL"): return @@ -1158,7 +1158,7 @@ Signed-off-by: Glenn Strauss if not tls.startswith("OpenSSL"): raise HwsimSkip("TLS library not supported for Suite B: " + tls) supported = False -@@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh +@@ -499,6 +501,7 @@ def test_suite_b_192_rsa_insufficient_dh dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", ieee80211w="2", @@ -1168,7 +1168,7 @@ Signed-off-by: Glenn Strauss ca_cert="auth_serv/rsa3072-ca.pem", --- a/tests/hwsim/test_wpas_ctrl.py +++ b/tests/hwsim/test_wpas_ctrl.py -@@ -1842,7 +1842,7 @@ def _test_wpas_ctrl_oom(dev): +@@ -1834,7 +1834,7 @@ def _test_wpas_ctrl_oom(dev): tls = dev[0].request("GET tls_library") if not tls.startswith("internal"): tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', @@ -1179,7 +1179,7 @@ Signed-off-by: Glenn Strauss res = dev[0].request(cmd) --- a/tests/hwsim/utils.py +++ b/tests/hwsim/utils.py -@@ -141,7 +141,13 @@ def check_imsi_privacy_support(dev): +@@ -135,7 +135,13 @@ def check_fils_sk_pfs_capa(dev): def check_tls_tod(dev): tls = dev.request("GET tls_library") @@ -1308,7 +1308,7 @@ Signed-off-by: Glenn Strauss if (need_more_data) { --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1122,6 +1122,7 @@ CFLAGS += -DCONFIG_TLSV12 +@@ -1108,6 +1108,7 @@ CFLAGS += -DCONFIG_TLSV12 endif ifeq ($(CONFIG_TLS), wolfssl) @@ -1316,7 +1316,7 @@ Signed-off-by: Glenn Strauss ifdef TLS_FUNCS CFLAGS += -DWOLFSSL_DER_LOAD OBJS += ../src/crypto/tls_wolfssl.o -@@ -1137,6 +1138,7 @@ LIBS_p += -lwolfssl -lm +@@ -1123,6 +1124,7 @@ LIBS_p += -lwolfssl -lm endif ifeq ($(CONFIG_TLS), openssl) @@ -1324,7 +1324,7 @@ Signed-off-by: Glenn Strauss CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 ifdef TLS_FUNCS CFLAGS += -DEAP_TLS_OPENSSL -@@ -1164,6 +1166,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF +@@ -1150,6 +1152,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF endif ifeq ($(CONFIG_TLS), mbedtls) @@ -1332,7 +1332,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=mbedtls endif -@@ -1183,6 +1186,7 @@ endif +@@ -1169,6 +1172,7 @@ endif endif ifeq ($(CONFIG_TLS), gnutls) @@ -1340,7 +1340,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO # default to libgcrypt CONFIG_CRYPTO=gnutls -@@ -1213,6 +1217,7 @@ endif +@@ -1199,6 +1203,7 @@ endif endif ifeq ($(CONFIG_TLS), internal) @@ -1348,7 +1348,7 @@ Signed-off-by: Glenn Strauss ifndef CONFIG_CRYPTO CONFIG_CRYPTO=internal endif -@@ -1293,6 +1298,7 @@ endif +@@ -1279,6 +1284,7 @@ endif endif ifeq ($(CONFIG_TLS), linux) diff --git a/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch b/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch index c8c3ff33f..361f72614 100644 --- a/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch +++ b/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch @@ -14,7 +14,7 @@ Signed-off-by: Glenn Strauss --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c -@@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec +@@ -248,6 +248,12 @@ struct crypto_ec_key * dpp_set_pubkey_po struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) { diff --git a/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch b/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch index db4fcfe23..56ae8d0b8 100644 --- a/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch +++ b/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch @@ -13,7 +13,7 @@ Signed-off-by: Glenn Strauss --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c -@@ -1588,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curv +@@ -1567,7 +1567,9 @@ dpp_pkex_derive_Qr(const struct dpp_curv Pr = crypto_ec_key_get_public_key(Pr_key); Qr = crypto_ec_point_init(ec); hash_bn = crypto_bignum_init_set(hash, curve->hash_len); diff --git a/package/network/services/hostapd/patches/170-DPP-fix-memleak-of-intro.peer_key.patch b/package/network/services/hostapd/patches/170-DPP-fix-memleak-of-intro.peer_key.patch new file mode 100644 index 000000000..157347d6d --- /dev/null +++ b/package/network/services/hostapd/patches/170-DPP-fix-memleak-of-intro.peer_key.patch @@ -0,0 +1,32 @@ +From 639bb1bb912029ec4ff110c3ed807b62f583d6bf Mon Sep 17 00:00:00 2001 +From: Glenn Strauss +Date: Sun, 9 Oct 2022 04:02:44 -0400 +Subject: [PATCH 7/7] DPP: fix memleak of intro.peer_key + +fix memleak of intro.peer_key in wpas_dpp_rx_peer_disc_resp() + +Signed-off-by: Glenn Strauss +--- + wpa_supplicant/dpp_supplicant.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/wpa_supplicant/dpp_supplicant.c ++++ b/wpa_supplicant/dpp_supplicant.c +@@ -2610,6 +2610,8 @@ static void wpas_dpp_rx_peer_disc_resp(s + return; + } + ++ os_memset(&intro, 0, sizeof(intro)); ++ + trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, + &trans_id_len); + if (!trans_id || trans_id_len != 1) { +@@ -2720,7 +2722,7 @@ static void wpas_dpp_rx_peer_disc_resp(s + wpa_supplicant_req_scan(wpa_s, 0, 0); + } + fail: +- os_memset(&intro, 0, sizeof(intro)); ++ dpp_peer_intro_deinit(&intro); + } + + diff --git a/package/network/services/hostapd/patches/170-wpa_supplicant-fix-compiling-without-IEEE8021X_EAPOL.patch b/package/network/services/hostapd/patches/170-wpa_supplicant-fix-compiling-without-IEEE8021X_EAPOL.patch deleted file mode 100644 index 7724f1ae8..000000000 --- a/package/network/services/hostapd/patches/170-wpa_supplicant-fix-compiling-without-IEEE8021X_EAPOL.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c85ce84d942e1eabde33e120b18e5b1f1637b76e Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Tue, 14 Mar 2023 21:40:53 +0100 -Subject: [PATCH] wpa_supplicant: fix compiling without IEEE8021X_EAPOL - -If IEEE8021X_EAPOL is not defined wpa_supplicant will not compile with -following error: - - events.c: In function 'wpa_supplicant_connect': - events.c:1827:14: warning: implicit declaration of function 'eap_is_wps_pbc_enrollee' [-Wimplicit-function-declaration] - 1827 | if ((eap_is_wps_pbc_enrollee(&ssid->eap) && - | ^~~~~~~~~~~~~~~~~~~~~~~ - events.c:1827:43: error: 'struct wpa_ssid' has no member named 'eap' - 1827 | if ((eap_is_wps_pbc_enrollee(&ssid->eap) && - | ^~ - -Adding ifdef statements around the calling function fixes the issue. - -Signed-off-by: Nick Hainke ---- - wpa_supplicant/events.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -1824,6 +1824,7 @@ int wpa_supplicant_connect(struct wpa_su - struct wpa_bss *selected, - struct wpa_ssid *ssid) - { -+#ifdef IEEE8021X_EAPOL - if ((eap_is_wps_pbc_enrollee(&ssid->eap) && - wpas_wps_partner_link_overlap_detect(wpa_s)) || - wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { -@@ -1846,6 +1847,7 @@ int wpa_supplicant_connect(struct wpa_su - #endif /* CONFIG_WPS */ - return -1; - } -+#endif /* IEEE8021X_EAPOL */ - - wpa_msg(wpa_s, MSG_DEBUG, - "Considering connect request: reassociate: %d selected: " diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch index f12aeb0ca..0db8caa20 100644 --- a/package/network/services/hostapd/patches/200-multicall.patch +++ b/package/network/services/hostapd/patches/200-multicall.patch @@ -36,7 +36,7 @@ LIBS += $(DRV_AP_LIBS) ifdef CONFIG_L2_PACKET -@@ -1380,6 +1386,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) +@@ -1378,6 +1384,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) _OBJS_VAR := OBJS include ../src/objs.mk @@ -49,7 +49,7 @@ hostapd: $(OBJS) $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) @$(E) " LD " $@ -@@ -1460,6 +1472,12 @@ include ../src/objs.mk +@@ -1458,6 +1470,12 @@ include ../src/objs.mk _OBJS_VAR := SOBJS include ../src/objs.mk @@ -71,8 +71,8 @@ +-include $(if $(MULTICALL),../hostapd/.config) include ../src/build.rules - ifdef CONFIG_BUILD_PASN_SO -@@ -382,7 +383,9 @@ endif + ifdef CONFIG_BUILD_WPA_CLIENT_SO +@@ -371,7 +372,9 @@ endif ifdef CONFIG_IBSS_RSN NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_IBSS_RSN @@ -82,7 +82,7 @@ OBJS += ibss_rsn.o endif -@@ -924,6 +927,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS +@@ -912,6 +915,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif @@ -93,7 +93,7 @@ endif ifdef CONFIG_AP -@@ -931,9 +938,11 @@ NEED_EAP_COMMON=y +@@ -919,9 +926,11 @@ NEED_EAP_COMMON=y NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_AP OBJS += ap.o @@ -105,7 +105,7 @@ OBJS += ../src/ap/hostapd.o OBJS += ../src/ap/wpa_auth_glue.o OBJS += ../src/ap/utils.o -@@ -1022,6 +1031,12 @@ endif +@@ -1008,6 +1017,12 @@ endif ifdef CONFIG_HS20 OBJS += ../src/ap/hs20.o endif @@ -118,7 +118,7 @@ endif ifdef CONFIG_MBO -@@ -1030,7 +1045,9 @@ CFLAGS += -DCONFIG_MBO +@@ -1016,7 +1031,9 @@ CFLAGS += -DCONFIG_MBO endif ifdef NEED_RSN_AUTHENTICATOR @@ -128,7 +128,7 @@ NEED_AES_WRAP=y OBJS += ../src/ap/wpa_auth.o OBJS += ../src/ap/wpa_auth_ie.o -@@ -2010,6 +2027,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) +@@ -1996,6 +2013,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) _OBJS_VAR := OBJS include ../src/objs.mk @@ -141,7 +141,7 @@ wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) @$(E) " LD " $@ -@@ -2142,6 +2165,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) +@@ -2128,6 +2151,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ @$(E) " sed" $< @@ -156,7 +156,7 @@ wpa_cli.exe: wpa_cli --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -6544,8 +6544,8 @@ union wpa_event_data { +@@ -6171,8 +6171,8 @@ union wpa_event_data { * Driver wrapper code should call this function whenever an event is received * from the driver. */ @@ -167,7 +167,7 @@ /** * wpa_supplicant_event_global - Report a driver event for wpa_supplicant -@@ -6557,7 +6557,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6184,7 +6184,7 @@ void wpa_supplicant_event(void *ctx, enu * Same as wpa_supplicant_event(), but we search for the interface in * wpa_global. */ @@ -178,7 +178,7 @@ /* --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c -@@ -1887,8 +1887,8 @@ err: +@@ -1872,8 +1872,8 @@ err: #endif /* CONFIG_OWE */ @@ -189,7 +189,7 @@ { struct hostapd_data *hapd = ctx; #ifndef CONFIG_NO_STDOUT_DEBUG -@@ -2161,7 +2161,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -2145,7 +2145,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -200,7 +200,7 @@ struct hapd_interfaces *interfaces = ctx; --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c -@@ -1039,8 +1039,8 @@ static void wpa_priv_send_ft_response(st +@@ -1038,8 +1038,8 @@ static void wpa_priv_send_ft_response(st } @@ -211,7 +211,7 @@ { struct wpa_priv_interface *iface = ctx; -@@ -1103,7 +1103,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -1102,7 +1102,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -220,7 +220,7 @@ union wpa_event_data *data) { struct wpa_priv_global *global = ctx; -@@ -1217,6 +1217,8 @@ int main(int argc, char *argv[]) +@@ -1216,6 +1216,8 @@ int main(int argc, char *argv[]) if (os_program_init()) return -1; @@ -231,7 +231,7 @@ os_memset(&global, 0, sizeof(global)); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -5237,8 +5237,8 @@ static void wpas_event_unprot_beacon(str +@@ -4953,8 +4953,8 @@ static void wpas_event_unprot_beacon(str } @@ -242,7 +242,7 @@ { struct wpa_supplicant *wpa_s = ctx; int resched; -@@ -6149,7 +6149,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -5813,7 +5813,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -253,7 +253,7 @@ struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -7408,7 +7408,6 @@ struct wpa_interface * wpa_supplicant_ma +@@ -7087,7 +7087,6 @@ struct wpa_interface * wpa_supplicant_ma return NULL; } @@ -261,7 +261,7 @@ /** * wpa_supplicant_match_existing - Match existing interfaces * @global: Pointer to global data from wpa_supplicant_init() -@@ -7443,6 +7442,11 @@ static int wpa_supplicant_match_existing +@@ -7122,6 +7121,11 @@ static int wpa_supplicant_match_existing #endif /* CONFIG_MATCH_IFACE */ @@ -273,7 +273,7 @@ /** * wpa_supplicant_add_iface - Add a new network interface -@@ -7699,6 +7703,8 @@ struct wpa_global * wpa_supplicant_init( +@@ -7378,6 +7382,8 @@ struct wpa_global * wpa_supplicant_init( #ifndef CONFIG_NO_WPA_MSG wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); #endif /* CONFIG_NO_WPA_MSG */ @@ -284,7 +284,7 @@ wpa_debug_open_file(params->wpa_debug_file_path); --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -595,6 +595,11 @@ fail: +@@ -591,6 +591,11 @@ fail: return -1; } @@ -296,7 +296,7 @@ #ifdef CONFIG_WPS static int gen_uuid(const char *txt_addr) -@@ -688,6 +693,8 @@ int main(int argc, char *argv[]) +@@ -684,6 +689,8 @@ int main(int argc, char *argv[]) return -1; #endif /* CONFIG_DPP */ diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch index 91e1aaad8..a0e00c4d5 100644 --- a/package/network/services/hostapd/patches/300-noscan.patch +++ b/package/network/services/hostapd/patches/300-noscan.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3446,6 +3446,10 @@ static int hostapd_config_fill(struct ho +@@ -3439,6 +3439,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -13,7 +13,7 @@ } else if (os_strcmp(buf, "ht_capab") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1061,6 +1061,8 @@ struct hostapd_config { +@@ -1043,6 +1043,8 @@ struct hostapd_config { int ht_op_mode_fixed; u16 ht_capab; diff --git a/package/network/services/hostapd/patches/301-mesh-noscan.patch b/package/network/services/hostapd/patches/301-mesh-noscan.patch index 8a1bdaa18..998540198 100644 --- a/package/network/services/hostapd/patches/301-mesh-noscan.patch +++ b/package/network/services/hostapd/patches/301-mesh-noscan.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c -@@ -2599,6 +2599,7 @@ static const struct parse_data ssid_fiel +@@ -2555,6 +2555,7 @@ static const struct parse_data ssid_fiel #else /* CONFIG_MESH */ { INT_RANGE(mode, 0, 4) }, #endif /* CONFIG_MESH */ @@ -10,7 +10,7 @@ { STR(id_str) }, --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c -@@ -775,6 +775,7 @@ static void wpa_config_write_network(FIL +@@ -766,6 +766,7 @@ static void wpa_config_write_network(FIL #endif /* IEEE8021X_EAPOL */ INT(mode); INT(no_auto_peer); @@ -31,36 +31,36 @@ /* --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -2693,7 +2693,7 @@ static bool ibss_mesh_can_use_vht(struct - const struct wpa_ssid *ssid, - struct hostapd_hw_modes *mode) - { -- if (mode->mode != HOSTAPD_MODE_IEEE80211A) -+ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) - return false; - - if (!drv_supports_vht(wpa_s, ssid)) -@@ -2766,7 +2766,7 @@ static void ibss_mesh_select_40mhz(struc - int i, res; - unsigned int j; - static const int ht40plus[] = { -- 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, -+ 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, - 184, 192 - }; - int ht40 = -1; -@@ -3016,7 +3016,7 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -2463,7 +2463,7 @@ void ibss_mesh_setup_freq(struct wpa_sup int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode); enum hostapd_hw_mode hw_mode; struct hostapd_hw_modes *mode = NULL; -- int i, obss_scan = 1; -+ int i, obss_scan = !(ssid->noscan); +- int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, ++ int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, + 184, 192 }; + int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, + 6035, 6115, 6195, 6275, 6355, 6435, 6515, +@@ -2471,7 +2471,7 @@ void ibss_mesh_setup_freq(struct wpa_sup + int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; + struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL; u8 channel; - bool is_6ghz; - bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); +- int i, chan_idx, ht40 = -1, res, obss_scan = 1; ++ int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan); + unsigned int j, k; + struct hostapd_freq_params vht_freq; + int chwidth, seg0, seg1; +@@ -2562,7 +2562,7 @@ void ibss_mesh_setup_freq(struct wpa_sup + #endif /* CONFIG_HE_OVERRIDES */ + + /* Setup higher BW only for 5 GHz */ +- if (mode->mode != HOSTAPD_MODE_IEEE80211A) ++ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) + return; + + for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) { --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h -@@ -1035,6 +1035,8 @@ struct wpa_ssid { +@@ -981,6 +981,8 @@ struct wpa_ssid { */ int no_auto_peer; diff --git a/package/network/services/hostapd/patches/310-rescan_immediately.patch b/package/network/services/hostapd/patches/310-rescan_immediately.patch index 033f76309..2c2541947 100644 --- a/package/network/services/hostapd/patches/310-rescan_immediately.patch +++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -5713,7 +5713,7 @@ wpa_supplicant_alloc(struct wpa_supplica +@@ -5419,7 +5419,7 @@ wpa_supplicant_alloc(struct wpa_supplica if (wpa_s == NULL) return NULL; wpa_s->scan_req = INITIAL_SCAN_REQ; diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch index 93a03a6db..8218a439a 100644 --- a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch +++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -1,6 +1,6 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -5224,7 +5224,7 @@ static int nl80211_set_channel(struct i8 +@@ -5022,7 +5022,7 @@ static int nl80211_set_channel(struct i8 freq->he_enabled, freq->eht_enabled, freq->bandwidth, freq->center_freq1, freq->center_freq2); diff --git a/package/network/services/hostapd/patches/340-reload_freq_change.patch b/package/network/services/hostapd/patches/340-reload_freq_change.patch index 9a468079d..b59107463 100644 --- a/package/network/services/hostapd/patches/340-reload_freq_change.patch +++ b/package/network/services/hostapd/patches/340-reload_freq_change.patch @@ -1,6 +1,6 @@ --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -142,6 +142,29 @@ static void hostapd_reload_bss(struct ho +@@ -119,6 +119,29 @@ static void hostapd_reload_bss(struct ho #endif /* CONFIG_NO_RADIUS */ ssid = &hapd->conf->ssid; @@ -30,7 +30,7 @@ if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && ssid->wpa_passphrase_set && ssid->wpa_passphrase) { /* -@@ -250,6 +273,7 @@ int hostapd_reload_config(struct hostapd +@@ -220,6 +243,7 @@ int hostapd_reload_config(struct hostapd struct hostapd_data *hapd = iface->bss[0]; struct hostapd_config *newconf, *oldconf; size_t j; @@ -38,7 +38,7 @@ if (iface->config_fname == NULL) { /* Only in-memory config in use - assume it has been updated */ -@@ -300,6 +324,17 @@ int hostapd_reload_config(struct hostapd +@@ -270,24 +294,20 @@ int hostapd_reload_config(struct hostapd } iface->conf = newconf; @@ -55,10 +55,6 @@ + for (j = 0; j < iface->num_bss; j++) { hapd = iface->bss[j]; - if (!hapd->conf->config_id || !newconf->bss[j]->config_id || -@@ -307,21 +342,6 @@ int hostapd_reload_config(struct hostapd - newconf->bss[j]->config_id) != 0) - hostapd_clear_old_bss(hapd); hapd->iconf = newconf; - hapd->iconf->channel = oldconf->channel; - hapd->iconf->acs = oldconf->acs; diff --git a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch index 878445287..29a3799b5 100644 --- a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch +++ b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c -@@ -1825,15 +1825,35 @@ int ap_switch_channel(struct wpa_supplic +@@ -1803,15 +1803,35 @@ int ap_switch_channel(struct wpa_supplic #ifdef CONFIG_CTRL_IFACE diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch index a943395b5..a88b63e91 100644 --- a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch +++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch @@ -1,35 +1,34 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -3006,12 +3006,12 @@ static int wpa_driver_nl80211_del_beacon - return 0; +@@ -2938,11 +2938,11 @@ static int wpa_driver_nl80211_del_beacon + struct wpa_driver_nl80211_data *drv = bss->drv; wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", - drv->ifindex); + bss->ifindex); - link->beacon_set = 0; - link->freq = 0; - + bss->beacon_set = 0; + bss->freq = 0; nl80211_put_wiphy_data_ap(bss); - msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON); - if (!msg) - return -ENOBUFS; + return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); + } -@@ -5907,7 +5907,7 @@ static void nl80211_teardown_ap(struct i +@@ -5661,7 +5661,7 @@ static void nl80211_teardown_ap(struct i nl80211_mgmt_unsubscribe(bss, "AP teardown"); nl80211_put_wiphy_data_ap(bss); -- bss->flink->beacon_set = 0; -+ wpa_driver_nl80211_del_beacon_all(bss); +- bss->beacon_set = 0; ++ wpa_driver_nl80211_del_beacon(bss); } -@@ -8642,8 +8642,6 @@ static int wpa_driver_nl80211_if_remove( +@@ -8120,8 +8120,6 @@ static int wpa_driver_nl80211_if_remove( } else { wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); nl80211_teardown_ap(bss); - if (!bss->added_if && !drv->first_bss->next) -- wpa_driver_nl80211_del_beacon_all(bss); +- wpa_driver_nl80211_del_beacon(bss); nl80211_destroy_bss(bss); if (!bss->added_if) i802_set_iface_flags(bss, 0); diff --git a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch index e9f46ce9d..7699541fd 100644 --- a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch +++ b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch @@ -1,6 +1,6 @@ --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -68,6 +68,7 @@ +@@ -67,6 +67,7 @@ #include "fst/fst_ctrl_iface.h" #include "config_file.h" #include "ctrl_iface.h" @@ -8,7 +8,7 @@ #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256 -@@ -83,6 +84,7 @@ static void hostapd_ctrl_iface_send(stru +@@ -82,6 +83,7 @@ static void hostapd_ctrl_iface_send(stru enum wpa_msg_type type, const char *buf, size_t len); @@ -16,7 +16,7 @@ static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, struct sockaddr_storage *from, -@@ -134,6 +136,61 @@ static int hostapd_ctrl_iface_new_sta(st +@@ -133,6 +135,61 @@ static int hostapd_ctrl_iface_new_sta(st return 0; } @@ -78,7 +78,7 @@ #ifdef NEED_AP_MLME static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd, -@@ -3529,6 +3586,8 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3449,6 +3506,8 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "VENDOR ", 7) == 0) { reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, reply_size); @@ -89,7 +89,7 @@ #ifdef RADIUS_SERVER --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c -@@ -1008,7 +1008,13 @@ int hostapd_parse_csa_settings(const cha +@@ -945,7 +945,13 @@ int hostapd_parse_csa_settings(const cha int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) { diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch index 24064839f..6faaffcf7 100644 --- a/package/network/services/hostapd/patches/370-ap_sta_support.patch +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -126,6 +126,8 @@ OBJS_c += ../src/utils/common.o +@@ -115,6 +115,8 @@ OBJS_c += ../src/utils/common.o OBJS_c += ../src/common/cli.o OBJS += wmm_ac.o @@ -19,7 +19,7 @@ #include "drivers/driver.h" #include "eap_peer/eap.h" #include "wpa_supplicant_i.h" -@@ -283,6 +284,10 @@ void calculate_update_time(const struct +@@ -282,6 +283,10 @@ void calculate_update_time(const struct static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, struct os_reltime *fetch_time) { @@ -30,7 +30,7 @@ dst->flags = src->flags; os_memcpy(dst->bssid, src->bssid, ETH_ALEN); dst->freq = src->freq; -@@ -296,6 +301,15 @@ static void wpa_bss_copy_res(struct wpa_ +@@ -295,6 +300,15 @@ static void wpa_bss_copy_res(struct wpa_ dst->est_throughput = src->est_throughput; dst->snr = src->snr; @@ -154,7 +154,7 @@ #ifdef CONFIG_WEP /* Configure default/group WEP keys for static WEP */ -@@ -1026,6 +1074,8 @@ void wpa_supplicant_set_state(struct wpa +@@ -1016,6 +1064,8 @@ void wpa_supplicant_set_state(struct wpa sme_sched_obss_scan(wpa_s, 1); @@ -163,7 +163,7 @@ #if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL) if (!fils_hlp_sent && ssid && ssid->eap.erp) update_fils_connect_params = true; -@@ -1036,6 +1086,8 @@ void wpa_supplicant_set_state(struct wpa +@@ -1026,6 +1076,8 @@ void wpa_supplicant_set_state(struct wpa #endif /* CONFIG_OWE */ } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || state == WPA_ASSOCIATED) { @@ -172,7 +172,7 @@ wpa_s->new_connection = 1; wpa_drv_set_operstate(wpa_s, 0); #ifndef IEEE8021X_EAPOL -@@ -2520,6 +2572,8 @@ void wpa_supplicant_associate(struct wpa +@@ -2335,6 +2387,8 @@ void wpa_supplicant_associate(struct wpa return; } wpa_s->current_bss = bss; @@ -181,7 +181,7 @@ #else /* CONFIG_MESH */ wpa_msg(wpa_s, MSG_ERROR, "mesh mode support not included in the build"); -@@ -7010,6 +7064,16 @@ static int wpa_supplicant_init_iface(str +@@ -6693,6 +6747,16 @@ static int wpa_supplicant_init_iface(str sizeof(wpa_s->bridge_ifname)); } @@ -198,7 +198,7 @@ /* RSNA Supplicant Key Management - INITIALIZE */ eapol_sm_notify_portEnabled(wpa_s->eapol, false); eapol_sm_notify_portValid(wpa_s->eapol, false); -@@ -7352,6 +7416,11 @@ static void wpa_supplicant_deinit_iface( +@@ -7031,6 +7095,11 @@ static void wpa_supplicant_deinit_iface( if (terminate) wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); @@ -212,7 +212,7 @@ --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -106,6 +106,11 @@ struct wpa_interface { +@@ -105,6 +105,11 @@ struct wpa_interface { const char *ifname; /** @@ -224,7 +224,7 @@ * bridge_ifname - Optional bridge interface name * * If the driver interface (ifname) is included in a Linux bridge -@@ -665,6 +670,8 @@ struct wpa_supplicant { +@@ -717,6 +722,8 @@ struct wpa_supplicant { #endif /* CONFIG_CTRL_IFACE_BINDER */ char bridge_ifname[16]; @@ -235,7 +235,7 @@ --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -2716,6 +2716,12 @@ static int hostapd_ctrl_iface_chan_switc +@@ -2641,6 +2641,12 @@ static int hostapd_ctrl_iface_chan_switc return 0; } @@ -250,7 +250,7 @@ /* Save CHAN_SWITCH VHT, HE, and EHT config */ --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -2052,11 +2052,6 @@ static int __ieee802_11_set_beacon(struc +@@ -1903,11 +1903,6 @@ static int __ieee802_11_set_beacon(struc return -1; } @@ -264,7 +264,7 @@ if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -5237,6 +5237,60 @@ static void wpas_event_unprot_beacon(str +@@ -4953,6 +4953,60 @@ static void wpas_event_unprot_beacon(str } @@ -325,7 +325,7 @@ void supplicant_event(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { -@@ -5586,8 +5640,10 @@ void supplicant_event(void *ctx, enum wp +@@ -5268,8 +5322,10 @@ void supplicant_event(void *ctx, enum wp channel_width_to_string(data->ch_switch.ch_width), data->ch_switch.cf1, data->ch_switch.cf2); @@ -339,7 +339,7 @@ wpa_s->current_ssid->frequency = data->ch_switch.freq; --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -6324,6 +6324,7 @@ union wpa_event_data { +@@ -5968,6 +5968,7 @@ union wpa_event_data { /** * struct ch_switch @@ -347,8 +347,8 @@ * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset -@@ -6334,6 +6335,7 @@ union wpa_event_data { - * @punct_bitmap: Puncturing bitmap +@@ -5976,6 +5977,7 @@ union wpa_event_data { + * @cf2: Center frequency 2 */ struct ch_switch { + int count; @@ -357,15 +357,16 @@ int ch_offset; --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c -@@ -997,6 +997,7 @@ static void mlme_event_ch_switch(struct - struct nlattr *bw, struct nlattr *cf1, - struct nlattr *cf2, - struct nlattr *punct_bitmap, -+ struct nlattr *count, - int finished) +@@ -694,7 +694,7 @@ static void mlme_event_ch_switch(struct + struct nlattr *ifindex, struct nlattr *freq, + struct nlattr *type, struct nlattr *bw, + struct nlattr *cf1, struct nlattr *cf2, +- int finished) ++ struct nlattr *count, int finished) { struct i802_bss *bss; -@@ -1060,6 +1061,8 @@ static void mlme_event_ch_switch(struct + union wpa_event_data data; +@@ -755,6 +755,8 @@ static void mlme_event_ch_switch(struct data.ch_switch.cf1 = nla_get_u32(cf1); if (cf2) data.ch_switch.cf2 = nla_get_u32(cf2); @@ -373,19 +374,19 @@ + data.ch_switch.count = nla_get_u32(count); if (finished) - bss->flink->freq = data.ch_switch.freq; -@@ -3604,6 +3607,7 @@ static void do_process_drv_event(struct + bss->freq = data.ch_switch.freq; +@@ -3113,6 +3115,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], - tb[NL80211_ATTR_PUNCT_BITMAP], + tb[NL80211_ATTR_CH_SWITCH_COUNT], 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: -@@ -3616,6 +3620,7 @@ static void do_process_drv_event(struct +@@ -3123,6 +3126,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], - tb[NL80211_ATTR_PUNCT_BITMAP], + NULL, 1); break; diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch index b886ab749..1f78c42de 100644 --- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -12,7 +12,7 @@ else --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -3342,6 +3342,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3265,6 +3265,7 @@ static int hostapd_ctrl_iface_receive_pr reply_size); } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { reply_len = hostapd_drv_status(hapd, reply, reply_size); @@ -20,7 +20,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = ieee802_11_get_mib(hapd, reply, reply_size); if (reply_len >= 0) { -@@ -3383,6 +3384,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3306,6 +3307,7 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, reply_size); @@ -30,7 +30,7 @@ reply_len = -1; --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -985,6 +985,9 @@ ifdef CONFIG_FILS +@@ -973,6 +973,9 @@ ifdef CONFIG_FILS OBJS += ../src/ap/fils_hlp.o endif ifdef CONFIG_CTRL_IFACE @@ -42,7 +42,7 @@ --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c -@@ -2326,7 +2326,7 @@ static int wpa_supplicant_ctrl_iface_sta +@@ -2325,7 +2325,7 @@ static int wpa_supplicant_ctrl_iface_sta pos += ret; } @@ -51,7 +51,7 @@ if (wpa_s->ap_iface) { pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, end - pos, -@@ -11964,6 +11964,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -11565,6 +11565,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = -1; } else if (os_strncmp(buf, "NOTE ", 5) == 0) { wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); @@ -59,7 +59,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { -@@ -11976,6 +11977,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -11577,6 +11578,7 @@ char * wpa_supplicant_ctrl_iface_process reply_size - reply_len); #endif /* CONFIG_MACSEC */ } @@ -67,7 +67,7 @@ } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); -@@ -12464,6 +12466,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12065,6 +12067,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = wpa_supplicant_ctrl_iface_bss( wpa_s, buf + 4, reply, reply_size); #ifdef CONFIG_AP @@ -75,7 +75,7 @@ } else if (os_strcmp(buf, "STA-FIRST") == 0) { reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); } else if (os_strncmp(buf, "STA ", 4) == 0) { -@@ -12472,12 +12475,15 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12073,12 +12076,15 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, reply_size); @@ -93,61 +93,15 @@ reply_len = -1; --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c -@@ -26,6 +26,26 @@ +@@ -26,6 +26,7 @@ #include "taxonomy.h" #include "wnm_ap.h" -+static const char * hw_mode_str(enum hostapd_hw_mode mode) -+{ -+ switch (mode) { -+ case HOSTAPD_MODE_IEEE80211B: -+ return "b"; -+ case HOSTAPD_MODE_IEEE80211G: -+ return "g"; -+ case HOSTAPD_MODE_IEEE80211A: -+ return "a"; -+ case HOSTAPD_MODE_IEEE80211AD: -+ return "ad"; -+ case HOSTAPD_MODE_IEEE80211ANY: -+ return "any"; -+ case NUM_HOSTAPD_MODES: -+ return "invalid"; -+ } -+ return "unknown"; -+} -+ +#ifdef CONFIG_CTRL_IFACE_MIB static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen, size_t curr_len, const u8 *mcs_set) -@@ -212,26 +232,6 @@ static const char * timeout_next_str(int - } - - --static const char * hw_mode_str(enum hostapd_hw_mode mode) --{ -- switch (mode) { -- case HOSTAPD_MODE_IEEE80211B: -- return "b"; -- case HOSTAPD_MODE_IEEE80211G: -- return "g"; -- case HOSTAPD_MODE_IEEE80211A: -- return "a"; -- case HOSTAPD_MODE_IEEE80211AD: -- return "ad"; -- case HOSTAPD_MODE_IEEE80211ANY: -- return "any"; -- case NUM_HOSTAPD_MODES: -- return "invalid"; -- } -- return "unknown"; --} -- -- - static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd, - struct sta_info *sta, - char *buf, size_t buflen) -@@ -493,6 +493,7 @@ int hostapd_ctrl_iface_sta_next(struct h +@@ -460,6 +461,7 @@ int hostapd_ctrl_iface_sta_next(struct h return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); } @@ -155,7 +109,7 @@ #ifdef CONFIG_P2P_MANAGER static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, -@@ -884,12 +885,12 @@ int hostapd_ctrl_iface_status(struct hos +@@ -832,12 +834,12 @@ int hostapd_ctrl_iface_status(struct hos return len; len += ret; } @@ -172,7 +126,7 @@ if (os_snprintf_error(buflen - len, ret)) --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c -@@ -2753,6 +2753,7 @@ static const char * bool_txt(bool val) +@@ -2740,6 +2740,7 @@ static const char * bool_txt(bool val) return val ? "TRUE" : "FALSE"; } @@ -180,7 +134,7 @@ int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) { -@@ -2939,6 +2940,7 @@ int ieee802_1x_get_mib_sta(struct hostap +@@ -2926,6 +2927,7 @@ int ieee802_1x_get_mib_sta(struct hostap return len; } @@ -190,7 +144,7 @@ static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c -@@ -4786,6 +4786,7 @@ static const char * wpa_bool_txt(int val +@@ -4559,6 +4559,7 @@ static const char * wpa_bool_txt(int val return val ? "TRUE" : "FALSE"; } @@ -198,7 +152,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ -@@ -4938,7 +4939,7 @@ int wpa_get_mib_sta(struct wpa_state_mac +@@ -4709,7 +4710,7 @@ int wpa_get_mib_sta(struct wpa_state_mac return len; } @@ -209,7 +163,7 @@ { --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c -@@ -3834,6 +3834,8 @@ static u32 wpa_key_mgmt_suite(struct wpa +@@ -2802,6 +2802,8 @@ static u32 wpa_key_mgmt_suite(struct wpa } @@ -218,7 +172,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff -@@ -3915,6 +3917,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch +@@ -2883,6 +2885,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch return (int) len; } @@ -228,7 +182,7 @@ --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c -@@ -1499,7 +1499,7 @@ int wpas_ap_wps_nfc_report_handover(stru +@@ -1477,7 +1477,7 @@ int wpas_ap_wps_nfc_report_handover(stru #endif /* CONFIG_WPS */ diff --git a/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch b/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch index e9083f6ec..d2414faf0 100644 --- a/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch +++ b/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch @@ -1,6 +1,6 @@ --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c -@@ -757,7 +757,7 @@ static int wpa_ctrl_command_sta(struct w +@@ -744,7 +744,7 @@ static int wpa_ctrl_command_sta(struct w } buf[len] = '\0'; diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch index 40c39ff29..bf481c3ba 100644 --- a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch +++ b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch @@ -1,6 +1,6 @@ --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c -@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm) +@@ -2529,6 +2529,31 @@ u32 wpa_akm_to_suite(int akm) } @@ -32,7 +32,7 @@ int wpa_compare_rsn_ie(int ft_initial_assoc, const u8 *ie1, size_t ie1len, const u8 *ie2, size_t ie2len) -@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as +@@ -2536,8 +2561,19 @@ int wpa_compare_rsn_ie(int ft_initial_as if (ie1 == NULL || ie2 == NULL) return -1; diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch index 48a558920..d2713fc29 100644 --- a/package/network/services/hostapd/patches/410-limit_debug_messages.patch +++ b/package/network/services/hostapd/patches/410-limit_debug_messages.patch @@ -60,7 +60,7 @@ #ifdef CONFIG_DEBUG_FILE static char *last_path = NULL; #endif /* CONFIG_DEBUG_FILE */ -@@ -644,7 +618,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ +@@ -636,7 +610,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ } @@ -69,7 +69,7 @@ { va_list ap; char *buf; -@@ -682,7 +656,7 @@ void wpa_msg(void *ctx, int level, const +@@ -674,7 +648,7 @@ void wpa_msg(void *ctx, int level, const } @@ -80,9 +80,9 @@ char *buf; --- a/src/utils/wpa_debug.h +++ b/src/utils/wpa_debug.h -@@ -51,6 +51,17 @@ void wpa_debug_close_file(void); +@@ -50,6 +50,17 @@ int wpa_debug_reopen_file(void); + void wpa_debug_close_file(void); void wpa_debug_setup_stdout(void); - void wpa_debug_stop_log(void); +/* internal */ +void _wpa_hexdump(int level, const char *title, const u8 *buf, @@ -98,7 +98,7 @@ /** * wpa_debug_printf_timestamp - Print timestamp for debug output * -@@ -71,9 +82,15 @@ void wpa_debug_print_timestamp(void); +@@ -70,9 +81,15 @@ void wpa_debug_print_timestamp(void); * * Note: New line '\n' is added to the end of the text when printing to stdout. */ @@ -115,7 +115,7 @@ /** * wpa_hexdump - conditional hex dump * @level: priority level (MSG_*) of the message -@@ -85,7 +102,13 @@ PRINTF_FORMAT(2, 3); +@@ -84,7 +101,13 @@ PRINTF_FORMAT(2, 3); * output may be directed to stdout, stderr, and/or syslog based on * configuration. The contents of buf is printed out has hex dump. */ @@ -130,7 +130,7 @@ static inline void wpa_hexdump_buf(int level, const char *title, const struct wpabuf *buf) -@@ -107,7 +130,13 @@ static inline void wpa_hexdump_buf(int l +@@ -106,7 +129,13 @@ static inline void wpa_hexdump_buf(int l * like wpa_hexdump(), but by default, does not include secret keys (passwords, * etc.) in debug output. */ @@ -145,7 +145,7 @@ static inline void wpa_hexdump_buf_key(int level, const char *title, const struct wpabuf *buf) -@@ -129,8 +158,14 @@ static inline void wpa_hexdump_buf_key(i +@@ -128,8 +157,14 @@ static inline void wpa_hexdump_buf_key(i * the hex numbers and ASCII characters (for printable range) are shown. 16 * bytes per line will be shown. */ @@ -162,7 +162,7 @@ /** * wpa_hexdump_ascii_key - conditional hex dump, hide keys -@@ -146,8 +181,14 @@ void wpa_hexdump_ascii(int level, const +@@ -145,8 +180,14 @@ void wpa_hexdump_ascii(int level, const * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by * default, does not include secret keys (passwords, etc.) in debug output. */ @@ -179,7 +179,7 @@ /* * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce -@@ -184,7 +225,12 @@ void wpa_hexdump_ascii_key(int level, co +@@ -183,7 +224,12 @@ void wpa_hexdump_ascii_key(int level, co * * Note: New line '\n' is added to the end of the text when printing to stdout. */ @@ -193,7 +193,7 @@ /** * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors -@@ -198,8 +244,13 @@ void wpa_msg(void *ctx, int level, const +@@ -197,8 +243,13 @@ void wpa_msg(void *ctx, int level, const * attached ctrl_iface monitors. In other words, it can be used for frequent * events that do not need to be sent to syslog. */ diff --git a/package/network/services/hostapd/patches/420-indicate-features.patch b/package/network/services/hostapd/patches/420-indicate-features.patch index 356d5f8c6..12edb6bac 100644 --- a/package/network/services/hostapd/patches/420-indicate-features.patch +++ b/package/network/services/hostapd/patches/420-indicate-features.patch @@ -9,7 +9,7 @@ struct hapd_global { void **drv_priv; -@@ -696,7 +696,7 @@ int main(int argc, char *argv[]) +@@ -692,7 +692,7 @@ int main(int argc, char *argv[]) wpa_supplicant_event = hostapd_wpa_event; wpa_supplicant_event_global = hostapd_wpa_event_global; for (;;) { @@ -18,7 +18,7 @@ if (c < 0) break; switch (c) { -@@ -733,6 +733,8 @@ int main(int argc, char *argv[]) +@@ -729,6 +729,8 @@ int main(int argc, char *argv[]) break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 'v': diff --git a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch index a21f0bf7c..e52420953 100644 --- a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch +++ b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch @@ -1,6 +1,6 @@ --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c -@@ -401,7 +401,6 @@ static int hostapd_cli_cmd_disassociate( +@@ -388,7 +388,6 @@ static int hostapd_cli_cmd_disassociate( } @@ -8,7 +8,7 @@ static int hostapd_cli_cmd_signature(struct wpa_ctrl *ctrl, int argc, char *argv[]) { -@@ -414,7 +413,6 @@ static int hostapd_cli_cmd_signature(str +@@ -401,7 +400,6 @@ static int hostapd_cli_cmd_signature(str os_snprintf(buf, sizeof(buf), "SIGNATURE %s", argv[0]); return wpa_ctrl_command(ctrl, buf); } @@ -16,7 +16,7 @@ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc, -@@ -431,7 +429,6 @@ static int hostapd_cli_cmd_sa_query(stru +@@ -418,7 +416,6 @@ static int hostapd_cli_cmd_sa_query(stru } @@ -24,7 +24,7 @@ static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) { -@@ -657,7 +654,6 @@ static int hostapd_cli_cmd_wps_config(st +@@ -644,7 +641,6 @@ static int hostapd_cli_cmd_wps_config(st ssid_hex, argv[1]); return wpa_ctrl_command(ctrl, buf); } @@ -32,7 +32,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, -@@ -1610,13 +1606,10 @@ static const struct hostapd_cli_cmd host +@@ -1588,13 +1584,10 @@ static const struct hostapd_cli_cmd host { "disassociate", hostapd_cli_cmd_disassociate, hostapd_complete_stations, " = disassociate a station" }, @@ -46,7 +46,7 @@ { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, " [timeout] [addr] = add WPS Enrollee PIN" }, { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, -@@ -1641,7 +1634,6 @@ static const struct hostapd_cli_cmd host +@@ -1619,7 +1612,6 @@ static const struct hostapd_cli_cmd host " = configure AP" }, { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, "= show current WPS status" }, diff --git a/package/network/services/hostapd/patches/432-missing-typedef.patch b/package/network/services/hostapd/patches/432-missing-typedef.patch new file mode 100644 index 000000000..7a100f1a0 --- /dev/null +++ b/package/network/services/hostapd/patches/432-missing-typedef.patch @@ -0,0 +1,10 @@ +--- a/src/drivers/linux_wext.h ++++ b/src/drivers/linux_wext.h +@@ -26,6 +26,7 @@ typedef int32_t __s32; + typedef uint16_t __u16; + typedef int16_t __s16; + typedef uint8_t __u8; ++typedef int8_t __s8; + #ifndef __user + #define __user + #endif /* __user */ diff --git a/package/network/services/hostapd/patches/450-scan_wait.patch b/package/network/services/hostapd/patches/450-scan_wait.patch index e265d1ac7..ac874ad66 100644 --- a/package/network/services/hostapd/patches/450-scan_wait.patch +++ b/package/network/services/hostapd/patches/450-scan_wait.patch @@ -33,7 +33,7 @@ /* Initialize the driver interface */ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) b = NULL; -@@ -407,8 +419,6 @@ static void hostapd_global_deinit(const +@@ -404,8 +416,6 @@ static void hostapd_global_deinit(const #endif /* CONFIG_NATIVE_WINDOWS */ eap_server_unregister_methods(); @@ -42,7 +42,7 @@ } -@@ -434,18 +444,6 @@ static int hostapd_global_run(struct hap +@@ -431,18 +441,6 @@ static int hostapd_global_run(struct hap } #endif /* EAP_SERVER_TNC */ @@ -61,7 +61,7 @@ eloop_run(); return 0; -@@ -649,8 +647,7 @@ int main(int argc, char *argv[]) +@@ -645,8 +643,7 @@ int main(int argc, char *argv[]) struct hapd_interfaces interfaces; int ret = 1; size_t i, j; diff --git a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch index 809877745..38ff66317 100644 --- a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli #include "common/defs.h" #include "common/ieee802_11_defs.h" #include "common/wpa_common.h" -@@ -936,6 +937,9 @@ struct wpa_driver_associate_params { +@@ -894,6 +895,9 @@ struct wpa_driver_associate_params { * responsible for selecting with which BSS to associate. */ const u8 *bssid; @@ -42,7 +42,7 @@ Signed-hostap: Antonio Quartulli #include "config.h" -@@ -2389,6 +2390,97 @@ static char * wpa_config_write_mac_value +@@ -2345,6 +2346,97 @@ static char * wpa_config_write_peerkey(c #endif /* NO_CONFIG_WRITE */ @@ -140,7 +140,7 @@ Signed-hostap: Antonio Quartulli /* Helper macros for network block parser */ #ifdef OFFSET -@@ -2673,6 +2765,8 @@ static const struct parse_data ssid_fiel +@@ -2629,6 +2721,8 @@ static const struct parse_data ssid_fiel { INT(ap_max_inactivity) }, { INT(dtim_period) }, { INT(beacon_int) }, @@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) -@@ -879,6 +881,9 @@ struct wpa_ssid { +@@ -846,6 +848,9 @@ struct wpa_ssid { */ void *parent_cred; @@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli * macsec_policy - Determines the policy for MACsec secure session --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -4177,6 +4177,12 @@ static void wpas_start_assoc_cb(struct w +@@ -3899,6 +3899,12 @@ static void wpas_start_assoc_cb(struct w params.beacon_int = ssid->beacon_int; else params.beacon_int = wpa_s->conf->beacon_int; diff --git a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch new file mode 100644 index 000000000..65d67b8b0 --- /dev/null +++ b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch @@ -0,0 +1,59 @@ +From ffc4445958a3ed4064f2e1bf73fa478a61c5cf7b Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Sun, 3 Jun 2012 18:42:25 +0200 +Subject: [PATCHv2 602/602] driver_nl80211: use new parameters during ibss join + +Signed-hostap: Antonio Quartulli +--- + src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -6005,7 +6005,7 @@ static int wpa_driver_nl80211_ibss(struc + struct wpa_driver_associate_params *params) + { + struct nl_msg *msg; +- int ret = -1; ++ int ret = -1, i; + int count = 0; + + wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); +@@ -6032,6 +6032,37 @@ retry: + nl80211_put_beacon_int(msg, params->beacon_int)) + goto fail; + ++ if (params->fixed_freq) { ++ wpa_printf(MSG_DEBUG, " * fixed_freq"); ++ nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED); ++ } ++ ++ if (params->beacon_int > 0) { ++ wpa_printf(MSG_DEBUG, " * beacon_int=%d", ++ params->beacon_int); ++ nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL, ++ params->beacon_int); ++ } ++ ++ if (params->rates[0] > 0) { ++ wpa_printf(MSG_DEBUG, " * basic_rates:"); ++ i = 0; ++ while (i < NL80211_MAX_SUPP_RATES && ++ params->rates[i] > 0) { ++ wpa_printf(MSG_DEBUG, " %.1f", ++ (double)params->rates[i] / 2); ++ i++; ++ } ++ nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, i, ++ params->rates); ++ } ++ ++ if (params->mcast_rate > 0) { ++ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", ++ (double)params->mcast_rate / 10); ++ nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); ++ } ++ + ret = nl80211_set_conn_keys(params, msg); + if (ret) + goto fail; diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch index e738ea131..5dc19fede 100644 --- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -1768,6 +1768,7 @@ struct wpa_driver_mesh_join_params { +@@ -1661,6 +1661,7 @@ struct wpa_driver_mesh_join_params { #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 unsigned int flags; bool handle_dfs; @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich struct wpa_driver_set_key_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -11388,6 +11388,18 @@ static int nl80211_put_mesh_id(struct nl +@@ -10627,6 +10627,18 @@ static int nl80211_put_mesh_id(struct nl } @@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params) { -@@ -11449,6 +11461,7 @@ static int nl80211_join_mesh(struct i802 +@@ -10688,6 +10700,7 @@ static int nl80211_join_mesh(struct i802 nl80211_put_basic_rates(msg, params->basic_rates) || nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || diff --git a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch index 73ccc65ad..48086ea0e 100644 --- a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch +++ b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch @@ -1,13 +1,19 @@ --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -3077,6 +3077,10 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -2539,11 +2539,13 @@ void ibss_mesh_setup_freq(struct wpa_sup + for (j = 0; j < wpa_s->last_scan_res_used; j++) { + struct wpa_bss *bss = wpa_s->last_scan_res[j]; - freq->freq = ssid->frequency; +- if (ssid->mode != WPAS_MODE_IBSS) ++ /* Don't adjust control freq in case of fixed_freq */ ++ if (ssid->fixed_freq) { ++ obss_scan = 0; + break; ++ } -+ if (ssid->fixed_freq) { -+ obss_scan = 0; -+ } -+ - if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) { - struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid); +- /* Don't adjust control freq in case of fixed_freq */ +- if (ssid->fixed_freq) ++ if (ssid->mode != WPAS_MODE_IBSS) + break; + if (!bss_is_ibss(bss)) diff --git a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch index ada77853f..6810b797c 100644 --- a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch +++ b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3498,6 +3498,8 @@ static int hostapd_config_fill(struct ho +@@ -3489,6 +3489,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "he_bss_color") == 0) { conf->he_op.he_bss_color = atoi(pos) & 0x3f; conf->he_op.he_bss_color_disabled = 0; diff --git a/package/network/services/hostapd/patches/470-survey_data_fallback.patch b/package/network/services/hostapd/patches/470-survey_data_fallback.patch index 79ab48c5c..359b5f3ef 100644 --- a/package/network/services/hostapd/patches/470-survey_data_fallback.patch +++ b/package/network/services/hostapd/patches/470-survey_data_fallback.patch @@ -1,29 +1,24 @@ --- a/src/ap/acs.c +++ b/src/ap/acs.c -@@ -455,17 +455,17 @@ static int acs_get_bw_center_chan(int fr +@@ -420,20 +420,19 @@ static int acs_usable_bw160_chan(const s static int acs_survey_is_sufficient(struct freq_survey *survey) { if (!(survey->filled & SURVEY_HAS_NF)) { + survey->nf = -95; - wpa_printf(MSG_INFO, - "ACS: Survey for freq %d is missing noise floor", - survey->freq); + wpa_printf(MSG_INFO, "ACS: Survey is missing noise floor"); - return 0; } if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { + survey->channel_time = 0; - wpa_printf(MSG_INFO, - "ACS: Survey for freq %d is missing channel time", - survey->freq); + wpa_printf(MSG_INFO, "ACS: Survey is missing channel time"); - return 0; } if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && -@@ -473,7 +473,6 @@ static int acs_survey_is_sufficient(stru + !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) { wpa_printf(MSG_INFO, - "ACS: Survey for freq %d is missing RX and busy time (at least one is required)", - survey->freq); + "ACS: Survey is missing RX and busy time (at least one is required)"); - return 0; } diff --git a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch index 046da42ab..1a0ce1256 100644 --- a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch +++ b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch @@ -1,6 +1,6 @@ --- a/hostapd/Makefile +++ b/hostapd/Makefile -@@ -1396,7 +1396,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) +@@ -1394,7 +1394,7 @@ hostapd_multi.a: $(BCHECK) $(OBJS) @$(AR) cr $@ hostapd_multi.o $(OBJS) hostapd: $(OBJS) @@ -9,7 +9,7 @@ @$(E) " LD " $@ ifdef CONFIG_WPA_TRACE -@@ -1407,7 +1407,7 @@ _OBJS_VAR := OBJS_c +@@ -1405,7 +1405,7 @@ _OBJS_VAR := OBJS_c include ../src/objs.mk hostapd_cli: $(OBJS_c) @@ -20,7 +20,7 @@ NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -2039,31 +2039,31 @@ wpa_supplicant_multi.a: .config $(BCHECK +@@ -2025,31 +2025,31 @@ wpa_supplicant_multi.a: .config $(BCHECK @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) diff --git a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch index a6f43171c..98b8820cd 100644 --- a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch +++ b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch @@ -42,9 +42,9 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " "validity_interval=%u", -@@ -790,10 +791,12 @@ int ieee802_11_rx_wnm_action_ap(struct h - plen); - return 0; +@@ -659,10 +660,12 @@ int ieee802_11_rx_wnm_action_ap(struct h + + switch (action) { case WNM_BSS_TRANS_MGMT_QUERY: + hapd->openwrt_stats.wnm.bss_transition_query_rx++; ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, @@ -55,7 +55,7 @@ ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, plen); return 0; -@@ -840,6 +843,7 @@ int wnm_send_disassoc_imminent(struct ho +@@ -709,6 +712,7 @@ int wnm_send_disassoc_imminent(struct ho pos = mgmt->u.action.u.bss_tm_req.variable; @@ -63,7 +63,7 @@ wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " MACSTR, disassoc_timer, MAC2STR(sta->addr)); if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { -@@ -921,6 +925,7 @@ int wnm_send_ess_disassoc_imminent(struc +@@ -790,6 +794,7 @@ int wnm_send_ess_disassoc_imminent(struc return -1; } @@ -71,7 +71,7 @@ if (disassoc_timer) { /* send disassociation frame after time-out */ set_disassoc_timer(hapd, sta, disassoc_timer); -@@ -1001,6 +1006,7 @@ int wnm_send_bss_tm_req(struct hostapd_d +@@ -870,6 +875,7 @@ int wnm_send_bss_tm_req(struct hostapd_d } os_free(buf); diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index aa68079fb..521e7df82 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -39,7 +39,7 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -682,6 +684,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -673,6 +675,7 @@ hostapd_alloc_bss_data(struct hostapd_if struct hostapd_bss_config *bss); int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); @@ -49,7 +49,7 @@ struct hostapd_iface * hostapd_alloc_iface(void); --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -435,6 +435,7 @@ void hostapd_free_hapd_data(struct hosta +@@ -401,6 +401,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -57,7 +57,7 @@ accounting_deinit(hapd); hostapd_deinit_wpa(hapd); vlan_deinit(hapd); -@@ -1185,6 +1186,8 @@ static int hostapd_start_beacon(struct h +@@ -1431,6 +1432,8 @@ static int hostapd_setup_bss(struct host if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); @@ -66,7 +66,7 @@ return 0; } -@@ -2126,6 +2129,7 @@ static int hostapd_setup_interface_compl +@@ -2050,6 +2053,7 @@ static int hostapd_setup_interface_compl if (err) goto fail; @@ -74,7 +74,7 @@ wpa_printf(MSG_DEBUG, "Completing interface initialization"); if (iface->freq) { #ifdef NEED_AP_MLME -@@ -2342,6 +2346,7 @@ dfs_offload: +@@ -2248,6 +2252,7 @@ dfs_offload: fail: wpa_printf(MSG_ERROR, "Interface initialization failed"); @@ -82,7 +82,7 @@ hostapd_set_state(iface, HAPD_IFACE_DISABLED); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); #ifdef CONFIG_FST -@@ -2817,6 +2822,7 @@ void hostapd_interface_deinit_free(struc +@@ -2723,6 +2728,7 @@ void hostapd_interface_deinit_free(struc (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; @@ -92,7 +92,7 @@ __func__, driver, drv_priv); --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -2740,13 +2740,18 @@ static void handle_auth(struct hostapd_d +@@ -3573,13 +3573,18 @@ static void handle_auth(struct hostapd_d u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; @@ -112,7 +112,7 @@ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", -@@ -2914,6 +2919,13 @@ static void handle_auth(struct hostapd_d +@@ -3747,6 +3752,13 @@ static void handle_auth(struct hostapd_d resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } @@ -126,7 +126,7 @@ if (res == HOSTAPD_ACL_PENDING) return; -@@ -4695,7 +4707,7 @@ static void handle_assoc(struct hostapd_ +@@ -5488,7 +5500,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; const u8 *pos; @@ -135,7 +135,7 @@ struct sta_info *sta; u8 *tmp = NULL; #ifdef CONFIG_FILS -@@ -4908,6 +4920,11 @@ static void handle_assoc(struct hostapd_ +@@ -5701,6 +5713,11 @@ static void handle_assoc(struct hostapd_ left = res; } #endif /* CONFIG_FILS */ @@ -147,7 +147,7 @@ /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ -@@ -5006,6 +5023,13 @@ static void handle_assoc(struct hostapd_ +@@ -5799,6 +5816,13 @@ static void handle_assoc(struct hostapd_ } #endif /* CONFIG_FILS */ @@ -161,7 +161,7 @@ fail: /* -@@ -5099,6 +5123,7 @@ static void handle_disassoc(struct hosta +@@ -5892,6 +5916,7 @@ static void handle_disassoc(struct hosta wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); @@ -169,7 +169,7 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { -@@ -5168,6 +5193,8 @@ static void handle_deauth(struct hostapd +@@ -5961,6 +5986,8 @@ static void handle_deauth(struct hostapd /* Clear the PTKSA cache entries for PASN */ ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); @@ -180,7 +180,7 @@ wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -1006,6 +1006,12 @@ void handle_probe_req(struct hostapd_dat +@@ -919,6 +919,12 @@ void handle_probe_req(struct hostapd_dat u16 csa_offs[2]; size_t csa_offs_len; struct radius_sta rad_info; @@ -193,7 +193,7 @@ if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && ssi_signal < hapd->iconf->rssi_ignore_probe_request) -@@ -1192,6 +1198,12 @@ void handle_probe_req(struct hostapd_dat +@@ -1105,6 +1111,12 @@ void handle_probe_req(struct hostapd_dat } #endif /* CONFIG_P2P */ @@ -250,7 +250,7 @@ ap_free_sta(hapd, sta); break; } -@@ -1305,15 +1307,28 @@ void ap_sta_set_authorized(struct hostap +@@ -1298,12 +1300,25 @@ void ap_sta_set_authorized(struct hostap sta->addr, authorized, dev_addr); if (authorized) { @@ -265,21 +265,18 @@ + [WLAN_AUTH_PASN] = "pasn", + }; + const char *auth_alg = NULL; - const u8 *dpp_pkhash; const char *keyid; - char dpp_pkhash_buf[100]; char keyid_buf[100]; char ip_addr[100]; + char alg_buf[100]; - dpp_pkhash_buf[0] = '\0'; keyid_buf[0] = '\0'; ip_addr[0] = '\0'; + alg_buf[0] = '\0'; #ifdef CONFIG_P2P if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { os_snprintf(ip_addr, sizeof(ip_addr), -@@ -1323,6 +1338,13 @@ void ap_sta_set_authorized(struct hostap +@@ -1313,22 +1328,31 @@ void ap_sta_set_authorized(struct hostap } #endif /* CONFIG_P2P */ @@ -288,29 +285,27 @@ + + if (auth_alg) + os_snprintf(alg_buf, sizeof(alg_buf), -+ " auth_alg=%s", auth_alg); ++ " auth_alg=%s", auth_alg); + keyid = ap_sta_wpa_get_keyid(hapd, sta); if (keyid) { os_snprintf(keyid_buf, sizeof(keyid_buf), -@@ -1341,17 +1363,19 @@ void ap_sta_set_authorized(struct hostap - dpp_pkhash, SHA256_MAC_LEN); + " keyid=%s", keyid); } -- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", -- buf, ip_addr, keyid_buf, dpp_pkhash_buf); +- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); + hostapd_ubus_notify_authorized(hapd, sta, auth_alg); -+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", -+ buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); ++ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); if (hapd->msg_ctx_parent && hapd->msg_ctx_parent != hapd->msg_ctx) wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, -- AP_STA_CONNECTED "%s%s%s%s", -+ AP_STA_CONNECTED "%s%s%s%s%s", - buf, ip_addr, keyid_buf, -- dpp_pkhash_buf); -+ dpp_pkhash_buf, alg_buf); +- AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); ++ AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); + hostapd_ubus_notify(hapd, "disassoc", sta->addr); @@ -319,7 +314,7 @@ hapd->msg_ctx_parent != hapd->msg_ctx) --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure +@@ -268,6 +268,7 @@ static void hostapd_wpa_auth_psk_failure struct hostapd_data *hapd = ctx; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, MAC2STR(addr)); @@ -329,7 +324,7 @@ --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -194,6 +194,12 @@ ifdef CONFIG_EAPOL_TEST +@@ -183,6 +183,12 @@ ifdef CONFIG_EAPOL_TEST CFLAGS += -Werror -DEAPOL_TEST endif @@ -342,7 +337,7 @@ ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage LIBS += -lgcov -@@ -989,6 +995,9 @@ ifdef CONFIG_CTRL_IFACE_MIB +@@ -977,6 +983,9 @@ ifdef CONFIG_CTRL_IFACE_MIB CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif OBJS += ../src/ap/ctrl_iface_ap.o @@ -354,7 +349,7 @@ CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -7608,6 +7608,8 @@ struct wpa_supplicant * wpa_supplicant_a +@@ -7285,6 +7285,8 @@ struct wpa_supplicant * wpa_supplicant_a } #endif /* CONFIG_P2P */ @@ -363,7 +358,7 @@ return wpa_s; } -@@ -7634,6 +7636,8 @@ int wpa_supplicant_remove_iface(struct w +@@ -7311,6 +7313,8 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -372,7 +367,7 @@ /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { -@@ -7980,8 +7984,12 @@ int wpa_supplicant_run(struct wpa_global +@@ -7614,8 +7618,12 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -387,15 +382,15 @@ --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -21,6 +21,7 @@ +@@ -20,6 +20,7 @@ + #include "wps/wps_defs.h" #include "config_ssid.h" #include "wmm_ac.h" - #include "pasn/pasn_common.h" +#include "ubus.h" extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; -@@ -324,6 +325,8 @@ struct wpa_global { +@@ -323,6 +324,8 @@ struct wpa_global { #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ @@ -404,7 +399,7 @@ }; -@@ -655,6 +658,7 @@ struct wpa_supplicant { +@@ -707,6 +710,7 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; @@ -422,7 +417,7 @@ #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG -@@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void +@@ -391,6 +392,8 @@ static int wpa_supplicant_wps_cred(void wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", cred->cred_attr, cred->cred_attr_len); @@ -433,7 +428,7 @@ --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -901,6 +901,7 @@ int main(int argc, char *argv[]) +@@ -897,6 +897,7 @@ int main(int argc, char *argv[]) } hostapd_global_ctrl_iface_init(&interfaces); @@ -441,7 +436,7 @@ if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); -@@ -910,6 +911,7 @@ int main(int argc, char *argv[]) +@@ -906,6 +907,7 @@ int main(int argc, char *argv[]) ret = 0; out: @@ -532,7 +527,7 @@ --- a/src/ap/dfs.c +++ b/src/ap/dfs.c -@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h +@@ -1203,6 +1203,8 @@ int hostapd_dfs_pre_cac_expired(struct h "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -574,7 +569,7 @@ } --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h -@@ -293,6 +293,7 @@ struct sta_info { +@@ -328,6 +328,7 @@ struct sta_info { #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_AIRTIME_POLICY unsigned int airtime_weight; diff --git a/package/network/services/hostapd/patches/700-wifi-reload.patch b/package/network/services/hostapd/patches/700-wifi-reload.patch index 5ac7f711a..174127df6 100644 --- a/package/network/services/hostapd/patches/700-wifi-reload.patch +++ b/package/network/services/hostapd/patches/700-wifi-reload.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2418,6 +2418,8 @@ static int hostapd_config_fill(struct ho +@@ -2416,6 +2416,8 @@ static int hostapd_config_fill(struct ho bss->isolate = atoi(pos); } else if (os_strcmp(buf, "ap_max_inactivity") == 0) { bss->ap_max_inactivity = atoi(pos); @@ -8,8 +8,8 @@ + bss->config_id = os_strdup(pos); } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { bss->skip_inactivity_poll = atoi(pos); - } else if (os_strcmp(buf, "config_id") == 0) { -@@ -3128,6 +3130,8 @@ static int hostapd_config_fill(struct ho + } else if (os_strcmp(buf, "country_code") == 0) { +@@ -3121,6 +3123,8 @@ static int hostapd_config_fill(struct ho } } else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { conf->acs_exclude_dfs = atoi(pos); @@ -20,7 +20,15 @@ } else if (os_strcmp(buf, "channel") == 0) { --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c -@@ -997,6 +997,7 @@ void hostapd_config_free(struct hostapd_ +@@ -796,6 +796,7 @@ void hostapd_config_free_bss(struct host + os_free(conf->radius_req_attr_sqlite); + os_free(conf->rsn_preauth_interfaces); + os_free(conf->ctrl_interface); ++ os_free(conf->config_id); + os_free(conf->ca_cert); + os_free(conf->server_cert); + os_free(conf->server_cert2); +@@ -995,6 +996,7 @@ void hostapd_config_free(struct hostapd_ for (i = 0; i < conf->num_bss; i++) hostapd_config_free_bss(conf->bss[i]); @@ -30,7 +38,16 @@ os_free(conf->basic_rates); --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -987,6 +987,7 @@ struct eht_phy_capabilities_info { +@@ -285,6 +285,8 @@ struct hostapd_bss_config { + char vlan_bridge[IFNAMSIZ + 1]; + char wds_bridge[IFNAMSIZ + 1]; + ++ char *config_id; ++ + enum hostapd_logger_level logger_syslog_level, logger_stdout_level; + + unsigned int logger_syslog; /* module bitfield */ +@@ -969,6 +971,7 @@ struct eht_phy_capabilities_info { struct hostapd_config { struct hostapd_bss_config **bss, *last_bss; size_t num_bss; @@ -40,7 +57,7 @@ int rts_threshold; --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -254,6 +254,10 @@ static int hostapd_iface_conf_changed(st +@@ -224,6 +224,10 @@ static int hostapd_iface_conf_changed(st { size_t i; @@ -51,7 +68,7 @@ if (newconf->num_bss != oldconf->num_bss) return 1; -@@ -267,7 +271,7 @@ static int hostapd_iface_conf_changed(st +@@ -237,7 +241,7 @@ static int hostapd_iface_conf_changed(st } @@ -60,17 +77,26 @@ { struct hapd_interfaces *interfaces = iface->interfaces; struct hostapd_data *hapd = iface->bss[0]; -@@ -295,6 +299,9 @@ int hostapd_reload_config(struct hostapd +@@ -260,13 +264,16 @@ int hostapd_reload_config(struct hostapd + if (newconf == NULL) + return -1; + +- hostapd_clear_old(iface); +- + oldconf = hapd->iconf; + if (hostapd_iface_conf_changed(newconf, oldconf)) { char *fname; int res; + if (reconf) + return -1; + - hostapd_clear_old(iface); - ++ hostapd_clear_old(iface); ++ wpa_printf(MSG_DEBUG, -@@ -321,6 +328,24 @@ int hostapd_reload_config(struct hostapd + "Configuration changes include interface/BSS modification - force full disable+enable sequence"); + fname = os_strdup(iface->config_fname); +@@ -291,6 +298,24 @@ int hostapd_reload_config(struct hostapd wpa_printf(MSG_ERROR, "Failed to enable interface on config reload"); return res; @@ -95,7 +121,7 @@ } iface->conf = newconf; -@@ -337,6 +362,12 @@ int hostapd_reload_config(struct hostapd +@@ -307,6 +332,12 @@ int hostapd_reload_config(struct hostapd for (j = 0; j < iface->num_bss; j++) { hapd = iface->bss[j]; @@ -105,10 +131,10 @@ + } + if (newconf->bss[j]->config_id) + hapd->config_id = strdup(newconf->bss[j]->config_id); - if (!hapd->conf->config_id || !newconf->bss[j]->config_id || - os_strcmp(hapd->conf->config_id, - newconf->bss[j]->config_id) != 0) -@@ -2514,6 +2545,10 @@ hostapd_alloc_bss_data(struct hostapd_if + hapd->iconf = newconf; + hapd->conf = newconf->bss[j]; + hostapd_reload_bss(hapd); +@@ -2420,6 +2451,10 @@ hostapd_alloc_bss_data(struct hostapd_if hapd->iconf = conf; hapd->conf = bss; hapd->iface = hapd_iface; @@ -138,7 +164,7 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -676,7 +677,7 @@ struct hostapd_iface { +@@ -667,7 +668,7 @@ struct hostapd_iface { int hostapd_for_each_interface(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, void *ctx), void *ctx); @@ -149,19 +175,19 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -5054,6 +5054,9 @@ static int wpa_driver_nl80211_set_ap(voi +@@ -4852,6 +4852,9 @@ static int wpa_driver_nl80211_set_ap(voi if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", ret, strerror(-ret)); -+ if (!bss->flink->beacon_set) ++ if (!bss->beacon_set) + ret = 0; -+ bss->flink->beacon_set = 0; ++ bss->beacon_set = 0; } else { - bss->flink->beacon_set = 1; + bss->beacon_set = 1; nl80211_set_bss(bss, params->cts_protect, params->preamble, --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -187,7 +187,7 @@ static int hostapd_ctrl_iface_update(str +@@ -186,7 +186,7 @@ static int hostapd_ctrl_iface_update(str iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; reload_opts = txt; @@ -172,7 +198,7 @@ } --- a/hostapd/main.c +++ b/hostapd/main.c -@@ -320,7 +320,7 @@ static void handle_term(int sig, void *s +@@ -317,7 +317,7 @@ static void handle_term(int sig, void *s static int handle_reload_iface(struct hostapd_iface *iface, void *ctx) { diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch index f625f4bda..b06ef8f68 100644 --- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch +++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch @@ -30,7 +30,7 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3353,6 +3353,8 @@ static int hostapd_config_fill(struct ho +@@ -3346,6 +3346,8 @@ static int hostapd_config_fill(struct ho #ifndef CONFIG_NO_VLAN } else if (os_strcmp(buf, "dynamic_vlan") == 0) { bss->ssid.dynamic_vlan = atoi(pos); diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch index e04ae6253..169807c61 100644 --- a/package/network/services/hostapd/patches/711-wds_bridge_force.patch +++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch @@ -6,12 +6,12 @@ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); + if (!bss->wds_bridge[0]) + os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); - } else if (os_strcmp(buf, "bridge_hairpin") == 0) { - bss->bridge_hairpin = atoi(pos); } else if (os_strcmp(buf, "vlan_bridge") == 0) { + os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); + } else if (os_strcmp(buf, "wds_bridge") == 0) { --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c -@@ -348,8 +348,6 @@ int hostapd_set_wds_sta(struct hostapd_d +@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d return -1; if (hapd->conf->wds_bridge[0]) bridge = hapd->conf->wds_bridge; diff --git a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch index a06f141c8..ed76d22dd 100644 --- a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch +++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2848,6 +2848,14 @@ static int hostapd_config_fill(struct ho +@@ -2841,6 +2841,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } @@ -17,7 +17,7 @@ } else if (os_strcmp(buf, "extended_key_id") == 0) { --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h -@@ -721,6 +721,7 @@ void hostapd_cleanup_cs_params(struct ho +@@ -711,6 +711,7 @@ void hostapd_cleanup_cs_params(struct ho void hostapd_periodic_iface(struct hostapd_iface *iface); int hostapd_owe_trans_get_info(struct hostapd_data *hapd); void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); @@ -27,7 +27,7 @@ void hostapd_cleanup_cca_params(struct hostapd_data *hapd); --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -271,6 +271,30 @@ static int hostapd_iface_conf_changed(st +@@ -241,6 +241,30 @@ static int hostapd_iface_conf_changed(st } @@ -60,7 +60,7 @@ struct hapd_interfaces *interfaces = iface->interfaces; --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -1222,7 +1222,7 @@ void handle_probe_req(struct hostapd_dat +@@ -1135,7 +1135,7 @@ void handle_probe_req(struct hostapd_dat if (hapd->conf->no_probe_resp_if_max_sta && is_multicast_ether_addr(mgmt->da) && is_multicast_ether_addr(mgmt->bssid) && @@ -71,7 +71,7 @@ " since no room for additional STA", --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1026,6 +1026,8 @@ struct hostapd_config { +@@ -1010,6 +1010,8 @@ struct hostapd_config { unsigned int track_sta_max_num; unsigned int track_sta_max_age; diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch index 1826c9762..d9a4f15f0 100644 --- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3007,6 +3007,8 @@ static int hostapd_config_fill(struct ho +@@ -3000,6 +3000,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP @@ -18,10 +18,10 @@ + char ft_iface[IFNAMSIZ + 1]; char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; - int bridge_hairpin; /* hairpin_mode on bridge members */ + --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -1616,8 +1616,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1595,8 +1595,12 @@ int hostapd_setup_wpa(struct hostapd_dat wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { const char *ft_iface; diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch index a11664473..608f15a25 100644 --- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch @@ -7,7 +7,7 @@ + char snoop_iface[IFNAMSIZ + 1]; char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; - int bridge_hairpin; /* hairpin_mode on bridge members */ + --- a/src/ap/x_snoop.c +++ b/src/ap/x_snoop.c @@ -33,14 +33,16 @@ int x_snoop_init(struct hostapd_data *ha @@ -55,10 +55,10 @@ "x_snoop: Failed to initialize L2 packet processing %s", --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2320,6 +2320,8 @@ static int hostapd_config_fill(struct ho +@@ -2318,6 +2318,8 @@ static int hostapd_config_fill(struct ho + os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); + if (!bss->wds_bridge[0]) os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); - } else if (os_strcmp(buf, "bridge_hairpin") == 0) { - bss->bridge_hairpin = atoi(pos); + } else if (os_strcmp(buf, "snoop_iface") == 0) { + os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); } else if (os_strcmp(buf, "vlan_bridge") == 0) { diff --git a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch index c3a77bc65..479d56155 100644 --- a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch +++ b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch @@ -18,7 +18,7 @@ #ifdef CONFIG_HS20 static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, -@@ -4064,10 +4064,10 @@ static int hostapd_config_fill(struct ho +@@ -4046,10 +4046,10 @@ static int hostapd_config_fill(struct ho bss->gas_frag_limit = val; } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { bss->gas_comeback_delay = atoi(pos); @@ -32,7 +32,7 @@ os_free(bss->dump_msk_file); --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -1499,6 +1499,7 @@ static int hostapd_setup_bss(struct host +@@ -1424,6 +1424,7 @@ static int hostapd_setup_bss(struct host wpa_printf(MSG_ERROR, "GAS server initialization failed"); return -1; } @@ -40,7 +40,7 @@ if (conf->qos_map_set_len && hostapd_drv_set_qos_map(hapd, conf->qos_map_set, -@@ -1506,7 +1507,6 @@ static int hostapd_setup_bss(struct host +@@ -1431,7 +1432,6 @@ static int hostapd_setup_bss(struct host wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); return -1; } @@ -50,7 +50,7 @@ wpa_printf(MSG_ERROR, "BSS Load initialization failed"); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -2672,8 +2672,6 @@ void wnm_bss_keep_alive_deinit(struct wp +@@ -2586,8 +2586,6 @@ void wnm_bss_keep_alive_deinit(struct wp } @@ -59,16 +59,16 @@ static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, size_t len) { -@@ -2706,8 +2704,6 @@ static void interworking_process_assoc_r +@@ -2620,8 +2618,6 @@ static void interworking_process_assoc_r } } -#endif /* CONFIG_INTERWORKING */ - - static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) - { -@@ -3087,10 +3083,8 @@ static int wpa_supplicant_event_associnf + static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) +@@ -2954,10 +2950,8 @@ static int wpa_supplicant_event_associnf wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, data->assoc_info.resp_ies_len); #endif /* CONFIG_WNM */ @@ -81,7 +81,7 @@ data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c -@@ -1116,13 +1116,11 @@ u8 * hostapd_eid_rsnxe(struct hostapd_da +@@ -1100,13 +1100,11 @@ u8 * hostapd_eid_rsnxe(struct hostapd_da u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, const u8 *ext_capab_ie, size_t ext_capab_ie_len) { diff --git a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch index 1fc4e8a77..d90a27523 100644 --- a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch +++ b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch @@ -1,6 +1,6 @@ --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c -@@ -874,7 +874,8 @@ int hostapd_start_dfs_cac(struct hostapd +@@ -864,7 +864,8 @@ int hostapd_start_dfs_cac(struct hostapd int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set, u8 qos_map_set_len) { diff --git a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch index 2f5015892..3d2b59e8c 100644 --- a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch +++ b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch @@ -1,6 +1,6 @@ --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -310,6 +310,7 @@ struct hostapd_bss_config { +@@ -311,6 +311,7 @@ struct hostapd_bss_config { unsigned int eap_sim_db_timeout; int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ struct hostapd_ip_addr own_ip_addr; @@ -98,7 +98,7 @@ hapd->conf->own_ip_addr.af == AF_INET && --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2688,6 +2688,8 @@ static int hostapd_config_fill(struct ho +@@ -2681,6 +2681,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "iapp_interface") == 0) { wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); #endif /* CONFIG_IAPP */ diff --git a/package/network/services/hostapd/patches/761-shared_das_port.patch b/package/network/services/hostapd/patches/761-shared_das_port.patch index 59c2a9679..7516b7349 100644 --- a/package/network/services/hostapd/patches/761-shared_das_port.patch +++ b/package/network/services/hostapd/patches/761-shared_das_port.patch @@ -10,7 +10,7 @@ unsigned int time_window; --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -1442,6 +1442,7 @@ static int hostapd_setup_bss(struct host +@@ -1367,6 +1367,7 @@ static int hostapd_setup_bss(struct host struct radius_das_conf das_conf; os_memset(&das_conf, 0, sizeof(das_conf)); das_conf.port = conf->radius_das_port; diff --git a/package/network/services/hostapd/patches/800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch b/package/network/services/hostapd/patches/800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch new file mode 100644 index 000000000..1d9e9564e --- /dev/null +++ b/package/network/services/hostapd/patches/800-acs-don-t-select-indoor-channel-on-outdoor-operation.patch @@ -0,0 +1,58 @@ +From 37528a5205cb0b9e2238b7d97fb2ff5457448f1c Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Thu, 8 Sep 2022 01:45:41 +0200 +Subject: [PATCH] acs: don't select indoor channel on outdoor operation + +Don't select channels designated for exclusive-indoor use when the +country3 element is set on outdoor operation. + +Signed-off-by: David Bauer +--- + src/ap/acs.c | 9 +++++++++ + src/ap/dfs.c | 3 +++ + 2 files changed, 12 insertions(+) + +--- a/src/ap/acs.c ++++ b/src/ap/acs.c +@@ -552,6 +552,9 @@ static void acs_survey_mode_interference + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + ++ if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f) ++ continue; ++ + wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)", + chan->chan, chan->freq); + +@@ -686,6 +689,9 @@ acs_find_ideal_chan_mode(struct hostapd_ + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + ++ if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f) ++ continue; ++ + if (!chan_bw_allowed(chan, bw, 1, 1)) { + wpa_printf(MSG_DEBUG, + "ACS: Channel %d: BW %u is not supported", +@@ -1067,6 +1073,9 @@ static int * acs_request_scan_add_freqs( + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + ++ if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f) ++ continue; ++ + *freq++ = chan->freq; + } + +--- a/src/ap/dfs.c ++++ b/src/ap/dfs.c +@@ -282,6 +282,9 @@ static int dfs_find_channel(struct hosta + if (chan->max_tx_power < iface->conf->min_tx_power) + continue; + ++ if (chan->flag & HOSTAPD_CHAN_INDOOR_ONLY && iface->conf->country[2] == 0x4f) ++ continue; ++ + if (ret_chan && idx == channel_idx) { + wpa_printf(MSG_DEBUG, "Selected channel %d (%d)", + chan->freq, chan->chan); diff --git a/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch b/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch index 51690def0..e78a4ef5c 100644 --- a/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch +++ b/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch @@ -13,7 +13,7 @@ Signed-off-by: David Bauer --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c -@@ -12640,7 +12640,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12241,7 +12241,7 @@ char * wpa_supplicant_ctrl_iface_process if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18)) reply_len = -1; #endif /* CONFIG_WNM */ @@ -22,7 +22,7 @@ Signed-off-by: David Bauer } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) { if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18)) reply_len = -1; -@@ -12650,7 +12650,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -12251,7 +12251,7 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) { if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11)) reply_len = -1; diff --git a/package/network/services/hostapd/patches/991-s8-u8.patch b/package/network/services/hostapd/patches/991-s8-u8.patch deleted file mode 100644 index e01101685..000000000 --- a/package/network/services/hostapd/patches/991-s8-u8.patch +++ /dev/null @@ -1,23 +0,0 @@ -Index: hostapd-2023-06-22-599d00be/src/drivers/driver_nl80211.c -=================================================================== ---- hostapd-2023-06-22-599d00be.orig/src/drivers/driver_nl80211.c -+++ hostapd-2023-06-22-599d00be/src/drivers/driver_nl80211.c -@@ -7686,7 +7686,7 @@ static int get_sta_handler(struct nl_msg - [NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8}, - [NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 }, - [NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 }, -- [NL80211_STA_INFO_ACK_SIGNAL_AVG] = { .type = NLA_S8 }, -+ [NL80211_STA_INFO_ACK_SIGNAL_AVG] = { .type = NLA_U8 }, - [NL80211_STA_INFO_RX_MPDUS] = { .type = NLA_U32 }, - [NL80211_STA_INFO_FCS_ERROR_COUNT] = { .type = NLA_U32 }, - [NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 }, -@@ -7792,7 +7792,7 @@ static int get_sta_handler(struct nl_msg - } - if (stats[NL80211_STA_INFO_ACK_SIGNAL_AVG]) - data->avg_ack_signal = -- nla_get_s8(stats[NL80211_STA_INFO_ACK_SIGNAL_AVG]); -+ nla_get_u8(stats[NL80211_STA_INFO_ACK_SIGNAL_AVG]); - if (stats[NL80211_STA_INFO_RX_MPDUS]) - data->rx_mpdus = nla_get_u32(stats[NL80211_STA_INFO_RX_MPDUS]); - if (stats[NL80211_STA_INFO_FCS_ERROR_COUNT]) - \ No newline at end of file diff --git a/package/network/services/hostapd/patches/992-openssl-include-rsa.patch b/package/network/services/hostapd/patches/992-openssl-include-rsa.patch new file mode 100644 index 000000000..581ae9f67 --- /dev/null +++ b/package/network/services/hostapd/patches/992-openssl-include-rsa.patch @@ -0,0 +1,32 @@ +From f374d52079111a4340acb6df835f45ac6b5f3f60 Mon Sep 17 00:00:00 2001 +From: Andre Heider +Date: Wed, 22 Jun 2022 14:13:55 +0200 +Subject: OpenSSL: Include rsa.h for all OpenSSL versions + +This fixes the build with OpenSSL 1.1.1: +../src/crypto/crypto_openssl.c: In function 'crypto_rsa_oaep_sha256_decrypt': +../src/crypto/crypto_openssl.c:4404:49: error: 'RSA_PKCS1_OAEP_PADDING' undeclared (first use in this function) + +Signed-off-by: Andre Heider +--- + src/crypto/crypto_openssl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/crypto/crypto_openssl.c ++++ b/src/crypto/crypto_openssl.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #ifdef CONFIG_ECC + #include +@@ -25,7 +26,6 @@ + #include + #include + #include +-#include + #include + #include + #else /* OpenSSL version >= 3.0 */ diff --git a/package/network/services/hostapd/patches/993-fix-mbo-module-build.patch b/package/network/services/hostapd/patches/993-fix-mbo-module-build.patch new file mode 100644 index 000000000..3efc484f8 --- /dev/null +++ b/package/network/services/hostapd/patches/993-fix-mbo-module-build.patch @@ -0,0 +1,10 @@ +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -339,6 +339,7 @@ + + ifdef CONFIG_MBO + CONFIG_WNM=y ++NEED_GAS=y + endif + + ifdef CONFIG_WNM diff --git a/package/network/services/unetd/Makefile b/package/network/services/unetd/Makefile new file mode 100644 index 000000000..687306149 --- /dev/null +++ b/package/network/services/unetd/Makefile @@ -0,0 +1,113 @@ +# +# Copyright (C) 2022 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=unetd +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=$(PROJECT_GIT)/project/unetd.git +PKG_SOURCE_DATE:=2024-03-31 +PKG_SOURCE_VERSION:=806457664ab6e952a7f4febb82e891f596fe577c +PKG_MIRROR_HASH:=0d3952f8079476e68487094b49c9c39074a1068c932f204a87c609074ce30d74 + +PKG_LICENSE:=GPL-2.0 +PKG_MAINTAINER:=Felix Fietkau + +PKG_BUILD_DEPENDS:=HAS_BPF_TOOLCHAIN:bpf-headers + +PKG_BUILD_PARALLEL:=1 + +PKG_CONFIG_DEPENDS += CONFIG_UNETD_VXLAN_SUPPORT + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk +include $(INCLUDE_DIR)/bpf.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/unetd + SECTION:=net + CATEGORY:=Network + TITLE:=WireGuard based VPN connection manager for OpenWrt + DEPENDS:=+libubox +libubus +libblobmsg-json +libnl-tiny +kmod-wireguard +UNETD_VXLAN_SUPPORT:libbpf +endef + +define Package/unetd/config + config UNETD_VXLAN_SUPPORT + bool "VXLAN support" + depends on PACKAGE_unetd + depends on HAS_BPF_TOOLCHAIN + default y + +endef + +define Package/unet-dht + SECTION:=net + CATEGORY:=Network + DEPENDS:=unetd + TITLE:=unetd DHT discovery support +endef + +define Package/unet-cli + SECTION:=net + CATEGORY:=Network + DEPENDS:=+unetd +ucode +ucode-mod-fs + TITLE:=unetd administration command line utility +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include/libnl-tiny \ + -I$(STAGING_DIR)/usr/include + +CMAKE_OPTIONS += \ + -DLIBNL_LIBS=-lnl-tiny \ + -DVXLAN_SUPPORT=$(if $(CONFIG_UNETD_VXLAN_SUPPORT),ON,OFF) + +ifdef CONFIG_UNETD_VXLAN_SUPPORT + define Build/Compile + $(call CompileBPF,$(PKG_BUILD_DIR)/mss-bpf.c) + $(call Build/Compile/Default,) + endef +endif + +define Package/unetd/conffiles +/etc/unetd +endef + +define Package/unetd/install + $(INSTALL_DIR) \ + $(1)/etc/unetd \ + $(1)/lib/bpf \ + $(1)/etc/init.d \ + $(1)/lib/netifd/proto \ + $(1)/usr/sbin \ + $(1)/usr/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libunet.so* $(1)/usr/lib/ + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/sbin/unetd \ + $(PKG_INSTALL_DIR)/usr/sbin/unet-tool \ + $(1)/usr/sbin/ + $(if $(CONFIG_UNETD_VXLAN_SUPPORT),$(INSTALL_DATA) $(PKG_BUILD_DIR)/mss-bpf.o $(1)/lib/bpf/mss.o) + $(INSTALL_BIN) ./files/unetd.init $(1)/etc/init.d/unetd + $(INSTALL_BIN) ./files/unetd.sh $(1)/lib/netifd/proto +endef + +define Package/unet-dht/install + $(INSTALL_DIR) \ + $(1)/etc/init.d \ + $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/unet-dht $(1)/usr/sbin + $(INSTALL_BIN) ./files/unet-dht.init $(1)/etc/init.d/unet-dht +endef + +define Package/unet-cli/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/unet-cli $(1)/usr/sbin +endef + +$(eval $(call BuildPackage,unetd)) +$(eval $(call BuildPackage,unet-dht)) +$(eval $(call BuildPackage,unet-cli)) diff --git a/package/network/services/unetd/files/unet-dht.init b/package/network/services/unetd/files/unet-dht.init new file mode 100644 index 000000000..272626a93 --- /dev/null +++ b/package/network/services/unetd/files/unet-dht.init @@ -0,0 +1,24 @@ +#!/bin/sh /etc/rc.common +# Copyright (c) 2022 OpenWrt.org + +START=19 + +USE_PROCD=1 +PROG=/usr/sbin/unet-dht + +unet_dht_id() { + cat \ + /sys/class/net/eth?/address \ + /sys/class/ieee80211/phy*/macaddress \ + /etc/board.json | md5sum | awk '{ print $1 }' +} + +start_service() { + mkdir -p /var/run/unetd /etc/unetd + + procd_open_instance + procd_set_param command "$PROG" -u /var/run/unetd/socket -n /var/run/unetd/nodes.dat $(unet_dht_id) + procd_set_param respawn + procd_set_param limits core="unlimited" + procd_close_instance +} diff --git a/package/network/services/unetd/files/unetd.init b/package/network/services/unetd/files/unetd.init new file mode 100644 index 000000000..c1124821e --- /dev/null +++ b/package/network/services/unetd/files/unetd.init @@ -0,0 +1,17 @@ +#!/bin/sh /etc/rc.common +# Copyright (c) 2022 OpenWrt.org + +START=19 + +USE_PROCD=1 +PROG=/usr/sbin/unetd + +start_service() { + mkdir -p /var/run/unetd /etc/unetd + + procd_open_instance + procd_set_param command "$PROG" -h /var/run/unetd/hosts -u /var/run/unetd/socket + procd_set_param respawn + procd_set_param limits core="unlimited" + procd_close_instance +} diff --git a/package/network/services/unetd/files/unetd.sh b/package/network/services/unetd/files/unetd.sh new file mode 100644 index 000000000..2f0f0c478 --- /dev/null +++ b/package/network/services/unetd/files/unetd.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +[ -x /usr/sbin/unetd ] || exit 0 + +. /lib/functions.sh +. /lib/functions/network.sh +. ../netifd-proto.sh + +init_proto "$@" + +proto_unet_init_config() { + proto_config_add_string device + proto_config_add_string type + proto_config_add_string auth_key + proto_config_add_string key + proto_config_add_string file + proto_config_add_int keepalive + proto_config_add_string domain + proto_config_add_boolean dht + proto_config_add_array "tunnels:list(string)" + proto_config_add_array "connect:list(string)" + proto_config_add_array "peer_data:list(string)" + no_device=1 + available=1 + no_proto_task=1 +} + +proto_unet_setup() { + local config="$1" + + local device type key file keepalive domain tunnels + json_get_vars device type auth_key key file keepalive domain dht + json_get_values tunnels tunnels + json_get_values connect connect + json_get_values peer_data peer_data + device="${device:-$config}" + + [ -n "$auth_key" ] && type="${type:-dynamic}" + [ -n "$file" ] && type="${type:-file}" + + json_init + json_add_string name "$device" + json_add_string type "$type" + json_add_string interface "$config" + json_add_string auth_key "$auth_key" + json_add_string key "$key" + json_add_string file "$file" + [ -n "$keepalive" ] && json_add_int keepalive "$keepalive" + [ -n "$dht" ] && json_add_boolean dht "$dht" + json_add_string domain "$domain" + + json_add_object tunnels + for t in $tunnels; do + local ifname="${t%%=*}" + local service="${t#*=}" + [ -n "$ifname" -a -n "$service" -a "$ifname" != "$t" ] || continue + json_add_string "$ifname" "$service" + done + json_close_object + + json_add_array auth_connect + for c in $connect; do + json_add_string "" "$c" + done + json_close_array + + json_add_array peer_data + for c in $peer_data; do + json_add_string "" "$c" + done + json_close_array + + ip link del dev "$device" >/dev/null 2>&1 + ip link add dev "$device" type wireguard || { + echo "Could not create wireguard device $device" + proto_setup_failed "$config" + exit 1 + } + + ubus call unetd network_add "$(json_dump)" +} + +proto_unet_teardown() { + local config="$1" + local iface="$2" + + local device + json_get_vars device + device="${device:-$iface}" + + json_init + json_add_string name "$device" + + ip link del dev "$device" + + ubus call unetd network_del "$(json_dump)" +} + +add_protocol unet diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index da38d6b78..7dde2522f 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -11,9 +11,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git -PKG_SOURCE_DATE:=2023-02-06 -PKG_SOURCE_VERSION:=c7eb8ebe33de2ff2d08064258edb047e5ac09f29 -PKG_MIRROR_HASH:=f1124cf305710b0f04e2ea6dd42ba96ba4a3367da4d4afb4c19d5af9905b1cc2 +PKG_SOURCE_DATE:=2024-03-08 +PKG_SOURCE_VERSION:=8ffb8bfd1115ae95265aa52590aa948aba7672e4 +PKG_MIRROR_HASH:=77bb6018b5001268c0f442dbfd8159893db620c575c9810221b1a42a30be4b5f PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=GPL-2.0 @@ -23,7 +23,7 @@ PKG_CONFIG_DEPENDS := \ CONFIG_PACKAGE_kmod-mt7615d_dbdc \ CONFIG_PACKAGE_kmod-cfg80211 -IWINFO_ABI_VERSION:=20230121 +IWINFO_ABI_VERSION:=20230701 include $(INCLUDE_DIR)/package.mk diff --git a/package/network/utils/iwinfo/patches/001-ralink.patch b/package/network/utils/iwinfo/patches/001-ralink.patch index 2d4e2c7a3..379e6eba8 100644 --- a/package/network/utils/iwinfo/patches/001-ralink.patch +++ b/package/network/utils/iwinfo/patches/001-ralink.patch @@ -1494,42 +1494,3 @@ compile: clean $(IWINFO_LIB) $(IWINFO_LUA) $(IWINFO_CLI) ---- a/devices.txt -+++ b/devices.txt -@@ -174,6 +174,36 @@ - 0x1814 0x3662 0x1814 0x000d 0 0 "Ralink" "Rt3662" - 0x1814 0x3883 0x1814 0x000d 0 0 "Ralink" "Rt3883" - 0x1814 0x5350 0x1814 0x000f 0 0 "Ralink" "Rt5350" -+/* MT7620 */ -+0x1814 0x7620 0x1814 0x0000 0 0 "Mediatek" "MT7620" -+0x1814 0x7620 0x1814 0xffff 0 0 "Mediatek" "MT7620" -+0x1814 0x7620 0x1814 0x7620 0 0 "Mediatek" "MT7620" -+/* MT7610 */ -+0x1814 0x7610 0x1814 0x0000 0 0 "Mediatek" "MT7610" -+0x1814 0x7610 0x1814 0xffff 0 0 "Mediatek" "MT7610" -+0x1814 0x7610 0x1814 0x7610 0 0 "Mediatek" "MT7610" -+/* MT7602/MT7612/MT7662 */ -+0x1814 0x7662 0x1814 0x0000 0 0 "Mediatek" "MT7612" -+0x1814 0x7662 0x1814 0xffff 0 0 "Mediatek" "MT7612" -+0x1814 0x7662 0x1814 0x7602 0 0 "Mediatek" "MT7602" -+0x1814 0x7662 0x1814 0x7612 0 0 "Mediatek" "MT7612" -+0x1814 0x7662 0x1814 0x7662 0 0 "Mediatek" "MT7662" -+/* MT7603 */ -+0x1814 0x7603 0x1814 0x0000 0 0 "Mediatek" "MT7603" -+0x1814 0x7603 0x1814 0xffff 0 0 "Mediatek" "MT7603" -+0x1814 0x7603 0x1814 0x7603 0 0 "Mediatek" "MT7603" -+/* MT7628/MT7688 */ -+0x1814 0x7628 0x1814 0x0000 0 0 "Mediatek" "MT7628" -+0x1814 0x7628 0x1814 0xffff 0 0 "Mediatek" "MT7628" -+0x1814 0x7628 0x1814 0x7628 0 0 "Mediatek" "MT7628" -+0x1814 0x7628 0x1814 0x7688 0 0 "Mediatek" "MT7688" -+/* MT7615 */ -+0x1814 0x7615 0x1814 0x0000 0 0 "Mediatek" "MT7615" -+0x1814 0x7615 0x1814 0xffff 0 0 "Mediatek" "MT7615" -+0x1814 0x7615 0x1814 0x7615 0 0 "Mediatek" "MT7615" -+ -+0x14c3 0x7615 0x14c3 0x0000 0 0 "MediaTek" "MT7615E" -+ - 0x11ab 0x2a55 0x11ab 0x0000 0 0 "Marvell" "88W8864" - 0x02df 0x9135 0x0000 0x0000 0 0 "Marvell" "88W8887" - 0x11ab 0x2b40 0x11ab 0x0000 0 0 "Marvell" "88W8964" diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh index 27a2e62c8..c0134f44d 100755 --- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh @@ -187,7 +187,7 @@ proto_qmi_setup() { # Cleanup current state if any uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null 2>&1 - uqmi -s -d "$device" --set-ip-family ipv6 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1 + # Go online uqmi -s -d "$device" --set-device-operating-mode online > /dev/null 2>&1 diff --git a/package/qca/nss-firmware/Makefile b/package/qca/nss-firmware/Makefile new file mode 100644 index 000000000..fda27749c --- /dev/null +++ b/package/qca/nss-firmware/Makefile @@ -0,0 +1,88 @@ +# +# Copyright (C) 2021 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nss-firmware +PKG_SOURCE_DATE:=2022-07-14 +PKG_SOURCE_VERSION:=ade6bff594377c9d9c79b45e39bf104303d919bc +PKG_MIRROR_HASH:=99ca44dd0733cff569308550c6c74febb0e7a03093b14df092d0f53362189647 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/quic/qca-sdk-nss-fw.git + +PKG_LICENSE_FILES:=LICENSE.md + +PKG_MAINTAINER:=Robert Marko + +include $(INCLUDE_DIR)/package.mk + +VERSION_PATH=$(PKG_BUILD_DIR)/QCA_Networking_2022.SPF_12.0.0/ED1 + +define Package/nss-firmware-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=$(PKG_SOURCE_URL) + DEPENDS:=@TARGET_qualcommax +endef + +define Package/nss-firmware-ipq5018 +$(Package/nss-firmware-default) + TITLE:=NSS firmware for IPQ5018 devices + NSS_ARCHIVE:=$(VERSION_PATH)/IPQ5018.ATH.12.0.0/BIN-NSS.FW.12.1-022-MP.R.tar.bz2 +endef + +define Package/nss-firmware-ipq6018 +$(Package/nss-firmware-default) + TITLE:=NSS firmware for IPQ6018 devices + NSS_ARCHIVE:=$(VERSION_PATH)/IPQ6018.ATH.12.0.0/BIN-NSS.FW.12.1-022-CP.R.tar.bz2 +endef + +define Package/nss-firmware-ipq8074 +$(Package/nss-firmware-default) + TITLE:=NSS firmware for IPQ8074 devices + NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.1-022-HK.R.tar.bz2 +endef + +define Build/Compile + true +endef + +define Package/nss-firmware-ipq5018/install + mkdir -p $(PKG_BUILD_DIR)/IPQ5018 + $(TAR) -C $(PKG_BUILD_DIR)/IPQ5018 -xf $(NSS_ARCHIVE) --strip-components=1 + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ5018/retail_router0.bin \ + $(1)/lib/firmware/qca-nss0.bin +endef + +define Package/nss-firmware-ipq6018/install + mkdir -p $(PKG_BUILD_DIR)/IPQ6018 + $(TAR) -C $(PKG_BUILD_DIR)/IPQ6018 -xf $(NSS_ARCHIVE) --strip-components=1 + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ6018/retail_router0.bin \ + $(1)/lib/firmware/qca-nss0.bin +endef + +define Package/nss-firmware-ipq8074/install + mkdir -p $(PKG_BUILD_DIR)/IPQ8074 + $(TAR) -C $(PKG_BUILD_DIR)/IPQ8074 -xf $(NSS_ARCHIVE) --strip-components=1 + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ8074/retail_router0.bin \ + $(1)/lib/firmware/qca-nss0.bin + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/IPQ8074/retail_router1.bin \ + $(1)/lib/firmware/qca-nss1.bin +endef + +$(eval $(call BuildPackage,nss-firmware-ipq5018)) +$(eval $(call BuildPackage,nss-firmware-ipq6018)) +$(eval $(call BuildPackage,nss-firmware-ipq8074)) diff --git a/package/qca/qca-mcs/Makefile b/package/qca/qca-mcs/Makefile new file mode 100644 index 000000000..b3cbe7675 --- /dev/null +++ b/package/qca/qca-mcs/Makefile @@ -0,0 +1,68 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-mcs +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-04-21 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-mcs.git +PKG_SOURCE_VERSION:=8797823e392ac3d9098c090964afd46805a0eb2b +PKG_MIRROR_HASH:=f0fa76af4545842ebf8b4f0743e1079e190dfa5f3f0d464c063063521d3d30df + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-mcs + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + URL:=http://www.qca.qualcomm.com + MAINTAINER:=Qualcomm Atheros, Inc. + TITLE:=QCA Multicast Snooping Support + DEPENDS:=@TARGET_qualcommax \ + +@KERNEL_IPV6_MROUTE +@KERNEL_IP_MROUTE + KCONFIG:=CONFIG_NETFILTER=y \ + CONFIG_BRIDGE_NETFILTER=y + FILES:=$(PKG_BUILD_DIR)/qca-mcs.ko + AUTOLOAD:=$(call AutoLoad,41,qca-mcs) +endef + +define KernelPackage/qca-mcs/Description + This package installs the IGMP/MLD Snooping Module +endef + +QCA_MC_SNOOPING_HEADERS= \ + $(PKG_BUILD_DIR)/mc_api.h \ + $(PKG_BUILD_DIR)/mc_ecm.h \ + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-mcs + $(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/qca-mcs;) + $(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/;) +endef + +EXTRA_CFLAGS+=-Wno-implicit-fallthrough + +QCA_MC_SNOOPING_MAKE_OPTS:= \ + $(KERNEL_MAKE_FLAGS) \ + CONFIG_SUPPORT_MLD=y \ + MDIR=$(PKG_BUILD_DIR) \ + KBUILDPATH=$(LINUX_DIR) \ + KERNELPATH=$(LINUX_SRC_DIR) \ + KERNELRELEASE=$(LINUX_RELEASE) + +define Build/Compile + +$(MAKE) -C $(LINUX_DIR) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + KBUILDPATH=$(LINUX_DIR) \ + $(PKG_MAKE_FLAGS) \ + M=$(PKG_BUILD_DIR) \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + $(strip $(QCA_MC_SNOOPING_MAKE_OPTS)) \ + modules +endef + +$(eval $(call KernelPackage,qca-mcs)) diff --git a/package/qca/qca-mcs/patches/0001-kernel-5.10-compat.patch b/package/qca/qca-mcs/patches/0001-kernel-5.10-compat.patch new file mode 100644 index 000000000..958a7a337 --- /dev/null +++ b/package/qca/qca-mcs/patches/0001-kernel-5.10-compat.patch @@ -0,0 +1,40 @@ +--- a/mc_osdep.h ++++ b/mc_osdep.h +@@ -189,7 +189,7 @@ static inline struct net_bridge_port *mc + + dst = os_br_fdb_get((struct net_bridge *)br, eth_hdr(*skb)->h_dest); + +- if (dst && !dst->is_local) ++ if (dst && !test_bit(BR_FDB_LOCAL, &dst->flags)) + return dst->dst; + + return NULL; +--- a/mc_snooping.c ++++ b/mc_snooping.c +@@ -3453,6 +3453,18 @@ static int mc_proc_snooper_open(struct i + return single_open(file, mc_proc_snooper_show, NULL); + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) ++#define HAVE_PROC_OPS ++#endif ++ ++#ifdef HAVE_PROC_OPS ++static const struct proc_ops mc_proc_snooper_fops = { ++ .proc_open = mc_proc_snooper_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++}; ++#else + static const struct file_operations mc_proc_snooper_fops = { + .owner = THIS_MODULE, + .open = mc_proc_snooper_open, +@@ -3460,6 +3472,7 @@ static const struct file_operations mc_p + .llseek = seq_lseek, + .release = single_release, + }; ++#endif + + /* mc_proc_create_snooper_entry + * create proc entry for information show diff --git a/package/qca/qca-nss-cfi/Makefile b/package/qca/qca-nss-cfi/Makefile new file mode 100644 index 000000000..c9964abd3 --- /dev/null +++ b/package/qca/qca-nss-cfi/Makefile @@ -0,0 +1,82 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-cfi +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-12-15 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-cfi.git +PKG_SOURCE_VERSION:=5cd07ce299ee3ce62dbe4f6783ad36361e57583b +PKG_MIRROR_HASH:=e449eee24fccc09b1cf0f1367bb54cedadcc46a30423934744e78272443197e7 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x" "ipq60xx")) + CFI_OCF_DIR:=ocf/v2.0 + CFI_CRYPTOAPI_DIR:=cryptoapi/v2.0 +else + CFI_CRYPTOAPI_DIR:=cryptoapi/v1.1 + CFI_OCF_DIR:=ocf/v1.0 + CFI_IPSEC_DIR:=ipsec/v1.0 +endif + +define KernelPackage/qca-nss-cfi-cryptoapi + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Cryptographic API modules + DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-crypto +kmod-crypto-authenc + TITLE:=Kernel driver for NSS cfi + FILES:=$(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/qca-nss-cfi-cryptoapi.ko + AUTOLOAD:=$(call AutoLoad,59,qca-nss-cfi-cryptoapi) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/../exports/* $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/qca-nss-cfi +endef + +define KernelPackage/qca-nss-cfi/Description +This package contains a NSS cfi driver for QCA chipset +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(LINUX_DIR)/crypto/ocf \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv + +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x")) +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-clients +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-cfi-cryptoapi),) +MAKE_OPTS+= \ + cryptoapi=y \ + NSS_CRYPTOAPI_ABLK=n \ + NSS_CRYPTOAPI_SKCIPHER=y +endif + +ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") + SOC:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(MAKE_OPTS)) \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + CC="$(TARGET_CC)" \ + CFI_CRYPTOAPI_DIR=$(CFI_CRYPTOAPI_DIR) \ + CFI_OCF_DIR=$(CFI_OCF_DIR) \ + CFI_IPSEC_DIR=$(CFI_IPSEC_DIR) \ + SoC=$(SOC) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-cfi-cryptoapi)) diff --git a/package/qca/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch b/package/qca/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch new file mode 100644 index 000000000..12df90fdc --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0001-cryptoapi-v2.0-fix-SHA1-header-include.patch @@ -0,0 +1,62 @@ +From 1569ac3b6bbcae9c3f4898e0d34aec8f88297ee6 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 21:45:23 +0100 +Subject: [PATCH 1/5] cryptoapi: v2.0: fix SHA1 header include + +SHA1 header has been merged to the generic SHA one, +and with that the cryptohash.h was dropped. + +So, fix include in kernels 5.8 and newer. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi.c | 5 +++++ + cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ + cryptoapi/v2.0/nss_cryptoapi_ahash.c | 5 +++++ + 3 files changed, 15 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -39,7 +39,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -39,7 +39,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c +@@ -38,7 +38,12 @@ + + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include diff --git a/package/qca/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch b/package/qca/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch new file mode 100644 index 000000000..e9702eb33 --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0002-cryptoapi-v2.0-make-ablkcipher-optional.patch @@ -0,0 +1,116 @@ +From 26cca5006bddb0da57398452616e07ee7b11edb1 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:01:34 +0100 +Subject: [PATCH 2/5] cryptoapi: v2.0: make ablkcipher optional + +albkcipher has been removed from the kernel in v5.5, so until it has been +converted to skcipher, lets make it optional to at least have hashes +working. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/Makefile | 3 +++ + cryptoapi/v2.0/nss_cryptoapi.c | 10 ++++++++++ + cryptoapi/v2.0/nss_cryptoapi_private.h | 2 ++ + 3 files changed, 15 insertions(+) + +--- a/cryptoapi/v2.0/Makefile ++++ b/cryptoapi/v2.0/Makefile +@@ -5,7 +5,10 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt + obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o + $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o ++ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o ++ccflags-y += -DNSS_CRYPTOAPI_ABLK ++endif + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o + + obj ?= . +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1367,6 +1367,7 @@ struct aead_alg cryptoapi_aead_algs[] = + /* + * ABLK cipher algorithms + */ ++#if defined(NSS_CRYPTOAPI_ABLK) + static struct crypto_alg cryptoapi_ablkcipher_algs[] = { + { + .cra_name = "cbc(aes)", +@@ -1466,6 +1467,7 @@ static struct crypto_alg cryptoapi_ablkc + }, + } + }; ++#endif + + /* + * AHASH algorithms +@@ -2189,7 +2191,9 @@ void nss_cryptoapi_add_ctx2debugfs(struc + */ + void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) + { ++#if defined(NSS_CRYPTOAPI_ABLK) + struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; + struct nss_cryptoapi *sc = app_data; +@@ -2212,6 +2216,7 @@ void nss_cryptoapi_attach_user(void *app + g_cryptoapi.user = user; + } + ++#if defined(NSS_CRYPTOAPI_ABLK) + for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { + info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); + if(!info || !nss_crypto_algo_is_supp(info->algo)) +@@ -2222,6 +2227,7 @@ void nss_cryptoapi_attach_user(void *app + ablk->cra_flags = 0; + } + } ++#endif + + for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { + info = nss_cryptoapi_cra_name_lookup(aead->base.cra_name); +@@ -2257,7 +2263,9 @@ void nss_cryptoapi_attach_user(void *app + */ + void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) + { ++#if defined(NSS_CRYPTOAPI_ABLK) + struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; + struct nss_cryptoapi *sc = app_data; +@@ -2270,6 +2278,7 @@ void nss_cryptoapi_detach_user(void *app + */ + atomic_set(&g_cryptoapi.registered, 0); + ++#if defined(NSS_CRYPTOAPI_ABLK) + for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { + if (!ablk->cra_flags) + continue; +@@ -2277,6 +2286,7 @@ void nss_cryptoapi_detach_user(void *app + crypto_unregister_alg(ablk); + nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); + } ++#endif + + for (i = 0; enable_aead && (i < ARRAY_SIZE(cryptoapi_aead_algs)); i++, aead++) { + if (!aead->base.cra_flags) +--- a/cryptoapi/v2.0/nss_cryptoapi_private.h ++++ b/cryptoapi/v2.0/nss_cryptoapi_private.h +@@ -250,12 +250,14 @@ extern void nss_cryptoapi_aead_tx_proc(s + /* + * ABLKCIPHER + */ ++#if defined(NSS_CRYPTOAPI_ABLK) + extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); + extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); + extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); + extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); + extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); + extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); ++#endif + + /* + * AHASH diff --git a/package/qca/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch b/package/qca/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch new file mode 100644 index 000000000..ad11b8b35 --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0003-cryptoapi-v2.0-remove-setting-crypto_ahash_type-for-.patch @@ -0,0 +1,137 @@ +From 797b5166783cda0886038ffb22f5386b9363a961 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:08:27 +0100 +Subject: [PATCH 3/5] cryptoapi: v2.0: remove setting crypto_ahash_type for + newer kernels + +Upstream has stopped exporting crypto_ahash_type and removed setting it +on ahash algos since v4.19 as its easily identifiable by the struct type +and its being set in the core directly, so lets do the same. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1495,7 +1495,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1521,7 +1523,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1547,7 +1551,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1573,7 +1579,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1599,7 +1607,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1625,7 +1635,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1655,7 +1667,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = MD5_HMAC_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1681,7 +1695,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1707,7 +1723,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1733,7 +1751,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1759,7 +1779,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, +@@ -1785,7 +1807,9 @@ static struct ahash_alg cryptoapi_ahash_ + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .cra_type = &crypto_ahash_type, ++#endif + .cra_module = THIS_MODULE, + .cra_init = nss_cryptoapi_ahash_cra_init, + .cra_exit = nss_cryptoapi_ahash_cra_exit, diff --git a/package/qca/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch b/package/qca/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch new file mode 100644 index 000000000..a872321fb --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0004-cryptoapi-v2.0-aead-add-downstream-crypto_tfm_alg_fl.patch @@ -0,0 +1,28 @@ +From 8db77add1a794bdee8eef0a351e40bf1cdf6dfa9 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:09:51 +0100 +Subject: [PATCH 4/5] cryptoapi: v2.0: aead: add downstream + crypto_tfm_alg_flags + +crypto_tfm_alg_flags newer made it upstream, but as a temporary stopgap +until a better solution is figured out lets add it. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi_aead.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -61,6 +61,11 @@ + #include + #include "nss_cryptoapi_private.h" + ++static inline u32 crypto_tfm_alg_flags(struct crypto_tfm *tfm) ++{ ++ return tfm->__crt_alg->cra_flags & ~CRYPTO_ALG_TYPE_MASK; ++} ++ + /* + * nss_cryptoapi_aead_ctx2session() + * Cryptoapi function to get the session ID for an AEAD diff --git a/package/qca/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch b/package/qca/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch new file mode 100644 index 000000000..645633abc --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0005-cryptoapi-v2.0-remove-dropped-flags.patch @@ -0,0 +1,97 @@ +From 62bbb188e1a72d28916e1eca31f4cb9fbbf51cd1 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 22:11:06 +0100 +Subject: [PATCH 5/5] cryptoapi: v2.0: remove dropped flags + +Upstream has dropped these flags as there was no use for them, so lets do +the same. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/nss_cryptoapi_aead.c | 6 ------ + cryptoapi/v2.0/nss_cryptoapi_ahash.c | 4 ---- + 2 files changed, 10 deletions(-) + +--- a/cryptoapi/v2.0/nss_cryptoapi_aead.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_aead.c +@@ -207,7 +207,6 @@ int nss_cryptoapi_aead_setkey_noauth(str + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); + if (!ctx->info) { + nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -ENOENT; + } + +@@ -239,7 +238,6 @@ int nss_cryptoapi_aead_setkey_noauth(str + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +@@ -271,14 +269,12 @@ int nss_cryptoapi_aead_setkey(struct cry + */ + if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) { + nss_cfi_err("%px: Unable to extract keys\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EIO; + } + + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keys.enckeylen, crypto_aead_maxauthsize(aead)); + if (!ctx->info) { + nss_cfi_err("%px: Unable to find algorithm with keylen\n", ctx); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -ENOENT; + } + +@@ -299,7 +295,6 @@ int nss_cryptoapi_aead_setkey(struct cry + */ + if (keys.authkeylen > ctx->info->auth_blocksize) { + nss_cfi_err("%px: Auth keylen(%d) exceeds supported\n", ctx, keys.authkeylen); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -342,7 +337,6 @@ int nss_cryptoapi_aead_setkey(struct cry + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +--- a/cryptoapi/v2.0/nss_cryptoapi_ahash.c ++++ b/cryptoapi/v2.0/nss_cryptoapi_ahash.c +@@ -192,7 +192,6 @@ int nss_cryptoapi_ahash_setkey(struct cr + + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, crypto_ahash_digestsize(ahash)); + if (!ctx->info) { +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -215,7 +214,6 @@ int nss_cryptoapi_ahash_setkey(struct cr + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_warn("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + +@@ -299,7 +297,6 @@ int nss_cryptoapi_ahash_init(struct ahas + */ + ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), 0, 0); + if (!ctx->info) { +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + +@@ -314,7 +311,6 @@ int nss_cryptoapi_ahash_init(struct ahas + status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); + if (status < 0) { + nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_FLAGS); + return status; + } + diff --git a/package/qca/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch b/package/qca/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch new file mode 100644 index 000000000..f85e3d892 --- /dev/null +++ b/package/qca/qca-nss-cfi/patches/0006-cryptoapi-v2.0-convert-to-skcipher.patch @@ -0,0 +1,1199 @@ +From 1b30927548c2498c76b815b87f604f9a1de40a48 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 22 Jan 2023 23:31:09 +0100 +Subject: [PATCH] cryptoapi: v2.0: convert to skcipher + +Finally convert the driver from ablkcipher that was dropped in v5.5 to +skcipher. + +Signed-off-by: Robert Marko +--- + cryptoapi/v2.0/Makefile | 6 +- + cryptoapi/v2.0/nss_cryptoapi.c | 200 ++++++++---------- + cryptoapi/v2.0/nss_cryptoapi_private.h | 14 +- + ...ptoapi_ablk.c => nss_cryptoapi_skcipher.c} | 116 +++++----- + 4 files changed, 145 insertions(+), 191 deletions(-) + rename cryptoapi/v2.0/{nss_cryptoapi_ablk.c => nss_cryptoapi_skcipher.c} (74%) + +--- a/cryptoapi/v2.0/Makefile ++++ b/cryptoapi/v2.0/Makefile +@@ -5,9 +5,9 @@ NSS_CRYPTOAPI_MOD_NAME=qca-nss-cfi-crypt + obj-m += $(NSS_CRYPTOAPI_MOD_NAME).o + $(NSS_CRYPTOAPI_MOD_NAME)-objs = nss_cryptoapi.o + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_aead.o +-ifneq "$(NSS_CRYPTOAPI_ABLK)" "n" +-$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ablk.o +-ccflags-y += -DNSS_CRYPTOAPI_ABLK ++ifneq "$(NSS_CRYPTOAPI_SKCIPHER)" "n" ++$(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_skcipher.o ++ccflags-y += -DNSS_CRYPTOAPI_SKCIPHER + endif + $(NSS_CRYPTOAPI_MOD_NAME)-objs += nss_cryptoapi_ahash.o + +--- a/cryptoapi/v2.0/nss_cryptoapi.c ++++ b/cryptoapi/v2.0/nss_cryptoapi.c +@@ -1367,104 +1367,78 @@ struct aead_alg cryptoapi_aead_algs[] = + /* + * ABLK cipher algorithms + */ +-#if defined(NSS_CRYPTOAPI_ABLK) +-static struct crypto_alg cryptoapi_ablkcipher_algs[] = { ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++static struct skcipher_alg cryptoapi_skcipher_algs[] = { + { +- .cra_name = "cbc(aes)", +- .cra_driver_name = "nss-cbc-aes", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = AES_BLOCK_SIZE, +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "rfc3686(ctr(aes))", +- .cra_driver_name = "nss-rfc3686-ctr-aes", +- .cra_priority = 30000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = CTR_RFC3686_IV_SIZE, +-/* +- * geniv deprecated from kernel version 5.0 and above +- */ +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) +- .geniv = "seqiv", +-#endif +- .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "ecb(aes)", +- .cra_driver_name = "nss-ecb-aes", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, +- }, +- { +- .cra_name = "cbc(des3_ede)", +- .cra_driver_name = "nss-cbc-des-ede", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, +- .cra_blocksize = DES3_EDE_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = DES3_EDE_BLOCK_SIZE, +- .min_keysize = DES3_EDE_KEY_SIZE, +- .max_keysize = DES3_EDE_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_setkey, +- .encrypt = nss_cryptoapi_ablk_encrypt, +- .decrypt = nss_cryptoapi_ablk_decrypt, +- }, +- }, ++ .base.cra_name = "cbc(aes)", ++ .base.cra_driver_name = "nss-cbc-aes", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = AES_BLOCK_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "rfc3686(ctr(aes))", ++ .base.cra_driver_name = "nss-rfc3686-ctr-aes", ++ .base.cra_priority = 30000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "ecb(aes)", ++ .base.cra_driver_name = "nss-ecb-aes", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, ++ }, ++ { ++ .base.cra_name = "cbc(des3_ede)", ++ .base.cra_driver_name = "nss-cbc-des-ede", ++ .base.cra_priority = 10000, ++ .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .base.cra_alignmask = 0, ++ .base.cra_module = THIS_MODULE, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .min_keysize = DES3_EDE_KEY_SIZE, ++ .max_keysize = DES3_EDE_KEY_SIZE, ++ .setkey = nss_cryptoapi_skcipher_setkey, ++ .encrypt = nss_cryptoapi_skcipher_encrypt, ++ .decrypt = nss_cryptoapi_skcipher_decrypt, + } + }; + #endif +@@ -2215,8 +2189,8 @@ void nss_cryptoapi_add_ctx2debugfs(struc + */ + void nss_cryptoapi_attach_user(void *app_data, struct nss_crypto_user *user) + { +-#if defined(NSS_CRYPTOAPI_ABLK) +- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; + #endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; +@@ -2240,15 +2214,15 @@ void nss_cryptoapi_attach_user(void *app + g_cryptoapi.user = user; + } + +-#if defined(NSS_CRYPTOAPI_ABLK) +- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { +- info = nss_cryptoapi_cra_name_lookup(ablk->cra_name); ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { ++ info = nss_cryptoapi_cra_name_lookup(ablk->base.cra_name); + if(!info || !nss_crypto_algo_is_supp(info->algo)) + continue; + +- if (crypto_register_alg(ablk)) { +- nss_cfi_err("%px: ABLK registration failed(%s)\n", sc, ablk->cra_name); +- ablk->cra_flags = 0; ++ if (crypto_register_skcipher(ablk)) { ++ nss_cfi_err("%px: skcipher registration failed(%s)\n", sc, ablk->base.cra_name); ++ ablk->base.cra_flags = 0; + } + } + #endif +@@ -2287,8 +2261,8 @@ void nss_cryptoapi_attach_user(void *app + */ + void nss_cryptoapi_detach_user(void *app_data, struct nss_crypto_user *user) + { +-#if defined(NSS_CRYPTOAPI_ABLK) +- struct crypto_alg *ablk = cryptoapi_ablkcipher_algs; ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ struct skcipher_alg *ablk = cryptoapi_skcipher_algs; + #endif + struct aead_alg *aead = cryptoapi_aead_algs; + struct ahash_alg *ahash = cryptoapi_ahash_algs; +@@ -2302,13 +2276,13 @@ void nss_cryptoapi_detach_user(void *app + */ + atomic_set(&g_cryptoapi.registered, 0); + +-#if defined(NSS_CRYPTOAPI_ABLK) +- for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_ablkcipher_algs)); i++, ablk++) { +- if (!ablk->cra_flags) ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++ for (i = 0; enable_ablk && (i < ARRAY_SIZE(cryptoapi_skcipher_algs)); i++, ablk++) { ++ if (!ablk->base.cra_flags) + continue; + +- crypto_unregister_alg(ablk); +- nss_cfi_info("%px: ABLK unregister succeeded, algo: %s\n", sc, ablk->cra_name); ++ crypto_unregister_skcipher(ablk); ++ nss_cfi_info("%px: skcipher unregister succeeded, algo: %s\n", sc, ablk->base.cra_name); + } + #endif + +--- a/cryptoapi/v2.0/nss_cryptoapi_private.h ++++ b/cryptoapi/v2.0/nss_cryptoapi_private.h +@@ -248,14 +248,14 @@ extern void nss_cryptoapi_aead_tx_proc(s + struct nss_cryptoapi_info *info, bool encrypt); + + /* +- * ABLKCIPHER ++ * SKCIPHER + */ +-#if defined(NSS_CRYPTOAPI_ABLK) +-extern int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); +-extern void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); +-extern int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); +-extern int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req); +-extern int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req); ++#if defined(NSS_CRYPTOAPI_SKCIPHER) ++extern int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm); ++extern void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm); ++extern int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len); ++extern int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req); ++extern int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req); + extern void nss_cryptoapi_copy_iv(struct nss_cryptoapi_ctx *ctx, struct scatterlist *sg, uint8_t *iv, uint8_t iv_len); + #endif + +--- a/cryptoapi/v2.0/nss_cryptoapi_ablk.c ++++ /dev/null +@@ -1,458 +0,0 @@ +-/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. +- * +- * Permission to use, copy, modify, and/or distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +- * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT +- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +- * PERFORMANCE OF THIS SOFTWARE. +- * +- * +- */ +- +-/** +- * nss_cryptoapi_ablk.c +- * Interface to communicate Native Linux crypto framework specific data +- * to Crypto core specific data +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "nss_cryptoapi_private.h" +- +-extern struct nss_cryptoapi g_cryptoapi; +- +-/* +- * nss_cryptoapi_skcipher_ctx2session() +- * Cryptoapi function to get the session ID for an skcipher +- */ +-int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) +-{ +- struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); +- struct crypto_ablkcipher **actx, *ablk; +- struct ablkcipher_tfm *ablk_tfm; +- struct nss_cryptoapi_ctx *ctx; +- +- if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) +- return -EINVAL; +- +- /* Get the ablkcipher from the skcipher */ +- actx = crypto_skcipher_ctx(sk); +- if (!actx || !(*actx)) +- return -EINVAL; +- +- /* +- * The ablkcipher now obtained is a wrapper around the actual +- * ablkcipher that is created when the skcipher is created. +- * Hence we derive the required ablkcipher through ablkcipher_tfm. +- */ +- ablk_tfm = crypto_ablkcipher_crt(*actx); +- if (!ablk_tfm) +- return -EINVAL; +- +- ablk = ablk_tfm->base; +- if (!ablk) +- return -EINVAL; +- +- /* Get the nss_cryptoapi context stored in the ablkcipher */ +- ctx = crypto_ablkcipher_ctx(ablk); +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- *sid = ctx->sid; +- return 0; +-} +-EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); +- +-/* +- * nss_cryptoapi_ablkcipher_init() +- * Cryptoapi ablkcipher init function. +- */ +-int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) +-{ +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_SET_MAGIC(ctx); +- +- memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); +- +- ctx->user = g_cryptoapi.user; +- ctx->stats.init++; +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- init_completion(&ctx->complete); +- +- return 0; +-} +- +-/* +- * nss_cryptoapi_ablkcipher_exit() +- * Cryptoapi ablkcipher exit function. +- */ +-void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) +-{ +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- int ret; +- +- BUG_ON(!ctx); +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- ctx->stats.exit++; +- +- /* +- * When fallback_req is set, it means that fallback tfm was used +- * we didn't create any sessions. +- */ +- if (ctx->fallback_req) { +- ctx->stats.failed_fallback++; +- return; +- } +- +- if (!atomic_read(&ctx->active)) { +- ctx->stats.failed_exit++; +- return; +- } +- +- /* +- * Mark cryptoapi context as inactive +- */ +- atomic_set(&ctx->active, 0); +- +- if (!atomic_sub_and_test(1, &ctx->refcnt)) { +- /* +- * We need to wait for any outstanding packet using this ctx. +- * Once the last packet get processed, reference count will become +- * 0 this ctx. We will wait for the reference to go down to 0. +- */ +- ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); +- WARN_ON(!ret); +- } +- +- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { +- nss_crypto_session_free(ctx->user, ctx->sid); +- debugfs_remove_recursive(ctx->dentry); +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- } +- +- NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); +-} +- +-/* +- * nss_cryptoapi_ablk_setkey() +- * Cryptoapi setkey routine for aes. +- */ +-int nss_cryptoapi_ablk_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) +-{ +- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- struct nss_crypto_session_data data = {0}; +- int status; +- +- /* +- * Validate magic number - init should be called before setkey +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); +- if (!ctx->info) { +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); +- return -EINVAL; +- } +- +- ctx->iv_size = crypto_ablkcipher_ivsize(cipher); +- +- if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { +- keylen = keylen - CTR_RFC3686_NONCE_SIZE; +- memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); +- ctx->ctx_iv[3] = ntohl(0x1); +- ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); +- } +- +- /* +- * Fill NSS crypto session data +- */ +- data.algo = ctx->info->algo; +- data.cipher_key = key; +- +- if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) +- return -ERANGE; +- +- if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { +- nss_crypto_session_free(ctx->user, ctx->sid); +- debugfs_remove_recursive(ctx->dentry); +- ctx->sid = NSS_CRYPTO_SESSION_MAX; +- } +- +- status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); +- if (status < 0) { +- nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_FLAGS); +- return status; +- } +- +- nss_cryptoapi_add_ctx2debugfs(ctx); +- atomic_set(&ctx->active, 1); +- atomic_set(&ctx->refcnt, 1); +- return 0; +-} +- +-/* +- * nss_cryptoapi_ablkcipher_done() +- * Cipher operation completion callback function +- */ +-void nss_cryptoapi_ablkcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) +-{ +- struct ablkcipher_request *req = app_data; +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm); +- int error; +- +- BUG_ON(!ch); +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * For skcipher decryption case, the last block of encrypted data is used as +- * an IV for the next data +- */ +- if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { +- nss_cryptoapi_copy_iv(ctx, req->dst, req->info, ch->iv_len); +- } +- +- /* +- * Free crypto hdr +- */ +- nss_crypto_hdr_free(ctx->user, ch); +- +- nss_cfi_dbg("data dump after transformation\n"); +- nss_cfi_dbg_data(sg_virt(req->dst), req->nbytes, ' '); +- +- /* +- * Check if there is any error reported by hardware +- */ +- error = nss_cryptoapi_status2error(ctx, status); +- ctx->stats.completed++; +- +- /* +- * Decrement cryptoapi reference +- */ +- nss_cryptoapi_ref_dec(ctx); +- req->base.complete(&req->base, error); +-} +- +-/* +- * nss_cryptoapi_ablk_encrypt() +- * Crytoapi encrypt for AES and 3DES algorithms. +- */ +-int nss_cryptoapi_ablk_encrypt(struct ablkcipher_request *req) +-{ +- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); +- struct crypto_tfm *tfm = req->base.tfm; +- struct scatterlist *cur; +- int tot_len = 0; +- int i; +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * Check if cryptoapi context is active or not +- */ +- if (!atomic_read(&ctx->active)) +- return -EINVAL; +- +- if (sg_nents(req->src) != sg_nents(req->dst)) { +- ctx->stats.failed_req++; +- return -EINVAL; +- } +- +- /* +- * Block size not aligned. +- * AES-CTR requires only a one-byte block size alignment. +- */ +- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { +- ctx->stats.failed_align++; +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); +- return -EFAULT; +- } +- +- /* +- * Fill the request information structure +- */ +- info.iv = req->info; +- info.src.nsegs = sg_nents(req->src); +- info.dst.nsegs = sg_nents(req->dst); +- info.op_dir = NSS_CRYPTO_OP_DIR_ENC; +- info.cb = nss_cryptoapi_ablkcipher_done; +- info.iv_size = ctx->iv_size; +- info.src.first_sg = req->src; +- info.dst.first_sg = req->dst; +- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); +- +- /* out and in length will be same as ablk does only encrypt/decryt operation */ +- info.total_in_len = info.total_out_len = req->nbytes; +- info.in_place = (req->src == req->dst) ? true : false; +- +- /* +- * The exact length of data that needs to be ciphered for an ABLK +- * request is stored in req->nbytes. Hence we may have to reduce +- * the DMA length to what is specified in req->nbytes and later +- * restore the length of scatterlist back to its original value. +- */ +- for_each_sg(req->src, cur, info.src.nsegs, i) { +- if (!cur) +- break; +- +- tot_len += cur->length; +- if (!sg_next(cur)) +- break; +- } +- +- /* +- * We only support (2^16 - 1) length. +- */ +- if (tot_len > U16_MAX) { +- ctx->stats.failed_len++; +- return -EFBIG; +- } +- +- info.src.last_sg = cur; +- info.ahash_skip = tot_len - req->nbytes; +- +- if (!atomic_inc_not_zero(&ctx->refcnt)) +- return -ENOENT; +- +- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); +-} +- +-/* +- * nss_cryptoapi_ablk_decrypt() +- * Crytoapi decrypt for AES and 3DES CBC algorithms. +- */ +-int nss_cryptoapi_ablk_decrypt(struct ablkcipher_request *req) +-{ +- struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); +- struct crypto_tfm *tfm = req->base.tfm; +- struct scatterlist *cur; +- int tot_len = 0; +- int i; +- +- /* +- * Check cryptoapi context magic number. +- */ +- NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); +- +- /* +- * Check if cryptoapi context is active or not +- */ +- if (!atomic_read(&ctx->active)) +- return -EINVAL; +- +- if (sg_nents(req->src) != sg_nents(req->dst)) { +- ctx->stats.failed_req++; +- return -EINVAL; +- } +- +- /* +- * Block size not aligned +- */ +- if (!IS_ALIGNED(req->nbytes, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { +- ctx->stats.failed_align++; +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); +- return -EFAULT; +- } +- +- /* +- * Fill the request information structure +- * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. +- * This is because linux gives iv size as 8 while we need to alloc 16 bytes +- * in crypto hdr to accomodate +- * - 4 bytes of nonce +- * - 8 bytes of IV +- * - 4 bytes of initial counter +- */ +- info.iv = req->info; +- info.src.nsegs = sg_nents(req->src); +- info.dst.nsegs = sg_nents(req->dst); +- info.iv_size = ctx->iv_size; +- info.op_dir = NSS_CRYPTO_OP_DIR_DEC; +- info.cb = nss_cryptoapi_ablkcipher_done; +- info.src.first_sg = req->src; +- info.dst.first_sg = req->dst; +- info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); +- +- /* out and in length will be same as ablk does only encrypt/decryt operation */ +- info.total_in_len = info.total_out_len = req->nbytes; +- info.in_place = (req->src == req->dst) ? true : false; +- +- /* +- * The exact length of data that needs to be ciphered for an ABLK +- * request is stored in req->nbytes. Hence we may have to reduce +- * the DMA length to what is specified in req->nbytes and later +- * restore the length of scatterlist back to its original value. +- */ +- for_each_sg(req->src, cur, info.src.nsegs, i) { +- tot_len += cur->length; +- if (!sg_next(cur)) +- break; +- } +- +- /* +- * We only support (2^16 - 1) length. +- */ +- if (tot_len > U16_MAX) { +- ctx->stats.failed_len++; +- return -EFBIG; +- } +- +- info.ahash_skip = tot_len - req->nbytes; +- info.src.last_sg = cur; +- +- if (!atomic_inc_not_zero(&ctx->refcnt)) +- return -ENOENT; +- +- return nss_cryptoapi_transform(ctx, &info, (void *)req, false); +-} +--- /dev/null ++++ b/cryptoapi/v2.0/nss_cryptoapi_skcipher.c +@@ -0,0 +1,438 @@ ++/* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT ++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ * ++ * ++ */ ++ ++/** ++ * nss_cryptoapi_ablk.c ++ * Interface to communicate Native Linux crypto framework specific data ++ * to Crypto core specific data ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) ++#include ++#else ++#include ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "nss_cryptoapi_private.h" ++ ++extern struct nss_cryptoapi g_cryptoapi; ++ ++/* ++ * nss_cryptoapi_skcipher_ctx2session() ++ * Cryptoapi function to get the session ID for an skcipher ++ */ ++int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(sk); ++ struct nss_cryptoapi_ctx *ctx; ++ ++ if (strncmp("nss-", crypto_tfm_alg_driver_name(tfm), 4)) ++ return -EINVAL; ++ ++ /* Get the nss_cryptoapi context stored in skcipher */ ++ ctx = crypto_skcipher_ctx(sk); ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ *sid = ctx->sid; ++ return 0; ++} ++EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); ++ ++/* ++ * nss_cryptoapi_skcipher_init() ++ * Cryptoapi skcipher init function. ++ */ ++int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm) ++{ ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); ++ ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_SET_MAGIC(ctx); ++ ++ memset(ctx, 0, sizeof(struct nss_cryptoapi_ctx)); ++ ++ ctx->user = g_cryptoapi.user; ++ ctx->stats.init++; ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ init_completion(&ctx->complete); ++ ++ return 0; ++} ++ ++/* ++ * nss_cryptoapi_skcipher_exit() ++ * Cryptoapi skcipher exit function. ++ */ ++void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm) ++{ ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); ++ int ret; ++ ++ BUG_ON(!ctx); ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ ctx->stats.exit++; ++ ++ /* ++ * When fallback_req is set, it means that fallback tfm was used ++ * we didn't create any sessions. ++ */ ++ if (ctx->fallback_req) { ++ ctx->stats.failed_fallback++; ++ return; ++ } ++ ++ if (!atomic_read(&ctx->active)) { ++ ctx->stats.failed_exit++; ++ return; ++ } ++ ++ /* ++ * Mark cryptoapi context as inactive ++ */ ++ atomic_set(&ctx->active, 0); ++ ++ if (!atomic_sub_and_test(1, &ctx->refcnt)) { ++ /* ++ * We need to wait for any outstanding packet using this ctx. ++ * Once the last packet get processed, reference count will become ++ * 0 this ctx. We will wait for the reference to go down to 0. ++ */ ++ ret = wait_for_completion_timeout(&ctx->complete, NSS_CRYPTOAPI_REQ_TIMEOUT_TICKS); ++ WARN_ON(!ret); ++ } ++ ++ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { ++ nss_crypto_session_free(ctx->user, ctx->sid); ++ debugfs_remove_recursive(ctx->dentry); ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ } ++ ++ NSS_CRYPTOAPI_CLEAR_MAGIC(ctx); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_setkey() ++ * Cryptoapi setkey routine for aes. ++ */ ++int nss_cryptoapi_skcipher_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct nss_crypto_session_data data = {0}; ++ int status; ++ ++ /* ++ * Validate magic number - init should be called before setkey ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ ctx->info = nss_cryptoapi_cra_name2info(crypto_tfm_alg_name(tfm), keylen, 0); ++ if (!ctx->info) { ++ return -EINVAL; ++ } ++ ++ ctx->iv_size = crypto_skcipher_ivsize(cipher); ++ ++ if (ctx->info->cipher_mode == NSS_CRYPTOAPI_CIPHER_MODE_CTR_RFC3686) { ++ keylen = keylen - CTR_RFC3686_NONCE_SIZE; ++ memcpy(ctx->ctx_iv, key + keylen, CTR_RFC3686_NONCE_SIZE); ++ ctx->ctx_iv[3] = ntohl(0x1); ++ ctx->iv_size += CTR_RFC3686_NONCE_SIZE + sizeof(uint32_t); ++ } ++ ++ /* ++ * Fill NSS crypto session data ++ */ ++ data.algo = ctx->info->algo; ++ data.cipher_key = key; ++ ++ if (data.algo >= NSS_CRYPTO_CMN_ALGO_MAX) ++ return -ERANGE; ++ ++ if (ctx->sid != NSS_CRYPTO_SESSION_MAX) { ++ nss_crypto_session_free(ctx->user, ctx->sid); ++ debugfs_remove_recursive(ctx->dentry); ++ ctx->sid = NSS_CRYPTO_SESSION_MAX; ++ } ++ ++ status = nss_crypto_session_alloc(ctx->user, &data, &ctx->sid); ++ if (status < 0) { ++ nss_cfi_err("%px: Unable to allocate crypto session(%d)\n", ctx, status); ++ return status; ++ } ++ ++ nss_cryptoapi_add_ctx2debugfs(ctx); ++ atomic_set(&ctx->active, 1); ++ atomic_set(&ctx->refcnt, 1); ++ return 0; ++} ++ ++/* ++ * nss_cryptoapi_skcipher_done() ++ * Cipher operation completion callback function ++ */ ++void nss_cryptoapi_skcipher_done(void *app_data, struct nss_crypto_hdr *ch, uint8_t status) ++{ ++ struct skcipher_request *req = app_data; ++ struct nss_cryptoapi_ctx *ctx = skcipher_request_ctx(req); ++ int error; ++ ++ BUG_ON(!ch); ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * For skcipher decryption case, the last block of encrypted data is used as ++ * an IV for the next data ++ */ ++ if (ch->op == NSS_CRYPTO_OP_DIR_ENC) { ++ nss_cryptoapi_copy_iv(ctx, req->dst, req->iv, ch->iv_len); ++ } ++ ++ /* ++ * Free crypto hdr ++ */ ++ nss_crypto_hdr_free(ctx->user, ch); ++ ++ nss_cfi_dbg("data dump after transformation\n"); ++ nss_cfi_dbg_data(sg_virt(req->dst), req->cryptlen, ' '); ++ ++ /* ++ * Check if there is any error reported by hardware ++ */ ++ error = nss_cryptoapi_status2error(ctx, status); ++ ctx->stats.completed++; ++ ++ /* ++ * Decrement cryptoapi reference ++ */ ++ nss_cryptoapi_ref_dec(ctx); ++ req->base.complete(&req->base, error); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_encrypt() ++ * Crytoapi encrypt for AES and 3DES algorithms. ++ */ ++int nss_cryptoapi_skcipher_encrypt(struct skcipher_request *req) ++{ ++ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_ENC}; ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct crypto_tfm *tfm = req->base.tfm; ++ struct scatterlist *cur; ++ int tot_len = 0; ++ int i; ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * Check if cryptoapi context is active or not ++ */ ++ if (!atomic_read(&ctx->active)) ++ return -EINVAL; ++ ++ if (sg_nents(req->src) != sg_nents(req->dst)) { ++ ctx->stats.failed_req++; ++ return -EINVAL; ++ } ++ ++ /* ++ * Block size not aligned. ++ * AES-CTR requires only a one-byte block size alignment. ++ */ ++ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { ++ ctx->stats.failed_align++; ++ return -EFAULT; ++ } ++ ++ /* ++ * Fill the request information structure ++ */ ++ info.iv = req->iv; ++ info.src.nsegs = sg_nents(req->src); ++ info.dst.nsegs = sg_nents(req->dst); ++ info.op_dir = NSS_CRYPTO_OP_DIR_ENC; ++ info.cb = nss_cryptoapi_skcipher_done; ++ info.iv_size = ctx->iv_size; ++ info.src.first_sg = req->src; ++ info.dst.first_sg = req->dst; ++ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); ++ ++ /* out and in length will be same as ablk does only encrypt/decryt operation */ ++ info.total_in_len = info.total_out_len = req->cryptlen; ++ info.in_place = (req->src == req->dst) ? true : false; ++ ++ /* ++ * The exact length of data that needs to be ciphered for an ABLK ++ * request is stored in req->cryptlen. Hence we may have to reduce ++ * the DMA length to what is specified in req->cryptlen and later ++ * restore the length of scatterlist back to its original value. ++ */ ++ for_each_sg(req->src, cur, info.src.nsegs, i) { ++ if (!cur) ++ break; ++ ++ tot_len += cur->length; ++ if (!sg_next(cur)) ++ break; ++ } ++ ++ /* ++ * We only support (2^16 - 1) length. ++ */ ++ if (tot_len > U16_MAX) { ++ ctx->stats.failed_len++; ++ return -EFBIG; ++ } ++ ++ info.src.last_sg = cur; ++ info.ahash_skip = tot_len - req->cryptlen; ++ ++ if (!atomic_inc_not_zero(&ctx->refcnt)) ++ return -ENOENT; ++ ++ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); ++} ++ ++/* ++ * nss_cryptoapi_skcipher_decrypt() ++ * Crytoapi decrypt for AES and 3DES CBC algorithms. ++ */ ++int nss_cryptoapi_skcipher_decrypt(struct skcipher_request *req) ++{ ++ struct nss_cryptoapi_info info = {.op_dir = NSS_CRYPTO_OP_DIR_DEC}; ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); ++ struct crypto_tfm *tfm = req->base.tfm; ++ struct scatterlist *cur; ++ int tot_len = 0; ++ int i; ++ ++ /* ++ * Check cryptoapi context magic number. ++ */ ++ NSS_CRYPTOAPI_VERIFY_MAGIC(ctx); ++ ++ /* ++ * Check if cryptoapi context is active or not ++ */ ++ if (!atomic_read(&ctx->active)) ++ return -EINVAL; ++ ++ if (sg_nents(req->src) != sg_nents(req->dst)) { ++ ctx->stats.failed_req++; ++ return -EINVAL; ++ } ++ ++ /* ++ * Block size not aligned ++ */ ++ if (!IS_ALIGNED(req->cryptlen, crypto_tfm_alg_blocksize(tfm)) && ctx->info->blk_align) { ++ ctx->stats.failed_align++; ++ return -EFAULT; ++ } ++ ++ /* ++ * Fill the request information structure ++ * Note: For CTR mode, IV size will be set to AES_BLOCK_SIZE. ++ * This is because linux gives iv size as 8 while we need to alloc 16 bytes ++ * in crypto hdr to accomodate ++ * - 4 bytes of nonce ++ * - 8 bytes of IV ++ * - 4 bytes of initial counter ++ */ ++ info.iv = req->iv; ++ info.src.nsegs = sg_nents(req->src); ++ info.dst.nsegs = sg_nents(req->dst); ++ info.iv_size = ctx->iv_size; ++ info.op_dir = NSS_CRYPTO_OP_DIR_DEC; ++ info.cb = nss_cryptoapi_skcipher_done; ++ info.src.first_sg = req->src; ++ info.dst.first_sg = req->dst; ++ info.dst.last_sg = sg_last(req->dst, info.dst.nsegs); ++ ++ /* out and in length will be same as ablk does only encrypt/decryt operation */ ++ info.total_in_len = info.total_out_len = req->cryptlen; ++ info.in_place = (req->src == req->dst) ? true : false; ++ ++ /* ++ * The exact length of data that needs to be ciphered for an ABLK ++ * request is stored in req->cryptlen. Hence we may have to reduce ++ * the DMA length to what is specified in req->cryptlen and later ++ * restore the length of scatterlist back to its original value. ++ */ ++ for_each_sg(req->src, cur, info.src.nsegs, i) { ++ tot_len += cur->length; ++ if (!sg_next(cur)) ++ break; ++ } ++ ++ /* ++ * We only support (2^16 - 1) length. ++ */ ++ if (tot_len > U16_MAX) { ++ ctx->stats.failed_len++; ++ return -EFBIG; ++ } ++ ++ info.ahash_skip = tot_len - req->cryptlen; ++ info.src.last_sg = cur; ++ ++ if (!atomic_inc_not_zero(&ctx->refcnt)) ++ return -ENOENT; ++ ++ return nss_cryptoapi_transform(ctx, &info, (void *)req, false); ++} diff --git a/package/qca/qca-nss-clients/Makefile b/package/qca/qca-nss-clients/Makefile new file mode 100644 index 000000000..555fd790f --- /dev/null +++ b/package/qca/qca-nss-clients/Makefile @@ -0,0 +1,612 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-clients +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-10-04 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-clients.git +PKG_SOURCE_VERSION:=f058ae199b42f30be9925b2ed1ce53afb128200c +PKG_MIRROR_HASH:=90401b577a7750d3b7eadb423700aab7e1da1af392637598e08f6007f23a92e1 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") + SOC="ipq807x_64" + subtarget:=$(CONFIG_TARGET_SUBTARGET) +else ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") + SOC="ipq60xx_64" + subtarget:=$(CONFIG_TARGET_SUBTARGET) +endif + +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq60xx")) + DTLSMGR_DIR:=v2.0 + IPSECMGR_DIR:=v2.0 + IPSECMGR_KLIPS:= $(PKG_BUILD_DIR)/ipsecmgr/$(IPSECMGR_DIR)/plugins/klips/qca-nss-ipsec-klips.ko +endif + +define KernelPackage/qca-nss-drv-gre + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - GRE + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_GRE_ENABLE +kmod-gre6 \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:= \ + $(PKG_BUILD_DIR)/gre/qca-nss-gre.ko \ + $(PKG_BUILD_DIR)/gre/test/qca-nss-gre-test.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-gre) +endef + +define KernelPackage/qca-nss-drv-gre/description +Kernel modules for NSS connection manager - Support for GRE +endef + +define KernelPackage/qca-nss-drv-l2tpv2 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - l2tp + DEPENDS:=@NSS_DRV_L2TP_ENABLE +kmod-ppp +kmod-l2tp \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/l2tp/l2tpv2/qca-nss-l2tpv2.ko + KCONFIG:=CONFIG_L2TP=y + AUTOLOAD:=$(call AutoLoad,51,qca-nss-l2tpv2) +endef + +define KernelPackage/qca-nss-drv-l2tp/description +Kernel modules for NSS connection manager - Support for l2tp tunnel +endef + +define KernelPackage/qca-nss-drv-pptp + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - PPTP + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_PPTP_ENABLE +kmod-pptp \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/pptp/qca-nss-pptp.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-pptp) +endef + +define KernelPackage/qca-nss-drv-pptp/description +Kernel modules for NSS connection manager - Support for PPTP tunnel +endef + +define KernelPackage/qca-nss-drv-pppoe + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - PPPoE + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_PPPOE_ENABLE \ + +PACKAGE_kmod-bonding:kmod-bonding +kmod-pppoe \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/pppoe/qca-nss-pppoe.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-pppoe) +endef + +define KernelPackage/qca-nss-drv-pppoe/Description +Kernel modules for NSS connection manager - Support for PPPoE +endef + +define KernelPackage/qca-nss-drv-map-t + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - MAP-T + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_MAPT_ENABLE \ + +PACKAGE_kmod-nat46:kmod-nat46 \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/map/map-t/qca-nss-map-t.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-map-t) +endef + +define KernelPackage/qca-nss-drv-map-t/description +Kernel modules for NSS connection manager - Support for MAP-T +endef + +define KernelPackage/qca-nss-drv-tun6rd + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - tun6rd + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_TUN6RD_ENABLE +6rd \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv +kmod-sit + FILES:=$(PKG_BUILD_DIR)/qca-nss-tun6rd.ko + AUTOLOAD:=$(call AutoLoad,60,qca-nss-tun6rd) +endef + +define KernelPackage/qca-nss-drv-tun6rd/description +Kernel modules for NSS connection manager - Support for 6rd tunnel +endef + +define KernelPackage/qca-nss-drv-tunipip6 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - DS-lite and ipip6 Tunnel + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_TUNIPIP6_ENABLE +kmod-iptunnel6 \ + +kmod-ip6-tunnel +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/tunipip6/qca-nss-tunipip6.ko + AUTOLOAD:=$(call AutoLoad,60,qca-nss-tunipip6) +endef + +define KernelPackage/qca-nss-drv-tunipip6/description +Kernel modules for NSS connection manager +Add support for DS-lite and ipip6 tunnel +endef + +define KernelPackage/qca-nss-drv-bridge-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS bridge manager + DEPENDS:=@TARGET_qualcommax \ + +kmod-qca-nss-drv-vlan-mgr \ + +@NSS_DRV_BRIDGE_ENABLE \ + +PACKAGE_kmod-bonding:kmod-bonding \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv +ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),) + DEPENDS+=kmod-qca-ovsmgr +endif + FILES:=$(PKG_BUILD_DIR)/bridge/qca-nss-bridge-mgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-bridge-mgr) +endef + +define KernelPackage/qca-nss-drv-bridge-mgr/Description +Kernel modules for NSS bridge manager +endef + +define KernelPackage/qca-nss-drv-clmapmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+@NSS_DRV_CLMAP_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +kmod-qca-nss-drv-eogremgr + TITLE:=NSS clmap Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/clmapmgr/qca-nss-clmapmgr.ko +endef + +define KernelPackage/qca-nss-drv-clmapmgr/description +Kernel module for managing NSS clmap +endef + +define KernelPackage/qca-nss-drv-dtlsmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - dtlsmgr + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_DTLS_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +PACKAGE_kmod-qca-nss-cfi-cryptoapi:kmod-qca-nss-cfi-cryptoapi + FILES:=$(PKG_BUILD_DIR)/dtls/$(DTLSMGR_DIR)/qca-nss-dtlsmgr.ko +endef + +define KernelPackage/qca-nss-drv-dtls/description +Kernel modules for NSS connection manager - Support for DTLS sessions +endef + +define KernelPackage/qca-nss-drv-tlsmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - tlsmgr + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_TLS_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +PACKAGE_kmod-qca-nss-cfi-cryptoapi:kmod-qca-nss-cfi-cryptoapi + FILES:=$(PKG_BUILD_DIR)/tls/qca-nss-tlsmgr.ko +endef + +define KernelPackage/qca-nss-drv-tls/description +Kernel modules for NSS connection manager - Support for TLS sessions +endef + +define KernelPackage/qca-nss-drv-ipsecmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (ipsec manager) - ipsecmgr + DEPENDS:=@TARGET_qualcommax \ + +@NSS_DRV_IPSEC_ENABLE \ + +@NSS_DRV_TSTAMP_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +PACKAGE_kmod-qca-nss-cfi-cryptoapi:kmod-qca-nss-cfi-cryptoapi +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-l2tpv2),) + DEPENDS+=+kmod-qca-nss-drv-l2tpv2 +endif + FILES:=$(PKG_BUILD_DIR)/ipsecmgr/$(IPSECMGR_DIR)/qca-nss-ipsecmgr.ko $(IPSECMGR_KLIPS) + AUTOLOAD:=$(call AutoLoad,60,qca-nss-ipsecmgr) +endef + +define KernelPackage/qca-nss-drv-ipsecmgr/description +Kernel module for NSS IPsec offload manager +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS OpenVPN manager + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_OVPN_ENABLE \ + +kmod-qca-nss-drv +kmod-tun +kmod-ipt-conntrack \ + +PACKAGE_kmod-qca-nss-cfi-cryptoapi:kmod-qca-nss-cfi-cryptoapi + FILES:=$(PKG_BUILD_DIR)/openvpn/src/qca-nss-ovpn-mgr.ko +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr/description +Kernel module for NSS OpenVPN manager +endef + +define KernelPackage/qca-nss-drv-ovpn-link + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for interfacing NSS OpenVPN manager with ECM + DEPENDS:=@TARGET_qualcommax \ + +kmod-qca-nss-drv-ovpn-mgr \ + +@PACKAGE_kmod-qca-nss-ecm + FILES:=$(PKG_BUILD_DIR)/openvpn/plugins/qca-nss-ovpn-link.ko +endef + +define KernelPackage/qca-nss-drv-ovpn-link/description +This module registers with ECM and communicates with NSS OpenVPN manager for supporting OpenVPN offload. +endef + +define KernelPackage/qca-nss-drv-pvxlanmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_PVXLAN_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + TITLE:=NSS PVXLAN Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/pvxlanmgr/qca-nss-pvxlanmgr.ko +endef + +define KernelPackage/qca-nss-drv-pvxlanmgr/description +Kernel module for managing NSS PVxLAN +endef + +define KernelPackage/qca-nss-drv-eogremgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+@NSS_DRV_GRE_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +kmod-qca-nss-drv-gre + TITLE:=NSS EOGRE Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/eogremgr/qca-nss-eogremgr.ko +endef + +define KernelPackage/qca-nss-drv-eogremgr/description +Kernel module for managing NSS EoGRE +endef + +define KernelPackage/qca-nss-drv-clmapmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+@NSS_DRV_CLMAP_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +kmod-qca-nss-drv-eogremgr + TITLE:=NSS clmap Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/clmapmgr/qca-nss-clmapmgr.ko +endef + +define KernelPackage/qca-nss-drv-clmapmgr/description +Kernel module for managing NSS clmap +endef + +define KernelPackage/qca-nss-drv-lag-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS LAG manager + DEPENDS:=+@NSS_DRV_LAG_ENABLE \ + +kmod-qca-nss-drv-vlan-mgr \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv \ + +PACKAGE_kmod-bonding:kmod-bonding + FILES:=$(PKG_BUILD_DIR)/lag/qca-nss-lag-mgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-lag-mgr) +endef + +define KernelPackage/qca-nss-drv-lag-mgr/description +Kernel modules for NSS LAG manager +endef + +define KernelPackage/qca-nss-drv-vxlanmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_qualcommax +kmod-vxlan \ + +@NSS_DRV_VXLAN_ENABLE +@NSS_DRV_PVXLAN_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + TITLE:=NSS VxLAN Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/vxlanmgr/qca-nss-vxlanmgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-vxlanmgr) +endef + +define KernelPackage/qca-nss-drv-vxlanmgr/description +Kernel module for managing NSS VxLAN +endef + +define KernelPackage/qca-nss-drv-vlan-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS vlan manager + DEPENDS:=@TARGET_qualcommax \ + +@NSS_DRV_VLAN_ENABLE \ + +PACKAGE_kmod-bonding:kmod-bonding \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/vlan/qca-nss-vlan.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-vlan) +endef + +define KernelPackage/qca-nss-drv-vlan-mgr/Description +Kernel modules for NSS vlan manager +endef + +define KernelPackage/qca-nss-drv-igs + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + TITLE:=Action for offloading traffic to an IFB interface to perform ingress shaping. + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_IGS_ENABLE +kmod-qca-nss-drv-qdisc \ + +kmod-sched-core +kmod-nf-conntrack +kmod-ifb \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/nss_qdisc/igs/act_nssmirred.ko +endef + +define KernelPackage/qca-nss-drv-igs/description +Linux action that helps in offloading traffic to an IFB interface to perform ingress shaping. +endef + +define KernelPackage/qca-nss-drv-match + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_MATCH_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + TITLE:=NSS Match for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/match/qca-nss-match.ko +endef + +define KernelPackage/qca-nss-drv-match/description +Kernel module for managing NSS Match +endef + +define KernelPackage/qca-nss-drv-mirror + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + TITLE:=Module for mirroring packets from NSS to host. + DEPENDS:=+@NSS_DRV_MIRROR_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/mirror/qca-nss-mirror.ko +endef + +define KernelPackage/qca-nss-drv-mirror/Description +Kernel module for managing NSS Mirror +endef + +define KernelPackage/qca-nss-drv-netlink + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=NSS NETLINK Manager for QCA NSS driver + DEPENDS:=@TARGET_qualcommax +@NSS_DRV_C2C_ENABLE +@NSS_DRV_GRE_REDIR_ENABLE \ + +@NSS_DRV_IPV4_REASM_ENABLE +@NSS_DRV_IPV6_ENABLE +@NSS_DRV_IPV6_REASM_ENABLE \ + +@NSS_DRV_RMNET_ENABLE +@NSS_DRV_OAM_ENABLE +@NSS_DRV_QRFS_ENABLE \ + +kmod-pppoe +kmod-qca-nss-drv-dtlsmgr \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/netlink/qca-nss-netlink.ko +endef + +define KernelPackage/qca-nss-drv-netlink/Description +Kernel module for NSS netlink manager +endef + +define KernelPackage/qca-nss-drv-qdisc + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + TITLE:=Qdisc for configuring shapers in NSS + DEPENDS:=@TARGET_qualcommax \ + +@NSS_DRV_SHAPER_ENABLE +@NSS_DRV_IGS_ENABLE \ + +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv + FILES:=$(PKG_BUILD_DIR)/nss_qdisc/qca-nss-qdisc.ko + KCONFIG:=CONFIG_NET_CLS_ACT=y + AUTOLOAD:=$(call AutoLoad,58,qca-nss-qdisc) +endef + +define KernelPackage/qca-nss-drv-qdisc/Description +Linux qdisc that aids in configuring shapers in the NSS +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-clients + $(CP) $(PKG_BUILD_DIR)/netlink/include/* $(1)/usr/include/qca-nss-clients/ + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-clients/ +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-ovpn.init $(1)/etc/init.d/qca-nss-ovpn +endef + +define KernelPackage/qca-nss-drv-ipsecmgr/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-ipsec $(1)/etc/init.d/qca-nss-ipsec +endef + +define KernelPackage/qca-nss-drv-igs/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-mirred.init $(1)/etc/init.d/qca-nss-mirred +endef + +define KernelPackage/qca-nss-drv-netlink/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-netlink.init $(1)/etc/init.d/qca-nss-netlink +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-cfi \ + -I$(STAGING_DIR)/usr/include/qca-nss-ecm \ + -I$(STAGING_DIR)/usr/include/qca-ssdk \ + -I$(STAGING_DIR)/usr/include/qca-ssdk/fal \ + -I$(STAGING_DIR)/usr/include/nat46 + +# Build individual packages if selected +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tun6rd),) +NSS_CLIENTS_MAKE_OPTS+=tun6rd=m +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-dtlsmgr),) +NSS_CLIENTS_MAKE_OPTS+=dtlsmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tlsmgr),) +EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports +NSS_CLIENTS_MAKE_OPTS+=tlsmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-l2tpv2),) +NSS_CLIENTS_MAKE_OPTS+=l2tpv2=y +EXTRA_CFLAGS += -DNSS_L2TPV2_ENABLED +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-gre),) +EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports +NSS_CLIENTS_MAKE_OPTS+=gre=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pppoe),) +NSS_CLIENTS_MAKE_OPTS+=pppoe=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-bridge-mgr),) +NSS_CLIENTS_MAKE_OPTS+=bridge-mgr=y +#enable OVS bridge if ovsmgr is enabled +ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),) +NSS_CLIENTS_MAKE_OPTS+= NSS_BRIDGE_MGR_OVS_ENABLE=y +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr +endif +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ipsecmgr),) +EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports \ + -I$(STAGING_DIR)/usr/include/qca-nss-ecm +NSS_CLIENTS_MAKE_OPTS+=ipsecmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr),) +NSS_CLIENTS_MAKE_OPTS+=vlan-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-lag-mgr),) +NSS_CLIENTS_MAKE_OPTS+=lag-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pvxlanmgr),) +# The memset() call in nss_pvxlanmgr_get_tunnel_stats +# triggers a compilation error with GCC 13, most likely +# it is a false positive, disable the warning for now. +EXTRA_CFLAGS+= -Wno-stringop-overread +NSS_CLIENTS_MAKE_OPTS+=pvxlanmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-clmapmgr),) +NSS_CLIENTS_MAKE_OPTS+=clmapmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-eogremgr),) +NSS_CLIENTS_MAKE_OPTS+=eogremgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr),) +NSS_CLIENTS_MAKE_OPTS+=vlan-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vxlanmgr),) +NSS_CLIENTS_MAKE_OPTS+=vxlanmgr=y +EXTRA_CFLAGS += -DNSS_VXLAN_ENABLED +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pptp),) +NSS_CLIENTS_MAKE_OPTS+=pptp=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-map-t),) +NSS_CLIENTS_MAKE_OPTS+=map-t=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-mgr),) +NSS_CLIENTS_MAKE_OPTS+=ovpn-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-link),) +NSS_CLIENTS_MAKE_OPTS+=ovpn-link=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tunipip6),) +NSS_CLIENTS_MAKE_OPTS+=tunipip6=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-igs),) +NSS_CLIENTS_MAKE_OPTS+=igs=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-netlink),) +NSS_CLIENTS_MAKE_OPTS+=netlink=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-qdisc),) +NSS_CLIENTS_MAKE_OPTS+=qdisc=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-match),) +NSS_CLIENTS_MAKE_OPTS+=match=y +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(NSS_CLIENTS_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + DTLSMGR_DIR="$(DTLSMGR_DIR)" \ + IPSECMGR_DIR="$(IPSECMGR_DIR)" \ + SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv-gre)) +$(eval $(call KernelPackage,qca-nss-drv-l2tpv2)) +$(eval $(call KernelPackage,qca-nss-drv-pptp)) +$(eval $(call KernelPackage,qca-nss-drv-pppoe)) +$(eval $(call KernelPackage,qca-nss-drv-ipsecmgr)) +$(eval $(call KernelPackage,qca-nss-drv-bridge-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-clmapmgr)) +$(eval $(call KernelPackage,qca-nss-drv-eogremgr)) +$(eval $(call KernelPackage,qca-nss-drv-lag-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-vlan-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-vxlanmgr)) +$(eval $(call KernelPackage,qca-nss-drv-pvxlanmgr)) +$(eval $(call KernelPackage,qca-nss-drv-ovpn-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-ovpn-link)) +$(eval $(call KernelPackage,qca-nss-drv-dtlsmgr)) +$(eval $(call KernelPackage,qca-nss-drv-tlsmgr)) +$(eval $(call KernelPackage,qca-nss-drv-match)) +$(eval $(call KernelPackage,qca-nss-drv-map-t)) +$(eval $(call KernelPackage,qca-nss-drv-tunipip6)) +$(eval $(call KernelPackage,qca-nss-drv-tun6rd)) +$(eval $(call KernelPackage,qca-nss-drv-qdisc)) +$(eval $(call KernelPackage,qca-nss-drv-igs)) +$(eval $(call KernelPackage,qca-nss-drv-netlink)) diff --git a/package/qca/qca-nss-clients/files/qca-nss-ipsec b/package/qca/qca-nss-clients/files/qca-nss-ipsec new file mode 100755 index 000000000..21eea7c4c --- /dev/null +++ b/package/qca/qca-nss-clients/files/qca-nss-ipsec @@ -0,0 +1,231 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +NSS_IPSEC_LOG_FILE=/tmp/.nss_ipsec_log +NSS_IPSEC_LOG_STR_ECM="ECM_Loaded" +NSS_IPSEC_OL_FILE=/tmp/qca_nss_ipsec_ol + +ecm_load () { + if [ ! -d /sys/module/ecm ]; then + /etc/init.d/qca-nss-ecm start + if [ -d /sys/module/ecm ]; then + echo ${NSS_IPSEC_LOG_STR_ECM} >> ${NSS_IPSEC_LOG_FILE} + fi + fi +} + +ecm_unload () { + if [ -f /tmp/.nss_ipsec_log ]; then + str=`grep ${NSS_IPSEC_LOG_STR_ECM} ${NSS_IPSEC_LOG_FILE}` + if [[ $str == ${NSS_IPSEC_LOG_STR_ECM} ]]; then + /etc/init.d/qca-nss-ecm stop + `sed 's/${NSS_IPSEC_LOG_STR_ECM}/ /g' $NSS_IPSEC_LOG_FILE > $NSS_IPSEC_LOG_FILE` + fi + fi +} + +ecm_disable() { + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +kernel_version_check_5_4() { + major_ver=$(uname -r | awk -F '.' '{print $1}') + minor_ver=$(uname -r | awk -F '.' '{print $2}') + if [ $major_ver -lt 5 ] || ([ $major_ver -eq 5 ] && [ $minor_ver -lt 4 ] ); then + return 1 + else + return 0 + fi +} + +kernel_version_check_5_15() { + major_ver=$(uname -r | awk -F '.' '{print $1}') + minor_ver=$(uname -r | awk -F '.' '{print $2}') + if [ $major_ver -lt 5 ] || ([ $major_ver -eq 5 ] && [ $minor_ver -lt 15 ] ); then + return 1 + else + return 0 + fi +} + +start_klips() { + if kernel_version_check_5_4; then + echo "Kernel 5.4 doesn't support klips stack." + return $? + fi + + if kernel_version_check_5_15; then + echo "Kernel 5.15 doesn't support klips stack." + return $? + fi + + touch $NSS_IPSEC_OL_FILE + ecm_load + + local kernel_version=$(uname -r) + + insmod /lib/modules/${kernel_version}/qca-nss-ipsec-klips.ko + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + rm $NSS_IPSEC_OL_FILE + return + fi + + /etc/init.d/ipsec start + sleep 2 + ipsec eroute + + ecm_enable +} + +stop_klips() { + if kernel_version_check_5_4; then + echo "Kernel 5.4 doesn't support klips stack." + return $? + fi + + if kernel_version_check_5_15; then + echo "Kernel 5.15 doesn't support klips stack." + return $? + fi + + ecm_disable + + /etc/init.d/ipsec stop + rmmod qca-nss-ipsec-klips + rm $NSS_IPSEC_OL_FILE + + ecm_unload +} + +start_xfrm() { + touch $NSS_IPSEC_OL_FILE + ecm_load + + local kernel_version=$(uname -r) + + # load all NETKEY modules first. + for mod in xfrm_ipcomp ipcomp xfrm6_tunnel ipcomp6 xfrm6_mode_tunnel xfrm6_mode_beet xfrm6_mode_ro \ + xfrm6_mode_transport xfrm4_mode_transport xfrm4_mode_tunnel \ + xfrm4_tunnel xfrm4_mode_beet esp4 esp6 ah4 ah6 af_key + do + insmod $mod 2> /dev/null + done + + # Now load the xfrm plugin + insmod /lib/modules/${kernel_version}/qca-nss-ipsec-xfrm.ko + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + rm $NSS_IPSEC_OL_FILE + return + fi + + /etc/init.d/ipsec start + sleep 2 + + ecm_enable +} + +stop_xfrm() { + ecm_disable + + #Shutdown Pluto first. Then only plugin can be removed. + plutopid=/var/run/pluto/pluto.pid + if [ -f $plutopid ]; then + pid=`cat $plutopid` + if [ ! -z "$pid" ]; then + ipsec whack --shutdown | grep -v "002"; + if [ -s $plutopid ]; then + echo "Attempt to shut Pluto down failed! Trying kill:" + kill $pid; + sleep 5; + fi + fi + rm -rf $plutopid + fi + ip xfrm state flush; + ip xfrm policy flush; + sleep 2 + + #Now we can remove the plugin + retries=5 + while [ -d /sys/module/qca_nss_ipsec_xfrm ] + do + rmmod qca-nss-ipsec-xfrm + if [ "$?" -eq 0 ]; then + rm $NSS_IPSEC_OL_FILE + break + fi + + if [ ${retries} -eq 0 ]; then + echo "Failed to unload qca-nss-ipsec-xfrm plugin!" + exit + fi + + echo "XFRM plugin unload failed; retrying ${retries} times" + sleep 1 + retries=`expr ${retries} - 1` + done + + /etc/init.d/ipsec stop + ecm_unload +} + +start() { + local protostack=`uci -q get ipsec.setup.protostack` + if [ "$protostack" = "klips" ]; then + start_klips + return $? + fi + + start_xfrm + return $? +} + +stop() { + local protostack=`uci -q get ipsec.setup.protostack` + if [ "$protostack" = "klips" ]; then + stop_klips + return $? + fi + + stop_xfrm + return $? +} + +restart() { + stop + start +} diff --git a/package/qca/qca-nss-clients/files/qca-nss-mirred.init b/package/qca/qca-nss-clients/files/qca-nss-mirred.init new file mode 100644 index 000000000..259aaa090 --- /dev/null +++ b/package/qca/qca-nss-clients/files/qca-nss-mirred.init @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +start() { + insmod act_nssmirred.ko +} + +stop() { + rmmod act_nssmirred.ko +} + +restart() { + stop + start +} diff --git a/package/qca/qca-nss-clients/files/qca-nss-netlink.init b/package/qca/qca-nss-clients/files/qca-nss-netlink.init new file mode 100644 index 000000000..8d38ad33f --- /dev/null +++ b/package/qca/qca-nss-clients/files/qca-nss-netlink.init @@ -0,0 +1,31 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2023, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +start() { + modprobe qca-nss-netlink + + echo 2048 > /proc/sys/dev/nss/n2hcfg/n2h_queue_limit_core0 + echo 2048 > /proc/sys/dev/nss/n2hcfg/n2h_queue_limit_core1 +} + +stop() { + rmmod qca-nss-netlink.ko +} + +restart() { + stop + start +} diff --git a/package/qca/qca-nss-clients/files/qca-nss-ovpn.init b/package/qca/qca-nss-clients/files/qca-nss-ovpn.init new file mode 100644 index 000000000..622e295ee --- /dev/null +++ b/package/qca/qca-nss-clients/files/qca-nss-ovpn.init @@ -0,0 +1,69 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +ecm_disable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +restart() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + insmod qca-nss-ovpn-mgr + insmod qca-nss-ovpn-link + + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + return + fi + + ecm_enable +} + +start() { + restart +} + +stop() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + ecm_enable +} diff --git a/package/qca/qca-nss-clients/patches/0001-kernel-5.15-support-qdisc.patch b/package/qca/qca-nss-clients/patches/0001-kernel-5.15-support-qdisc.patch new file mode 100644 index 000000000..97479d9b9 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0001-kernel-5.15-support-qdisc.patch @@ -0,0 +1,162 @@ +--- a/nss_qdisc/igs/nss_mirred.c ++++ b/nss_qdisc/igs/nss_mirred.c +@@ -82,20 +82,24 @@ static const struct nla_policy nss_mirre + * nss_mirred_init() + * Initialize the nss mirred action. + */ +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) + static int nss_mirred_init(struct net *net, struct nlattr *nla, +- struct nlattr *est, struct tc_action *tc_act, int ovr, +- int bind) ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) ++ struct nlattr *est, struct tc_action *tc_act, int ovr, ++ int bind) ++{ ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) ++ struct nlattr *est, struct tc_action **tc_act, int ovr, ++ int bind, bool rtnl_held, struct tcf_proto *tp, ++ u32 flags, struct netlink_ext_ack *extack) + { + #else +-static int nss_mirred_init(struct net *net, struct nlattr *nla, +- struct nlattr *est, struct tc_action **tc_act, int ovr, +- int bind, bool rtnl_held, struct tcf_proto *tp, +- struct netlink_ext_ack *extack) ++ struct nlattr *est, struct tc_action **tc_act, ++ struct tcf_proto *tp, u32 flags, struct netlink_ext_ack *extack) + { ++ bool bind = flags & TCA_ACT_FLAGS_BIND; ++#endif + struct tc_action_net *tn = net_generic(net, nss_mirred_net_id); + u32 index; +-#endif + struct nlattr *arr[TC_NSS_MIRRED_MAX + 1]; + struct tc_nss_mirred *parm; + struct nss_mirred_tcf *act; +@@ -239,8 +243,13 @@ static int nss_mirred_init(struct net *n + } + + if (!ret) { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) + ret = tcf_idr_create(tn, index, est, tc_act, &nss_mirred_act_ops, + bind, true); ++#else ++ ret = tcf_idr_create(tn, index, est, tc_act, &nss_mirred_act_ops, ++ bind, true, 0); ++#endif + if (ret) { + tcf_idr_cleanup(tn, index); + return ret; +--- a/nss_qdisc/nss_bf.c ++++ b/nss_qdisc/nss_bf.c +@@ -74,7 +74,7 @@ static inline struct nss_bf_class_data * + */ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) + static int nss_bf_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct netlink_ext_ack *extack = NULL; + #else +@@ -290,7 +290,11 @@ static void nss_bf_destroy_class(struct + * nss_bf_delete_class() + * Detaches a class from operation, but does not destroy it. + */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) ++static int nss_bf_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack) ++#else + static int nss_bf_delete_class(struct Qdisc *sch, unsigned long arg) ++#endif + { + struct nss_bf_sched_data *q = qdisc_priv(sch); + struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg; +--- a/nss_qdisc/nss_htb.c ++++ b/nss_qdisc/nss_htb.c +@@ -282,7 +282,7 @@ static int nss_htb_ppe_change_class(stru + */ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) + static int nss_htb_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct netlink_ext_ack *extack = NULL; + #else +@@ -516,7 +516,11 @@ static void nss_htb_destroy_class(struct + * nss_htb_delete_class() + * Detaches a class from operation, but does not destroy it. + */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) ++static int nss_htb_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack) ++#else + static int nss_htb_delete_class(struct Qdisc *sch, unsigned long arg) ++#endif + { + struct nss_htb_sched_data *q = qdisc_priv(sch); + struct nss_htb_class_data *cl = (struct nss_htb_class_data *)arg; +--- a/nss_qdisc/nss_qdisc.c ++++ b/nss_qdisc/nss_qdisc.c +@@ -1140,15 +1140,16 @@ unsigned int nss_qdisc_drop(struct Qdisc + { + struct nss_qdisc *nq = qdisc_priv(sch); + unsigned int ret; ++ struct sk_buff *to_free = qdisc_peek_head(sch); + + if (!nq->is_virtual) { +- ret = __qdisc_queue_drop_head(sch, &sch->q); ++ ret = __qdisc_queue_drop_head(sch, &sch->q, &to_free); + } else { + spin_lock_bh(&nq->bounce_protection_lock); + /* + * This function is safe to call within locks + */ +- ret = __qdisc_queue_drop_head(sch, &sch->q); ++ ret = __qdisc_queue_drop_head(sch, &sch->q, &to_free); + spin_unlock_bh(&nq->bounce_protection_lock); + } + +@@ -1209,10 +1210,10 @@ static bool nss_qdisc_iterate_fl(struct + return 0; + } + +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +- status = tc_classify(skb, tcf, &res, false); +-#else ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + status = tcf_classify(skb, tcf, &res, false); ++#else ++ status = tcf_classify(skb, NULL, tcf, &res, false); + #endif + if ((status == TC_ACT_STOLEN) || (status == TC_ACT_QUEUED)) { + return 1; +@@ -2188,6 +2189,8 @@ int __nss_qdisc_init(struct Qdisc *sch, + * This is to prevent mixing NSS and PPE qdisc with linux qdisc. + */ + if ((parent != TC_H_ROOT) && (root->ops->owner != THIS_MODULE)) { ++ nss_qdisc_warning("parent (%d) and TC_H_ROOT (%d))", parent, TC_H_ROOT); ++ nss_qdisc_warning("root->ops->owner (%px) and THIS_MODULE (%px))", root->ops->owner , THIS_MODULE); + nss_qdisc_warning("NSS qdisc %px (type %d) used along with non-nss qdiscs," + " or the interface is currently down", nq->qdisc, nq->type); + } +--- a/nss_qdisc/nss_wrr.c ++++ b/nss_qdisc/nss_wrr.c +@@ -229,7 +229,7 @@ static int nss_wrr_ppe_change_class(stru + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) + static int nss_wrr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct netlink_ext_ack *extack = NULL; + #else +@@ -400,7 +400,11 @@ failure: + return -EINVAL; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) ++static int nss_wrr_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack) ++#else + static int nss_wrr_delete_class(struct Qdisc *sch, unsigned long arg) ++#endif + { + struct nss_wrr_sched_data *q = qdisc_priv(sch); + struct nss_wrr_class_data *cl = (struct nss_wrr_class_data *)arg; diff --git a/package/qca/qca-nss-clients/patches/0002-kernel-5.4-support-gre.patch b/package/qca/qca-nss-clients/patches/0002-kernel-5.4-support-gre.patch new file mode 100644 index 000000000..7ed66bd45 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0002-kernel-5.4-support-gre.patch @@ -0,0 +1,31 @@ +--- a/gre/nss_connmgr_gre_v6.c ++++ b/gre/nss_connmgr_gre_v6.c +@@ -95,7 +95,8 @@ static int nss_connmgr_gre_v6_get_mac_ad + /* + * Find src MAC address + */ +- local_dev = (struct net_device *)ipv6_dev_find(&init_net, &src_addr, 1); ++ local_dev = NULL; ++ local_dev = (struct net_device *)ipv6_dev_find(&init_net, &src_addr, local_dev); + if (!local_dev) { + nss_connmgr_gre_warning("Unable to find local dev for %pI6", src_ip); + return GRE_ERR_NO_LOCAL_NETDEV; +--- a/gre/test/nss_connmgr_gre_test.c ++++ b/gre/test/nss_connmgr_gre_test.c +@@ -229,10 +229,12 @@ static int nss_connmgr_gre_test_open_pro + /* + * Proc ops + */ +-static const struct file_operations nss_connmgr_gre_test_proc_ops = { +- .open = nss_connmgr_gre_test_open_proc, +- .write = nss_connmgr_gre_test_write_proc, +- .read = seq_read, ++static const struct proc_ops nss_connmgr_gre_test_proc_ops = { ++ .proc_open = nss_connmgr_gre_test_open_proc, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = nss_connmgr_gre_test_write_proc, + }; + + /* diff --git a/package/qca/qca-nss-clients/patches/0003-kernel-5.4-support-ipsec.patch b/package/qca/qca-nss-clients/patches/0003-kernel-5.4-support-ipsec.patch new file mode 100644 index 000000000..de43b4d01 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0003-kernel-5.4-support-ipsec.patch @@ -0,0 +1,29 @@ +--- a/ipsecmgr/v1.0/nss_ipsecmgr.c ++++ b/ipsecmgr/v1.0/nss_ipsecmgr.c +@@ -377,7 +377,7 @@ free: + * nss_ipsecmgr_tunnel_stats() + * get tunnel statistics + */ +-static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) ++void nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + { + struct nss_ipsecmgr_priv *priv = netdev_priv(dev); + +@@ -389,8 +389,6 @@ static struct rtnl_link_stats64 *nss_ips + read_lock_bh(&ipsecmgr_ctx->lock); + memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64)); + read_unlock_bh(&ipsecmgr_ctx->lock); +- +- return stats; + } + + /* +@@ -442,7 +440,7 @@ static void nss_ipsecmgr_tunnel_setup(st + dev->header_ops = NULL; + dev->netdev_ops = &nss_ipsecmgr_tunnel_ops; + +- dev->destructor = nss_ipsecmgr_tunnel_free; ++ dev->priv_destructor = nss_ipsecmgr_tunnel_free; + + /* + * get the MAC address from the ethernet device diff --git a/package/qca/qca-nss-clients/patches/0004-kernel-5.4-support-dtls.patch b/package/qca/qca-nss-clients/patches/0004-kernel-5.4-support-dtls.patch new file mode 100644 index 000000000..ae9c91470 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0004-kernel-5.4-support-dtls.patch @@ -0,0 +1,11 @@ +--- a/dtls/v1.0/nss_connmgr_dtls_netdev.c ++++ b/dtls/v1.0/nss_connmgr_dtls_netdev.c +@@ -160,7 +160,7 @@ static void nss_dtlsmgr_dev_setup(struct + dev->ethtool_ops = NULL; + dev->header_ops = NULL; + dev->netdev_ops = &nss_dtlsmgr_session_ops; +- dev->destructor = NULL; ++ dev->priv_destructor = NULL; + + memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len); + memset(dev->broadcast, 0xff, dev->addr_len); diff --git a/package/qca/qca-nss-clients/patches/0005-vlanmgr-fix-compile-error.patch b/package/qca/qca-nss-clients/patches/0005-vlanmgr-fix-compile-error.patch new file mode 100644 index 000000000..13fb7673b --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0005-vlanmgr-fix-compile-error.patch @@ -0,0 +1,59 @@ +--- a/vlan/nss_vlan_mgr.c ++++ b/vlan/nss_vlan_mgr.c +@@ -800,8 +800,10 @@ static struct nss_vlan_pvt *nss_vlan_mgr + */ + static void nss_vlan_mgr_instance_free(struct nss_vlan_pvt *v) + { ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + int32_t i; + int ret = 0; ++#endif + + spin_lock(&vlan_mgr_ctx.lock); + BUG_ON(--v->refs); +@@ -961,8 +963,11 @@ static int nss_vlan_mgr_register_event(s + int ret; + #endif + uint32_t vlan_tag; ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *slave; +- int32_t port, port_if; ++ int32_t port; ++#endif ++ int32_t port_if; + struct vlan_dev_priv *vlan; + struct net_device *real_dev; + bool is_bond_master = false; +@@ -1355,8 +1360,10 @@ return_with_error: + int nss_vlan_mgr_join_bridge(struct net_device *dev, uint32_t bridge_vsi) + { + struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev); ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *real_dev; + int ret; ++#endif + + if (!v) + return 0; +@@ -1416,8 +1423,10 @@ EXPORT_SYMBOL(nss_vlan_mgr_join_bridge); + int nss_vlan_mgr_leave_bridge(struct net_device *dev, uint32_t bridge_vsi) + { + struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev); ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *real_dev; + int ret; ++#endif + + if (!v) + return 0; +--- a/vlan/Makefile ++++ b/vlan/Makefile +@@ -8,7 +8,7 @@ ifeq ($(SoC),$(filter $(SoC),ipq807x ipq + ccflags-y += -DNSS_VLAN_MGR_PPE_SUPPORT + endif + +-ccflags-y += -DNSS_VLAN_MGR_DEBUG_LEVEL=0 ++ccflags-y += -DNSS_VLAN_MGR_DEBUG_LEVEL=4 + ccflags-y += -Wall -Werror + + ifneq (,$(filter $(CONFIG_BONDING),y m)) diff --git a/package/qca/qca-nss-clients/patches/0006-match-fix-compile-error.patch b/package/qca/qca-nss-clients/patches/0006-match-fix-compile-error.patch new file mode 100644 index 000000000..ad3ad0b91 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0006-match-fix-compile-error.patch @@ -0,0 +1,25 @@ +--- a/match/nss_match_priv.h ++++ b/match/nss_match_priv.h +@@ -29,19 +29,19 @@ + /* + * Statically compile messages at different levels + */ +-#if (NSS_match_DEBUG_LEVEL < 2) ++#if (NSS_MATCH_DEBUG_LEVEL < 2) + #define nss_match_warn(s, ...) + #else + #define nss_match_warn(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) + #endif + +-#if (NSS_match_DEBUG_LEVEL < 3) ++#if (NSS_MATCH_DEBUG_LEVEL < 3) + #define nss_match_info(s, ...) + #else + #define nss_match_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) + #endif + +-#if (NSS_match_DEBUG_LEVEL < 4) ++#if (NSS_MATCH_DEBUG_LEVEL < 4) + #define nss_match_trace(s, ...) + #else + #define nss_match_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) diff --git a/package/qca/qca-nss-clients/patches/0007-bridge-fix-compile-error.patch b/package/qca/qca-nss-clients/patches/0007-bridge-fix-compile-error.patch new file mode 100644 index 000000000..539ff6874 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0007-bridge-fix-compile-error.patch @@ -0,0 +1,29 @@ +--- a/bridge/nss_bridge_mgr.c ++++ b/bridge/nss_bridge_mgr.c +@@ -1098,8 +1098,10 @@ int nss_bridge_mgr_register_br(struct ne + */ + b_pvt->ifnum = ifnum; + b_pvt->mtu = dev->mtu; ++#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT) + b_pvt->wan_if_num = -1; + b_pvt->wan_if_enabled = false; ++#endif + ether_addr_copy(b_pvt->dev_addr, dev->dev_addr); + spin_lock(&br_mgr_ctx.lock); + list_add(&b_pvt->list, &br_mgr_ctx.list); +@@ -1165,6 +1167,7 @@ static int nss_bridge_mgr_bond_slave_cha + return NOTIFY_DONE; + } + ++#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT) + /* + * Add or remove the slave based based on linking event + */ +@@ -1179,6 +1182,7 @@ static int nss_bridge_mgr_bond_slave_cha + cu_info->upper_dev->name, master->name); + } + } ++#endif + + return NOTIFY_DONE; + } diff --git a/package/qca/qca-nss-clients/patches/0008-profiler-fix-compile-error.patch b/package/qca/qca-nss-clients/patches/0008-profiler-fix-compile-error.patch new file mode 100644 index 000000000..8b6d92c05 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0008-profiler-fix-compile-error.patch @@ -0,0 +1,61 @@ +--- a/profiler/profile.c ++++ b/profiler/profile.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -937,12 +938,26 @@ static ssize_t debug_if(struct file *fil + return count; + } + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) ++#define HAVE_PROC_OPS ++#endif ++ ++#ifdef HAVE_PROC_OPS ++static const struct proc_ops profile_fops = { ++ .proc_open = profile_open, ++ .proc_read = profile_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = profile_release, ++ .proc_write = debug_if, ++}; ++#else + static const struct file_operations profile_fops = { + .open = profile_open, + .read = profile_read, + .release = profile_release, + .write = debug_if, + }; ++#endif + + /* + * showing sample status on Linux console +@@ -971,6 +986,15 @@ static ssize_t profile_rate_write(struct + return 0; + } + ++#ifdef HAVE_PROC_OPS ++static const struct proc_ops profile_rate_fops = { ++ .proc_open = profile_rate_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = profile_rate_write, ++}; ++#else + static const struct file_operations profile_rate_fops = { + .open = profile_rate_open, + .read = seq_read, +@@ -978,6 +1002,7 @@ static const struct file_operations prof + .release = single_release, + .write = profile_rate_write, + }; ++#endif + + /* + * hexdump diff --git a/package/qca/qca-nss-clients/patches/0009-gre-fix-compile-error.patch b/package/qca/qca-nss-clients/patches/0009-gre-fix-compile-error.patch new file mode 100644 index 000000000..e833327ed --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0009-gre-fix-compile-error.patch @@ -0,0 +1,17 @@ +--- a/gre/nss_connmgr_gre_v4.c ++++ b/gre/nss_connmgr_gre_v4.c +@@ -172,14 +172,6 @@ int nss_connmgr_gre_v4_set_config(struct + } + } + +- /* +- * IP address validate +- */ +- if ((cfg->src_ip == 0) || (cfg->dest_ip == 0)) { +- nss_connmgr_gre_warning("Source ip/Destination IP is invalid"); +- return GRE_ERR_INVALID_IP; +- } +- + memset(t, 0, sizeof(struct ip_tunnel)); + + priv->pad_len = (cfg->add_padding) ? GRE_HDR_PAD_LEN : 0; diff --git a/package/qca/qca-nss-clients/patches/0010-fix-portifmgr.patch b/package/qca/qca-nss-clients/patches/0010-fix-portifmgr.patch new file mode 100644 index 000000000..343f17b84 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0010-fix-portifmgr.patch @@ -0,0 +1,35 @@ +--- a/portifmgr/nss_portifmgr.c ++++ b/portifmgr/nss_portifmgr.c +@@ -187,16 +187,20 @@ drop: + } + + /* +- * nss_portifmgr_get_stats() ++ * nss_portifmgr_get_stats64() + * Netdev get stats function to get port stats + */ +-static struct rtnl_link_stats64 *nss_portifmgr_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) ++/* ++ * nss_nlgre_redir_cmn_dev_stats64 ++ * Report packet statistics to linux ++ */ ++static void nss_portifmgr_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *stats) + { + struct nss_portifmgr_priv *priv = (struct nss_portifmgr_priv *)netdev_priv(dev); + BUG_ON(priv == NULL); + + nss_portid_get_stats(priv->if_num, stats); +- return stats; + } + + /* +@@ -225,7 +229,7 @@ static const struct net_device_ops nss_p + .ndo_start_xmit = nss_portifmgr_start_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = nss_portifmgr_change_mtu, +- .ndo_get_stats64 = nss_portifmgr_get_stats, ++ .ndo_get_stats64 = nss_portifmgr_get_stats64, + }; + + /* diff --git a/package/qca/qca-nss-clients/patches/0011-dtlsmgr-fix-SHA-header-include-in-5.15.patch b/package/qca/qca-nss-clients/patches/0011-dtlsmgr-fix-SHA-header-include-in-5.15.patch new file mode 100644 index 000000000..a095a5370 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0011-dtlsmgr-fix-SHA-header-include-in-5.15.patch @@ -0,0 +1,48 @@ +--- a/dtls/v2.0/nss_dtlsmgr.c ++++ b/dtls/v2.0/nss_dtlsmgr.c +@@ -38,7 +38,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + +--- a/dtls/v2.0/nss_dtlsmgr_ctx.c ++++ b/dtls/v2.0/nss_dtlsmgr_ctx.c +@@ -40,7 +40,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + +--- a/dtls/v2.0/nss_dtlsmgr_ctx_dev.c ++++ b/dtls/v2.0/nss_dtlsmgr_ctx_dev.c +@@ -36,7 +36,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + + #include + #include diff --git a/package/qca/qca-nss-clients/patches/0012-dtlsmgr-fix-debug-print-in-5.15.patch b/package/qca/qca-nss-clients/patches/0012-dtlsmgr-fix-debug-print-in-5.15.patch new file mode 100644 index 000000000..89936dbdc --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0012-dtlsmgr-fix-debug-print-in-5.15.patch @@ -0,0 +1,36 @@ +--- a/dtls/v2.0/nss_dtlsmgr_private.h ++++ b/dtls/v2.0/nss_dtlsmgr_private.h +@@ -36,9 +36,9 @@ + /* + * Compile messages for dynamic enable/disable + */ +-#define nss_dtlsmgr_warn(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) +-#define nss_dtlsmgr_info(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) +-#define nss_dtlsmgr_trace(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) ++#define nss_dtlsmgr_warn(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); ++#define nss_dtlsmgr_info(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); ++#define nss_dtlsmgr_trace(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); + #else + + /* +@@ -46,17 +46,17 @@ + */ + #define nss_dtlsmgr_warn(s, ...) { \ + if (NSS_DTLSMGR_DEBUG_LEVEL > NSS_DTLSMGR_DEBUG_LEVEL_ERROR) \ +- pr_warn("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) \ ++ pr_warn("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); \ + } + + #define nss_dtlsmgr_info(s, ...) { \ + if (NSS_DTLSMGR_DEBUG_LEVEL > NSS_DTLSMGR_DEBUG_LEVEL_WARN) \ +- pr_notice("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) \ ++ pr_notice("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); \ + } + + #define nss_dtlsmgr_trace(s, ...) { \ + if (NSS_DTLSMGR_DEBUG_LEVEL > NSS_DTLSMGR_DEBUG_LEVEL_INFO) \ +- pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) \ ++ pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); \ + } + + #endif /* CONFIG_DYNAMIC_DEBUG */ diff --git a/package/qca/qca-nss-clients/patches/0013-tlsmgr-fix-SHA-header-include-in-5.15.patch b/package/qca/qca-nss-clients/patches/0013-tlsmgr-fix-SHA-header-include-in-5.15.patch new file mode 100644 index 000000000..f3cee731d --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0013-tlsmgr-fix-SHA-header-include-in-5.15.patch @@ -0,0 +1,32 @@ +--- a/tls/nss_tlsmgr_crypto.c ++++ b/tls/nss_tlsmgr_crypto.c +@@ -41,7 +41,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/tls/nss_tlsmgr_tun.c ++++ b/tls/nss_tlsmgr_tun.c +@@ -35,7 +35,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + + #include + #include diff --git a/package/qca/qca-nss-clients/patches/0014-ovpnmgr-fix-SHA-header-include-in-5.15.patch b/package/qca/qca-nss-clients/patches/0014-ovpnmgr-fix-SHA-header-include-in-5.15.patch new file mode 100644 index 000000000..0b8cd17eb --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0014-ovpnmgr-fix-SHA-header-include-in-5.15.patch @@ -0,0 +1,32 @@ +--- a/openvpn/src/nss_ovpnmgr_crypto.c ++++ b/openvpn/src/nss_ovpnmgr_crypto.c +@@ -28,7 +28,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + + #include +--- a/openvpn/src/nss_ovpnmgr_route.c ++++ b/openvpn/src/nss_ovpnmgr_route.c +@@ -34,7 +34,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + + #include diff --git a/package/qca/qca-nss-clients/patches/0015-tunipip6-fix-compile-error-in-5.15.patch b/package/qca/qca-nss-clients/patches/0015-tunipip6-fix-compile-error-in-5.15.patch new file mode 100644 index 000000000..b9d6c2e22 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0015-tunipip6-fix-compile-error-in-5.15.patch @@ -0,0 +1,11 @@ +--- a/tunipip6/nss_connmgr_tunipip6.c ++++ b/tunipip6/nss_connmgr_tunipip6.c +@@ -258,7 +258,7 @@ static void nss_tunipip6_decap_exception + struct iphdr *iph; + struct rtable *rt; + int cpu; +- int8_t ver = skb->data[0] >> 4; ++ __attribute__((unused)) int8_t ver = skb->data[0] >> 4; + + nss_tunipip6_trace("%px: received - %d bytes name %s ver %x\n", + dev, skb->len, dev->name, ver); diff --git a/package/qca/qca-nss-clients/patches/0016-vxlanmgr-fix-compile-error-in-5.15.patch b/package/qca/qca-nss-clients/patches/0016-vxlanmgr-fix-compile-error-in-5.15.patch new file mode 100644 index 000000000..80173f88a --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0016-vxlanmgr-fix-compile-error-in-5.15.patch @@ -0,0 +1,11 @@ +--- a/vxlanmgr/nss_vxlanmgr.c ++++ b/vxlanmgr/nss_vxlanmgr.c +@@ -84,7 +84,7 @@ int32_t nss_vxlanmgr_bind_ipsec_by_ip(un + { + int32_t ipsec_if_num; + nss_vxlanmgr_get_ipsec_if_num_by_ip_callback_t ipsec_cb; +- struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx(); ++ __attribute__((unused)) struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx(); + + /* + * Check if the VxLAN interface is applied over an IPsec interface by querying the IPsec. diff --git a/package/qca/qca-nss-clients/patches/0017-tlsmgr-fix-debug-print-in-5.15.patch b/package/qca/qca-nss-clients/patches/0017-tlsmgr-fix-debug-print-in-5.15.patch new file mode 100644 index 000000000..4fbdecb49 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0017-tlsmgr-fix-debug-print-in-5.15.patch @@ -0,0 +1,34 @@ +--- a/tls/nss_tlsmgr_priv.h ++++ b/tls/nss_tlsmgr_priv.h +@@ -28,7 +28,7 @@ + #define NSS_TLSMGR_DEBUG_LEVEL_INFO 3 + #define NSS_TLSMGR_DEBUG_LEVEL_TRACE 4 + +-#define nss_tlsmgr_info_always(s, ...) pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) ++#define nss_tlsmgr_info_always(s, ...) pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); + + #define nss_tlsmgr_error(s, ...) do { \ + if (net_ratelimit()) { \ +@@ -43,18 +43,18 @@ + } while (0) + + #if defined(CONFIG_DYNAMIC_DEBUG) +-#define nss_tlsmgr_info(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) +-#define nss_tlsmgr_trace(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) ++#define nss_tlsmgr_info(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); ++#define nss_tlsmgr_trace(s, ...) pr_debug("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); + #else + + #define nss_tlsmgr_info(s, ...) { \ + if (NSS_TLSMGR_DEBUG_LEVEL > NSS_TLSMGR_DEBUG_LEVEL_WARN) \ +- pr_notice("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) \ ++ pr_notice("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); \ + } + + #define nss_tlsmgr_trace(s, ...) { \ + if (NSS_TLSMGR_DEBUG_LEVEL > NSS_TLSMGR_DEBUG_LEVEL_INFO) \ +- pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__) \ ++ pr_info("%s[%d]:" s "\n", __func__, __LINE__, ##__VA_ARGS__); \ + } + + #endif /* CONFIG_DYNAMIC_DEBUG */ diff --git a/package/qca/qca-nss-clients/patches/0018-kernel-6.1-support.patch b/package/qca/qca-nss-clients/patches/0018-kernel-6.1-support.patch new file mode 100644 index 000000000..7606a1535 --- /dev/null +++ b/package/qca/qca-nss-clients/patches/0018-kernel-6.1-support.patch @@ -0,0 +1,301 @@ +--- a/bridge/nss_bridge_mgr.c ++++ b/bridge/nss_bridge_mgr.c +@@ -1081,7 +1081,7 @@ int nss_bridge_mgr_register_br(struct ne + } + #endif + +- err = nss_bridge_tx_set_mac_addr_msg(ifnum, dev->dev_addr); ++ err = nss_bridge_tx_set_mac_addr_msg(ifnum, (uint8_t *) dev->dev_addr); + if (err != NSS_TX_SUCCESS) { + nss_bridge_mgr_warn("%px: failed to set mac_addr msg, error = %d\n", b_pvt, err); + goto fail_4; +@@ -1242,7 +1242,7 @@ static int nss_bridge_mgr_changeaddr_eve + + nss_bridge_mgr_trace("%px: MAC changed to %pM, update NSS\n", b_pvt, dev->dev_addr); + +- if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, dev->dev_addr) != NSS_TX_SUCCESS) { ++ if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, (uint8_t *) dev->dev_addr) != NSS_TX_SUCCESS) { + nss_bridge_mgr_warn("%px: Failed to send change MAC address message to NSS\n", b_pvt); + return NOTIFY_DONE; + } +--- a/dtls/v2.0/nss_dtlsmgr_ctx_dev.c ++++ b/dtls/v2.0/nss_dtlsmgr_ctx_dev.c +@@ -532,7 +532,7 @@ void nss_dtlsmgr_ctx_dev_setup(struct ne + #else + dev->priv_destructor = nss_dtlsmgr_ctx_dev_free; + #endif +- memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len); ++ memcpy((void *) dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len); + memset(dev->broadcast, 0xff, dev->addr_len); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); + } +--- a/gre/test/nss_connmgr_gre_test.c ++++ b/gre/test/nss_connmgr_gre_test.c +@@ -223,7 +223,7 @@ static int nss_connmgr_gre_test_show_pro + */ + static int nss_connmgr_gre_test_open_proc(struct inode *inode, struct file *filp) + { +- return single_open(filp, nss_connmgr_gre_test_show_proc, PDE_DATA(inode)); ++ return single_open(filp, nss_connmgr_gre_test_show_proc, pde_data(inode)); + } + + /* +--- a/gre/nss_connmgr_gre.c ++++ b/gre/nss_connmgr_gre.c +@@ -279,10 +279,10 @@ static struct rtnl_link_stats64 *nss_con + #else + start = u64_stats_fetch_begin_irq(&tstats->syncp); + #endif +- rx_packets = tstats->rx_packets; +- tx_packets = tstats->tx_packets; +- rx_bytes = tstats->rx_bytes; +- tx_bytes = tstats->tx_bytes; ++ rx_packets = u64_stats_read(&tstats->rx_packets); ++ tx_packets = u64_stats_read(&tstats->tx_packets); ++ rx_bytes = u64_stats_read(&tstats->rx_bytes); ++ tx_bytes = u64_stats_read(&tstats->tx_bytes); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)) + } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); + #else +@@ -697,11 +697,11 @@ static void nss_connmgr_gre_event_receiv + tstats = this_cpu_ptr(dev->tstats); + u64_stats_update_begin(&tstats->syncp); + if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER) { +- tstats->tx_packets += stats->tx_packets; +- tstats->tx_bytes += stats->tx_bytes; ++ u64_stats_add(&tstats->tx_packets, stats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, stats->tx_bytes); + } else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER) { +- tstats->rx_packets += stats->rx_packets; +- tstats->rx_bytes += stats->rx_bytes; ++ u64_stats_add(&tstats->rx_packets, stats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, stats->rx_bytes); + } + u64_stats_update_end(&tstats->syncp); + dev->stats.rx_dropped += nss_cmn_rx_dropped_sum(stats); +--- a/tunipip6/nss_connmgr_tunipip6.c ++++ b/tunipip6/nss_connmgr_tunipip6.c +@@ -354,11 +354,11 @@ static void nss_tunipip6_update_dev_stat + + memset(&stats, 0, sizeof(stats)); + if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER) { +- stats.tx_packets = sync_stats->node_stats.tx_packets; +- stats.tx_bytes = sync_stats->node_stats.tx_bytes; ++ u64_stats_set(&stats.tx_packets, sync_stats->node_stats.tx_packets); ++ u64_stats_set(&stats.tx_bytes, sync_stats->node_stats.tx_bytes); + } else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER) { +- stats.rx_packets = sync_stats->node_stats.rx_packets; +- stats.rx_bytes = sync_stats->node_stats.rx_bytes; ++ u64_stats_set(&stats.rx_packets, sync_stats->node_stats.rx_packets); ++ u64_stats_set(&stats.rx_bytes, sync_stats->node_stats.rx_bytes); + } else { + nss_tunipip6_warning("%px: Invalid interface type received from NSS\n", dev); + return; +--- a/nss_qdisc/igs/nss_mirred.c ++++ b/nss_qdisc/igs/nss_mirred.c +@@ -317,7 +317,7 @@ static int nss_mirred_act(struct sk_buff + * Update the last use of action. + */ + tcf_lastuse_update(&act->tcf_tm); +- bstats_cpu_update(this_cpu_ptr(act->common.cpu_bstats), skb); ++ bstats_update(this_cpu_ptr(act->common.cpu_bstats), skb); + + rcu_read_lock(); + retval = READ_ONCE(act->tcf_action); +--- a/nss_qdisc/nss_qdisc.h ++++ b/nss_qdisc/nss_qdisc.h +@@ -217,7 +217,7 @@ struct nss_qdisc { + /* Shaper configure callback for reading shaper specific + * responses (e.g. memory size). + */ +- struct gnet_stats_basic_packed bstats; /* Basic class statistics */ ++ struct gnet_stats_basic_sync bstats; /* Basic class statistics */ + struct gnet_stats_queue qstats; /* Qstats for use by classes */ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) + atomic_t refcnt; /* Reference count for class use */ +@@ -464,7 +464,7 @@ extern int nss_qdisc_init(struct Qdisc * + * Wrapper around gnet_stats_copy_basic() + */ + extern int nss_qdisc_gnet_stats_copy_basic(struct Qdisc *sch, +- struct gnet_dump *d, struct gnet_stats_basic_packed *b); ++ struct gnet_dump *d, struct gnet_stats_basic_sync *b); + + /* + * nss_qdisc_gnet_stats_copy_queue() +--- a/nss_qdisc/igs/nss_ifb.c ++++ b/nss_qdisc/igs/nss_ifb.c +@@ -544,8 +544,10 @@ static void nss_ifb_update_dev_stats(str + * post shaping. Therefore IFB interface's stats should be updated + * with NSS firmware's IFB TX stats only. + */ +- stats.rx_packets = stats.tx_packets = node_stats->tx_packets; +- stats.rx_bytes = stats.tx_bytes = node_stats->tx_bytes; ++ u64_stats_set(&stats.rx_packets, node_stats->tx_packets); ++ u64_stats_set(&stats.tx_packets, node_stats->tx_packets); ++ u64_stats_set(&stats.rx_bytes, node_stats->tx_bytes); ++ u64_stats_set(&stats.tx_bytes, node_stats->tx_bytes); + dev->stats.rx_dropped = dev->stats.tx_dropped += sync_stats->igs_stats.tx_dropped; + u64_stats_update_end(&stats.syncp); + +--- a/nss_qdisc/nss_qdisc.c ++++ b/nss_qdisc/nss_qdisc.c +@@ -2608,12 +2608,14 @@ int nss_qdisc_init(struct Qdisc *sch, st + * Wrapper around gnet_stats_copy_basic() + */ + int nss_qdisc_gnet_stats_copy_basic(struct Qdisc *sch, struct gnet_dump *d, +- struct gnet_stats_basic_packed *b) ++ struct gnet_stats_basic_sync *b) + { + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 18, 0)) + return gnet_stats_copy_basic(d, b); + #elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)) + return gnet_stats_copy_basic(d, NULL, b); ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) ++ return gnet_stats_copy_basic(d, NULL, b, true); + #else + return gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d, NULL, b); + #endif +--- a/nss_qdisc/nss_qdisc_stats.c ++++ b/nss_qdisc/nss_qdisc_stats.c +@@ -160,7 +160,7 @@ static void nss_qdisc_stats_process_node + { + struct Qdisc *qdisc; + struct nss_qdisc *nq; +- struct gnet_stats_basic_packed *bstats; ++ struct gnet_stats_basic_sync *bstats; + struct gnet_stats_queue *qstats; + uint32_t qos_tag = response->qos_tag; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)) +@@ -214,8 +214,8 @@ static void nss_qdisc_stats_process_node + * Update qdisc->bstats + */ + spin_lock_bh(&nq->lock); +- bstats->bytes += (__u64)response->sn_stats.delta.dequeued_bytes; +- bstats->packets += response->sn_stats.delta.dequeued_packets; ++ u64_stats_add(&bstats->bytes, (__u64)response->sn_stats.delta.dequeued_bytes); ++ u64_stats_add(&bstats->packets, response->sn_stats.delta.dequeued_packets); + + /* + * Update qdisc->qstats +--- a/vlan/nss_vlan_mgr.c ++++ b/vlan/nss_vlan_mgr.c +@@ -787,7 +787,7 @@ static struct nss_vlan_pvt *nss_vlan_mgr + } + + v->mtu = dev->mtu; +- ether_addr_copy(v->dev_addr, dev->dev_addr); ++ ether_addr_copy(v->dev_addr, (uint8_t *) dev->dev_addr); + v->ifindex = dev->ifindex; + v->refs = 1; + +@@ -936,14 +936,14 @@ static int nss_vlan_mgr_changeaddr_event + } + spin_unlock(&vlan_mgr_ctx.lock); + +- if (nss_vlan_tx_set_mac_addr_msg(v_pvt->nss_if, dev->dev_addr) != NSS_TX_SUCCESS) { ++ if (nss_vlan_tx_set_mac_addr_msg(v_pvt->nss_if, (uint8_t *) dev->dev_addr) != NSS_TX_SUCCESS) { + nss_vlan_mgr_warn("%s: Failed to send change MAC address message to NSS\n", dev->name); + nss_vlan_mgr_instance_deref(v_pvt); + return NOTIFY_BAD; + } + + spin_lock(&vlan_mgr_ctx.lock); +- ether_addr_copy(v_pvt->dev_addr, dev->dev_addr); ++ ether_addr_copy(v_pvt->dev_addr, (uint8_t *) dev->dev_addr); + spin_unlock(&vlan_mgr_ctx.lock); + nss_vlan_mgr_trace("%s: MAC changed to %pM, updated NSS\n", dev->name, dev->dev_addr); + nss_vlan_mgr_instance_deref(v_pvt); +--- a/vxlanmgr/nss_vxlanmgr_tunnel.c ++++ b/vxlanmgr/nss_vxlanmgr_tunnel.c +@@ -489,8 +489,8 @@ static void nss_vxlanmgr_tunnel_inner_st + + tstats = this_cpu_ptr(dev->tstats); + u64_stats_update_begin(&tstats->syncp); +- tstats->tx_packets += stats->node_stats.tx_packets; +- tstats->tx_bytes += stats->node_stats.tx_bytes; ++ u64_stats_add(&tstats->tx_packets, stats->node_stats.tx_packets); ++ u64_stats_add(&tstats->tx_bytes, stats->node_stats.tx_bytes); + u64_stats_update_end(&tstats->syncp); + netdev_stats->tx_dropped += dropped; + } +@@ -526,8 +526,8 @@ static void nss_vxlanmgr_tunnel_outer_st + + tstats = this_cpu_ptr(dev->tstats); + u64_stats_update_begin(&tstats->syncp); +- tstats->rx_packets += stats->node_stats.tx_packets; +- tstats->rx_bytes += stats->node_stats.tx_bytes; ++ u64_stats_add(&tstats->rx_packets, stats->node_stats.tx_packets); ++ u64_stats_add(&tstats->rx_bytes, stats->node_stats.tx_bytes); + u64_stats_update_end(&tstats->syncp); + netdev_stats->rx_dropped += dropped; + dev_put(dev); +--- a/pvxlanmgr/nss_pvxlanmgr.c ++++ b/pvxlanmgr/nss_pvxlanmgr.c +@@ -177,7 +177,7 @@ static struct rtnl_link_stats64 *nss_pvx + * Netdev seems to be incrementing rx_dropped because we don't give IP header. + * So reset it as it's of no use for us. + */ +- atomic_long_set(&dev->rx_dropped, 0); ++ atomic_long_set(&(dev)->stats.__rx_dropped, 0); + priv = netdev_priv(dev); + memset(stats, 0, sizeof(struct rtnl_link_stats64)); + memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64)); +@@ -305,7 +305,7 @@ static void nss_pvxlanmgr_dummy_netdev_s + dev->priv_destructor = NULL; + #endif + +- memcpy(dev->dev_addr, "\x00\x00\x00\x00\x00\x00", dev->addr_len); ++ memcpy((void *) dev->dev_addr, "\x00\x00\x00\x00\x00\x00", dev->addr_len); + memset(dev->broadcast, 0xff, dev->addr_len); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); + } +--- a/clmapmgr/nss_clmapmgr.c ++++ b/clmapmgr/nss_clmapmgr.c +@@ -103,7 +103,7 @@ static struct rtnl_link_stats64 *nss_clm + * Netdev seems to be incrementing rx_dropped because we don't give IP header. + * So reset it as it's of no use for us. + */ +- atomic_long_set(&dev->rx_dropped, 0); ++ atomic_long_set(&(dev)->stats.__rx_dropped, 0); + priv = netdev_priv(dev); + memset(stats, 0, sizeof(struct rtnl_link_stats64)); + memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64)); +--- a/tls/nss_tlsmgr_tun.c ++++ b/tls/nss_tlsmgr_tun.c +@@ -185,7 +185,7 @@ static void nss_tlsmgr_tun_setup(struct + /* + * Get the MAC address from the ethernet device + */ +- random_ether_addr(dev->dev_addr); ++ eth_random_addr((u8 *) dev->dev_addr); + + memset(dev->broadcast, 0xff, dev->addr_len); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); +--- a/netlink/nss_nlgre_redir_cmn.c ++++ b/netlink/nss_nlgre_redir_cmn.c +@@ -384,7 +384,7 @@ static int nss_nlgre_redir_cmn_set_mac_a + return -EINVAL; + } + +- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); ++ memcpy((void *) dev->dev_addr, addr->sa_data, ETH_ALEN); + return 0; + } + +--- a/nss_connmgr_tun6rd.c ++++ b/nss_connmgr_tun6rd.c +@@ -101,10 +101,10 @@ static void nss_tun6rd_update_dev_stats( + + u64_stats_init(&stats.syncp); + u64_stats_update_begin(&stats.syncp); +- stats.rx_packets = sync_stats->node_stats.rx_packets; +- stats.rx_bytes = sync_stats->node_stats.rx_bytes; +- stats.tx_packets = sync_stats->node_stats.tx_packets; +- stats.tx_bytes = sync_stats->node_stats.tx_bytes; ++ u64_stats_set(&stats.rx_packets, sync_stats->node_stats.rx_packets); ++ u64_stats_set(&stats.rx_bytes, sync_stats->node_stats.rx_bytes); ++ u64_stats_set(&stats.tx_packets, sync_stats->node_stats.tx_packets); ++ u64_stats_set(&stats.tx_bytes, sync_stats->node_stats.tx_bytes); + u64_stats_update_end(&stats.syncp); + #else + struct nss_tun6rd_stats stats; diff --git a/package/qca/qca-nss-crypto/Makefile b/package/qca/qca-nss-crypto/Makefile new file mode 100644 index 000000000..c0d2dc4bb --- /dev/null +++ b/package/qca/qca-nss-crypto/Makefile @@ -0,0 +1,68 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-crypto +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-12-15 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-crypto.git +PKG_SOURCE_VERSION:=3c5a574ce99d7f0b9f892002020f1bf9bfc57a81 +PKG_MIRROR_HASH:=ff487c5574481f548eef7b61129fa7be1d83ae285dcc3356a06be237440d8782 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +# v1.0 is for Akronite +# v2.0 is for Hawkeye/Cypress/Maple +ifneq (, $(findstring $(CONFIG_TARGET_SUBTARGET), "ipq807x" "ipq60xx")) +NSS_CRYPTO_DIR:=v2.0 +else +NSS_CRYPTO_DIR:=v1.0 +endif + +define KernelPackage/qca-nss-crypto + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Cryptographic API modules + DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-drv + TITLE:=Kernel driver for NSS crypto driver + FILES:=$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src/qca-nss-crypto.ko \ + $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/tool/qca-nss-crypto-tool.ko + AUTOLOAD:=$(call AutoProbe,qca-nss-crypto) +endef + +define KernelPackage/qca-nss-crypto/Description +This package contains a NSS crypto driver for QCA chipset +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-crypto + $(CP) $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include/* $(1)/usr/include/qca-nss-crypto +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src + +ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") + SOC:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" \ + CC="$(TARGET_CC)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + NSS_CRYPTO_DIR=$(NSS_CRYPTO_DIR) \ + SoC=$(SOC) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-crypto)) diff --git a/package/qca/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch b/package/qca/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch new file mode 100644 index 000000000..c9849a2e8 --- /dev/null +++ b/package/qca/qca-nss-crypto/patches/0001-nss-crypto-fix-SHA1-header-include.patch @@ -0,0 +1,27 @@ +From 0c6c593783f2d64a429ad38523661a915aa462fc Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 13 Mar 2022 13:44:47 +0100 +Subject: [PATCH 1/3] nss-crypto: fix SHA1 header include + +SHA1 header has been merged to the generic SHA one, +and with that the cryptohash.h was dropped. + +So, fix include in kernels 5.8 and newer. + +Signed-off-by: Robert Marko +--- + v2.0/src/nss_crypto_hlos.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/v2.0/src/nss_crypto_hlos.h ++++ b/v2.0/src/nss_crypto_hlos.h +@@ -55,7 +55,9 @@ + #include + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) + #include ++#endif + #include + #include + #include diff --git a/package/qca/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch b/package/qca/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch new file mode 100644 index 000000000..19454c457 --- /dev/null +++ b/package/qca/qca-nss-crypto/patches/0002-nss-crypto-replace-ioremap_nocache-with-ioremap.patch @@ -0,0 +1,94 @@ +From 8baa8e747247403c6f814ea5dc3e463c70e0415f Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 8 Jun 2021 22:14:34 +0200 +Subject: [PATCH 2/3] nss-crypto: replace ioremap_nocache() with ioremap + +ioremap_nocache() was dropped in kernel 5.5 as regular +ioremap() was exactly the same. + +So, simply replace all of the ioremap_nocache() calls +with ioremap(). + +Signed-off-by: Robert Marko +--- + v1.0/src/nss_crypto_dtsi.c | 4 ++-- + v1.0/src/nss_crypto_platform.c | 4 ++-- + v2.0/src/hal/ipq50xx/nss_crypto_ce5.c | 4 ++-- + v2.0/src/hal/ipq60xx/nss_crypto_eip197.c | 2 +- + v2.0/src/hal/ipq807x/nss_crypto_eip197.c | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +--- a/v1.0/src/nss_crypto_dtsi.c ++++ b/v1.0/src/nss_crypto_dtsi.c +@@ -311,11 +311,11 @@ static int nss_crypto_probe(struct platf + e_ctrl->dev = &pdev->dev; + + e_ctrl->cmd_base = crypto_res.start; +- e_ctrl->crypto_base = ioremap_nocache(e_ctrl->cmd_base, resource_size(&crypto_res)); ++ e_ctrl->crypto_base = ioremap(e_ctrl->cmd_base, resource_size(&crypto_res)); + nss_crypto_assert(e_ctrl->crypto_base); + + e_ctrl->bam_pbase = bam_res.start; +- e_ctrl->bam_base = ioremap_nocache(e_ctrl->bam_pbase, resource_size(&bam_res)); ++ e_ctrl->bam_base = ioremap(e_ctrl->bam_pbase, resource_size(&bam_res)); + nss_crypto_assert(e_ctrl->bam_base); + + e_ctrl->bam_ee = bam_ee; +--- a/v1.0/src/nss_crypto_platform.c ++++ b/v1.0/src/nss_crypto_platform.c +@@ -134,11 +134,11 @@ static int nss_crypto_probe(struct platf + e_ctrl->bam_ee = res->bam_ee; + + e_ctrl->cmd_base = res->crypto_pbase; +- e_ctrl->crypto_base = ioremap_nocache(res->crypto_pbase, res->crypto_pbase_sz); ++ e_ctrl->crypto_base = ioremap(res->crypto_pbase, res->crypto_pbase_sz); + nss_crypto_assert(e_ctrl->crypto_base); + + e_ctrl->bam_pbase = res->bam_pbase; +- e_ctrl->bam_base = ioremap_nocache(res->bam_pbase, res->bam_pbase_sz); ++ e_ctrl->bam_base = ioremap(res->bam_pbase, res->bam_pbase_sz); + nss_crypto_assert(e_ctrl->bam_base); + + /* +--- a/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c ++++ b/v2.0/src/hal/ipq50xx/nss_crypto_ce5.c +@@ -288,7 +288,7 @@ int nss_crypto_ce5_engine_init(struct pl + * remap the I/O addresses for crypto + */ + eng->crypto_paddr = crypto_res->start; +- eng->crypto_vaddr = ioremap_nocache(crypto_res->start, resource_size(crypto_res)); ++ eng->crypto_vaddr = ioremap(crypto_res->start, resource_size(crypto_res)); + if (!eng->crypto_vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)eng->crypto_paddr); + nss_crypto_engine_free(eng); +@@ -299,7 +299,7 @@ int nss_crypto_ce5_engine_init(struct pl + * remap the I/O addresses for bam + */ + eng->dma_paddr = bam_res->start; +- eng->dma_vaddr = ioremap_nocache(bam_res->start, resource_size(bam_res)); ++ eng->dma_vaddr = ioremap(bam_res->start, resource_size(bam_res)); + if (!eng->dma_vaddr) { + iounmap(eng->crypto_vaddr); + nss_crypto_warn("%px: unable to remap dma_addr(0x%px)\n", node, (void *)eng->dma_paddr); +--- a/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c ++++ b/v2.0/src/hal/ipq60xx/nss_crypto_eip197.c +@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct + * remap the I/O addresses + */ + paddr = res->start + offset; +- vaddr = ioremap_nocache(paddr, resource_size(res)); ++ vaddr = ioremap(paddr, resource_size(res)); + if (!vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); + return -EIO; +--- a/v2.0/src/hal/ipq807x/nss_crypto_eip197.c ++++ b/v2.0/src/hal/ipq807x/nss_crypto_eip197.c +@@ -490,7 +490,7 @@ int nss_crypto_eip197_engine_init(struct + * remap the I/O addresses + */ + paddr = res->start + offset; +- vaddr = ioremap_nocache(paddr, resource_size(res)); ++ vaddr = ioremap(paddr, resource_size(res)); + if (!vaddr) { + nss_crypto_warn("%px: unable to remap crypto_addr(0x%px)\n", node, (void *)paddr); + return -EIO; diff --git a/package/qca/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch b/package/qca/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch new file mode 100644 index 000000000..61df791fd --- /dev/null +++ b/package/qca/qca-nss-crypto/patches/0003-nss-crypto-fix-SHA-header-include-in-5.15.patch @@ -0,0 +1,44 @@ +From 96da3ca01ac172e5d858209b3d3d9aefad04423c Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 13 Mar 2022 13:47:24 +0100 +Subject: [PATCH 3/3] nss-crypto: fix SHA header include in 5.15 + +SHA header was split into SHA-1 and SHA-2 headers in kernel 5.11, so +fix the include for newer kernels. + +Signed-off-by: Robert Marko +--- + v2.0/src/nss_crypto_ctrl.c | 6 ++++++ + v2.0/src/nss_crypto_hlos.h | 4 ++++ + 2 files changed, 10 insertions(+) + +--- a/v2.0/src/nss_crypto_ctrl.c ++++ b/v2.0/src/nss_crypto_ctrl.c +@@ -38,7 +38,13 @@ + #include + #include + #include ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#include ++#endif + #include + #include + #include +--- a/v2.0/src/nss_crypto_hlos.h ++++ b/v2.0/src/nss_crypto_hlos.h +@@ -58,7 +58,11 @@ + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) + #include + #endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + #include ++#else ++#include ++#endif + #include + #include + #include diff --git a/package/qca/qca-nss-drv/Config.in b/package/qca/qca-nss-drv/Config.in new file mode 100644 index 000000000..c1bd4760a --- /dev/null +++ b/package/qca/qca-nss-drv/Config.in @@ -0,0 +1,184 @@ +menu "Configuration" + depends on PACKAGE_kmod-qca-nss-drv + +comment "Build Options" + +config NSS_DRV_BRIDGE_ENABLE + bool + default n + prompt "Enable BRIDGE" +config NSS_DRV_C2C_ENABLE + bool + default n + prompt "Enable C2C" +config NSS_DRV_CLMAP_ENABLE + bool + default n + prompt "Enable CLMAP" +config NSS_DRV_CRYPTO_ENABLE + bool + default y + prompt "Enable CRYPTO" +config NSS_DRV_DTLS_ENABLE + bool + default n + prompt "Enable DTLS" +config NSS_DRV_EDMA_ENABLE + bool + default n + prompt "Enable EDMA" +config NSS_DRV_GRE_ENABLE + bool + default n + prompt "Enable GRE" +config NSS_DRV_GRE_REDIR_ENABLE + bool + default n + depends on NSS_DRV_GRE_ENABLE + prompt "Enable GRE_REDIR" +config NSS_DRV_GRE_TUNNEL_ENABLE + bool + default n + depends on NSS_DRV_GRE_ENABLE + prompt "Enable GRE_TUNNEL" +config NSS_DRV_IGS_ENABLE + bool + default n + prompt "Enable IGS" +config NSS_DRV_IPSEC_ENABLE + bool + default n + prompt "Enable IPSEC" +config NSS_DRV_IPV4_REASM_ENABLE + bool + default n + prompt "Enable IPV4_REASM" +config NSS_DRV_IPV6_ENABLE + bool + default n + prompt "Enable IPV6" +config NSS_DRV_IPV6_REASM_ENABLE + bool + default n + depends on NSS_DRV_IPV6_ENABLE + prompt "Enable IPV6_REASM" +config NSS_DRV_L2TP_ENABLE + bool + default n + prompt "Enable L2TP" +config NSS_DRV_LAG_ENABLE + bool + default n + prompt "Enable LAG" +config NSS_DRV_MAPT_ENABLE + bool + default n + prompt "Enable MAPT" +config NSS_DRV_MATCH_ENABLE + bool + default n + prompt "Enable MATCH" +config NSS_DRV_MIRROR_ENABLE + bool + default n + prompt "Enable MIRROR" +config NSS_DRV_OAM_ENABLE + bool + default n + prompt "Enable OAM" +config NSS_DRV_PORTID_ENABLE + bool + default n + prompt "Enable PORTID" +config NSS_DRV_PPE_ENABLE + bool + default n + prompt "Enable PPE" +config NSS_DRV_PPPOE_ENABLE + bool + default n + prompt "Enable PPPOE" +config NSS_DRV_PPTP_ENABLE + bool + default y + prompt "Enable PPTP" +config NSS_DRV_PVXLAN_ENABLE + bool + default n + prompt "Enable PVXLAN" +config NSS_DRV_QRFS_ENABLE + bool + default n + prompt "Enable QRFS" +config NSS_DRV_QVPN_ENABLE + bool + default n + prompt "Enable QVPN" +config NSS_DRV_OVPN_ENABLE + bool + default n + prompt "Enable OVPN" +config NSS_DRV_RMNET_ENABLE + bool + default n + prompt "Enable RMNET" +config NSS_DRV_SHAPER_ENABLE + bool + default n + prompt "Enable SHAPER" +config NSS_DRV_SJACK_ENABLE + bool + default n + prompt "Enable SJACK" +config NSS_DRV_TLS_ENABLE + bool + default n + prompt "Enable TLS" +config NSS_DRV_TRUSTSEC_ENABLE + bool + default n + prompt "Enable TRUSTSEC" +config NSS_DRV_TRUSTSEC_RX_ENABLE + bool + default n + prompt "Enable TRUSTSEC_RX" + depends on NSS_DRV_TRUSTSEC_ENABLE +config NSS_DRV_TSTAMP_ENABLE + bool + default n + prompt "Enable TSTAMP" +config NSS_DRV_TUN6RD_ENABLE + bool + default n + prompt "Enable TUN6RD" +config NSS_DRV_TUNIPIP6_ENABLE + bool + default n + prompt "Enable TUNIPIP6" +config NSS_DRV_VIRT_IF_ENABLE + bool + default y + prompt "Enable VIRT_IF" +config NSS_DRV_VLAN_ENABLE + bool + default n + prompt "Enable VLAN" +config NSS_DRV_VXLAN_ENABLE + bool + default n + prompt "Enable VXLAN" +config NSS_DRV_WIFI_ENABLE + bool + default n + prompt "Enable WIFI" +config NSS_DRV_WIFI_EXT_VDEV_ENABLE + bool + default n + depends on NSS_DRV_WIFI_ENABLE + prompt "Enable WIFI EXT VDEV" +config NSS_DRV_WIFI_MESH_ENABLE + bool + default n + depends on NSS_DRV_WIFI_ENABLE + prompt "Enable WIFI MESH" +endmenu diff --git a/package/qca/qca-nss-drv/Makefile b/package/qca/qca-nss-drv/Makefile new file mode 100644 index 000000000..f7ef833f9 --- /dev/null +++ b/package/qca/qca-nss-drv/Makefile @@ -0,0 +1,275 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-drv +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-08-06 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-drv.git +PKG_SOURCE_VERSION:=1ab184034529539f61093184a67d4454cb3eb352 +PKG_MIRROR_HASH:=6aa081c0853d3e3b6d78eee588a0967e540b2317d15aef3c3f6f7129925653f7 + +PKG_BUILD_PARALLEL:=1 +PKG_FLAGS:=nonshared + +PKG_CONFIG_DEPENDS:= \ + CONFIG_NSS_DRV_BRIDGE_ENABLE \ + CONFIG_NSS_DRV_C2C_ENABLE \ + CONFIG_NSS_DRV_CLMAP_ENABLE \ + CONFIG_NSS_DRV_CRYPTO_ENABLE \ + CONFIG_NSS_DRV_DMA_ENABLE \ + CONFIG_NSS_DRV_DTLS_ENABLE \ + CONFIG_NSS_DRV_EDMA_ENABLE \ + CONFIG_NSS_DRV_GRE_ENABLE \ + CONFIG_NSS_DRV_GRE_REDIR_ENABLE \ + CONFIG_NSS_DRV_GRE_TUNNEL_ENABLE \ + CONFIG_NSS_DRV_IGS_ENABLE \ + CONFIG_NSS_DRV_IPSEC_ENABLE \ + CONFIG_NSS_DRV_IPV4_REASM_ENABLE \ + CONFIG_NSS_DRV_IPV6_ENABLE \ + CONFIG_NSS_DRV_IPV6_REASM_ENABLE \ + CONFIG_NSS_DRV_L2TP_ENABLE \ + CONFIG_NSS_DRV_LAG_ENABLE \ + CONFIG_NSS_DRV_MAPT_ENABLE \ + CONFIG_NSS_DRV_MATCH_ENABLE \ + CONFIG_NSS_DRV_MIRROR_ENABLE \ + CONFIG_NSS_DRV_OAM_ENABLE \ + CONFIG_NSS_DRV_PORTID_ENABLE \ + CONFIG_NSS_DRV_PPE_ENABLE \ + CONFIG_NSS_DRV_PPPOE_ENABLE \ + CONFIG_NSS_DRV_PPTP_ENABLE \ + CONFIG_NSS_DRV_PVXLAN_ENABLE \ + CONFIG_NSS_DRV_QRFS_ENABLE \ + CONFIG_NSS_DRV_QVPN_ENABLE \ + CONFIG_NSS_DRV_OVPN_ENABLE \ + CONFIG_NSS_DRV_RMNET_ENABLE \ + CONFIG_NSS_DRV_SHAPER_ENABLE \ + CONFIG_NSS_DRV_SJACK_ENABLE \ + CONFIG_NSS_DRV_TLS_ENABLE \ + CONFIG_NSS_DRV_TRUSTSEC_ENABLE \ + CONFIG_NSS_DRV_TRUSTSEC_RX_ENABLE \ + CONFIG_NSS_DRV_TSTAMP_ENABLE \ + CONFIG_NSS_DRV_TUN6RD_ENABLE \ + CONFIG_NSS_DRV_TUNIPIP6_ENABLE \ + CONFIG_NSS_DRV_VIRT_IF_ENABLE \ + CONFIG_NSS_DRV_VLAN_ENABLE \ + CONFIG_NSS_DRV_VXLAN_ENABLE \ + CONFIG_NSS_DRV_WIFI_ENABLE \ + CONFIG_NSS_DRV_WIFI_EXT_VDEV_ENABLE \ + CONFIG_NSS_DRV_WIFI_MESH_ENABLE + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +NSS_CLIENTS_DIR:=$(TOPDIR)/qca/src/qca-nss-clients + +define KernelPackage/qca-nss-drv + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_qualcommax +kmod-qca-nss-dp + TITLE:=Qualcomm NSS core driver + FILES:=$(PKG_BUILD_DIR)/qca-nss-drv.ko + AUTOLOAD:=$(call AutoLoad,32,qca-nss-drv) +endef + +define KernelPackage/qca-nss-drv/config + source "$(SOURCE)/Config.in" +endef + +define KernelPackage/qca-nss-drv/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/hotplug.d/firmware + $(INSTALL_DIR) $(1)/lib/debug + + $(INSTALL_BIN) ./files/qca-nss-drv.init $(1)/etc/init.d/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.sysctl $(1)/etc/sysctl.d/qca-nss-drv.conf + $(INSTALL_BIN) ./files/qca-nss-drv.conf $(1)/etc/config/nss + $(INSTALL_BIN) ./files/qca-nss-drv.hotplug $(1)/etc/hotplug.d/firmware/10-qca-nss-fw + $(INSTALL_BIN) ./files/qca-nss-drv.debug $(1)/lib/debug/qca-nss-drv +endef + +define KernelPackage/qca-nss-drv/Description +This package contains a NSS driver for QCA chipset +endef + +ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") + SOC="ipq807x_64" + subtarget:=$(CONFIG_TARGET_SUBTARGET) +else ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") + SOC="ipq60xx_64" + subtarget:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-drv + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-drv/ +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq60xx")) + $(RM) $(1)/usr/include/qca-nss-drv/nss_ipsecmgr.h + # $(INSTALL_DIR) $(1)/usr/include/qca-nss-clients + # $(CP) $(NSS_CLIENTS_DIR)/exports/nss_ipsecmgr.h $(1)/usr/include/qca-nss-clients/. +endif +endef + +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-gmac \ + -I$(STAGING_DIR)/usr/include/qca-nss-dp \ + -I$(STAGING_DIR)/usr/include/qca-ssdk \ + -Wno-unused-variable \ + -Wno-error=unused-function + +ifeq ($(BOARD),qualcommax) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_MEDIUM +endif + +DRV_MAKE_OPTS:= +ifndef CONFIG_NSS_DRV_BRIDGE_ENABLE + DRV_MAKE_OPTS += NSS_DRV_BRIDGE_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_C2C_ENABLE + DRV_MAKE_OPTS += NSS_DRV_C2C_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_CLMAP_ENABLE + DRV_MAKE_OPTS += NSS_DRV_CLMAP_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_CRYPTO_ENABLE + DRV_MAKE_OPTS += NSS_DRV_CRYPTO_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_DMA_ENABLE + DRV_MAKE_OPTS += NSS_DRV_DMA_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_DTLS_ENABLE + DRV_MAKE_OPTS += NSS_DRV_DTLS_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_EDMA_ENABLE + DRV_MAKE_OPTS += NSS_DRV_EDMA_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_GRE_ENABLE + DRV_MAKE_OPTS += NSS_DRV_GRE_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_GRE_REDIR_ENABLE + DRV_MAKE_OPTS += NSS_DRV_GRE_REDIR_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_GRE_TUNNEL_ENABLE + DRV_MAKE_OPTS += NSS_DRV_GRE_TUNNEL_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_IGS_ENABLE + DRV_MAKE_OPTS += NSS_DRV_IGS_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_IPSEC_ENABLE + DRV_MAKE_OPTS += NSS_DRV_IPSEC_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_IPV4_REASM_ENABLE + DRV_MAKE_OPTS += NSS_DRV_IPV4_REASM_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_IPV6_ENABLE + DRV_MAKE_OPTS += NSS_DRV_IPV6_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_IPV6_REASM_ENABLE + DRV_MAKE_OPTS += NSS_DRV_IPV6_REASM_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_L2TP_ENABLE + DRV_MAKE_OPTS += NSS_DRV_L2TP_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_LAG_ENABLE + DRV_MAKE_OPTS += NSS_DRV_LAG_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_MAPT_ENABLE + DRV_MAKE_OPTS += NSS_DRV_MAPT_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_MATCH_ENABLE + DRV_MAKE_OPTS += NSS_DRV_MATCH_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_MIRROR_ENABLE + DRV_MAKE_OPTS += NSS_DRV_MIRROR_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_OAM_ENABLE + DRV_MAKE_OPTS += NSS_DRV_OAM_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_PORTID_ENABLE + DRV_MAKE_OPTS += NSS_DRV_PORTID_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_PPE_ENABLE + DRV_MAKE_OPTS += NSS_DRV_PPE_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_PPPOE_ENABLE + DRV_MAKE_OPTS += NSS_DRV_PPPOE_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_PPTP_ENABLE + DRV_MAKE_OPTS += NSS_DRV_PPTP_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_PVXLAN_ENABLE + DRV_MAKE_OPTS += NSS_DRV_PVXLAN_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_QRFS_ENABLE + DRV_MAKE_OPTS += NSS_DRV_QRFS_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_QVPN_ENABLE + DRV_MAKE_OPTS += NSS_DRV_QVPN_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_OVPN_ENABLE + DRV_MAKE_OPTS += NSS_DRV_OVPN_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_RMNET_ENABLE + DRV_MAKE_OPTS += NSS_DRV_RMNET_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_SHAPER_ENABLE + DRV_MAKE_OPTS += NSS_DRV_SHAPER_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_SJACK_ENABLE + DRV_MAKE_OPTS += NSS_DRV_SJACK_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TLS_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TLS_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TRUSTSEC_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TRUSTSEC_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TRUSTSEC_RX_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TRUSTSEC_RX_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TSTAMP_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TSTAMP_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TUN6RD_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TUN6RD_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_TUNIPIP6_ENABLE + DRV_MAKE_OPTS += NSS_DRV_TUNIPIP6_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_VIRT_IF_ENABLE + DRV_MAKE_OPTS += NSS_DRV_VIRT_IF_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_VLAN_ENABLE + DRV_MAKE_OPTS += NSS_DRV_VLAN_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_VXLAN_ENABLE + DRV_MAKE_OPTS += NSS_DRV_VXLAN_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_WIFI_ENABLE + DRV_MAKE_OPTS += NSS_DRV_WIFI_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_WIFI_EXT_VDEV_ENABLE + DRV_MAKE_OPTS += NSS_DRV_WIFI_EXT_VDEV_ENABLE=n +endif +ifndef CONFIG_NSS_DRV_WIFI_MESH_ENABLE + DRV_MAKE_OPTS += NSS_DRV_WIFI_MESH_ENABLE=n +endif + +define Build/Configure + $(LN) arch/nss_$(SOC).h $(PKG_BUILD_DIR)/exports/nss_arch.h +endef + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(DRV_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SoC=$(SOC) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv)) diff --git a/package/qca/qca-nss-drv/files/qca-nss-drv.conf b/package/qca/qca-nss-drv/files/qca-nss-drv.conf new file mode 100644 index 000000000..a8a1fbf40 --- /dev/null +++ b/package/qca/qca-nss-drv/files/qca-nss-drv.conf @@ -0,0 +1,6 @@ +config nss_firmware 'qca_nss_0' + +config nss_firmware 'qca_nss_1' + +config general + option enable_rps '1' diff --git a/package/qca/qca-nss-drv/files/qca-nss-drv.debug b/package/qca/qca-nss-drv/files/qca-nss-drv.debug new file mode 100644 index 000000000..5d435c3a7 --- /dev/null +++ b/package/qca/qca-nss-drv/files/qca-nss-drv.debug @@ -0,0 +1,26 @@ +#!/bin/sh /sbin/sysdebug +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +log cat /sys/kernel/debug/qca-nss-drv/stats/pppoe +log cat /sys/kernel/debug/qca-nss-drv/stats/n2h +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv6 +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv4 +log cat /sys/kernel/debug/qca-nss-drv/stats/gmac +log cat /sys/kernel/debug/qca-nss-drv/stats/drv +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi_if +log cat /sys/kernel/debug/qca-nss-drv/stats/eth_rx diff --git a/package/qca/qca-nss-drv/files/qca-nss-drv.hotplug b/package/qca/qca-nss-drv/files/qca-nss-drv.hotplug new file mode 100644 index 000000000..1e4813838 --- /dev/null +++ b/package/qca/qca-nss-drv/files/qca-nss-drv.hotplug @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +KERNEL=`uname -r` +case "${KERNEL}" in + 3.4*) + select_or_load=load_nss_fw + ;; + *) + select_or_load=select_nss_fw + ;; +esac + +load_nss_fw () { + ls -l $1 | awk ' { print $9,$5 } '> /dev/console + echo 1 > /sys/class/firmware/$DEVICENAME/loading + cat $1 > /sys/class/firmware/$DEVICENAME/data + echo 0 > /sys/class/firmware/$DEVICENAME/loading +} + +select_nss_fw () { + rm -f /lib/firmware/$DEVICENAME + ln -s $1 /lib/firmware/$DEVICENAME + ls -l /lib/firmware/$DEVICENAME | awk ' { print $9,$5 } '> /dev/console +} + +[ "$ACTION" != "add" ] && exit + +# dev name for UCI, since it doesn't let you use . or - +SDEVNAME=$(echo ${DEVICENAME} | sed s/[.-]/_/g) + +SELECTED_FW=$(uci get nss.${SDEVNAME}.firmware 2>/dev/null) +[ -e "${SELECTED_FW}" ] && { + $select_or_load ${SELECTED_FW} + exit +} + +case $DEVICENAME in + qca-nss0* | qca-nss.0*) + if [ -e /lib/firmware/qca-nss0-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss0-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss0-retail.bin + fi + exit + ;; + qca-nss1* | qca-nss.1*) + if [ -e /lib/firmware/qca-nss1-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss1-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss1-retail.bin + fi + exit + ;; +esac + diff --git a/package/qca/qca-nss-drv/files/qca-nss-drv.init b/package/qca/qca-nss-drv/files/qca-nss-drv.init new file mode 100644 index 000000000..de12cb6d1 --- /dev/null +++ b/package/qca/qca-nss-drv/files/qca-nss-drv.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=70 + +enable_rps() { + irq_nss_rps=`grep nss_queue1 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 2 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue2 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 4 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue3 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 8 > /proc/irq/$entry/smp_affinity + done + + # Enable NSS RPS + sysctl -w dev.nss.rps.enable=1 >/dev/null 2>/dev/null + +} + + +start() { + local rps_enabled="$(uci_get nss @general[0] enable_rps)" + if [ "$rps_enabled" -eq 1 ]; then + enable_rps + fi +} diff --git a/package/qca/qca-nss-drv/files/qca-nss-drv.sysctl b/package/qca/qca-nss-drv/files/qca-nss-drv.sysctl new file mode 100644 index 000000000..0276bba12 --- /dev/null +++ b/package/qca/qca-nss-drv/files/qca-nss-drv.sysctl @@ -0,0 +1,3 @@ +# Default Number of connection configuration +dev.nss.ipv4cfg.ipv4_conn=4096 +dev.nss.ipv6cfg.ipv6_conn=4096 diff --git a/package/qca/qca-nss-drv/patches/0001-nss-drv-replace-ioremap_nocache-with-ioremap.patch b/package/qca/qca-nss-drv/patches/0001-nss-drv-replace-ioremap_nocache-with-ioremap.patch new file mode 100644 index 000000000..edbd10434 --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0001-nss-drv-replace-ioremap_nocache-with-ioremap.patch @@ -0,0 +1,207 @@ +From dddfe22459a988a5b86d195bc3cc3bd3c2ac7037 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sat, 14 Jan 2023 21:52:38 +0100 +Subject: [PATCH 1/4] nss-drv: replace ioremap_nocache() with ioremap() + +Since 5.5 ioremap_nocache is equal to ioremap on all archs and was removed +from the kernel, so just use ioremap instead. + +Signed-off-by: Robert Marko +--- + nss_hal/fsm9010/nss_hal_pvt.c | 2 +- + nss_hal/ipq50xx/nss_hal_pvt.c | 6 +++--- + nss_hal/ipq60xx/nss_hal_pvt.c | 8 ++++---- + nss_hal/ipq806x/nss_hal_pvt.c | 4 ++-- + nss_hal/ipq807x/nss_hal_pvt.c | 6 +++--- + nss_hal/ipq95xx/nss_hal_pvt.c | 6 +++--- + nss_hal/nss_hal.c | 4 ++-- + nss_meminfo.c | 2 +- + nss_ppe.c | 2 +- + 9 files changed, 20 insertions(+), 20 deletions(-) + +--- a/nss_hal/fsm9010/nss_hal_pvt.c ++++ b/nss_hal/fsm9010/nss_hal_pvt.c +@@ -145,7 +145,7 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +--- a/nss_hal/ipq50xx/nss_hal_pvt.c ++++ b/nss_hal/ipq50xx/nss_hal_pvt.c +@@ -185,13 +185,13 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -349,7 +349,7 @@ static int __nss_hal_common_reset(struct + + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq60xx/nss_hal_pvt.c ++++ b/nss_hal/ipq60xx/nss_hal_pvt.c +@@ -208,13 +208,13 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -434,13 +434,13 @@ static int __nss_hal_common_reset(struct + + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; + } + +- nss_misc_reset_flag = ioremap_nocache(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag)); ++ nss_misc_reset_flag = ioremap(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag)); + if (!nss_misc_reset_flag) { + pr_err("%px: ioremap fail for nss_misc_reset_flag\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq806x/nss_hal_pvt.c ++++ b/nss_hal/ipq806x/nss_hal_pvt.c +@@ -461,7 +461,7 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +@@ -714,7 +714,7 @@ static int __nss_hal_common_reset(struct + } + of_node_put(cmn); + +- fpb_base = ioremap_nocache(res_nss_fpb_base.start, resource_size(&res_nss_fpb_base)); ++ fpb_base = ioremap(res_nss_fpb_base.start, resource_size(&res_nss_fpb_base)); + if (!fpb_base) { + pr_err("%px: ioremap fail for nss_fpb_base\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq807x/nss_hal_pvt.c ++++ b/nss_hal/ipq807x/nss_hal_pvt.c +@@ -237,7 +237,7 @@ static struct nss_platform_data *__nss_h + npd->vphys = res_vphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +@@ -250,7 +250,7 @@ static struct nss_platform_data *__nss_h + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -470,7 +470,7 @@ static int __nss_hal_common_reset(struct + } + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq95xx/nss_hal_pvt.c ++++ b/nss_hal/ipq95xx/nss_hal_pvt.c +@@ -291,7 +291,7 @@ static struct nss_platform_data *__nss_h + npd->vphys = res_vphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +@@ -303,7 +303,7 @@ static struct nss_platform_data *__nss_h + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -608,7 +608,7 @@ static int __nss_hal_common_reset(struct + + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -81,9 +81,9 @@ int nss_hal_firmware_load(struct nss_ctx + } + + +- load_mem = ioremap_nocache(npd->load_addr, nss_fw->size); ++ load_mem = ioremap(npd->load_addr, nss_fw->size); + if (!load_mem) { +- nss_info_always("%px: ioremap_nocache failed: %x", nss_ctx, npd->load_addr); ++ nss_info_always("%px: ioremap failed: %x", nss_ctx, npd->load_addr); + release_firmware(nss_fw); + return rc; + } +--- a/nss_meminfo.c ++++ b/nss_meminfo.c +@@ -736,7 +736,7 @@ bool nss_meminfo_init(struct nss_ctx_ins + /* + * meminfo_start is the label where the start address of meminfo map is stored. + */ +- meminfo_start = (uint32_t *)ioremap_nocache(nss_ctx->load + NSS_MEMINFO_MAP_START_OFFSET, ++ meminfo_start = (uint32_t *)ioremap(nss_ctx->load + NSS_MEMINFO_MAP_START_OFFSET, + NSS_MEMINFO_RESERVE_AREA_SIZE); + if (!meminfo_start) { + nss_info_always("%px: cannot remap meminfo start\n", nss_ctx); +--- a/nss_ppe.c ++++ b/nss_ppe.c +@@ -357,7 +357,7 @@ void nss_ppe_init(void) + /* + * Get the PPE base address + */ +- ppe_pvt.ppe_base = ioremap_nocache(PPE_BASE_ADDR, PPE_REG_SIZE); ++ ppe_pvt.ppe_base = ioremap(PPE_BASE_ADDR, PPE_REG_SIZE); + if (!ppe_pvt.ppe_base) { + nss_warning("DRV can't get PPE base address\n"); + return; diff --git a/package/qca/qca-nss-drv/patches/0002-nss-drv-add-support-for-kernel-5.15.patch b/package/qca/qca-nss-drv/patches/0002-nss-drv-add-support-for-kernel-5.15.patch new file mode 100644 index 000000000..279c18e57 --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0002-nss-drv-add-support-for-kernel-5.15.patch @@ -0,0 +1,62 @@ +From 2a3b9f4659542e529f4e1a535c33dfde7e272707 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 5 Apr 2022 18:10:57 +0200 +Subject: [PATCH 2/4] nss-drv: add support for kernel 5.15 + +- Fix coredump panic notifier include change. +- Fix skb ZEROCOPY flag. +- Add skb reuse support for 5.15 kernel version. + +Signed-off-by: Ansuel Smith +--- + nss_core.c | 5 +++-- + nss_coredump.c | 4 ++++ + nss_hal/nss_hal.c | 1 + + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -61,7 +61,9 @@ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \ +-(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))))) ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))) || \ ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)))) || \ ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)))))) + #error "Check skb recycle code in this file to match Linux version" + #endif + +@@ -2658,7 +2660,7 @@ static inline bool nss_core_skb_can_reus + if (unlikely(irqs_disabled())) + return false; + +- if (unlikely(skb_shinfo(nbuf)->tx_flags & SKBTX_DEV_ZEROCOPY)) ++ if (unlikely(skb_shinfo(nbuf)->flags & SKBFL_ZEROCOPY_ENABLE)) + return false; + + if (unlikely(skb_is_nonlinear(nbuf))) +--- a/nss_coredump.c ++++ b/nss_coredump.c +@@ -25,7 +25,11 @@ + #include "nss_hal.h" + #include "nss_log.h" + #include ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) + #include /* for panic_notifier_list */ ++#else ++#include ++#endif + #include /* for time */ + #include "nss_tx_rx_common.h" + +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "nss_hal.h" + #include "nss_arch.h" diff --git a/package/qca/qca-nss-drv/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch b/package/qca/qca-nss-drv/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch new file mode 100644 index 000000000..4577b8a4b --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch @@ -0,0 +1,28 @@ +From a6e3e81daab4eb9acbdef0ad1fed056e1bfbe320 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 8 Jun 2021 23:24:43 +0200 +Subject: [PATCH 3/4] DMA: Fix NULL pointer exceptions + +There are multiple instances that pass NULL instead +of device to DMA functions. +That is incorrect and will cause kernel NULL pointer +exceptions. + +So, simply pass the device structure pointers. + +Signed-off-by: Robert Marko +--- + nss_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -1660,7 +1660,7 @@ static int32_t nss_core_handle_cause_que + * + */ + if (unlikely((buffer_type == N2H_BUFFER_CRYPTO_RESP))) { +- dma_unmap_single(NULL, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); ++ dma_unmap_single(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); + goto consume; + } + diff --git a/package/qca/qca-nss-drv/patches/0004-nss-drv-rework-NSS_CORE_DMA_CACHE_MAINT-ops.patch b/package/qca/qca-nss-drv/patches/0004-nss-drv-rework-NSS_CORE_DMA_CACHE_MAINT-ops.patch new file mode 100644 index 000000000..793da70f0 --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0004-nss-drv-rework-NSS_CORE_DMA_CACHE_MAINT-ops.patch @@ -0,0 +1,558 @@ +From e6814c47d22ee5133a71016375239f87ea265794 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 5 Apr 2022 15:38:18 +0200 +Subject: [PATCH 4/4] nss-drv: rework NSS_CORE_DMA_CACHE_MAINT ops + +Rework NSS_CORE_DMA_CACHE_MAINT ops to use standard dma sync ops instead +of using the direct arch function. This permit to skip any hack/patch +needed for nss-drv to correctly compile on upstream kernel. + +We drop any NSS_CORE_DMA_CACHE_MAINT use in nss_core and we correctly +use the dma_sync_single_for_device we correctly dma addr using the new +DMA helper. +We drop sync for IOREMAP addr and we just leave a memory block. +We hope the nss_profiler is correctly ported. +We finally drop the NSS_CORE_DMA_CACHE_MAINT jus in case someone wants +to use it. + +Signed-off-by: Christian Marangi +--- + nss_core.c | 136 +++++++++++++++++++++++++--------- + nss_core.h | 41 +++++----- + nss_hal/ipq806x/nss_hal_pvt.c | 5 +- + nss_hal/ipq807x/nss_hal_pvt.c | 5 +- + nss_meminfo.c | 5 +- + nss_profiler.c | 3 +- + 6 files changed, 127 insertions(+), 68 deletions(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -1472,6 +1472,8 @@ static inline void nss_core_handle_empty + uint32_t count, uint32_t hlos_index, + uint16_t mask) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; ++ + while (count) { + /* + * Since we only return the primary skb, we have no way to unmap +@@ -1525,7 +1527,9 @@ next: + n2h_desc_ring->hlos_index = hlos_index; + if_map->n2h_hlos_index[NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_hlos_index[NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, ++ n2h_hlos_index_to_dma(mem_ctx->if_map_dma, NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + } + +@@ -1547,6 +1551,7 @@ static int32_t nss_core_handle_cause_que + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_if_mem_map *if_map = mem_ctx->if_map; ++ int dma_size; + + qid = nss_core_cause_to_queue(cause); + +@@ -1558,7 +1563,8 @@ static int32_t nss_core_handle_cause_que + n2h_desc_ring = &nss_ctx->n2h_desc_ring[qid]; + desc_if = &n2h_desc_ring->desc_ring; + desc_ring = desc_if->desc; +- NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_nss_index[qid], sizeof(uint32_t), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, n2h_nss_index_to_dma(mem_ctx->if_map_dma, qid), ++ sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->n2h_nss_index[qid]; + +@@ -1587,13 +1593,23 @@ static int32_t nss_core_handle_cause_que + start = hlos_index; + end = (hlos_index + count) & mask; + if (end > start) { +- dmac_inv_range((void *)&desc_ring[start], (void *)&desc_ring[end] + sizeof(struct n2h_descriptor)); ++ dma_size = sizeof(struct n2h_descriptor) * (end - start + 1); ++ ++ dma_sync_single_for_cpu(nss_ctx->dev, n2h_desc_index_to_dma(if_map, qid, start), ++ dma_size, DMA_FROM_DEVICE); + } else { + /* + * We have wrapped around + */ +- dmac_inv_range((void *)&desc_ring[start], (void *)&desc_ring[mask] + sizeof(struct n2h_descriptor)); +- dmac_inv_range((void *)&desc_ring[0], (void *)&desc_ring[end] + sizeof(struct n2h_descriptor)); ++ dma_size = sizeof(struct n2h_descriptor) * (mask - start + 1); ++ ++ dma_sync_single_for_cpu(nss_ctx->dev, n2h_desc_index_to_dma(if_map, qid, start), ++ dma_size, DMA_FROM_DEVICE); ++ ++ dma_size = sizeof(struct n2h_descriptor) * (end + 1); ++ ++ dma_sync_single_for_cpu(nss_ctx->dev, n2h_desc_index_to_dma(if_map, qid, 0), dma_size, ++ DMA_FROM_DEVICE); + } + + /* +@@ -1722,7 +1738,8 @@ next: + n2h_desc_ring->hlos_index = hlos_index; + if_map->n2h_hlos_index[qid] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_hlos_index[qid], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, n2h_hlos_index_to_dma(mem_ctx->if_map_dma, qid), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + return count; +@@ -1734,11 +1751,12 @@ next: + */ + static void nss_core_init_nss(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_top_instance *nss_top; + int ret; + int i; + +- NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(*if_map), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, mem_ctx->if_map_dma, sizeof(*if_map), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + + /* +@@ -1835,6 +1853,7 @@ static void nss_core_alloc_paged_buffers + uint16_t count, int16_t mask, int32_t hlos_index, uint32_t alloc_fail_count, + uint32_t buffer_type, uint32_t buffer_queue, uint32_t stats_index) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct sk_buff *nbuf; + struct page *npage; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[buffer_queue]; +@@ -1904,7 +1923,9 @@ static void nss_core_alloc_paged_buffers + /* + * Flush the descriptor + */ +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, ++ h2n_desc_index_to_dma(if_map, buffer_queue, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + hlos_index = (hlos_index + 1) & (mask); + count--; +@@ -1918,7 +1939,8 @@ static void nss_core_alloc_paged_buffers + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[buffer_queue] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[buffer_queue], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_hlos_index_to_dma(mem_ctx->if_map_dma, buffer_queue), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[stats_index]); +@@ -1931,7 +1953,7 @@ static void nss_core_alloc_paged_buffers + static void nss_core_alloc_jumbo_mru_buffers(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map, + int jumbo_mru, uint16_t count, int16_t mask, int32_t hlos_index) + { +- ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct sk_buff *nbuf; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; +@@ -1978,7 +2000,9 @@ static void nss_core_alloc_jumbo_mru_buf + /* + * Flush the descriptor + */ +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, ++ h2n_desc_index_to_dma(if_map, NSS_IF_H2N_EMPTY_BUFFER_QUEUE, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + hlos_index = (hlos_index + 1) & (mask); + count--; +@@ -1992,7 +2016,8 @@ static void nss_core_alloc_jumbo_mru_buf + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_hlos_index_to_dma(mem_ctx->if_map_dma, NSS_IF_H2N_EMPTY_BUFFER_QUEUE), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_TX_EMPTY]); +@@ -2005,6 +2030,7 @@ static void nss_core_alloc_jumbo_mru_buf + static void nss_core_alloc_max_avail_size_buffers(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map, + uint16_t max_buf_size, uint16_t count, int16_t mask, int32_t hlos_index) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; + struct h2n_descriptor *desc_ring = desc_if->desc; +@@ -2012,6 +2038,7 @@ static void nss_core_alloc_max_avail_siz + uint16_t payload_len = max_buf_size + NET_SKB_PAD; + uint16_t start = hlos_index; + uint16_t prev_hlos_index; ++ int dma_size; + + while (count) { + dma_addr_t buffer; +@@ -2064,13 +2091,26 @@ static void nss_core_alloc_max_avail_siz + * Flush the descriptors, including the descriptor at prev_hlos_index. + */ + if (prev_hlos_index > start) { +- dmac_clean_range((void *)&desc_ring[start], (void *)&desc_ring[prev_hlos_index] + sizeof(struct h2n_descriptor)); ++ dma_size = sizeof(struct h2n_descriptor) * (prev_hlos_index - start + 1); ++ ++ dma_sync_single_for_device(nss_ctx->dev, ++ h2n_desc_index_to_dma(if_map, NSS_IF_H2N_EMPTY_BUFFER_QUEUE, start), ++ dma_size, DMA_TO_DEVICE); + } else { + /* + * We have wrapped around + */ +- dmac_clean_range((void *)&desc_ring[start], (void *)&desc_ring[mask] + sizeof(struct h2n_descriptor)); +- dmac_clean_range((void *)&desc_ring[0], (void *)&desc_ring[prev_hlos_index] + sizeof(struct h2n_descriptor)); ++ dma_size = sizeof(struct h2n_descriptor) * (mask - start + 1); ++ ++ dma_sync_single_for_device(nss_ctx->dev, ++ h2n_desc_index_to_dma(if_map, NSS_IF_H2N_EMPTY_BUFFER_QUEUE, start), ++ dma_size, DMA_TO_DEVICE); ++ ++ dma_size = sizeof(struct h2n_descriptor) * (prev_hlos_index + 1); ++ ++ dma_sync_single_for_device(nss_ctx->dev, ++ h2n_desc_index_to_dma(if_map, NSS_IF_H2N_EMPTY_BUFFER_QUEUE, 0), ++ dma_size, DMA_TO_DEVICE); + } + + /* +@@ -2081,7 +2121,8 @@ static void nss_core_alloc_max_avail_siz + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_hlos_index_to_dma(mem_ctx->if_map_dma, NSS_IF_H2N_EMPTY_BUFFER_QUEUE), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_TX_EMPTY]); +@@ -2094,6 +2135,7 @@ static void nss_core_alloc_max_avail_siz + static inline void nss_core_handle_empty_buffer_sos(struct nss_ctx_instance *nss_ctx, + struct nss_if_mem_map *if_map, uint16_t max_buf_size) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint16_t count, size, mask; + int32_t nss_index, hlos_index; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; +@@ -2104,7 +2146,8 @@ static inline void nss_core_handle_empty + /* + * Check how many empty buffers could be filled in queue + */ +- NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, h2n_nss_index_to_dma(mem_ctx->if_map_dma, NSS_IF_H2N_EMPTY_BUFFER_QUEUE), ++ sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + +@@ -2149,6 +2192,7 @@ static inline void nss_core_handle_empty + static inline void nss_core_handle_paged_empty_buffer_sos(struct nss_ctx_instance *nss_ctx, + struct nss_if_mem_map *if_map, uint16_t max_buf_size) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint16_t count, size, mask; + int32_t nss_index, hlos_index; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE]; +@@ -2156,7 +2200,8 @@ static inline void nss_core_handle_paged + /* + * Check how many empty buffers could be filled in queue + */ +- NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE], sizeof(uint32_t), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, h2n_nss_index_to_dma(mem_ctx->if_map_dma, NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE), ++ sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE]; + +@@ -2733,9 +2778,11 @@ void nss_skb_reuse(struct sk_buff *nbuf) + * Sends one skb to NSS FW + */ + static inline int32_t nss_core_send_buffer_simple_skb(struct nss_ctx_instance *nss_ctx, +- struct h2n_desc_if_instance *desc_if, uint32_t if_num, +- struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) ++ struct h2n_desc_if_instance *desc_if, uint32_t if_num, struct sk_buff *nbuf, ++ uint16_t qid, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; ++ struct nss_if_mem_map *if_map = mem_ctx->if_map; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + uint16_t bit_flags; +@@ -2789,7 +2836,8 @@ static inline int32_t nss_core_send_buff + (nss_ptr_t)nbuf, (uint16_t)(nbuf->data - nbuf->head), nbuf->len, + sz, (uint32_t)nbuf->priority, mss, bit_flags); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + /* + * We are done using the skb fields and can reuse it now +@@ -2813,7 +2861,8 @@ no_reuse: + (nss_ptr_t)nbuf, (uint16_t)(nbuf->data - nbuf->head), nbuf->len, + (uint16_t)skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_SIMPLE]); + return 1; +@@ -2827,9 +2876,11 @@ no_reuse: + * Used to differentiate from FRAGLIST + */ + static inline int32_t nss_core_send_buffer_nr_frags(struct nss_ctx_instance *nss_ctx, +- struct h2n_desc_if_instance *desc_if, uint32_t if_num, +- struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) ++ struct h2n_desc_if_instance *desc_if, uint32_t if_num, struct sk_buff *nbuf, ++ uint16_t qid, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; ++ struct nss_if_mem_map *if_map = mem_ctx->if_map; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + const skb_frag_t *frag; +@@ -2869,7 +2920,8 @@ static inline int32_t nss_core_send_buff + (nss_ptr_t)NULL, nbuf->data - nbuf->head, nbuf->len - nbuf->data_len, + skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags | H2N_BIT_FLAG_FIRST_SEGMENT); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + /* + * Now handle rest of the fragments. +@@ -2893,7 +2945,8 @@ static inline int32_t nss_core_send_buff + (nss_ptr_t)NULL, 0, skb_frag_size(frag), skb_frag_size(frag), + nbuf->priority, mss, bit_flags); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + } + + /* +@@ -2909,7 +2962,8 @@ static inline int32_t nss_core_send_buff + desc->bit_flags &= ~(H2N_BIT_FLAG_DISCARD); + desc->opaque = (nss_ptr_t)nbuf; + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_NR_FRAGS]); + return i+1; +@@ -2923,9 +2977,11 @@ static inline int32_t nss_core_send_buff + * Used to differentiate from FRAGS + */ + static inline int32_t nss_core_send_buffer_fraglist(struct nss_ctx_instance *nss_ctx, +- struct h2n_desc_if_instance *desc_if, uint32_t if_num, +- struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) ++ struct h2n_desc_if_instance *desc_if, uint32_t if_num, struct sk_buff *nbuf, ++ uint16_t qid, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) + { ++ struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; ++ struct nss_if_mem_map *if_map = mem_ctx->if_map; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + dma_addr_t buffer; +@@ -2964,7 +3020,8 @@ static inline int32_t nss_core_send_buff + (nss_ptr_t)nbuf, nbuf->data - nbuf->head, nbuf->len - nbuf->data_len, + skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags | H2N_BIT_FLAG_FIRST_SEGMENT); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + /* + * Walk the frag_list in nbuf +@@ -3017,7 +3074,8 @@ static inline int32_t nss_core_send_buff + (nss_ptr_t)iter, iter->data - iter->head, iter->len - iter->data_len, + skb_end_offset(iter), iter->priority, mss, bit_flags); + +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + i++; + } +@@ -3036,7 +3094,8 @@ static inline int32_t nss_core_send_buff + * Update bit flag for last descriptor. + */ + desc->bit_flags |= H2N_BIT_FLAG_LAST_SEGMENT; +- NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_desc_index_to_dma(if_map, qid, hlos_index), ++ sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_FRAGLIST]); + return i+1; +@@ -3115,8 +3174,10 @@ int32_t nss_core_send_buffer(struct nss_ + * We need to work out if there's sufficent space in our transmit descriptor + * ring to place all the segments of a nbuf. + */ +- NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->h2n_nss_index[qid], sizeof(uint32_t), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, h2n_nss_index_to_dma(mem_ctx->if_map_dma, qid), ++ sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); ++ + nss_index = if_map->h2n_nss_index[qid]; + h2n_desc_ring->nss_index_local = nss_index; + count = ((nss_index - hlos_index - 1) + size) & (mask); +@@ -3181,13 +3242,13 @@ int32_t nss_core_send_buffer(struct nss_ + count = 0; + if (likely((segments == 0) || is_bounce)) { + count = nss_core_send_buffer_simple_skb(nss_ctx, desc_if, if_num, +- nbuf, hlos_index, flags, buffer_type, mss); ++ nbuf, qid, hlos_index, flags, buffer_type, mss); + } else if (skb_has_frag_list(nbuf)) { + count = nss_core_send_buffer_fraglist(nss_ctx, desc_if, if_num, +- nbuf, hlos_index, flags, buffer_type, mss); ++ nbuf, qid, hlos_index, flags, buffer_type, mss); + } else { + count = nss_core_send_buffer_nr_frags(nss_ctx, desc_if, if_num, +- nbuf, hlos_index, flags, buffer_type, mss); ++ nbuf, qid, hlos_index, flags, buffer_type, mss); + } + + if (unlikely(count <= 0)) { +@@ -3211,7 +3272,8 @@ int32_t nss_core_send_buffer(struct nss_ + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[qid] = hlos_index; + +- NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[qid], sizeof(uint32_t), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, h2n_hlos_index_to_dma(mem_ctx->if_map_dma, qid), ++ sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + #ifdef CONFIG_DEBUG_KMEMLEAK +--- a/nss_core.h ++++ b/nss_core.h +@@ -105,31 +105,30 @@ + #endif + + /* +- * Cache operation ++ * DMA Offset helper + */ +-#define NSS_CORE_DSB() dsb(sy) +-#define NSS_CORE_DMA_CACHE_MAINT(start, size, dir) nss_core_dma_cache_maint(start, size, dir) ++#define n2h_desc_index_offset(_index) sizeof(struct n2h_descriptor) * (_index) ++#define h2n_desc_index_offset(_index) sizeof(struct h2n_descriptor) * (_index) ++ ++#define n2h_desc_index_to_dma(_if_map_addr, _qid, _index) (_if_map_addr)->n2h_desc_if[(_qid)].desc_addr + n2h_desc_index_offset(_index) ++#define h2n_desc_index_to_dma(_if_map_addr, _qid, _index) (_if_map_addr)->h2n_desc_if[(_qid)].desc_addr + h2n_desc_index_offset(_index) ++ ++#define h2n_nss_index_offset offsetof(struct nss_if_mem_map, h2n_nss_index) ++#define n2h_nss_index_offset offsetof(struct nss_if_mem_map, n2h_nss_index) ++#define h2n_hlos_index_offset offsetof(struct nss_if_mem_map, h2n_hlos_index) ++#define n2h_hlos_index_offset offsetof(struct nss_if_mem_map, n2h_hlos_index) ++ ++#define h2n_nss_index_to_dma(_if_map_addr, _index) (_if_map_addr) + h2n_nss_index_offset + (sizeof(uint32_t) * (_index)) ++#define n2h_nss_index_to_dma(_if_map_addr, _index) (_if_map_addr) + n2h_nss_index_offset + (sizeof(uint32_t) * (_index)) ++#define h2n_hlos_index_to_dma(_if_map_addr, _index) (_if_map_addr) + h2n_hlos_index_offset + (sizeof(uint32_t) * (_index)) ++#define n2h_hlos_index_to_dma(_if_map_addr, _index) (_if_map_addr) + n2h_hlos_index_offset + (sizeof(uint32_t) * (_index)) + + /* +- * nss_core_dma_cache_maint() +- * Perform the appropriate cache op based on direction ++ * Cache operation + */ +-static inline void nss_core_dma_cache_maint(void *start, uint32_t size, int direction) +-{ +- switch (direction) { +- case DMA_FROM_DEVICE:/* invalidate only */ +- dmac_inv_range(start, start + size); +- break; +- case DMA_TO_DEVICE:/* writeback only */ +- dmac_clean_range(start, start + size); +- break; +- case DMA_BIDIRECTIONAL:/* writeback and invalidate */ +- dmac_flush_range(start, start + size); +- break; +- default: +- BUG(); +- } +-} ++#define NSS_CORE_DSB() dsb(sy) ++#define NSS_CORE_DMA_CACHE_MAINT(dev, start, size, dir) BUILD_BUG_ON_MSG(1, \ ++ "NSS_CORE_DMA_CACHE_MAINT is deprecated. Fix the code to use correct dma_sync_* API") + + #define NSS_DEVICE_IF_START NSS_PHYSICAL_IF_START + +--- a/nss_hal/ipq806x/nss_hal_pvt.c ++++ b/nss_hal/ipq806x/nss_hal_pvt.c +@@ -477,10 +477,9 @@ static struct nss_platform_data *__nss_h + /* + * Clear TCM memory used by this core + */ +- for (i = 0; i < resource_size(&res_vphys) ; i += 4) { ++ for (i = 0; i < resource_size(&res_vphys) ; i += 4) + nss_write_32(npd->vmap, i, 0); +- NSS_CORE_DMA_CACHE_MAINT((npd->vmap + i), 4, DMA_TO_DEVICE); +- } ++ + NSS_CORE_DSB(); + + /* +--- a/nss_hal/ipq807x/nss_hal_pvt.c ++++ b/nss_hal/ipq807x/nss_hal_pvt.c +@@ -259,10 +259,9 @@ static struct nss_platform_data *__nss_h + /* + * Clear TCM memory used by this core + */ +- for (i = 0; i < resource_size(&res_vphys) ; i += 4) { ++ for (i = 0; i < resource_size(&res_vphys) ; i += 4) + nss_write_32(npd->vmap, i, 0); +- NSS_CORE_DMA_CACHE_MAINT((npd->vmap + i), 4, DMA_TO_DEVICE); +- } ++ + NSS_CORE_DSB(); + + /* +--- a/nss_meminfo.c ++++ b/nss_meminfo.c +@@ -415,7 +415,6 @@ static bool nss_meminfo_init_block_lists + /* + * Flush the updated meminfo request. + */ +- NSS_CORE_DMA_CACHE_MAINT(r, sizeof(struct nss_meminfo_request), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + /* +@@ -546,7 +545,7 @@ static bool nss_meminfo_configure_n2h_h2 + * Bring a fresh copy of if_map from memory in order to read it correctly. + */ + if_map = mem_ctx->if_map; +- NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(struct nss_if_mem_map), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_ctx->dev, mem_ctx->if_map_dma, sizeof(struct nss_if_mem_map), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + + if_map->n2h_rings = NSS_N2H_RING_COUNT; +@@ -584,7 +583,7 @@ static bool nss_meminfo_configure_n2h_h2 + /* + * Flush the updated nss_if_mem_map. + */ +- NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(struct nss_if_mem_map), DMA_TO_DEVICE); ++ dma_sync_single_for_device(nss_ctx->dev, mem_ctx->if_map_dma, sizeof(struct nss_if_mem_map), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + return true; +--- a/nss_profiler.c ++++ b/nss_profiler.c +@@ -209,11 +209,12 @@ EXPORT_SYMBOL(nss_profile_dma_deregister + struct nss_profile_sdma_ctrl *nss_profile_dma_get_ctrl(struct nss_ctx_instance *nss_ctx) + { + struct nss_profile_sdma_ctrl *ctrl = nss_ctx->meminfo_ctx.sdma_ctrl; ++ int size = offsetof(struct nss_profile_sdma_ctrl, cidx); + if (!ctrl) { + return ctrl; + } + +- dmac_inv_range(ctrl, &ctrl->cidx); ++ dma_sync_single_for_cpu(nss_ctx->dev, (dma_addr_t) ctrl, size, DMA_FROM_DEVICE); + dsb(sy); + return ctrl; + } diff --git a/package/qca/qca-nss-drv/patches/0005-nss-drv-rework-getting-the-reserved-memory-size.patch b/package/qca/qca-nss-drv/patches/0005-nss-drv-rework-getting-the-reserved-memory-size.patch new file mode 100644 index 000000000..7bb8549e5 --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0005-nss-drv-rework-getting-the-reserved-memory-size.patch @@ -0,0 +1,114 @@ +From 1c2b564d7b29644765925a784d468f40555ded8a Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 10 Feb 2023 12:50:51 +0100 +Subject: [PATCH] nss-drv: rework getting the reserved-memory size + +Currently, the way NSS DRV gets the reserved memory node strictly depends +on the nss@40000000 node being present so it can find it after globaly +looking for the reserved-memory node and then going through its children. + +After that its evaluation the address and size cells manually in order to +properly calculate the size of reserved-memory. + +We can make this way more reliable and generic, so lets pass the memory +region wia the NSS common DTS node, match it via its compatible and then +get the memory region phandle and simply convert it to a resource. + +Signed-off-by: Robert Marko +--- + nss_core.c | 70 +++++++++++++++++++++++------------------------------- + 1 file changed, 30 insertions(+), 40 deletions(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #ifdef CONFIG_BRIDGE_NETFILTER +@@ -492,50 +494,38 @@ static void nss_core_handle_crypto_pkt(s + */ + static uint32_t nss_soc_mem_info(void) + { +- struct device_node *node; +- struct device_node *snode; +- int addr_cells; +- int size_cells; +- int n_items; +- uint32_t nss_msize = 8 << 20; /* default: 8MB */ +- const __be32 *ppp; +- +- node = of_find_node_by_name(NULL, "reserved-memory"); +- if (!node) { +- nss_info_always("reserved-memory not found\n"); +- return nss_msize; +- } +- +- ppp = (__be32 *)of_get_property(node, "#address-cells", NULL); +- addr_cells = ppp ? be32_to_cpup(ppp) : 2; +- nss_info("%px addr cells %d\n", ppp, addr_cells); +- ppp = (__be32 *)of_get_property(node, "#size-cells", NULL); +- size_cells = ppp ? be32_to_cpup(ppp) : 2; +- nss_info("%px size cells %d\n", ppp, size_cells); +- +- for_each_child_of_node(node, snode) { +- /* +- * compare (snode->full_name, "/reserved-memory/nss@40000000") may be safer +- */ +- nss_info("%px snode %s fn %s\n", snode, snode->name, snode->full_name); +- if (strcmp(snode->name, "nss") == 0) +- break; +- } +- of_node_put(node); +- if (!snode) { +- nss_info_always("nss@node not found: needed to determine NSS reserved DDR\n"); +- return nss_msize; +- } +- +- ppp = (__be32 *)of_get_property(snode, "reg", &n_items); +- if (ppp) { +- n_items /= sizeof(ppp[0]); +- nss_msize = be32_to_cpup(ppp + addr_cells + size_cells - 1); +- nss_info("addr/size storage words %d %d # words %d in DTS, ddr size %x\n", +- addr_cells, size_cells, n_items, nss_msize); ++ struct device_node *common_node, *memory_node; ++ struct resource r; ++ int ret; ++ ++ common_node = of_find_compatible_node(NULL, NULL, "qcom,nss-common"); ++ if (!common_node) { ++ nss_info_always("NSS common node not found!\n"); ++ goto err_use_default_memsize; ++ } ++ ++ memory_node = of_parse_phandle(common_node, "memory-region", 0); ++ if (!memory_node) { ++ nss_info_always("NSS reserved-memory node not found!\n"); ++ goto err_use_default_memsize; ++ } ++ ++ ret = of_address_to_resource(memory_node, 0, &r); ++ of_node_put(common_node); ++ of_node_put(memory_node); ++ if (ret) { ++ nss_info_always("NSS reserved-memory resource not found!\n"); ++ goto err_use_default_memsize; + } +- of_node_put(snode); +- return nss_msize; ++ ++ nss_info_always("NSS DDR size is 0x%x\n", (uint32_t) resource_size(&r)); ++ ++ return resource_size(&r); ++ ++err_use_default_memsize: ++ nss_info_always("Using default NSS reserved-memory size of 0x%x !\n", SZ_8M); ++ ++ return SZ_8M; + } + + /* diff --git a/package/qca/qca-nss-drv/patches/0006-nss-drv-Fix-nss_clmap_stats-enum-int-compilation-error-GCC-13.patch b/package/qca/qca-nss-drv/patches/0006-nss-drv-Fix-nss_clmap_stats-enum-int-compilation-error-GCC-13.patch new file mode 100644 index 000000000..7cdb0127f --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0006-nss-drv-Fix-nss_clmap_stats-enum-int-compilation-error-GCC-13.patch @@ -0,0 +1,11 @@ +--- a/nss_clmap_stats.c ++++ b/nss_clmap_stats.c +@@ -63,7 +63,7 @@ void nss_clmap_stats_session_unregister( + * nss_clmap_stats_session_register + * Register debug statistic for clmap session. + */ +-bool nss_clmap_stats_session_register(uint32_t if_num, uint32_t if_type, struct net_device *netdev) ++bool nss_clmap_stats_session_register(uint32_t if_num, enum nss_clmap_interface_type if_type, struct net_device *netdev) + { + uint32_t i; + bool stats_status = false; diff --git a/package/qca/qca-nss-drv/patches/0007-nss-drv-Fix-nss_wifili_if-compilation-error-GCC-13.patch b/package/qca/qca-nss-drv/patches/0007-nss-drv-Fix-nss_wifili_if-compilation-error-GCC-13.patch new file mode 100644 index 000000000..0abeab1ad --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0007-nss-drv-Fix-nss_wifili_if-compilation-error-GCC-13.patch @@ -0,0 +1,11 @@ +--- a/exports/nss_wifili_if.h ++++ b/exports/nss_wifili_if.h +@@ -2207,7 +2207,7 @@ void nss_wifili_release_external_if(nss_ + */ + uint8_t nss_wifili_thread_scheme_alloc(struct nss_ctx_instance *nss_ctx, + int32_t radio_ifnum, +- uint32_t radio_priority); ++ enum nss_wifili_thread_scheme_priority radio_priority); + + /** + * nss_wifili_thread_scheme_dealloc diff --git a/package/qca/qca-nss-drv/patches/0008-add-kernel-6.1-support.patch b/package/qca/qca-nss-drv/patches/0008-add-kernel-6.1-support.patch new file mode 100644 index 000000000..1ab62585f --- /dev/null +++ b/package/qca/qca-nss-drv/patches/0008-add-kernel-6.1-support.patch @@ -0,0 +1,250 @@ +--- a/nss_hal/fsm9010/nss_hal_pvt.c ++++ b/nss_hal/fsm9010/nss_hal_pvt.c +@@ -291,7 +291,11 @@ static int __nss_hal_request_irq(struct + } + + int_ctx->irq = npd->irq[irq_num]; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#endif + return 0; + } + +--- a/nss_hal/ipq50xx/nss_hal_pvt.c ++++ b/nss_hal/ipq50xx/nss_hal_pvt.c +@@ -599,7 +599,11 @@ static int __nss_hal_request_irq(struct + return err; + } + +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#endif + int_ctx->cause = cause; + err = request_irq(irq, nss_hal_handle_irq, 0, irq_name, int_ctx); + if (err) { +--- a/nss_hal/ipq60xx/nss_hal_pvt.c ++++ b/nss_hal/ipq60xx/nss_hal_pvt.c +@@ -615,62 +615,102 @@ static int __nss_hal_request_irq(struct + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#endif + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); ++#endif + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); ++#endif + int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) { + int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++#endif + int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) { + int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++#endif + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx); + } + +--- a/nss_hal/ipq806x/nss_hal_pvt.c ++++ b/nss_hal/ipq806x/nss_hal_pvt.c +@@ -1185,7 +1185,11 @@ static int __nss_hal_request_irq(struct + } + + int_ctx->irq = npd->irq[irq_num]; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); ++#endif + + return 0; + } +--- a/nss_hal/ipq807x/nss_hal_pvt.c ++++ b/nss_hal/ipq807x/nss_hal_pvt.c +@@ -659,62 +659,62 @@ static int __nss_hal_request_irq(struct + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) { + int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) { +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) { + int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA; +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx); + } + +--- a/nss_hal/ipq95xx/nss_hal_pvt.c ++++ b/nss_hal/ipq95xx/nss_hal_pvt.c +@@ -889,7 +889,11 @@ static int __nss_hal_request_irq(struct + return err; + } + +- netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) ++ netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#else ++ netif_napi_add_weight(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); ++#endif + int_ctx->cause = cause; + err = request_irq(irq, nss_hal_handle_irq, 0, irq_name, int_ctx); + if (err) { diff --git a/package/qca/qca-nss-ecm/Makefile b/package/qca/qca-nss-ecm/Makefile new file mode 100644 index 000000000..c5de42d92 --- /dev/null +++ b/package/qca/qca-nss-ecm/Makefile @@ -0,0 +1,161 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-ecm +PKG_RELEASE=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-10-20 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-nss-ecm.git +PKG_SOURCE_VERSION:=82b27915fffdbe2cdb2d4eb70e5736ccf92e2560 +PKG_MIRROR_HASH:=643895cb187cacfcde337c19dc5a34512acc225c0db1813a15cc1b66523835c4 + +PKG_BUILD_PARALLEL:=1 +PKG_FLAGS:=nonshared + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-ecm + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + DEPENDS:=@TARGET_qualcommax \ + +@NSS_DRV_IPV6_ENABLE \ + +@NSS_DRV_PPE_ENABLE \ + +@NSS_DRV_TUN6RD_ENABLE \ + +@NSS_DRV_PPPOE_ENABLE \ + +@NSS_DRV_PPTP_ENABLE \ + +@NSS_DRV_VIRT_IF_ENABLE \ + +@NSS_DRV_WIFI_ENABLE \ + +kmod-qca-nss-drv \ + +kmod-bonding +kmod-nf-conntrack \ + +kmod-ppp +kmod-pppoe +kmod-pptp \ + +PACKAGE_kmod-pppol2tp:kmod-pppol2tp \ + +PACKAGE_kmod-qca-mcs:kmod-qca-mcs \ + +PACKAGE_kmod-nat46:kmod-nat46 \ + +PACKAGE_kmod-vxlan:kmod-vxlan + TITLE:=QCA NSS Enhanced Connection Manager (ECM) + FILES:=$(PKG_BUILD_DIR)/ecm.ko + KCONFIG:=CONFIG_BRIDGE_NETFILTER=y \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_DSCPREMARK_EXT=y +endef + +define KernelPackage/qca-nss-ecm/Description +This package contains the QCA NSS Enhanced Connection Manager +endef + +define KernelPackage/qca-nss-ecm/install + $(INSTALL_DIR) $(1)/etc/firewall.d $(1)/etc/init.d $(1)/usr/bin $(1)/lib/netifd/offload $(1)/etc/config $(1)/etc/uci-defaults $(1)/etc/sysctl.d $(1)/etc/hotplug.d/net + $(INSTALL_DATA) ./files/qca-nss-ecm.firewall $(1)/etc/firewall.d/qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.init $(1)/etc/init.d/qca-nss-ecm + $(INSTALL_BIN) ./files/ecm_dump.sh $(1)/usr/bin/ + $(INSTALL_BIN) ./files/disable_offloads.sh $(1)/usr/bin/ + $(INSTALL_BIN) ./files/on-demand-down $(1)/lib/netifd/offload/on-demand-down + $(INSTALL_DATA) ./files/qca-nss-ecm.uci $(1)/etc/config/ecm + $(INSTALL_DATA) ./files/qca-nss-ecm.defaults $(1)/etc/uci-defaults/99-qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.sysctl $(1)/etc/sysctl.d/qca-nss-ecm.conf + $(INSTALL_BIN) ./files/disable_offloads.hotplug $(1)/etc/hotplug.d/net/99-disable_offloads +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(STAGING_DIR)/usr/include/qca-mcs \ + -I$(STAGING_DIR)/usr/include/nat46 + +ifeq ($(BOARD),qualcommax) +ECM_MAKE_OPTS+=ECM_FRONT_END_NSS_ENABLE=y \ + ECM_FRONT_END_SFE_ENABLE=n \ + ECM_NON_PORTED_SUPPORT_ENABLE=y \ + ECM_INTERFACE_BOND_ENABLE=y \ + ECM_INTERFACE_VLAN_ENABLE=y \ + ECM_CLASSIFIER_MARK_ENABLE=y \ + ECM_CLASSIFIER_DSCP_ENABLE=y \ + ECM_CLASSIFIER_PCC_ENABLE=n \ + ECM_BAND_STEERING_ENABLE=n +endif + +# Disable ECM IPv6 support when global IPv6 support is disabled. +ifneq ($(CONFIG_IPV6),) +ECM_MAKE_OPTS+=ECM_IPV6_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-link),) +ECM_MAKE_OPTS+=ECM_INTERFACE_OVPN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vxlanmgr),) +ECM_MAKE_OPTS+=ECM_INTERFACE_VXLAN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),) +ECM_MAKE_OPTS+=ECM_INTERFACE_OVS_BRIDGE_ENABLE=y \ + ECM_CLASSIFIER_OVS_ENABLE=y +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr +endif + +ifneq ($(CONFIG_PACKAGE_kmod-macvlan),) +ECM_MAKE_OPTS+=ECM_INTERFACE_MACVLAN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-mcs),) +ECM_MAKE_OPTS+=ECM_MULTICAST_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-nat46),) +ECM_MAKE_OPTS+=ECM_INTERFACE_MAP_T_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-ipsec),) +ECM_MAKE_OPTS+=ECM_INTERFACE_IPSEC_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-pppoe),) +ECM_MAKE_OPTS+=ECM_INTERFACE_PPPOE_ENABLE=y \ + ECM_INTERFACE_PPTP_ENABLE=y \ + ECM_INTERFACE_PPP_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-pppol2tp),) +ECM_MAKE_OPTS+=ECM_INTERFACE_L2TPV2_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-gre)$(CONFIG_PACKAGE_kmod-gre6),) +ECM_MAKE_OPTS+=ECM_INTERFACE_GRE_TAP_ENABLE=y \ + ECM_INTERFACE_GRE_TUN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-sit),) +ECM_MAKE_OPTS+=ECM_INTERFACE_SIT_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-ip6-tunnel),) +ECM_MAKE_OPTS+=ECM_INTERFACE_TUNIPIP6_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-mscs),) +ECM_MAKE_OPTS+=ECM_CLASSIFIER_MSCS_ENABLE=y +endif + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-ecm + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm +endef + +ifeq ($(CONFIG_TARGET_BOARD), "qualcommax") + SOC:=$(CONFIG_TARGET_SUBTARGET) +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(ECM_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS) -Wno-error=unused-function " \ + SoC=$(SOC) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-ecm)) diff --git a/package/qca/qca-nss-ecm/files/disable_offloads.hotplug b/package/qca/qca-nss-ecm/files/disable_offloads.hotplug new file mode 100755 index 000000000..01c564740 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/disable_offloads.hotplug @@ -0,0 +1,187 @@ +#!/bin/sh + +[ "$ACTION" != "add" ] && exit + +function log() +{ + local status="$1" + local feature="$2" + local interface="$3" + + if [ $status -eq 0 ]; then + logger "[ethtool] $feature: disabled on $interface" + fi + + if [ $status -eq 1 ]; then + logger -s "[ethtool] $feature: failed to disable on $interface" + fi + + if [ $status -gt 1 ]; then + logger "[ethtool] $feature: no changes performed on $interface" + fi +} + +function interface_is_virtual() +{ + local interface="$1" + [ -d /sys/devices/virtual/net/"$interface"/ ] || return 1 + return 0 +} + +function get_base_interface() +{ + local interface="$1" + echo "$interface" | grep -Eo '^[a-z]*[0-9]*' 2>/dev/null || return 1 + return 0 +} + +function disable_offloads() +{ + local interface="$1" + local features + local cmd + + # Check if we can change features + if ethtool -k $interface 1>/dev/null 2>/dev/null; then + # Filter whitespaces + # Get only enabled/not fixed features + # Filter features that are only changeable by global keyword + # Filter empty lines + # Cut to First column + features=$(ethtool -k "$interface" | awk '{$1=$1;print}' \ + | grep -E '^.+: on$' \ + | grep -v -E '^tx-checksum-.+$' \ + | grep -v -E '^tx-scatter-gather.+$' \ + | grep -v -E '^tx-tcp.+segmentation.+$' \ + | grep -v -E '^tx-udp-fragmentation$' \ + | grep -v -E '^tx-generic-segmentation$' \ + | grep -v -E '^rx-gro$' \ + | grep -v -E '^rx-gro$' \ + | grep -v -E '^$' \ + | cut -d: -f1) + + # Replace feature name by global keyword + features=$(echo "$features" | sed -e s/rx-checksumming/rx/ \ + -e s/tx-checksumming/tx/ \ + -e s/scatter-gather/sg/ \ + -e s/tcp-segmentation-offload/tso/ \ + -e s/udp-fragmentation-offload/ufo/ \ + -e s/generic-segmentation-offload/gso/ \ + -e s/generic-receive-offload/gro/ \ + -e s/large-receive-offload/lro/ \ + -e s/rx-vlan-offload/rxvlan/ \ + -e s/tx-vlan-offload/txvlan/ \ + -e s/ntuple-filters/ntuple/ \ + -e s/receive-hashing/rxhash/) + + # Check if we can disable anything + if [ -z "$features" ]; then + logger "[ethtool] offloads: no changes performed on $interface" + return 0 + fi + + # Construct ethtool command line + cmd="-K $interface" + + for feature in $features; do + cmd="$cmd $feature off" + done + + # Try to disable offloads + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Offloads" "$interface" + + else + log $? "Offloads" "$interface" + fi +} + +function disable_flow_control() +{ + local interface="$1" + local features + local cmd + + # Check if we can change settings + if ethtool -a $interface 1>/dev/null 2>/dev/null; then + # Construct ethtool command line + cmd="-A $interface autoneg off tx off rx off" + + # Try to disable flow control + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Flow Control" "$interface" + + else + log $? "Flow Control" "$interface" + fi +} + +function disable_interrupt_moderation() +{ + local interface="$1" + local features + local cmd + + # Check if we can change settings + if ethtool -c $interface 1>/dev/null 2>/dev/null; then + # Construct ethtool command line + cmd="-C $interface adaptive-tx off adaptive-rx off" + + # Try to disable adaptive interrupt moderation + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Adaptive Interrupt Moderation" "$interface" + + features=$(ethtool -c $interface | awk '{$1=$1;print}' \ + | grep -v -E '^.+: 0$|Adaptive|Coalesce' \ + | grep -v -E '^$' \ + | cut -d: -f1) + + # Check if we can disable anything + if [ -z "$features" ]; then + logger "[ethtool] Interrupt Moderation: no changes performed on $interface" + return 0 + fi + + # Construct ethtool command line + cmd="-C $interface" + + for feature in $features; do + cmd="$cmd $feature 0" + done + + # Try to disable interrupt Moderation + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Interrupt Moderation" "$interface" + + else + log $? "Interrupt Moderation" "$interface" + fi +} + +function disable_interface_offloads() { + #local interface=$(get_base_interface "$1") + #{ [ -z "$interface" ] || interface_is_virtual "$interface"; } && exit 0 + + local interface="$1" + + local disable_offloads="$(uci get ecm.@general[0].disable_offloads)" + if [ "$disable_offloads" -eq 1 ]; then + disable_offloads "$interface" + fi + + local disable_flow_control="$(uci get ecm.@general[0].disable_flow_control)" + if [ "$disable_flow_control" -eq 1 ]; then + disable_flow_control "$interface" + fi + + local disable_interrupt_moderation="$(uci get ecm.@general[0].disable_interrupt_moderation)" + if [ "$disable_interrupt_moderation" -eq 1 ]; then + disable_interrupt_moderation "$interface" + fi +} + +if [ "$ACTION" = add ]; then + disable_interface_offloads "$INTERFACE" +fi + +exit 0 diff --git a/package/qca/qca-nss-ecm/files/disable_offloads.sh b/package/qca/qca-nss-ecm/files/disable_offloads.sh new file mode 100755 index 000000000..9f8394fe7 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/disable_offloads.sh @@ -0,0 +1,189 @@ +#!/bin/sh +# +# Helper script which uses ethtool to disable (most) +# interface offloads, if possible. +# +# Reference: +# https://forum.openwrt.org/t/how-to-make-ethtool-setting-persistent-on-br-lan/6433/14 +# + +function log() +{ + local status="$1" + local feature="$2" + local interface="$3" + + if [ $status -eq 0 ]; then + logger "[ethtool] $feature: disabled on $interface" + fi + + if [ $status -eq 1 ]; then + logger -s "[ethtool] $feature: failed to disable on $interface" + fi + + if [ $status -gt 1 ]; then + logger "[ethtool] $feature: no changes performed on $interface" + fi +} + +function interface_is_virtual() +{ + local interface="$1" + [ -d /sys/devices/virtual/net/"$interface"/ ] || return 1 + return 0 +} + +function get_base_interface() +{ + local interface="$1" + echo "$interface" | grep -Eo '^[a-z]*[0-9]*' 2>/dev/null || return 1 + return 0 +} + +function disable_offloads() +{ + local interface="$1" + local features + local cmd + + # Check if we can change features + if ethtool -k $interface 1>/dev/null 2>/dev/null; then + + # Filter whitespaces + # Get only enabled/not fixed features + # Filter features that are only changeable by global keyword + # Filter empty lines + # Cut to First column + features=$(ethtool -k "$interface" | awk '{$1=$1;print}' \ + | grep -E '^.+: on$' \ + | grep -v -E '^tx-checksum-.+$' \ + | grep -v -E '^tx-scatter-gather.+$' \ + | grep -v -E '^tx-tcp.+segmentation.+$' \ + | grep -v -E '^tx-udp-fragmentation$' \ + | grep -v -E '^tx-generic-segmentation$' \ + | grep -v -E '^rx-gro$' \ + | grep -v -E '^rx-gro$' \ + | grep -v -E '^$' \ + | cut -d: -f1) + + # Replace feature name by global keyword + features=$(echo "$features" | sed -e s/rx-checksumming/rx/ \ + -e s/tx-checksumming/tx/ \ + -e s/scatter-gather/sg/ \ + -e s/tcp-segmentation-offload/tso/ \ + -e s/udp-fragmentation-offload/ufo/ \ + -e s/generic-segmentation-offload/gso/ \ + -e s/generic-receive-offload/gro/ \ + -e s/large-receive-offload/lro/ \ + -e s/rx-vlan-offload/rxvlan/ \ + -e s/tx-vlan-offload/txvlan/ \ + -e s/ntuple-filters/ntuple/ \ + -e s/receive-hashing/rxhash/) + + # Check if we can disable anything + if [ -z "$features" ]; then + logger "[ethtool] offloads: no changes performed on $interface" + return 0 + fi + + # Construct ethtool command line + cmd="-K $interface" + + for feature in $features; do + cmd="$cmd $feature off" + done + + # Try to disable offloads + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Offloads" "$interface" + + else + log $? "Offloads" "$interface" + fi +} + +function disable_flow_control() +{ + local interface="$1" + local features + local cmd + + # Check if we can change settings + if ethtool -a $interface 1>/dev/null 2>/dev/null; then + + # Construct ethtool command line + cmd="-A $interface autoneg off tx off rx off" + + # Try to disable flow control + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Flow Control" "$interface" + + else + log $? "Flow Control" "$interface" + fi +} + +function disable_interrupt_moderation() +{ + local interface="$1" + local features + local cmd + + # Check if we can change settings + if ethtool -c $interface 1>/dev/null 2>/dev/null; then + # Construct ethtool command line + cmd="-C $interface adaptive-tx off adaptive-rx off" + + # Try to disable adaptive interrupt moderation + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Adaptive Interrupt Moderation" "$interface" + + features=$(ethtool -c $interface | awk '{$1=$1;print}' \ + | grep -v -E '^.+: 0$|Adaptive|Coalesce' \ + | grep -v -E '^$' \ + | cut -d: -f1) + + # Check if we can disable anything + if [ -z "$features" ]; then + logger "[ethtool] Interrupt Moderation: no changes performed on $interface" + return 0 + fi + + # Construct ethtool command line + cmd="-C $interface" + + for feature in $features; do + cmd="$cmd $feature 0" + done + + # Try to disable interrupt Moderation + ethtool $cmd 1>/dev/null 2>/dev/null + log $? "Interrupt Moderation" "$interface" + + else + log $? "Interrupt Moderation" "$interface" + fi +} + +function main() +{ + for interface in /sys/class/net/*; do + interface=$(basename $interface) + + #interface=$(get_base_interface "$interface") + #{ [ -z "$interface" ] || interface_is_virtual "$interface"; } && exit 0 + + # Skip Loopback + if [ $interface == lo ]; then + continue + fi + + disable_offloads "$interface" + disable_flow_control "$interface" + disable_interrupt_moderation "$interface" + done +} + +main + +exit 0 diff --git a/package/qca/qca-nss-ecm/files/ecm_dump.sh b/package/qca/qca-nss-ecm/files/ecm_dump.sh new file mode 100755 index 000000000..dbf7de753 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/ecm_dump.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +ECM_MODULE=${1:-ecm_state} +MOUNT_ROOT=/dev/ecm + +# +# usage: ecm_dump.sh [module=ecm_db] +# +# with no parameters, ecm_dump.sh will attempt to mount the +# ecm_db state file and cat its contents. +# +# example with a parameter: ecm_dump.sh ecm_classifier_default +# +# this will cause ecm_dump to attempt to find and mount the state +# file for the ecm_classifier_default module, and if successful +# cat the contents. +# + +# this is one of the state files, which happens to be the +# last module started in ecm +ECM_STATE=/sys/kernel/debug/ecm/ecm_state/state_dev_major + +# tests to see if ECM is up and ready to receive commands. +# returns 0 if ECM is fully up and ready, else 1 +ecm_is_ready() { + if [ ! -e "${ECM_STATE}" ] + then + return 1 + fi + return 0 +} + +# +# module_state_mount(module_name) +# Mounts the state file of the module, if supported +# +module_state_mount() { + local module_name=$1 + local mount_dir=$2 + local state_file="/sys/kernel/debug/ecm/${module_name}/state_dev_major" + + if [ -e "${mount_dir}/${module_name}" ] + then + # already mounted + return 0 + fi + + #echo "Mount state file for $module_name ..." + if [ ! -e "$state_file" ] + then + #echo "... $module_name does not support state" + return 1 + fi + + local major="`cat $state_file`" + #echo "... Mounting state $state_file with major: $major" + mknod "${mount_dir}/${module_name}" c $major 0 +} + +# +# main +# +ecm_is_ready || { + #echo "ECM is not running" + exit 1 +} + +# all state files are mounted under MOUNT_ROOT, so make sure it exists +mkdir -p ${MOUNT_ROOT} + +# +# attempt to mount state files for the requested module and cat it +# if the mount succeeded +# +module_state_mount ${ECM_MODULE} ${MOUNT_ROOT} && { + cat ${MOUNT_ROOT}/${ECM_MODULE} + exit 0 +} + +exit 2 diff --git a/package/qca/qca-nss-ecm/files/on-demand-down b/package/qca/qca-nss-ecm/files/on-demand-down new file mode 100644 index 000000000..02d708e03 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/on-demand-down @@ -0,0 +1,6 @@ +#!/bin/sh +# Copyright (c) 2016 The Linux Foundation. All rights reserved. + +[ -e "/sys/kernel/debug/ecm/ecm_db/defunct_all" ] && { + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all +} diff --git a/package/qca/qca-nss-ecm/files/qca-nss-ecm.defaults b/package/qca/qca-nss-ecm/files/qca-nss-ecm.defaults new file mode 100644 index 000000000..308e265c9 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/qca-nss-ecm.defaults @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +uci -q batch << EOF + delete firewall.qcanssecm + set firewall.qcanssecm=include + set firewall.qcanssecm.type=script + set firewall.qcanssecm.path=/etc/firewall.d/qca-nss-ecm + set firewall.qcanssecm.family=any + set firewall.qcanssecm.reload=1 + commit firewall +EOF + +exit 0 diff --git a/package/qca/qca-nss-ecm/files/qca-nss-ecm.firewall b/package/qca/qca-nss-ecm/files/qca-nss-ecm.firewall new file mode 100644 index 000000000..2ec5b7e51 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/qca-nss-ecm.firewall @@ -0,0 +1,11 @@ +#!/bin/sh +if [ ! -r /sbin/fw4 ]; then +iptables-save|grep physdev-is-bridged|while read a; do + iptables -D FORWARD -m physdev --physdev-is-bridged -j ACCEPT +done +iptables -I FORWARD 1 -m physdev --physdev-is-bridged -j ACCEPT +ip6tables-save|grep physdev-is-bridged|while read a; do + ip6tables -D FORWARD -m physdev --physdev-is-bridged -j ACCEPT +done +ip6tables -I FORWARD 1 -m physdev --physdev-is-bridged -j ACCEPT +fi diff --git a/package/qca/qca-nss-ecm/files/qca-nss-ecm.init b/package/qca/qca-nss-ecm/files/qca-nss-ecm.init new file mode 100644 index 000000000..461c70d49 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/qca-nss-ecm.init @@ -0,0 +1,137 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2014, 2019-2020 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# The shebang above has an extra space intentially to avoid having +# openwrt build scripts automatically enable this package starting +# at boot. + +START=19 + +get_front_end_mode() { + config_load "ecm" + config_get front_end global acceleration_engine "auto" + + case $front_end in + auto) + echo '0' + ;; + nss) + echo '1' + ;; + *) + echo 'uci_option_acceleration_engine is invalid' + esac +} + +support_bridge() { + # NSS support bridge acceleration + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && [ -d /sys/kernel/debug/ecm/ecm_nss_ipv6 ] && return 0 +} + +enable_bridge_filtering() { + sysctl -w net.bridge.bridge-nf-call-arptables=0 + sysctl -w net.bridge.bridge-nf-call-iptables=0 + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 + + if ([ -z "$(grep "net.bridge.bridge-nf-call-arptables=0" /etc/sysctl.d/qca-nss-ecm.conf)" ] && \ + [ -z "$(grep "net.bridge.bridge-nf-call-iptables=0" /etc/sysctl.d/qca-nss-ecm.conf)" ] && \ + [ -z "$(grep "net.bridge.bridge-nf-call-ip6tables=0" /etc/sysctl.d/qca-nss-ecm.conf)" ] \ + ); then + echo 'net.bridge.bridge-nf-call-arptables=0' >> /etc/sysctl.d/qca-nss-ecm.conf + echo 'net.bridge.bridge-nf-call-iptables=0' >> /etc/sysctl.d/qca-nss-ecm.conf + echo 'net.bridge.bridge-nf-call-ip6tables=0' >> /etc/sysctl.d/qca-nss-ecm.conf + fi +} + +disable_bridge_filtering() { + sysctl -w net.bridge.bridge-nf-call-arptables=0 + sysctl -w net.bridge.bridge-nf-call-iptables=0 + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 + + sed '/net.bridge.bridge-nf-call-arptables/d' -i /etc/sysctl.d/qca-nss-ecm.conf + sed '/net.bridge.bridge-nf-call-iptables/d' -i /etc/sysctl.d/qca-nss-ecm.conf + sed '/net.bridge.bridge-nf-call-ip6tables/d' -i /etc/sysctl.d/qca-nss-ecm.conf +} + +load_ecm() { + [ -d /sys/module/ecm ] || { + insmod ecm front_end_selection=$(get_front_end_mode) + echo 1 > /sys/kernel/debug/ecm/ecm_classifier_default/accel_delay_pkts + } + + support_bridge && enable_bridge_filtering +} + +unload_ecm() { + disable_bridge_filtering + + if [ -d /sys/module/ecm ]; then + # + # Stop ECM frontends + # + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + + # + # Defunct the connections + # + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 5 + + rmmod ecm + sleep 1 + fi +} + +start() { + load_ecm + + # If the acceleration engine is NSS, enable wifi redirect + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=1 + + # If bridge filtering is enabled, apply and persist the sysctl flags + local bridge_filtering_enabled="$(uci_get ecm @general[0] enable_bridge_filtering)" + if [ "$bridge_filtering_enabled" -eq 1 ]; then + echo "Bridge filtering is enabled in the ECM config, this will cause issues with NAT loopback!" + enable_bridge_filtering + fi + + if [ -d /sys/module/qca_ovsmgr ]; then + insmod ecm_ovs + fi +} + +stop() { + # If ECM is already not loaded, just return + if [ ! -d /sys/module/ecm ]; then + return + fi + + # If the acceleration engine is NSS, disable wifi redirect + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=0 + + # If bridge filtering is enabled, reset the sysctl flags + local bridge_filtering_enabled="$(uci_get ecm @general[0] enable_bridge_filtering)" + if [ "$bridge_filtering_enabled" -eq 1 ]; then + disable_bridge_filtering + fi + + if [ -d /sys/module/ecm_ovs ]; then + rmmod ecm_ovs + fi + + unload_ecm +} diff --git a/package/qca/qca-nss-ecm/files/qca-nss-ecm.sysctl b/package/qca/qca-nss-ecm/files/qca-nss-ecm.sysctl new file mode 100644 index 000000000..e5b0dced3 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/qca-nss-ecm.sysctl @@ -0,0 +1 @@ +net.netfilter.nf_conntrack_max=65536 diff --git a/package/qca/qca-nss-ecm/files/qca-nss-ecm.uci b/package/qca/qca-nss-ecm/files/qca-nss-ecm.uci new file mode 100644 index 000000000..20c02bbf2 --- /dev/null +++ b/package/qca/qca-nss-ecm/files/qca-nss-ecm.uci @@ -0,0 +1,8 @@ +config ecm 'global' + option acceleration_engine 'auto' + +config general + option enable_bridge_filtering '1' + option disable_offloads '0' + option disable_flow_control '0' + option disable_interrupt_moderation '0' diff --git a/package/qca/qca-nss-ecm/patches/0001-treewide-componentize-the-module-even-more.patch b/package/qca/qca-nss-ecm/patches/0001-treewide-componentize-the-module-even-more.patch new file mode 100644 index 000000000..584f0a3fc --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0001-treewide-componentize-the-module-even-more.patch @@ -0,0 +1,361 @@ +From 09980e54011e2d95a9db2d6134f635bc90e5a7f2 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 19 May 2021 02:38:53 +0200 +Subject: [PATCH 01/12] treewide: componentize the module even more + +Signed-off-by: Ansuel Smith +--- + Makefile | 57 +++++++++++++++++++++++++------- + Makefile_61.mk | 1 - + ecm_db/ecm_db_connection.c | 8 +++++ + ecm_db/ecm_db_node.c | 4 +++ + ecm_interface.c | 8 +++++ + frontends/ecm_front_end_common.c | 7 ++++ + 6 files changed, 72 insertions(+), 13 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -17,7 +17,7 @@ + # ################################################### + # Makefile for the QCA NSS ECM + # ################################################### +-ifneq ($(findstring 6.1., $(KERNELVERSION)),) ++ifneq ($(findstring 6.2., $(KERNELVERSION)),) + include $(obj)/Makefile_61.mk + else + ifeq ($(ECM_FRONT_END_SFE_ENABLE), y) +@@ -134,9 +134,17 @@ ccflags-$(ECM_INTERFACE_BOND_ENABLE) += -DECM_INTERFACE_BOND_ENABLE + # Define ECM_INTERFACE_PPPOE_ENABLE=y in order + # to enable support for PPPoE acceleration. + # ############################################################################# +-ECM_INTERFACE_PPPOE_ENABLE=y ++ifndef $(ECM_INTERFACE_PPPOE_ENABLE) ++ ECM_INTERFACE_PPPOE_ENABLE=y ++endif + ccflags-$(ECM_INTERFACE_PPPOE_ENABLE) += -DECM_INTERFACE_PPPOE_ENABLE + ++# ############################################################################# ++# Define ECM_INTERFACE_L2TPV2_PPTP_ENABLE=y in order ++# to enable support for l2tpv2 or PPTP detection. ++# ############################################################################# ++ccflags-$(ECM_INTERFACE_L2TPV2_PPTP_ENABLE) += -DECM_INTERFACE_L2TPV2_PPTP_ENABLE ++ + # ############################################################################# + # Define ECM_INTERFACE_L2TPV2_ENABLE=y in order + # to enable support for l2tpv2 acceleration. +@@ -163,6 +171,12 @@ endif + endif + ccflags-$(ECM_INTERFACE_PPP_ENABLE) += -DECM_INTERFACE_PPP_ENABLE + ++# ############################################################################# ++# Define ECM_INTERFACE_GRE_ENABLE=y in order ++# to enable support for GRE detection. ++# ############################################################################# ++ccflags-$(ECM_INTERFACE_GRE_ENABLE) += -DECM_INTERFACE_GRE_ENABLE ++ + # ############################################################################# + # Define ECM_INTERFACE_GRE_TAP_ENABLE=y in order + # to enable support for GRE TAP interface. +@@ -246,7 +260,9 @@ ccflags-$(ECM_INTERFACE_OVS_BRIDGE_ENABLE) += -DECM_INTERFACE_OVS_BRIDGE_ENABLE + # ############################################################################# + # Define ECM_INTERFACE_VLAN_ENABLE=y in order to enable support for VLAN + # ############################################################################# +-ECM_INTERFACE_VLAN_ENABLE=y ++ifndef $(ECM_INTERFACE_VLAN_ENABLE) ++ ECM_INTERFACE_VLAN_ENABLE=y ++endif + ccflags-$(ECM_INTERFACE_VLAN_ENABLE) += -DECM_INTERFACE_VLAN_ENABLE + + # ############################################################################# +@@ -288,7 +304,9 @@ ccflags-$(ECM_CLASSIFIER_OVS_ENABLE) += -DECM_CLASSIFIER_OVS_ENABLE + # ############################################################################# + # Define ECM_CLASSIFIER_MARK_ENABLE=y in order to enable mark classifier. + # ############################################################################# +-ECM_CLASSIFIER_MARK_ENABLE=y ++ifndef $(ECM_CLASSIFIER_MARK_ENABLE) ++ ECM_CLASSIFIER_MARK_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_MARK_ENABLE) += ecm_classifier_mark.o + ccflags-$(ECM_CLASSIFIER_MARK_ENABLE) += -DECM_CLASSIFIER_MARK_ENABLE + +@@ -312,7 +330,9 @@ ccflags-$(ECM_CLASSIFIER_NL_ENABLE) += -DECM_CLASSIFIER_NL_ENABLE + # ############################################################################# + # Define ECM_CLASSIFIER_DSCP_ENABLE=y in order to enable DSCP classifier. + # ############################################################################# +-ECM_CLASSIFIER_DSCP_ENABLE=y ++ifndef $(ECM_CLASSIFIER_DSCP_ENABLE) ++ ECM_CLASSIFIER_DSCP_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_DSCP_ENABLE) += ecm_classifier_dscp.o + ccflags-$(ECM_CLASSIFIER_DSCP_ENABLE) += -DECM_CLASSIFIER_DSCP_ENABLE + ccflags-$(ECM_CLASSIFIER_DSCP_IGS) += -DECM_CLASSIFIER_DSCP_IGS +@@ -331,7 +351,9 @@ ccflags-$(ECM_CLASSIFIER_HYFI_ENABLE) += -DECM_CLASSIFIER_HYFI_ENABLE + # the Parental Controls subsystem classifier in ECM. Currently disabled until + # customers require it / if they need to integrate their Parental Controls with it. + # ############################################################################# +-ECM_CLASSIFIER_PCC_ENABLE=y ++ifndef $(ECM_CLASSIFIER_PCC_ENABLE) ++ ECM_CLASSIFIER_PCC_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_PCC_ENABLE) += ecm_classifier_pcc.o + ccflags-$(ECM_CLASSIFIER_PCC_ENABLE) += -DECM_CLASSIFIER_PCC_ENABLE + +@@ -372,27 +394,36 @@ ccflags-$(ECM_NON_PORTED_SUPPORT_ENABLE) += -DECM_NON_PORTED_SUPPORT_ENABLE + # ############################################################################# + # Define ECM_STATE_OUTPUT_ENABLE=y to support XML state output + # ############################################################################# +-ECM_STATE_OUTPUT_ENABLE=y ++ifndef $(ECM_STATE_OUTPUT_ENABLE) ++ ECM_STATE_OUTPUT_ENABLE=y ++endif + ecm-$(ECM_STATE_OUTPUT_ENABLE) += ecm_state.o + ccflags-$(ECM_STATE_OUTPUT_ENABLE) += -DECM_STATE_OUTPUT_ENABLE + + # ############################################################################# + # Define ECM_DB_ADVANCED_STATS_ENABLE to support XML state output + # ############################################################################# +-ECM_DB_ADVANCED_STATS_ENABLE=y ++ifndef $(ECM_DB_ADVANCED_STATS_ENABLE) ++ ECM_DB_ADVANCED_STATS_ENABLE=y ++endif + ccflags-$(ECM_DB_ADVANCED_STATS_ENABLE) += -DECM_DB_ADVANCED_STATS_ENABLE + + # ############################################################################# + # Define ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y in order to enable + # the database to track relationships between objects. + # ############################################################################# +-ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y ++ifndef $(ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE) ++ ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y ++endif + ccflags-$(ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE) += -DECM_DB_XREF_ENABLE + + # ############################################################################# + # Define ECM_TRACKER_DPI_SUPPORT_ENABLE=y in order to enable support for + # deep packet inspection and tracking of data with the trackers. + # ############################################################################# ++ifndef $(ECM_TRACKER_DPI_SUPPORT_ENABLE) ++ ECM_TRACKER_DPI_SUPPORT_ENABLE=y ++endif + ccflags-$(ECM_TRACKER_DPI_SUPPORT_ENABLE) += -DECM_TRACKER_DPI_SUPPORT_ENABLE + + # ############################################################################# +@@ -400,14 +431,18 @@ ccflags-$(ECM_TRACKER_DPI_SUPPORT_ENABLE) += -DECM_TRACKER_DPI_SUPPORT_ENABLE + # support for the database keeping lists of connections that are assigned + # on a per TYPE of classifier basis. + # ############################################################################# +-ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE=y ++ifndef $(ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE) ++ ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE=y ++endif + ccflags-$(ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE) += -DECM_DB_CTA_TRACK_ENABLE + + # ############################################################################# + # Define ECM_BAND_STEERING_ENABLE=y in order to enable + # band steering feature. + # ############################################################################# +-ECM_BAND_STEERING_ENABLE=y ++ifndef $(ECM_BAND_STEERING_ENABLE) ++ ECM_BAND_STEERING_ENABLE=y ++endif + ccflags-$(ECM_BAND_STEERING_ENABLE) += -DECM_BAND_STEERING_ENABLE + + # ############################################################################# +@@ -488,7 +523,6 @@ ccflags-y += -DECM_TRACKER_UDP_DEBUG_LEVEL=1 + ccflags-y += -DECM_BOND_NOTIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_INTERFACE_DEBUG_LEVEL=1 + ccflags-y += -DECM_STATE_DEBUG_LEVEL=1 +-ccflags-y += -DECM_OPENWRT_SUPPORT=1 + ccflags-y += -DECM_NOTIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_AE_CLASSIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_STATS_DEBUG_LEVEL=1 +--- a/Makefile_61.mk ++++ b/Makefile_61.mk +@@ -465,7 +465,6 @@ ccflags-y += -DECM_TRACKER_UDP_DEBUG_LEVEL=1 + ccflags-y += -DECM_BOND_NOTIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_INTERFACE_DEBUG_LEVEL=1 + ccflags-y += -DECM_STATE_DEBUG_LEVEL=1 +-ccflags-y += -DECM_OPENWRT_SUPPORT=1 + ccflags-y += -DECM_NOTIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_AE_CLASSIFIER_DEBUG_LEVEL=1 + ccflags-y += -DECM_STATS_DEBUG_LEVEL=1 +--- a/ecm_db/ecm_db_connection.c ++++ b/ecm_db/ecm_db_connection.c +@@ -446,7 +446,9 @@ EXPORT_SYMBOL(ecm_db_connection_make_def + */ + void ecm_db_connection_data_totals_update(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets) + { ++#ifdef ECM_DB_ADVANCED_STATS_ENABLE + int32_t i; ++#endif + + DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed\n", ci); + +@@ -545,7 +547,9 @@ EXPORT_SYMBOL(ecm_db_connection_data_tot + */ + void ecm_db_connection_data_totals_update_dropped(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets) + { ++#ifdef ECM_DB_ADVANCED_STATS_ENABLE + int32_t i; ++#endif + + DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed\n", ci); + +@@ -1539,6 +1543,7 @@ void ecm_db_connection_defunct_all(void) + } + EXPORT_SYMBOL(ecm_db_connection_defunct_all); + ++#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE + /* + * ecm_db_connection_defunct_by_classifier() + * Make defunct based on masked fields +@@ -1705,6 +1710,7 @@ next_ci: + ECM_IP_ADDR_TO_OCTAL(dest_addr_mask), dest_port_mask, proto_mask, cnt); + } + } ++#endif + + /* + * ecm_db_connection_defunct_by_port() +@@ -1994,6 +2000,7 @@ struct ecm_db_node_instance *ecm_db_conn + } + EXPORT_SYMBOL(ecm_db_connection_node_get_and_ref); + ++#ifdef ECM_DB_XREF_ENABLE + /* + * ecm_db_connection_mapping_get_and_ref_next() + * Return reference to next connection in the mapping chain in the specified direction. +@@ -2035,6 +2042,7 @@ struct ecm_db_connection_instance *ecm_d + return nci; + } + EXPORT_SYMBOL(ecm_db_connection_iface_get_and_ref_next); ++#endif + + /* + * ecm_db_connection_mapping_get_and_ref() +--- a/ecm_db/ecm_db_node.c ++++ b/ecm_db/ecm_db_node.c +@@ -227,9 +227,11 @@ EXPORT_SYMBOL(ecm_db_node_get_and_ref_ne + */ + int ecm_db_node_deref(struct ecm_db_node_instance *ni) + { ++#ifdef ECM_DB_XREF_ENABLE + #if (DEBUG_LEVEL >= 1) + int dir; + #endif ++#endif + DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni); + + spin_lock_bh(&ecm_db_lock); +@@ -489,9 +491,11 @@ EXPORT_SYMBOL(ecm_db_node_iface_get_and_ + void ecm_db_node_add(struct ecm_db_node_instance *ni, struct ecm_db_iface_instance *ii, uint8_t *address, + ecm_db_node_final_callback_t final, void *arg) + { ++#ifdef ECM_DB_XREF_ENABLE + #if (DEBUG_LEVEL >= 1) + int dir; + #endif ++#endif + ecm_db_node_hash_t hash_index; + struct ecm_db_listener_instance *li; + +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -1509,6 +1509,7 @@ struct neighbour *ecm_interface_ipv6_nei + */ + bool ecm_interface_is_pptp(struct sk_buff *skb, const struct net_device *out) + { ++#ifdef ECM_INTERFACE_PPTP_ENABLE + struct net_device *in; + + /* +@@ -1533,6 +1534,7 @@ bool ecm_interface_is_pptp(struct sk_buf + } + + dev_put(in); ++#endif + return false; + } + +@@ -1545,6 +1547,7 @@ bool ecm_interface_is_pptp(struct sk_buf + */ + bool ecm_interface_is_l2tp_packet_by_version(struct sk_buff *skb, const struct net_device *out, int ver) + { ++#ifdef ECM_INTERFACE_L2TPV2_PPTP_ENABLE + uint32_t flag = 0; + struct net_device *in; + +@@ -1577,6 +1580,7 @@ bool ecm_interface_is_l2tp_packet_by_ver + } + + dev_put(in); ++#endif + return false; + } + +@@ -1589,6 +1593,7 @@ bool ecm_interface_is_l2tp_packet_by_ver + */ + bool ecm_interface_is_l2tp_pptp(struct sk_buff *skb, const struct net_device *out) + { ++#ifdef ECM_INTERFACE_L2TPV2_PPTP_ENABLE + struct net_device *in; + + /* +@@ -1611,6 +1616,7 @@ bool ecm_interface_is_l2tp_pptp(struct s + } + + dev_put(in); ++#endif + return false; + } + +@@ -7127,6 +7133,7 @@ static void ecm_interface_regenerate_con + return; + } + ++#ifdef ECM_DB_XREF_ENABLE + for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) { + /* + * Re-generate all connections associated with this interface +@@ -7142,6 +7149,7 @@ static void ecm_interface_regenerate_con + ci[dir] = cin; + } + } ++#endif + + #ifdef ECM_MULTICAST_ENABLE + /* +--- a/frontends/ecm_front_end_common.c ++++ b/frontends/ecm_front_end_common.c +@@ -517,6 +517,7 @@ bool ecm_front_end_gre_proto_is_accel_al + struct nf_conntrack_tuple *reply_tuple, + int ip_version, uint16_t offset) + { ++#ifdef ECM_INTERFACE_GRE_ENABLE + struct net_device *dev; + struct gre_base_hdr *greh; + +@@ -528,10 +529,12 @@ bool ecm_front_end_gre_proto_is_accel_al + /* + * Case 1: PPTP locally terminated + */ ++#ifdef ECM_INTERFACE_PPTP_ENABLE + if (ecm_interface_is_pptp(skb, outdev)) { + DEBUG_TRACE("%px: PPTP GRE locally terminated - allow acceleration\n", skb); + return true; + } ++#endif + + /* + * Case 2: PPTP pass through +@@ -657,6 +660,10 @@ bool ecm_front_end_gre_proto_is_accel_al + */ + DEBUG_TRACE("%px: GRE IPv%d pass through non NAT - allow acceleration\n", skb, ip_version); + return true; ++#else ++ DEBUG_TRACE("%px: GRE%d feature is disabled - do not allow acceleration\n", skb, ip_version); ++ return false; ++#endif + } + + #ifdef ECM_CLASSIFIER_DSCP_ENABLE diff --git a/package/qca/qca-nss-ecm/patches/0002-treewide-rework-ipv6_dev_find_and_hold.patch b/package/qca/qca-nss-ecm/patches/0002-treewide-rework-ipv6_dev_find_and_hold.patch new file mode 100644 index 000000000..57765758c --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0002-treewide-rework-ipv6_dev_find_and_hold.patch @@ -0,0 +1,63 @@ +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -339,9 +339,9 @@ static struct net_device *ecm_interface_ + + ECM_IP_ADDR_TO_NIN6_ADDR(addr6, addr); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) +- dev = (struct net_device *)ipv6_dev_find(&init_net, &addr6, 1); ++ dev = (struct net_device *)ipv6_dev_find_and_hold(&init_net, &addr6, 1); + #else +- dev = (struct net_device *)ipv6_dev_find(&init_net, &addr6, NULL); ++ dev = (struct net_device *)ipv6_dev_find_and_hold(&init_net, &addr6, 1); + #endif + return dev; + } +@@ -802,9 +802,9 @@ static bool ecm_interface_mac_addr_get_i + */ + ECM_IP_ADDR_TO_NIN6_ADDR(daddr, addr); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) +- local_dev = ipv6_dev_find(&init_net, &daddr, 1); ++ local_dev = ipv6_dev_find_and_hold(&init_net, &daddr, 1); + #else +- local_dev = ipv6_dev_find(&init_net, &daddr, NULL); ++ local_dev = ipv6_dev_find_and_hold(&init_net, &daddr, 1); + #endif + if (local_dev) { + DEBUG_TRACE("%pi6 is a local address\n", &daddr); +--- a/frontends/ecm_front_end_common.c ++++ b/frontends/ecm_front_end_common.c +@@ -103,6 +103,10 @@ + #endif + #endif + ++#ifdef ECM_IPV6_ENABLE ++#include "ecm_front_end_ipv6.h" ++#endif ++ + #ifdef ECM_FRONT_END_FSE_ENABLE + /* + * Callback object for ECM frontend interaction with wlan driver to add/delete FSE rules. +@@ -614,9 +618,9 @@ bool ecm_front_end_gre_proto_is_accel_al + } else { + #ifdef ECM_IPV6_ENABLE + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) +- dev = ipv6_dev_find(&init_net, &(orig_tuple->src.u3.in6), 1); ++ dev = ipv6_dev_find_and_hold(&init_net, &(orig_tuple->src.u3.in6), 1); + #else +- dev = ipv6_dev_find(&init_net, &(orig_tuple->src.u3.in6), NULL); ++ dev = ipv6_dev_find_and_hold(&init_net, &(orig_tuple->src.u3.in6), 1); + #endif + if (dev) { + /* +@@ -628,9 +632,9 @@ bool ecm_front_end_gre_proto_is_accel_al + } + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) +- dev = ipv6_dev_find(&init_net, &(orig_tuple->dst.u3.in6), 1); ++ dev = ipv6_dev_find_and_hold(&init_net, &(orig_tuple->dst.u3.in6), 1); + #else +- dev = ipv6_dev_find(&init_net, &(orig_tuple->dst.u3.in6), NULL); ++ dev = ipv6_dev_find_and_hold(&init_net, &(orig_tuple->dst.u3.in6), 1); + #endif + if (dev) { + /* diff --git a/package/qca/qca-nss-ecm/patches/0003-qca-nss-ecm-resolve-the-cpu-high-load-regarding-ecm.patch b/package/qca/qca-nss-ecm/patches/0003-qca-nss-ecm-resolve-the-cpu-high-load-regarding-ecm.patch new file mode 100644 index 000000000..00476932b --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0003-qca-nss-ecm-resolve-the-cpu-high-load-regarding-ecm.patch @@ -0,0 +1,55 @@ +From 65aa71f33891bcf0b75995219e31abaf674c6199 Mon Sep 17 00:00:00 2001 +From: Dirk Buchwalder +Date: Sun, 27 Jun 2021 16:52:39 +0200 +Subject: [PATCH 05/12] qca-nss-ecm: resolve the cpu high load regarding ecm + +If using ECM, cpu load goes up (around 1.0) and stucks there. +This is due to using uninterruptible sleep function, +the patch changes this to interruptible sleep function. + +Signed-off-by: Dirk Buchwalder buchwalder@posteo.de +--- + frontends/nss/ecm_nss_ipv4.c | 4 ++-- + frontends/nss/ecm_nss_ipv6.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -700,7 +700,7 @@ static void ecm_nss_ipv4_stats_sync_req_ + } + spin_unlock_bh(&ecm_nss_ipv4_lock); + +- usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV4_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -714,7 +714,7 @@ static void ecm_nss_ipv4_stats_sync_req_ + } + + if (time_after(ecm_nss_ipv4_next_req_time, current_jiffies)) { +- msleep(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); + } + ecm_nss_ipv4_roll_check_jiffies = jiffies; + ecm_nss_ipv4_next_req_time = ecm_nss_ipv4_roll_check_jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD; +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -676,7 +676,7 @@ static void ecm_nss_ipv6_stats_sync_req_ + } + spin_unlock_bh(&ecm_nss_ipv6_lock); + +- usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV6_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -690,7 +690,7 @@ static void ecm_nss_ipv6_stats_sync_req_ + } + + if (time_after(ecm_nss_ipv6_next_req_time, current_jiffies)) { +- msleep(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); + } + ecm_nss_ipv6_roll_check_jiffies = jiffies; + ecm_nss_ipv6_next_req_time = ecm_nss_ipv6_roll_check_jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD; diff --git a/package/qca/qca-nss-ecm/patches/0005-frontends-drop-use-of-static-be_liberal-and-no_windo.patch b/package/qca/qca-nss-ecm/patches/0005-frontends-drop-use-of-static-be_liberal-and-no_windo.patch new file mode 100644 index 000000000..fc3ff0e38 --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0005-frontends-drop-use-of-static-be_liberal-and-no_windo.patch @@ -0,0 +1,88 @@ +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -1213,7 +1213,6 @@ static void ecm_nss_ported_ipv4_connection_accelerate(struct ecm_front_end_conne + #else + struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + uint32_t tcp_be_liberal = tn->tcp_be_liberal; +- uint32_t tcp_no_window_check = tn->tcp_no_window_check; + #endif + ecm_db_connection_address_get(feci->ci, ECM_DB_OBJ_DIR_FROM, addr); + ecm_front_end_flow_and_return_directions_get(ct, addr, 4, &flow_dir, &return_dir); +@@ -1228,11 +1227,7 @@ static void ecm_nss_ported_ipv4_connection_accelerate(struct ecm_front_end_conne + nircm->tcp_rule.return_max_window = ct->proto.tcp.seen[return_dir].td_maxwin; + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; +-#ifdef ECM_OPENWRT_SUPPORT +- if (tcp_be_liberal || tcp_no_window_check +-#else + if (tcp_be_liberal +-#endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { + nircm->rule_flags |= NSS_IPV4_RULE_CREATE_FLAG_NO_SEQ_CHECK; +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -1133,7 +1133,6 @@ static void ecm_nss_ported_ipv6_connection_accelerate(struct ecm_front_end_conne + #else + struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + uint32_t tcp_be_liberal = tn->tcp_be_liberal; +- uint32_t tcp_no_window_check = tn->tcp_no_window_check; + #endif + ecm_front_end_flow_and_return_directions_get(ct, src_ip, 6, &flow_dir, &return_dir); + +@@ -1147,11 +1146,7 @@ static void ecm_nss_ported_ipv6_connection_accelerate(struct ecm_front_end_conne + nircm->tcp_rule.return_max_window = ct->proto.tcp.seen[return_dir].td_maxwin; + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; +-#ifdef ECM_OPENWRT_SUPPORT +- if (tcp_be_liberal || tcp_no_window_check +-#else + if (tcp_be_liberal +-#endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { + nircm->rule_flags |= NSS_IPV6_RULE_CREATE_FLAG_NO_SEQ_CHECK; +--- a/frontends/sfe/ecm_sfe_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv4.c +@@ -1358,7 +1358,6 @@ static void ecm_sfe_ported_ipv4_connection_accelerate(struct ecm_front_end_conne + #else + struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + uint32_t tcp_be_liberal = tn->tcp_be_liberal; +- uint32_t tcp_no_window_check = tn->tcp_no_window_check; + #endif + ecm_db_connection_address_get(feci->ci, ECM_DB_OBJ_DIR_FROM, addr); + ecm_front_end_flow_and_return_directions_get(ct, addr, 4, &flow_dir, &return_dir); +@@ -1374,11 +1373,7 @@ static void ecm_sfe_ported_ipv4_connection_accelerate(struct ecm_front_end_conne + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; + +-#ifdef ECM_OPENWRT_SUPPORT +- if (tcp_be_liberal || tcp_no_window_check +-#else + if (tcp_be_liberal +-#endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { + nircm->rule_flags |= SFE_RULE_CREATE_FLAG_NO_SEQ_CHECK; +--- a/frontends/sfe/ecm_sfe_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv6.c +@@ -1371,7 +1371,6 @@ static void ecm_sfe_ported_ipv6_connection_accelerate(struct ecm_front_end_conne + #else + struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + uint32_t tcp_be_liberal = tn->tcp_be_liberal; +- uint32_t tcp_no_window_check = tn->tcp_no_window_check; + #endif + ecm_front_end_flow_and_return_directions_get(ct, src_ip, 6, &flow_dir, &return_dir); + +@@ -1385,11 +1384,7 @@ static void ecm_sfe_ported_ipv6_connection_accelerate(struct ecm_front_end_conne + nircm->tcp_rule.return_max_window = ct->proto.tcp.seen[return_dir].td_maxwin; + nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; + nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; +-#ifdef ECM_OPENWRT_SUPPORT +- if (tcp_be_liberal || tcp_no_window_check +-#else + if (tcp_be_liberal +-#endif + || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) + || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { + nircm->rule_flags |= SFE_RULE_CREATE_FLAG_NO_SEQ_CHECK; diff --git a/package/qca/qca-nss-ecm/patches/0006-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch b/package/qca/qca-nss-ecm/patches/0006-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch new file mode 100644 index 000000000..aa95ce15d --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0006-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch @@ -0,0 +1,50 @@ +From 9827d8597545ecfee17eba7b08d48dbcdf55c614 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 8 May 2022 18:39:39 +0200 +Subject: [PATCH 09/12] ecm_tracker_datagram: drop static for EXPORT_SYMBOL + +EXPORT_SYMBOL should NOT be static + +Signed-off-by: Ansuel Smith +--- + ecm_tracker_datagram.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/ecm_tracker_datagram.c ++++ b/ecm_tracker_datagram.c +@@ -203,7 +203,7 @@ static void ecm_tracker_datagram_datagra + * ecm_tracker_datagram_discard_all() + * Discard all tracked data + */ +-static void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) ++void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) + { + int32_t src_count; + int32_t dest_count; +@@ -364,7 +364,7 @@ static void ecm_tracker_datagram_datagra + * ecm_tracker_datagram_datagram_size_get() + * Return size in bytes of datagram at index i that was sent to the target + */ +-static int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) ++int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + +@@ -412,7 +412,7 @@ static int32_t ecm_tracker_datagram_data + * ecm_tracker_datagram_datagram_read() + * Read size bytes from datagram at index i into the buffer + */ +-static int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) ++int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + int res; +@@ -466,7 +466,7 @@ static int ecm_tracker_datagram_datagram + * ecm_tracker_datagram_datagram_add() + * Append the datagram onto the tracker queue for the given target + */ +-static bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) ++bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) + { + struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; + struct sk_buff *skbc; diff --git a/package/qca/qca-nss-ecm/patches/0007-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch b/package/qca/qca-nss-ecm/patches/0007-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch new file mode 100644 index 000000000..1554f2138 --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0007-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch @@ -0,0 +1,63 @@ +From ef638a84405c9f6556a9d7c257ccbba74efd228e Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 14 May 2022 20:15:10 +0200 +Subject: [PATCH 10/12] frontends: drop udp_get_timeouts and use standard + upstream api + +Drop udp_get_timeouts and use nf_udp_pernet and ->timeouts +instead or relying on a downstream api not present upstream. +--- + frontends/nss/ecm_nss_ipv4.c | 3 ++- + frontends/nss/ecm_nss_ipv6.c | 3 ++- + frontends/sfe/ecm_sfe_ipv4.c | 3 ++- + frontends/sfe/ecm_sfe_ipv6.c | 3 ++- + 4 files changed, 8 insertions(+), 4 deletions(-) + +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -610,7 +610,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -587,7 +587,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +--- a/frontends/sfe/ecm_sfe_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ipv4.c +@@ -562,7 +562,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -556,7 +556,8 @@ sync_conntrack: + #else + timeouts = nf_ct_timeout_lookup(ct); + if (!timeouts) { +- timeouts = udp_get_timeouts(nf_ct_net(ct)); ++ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); ++ timeouts = un->timeouts; + } + + spin_lock_bh(&ct->lock); diff --git a/package/qca/qca-nss-ecm/patches/0008-ecm_interface-fix-ppp-generic-function-calls-for-5.15.patch b/package/qca/qca-nss-ecm/patches/0008-ecm_interface-fix-ppp-generic-function-calls-for-5.15.patch new file mode 100644 index 000000000..e314dc1ef --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0008-ecm_interface-fix-ppp-generic-function-calls-for-5.15.patch @@ -0,0 +1,20 @@ +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -3606,7 +3606,7 @@ identifier_update: + if (skb && (skb->skb_iif == dev->ifindex)) { + struct pppol2tp_common_addr info; + +- if (__ppp_is_multilink(dev) > 0) { ++ if (ppp_is_multilink(dev) > 0) { + DEBUG_TRACE("%px: Net device: %px is MULTILINK PPP - Unknown to the ECM\n", feci, dev); + type_info.unknown.os_specific_ident = dev_interface_num; + +@@ -3616,7 +3616,7 @@ identifier_update: + ii = ecm_interface_unknown_interface_establish(&type_info.unknown, dev_name, dev_interface_num, ae_interface_num, dev_mtu); + return ii; + } +- channel_count = __ppp_hold_channels(dev, ppp_chan, 1); ++ channel_count = ppp_hold_channels(dev, ppp_chan, 1); + if (channel_count != 1) { + DEBUG_TRACE("%px: Net device: %px PPP has %d channels - ECM cannot handle this (interface becomes Unknown type)\n", + feci, dev, channel_count); diff --git a/package/qca/qca-nss-ecm/patches/0009-treewide-export-ipv4-and-ipv6-symbols.patch b/package/qca/qca-nss-ecm/patches/0009-treewide-export-ipv4-and-ipv6-symbols.patch new file mode 100644 index 000000000..6c4cf8b5b --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/0009-treewide-export-ipv4-and-ipv6-symbols.patch @@ -0,0 +1,99 @@ +--- a/frontends/nss/ecm_nss_common.c ++++ b/frontends/nss/ecm_nss_common.c +@@ -67,6 +67,7 @@ bool ecm_nss_ipv6_is_conn_limit_reached( + + return false; + } ++EXPORT_SYMBOL(ecm_nss_ipv6_is_conn_limit_reached); + #endif + + /* +@@ -116,3 +117,4 @@ bool ecm_nss_ipv4_is_conn_limit_reached( + + return false; + } ++EXPORT_SYMBOL(ecm_nss_ipv4_is_conn_limit_reached); +--- a/frontends/nss/ecm_nss_non_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv4.c +@@ -1831,6 +1831,7 @@ struct ecm_front_end_connection_instance + + return feci; + } ++EXPORT_SYMBOL(ecm_nss_non_ported_ipv4_connection_instance_alloc); + + /* + * ecm_nss_non_ported_ipv4_debugfs_init() +--- a/frontends/nss/ecm_nss_non_ported_ipv4.h ++++ b/frontends/nss/ecm_nss_non_ported_ipv4.h +@@ -19,7 +19,7 @@ + + extern bool ecm_nss_non_ported_ipv4_debugfs_init(struct dentry *dentry); + +-extern struct ecm_front_end_connection_instance *ecm_nss_non_ported_ipv4_connection_instance_alloc( ++struct ecm_front_end_connection_instance *ecm_nss_non_ported_ipv4_connection_instance_alloc( + uint32_t accel_flags, + int protocol, + struct ecm_db_connection_instance **nci); +--- a/frontends/nss/ecm_nss_non_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv6.c +@@ -1657,6 +1657,7 @@ struct ecm_front_end_connection_instance + + return feci; + } ++EXPORT_SYMBOL(ecm_nss_non_ported_ipv6_connection_instance_alloc); + + /* + * ecm_nss_non_ported_ipv6_debugfs_init() +--- a/frontends/nss/ecm_nss_non_ported_ipv6.h ++++ b/frontends/nss/ecm_nss_non_ported_ipv6.h +@@ -19,7 +19,7 @@ + + extern bool ecm_nss_non_ported_ipv6_debugfs_init(struct dentry *dentry); + +-extern struct ecm_front_end_connection_instance *ecm_nss_non_ported_ipv6_connection_instance_alloc( ++struct ecm_front_end_connection_instance *ecm_nss_non_ported_ipv6_connection_instance_alloc( + uint32_t accel_flags, + int protocol, + struct ecm_db_connection_instance **nci); +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -1906,6 +1906,7 @@ struct ecm_front_end_connection_instance + + return feci; + } ++EXPORT_SYMBOL(ecm_nss_ported_ipv4_connection_instance_alloc); + + /* + * ecm_nss_ported_ipv4_debugfs_init() +--- a/frontends/nss/ecm_nss_ported_ipv4.h ++++ b/frontends/nss/ecm_nss_ported_ipv4.h +@@ -19,7 +19,7 @@ + + extern bool ecm_nss_ported_ipv4_debugfs_init(struct dentry *dentry); + +-extern struct ecm_front_end_connection_instance *ecm_nss_ported_ipv4_connection_instance_alloc( ++struct ecm_front_end_connection_instance *ecm_nss_ported_ipv4_connection_instance_alloc( + uint32_t accel_flags, + int protocol, + struct ecm_db_connection_instance **nci); +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -1812,6 +1812,7 @@ struct ecm_front_end_connection_instance + + return feci; + } ++EXPORT_SYMBOL(ecm_nss_ported_ipv6_connection_instance_alloc); + + /* + * ecm_nss_ported_ipv6_debugfs_init() +--- a/frontends/nss/ecm_nss_ported_ipv6.h ++++ b/frontends/nss/ecm_nss_ported_ipv6.h +@@ -19,7 +19,7 @@ + + extern bool ecm_nss_ported_ipv6_debugfs_init(struct dentry *dentry); + +-extern struct ecm_front_end_connection_instance *ecm_nss_ported_ipv6_connection_instance_alloc( ++struct ecm_front_end_connection_instance *ecm_nss_ported_ipv6_connection_instance_alloc( + uint32_t accel_flags, + int protocol, + struct ecm_db_connection_instance **nci); diff --git a/package/qca/qca-nss-ecm/patches/1000-fix-missing-include-header.patch b/package/qca/qca-nss-ecm/patches/1000-fix-missing-include-header.patch new file mode 100644 index 000000000..cdc42b18e --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/1000-fix-missing-include-header.patch @@ -0,0 +1,10 @@ +--- a/frontends/ecm_front_end_common.c ++++ b/frontends/ecm_front_end_common.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #ifdef ECM_CLASSIFIER_DSCP_ENABLE + #include + #include diff --git a/package/qca/qca-nss-ecm/patches/900-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch b/package/qca/qca-nss-ecm/patches/900-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch new file mode 100644 index 000000000..529c79292 --- /dev/null +++ b/package/qca/qca-nss-ecm/patches/900-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch @@ -0,0 +1,61 @@ +From 1958e34c4c1b8b4fb62eba693fbd7693536947b9 Mon Sep 17 00:00:00 2001 +From: flebourse +Date: Thu, 23 Dec 2021 16:11:06 +0100 +Subject: [PATCH] qca-nss-ecm: fix a memcpy overflow in ecm_db + +Calls to ipv6_addr_prefix() trigger a memcpy overflow if the prefix len +argument is greater than 128, cap it at this value. + +stack bactrace: +detected buffer overflow in memcpy +Kernel BUG at fortify_panic+0x20/0x24 +Internal error: Oops - BUG: 0 [#1] SMP +CPU: 2 PID: 2592 Comm: netifd Not tainted 5.10.80 #0 +Hardware name: Xiaomi AX9000 (DT) +Call trace: + fortify_panic+0x20/0x24 + ecm_db_exit+0x42c/0x49c [ecm] + ecm_db_exit+0x464/0x49c [ecm] + atomic_notifier_call_chain+0x5c/0x90 + ip6_route_add+0x13c/0x1a4 + inet6_rtm_newroute+0x98/0xa0 + rtnetlink_rcv_msg+0x10c/0x34c + netlink_rcv_skb+0x5c/0x130 + rtnetlink_rcv+0x1c/0x2c + netlink_unicast+0x1ec/0x2e0 + netlink_sendmsg+0x1a4/0x394 + ____sys_sendmsg+0x270/0x2b4 + ___sys_sendmsg+0x7c/0xc0 + __sys_sendmsg+0x5c/0xb0 + __arm64_sys_sendmsg+0x28/0x34 + el0_svc_common.constprop.0+0x88/0x190 + do_el0_svc+0x74/0x94 + el0_svc+0x14/0x20 + el0_sync_handler+0xa8/0x130 + el0_sync+0x184/0x1c0 +Code: aa0003e1 912b4040 910003fd 97fff56c (d4210000) + +Signed-off-By: Francis Le Bourse +--- + ecm_db/ecm_db.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/ecm_db/ecm_db.c ++++ b/ecm_db/ecm_db.c +@@ -298,7 +298,7 @@ static int ecm_db_ipv6_route_table_updat + * Compute ECM connection's prefix destination address by masking it with the + * route config's destination address prefix length. + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); + + DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); + +@@ -326,7 +326,7 @@ static int ecm_db_ipv6_route_table_updat + * Compute ECM connection's prefix source address by masking it with the + * route config's destination address prefix length. + */ +- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); ++ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); + + DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); diff --git a/package/qca/qca-ssdk-shell/Makefile b/package/qca/qca-ssdk-shell/Makefile new file mode 100644 index 000000000..f177e3788 --- /dev/null +++ b/package/qca/qca-ssdk-shell/Makefile @@ -0,0 +1,48 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-ssdk-shell +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-10-04 +PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/ssdk-shell.git +PKG_SOURCE_VERSION:=451c3a26e366ea1acdb4305999a72a0389e74fed +PKG_MIRROR_HASH:=e2da723c12120096f1c851808b868abe1affa14e4d969eff7bedb1e1eb984418 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define Package/qca-ssdk-shell + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Shell application for QCA SSDK + DEPENDS:=@(TARGET_qualcommax) +endef + +define Package/qca-ssdk-shell/Description + This package contains a qca-ssdk shell application for QCA chipset +endef + +ifndef CONFIG_TOOLCHAIN_BIN_PATH +CONFIG_TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin +endif + +QCASSDK_CONFIG_OPTS+= \ + TOOL_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH) \ + SYS_PATH=$(LINUX_DIR) \ + TOOLPREFIX=$(TARGET_CROSS) \ + KVER=$(LINUX_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + ARCH=$(LINUX_KARCH) + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCASSDK_CONFIG_OPTS)) +endef + +define Package/qca-ssdk-shell/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/bin/ssdk_sh $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,qca-ssdk-shell)) diff --git a/package/qca/qca-ssdk-shell/patches/0001-qca-ssdk-shell-Fix-fal_port_cdt-compilation-error-GCC-13.patch b/package/qca/qca-ssdk-shell/patches/0001-qca-ssdk-shell-Fix-fal_port_cdt-compilation-error-GCC-13.patch new file mode 100644 index 000000000..9a97ff2d9 --- /dev/null +++ b/package/qca/qca-ssdk-shell/patches/0001-qca-ssdk-shell-Fix-fal_port_cdt-compilation-error-GCC-13.patch @@ -0,0 +1,10 @@ +--- a/src/fal_uk/fal_port_ctrl.c ++++ b/src/fal_uk/fal_port_ctrl.c +@@ -214,7 +214,7 @@ fal_port_hibernate_get(a_uint32_t dev_id + + sw_error_t + fal_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, +- a_uint32_t *cable_status, a_uint32_t *cable_len) ++ fal_cable_status_t * cable_status, a_uint32_t *cable_len) + { + sw_error_t rv; diff --git a/scripts/download.pl b/scripts/download.pl index 12e83325d..419fb947a 100755 --- a/scripts/download.pl +++ b/scripts/download.pl @@ -248,59 +248,49 @@ foreach my $mirror (@ARGV) { } } elsif ($mirror =~ /^\@OPENWRT$/) { # use OpenWrt source server directly - } elsif ($mirror =~ /^\@IMMORTALWRT$/) { - # use ImmortalWrt source server directly } elsif ($mirror =~ /^\@DEBIAN\/(.+)$/) { - push @mirrors, "https://mirrors.tencent.com/debian/$1"; push @mirrors, "https://mirrors.aliyun.com/debian/$1"; - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/debian/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/debian/$1"; + push @mirrors, "https://mirrors.tencent.com/debian/$1"; push @mirrors, "https://ftp.debian.org/debian/$1"; push @mirrors, "https://mirror.leaseweb.com/debian/$1"; push @mirrors, "https://mirror.netcologne.de/debian/$1"; } elsif ($mirror =~ /^\@APACHE\/(.+)$/) { - push @mirrors, "https://mirrors.tencent.com/apache/$1"; push @mirrors, "https://mirrors.aliyun.com/apache/$1"; - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/apache/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/apache/$1"; - push @mirrors, "https://dlcdn.apache.org/$1"; + push @mirrors, "https://mirrors.tencent.com/apache/$1"; + push @mirrors, "https://mirror.netcologne.de/apache.org/$1"; push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1"; push @mirrors, "https://archive.apache.org/dist/$1"; - push @mirrors, "https://mirror.cogentco.com/pub/apache/$1"; - push @mirrors, "https://mirror.navercorp.com/apache/$1"; - push @mirrors, "https://ftp.jaist.ac.jp/pub/apache/$1"; - push @mirrors, "https://apache.cs.utah.edu/apache.org/$1"; - push @mirrors, "http://apache.mirrors.ovh.net/ftp.apache.org/dist/$1"; + push @mirrors, "http://mirror.cogentco.com/pub/apache/$1"; + push @mirrors, "http://mirror.navercorp.com/apache/$1"; + push @mirrors, "http://ftp.jaist.ac.jp/pub/apache/$1"; + push @mirrors, "ftp://apache.cs.utah.edu/apache.org/$1"; + push @mirrors, "ftp://apache.mirrors.ovh.net/ftp.apache.org/dist/$1"; } elsif ($mirror =~ /^\@GITHUB\/(.+)$/) { - my $dir = $1; - my $i = 0; - # replace the 2nd '/' with '@' for jsDelivr mirror - push @mirrors, "https://cdn.jsdelivr.net/gh/". $dir =~ s{\/}{++$i == 2 ? '@' : $&}ger; - push @mirrors, "https://raw.sevencdn.com/$dir"; - push @mirrors, "https://raw.fastgit.org/$dir"; # give github a few more tries (different mirrors) for (1 .. 5) { - push @mirrors, "https://raw.githubusercontent.com/$dir"; + push @mirrors, "https://raw.githubusercontent.com/$1"; } } elsif ($mirror =~ /^\@GNU\/(.+)$/) { - push @mirrors, "https://mirrors.tencent.com/gnu/$1"; push @mirrors, "https://mirrors.aliyun.com/gnu/$1"; - push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/gnu/$1"; - push @mirrors, "https://mirrors.ustc.edu.cn/gnu/$1"; + push @mirrors, "https://mirrors.tencent.com/gnu/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnu/$1"; push @mirrors, "https://mirror.netcologne.de/gnu/$1"; - push @mirrors, "https://ftp.kddilabs.jp/GNU/gnu/$1"; - push @mirrors, "https://www.nic.funet.fi/pub/gnu/gnu/$1"; - push @mirrors, "https://mirror.navercorp.com/gnu/$1"; - push @mirrors, "https://mirrors.rit.edu/gnu/$1"; + push @mirrors, "http://ftp.kddilabs.jp/GNU/gnu/$1"; + push @mirrors, "http://www.nic.funet.fi/pub/gnu/gnu/$1"; + push @mirrors, "http://mirror.internode.on.net/pub/gnu/$1"; + push @mirrors, "http://mirror.navercorp.com/gnu/$1"; + push @mirrors, "ftp://mirrors.rit.edu/gnu/$1"; + push @mirrors, "ftp://download.xs4all.nl/pub/gnu/$1"; push @mirrors, "https://ftp.gnu.org/gnu/$1"; } elsif ($mirror =~ /^\@SAVANNAH\/(.+)$/) { push @mirrors, "https://mirror.netcologne.de/savannah/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/nongnu/$1"; - push @mirrors, "https://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; - push @mirrors, "https://nongnu.uib.no/$1"; - push @mirrors, "https://cdimage.debian.org/mirror/gnu.org/savannah/$1"; + push @mirrors, "http://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; + push @mirrors, "http://nongnu.uib.no/$1"; + push @mirrors, "http://ftp.igh.cnrs.fr/pub/nongnu/$1"; + push @mirrors, "ftp://cdimage.debian.org/mirror/gnu.org/savannah/$1"; + push @mirrors, "ftp://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; } elsif ($mirror =~ /^\@KERNEL\/(.+)$/) { my @extra = ( $1 ); if ($filename =~ /linux-\d+\.\d+(?:\.\d+)?-rc/) { @@ -311,20 +301,19 @@ foreach my $mirror (@ARGV) { foreach my $dir (@extra) { push @mirrors, "https://mirror.iscas.ac.cn/kernel.org/$dir"; push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir"; - push @mirrors, "https://mirror.nju.edu.cn/kernel.org/$dir"; push @mirrors, "https://cdn.kernel.org/pub/$dir"; + push @mirrors, "https://download.xs4all.nl/ftp.kernel.org/pub/$dir"; push @mirrors, "https://mirrors.mit.edu/kernel/$dir"; push @mirrors, "http://ftp.nara.wide.ad.jp/pub/kernel.org/$dir"; push @mirrors, "http://www.ring.gr.jp/archives/linux/kernel.org/$dir"; - push @mirrors, "https://ftp.riken.jp/Linux/kernel.org/$dir"; - push @mirrors, "https://www.mirrorservice.org/sites/ftp.kernel.org/pub/$dir"; + push @mirrors, "ftp://ftp.riken.jp/Linux/kernel.org/$dir"; + push @mirrors, "ftp://www.mirrorservice.org/sites/ftp.kernel.org/pub/$dir"; } } elsif ($mirror =~ /^\@GNOME\/(.+)$/) { push @mirrors, "https://mirrors.ustc.edu.cn/gnome/sources/$1"; - push @mirrors, "https://mirror.nju.edu.cn/gnome/$1"; push @mirrors, "https://download.gnome.org/sources/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnome/sources/$1"; - push @mirrors, "https://ftp.acc.umu.se/pub/GNOME/sources/$1"; + push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1"; push @mirrors, "http://ftp.cse.buffalo.edu/pub/Gnome/sources/$1"; push @mirrors, "http://ftp.nara.wide.ad.jp/pub/X11/GNOME/sources/$1"; } else { @@ -332,11 +321,6 @@ foreach my $mirror (@ARGV) { } } -# push @mirrors, 'https://mirror01.download.immortalwrt.eu.org'; -push @mirrors, 'https://mirror2.immortalwrt.org/sources'; -push @mirrors, 'https://mirror.immortalwrt.org/sources'; -push @mirrors, 'https://sources-cdn.immortalwrt.org'; -push @mirrors, 'https://sources.immortalwrt.org'; push @mirrors, 'https://sources.cdn.openwrt.org'; push @mirrors, 'https://sources.openwrt.org'; push @mirrors, 'https://mirror2.openwrt.org/sources'; diff --git a/target/linux/meson/Makefile b/target/linux/amlogic/Makefile similarity index 71% rename from target/linux/meson/Makefile rename to target/linux/amlogic/Makefile index 19e97332a..31dfb3ab1 100644 --- a/target/linux/meson/Makefile +++ b/target/linux/amlogic/Makefile @@ -4,11 +4,11 @@ include $(TOPDIR)/rules.mk -ARCH:=arm -BOARD:=meson +BOARD:=amlogic +BOARDNAME:=Amlogic BOARDNAME:=Amlogic Meson family -FEATURES:=boot-part ext4 fpu legacy-sdcard squashfs usbgadget -SUBTARGETS:=meson8b +FEATURES:=boot-part ext4 audio usb fpu legacy-sdcard squashfs usbgadget display gpio fpu pci pcie +SUBTARGETS:=meson8b mesongx KERNEL_PATCHVER:=6.1 @@ -25,7 +25,7 @@ DEFAULT_PACKAGES += \ automount \ resize2fs \ partx-utils \ - losetup + losetup htop autocore-arm KERNELNAME:=Image dtbs diff --git a/target/linux/amlogic/config-5.15 b/target/linux/amlogic/config-5.15 new file mode 100644 index 000000000..6922acd2f --- /dev/null +++ b/target/linux/amlogic/config-5.15 @@ -0,0 +1,46 @@ +CONFIG_AMLOGIC_THERMAL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_DRM_MESON is not set +# CONFIG_DRM_MESON_DW_HDMI is not set +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM_MESON=y +CONFIG_HW_RANDOM_OPTEE=y +CONFIG_INPUT=y +CONFIG_KVM_ARM_PMU=y +# CONFIG_MAX77620_WATCHDOG is not set +# CONFIG_MAX77620_THERMAL is not set +CONFIG_MESON_EFUSE=y +# CONFIG_MESON_MX_EFUSE is not set +# CONFIG_MFD_KHADAS_MCU is not set +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_NVMEM_SPMI_SDAM is not set +# CONFIG_PHY_MESON8B_USB2 is not set +# CONFIG_PINCTRL_MESON8_PMX is not set +# CONFIG_REGULATOR_S2MPA01 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_S5M8767 is not set +# CONFIG_REGULATOR_VEXPRESS is not set +# CONFIG_SDIO_UART is not set +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_ARM_SCPI=y +# CONFIG_SND_MESON_AIU is not set +# CONFIG_SND_MESON_AXG_FRDDR is not set +# CONFIG_SND_MESON_AXG_TODDR is not set +# CONFIG_SND_MESON_AXG_TDMIN is not set +# CONFIG_SND_MESON_AXG_TDMOUT is not set +# CONFIG_SND_MESON_AXG_SOUND_CARD is not set +# CONFIG_SND_MESON_AXG_SPDIFOUT is not set +# CONFIG_SND_MESON_AXG_SPDIFIN is not set +# CONFIG_SND_MESON_AXG_PDM is not set +# CONFIG_SND_MESON_GX_SOUND_CARD is not set +# CONFIG_SND_MESON_G12A_TOACODEC is not set +# CONFIG_SND_MESON_G12A_TOHDMITX is not set +# CONFIG_SND_SOC_MESON_T9015 is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y diff --git a/target/linux/meson/files/arch/arm/boot/dts/meson8b-onecloud.dts b/target/linux/amlogic/files/arch/arm/boot/dts/meson8b-onecloud.dts similarity index 100% rename from target/linux/meson/files/arch/arm/boot/dts/meson8b-onecloud.dts rename to target/linux/amlogic/files/arch/arm/boot/dts/meson8b-onecloud.dts diff --git a/target/linux/amlogic/image/Makefile b/target/linux/amlogic/image/Makefile new file mode 100644 index 000000000..3190b93d7 --- /dev/null +++ b/target/linux/amlogic/image/Makefile @@ -0,0 +1,91 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +DEVICE_VARS += UBOOT_DEVICE_NAME + +FAT32_BLOCK_SIZE=1024 +FAT32_BLOCKS=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) + +define Build/boot-script + # Make an U-boot image and copy it to the boot partition + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "boot.scr" -d boot.txt $(KDIR)/boot.scr +endef + +define Build/emmc-common + $(RM) -f $@.boot + mkfs.fat -C $@.boot $(FAT32_BLOCKS) + + mkdir -p $(KDIR)/boot.fat + + $(CP) $(KDIR)/boot.scr $(KDIR)/boot.fat/boot.scr + mcopy -i $@.boot $(KDIR)/boot.scr :: + $(CP) $(IMAGE_KERNEL) $(KDIR)/boot.fat/uImage + mcopy -i $@.boot $(KDIR)/boot.fat/uImage :: + + $(foreach dts,$(shell echo $(DEVICE_DTS)),$(CP) $(DTS_DIR)/$(dts).dtb $(KDIR)/boot.fat/dtb;) + mcopy -i $@.boot $(KDIR)/boot.fat/dtb :: + + $(RM) -rf $(KDIR)/boot.fat + + ./gen_aml_emmc_img.sh $@ $@.boot $(IMAGE_ROOTFS) \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) $(CONFIG_TARGET_ROOTFS_PARTSIZE) +endef + +### Image scripts ### + +define Build/boot-common + # This creates a new folder copies the dtb (as amlogic.dtb) + # and the kernel image (as kernel.img) + rm -fR $@.boot + mkdir -p $@.boot + + $(CP) $(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb $@.boot/amlogic.dtb + $(CP) $(IMAGE_KERNEL) $@.boot/kernel.img + $(CP) "$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot-overlay.bin $@.boot/u-boot.emmc +endef + +define Build/boot-combined + # This creates a new folder copies the dtbs (as amlogic*.dtb) + # and the kernel image (as kernel.img) + rm -fR $@.boot + mkdir -p $@.boot + + i=0; \ + for dts in $(DEVICE_DTS); do \ + $(CP) $(KDIR)/image-$${dts}.dtb $@.boot/amlogic$$(perl -e 'printf "%b\n",'$$i).dtb; \ + let i+=1; \ + done + $(CP) $(IMAGE_KERNEL) $@.boot/kernel.img + $(CP) "$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot-overlay.bin $@.boot/u-boot.emmc +endef + +define Build/boot-combined-script + # Make an U-boot image and copy it to the boot partition + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d aml_autoscript.cmd $@.boot/aml_autoscript + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d emmc_autoscript.cmd $@.boot/emmc_autoscript + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d s905_autoscript.cmd $@.boot/s905_autoscript + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d $(if $(1),$(1),amlogic).bootscript $@.boot/boot.scr +endef + +define Build/aml-img + # Creates the final SD/USB images, + # combining boot partition, root partition + + SIGNATURE="$(IMG_PART_SIGNATURE)" \ + ./gen_amlogic_image.sh \ + $@ \ + 64 $@.boot \ + 256 $(IMAGE_ROOTFS) \ + 2048 + +endef + +### Devices ### + +include $(SUBTARGET).mk + +$(eval $(call BuildImage)) diff --git a/target/linux/amlogic/image/aml_autoscript.cmd b/target/linux/amlogic/image/aml_autoscript.cmd new file mode 100644 index 000000000..637f7e4cd --- /dev/null +++ b/target/linux/amlogic/image/aml_autoscript.cmd @@ -0,0 +1,10 @@ +if printenv bootfromsd; then exit; else setenv ab 0; fi; +setenv bootcmd 'run start_autoscript; run storeboot' +setenv start_autoscript 'if mmcinfo; then run start_mmc_autoscript; fi; if usb start; then run start_usb_autoscript; fi; run start_emmc_autoscript' +setenv start_emmc_autoscript 'if fatload mmc 1 1020000 emmc_autoscript; then autoscr 1020000; fi;' +setenv start_mmc_autoscript 'if fatload mmc 0 1020000 s905_autoscript; then env delete usbdev; autoscr 1020000; fi;' +setenv start_usb_autoscript 'for usbdev in 0 1 2 3; do if fatload usb ${usbdev} 1020000 s905_autoscript; then autoscr 1020000; fi; done' +setenv upgrade_step 2 +saveenv +sleep 1 +reboot \ No newline at end of file diff --git a/target/linux/amlogic/image/amlogic.bootscript b/target/linux/amlogic/image/amlogic.bootscript new file mode 100644 index 000000000..3369e5c4f --- /dev/null +++ b/target/linux/amlogic/image/amlogic.bootscript @@ -0,0 +1,34 @@ +echo "Start AMLOGIC mainline U-boot" +setenv l_mmc "0" +for l_devtype in "sd usb mmc" ; do + if test "${l_devtype}" = "usb"; then + setenv l_mmc "0 1 2 3" + fi + if test "${l_devtype}" = "mmc"; then + setenv l_mmc "1" + fi + if test "${l_devtype}" = "sd"; then + setenv devtype "mmc" + else + setenv devtype "${l_devtype}" + fi + for devnum in ${l_mmc} ; do + if test -e ${devtype} ${devnum}:1 /boot.scr; then + part uuid ${devtype} ${devnum}:2 uuid + setenv bootargs "console=tty0 no_console_suspend consoleblank=0 console=ttyAML0,115200n8 root=PARTUUID=${uuid} rw rootwait" + if printenv mac; then + setenv bootargs ${bootargs} mac=${mac} + elif printenv eth_mac; then + setenv bootargs ${bootargs} mac=${eth_mac} + elif printenv ethaddr; then + setenv bootargs ${bootargs} mac=${ethaddr} + fi + load ${devtype} ${devnum}:1 ${fdt_addr_r} /amlogic.dtb + load ${devtype} ${devnum}:1 ${kernel_addr_r} /kernel.img + fdt addr ${fdt_addr_r} + booti ${kernel_addr_r} - ${fdt_addr_r} + fi + done +done +# Recompile with: +# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr \ No newline at end of file diff --git a/target/linux/meson/image/boot.txt b/target/linux/amlogic/image/boot.txt similarity index 100% rename from target/linux/meson/image/boot.txt rename to target/linux/amlogic/image/boot.txt diff --git a/target/linux/amlogic/image/emmc_autoscript.cmd b/target/linux/amlogic/image/emmc_autoscript.cmd new file mode 100755 index 000000000..eec1c7fd2 --- /dev/null +++ b/target/linux/amlogic/image/emmc_autoscript.cmd @@ -0,0 +1,8 @@ +if fatload mmc 1 0x1000000 u-boot.emmc; then go 0x1000000; fi; +setenv dtb_addr 0x1000000 +setenv env_addr 0x1040000 +setenv kernel_addr 0x11000000 +setenv initrd_addr 0x13000000 +setenv boot_start booti ${kernel_addr} ${initrd_addr} ${dtb_addr} +setenv addmac 'if printenv mac; then setenv bootargs ${bootargs} mac=${mac}; elif printenv eth_mac; then setenv bootargs ${bootargs} mac=${eth_mac}; elif printenv ethaddr; then setenv bootargs ${bootargs} mac=${ethaddr}; fi' +if fatload mmc 1 ${env_addr} uEnv.txt && env import -t ${env_addr} ${filesize}; setenv bootargs ${APPEND}; then if fatload mmc 1 ${kernel_addr} ${LINUX}; then if fatload mmc 1 ${initrd_addr} ${INITRD}; then if fatload mmc 1 ${dtb_addr} ${FDT}; then run addmac; run boot_start; fi; fi; fi; fi; diff --git a/target/linux/meson/image/gen_aml_emmc_img.sh b/target/linux/amlogic/image/gen_aml_emmc_img.sh similarity index 100% rename from target/linux/meson/image/gen_aml_emmc_img.sh rename to target/linux/amlogic/image/gen_aml_emmc_img.sh diff --git a/target/linux/amlogic/image/gen_amlogic_image.sh b/target/linux/amlogic/image/gen_amlogic_image.sh new file mode 100755 index 000000000..650df1304 --- /dev/null +++ b/target/linux/amlogic/image/gen_amlogic_image.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Copyright (C) 2006-2012 OpenWrt.org +set -e -x +if [ $# -ne 5 ] && [ $# -ne 6 ]; then + echo "SYNTAX: $0 []" + exit 1 +fi + +OUTPUT="$1" +KERNELSIZE="$2" +KERNELDIR="$3" +ROOTFSSIZE="$4" +ROOTFSIMAGE="$5" +ALIGN="$6" +USERDATASIZE="2048" + +rm -f "$OUTPUT" + +head=16 +sect=63 + +# create partition table +set $(ptgen -o "$OUTPUT" -h $head -s $sect -p "${KERNELSIZE}m" -p "${ROOTFSSIZE}m" -p "${USERDATASIZE}m" ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}) + +KERNELOFFSET="$(($1 / 512))" +KERNELSIZE="$2" +ROOTFSOFFSET="$(($3 / 512))" +ROOTFSSIZE="$(($4 / 512))" +USERDATAOFFSET="$(($5 / 512))" +USERDATASIZE="$(($6 / 512))" + +# Using mcopy -s ... is using READDIR(3) to iterate through the directory +# entries, hence they end up in the FAT filesystem in traversal order which +# breaks reproducibility. +# Implement recursive copy with reproducible order. +dos_dircopy() { + local entry + local baseentry + for entry in "$1"/* ; do + if [ -f "$entry" ]; then + mcopy -i "$OUTPUT.kernel" "$entry" ::"$2" + elif [ -d "$entry" ]; then + baseentry="$(basename "$entry")" + mmd -i "$OUTPUT.kernel" ::"$2""$baseentry" + dos_dircopy "$entry" "$2""$baseentry"/ + fi + done +} + +dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE" +dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc + +[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$USERDATAOFFSET" conv=notrunc count="$USERDATASIZE" +echo "RESET000" | dd of="$OUTPUT" bs=512 seek="$USERDATAOFFSET" conv=notrunc,sync count=1 + +mkfs.fat --invariant -n kernel -C "$OUTPUT.kernel" -S 512 "$((KERNELSIZE / 1024))" +LC_ALL=C dos_dircopy "$KERNELDIR" / + +dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc +rm -f "$OUTPUT.kernel" diff --git a/target/linux/amlogic/image/meson8b.mk b/target/linux/amlogic/image/meson8b.mk new file mode 100644 index 000000000..bab17477e --- /dev/null +++ b/target/linux/amlogic/image/meson8b.mk @@ -0,0 +1,18 @@ + +define Device/Default + FILESYSTEMS := ext4 + IMAGES := emmc.img + KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) + KERNEL_LOADADDR := 0x01080000 + KERNEL_NAME := Image + KERNEL := kernel-bin | uImage none + PROFILES = Default $$(DEVICE_NAME) +endef + +define Device/thunder-onecloud + DEVICE_DTS := meson8b-onecloud + DEVICE_TITLE := Thunder OneCloud + KERNEL_LOADADDR := 0x00208000 + IMAGE/emmc.img := boot-script onecloud | emmc-common $$(DEVICE_NAME) +endef +TARGET_DEVICES += thunder-onecloud diff --git a/target/linux/amlogic/image/mesongx.mk b/target/linux/amlogic/image/mesongx.mk new file mode 100644 index 000000000..c285014d8 --- /dev/null +++ b/target/linux/amlogic/image/mesongx.mk @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0-only + +define Device/Default + PROFILES := Default + KERNEL := kernel-bin + IMAGES := sysupgrade.img.gz + DEVICE_DTS_DIR := $(DTS_DIR)/amlogic + DEVICE_DTS = $$(SOC)-$(subst _,-,$(1)) +endef + +define Device/phicomm_n1 + DEVICE_VENDOR := Phicomm + DEVICE_MODEL := N1 + SOC := meson-gxl-s905d + UBOOT_DEVICE_NAME := phicomm-n1 + IMAGE/sysupgrade.img.gz := boot-common | boot-combined-script | aml-img | gzip | append-metadata + DEVICE_PACKAGES := ethtool kmod-brcmfmac brcmfmac-firmware-43455-sdio-phicomm-n1 wpad-openssl +endef +TARGET_DEVICES += phicomm_n1 \ No newline at end of file diff --git a/target/linux/amlogic/image/s905_autoscript.cmd b/target/linux/amlogic/image/s905_autoscript.cmd new file mode 100755 index 000000000..16ad8df4b --- /dev/null +++ b/target/linux/amlogic/image/s905_autoscript.cmd @@ -0,0 +1,16 @@ +if test "${usbdev}" = ""; then + setenv devtype "mmc" + setenv devnum 0 +else + setenv devtype "usb" + setenv devnum ${usbdev} +fi + +if fatload ${devtype} ${devnum} 0x1000000 u-boot.emmc; then go 0x1000000; fi; +setenv dtb_addr 0x1000000 +setenv env_addr 0x1040000 +setenv kernel_addr 0x11000000 +setenv initrd_addr 0x13000000 +setenv boot_start booti ${kernel_addr} ${initrd_addr} ${dtb_addr} +setenv addmac 'if printenv mac; then setenv bootargs ${bootargs} mac=${mac}; elif printenv eth_mac; then setenv bootargs ${bootargs} mac=${eth_mac}; elif printenv ethaddr; then setenv bootargs ${bootargs} mac=${ethaddr}; fi' +if fatload ${devtype} ${devnum} ${env_addr} uEnv.txt && env import -t ${env_addr} ${filesize}; setenv bootargs ${APPEND}; then if fatload ${devtype} ${devnum} ${kernel_addr} ${LINUX}; then if fatload ${devtype} ${devnum} ${initrd_addr} ${INITRD}; then if fatload ${devtype} ${devnum} ${dtb_addr} ${FDT}; then run addmac; run boot_start; fi; fi; fi; fi; diff --git a/target/linux/meson/base-files/etc/inittab b/target/linux/amlogic/meson8b/base-files/etc/inittab similarity index 100% rename from target/linux/meson/base-files/etc/inittab rename to target/linux/amlogic/meson8b/base-files/etc/inittab diff --git a/target/linux/meson/base-files/etc/rc.local b/target/linux/amlogic/meson8b/base-files/etc/rc.local similarity index 100% rename from target/linux/meson/base-files/etc/rc.local rename to target/linux/amlogic/meson8b/base-files/etc/rc.local diff --git a/target/linux/meson/base-files/lib/preinit/79_move_config b/target/linux/amlogic/meson8b/base-files/lib/preinit/79_move_config similarity index 100% rename from target/linux/meson/base-files/lib/preinit/79_move_config rename to target/linux/amlogic/meson8b/base-files/lib/preinit/79_move_config diff --git a/target/linux/meson/base-files/lib/upgrade/platform.sh b/target/linux/amlogic/meson8b/base-files/lib/upgrade/platform.sh similarity index 100% rename from target/linux/meson/base-files/lib/upgrade/platform.sh rename to target/linux/amlogic/meson8b/base-files/lib/upgrade/platform.sh diff --git a/target/linux/meson/base-files/root/resize.sh b/target/linux/amlogic/meson8b/base-files/root/resize.sh similarity index 100% rename from target/linux/meson/base-files/root/resize.sh rename to target/linux/amlogic/meson8b/base-files/root/resize.sh diff --git a/target/linux/meson/meson8b/config-6.1 b/target/linux/amlogic/meson8b/config-6.1 similarity index 100% rename from target/linux/meson/meson8b/config-6.1 rename to target/linux/amlogic/meson8b/config-6.1 diff --git a/target/linux/meson/meson8b/target.mk b/target/linux/amlogic/meson8b/target.mk similarity index 100% rename from target/linux/meson/meson8b/target.mk rename to target/linux/amlogic/meson8b/target.mk diff --git a/target/linux/amlogic/mesongx/base-files/etc/board.d/02_network b/target/linux/amlogic/mesongx/base-files/etc/board.d/02_network new file mode 100755 index 000000000..187c66c7a --- /dev/null +++ b/target/linux/amlogic/mesongx/base-files/etc/board.d/02_network @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (C) 2013-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +amlogic_setup_interfaces() +{ + local board="$1" + + case "$board" in + *) + ucidef_set_interface_lan 'eth0' + ;; + esac +} + +generate_mac_from_mmc() +{ + local sd_hash + local bootdisk=$( + . /lib/upgrade/common.sh + export_bootdevice && export_partdevice bootdisk 0 && echo $bootdisk + ) + if echo "$bootdisk" | grep -q '^mmcblk' && [ -f "/sys/class/block/$bootdisk/device/cid" ]; then + sd_hash=$(sha256sum /sys/class/block/$bootdisk/device/cid | head -n 1) + else + sd_hash=$(sha256sum /sys/class/block/mmcblk*/device/cid | head -n 1) + fi + local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)") + echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")" +} + +amlogic_setup_macs() +{ + local board="$1" + local lan_mac="" + local wan_mac="" + + case "$board" in + *) + lan_mac=$(generate_mac_from_mmc) + ;; + esac + + [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac + [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac +} + + +board_config_update +board=$(board_name) +amlogic_setup_interfaces $board +amlogic_setup_macs $board +board_config_flush + +exit 0 diff --git a/target/linux/amlogic/mesongx/base-files/etc/uci-defaults/12_enable-netifd-smp-tune b/target/linux/amlogic/mesongx/base-files/etc/uci-defaults/12_enable-netifd-smp-tune new file mode 100755 index 000000000..e6a9e6a9a --- /dev/null +++ b/target/linux/amlogic/mesongx/base-files/etc/uci-defaults/12_enable-netifd-smp-tune @@ -0,0 +1,7 @@ +#!/bin/sh +uci -q batch <<-EOF >/dev/null + set network.globals.packet_steering=1 + commit network +EOF + +exit 0 diff --git a/target/linux/amlogic/mesongx/base-files/lib/preinit/79_move_config b/target/linux/amlogic/mesongx/base-files/lib/preinit/79_move_config new file mode 100644 index 000000000..10d9181d5 --- /dev/null +++ b/target/linux/amlogic/mesongx/base-files/lib/preinit/79_move_config @@ -0,0 +1,16 @@ +move_config() { + local partdev parttype=ext4 + + . /lib/upgrade/common.sh + + if export_bootdevice && export_partdevice partdev 1; then + mkdir -p /boot + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /boot + if [ -f "/boot/$BACKUP_FILE" ]; then + mv -f "/boot/$BACKUP_FILE" / + fi + fi +} + +boot_hook_add preinit_mount_root move_config diff --git a/target/linux/amlogic/mesongx/base-files/lib/upgrade/platform.sh b/target/linux/amlogic/mesongx/base-files/lib/upgrade/platform.sh new file mode 100644 index 000000000..8de2e1a9a --- /dev/null +++ b/target/linux/amlogic/mesongx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,84 @@ + +platform_check_image() { + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev 0 || { + v "Unable to determine upgrade device" + return 1 + } + [ "$SAVE_CONFIG" -eq 1 ] && return 0 + + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + + rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image + + if [ -n "$diff" ]; then + v "Partition layout has changed. Full image will be written." + ask_bool 0 "Abort" && exit 1 + return 0 + fi +} + +platform_do_upgrade() { + local diskdev partdev part start size cursize + + export_bootdevice && export_partdevice diskdev 0 || { + v "Unable to determine upgrade device" + return 1 + } + + sync + + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b + + get_partitions /tmp/image.bs image + + #iterate over each partition from the image and check boot disk partition size + while read part start size; do + if [ -n "$UPGRADE_BACKUP" -a "$part" -ge 3 ]; then + continue + fi + cursize=$(echo $(grep -m1 '^ *'"$part"' *' /tmp/partmap.bootdisk) | cut -d' ' -f 3) + if [ -z "$cursize" ]; then + v "Unable to find partition $part on boot disk" + return 1 + fi + if [ "$size" -gt "$cursize" ]; then + v "Partition $part on image is bigger than boot disk ($size > $cursize)" + return 1 + fi + done < /tmp/partmap.image + + #iterate over each partition from the image and write it to the boot disk + while read part start size; do + if [ -n "$UPGRADE_BACKUP" -a "$part" -ge 3 ]; then + v "Skip partition $part >= 3 when upgrading" + continue + fi + if export_partdevice partdev $part; then + v "Writing image to /dev/$partdev..." + if [ "$part" -eq 3 ]; then + echo "RESET000" | dd of="/dev/$partdev" bs=512 count=1 conv=sync,fsync 2>/dev/null + else + get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + fi + else + v "Unable to find partition $part device, skipped." + fi + done < /tmp/partmap.image + + #copy partition uuid + v "Writing new UUID to /dev/$diskdev..." + get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync +} diff --git a/target/linux/amlogic/mesongx/base-files/usr/sbin/install-to-emmc.sh b/target/linux/amlogic/mesongx/base-files/usr/sbin/install-to-emmc.sh new file mode 100755 index 000000000..299684c18 --- /dev/null +++ b/target/linux/amlogic/mesongx/base-files/usr/sbin/install-to-emmc.sh @@ -0,0 +1,144 @@ +#!/bin/sh +# Copy running OpenWrt to eMMC for amlogic + +. /lib/functions.sh +. /lib/functions/system.sh + +include /lib/upgrade +NEWLINE=" +" + +function umount_disk() { + local mounted + local to="${1#/dev/}" + umount "/dev/$to"* 2>/dev/null + mounted="`mount | cut -d' ' -f1 | grep -Fm1 "/dev/$to"`" + if [ -n "$mounted" ] ; then + echo "can not umount $mounted" >&2 + return 1 + fi + return 0 +} + +function part_disk() { + local to="${1#/dev/}" + dd if=/dev/zero of="/dev/$to" bs=512 count=1 conv=notrunc 2>/dev/null + parted --script "/dev/$to" \ + mktable msdos \ + mkpart primary 68MiB 132MiB \ + mkpart primary 132MiB 388MiB \ + mkpart primary 764MiB 2812MiB +} + +function get_bootdisk() { + local var=$1 + local diskdev + export_bootdevice && export_partdevice diskdev 0 || { + echo "Unable to determine upgrade device" >&2 + return 1 + } + export "$var=$diskdev" + return 0 +} + +function get_emmcs() { + local disk index disks + local bootdisk=$1 + + index=1 + for disk in `cd /sys/block && ls | grep '^mmcblk' | grep -Ev 'mmcblk\d+boot\d+'`; do + [[ "$bootdisk" = "$disk" ]] && continue + [ -b /dev/$disk ] && [ "`cat /sys/block/$disk/size`" -gt 0 ] || continue + local diskinfo="`parted -ms "/dev/$disk" unit GiB print 2>/dev/null | grep -m1 "^/dev/$disk:"`" + [ -z "$diskinfo" ] && continue + local size="`echo "$diskinfo" | cut -d: -f2`" + # check disk greater than 2.8GB + [ $(( `echo "${size%%GiB}" | sed 's/\.\(.\).*/ * 10 + \1/'` )) -ge 28 ] || continue + local model="`echo "$diskinfo" | cut -d: -f7 | sed 's/"/_/g'`" + disks="${disks}$index. $disk $size \"$model\"$NEWLINE" + index=$(($index + 1)) + done + echo "$disks" + return 0 +} + +function get_emmc() { + local index + local var=$2 + local emmcs="$(get_emmcs $1)" + [ -z "$emmcs" ] && { + echo "Get eMMC list failed! (Maybe already running on eMMC? Current boot disk is $1)" >&2 + return 1 + } + local count=$(echo "$emmcs" | wc -l) + if [ "$count" -gt 1 ]; then + while true; do + echo "Found these eMMC devices:" + echo "Index. device size model" + echo "$emmcs" + echo -n "Select a disk to install (input index then press Enter): " + read index || { + echo "No input!" >&2 + exit 1 + } + if [ -z "$index" ]; then + echo "Empty input!" + else + echo "$emmcs" | grep -q "^${index}. " && break + echo "Wrong index!" + fi + done + else + echo "Found eMMC device:" + echo "Index. device size model" + echo "$emmcs" + index=1 + fi + local value=$(echo "$emmcs" | grep "^${index}. " | cut -d' ' -f 2) + export "$var=$value" +} + +function main() { + local bootdisk yn partdev part partdevto to + get_bootdisk bootdisk + [ -z "$bootdisk" ] && return 1 + get_emmc $bootdisk to + [ -n "$to" ] || return 1 + echo -ne "Will install to $to, confirm? y/N [n]\b\b" + read yn + if [ "$yn" = Y -o "$yn" = y ]; then + echo "" + echo "umount /dev/$to*" + umount_disk "$to" || return 1 + echo "part /dev/$to" + part_disk "$to" || return 1 + partprobe "/dev/$to" + if export_partdevice partdev 1; then + # umount /boot + echo "try umount /boot" + /bin/mount -o noatime,remount,ro /dev/$partdev + /usr/bin/umount -R -d -l /dev/$partdev 2>/dev/null || /bin/umount -l /dev/$partdev + fi + sleep 1 + echo "copy rom data from /dev/$bootdisk to /dev/$to" + for part in 1 2; do + # copy boot and rootfs partitions + export_partdevice partdev $part + partdevto=${to}p$part + echo "copy /dev/$partdev to /dev/$partdevto" + dd if=/dev/$partdev of=/dev/$partdevto bs=1M conv=notrunc + done + # mark RESET overlay partition + partdevto=${to}p3 + echo "mark /dev/$partdevto as RESET" + echo "RESET000" | dd of="/dev/$partdevto" bs=512 count=1 conv=sync,fsync + echo "All Done!" + else + echo "Bye!" + fi +} + +echo "Copy running OpenWrt to eMMC for amlogic" +echo "" + +main diff --git a/target/linux/amlogic/mesongx/config-5.15 b/target/linux/amlogic/mesongx/config-5.15 new file mode 100644 index 000000000..d3dc2df62 --- /dev/null +++ b/target/linux/amlogic/mesongx/config-5.15 @@ -0,0 +1,710 @@ +CONFIG_64BIT=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MESON=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=33 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +CONFIG_ARM64_CRYPTO=y +CONFIG_ARM64_MODULE_PLTS=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PTR_AUTH=y +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=48 +# CONFIG_ARM64_VA_BITS_39 is not set +CONFIG_ARM64_VA_BITS_48=y +# CONFIG_ARMV8_DEPRECATED is not set +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_GIC_V3_ITS_PCI=y +CONFIG_ARM_MHU=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_SBSA_WATCHDOG=y +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_ARM_SCMI_POWER_DOMAIN=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCPI_CPUFREQ=y +CONFIG_ARM_SCPI_POWER_DOMAIN=y +CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_ARM_SMC_WATCHDOG=y +CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_ATA=y +CONFIG_ATA_LINK_SUPPORTS_LEDS=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_BINFMT_MISC=y +CONFIG_BLK_CGROUP=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_DM is not set +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BRCMSTB_GISB_ARB=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_CGROUPS=y +CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +# CONFIG_CGROUP_NET_CLASSID is not set +# CONFIG_CGROUP_NET_PRIO is not set +CONFIG_CGROUP_PIDS=y +# CONFIG_CGROUP_RDMA is not set +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_AXG=y +# CONFIG_COMMON_CLK_AXG_AUDIO is not set +CONFIG_COMMON_CLK_CS2000_CP=y +CONFIG_COMMON_CLK_G12A=y +CONFIG_COMMON_CLK_GXBB=y +CONFIG_COMMON_CLK_MESON_AO_CLKC=y +CONFIG_COMMON_CLK_MESON_CPU_DYNDIV=y +CONFIG_COMMON_CLK_MESON_DUALDIV=y +CONFIG_COMMON_CLK_MESON_EE_CLKC=y +CONFIG_COMMON_CLK_MESON_MPLL=y +CONFIG_COMMON_CLK_MESON_PLL=y +CONFIG_COMMON_CLK_MESON_REGMAP=y +CONFIG_COMMON_CLK_MESON_VID_PLL_DIV=y +CONFIG_COMMON_CLK_PWM=y +CONFIG_COMMON_CLK_S2MPS11=y +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SCPI=y +CONFIG_COMMON_CLK_VC5=y +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMPAT=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONTIG_ALLOC=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CRASH_CORE=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +CONFIG_CRC7=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SIMD=y +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DEV_COREDUMP=y +CONFIG_DMADEVICES=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DMA_OF=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DNS_RESOLVER=y +CONFIG_DTC=y +CONFIG_DT_IDLE_STATES=y +CONFIG_DWMAC_GENERIC=y +CONFIG_DWMAC_MESON=y +CONFIG_DW_WATCHDOG=y +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +# CONFIG_EDAC_DMC520 is not set +CONFIG_EDAC_LEGACY_SYSFS=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC_THUNDERX is not set +# CONFIG_EDAC_XGENE is not set +CONFIG_ENERGY_MODEL=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXTCON=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_F2FS_FS=y +CONFIG_FAILOVER=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_FAT_FS=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SIMPLE=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FRAME_POINTER=y +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GARP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_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_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=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=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SNAPSHOT_DEV=y +CONFIG_HOLES_IN_ZONE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +CONFIG_HWMON=y +# CONFIG_HWPOISON_INJECT is not set +CONFIG_HWSPINLOCK=y +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_MESON=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_SLAVE=y +# CONFIG_I2C_SLAVE_TESTUNIT is not set +CONFIG_IIO=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INDIRECT_PIO=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INTERCONNECT=y +CONFIG_INTERVAL_TREE=y +CONFIG_IOMMU_API=y +CONFIG_IPC_NS=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_IRQCHIP=y +CONFIG_IRQ_BYPASS_MANAGER=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_POLL=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_JUMP_LABEL=y +CONFIG_KALLSYMS=y +CONFIG_KEXEC=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC_FILE=y +CONFIG_KEYS=y +CONFIG_KSM=y +CONFIG_KVM=y +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_KVM_MMIO=y +CONFIG_KVM_VFIO=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MD=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX_MESON_G12A=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MDIO_GPIO is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_KMEM=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MEMORY_BALLOON=y +CONFIG_MEMORY_FAILURE=y +CONFIG_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE is not set +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_MEMTEST=y +# CONFIG_MESON_CANVAS is not set +CONFIG_MESON_CLK_MEASURE=y +CONFIG_MESON_EE_PM_DOMAINS=y +CONFIG_MESON_GXBB_WATCHDOG=y +CONFIG_MESON_GXL_PHY=y +CONFIG_MESON_GX_PM_DOMAINS=y +CONFIG_MESON_GX_SOCINFO=y +CONFIG_MESON_IRQ_GPIO=y +CONFIG_MESON_MX_SOCINFO=y +CONFIG_MESON_SARADC=y +CONFIG_MESON_SECURE_PM_DOMAINS=y +CONFIG_MESON_SM=y +# CONFIG_MESON_WATCHDOG is not set +CONFIG_MFD_CORE=y +CONFIG_MFD_SEC_CORE=y +CONFIG_MFD_SYSCON=y +CONFIG_MFD_VEXPRESS_SYSREG=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_DW=y +# CONFIG_MMC_DW_BLUEFIELD is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_K3 is not set +# CONFIG_MMC_DW_PCI is not set +CONFIG_MMC_DW_PLTFM=y +CONFIG_MMC_MESON_GX=y +# CONFIG_MMC_MESON_MX_SDIO is not set +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_OF_DWCMSHC=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MRP=y +CONFIG_MULTIPLEXER=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_MUX_MMIO=y +CONFIG_MV_XOR_V2=y +CONFIG_NAMESPACES=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NETFILTER=y +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_FAILOVER=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_NS=y +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=256 +CONFIG_NVMEM=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_OF_NET=y +CONFIG_OID_REGISTRY=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OPTEE=y +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 +CONFIG_PADATA=y +CONFIG_PAGE_COUNTER=y +CONFIG_PAGE_REPORTING=y +CONFIG_PARAVIRT=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_PME=y +CONFIG_PCI_HOST_COMMON=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PASID=y +CONFIG_PCS_XPCS=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_MESON8B_USB2=y +CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y +CONFIG_PHY_MESON_AXG_PCIE=y +CONFIG_PHY_MESON_G12A_USB2=y +CONFIG_PHY_MESON_G12A_USB3_PCIE=y +CONFIG_PHY_MESON_GXL_USB2=y +CONFIG_PHY_SAMSUNG_USB2=y +CONFIG_PHY_XGENE=y +CONFIG_PID_NS=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MESON=y +CONFIG_PINCTRL_MESON8_PMX=y +CONFIG_PINCTRL_MESON_A1=y +CONFIG_PINCTRL_MESON_AXG=y +CONFIG_PINCTRL_MESON_AXG_PMX=y +CONFIG_PINCTRL_MESON_G12A=y +CONFIG_PINCTRL_MESON_GXBB=y +CONFIG_PINCTRL_MESON_GXL=y +CONFIG_PL330_DMA=y +CONFIG_PLATFORM_MHU=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_DEVFREQ=y +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +# CONFIG_POWER_RESET_VEXPRESS is not set +CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +CONFIG_PSTORE=y +CONFIG_PWM=y +CONFIG_PWM_MESON=y +CONFIG_PWM_SYSFS=y +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_MODULE_REGION_FULL=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REALTEK_PHY=y +CONFIG_REBOOT_MODE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_PWM=y +CONFIG_RELOCATABLE=y +CONFIG_REMOTEPROC=y +# CONFIG_REMOTEPROC_CDEV is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_MESON=y +# CONFIG_RESET_MESON_AUDIO_ARB is not set +CONFIG_RESET_SCMI=y +CONFIG_RFS_ACCEL=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_RPMSG=y +# CONFIG_RPMSG_CHAR is not set +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MESON_VRTC=y +# CONFIG_RTC_DRV_S5M is not set +CONFIG_RTC_I2C_AND_SPI=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_SATA_HOST=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_SCHED_INFO=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI=y +CONFIG_SCSI_HISI_SAS=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_UFSHCD=y +# CONFIG_SCSI_UFSHCD_PCI is not set +CONFIG_SCSI_UFSHCD_PLATFORM=y +# CONFIG_SCSI_UFS_BSG is not set +# CONFIG_SCSI_UFS_CDNS_PLATFORM is not set +# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set +CONFIG_SECURITY=y +# CONFIG_SECURITY_NETWORK is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_MESON=y +CONFIG_SERIAL_MESON_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_SOC_BRCMSTB=y +CONFIG_SOC_BUS=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +# CONFIG_SPI_MESON_SPICC is not set +# CONFIG_SPI_MESON_SPIFC is not set +CONFIG_SRAM=y +CONFIG_SRCU=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_TCG_TPM=y +CONFIG_TEE=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_TIME_NS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_TUN=y +# CONFIG_UACCE is not set +# CONFIG_UCLAMP_TASK is not set +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_USB=y +CONFIG_USB_BDC_UDC=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_COMMON=y +CONFIG_USB_CONN_GPIO=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_DUAL_ROLE=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_DUAL_ROLE=y +# CONFIG_USB_DWC3_GADGET is not set +# CONFIG_USB_DWC3_HOST is not set +CONFIG_USB_DWC3_MESON_G12A=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_GADGET=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_ISP1760=y +CONFIG_USB_ISP1760_DUAL_ROLE=y +# CONFIG_USB_ISP1760_GADGET_ROLE is not set +CONFIG_USB_ISP1760_HCD=y +# CONFIG_USB_ISP1760_HOST_ROLE is not set +CONFIG_USB_ISP1761_UDC=y +CONFIG_USB_MUSB_DUAL_ROLE=y +# CONFIG_USB_MUSB_GADGET is not set +CONFIG_USB_MUSB_HDRC=y +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_OTG=y +CONFIG_USB_PHY=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_SNP_CORE=y +CONFIG_USB_SNP_UDC_PLAT=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USER_NS=y +CONFIG_UTS_NS=y +CONFIG_VEXPRESS_CONFIG=y +CONFIG_VFAT_FS=y +CONFIG_VFIO=y +CONFIG_VFIO_IOMMU_TYPE1=y +# CONFIG_VFIO_MDEV is not set +# CONFIG_VFIO_NOIOMMU is not set +CONFIG_VFIO_PCI=y +CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI_MMAP=y +# CONFIG_VFIO_PLATFORM is not set +CONFIG_VFIO_VIRQFD=y +CONFIG_VIRTIO=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_NET=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_PCI_LEGACY=y +CONFIG_VIRTUALIZATION=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_VMAP_STACK=y +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XARRAY_MULTI=y +CONFIG_XPS=y +CONFIG_XXHASH=y +# CONFIG_ZONE_DEVICE is not set +CONFIG_ZONE_DMA32=y diff --git a/target/linux/amlogic/mesongx/target.mk b/target/linux/amlogic/mesongx/target.mk new file mode 100644 index 000000000..34d1a58c6 --- /dev/null +++ b/target/linux/amlogic/mesongx/target.mk @@ -0,0 +1,12 @@ +ARCH:=aarch64 +CPU_TYPE:=cortex-a53 +BOARDNAME:=Amlogic S905x boards (64 bit) + +KERNEL_PATCHVER:=5.15 + +DEFAULT_PACKAGES+=ethtool parted kmod-fb + +define Target/Description + Build firmware image for Amlogic S905x devices. + This firmware features a 64 bit kernel. +endef diff --git a/target/linux/amlogic/modules.mk b/target/linux/amlogic/modules.mk new file mode 100644 index 000000000..6866241a0 --- /dev/null +++ b/target/linux/amlogic/modules.mk @@ -0,0 +1,15 @@ +define Package/brcmfmac-firmware-43455-sdio-phicomm-n1 + SECTION:=firmware + CATEGORY:=Firmware + TITLE:=Broadcom BCM43455 firmware for Phicomm N1 + VERSION:=1.0.0 + DEPENDS:=+brcmfmac-firmware-43455-sdio +brcmfmac-nvram-43455-sdio +endef + +define Package/brcmfmac-firmware-43455-sdio-phicomm-n1/install + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) brcmfmac43455-sdio.raspberrypi,4-model-b.txt $(1)/lib/firmware/brcm/brcmfmac43455-sdio.phicomm,n1.txt + $(LN) brcmfmac43455-sdio.bin $(1)/lib/firmware/brcm/brcmfmac43455-sdio.phicomm,n1.bin + $(LN) brcmfmac43455-sdio.clm_blob $(1)/lib/firmware/brcm/brcmfmac43455-sdio.phicomm,n1.clm_blob +endef +$(eval $(call BuildPackage,brcmfmac-firmware-43455-sdio-phicomm-n1)) diff --git a/target/linux/amlogic/patches-5.15/001-dts-s905d-fix-high-load.patch b/target/linux/amlogic/patches-5.15/001-dts-s905d-fix-high-load.patch new file mode 100644 index 000000000..0e2045d00 --- /dev/null +++ b/target/linux/amlogic/patches-5.15/001-dts-s905d-fix-high-load.patch @@ -0,0 +1,16 @@ +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -86,8 +86,7 @@ + reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; + + interrupt-parent = <&gpio_intc>; +- interrupts = <29 IRQ_TYPE_LEVEL_LOW>; +- eee-broken-1000t; ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; + }; + }; + diff --git a/target/linux/amlogic/patches-5.15/002-dts-improve-phicomm-n1-support.patch b/target/linux/amlogic/patches-5.15/002-dts-improve-phicomm-n1-support.patch new file mode 100644 index 000000000..c73ebea11 --- /dev/null +++ b/target/linux/amlogic/patches-5.15/002-dts-improve-phicomm-n1-support.patch @@ -0,0 +1,48 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts +@@ -10,6 +10,17 @@ + / { + compatible = "phicomm,n1", "amlogic,s905d", "amlogic,meson-gxl"; + model = "Phicomm N1"; ++ ++ aliases { ++ mmc0 = &sd_emmc_b; ++ mmc1 = &sd_emmc_c; ++ mmc2 = &sd_emmc_a; ++ ++ led-boot = &led_work; ++ led-failsafe = &led_work; ++ led-running = &led_work; ++ led-upgrade = &led_work; ++ }; + + cvbs-connector { + status = "disabled"; +@@ -18,7 +29,7 @@ + leds { + compatible = "gpio-leds"; + +- led { ++ led_work: led { + label = "n1:white:status"; + gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; + default-state = "on"; +@@ -33,3 +44,18 @@ + &usb { + dr_mode = "host"; + }; ++ ++&sd_emmc_a { ++ max-frequency = <80000000>; ++ sd-uhs-ddr50; ++}; ++ ++&sd_emmc_b { ++ status = "disabled"; ++}; ++ ++ðmac { ++ snps,aal; ++ snps,txpbl = <0x8>; ++ snps,rxpbl = <0x8>; ++}; diff --git a/target/linux/meson/patches-6.1/902-use-system-LED-for-OpenWrt.patch b/target/linux/amlogic/patches-6.1/902-use-system-LED-for-OpenWrt.patch similarity index 100% rename from target/linux/meson/patches-6.1/902-use-system-LED-for-OpenWrt.patch rename to target/linux/amlogic/patches-6.1/902-use-system-LED-for-OpenWrt.patch diff --git a/target/linux/meson/patches-6.1/903-add-dts-and-identify-emmc.patch b/target/linux/amlogic/patches-6.1/903-add-dts-and-identify-emmc.patch similarity index 100% rename from target/linux/meson/patches-6.1/903-add-dts-and-identify-emmc.patch rename to target/linux/amlogic/patches-6.1/903-add-dts-and-identify-emmc.patch diff --git a/target/linux/meson/patches-6.1/905-pwm-meson-modify-and-simplify-calculation-in.patch b/target/linux/amlogic/patches-6.1/905-pwm-meson-modify-and-simplify-calculation-in.patch similarity index 100% rename from target/linux/meson/patches-6.1/905-pwm-meson-modify-and-simplify-calculation-in.patch rename to target/linux/amlogic/patches-6.1/905-pwm-meson-modify-and-simplify-calculation-in.patch diff --git a/target/linux/bcm27xx/patches-6.1/950-0025-drm-panel-Add-and-initialise-an-orientation-field-to.patch b/target/linux/bcm27xx/patches-6.1/950-0025-drm-panel-Add-and-initialise-an-orientation-field-to.patch index 9cdbe6d7c..67c1e1826 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0025-drm-panel-Add-and-initialise-an-orientation-field-to.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0025-drm-panel-Add-and-initialise-an-orientation-field-to.patch @@ -46,7 +46,7 @@ Signed-off-by: Dave Stevenson } EXPORT_SYMBOL(drm_panel_init); -@@ -289,16 +292,18 @@ int of_drm_get_panel_orientation(const s +@@ -294,16 +297,18 @@ int of_drm_get_panel_orientation(const s if (ret < 0) return ret; diff --git a/target/linux/bcm27xx/patches-6.1/950-0035-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch b/target/linux/bcm27xx/patches-6.1/950-0035-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch index 1e54e6130..7bda98e6e 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0035-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0035-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch @@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c -@@ -368,6 +368,8 @@ struct drm_bridge *devm_drm_panel_bridge +@@ -371,6 +371,8 @@ struct drm_bridge *devm_drm_panel_bridge devres_free(ptr); } diff --git a/target/linux/bcm27xx/patches-6.1/950-0038-drm-vc4-Support-zpos-on-all-planes.patch b/target/linux/bcm27xx/patches-6.1/950-0038-drm-vc4-Support-zpos-on-all-planes.patch index 068862766..cc8310bf6 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0038-drm-vc4-Support-zpos-on-all-planes.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0038-drm-vc4-Support-zpos-on-all-planes.patch @@ -88,7 +88,7 @@ Signed-off-by: Dave Stevenson if (ret) --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -1600,9 +1600,14 @@ struct drm_plane *vc4_plane_init(struct +@@ -1597,9 +1597,14 @@ struct drm_plane *vc4_plane_init(struct DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); @@ -103,7 +103,7 @@ Signed-off-by: Dave Stevenson int vc4_plane_create_additional_planes(struct drm_device *drm) { struct drm_plane *cursor_plane; -@@ -1618,24 +1623,35 @@ int vc4_plane_create_additional_planes(s +@@ -1615,24 +1620,35 @@ int vc4_plane_create_additional_planes(s * modest number of planes to expose, that should hopefully * still cover any sane usecase. */ diff --git a/target/linux/bcm27xx/patches-6.1/950-0043-vc4-drm-plane-Make-use-of-chroma-siting-parameter.patch b/target/linux/bcm27xx/patches-6.1/950-0043-vc4-drm-plane-Make-use-of-chroma-siting-parameter.patch index b5ebb28bb..fb648b1fc 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0043-vc4-drm-plane-Make-use-of-chroma-siting-parameter.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0043-vc4-drm-plane-Make-use-of-chroma-siting-parameter.patch @@ -49,7 +49,7 @@ Signed-off-by: Dom Cobley vc4_dlist_write(vc4_state, 0xc0c0c0c0); } -@@ -1649,6 +1652,8 @@ struct drm_plane *vc4_plane_init(struct +@@ -1646,6 +1649,8 @@ struct drm_plane *vc4_plane_init(struct DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); diff --git a/target/linux/bcm27xx/patches-6.1/950-0051-drm-vc4-Add-3-3-2-and-4-4-4-4-RGB-RGBX-RGBA-formats.patch b/target/linux/bcm27xx/patches-6.1/950-0051-drm-vc4-Add-3-3-2-and-4-4-4-4-RGB-RGBX-RGBA-formats.patch index c4e005058..2cd79eac1 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0051-drm-vc4-Add-3-3-2-and-4-4-4-4-RGB-RGBX-RGBA-formats.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0051-drm-vc4-Add-3-3-2-and-4-4-4-4-RGB-RGBX-RGBA-formats.patch @@ -85,7 +85,7 @@ Signed-off-by: Dave Stevenson }; static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) -@@ -1575,6 +1635,16 @@ static bool vc4_format_mod_supported(str +@@ -1572,6 +1632,16 @@ static bool vc4_format_mod_supported(str case DRM_FORMAT_BGRX1010102: case DRM_FORMAT_RGBA1010102: case DRM_FORMAT_BGRA1010102: diff --git a/target/linux/bcm27xx/patches-6.1/950-0080-Revert-net-bcmgenet-Request-APD-DLL-disable-and-IDDQ.patch b/target/linux/bcm27xx/patches-6.1/950-0080-Revert-net-bcmgenet-Request-APD-DLL-disable-and-IDDQ.patch index 9a29d6179..57a59c1ae 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0080-Revert-net-bcmgenet-Request-APD-DLL-disable-and-IDDQ.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0080-Revert-net-bcmgenet-Request-APD-DLL-disable-and-IDDQ.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c -@@ -290,9 +290,7 @@ int bcmgenet_mii_probe(struct net_device +@@ -303,9 +303,7 @@ int bcmgenet_mii_probe(struct net_device struct device_node *dn = kdev->of_node; phy_interface_t phy_iface = priv->phy_interface; struct phy_device *phydev; diff --git a/target/linux/bcm27xx/patches-6.1/950-0081-smsx95xx-fix-crimes-against-truesize.patch b/target/linux/bcm27xx/patches-6.1/950-0081-smsx95xx-fix-crimes-against-truesize.patch deleted file mode 100644 index 98a6ed86b..000000000 --- a/target/linux/bcm27xx/patches-6.1/950-0081-smsx95xx-fix-crimes-against-truesize.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 648c906a27d3713f589717f4be36583fc64f2ba1 Mon Sep 17 00:00:00 2001 -From: Steve Glendinning -Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH] smsx95xx: fix crimes against truesize - -smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. - -This patch stops smsc95xx from changing truesize. - -Signed-off-by: Steve Glendinning ---- - drivers/net/usb/smsc95xx.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -79,6 +79,10 @@ static bool turbo_mode = true; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -+static bool truesize_mode = false; -+module_param(truesize_mode, bool, 0644); -+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); -+ - static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, - u32 *data) - { -@@ -1870,7 +1874,8 @@ static int smsc95xx_rx_fixup(struct usbn - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(skb); - skb_trim(skb, skb->len - 4); /* remove fcs */ -- skb->truesize = size + sizeof(struct sk_buff); -+ if (truesize_mode) -+ skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } -@@ -1888,7 +1893,8 @@ static int smsc95xx_rx_fixup(struct usbn - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(ax_skb); - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ -- ax_skb->truesize = size + sizeof(struct sk_buff); -+ if (truesize_mode) -+ ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } diff --git a/target/linux/bcm27xx/patches-6.1/950-0082-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch b/target/linux/bcm27xx/patches-6.1/950-0082-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch index c55f194b2..593e5eb45 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0082-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0082-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch @@ -11,9 +11,9 @@ See: http://forum.kodi.tv/showthread.php?tid=285288 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -83,6 +83,10 @@ static bool truesize_mode = false; - module_param(truesize_mode, bool, 0644); - MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); +@@ -79,6 +79,10 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); +static int packetsize = 2560; +module_param(packetsize, int, 0644); @@ -22,7 +22,7 @@ See: http://forum.kodi.tv/showthread.php?tid=285288 static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data) { -@@ -936,13 +940,13 @@ static int smsc95xx_reset(struct usbnet +@@ -932,13 +936,13 @@ static int smsc95xx_reset(struct usbnet if (!turbo_mode) { burst_cap = 0; diff --git a/target/linux/bcm27xx/patches-6.1/950-0083-Allow-mac-address-to-be-set-in-smsc95xx.patch b/target/linux/bcm27xx/patches-6.1/950-0083-Allow-mac-address-to-be-set-in-smsc95xx.patch index a47a858e1..d9035fddb 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0083-Allow-mac-address-to-be-set-in-smsc95xx.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0083-Allow-mac-address-to-be-set-in-smsc95xx.patch @@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -87,6 +87,10 @@ static int packetsize = 2560; +@@ -83,6 +83,10 @@ static int packetsize = 2560; module_param(packetsize, int, 0644); MODULE_PARM_DESC(packetsize, "Override the RX URB packet size"); @@ -33,7 +33,7 @@ Signed-off-by: Phil Elwell static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data) { -@@ -809,6 +813,52 @@ static int smsc95xx_ioctl(struct net_dev +@@ -805,6 +809,52 @@ static int smsc95xx_ioctl(struct net_dev return phy_mii_ioctl(netdev->phydev, rq, cmd); } @@ -86,7 +86,7 @@ Signed-off-by: Phil Elwell static void smsc95xx_init_mac_address(struct usbnet *dev) { u8 addr[ETH_ALEN]; -@@ -832,6 +882,10 @@ static void smsc95xx_init_mac_address(st +@@ -828,6 +878,10 @@ static void smsc95xx_init_mac_address(st } } diff --git a/target/linux/bcm27xx/patches-6.1/950-0106-Add-dwc_otg-driver.patch b/target/linux/bcm27xx/patches-6.1/950-0106-Add-dwc_otg-driver.patch index f8ab3b04a..89ed66656 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0106-Add-dwc_otg-driver.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0106-Add-dwc_otg-driver.patch @@ -1185,7 +1185,7 @@ Signed-off-by: Jonathan Bell } --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -5677,7 +5677,7 @@ static void port_event(struct usb_hub *h +@@ -5698,7 +5698,7 @@ static void port_event(struct usb_hub *h port_dev->over_current_count++; port_over_current_notify(port_dev); diff --git a/target/linux/bcm27xx/patches-6.1/950-0111-MMC-added-alternative-MMC-driver.patch b/target/linux/bcm27xx/patches-6.1/950-0111-MMC-added-alternative-MMC-driver.patch index 476a3caf3..c50177898 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0111-MMC-added-alternative-MMC-driver.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0111-MMC-added-alternative-MMC-driver.patch @@ -266,7 +266,7 @@ Signed-off-by: Phil Elwell static inline int mmc_blk_part_switch(struct mmc_card *card, unsigned int part_type); static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, -@@ -3040,6 +3047,8 @@ static int mmc_blk_probe(struct mmc_card +@@ -3042,6 +3049,8 @@ static int mmc_blk_probe(struct mmc_card { struct mmc_blk_data *md; int ret = 0; @@ -275,7 +275,7 @@ Signed-off-by: Phil Elwell /* * Check that the card supports the command class(es) we need. -@@ -3047,7 +3056,16 @@ static int mmc_blk_probe(struct mmc_card +@@ -3049,7 +3058,16 @@ static int mmc_blk_probe(struct mmc_card if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; @@ -293,7 +293,7 @@ Signed-off-by: Phil Elwell card->complete_wq = alloc_workqueue("mmc_complete", WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); -@@ -3062,6 +3080,17 @@ static int mmc_blk_probe(struct mmc_card +@@ -3064,6 +3082,17 @@ static int mmc_blk_probe(struct mmc_card goto out_free; } diff --git a/target/linux/bcm27xx/patches-6.1/950-0118-firmware-bcm2835-Support-ARCH_BCM270x.patch b/target/linux/bcm27xx/patches-6.1/950-0118-firmware-bcm2835-Support-ARCH_BCM270x.patch index 3b847b561..3b32562b4 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0118-firmware-bcm2835-Support-ARCH_BCM270x.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0118-firmware-bcm2835-Support-ARCH_BCM270x.patch @@ -27,7 +27,7 @@ Signed-off-by: Noralf Trønnes --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -32,6 +32,8 @@ struct rpi_firmware { +@@ -33,6 +33,8 @@ struct rpi_firmware { struct kref consumers; }; @@ -36,7 +36,7 @@ Signed-off-by: Noralf Trønnes static DEFINE_MUTEX(transaction_lock); static void response_callback(struct mbox_client *cl, void *msg) -@@ -280,6 +282,7 @@ static int rpi_firmware_probe(struct pla +@@ -281,6 +283,7 @@ static int rpi_firmware_probe(struct pla kref_init(&fw->consumers); platform_set_drvdata(pdev, fw); @@ -44,7 +44,7 @@ Signed-off-by: Noralf Trønnes rpi_firmware_print_firmware_revision(fw); rpi_register_hwmon_driver(dev, fw); -@@ -308,6 +311,7 @@ static int rpi_firmware_remove(struct pl +@@ -309,6 +312,7 @@ static int rpi_firmware_remove(struct pl rpi_clk = NULL; rpi_firmware_put(fw); @@ -52,7 +52,7 @@ Signed-off-by: Noralf Trønnes return 0; } -@@ -382,7 +386,18 @@ static struct platform_driver rpi_firmwa +@@ -383,7 +387,18 @@ static struct platform_driver rpi_firmwa .shutdown = rpi_firmware_shutdown, .remove = rpi_firmware_remove, }; diff --git a/target/linux/bcm27xx/patches-6.1/950-0119-leds-Add-the-input-trigger-for-pwr_led.patch b/target/linux/bcm27xx/patches-6.1/950-0119-leds-Add-the-input-trigger-for-pwr_led.patch index e5e5a8a1b..4d30fab65 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0119-leds-Add-the-input-trigger-for-pwr_led.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0119-leds-Add-the-input-trigger-for-pwr_led.patch @@ -156,7 +156,7 @@ See: https://github.com/raspberrypi/linux/issues/1064 +MODULE_LICENSE("GPL"); --- a/include/linux/leds.h +++ b/include/linux/leds.h -@@ -85,6 +85,9 @@ struct led_classdev { +@@ -95,6 +95,9 @@ struct led_classdev { #define LED_BRIGHT_HW_CHANGED BIT(21) #define LED_RETAIN_AT_SHUTDOWN BIT(22) #define LED_INIT_DEFAULT_TRIGGER BIT(23) diff --git a/target/linux/bcm27xx/patches-6.1/950-0124-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.1/950-0124-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch index 3b5bfaa7e..e384710da 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0124-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0124-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch @@ -17578,7 +17578,7 @@ Signed-off-by: Ashish Vara +#endif /* _TAS5713_H */ --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c -@@ -1220,7 +1220,15 @@ int snd_soc_runtime_set_dai_fmt(struct s +@@ -1223,7 +1223,15 @@ int snd_soc_runtime_set_dai_fmt(struct s return 0; for_each_rtd_codec_dais(rtd, i, codec_dai) { diff --git a/target/linux/bcm27xx/patches-6.1/950-0140-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch b/target/linux/bcm27xx/patches-6.1/950-0140-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch index 90408f491..8a9a2da72 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0140-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0140-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch @@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -12,6 +12,7 @@ +@@ -13,6 +13,7 @@ #include #include #include @@ -21,7 +21,7 @@ Signed-off-by: Phil Elwell #include #include -@@ -179,6 +180,26 @@ int rpi_firmware_property(struct rpi_fir +@@ -180,6 +181,26 @@ int rpi_firmware_property(struct rpi_fir } EXPORT_SYMBOL_GPL(rpi_firmware_property); @@ -48,7 +48,7 @@ Signed-off-by: Phil Elwell static void rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) { -@@ -387,15 +408,32 @@ static struct platform_driver rpi_firmwa +@@ -388,15 +409,32 @@ static struct platform_driver rpi_firmwa .remove = rpi_firmware_remove, }; diff --git a/target/linux/bcm27xx/patches-6.1/950-0145-firmware-raspberrypi-Add-backward-compatible-get_thr.patch b/target/linux/bcm27xx/patches-6.1/950-0145-firmware-raspberrypi-Add-backward-compatible-get_thr.patch index 1f62f7f54..2b5a9fc3f 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0145-firmware-raspberrypi-Add-backward-compatible-get_thr.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0145-firmware-raspberrypi-Add-backward-compatible-get_thr.patch @@ -16,7 +16,7 @@ Signed-off-by: Stefan Wahren --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -31,6 +31,7 @@ struct rpi_firmware { +@@ -32,6 +32,7 @@ struct rpi_firmware { u32 enabled; struct kref consumers; @@ -24,7 +24,7 @@ Signed-off-by: Stefan Wahren }; static struct platform_device *g_pdev; -@@ -176,6 +177,12 @@ int rpi_firmware_property(struct rpi_fir +@@ -177,6 +178,12 @@ int rpi_firmware_property(struct rpi_fir kfree(data); @@ -37,7 +37,7 @@ Signed-off-by: Stefan Wahren return ret; } EXPORT_SYMBOL_GPL(rpi_firmware_property); -@@ -200,6 +207,27 @@ static int rpi_firmware_notify_reboot(st +@@ -201,6 +208,27 @@ static int rpi_firmware_notify_reboot(st return 0; } @@ -65,7 +65,7 @@ Signed-off-by: Stefan Wahren static void rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) { -@@ -229,6 +257,11 @@ rpi_register_hwmon_driver(struct device +@@ -230,6 +258,11 @@ rpi_register_hwmon_driver(struct device rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon", -1, NULL, 0); diff --git a/target/linux/bcm27xx/patches-6.1/950-0151-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch b/target/linux/bcm27xx/patches-6.1/950-0151-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch index 7a4b26ebd..742ae4216 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0151-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0151-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch @@ -26,7 +26,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -233,6 +233,15 @@ rpi_firmware_print_firmware_revision(str +@@ -234,6 +234,15 @@ rpi_firmware_print_firmware_revision(str { time64_t date_and_time; u32 packet; @@ -42,7 +42,7 @@ Signed-off-by: Dave Stevenson int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_FIRMWARE_REVISION, &packet, sizeof(packet)); -@@ -242,7 +251,35 @@ rpi_firmware_print_firmware_revision(str +@@ -243,7 +252,35 @@ rpi_firmware_print_firmware_revision(str /* This is not compatible with y2038 */ date_and_time = packet; @@ -79,7 +79,7 @@ Signed-off-by: Dave Stevenson } static void -@@ -339,6 +376,7 @@ static int rpi_firmware_probe(struct pla +@@ -340,6 +377,7 @@ static int rpi_firmware_probe(struct pla g_pdev = pdev; rpi_firmware_print_firmware_revision(fw); diff --git a/target/linux/bcm27xx/patches-6.1/950-0165-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch b/target/linux/bcm27xx/patches-6.1/950-0165-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch index ec5a217c7..ba8d2beed 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0165-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0165-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch @@ -13,7 +13,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1773,7 +1773,7 @@ int vchiq_mmal_component_enable(struct v +@@ -1774,7 +1774,7 @@ int vchiq_mmal_component_enable(struct v ret = enable_component(instance, component); if (ret == 0) diff --git a/target/linux/bcm27xx/patches-6.1/950-0166-staging-mmal-vchiq-Add-support-for-event-callbacks.patch b/target/linux/bcm27xx/patches-6.1/950-0166-staging-mmal-vchiq-Add-support-for-event-callbacks.patch index 743c757dd..01a4d49fa 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0166-staging-mmal-vchiq-Add-support-for-event-callbacks.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0166-staging-mmal-vchiq-Add-support-for-event-callbacks.patch @@ -234,7 +234,7 @@ Signed-off-by: Dave Stevenson /* deals with receipt of buffer to host message */ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, struct mmal_msg *msg, u32 msg_len) -@@ -1330,6 +1423,7 @@ static int port_disable(struct vchiq_mma +@@ -1331,6 +1424,7 @@ static int port_disable(struct vchiq_mma mmalbuf->mmal_flags = 0; mmalbuf->dts = MMAL_TIME_UNKNOWN; mmalbuf->pts = MMAL_TIME_UNKNOWN; @@ -242,7 +242,7 @@ Signed-off-by: Dave Stevenson port->buffer_cb(instance, port, 0, mmalbuf); } -@@ -1631,6 +1725,43 @@ int mmal_vchi_buffer_cleanup(struct mmal +@@ -1632,6 +1726,43 @@ int mmal_vchi_buffer_cleanup(struct mmal } EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); @@ -286,7 +286,7 @@ Signed-off-by: Dave Stevenson /* Initialise a mmal component and its ports * */ -@@ -1680,6 +1811,7 @@ int vchiq_mmal_component_init(struct vch +@@ -1681,6 +1812,7 @@ int vchiq_mmal_component_init(struct vch ret = port_info_get(instance, &component->control); if (ret < 0) goto release_component; @@ -294,7 +294,7 @@ Signed-off-by: Dave Stevenson for (idx = 0; idx < component->inputs; idx++) { component->input[idx].type = MMAL_PORT_TYPE_INPUT; -@@ -1690,6 +1822,7 @@ int vchiq_mmal_component_init(struct vch +@@ -1691,6 +1823,7 @@ int vchiq_mmal_component_init(struct vch ret = port_info_get(instance, &component->input[idx]); if (ret < 0) goto release_component; @@ -302,7 +302,7 @@ Signed-off-by: Dave Stevenson } for (idx = 0; idx < component->outputs; idx++) { -@@ -1701,6 +1834,7 @@ int vchiq_mmal_component_init(struct vch +@@ -1702,6 +1835,7 @@ int vchiq_mmal_component_init(struct vch ret = port_info_get(instance, &component->output[idx]); if (ret < 0) goto release_component; @@ -310,7 +310,7 @@ Signed-off-by: Dave Stevenson } for (idx = 0; idx < component->clocks; idx++) { -@@ -1712,6 +1846,7 @@ int vchiq_mmal_component_init(struct vch +@@ -1713,6 +1847,7 @@ int vchiq_mmal_component_init(struct vch ret = port_info_get(instance, &component->clock[idx]); if (ret < 0) goto release_component; @@ -318,7 +318,7 @@ Signed-off-by: Dave Stevenson } *component_out = component; -@@ -1737,7 +1872,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i +@@ -1738,7 +1873,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, struct vchiq_mmal_component *component) { @@ -327,7 +327,7 @@ Signed-off-by: Dave Stevenson if (mutex_lock_interruptible(&instance->vchiq_mutex)) return -EINTR; -@@ -1749,6 +1884,13 @@ int vchiq_mmal_component_finalise(struct +@@ -1750,6 +1885,13 @@ int vchiq_mmal_component_finalise(struct component->in_use = 0; diff --git a/target/linux/bcm27xx/patches-6.1/950-0172-staging-mmal-vchiq-Free-the-event-context-for-contro.patch b/target/linux/bcm27xx/patches-6.1/950-0172-staging-mmal-vchiq-Free-the-event-context-for-contro.patch index 02b8ed941..862592856 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0172-staging-mmal-vchiq-Free-the-event-context-for-contro.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0172-staging-mmal-vchiq-Free-the-event-context-for-contro.patch @@ -17,7 +17,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1899,6 +1899,8 @@ int vchiq_mmal_component_finalise(struct +@@ -1900,6 +1900,8 @@ int vchiq_mmal_component_finalise(struct for (idx = 0; idx < component->clocks; idx++) free_event_context(&component->clock[idx]); diff --git a/target/linux/bcm27xx/patches-6.1/950-0173-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch b/target/linux/bcm27xx/patches-6.1/950-0173-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch index 6582bcceb..c14f6c080 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0173-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0173-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch @@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1765,9 +1765,26 @@ static void free_event_context(struct vc +@@ -1766,9 +1766,26 @@ static void free_event_context(struct vc { struct mmal_msg_context *ctx = port->event_context; @@ -41,7 +41,7 @@ Signed-off-by: Dave Stevenson } /* Initialise a mmal component and its ports -@@ -1865,6 +1882,7 @@ int vchiq_mmal_component_init(struct vch +@@ -1866,6 +1883,7 @@ int vchiq_mmal_component_init(struct vch release_component: destroy_component(instance, component); @@ -49,7 +49,7 @@ Signed-off-by: Dave Stevenson unlock: if (component) component->in_use = 0; -@@ -1880,7 +1898,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i +@@ -1881,7 +1899,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, struct vchiq_mmal_component *component) { @@ -58,7 +58,7 @@ Signed-off-by: Dave Stevenson if (mutex_lock_interruptible(&instance->vchiq_mutex)) return -EINTR; -@@ -1892,14 +1910,7 @@ int vchiq_mmal_component_finalise(struct +@@ -1893,14 +1911,7 @@ int vchiq_mmal_component_finalise(struct component->in_use = 0; diff --git a/target/linux/bcm27xx/patches-6.1/950-0179-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/bcm27xx/patches-6.1/950-0179-bcmgenet-Better-coalescing-parameter-defaults.patch index b805f1df3..41c619900 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0179-bcmgenet-Better-coalescing-parameter-defaults.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0179-bcmgenet-Better-coalescing-parameter-defaults.patch @@ -18,7 +18,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -2659,7 +2659,7 @@ static void bcmgenet_init_tx_ring(struct +@@ -2665,7 +2665,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX); bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX); @@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell /* Disable rate control for now */ bcmgenet_tdma_ring_writel(priv, index, flow_period_val, TDMA_FLOW_PERIOD); -@@ -4140,9 +4140,12 @@ static int bcmgenet_probe(struct platfor +@@ -4160,9 +4160,12 @@ static int bcmgenet_probe(struct platfor netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); /* Set default coalescing parameters */ diff --git a/target/linux/bcm27xx/patches-6.1/950-0180-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/bcm27xx/patches-6.1/950-0180-net-genet-enable-link-energy-detect-powerdown-for-ex.patch index cc76ba5db..44d8613b5 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0180-net-genet-enable-link-energy-detect-powerdown-for-ex.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0180-net-genet-enable-link-energy-detect-powerdown-for-ex.patch @@ -20,7 +20,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c -@@ -296,6 +296,8 @@ int bcmgenet_mii_probe(struct net_device +@@ -309,6 +309,8 @@ int bcmgenet_mii_probe(struct net_device /* Communicate the integrated PHY revision */ if (priv->internal_phy) phy_flags = priv->gphy_rev; diff --git a/target/linux/bcm27xx/patches-6.1/950-0181-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/bcm27xx/patches-6.1/950-0181-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch index 34b923fb2..3feabeaf9 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0181-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0181-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch @@ -90,10 +90,10 @@ Signed-off-by: Jonathan Bell + */ + void (*fixup_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep, int interval); - /* Returns the hardware-chosen device address */ - int (*address_device)(struct usb_hcd *, struct usb_device *udev); - /* prepares the hardware to send commands to the device */ -@@ -435,6 +440,8 @@ extern void usb_hcd_unmap_urb_setup_for_ + /* Set the hardware-chosen device address */ + int (*address_device)(struct usb_hcd *, struct usb_device *udev, + unsigned int timeout_ms); +@@ -436,6 +441,8 @@ extern void usb_hcd_unmap_urb_setup_for_ extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); extern void usb_hcd_flush_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep); diff --git a/target/linux/bcm27xx/patches-6.1/950-0182-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-6.1/950-0182-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch index 480995112..a5e08d4cc 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0182-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0182-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch @@ -15,7 +15,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1641,6 +1641,109 @@ command_cleanup: +@@ -1643,6 +1643,109 @@ command_cleanup: } /* @@ -125,7 +125,7 @@ Signed-off-by: Jonathan Bell * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it */ -@@ -5469,6 +5572,7 @@ static const struct hc_driver xhci_hc_dr +@@ -5480,6 +5583,7 @@ static const struct hc_driver xhci_hc_dr .endpoint_reset = xhci_endpoint_reset, .check_bandwidth = xhci_check_bandwidth, .reset_bandwidth = xhci_reset_bandwidth, diff --git a/target/linux/bcm27xx/patches-6.1/950-0189-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch b/target/linux/bcm27xx/patches-6.1/950-0189-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch index da60efe07..1507baa65 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0189-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0189-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch @@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell static inline void bcmgenet_writel(u32 value, void __iomem *offset) { -@@ -2490,6 +2493,11 @@ static void reset_umac(struct bcmgenet_p +@@ -2494,6 +2497,11 @@ static void reset_umac(struct bcmgenet_p bcmgenet_rbuf_ctrl_set(priv, 0); udelay(10); @@ -47,5 +47,5 @@ Signed-off-by: Phil Elwell + } + /* issue soft reset and disable MAC while updating its registers */ + spin_lock_bh(&priv->reg_lock); bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); - udelay(2); diff --git a/target/linux/bcm27xx/patches-6.1/950-0190-xhci-Use-more-event-ring-segment-table-entries.patch b/target/linux/bcm27xx/patches-6.1/950-0190-xhci-Use-more-event-ring-segment-table-entries.patch index 93f7ffde9..93a6707f4 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0190-xhci-Use-more-event-ring-segment-table-entries.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0190-xhci-Use-more-event-ring-segment-table-entries.patch @@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c -@@ -2522,9 +2522,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, +@@ -2524,9 +2524,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, * Event ring setup: Allocate a normal ring, but also setup * the event ring segment table (ERST). Section 4.9.3. */ @@ -36,7 +36,7 @@ Signed-off-by: Jonathan Bell if (!xhci->event_ring) goto fail; if (xhci_check_trb_in_td_math(xhci) < 0) -@@ -2537,7 +2539,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, +@@ -2539,7 +2541,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, /* set ERST count with the number of entries in the segment table */ val = readl(&xhci->ir_set->erst_size); val &= ERST_SIZE_MASK; @@ -47,7 +47,7 @@ Signed-off-by: Jonathan Bell val); --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1672,8 +1672,8 @@ struct urb_priv { +@@ -1678,8 +1678,8 @@ struct urb_priv { * Each segment table entry is 4*32bits long. 1K seems like an ok size: * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, * meaning 64 ring segments. diff --git a/target/linux/bcm27xx/patches-6.1/950-0216-Initialise-rpi-firmware-before-clk-bcm2835.patch b/target/linux/bcm27xx/patches-6.1/950-0216-Initialise-rpi-firmware-before-clk-bcm2835.patch index 43781f125..d07fdf05d 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0216-Initialise-rpi-firmware-before-clk-bcm2835.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0216-Initialise-rpi-firmware-before-clk-bcm2835.patch @@ -36,7 +36,7 @@ Co-authored-by: Phil Elwell MODULE_DESCRIPTION("BCM2835 clock driver"); --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -499,7 +499,7 @@ out2: +@@ -500,7 +500,7 @@ out2: out1: return ret; } diff --git a/target/linux/bcm27xx/patches-6.1/950-0227-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch b/target/linux/bcm27xx/patches-6.1/950-0227-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch index ef96ffe86..19573eda1 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0227-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0227-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch @@ -32,7 +32,7 @@ Signed-off-by: Phil Elwell --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c -@@ -3679,6 +3679,7 @@ static int spi_set_cs_timing(struct spi_ +@@ -3694,6 +3694,7 @@ static int spi_set_cs_timing(struct spi_ */ int spi_setup(struct spi_device *spi) { @@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell unsigned bad_bits, ugly_bits; int status = 0; -@@ -3699,6 +3700,14 @@ int spi_setup(struct spi_device *spi) +@@ -3714,6 +3715,14 @@ int spi_setup(struct spi_device *spi) (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) return -EINVAL; diff --git a/target/linux/bcm27xx/patches-6.1/950-0270-net-bcmgenet-Reset-RBUF-on-first-open.patch b/target/linux/bcm27xx/patches-6.1/950-0270-net-bcmgenet-Reset-RBUF-on-first-open.patch deleted file mode 100644 index e21de6f79..000000000 --- a/target/linux/bcm27xx/patches-6.1/950-0270-net-bcmgenet-Reset-RBUF-on-first-open.patch +++ /dev/null @@ -1,70 +0,0 @@ -From e857a27d5bca6269cea7a0ca0058aa8fffe90a83 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 25 Sep 2020 15:07:23 +0100 -Subject: [PATCH] net: bcmgenet: Reset RBUF on first open - -If the RBUF logic is not reset when the kernel starts then there -may be some data left over from any network boot loader. If the -64-byte packet headers are enabled then this can be fatal. - -Extend bcmgenet_dma_disable to do perform the reset, but not when -called from bcmgenet_resume in order to preserve a wake packet. - -N.B. This different handling of resume is just based on a hunch - -why else wouldn't one reset the RBUF as well as the TBUF? If this -isn't the case then it's easy to change the patch to make the RBUF -reset unconditional. - -See: https://github.com/raspberrypi/linux/issues/3850 - -Signed-off-by: Phil Elwell ---- - drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -3306,7 +3306,7 @@ static void bcmgenet_get_hw_addr(struct - } - - /* Returns a reusable dma control register value */ --static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) -+static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx) - { - unsigned int i; - u32 reg; -@@ -3331,6 +3331,14 @@ static u32 bcmgenet_dma_disable(struct b - udelay(10); - bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH); - -+ if (flush_rx) { -+ reg = bcmgenet_rbuf_ctrl_get(priv); -+ bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0)); -+ udelay(10); -+ bcmgenet_rbuf_ctrl_set(priv, reg); -+ udelay(10); -+ } -+ - return dma_ctrl; - } - -@@ -3394,8 +3402,8 @@ static int bcmgenet_open(struct net_devi - - bcmgenet_set_hw_addr(priv, dev->dev_addr); - -- /* Disable RX/TX DMA and flush TX queues */ -- dma_ctrl = bcmgenet_dma_disable(priv); -+ /* Disable RX/TX DMA and flush TX and RX queues */ -+ dma_ctrl = bcmgenet_dma_disable(priv, true); - - /* Reinitialize TDMA and RDMA and SW housekeeping */ - ret = bcmgenet_init_dma(priv); -@@ -4269,7 +4277,7 @@ static int bcmgenet_resume(struct device - bcmgenet_hfb_create_rxnfc_filter(priv, rule); - - /* Disable RX/TX DMA and flush TX queues */ -- dma_ctrl = bcmgenet_dma_disable(priv); -+ dma_ctrl = bcmgenet_dma_disable(priv, false); - - /* Reinitialize TDMA and RDMA and SW housekeeping */ - ret = bcmgenet_init_dma(priv); diff --git a/target/linux/bcm27xx/patches-6.1/950-0276-staging-mmal-vchiq-Use-vc-sm-cma-to-support-zero-cop.patch b/target/linux/bcm27xx/patches-6.1/950-0276-staging-mmal-vchiq-Use-vc-sm-cma-to-support-zero-cop.patch index bcb322d55..59ce23263 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0276-staging-mmal-vchiq-Use-vc-sm-cma-to-support-zero-cop.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0276-staging-mmal-vchiq-Use-vc-sm-cma-to-support-zero-cop.patch @@ -91,7 +91,7 @@ Signed-off-by: Dave Stevenson } else if (msg->u.buffer_from_host.buffer_header.length == 0) { /* empty buffer */ if (msg->u.buffer_from_host.buffer_header.flags & -@@ -1528,6 +1551,9 @@ int vchiq_mmal_port_parameter_set(struct +@@ -1529,6 +1552,9 @@ int vchiq_mmal_port_parameter_set(struct mutex_unlock(&instance->vchiq_mutex); @@ -101,7 +101,7 @@ Signed-off-by: Dave Stevenson return ret; } EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); -@@ -1696,6 +1722,31 @@ int vchiq_mmal_submit_buffer(struct vchi +@@ -1697,6 +1723,31 @@ int vchiq_mmal_submit_buffer(struct vchi unsigned long flags = 0; int ret; @@ -133,7 +133,7 @@ Signed-off-by: Dave Stevenson ret = buffer_from_host(instance, port, buffer); if (ret == -EINVAL) { /* Port is disabled. Queue for when it is enabled. */ -@@ -1729,6 +1780,16 @@ int mmal_vchi_buffer_cleanup(struct mmal +@@ -1730,6 +1781,16 @@ int mmal_vchi_buffer_cleanup(struct mmal release_msg_context(msg_context); buf->msg_context = NULL; diff --git a/target/linux/bcm27xx/patches-6.1/950-0281-gpio-Add-gpio-fsm-driver.patch b/target/linux/bcm27xx/patches-6.1/950-0281-gpio-Add-gpio-fsm-driver.patch index 1e0c3a0d0..7f65a3b66 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0281-gpio-Add-gpio-fsm-driver.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0281-gpio-Add-gpio-fsm-driver.patch @@ -63,7 +63,7 @@ Signed-off-by: Phil Elwell --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -1243,6 +1243,15 @@ config HTC_EGPIO +@@ -1244,6 +1244,15 @@ config HTC_EGPIO several HTC phones. It provides basic support for input pins, output pins, and IRQs. diff --git a/target/linux/bcm27xx/patches-6.1/950-0285-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch b/target/linux/bcm27xx/patches-6.1/950-0285-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch index 42cb682e0..795e6bd90 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0285-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0285-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch @@ -19,7 +19,7 @@ mechanism to be implemented for OS upgrades. --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -193,6 +193,7 @@ static int rpi_firmware_notify_reboot(st +@@ -194,6 +194,7 @@ static int rpi_firmware_notify_reboot(st { struct rpi_firmware *fw; struct platform_device *pdev = g_pdev; @@ -27,7 +27,7 @@ mechanism to be implemented for OS upgrades. if (!pdev) return 0; -@@ -201,8 +202,28 @@ static int rpi_firmware_notify_reboot(st +@@ -202,8 +203,28 @@ static int rpi_firmware_notify_reboot(st if (!fw) return 0; diff --git a/target/linux/bcm27xx/patches-6.1/950-0327-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch b/target/linux/bcm27xx/patches-6.1/950-0327-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch index db15c6580..ed242cbbe 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0327-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0327-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch @@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -674,9 +674,9 @@ deq_found: +@@ -675,9 +675,9 @@ deq_found: } if ((ep->ep_state & SET_DEQ_PENDING)) { diff --git a/target/linux/bcm27xx/patches-6.1/950-0332-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch b/target/linux/bcm27xx/patches-6.1/950-0332-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch index d0eecb7ee..fa6aaa3d1 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0332-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0332-drm-panel-simple-Add-a-timing-for-the-Raspberry-Pi-7.patch @@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c -@@ -3193,6 +3193,31 @@ static const struct panel_desc qishenglo +@@ -3196,6 +3196,31 @@ static const struct panel_desc qishenglo .connector_type = DRM_MODE_CONNECTOR_DPI, }; @@ -47,7 +47,7 @@ Signed-off-by: Dave Stevenson static const struct display_timing rocktech_rk070er9427_timing = { .pixelclock = { 26400000, 33300000, 46800000 }, .hactive = { 800, 800, 800 }, -@@ -4226,6 +4251,9 @@ static const struct of_device_id platfor +@@ -4229,6 +4254,9 @@ static const struct of_device_id platfor .compatible = "qishenglong,gopher2b-lcd", .data = &qishenglong_gopher2b_lcd, }, { diff --git a/target/linux/bcm27xx/patches-6.1/950-0339-staging-mmal-vchiq-Add-module-parameter-to-enable-lo.patch b/target/linux/bcm27xx/patches-6.1/950-0339-staging-mmal-vchiq-Add-module-parameter-to-enable-lo.patch index 31162b3ce..9fef146bf 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0339-staging-mmal-vchiq-Add-module-parameter-to-enable-lo.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0339-staging-mmal-vchiq-Add-module-parameter-to-enable-lo.patch @@ -172,7 +172,7 @@ Signed-off-by: Dave Stevenson vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1086,9 +1101,9 @@ static int create_component(struct vchiq +@@ -1087,9 +1102,9 @@ static int create_component(struct vchiq component->outputs = rmsg->u.component_create_reply.output_num; component->clocks = rmsg->u.component_create_reply.clock_num; @@ -185,7 +185,7 @@ Signed-off-by: Dave Stevenson release_msg: vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1257,10 +1272,9 @@ static int port_action_port(struct vchiq +@@ -1258,10 +1273,9 @@ static int port_action_port(struct vchiq ret = -rmsg->u.port_action_reply.status; @@ -199,7 +199,7 @@ Signed-off-by: Dave Stevenson release_msg: vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1304,11 +1318,11 @@ static int port_action_handle(struct vch +@@ -1305,11 +1319,11 @@ static int port_action_handle(struct vch ret = -rmsg->u.port_action_reply.status; @@ -216,7 +216,7 @@ Signed-off-by: Dave Stevenson release_msg: vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1347,9 +1361,9 @@ static int port_parameter_set(struct vch +@@ -1348,9 +1362,9 @@ static int port_parameter_set(struct vch ret = -rmsg->u.port_parameter_set_reply.status; @@ -229,7 +229,7 @@ Signed-off-by: Dave Stevenson release_msg: vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1407,8 +1421,9 @@ static int port_parameter_get(struct vch +@@ -1408,8 +1422,9 @@ static int port_parameter_get(struct vch /* Always report the size of the returned parameter to the caller */ *value_size = rmsg->u.port_parameter_get_reply.size; @@ -241,7 +241,7 @@ Signed-off-by: Dave Stevenson release_msg: vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle); -@@ -1665,7 +1680,7 @@ int vchiq_mmal_port_connect_tunnel(struc +@@ -1666,7 +1681,7 @@ int vchiq_mmal_port_connect_tunnel(struc if (!dst) { /* do not make new connection */ ret = 0; @@ -250,7 +250,7 @@ Signed-off-by: Dave Stevenson goto release_unlock; } -@@ -1683,14 +1698,14 @@ int vchiq_mmal_port_connect_tunnel(struc +@@ -1684,14 +1699,14 @@ int vchiq_mmal_port_connect_tunnel(struc /* set new format */ ret = port_info_set(instance, dst); if (ret) { @@ -267,7 +267,7 @@ Signed-off-by: Dave Stevenson goto release_unlock; } -@@ -1699,9 +1714,9 @@ int vchiq_mmal_port_connect_tunnel(struc +@@ -1700,9 +1715,9 @@ int vchiq_mmal_port_connect_tunnel(struc MMAL_MSG_PORT_ACTION_TYPE_CONNECT, dst->component->handle, dst->handle); if (ret < 0) { @@ -280,7 +280,7 @@ Signed-off-by: Dave Stevenson goto release_unlock; } src->connected = dst; -@@ -1726,7 +1741,8 @@ int vchiq_mmal_submit_buffer(struct vchi +@@ -1727,7 +1742,8 @@ int vchiq_mmal_submit_buffer(struct vchi * videobuf2 won't let us have the dmabuf there. */ if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) { @@ -290,7 +290,7 @@ Signed-off-by: Dave Stevenson ret = vc_sm_cma_import_dmabuf(buffer->dma_buf, &buffer->vcsm_handle); if (ret) { -@@ -1742,8 +1758,8 @@ int vchiq_mmal_submit_buffer(struct vchi +@@ -1743,8 +1759,8 @@ int vchiq_mmal_submit_buffer(struct vchi vc_sm_cma_free(buffer->vcsm_handle); return ret; } @@ -301,7 +301,7 @@ Signed-off-by: Dave Stevenson } ret = buffer_from_host(instance, port, buffer); -@@ -1782,8 +1798,8 @@ int mmal_vchi_buffer_cleanup(struct mmal +@@ -1783,8 +1799,8 @@ int mmal_vchi_buffer_cleanup(struct mmal if (buf->vcsm_handle) { int ret; diff --git a/target/linux/bcm27xx/patches-6.1/950-0340-staging-mmal-vchiq-Reset-buffers_with_vpu-on-port_en.patch b/target/linux/bcm27xx/patches-6.1/950-0340-staging-mmal-vchiq-Reset-buffers_with_vpu-on-port_en.patch index 46414dc74..8b7eb58b7 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0340-staging-mmal-vchiq-Reset-buffers_with_vpu-on-port_en.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0340-staging-mmal-vchiq-Reset-buffers_with_vpu-on-port_en.patch @@ -20,7 +20,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1500,6 +1500,8 @@ static int port_enable(struct vchiq_mmal +@@ -1501,6 +1501,8 @@ static int port_enable(struct vchiq_mmal port->enabled = 1; diff --git a/target/linux/bcm27xx/patches-6.1/950-0359-xhci-quirks-add-link-TRB-quirk-for-VL805.patch b/target/linux/bcm27xx/patches-6.1/950-0359-xhci-quirks-add-link-TRB-quirk-for-VL805.patch index 073bb8be7..305480492 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0359-xhci-quirks-add-link-TRB-quirk-for-VL805.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0359-xhci-quirks-add-link-TRB-quirk-for-VL805.patch @@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -293,8 +293,10 @@ static void xhci_pci_quirks(struct devic +@@ -300,8 +300,10 @@ static void xhci_pci_quirks(struct devic pdev->device == 0x3432) xhci->quirks |= XHCI_BROKEN_STREAMS; @@ -36,7 +36,7 @@ Signed-off-by: Jonathan Bell pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -664,6 +664,15 @@ static int xhci_move_dequeue_past_td(str +@@ -665,6 +665,15 @@ static int xhci_move_dequeue_past_td(str } while (!cycle_found || !td_last_trb_found); deq_found: @@ -54,7 +54,7 @@ Signed-off-by: Jonathan Bell addr = xhci_trb_virt_to_dma(new_seg, new_deq); --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1902,6 +1902,7 @@ struct xhci_hcd { +@@ -1908,6 +1908,7 @@ struct xhci_hcd { #define XHCI_RESET_TO_DEFAULT BIT_ULL(44) #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) #define XHCI_ZHAOXIN_HOST BIT_ULL(46) diff --git a/target/linux/bcm27xx/patches-6.1/950-0361-xhci-refactor-out-TRBS_PER_SEGMENT-define-in-runtime.patch b/target/linux/bcm27xx/patches-6.1/950-0361-xhci-refactor-out-TRBS_PER_SEGMENT-define-in-runtime.patch index ab76ad76c..f8e7a13da 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0361-xhci-refactor-out-TRBS_PER_SEGMENT-define-in-runtime.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0361-xhci-refactor-out-TRBS_PER_SEGMENT-define-in-runtime.patch @@ -144,7 +144,7 @@ Signed-off-by: Jonathan Bell if (ret) return -ENOMEM; -@@ -1811,7 +1815,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhc +@@ -1813,7 +1817,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhc for (val = 0; val < evt_ring->num_segs; val++) { entry = &erst->entries[val]; entry->seg_addr = cpu_to_le64(seg->dma); @@ -204,7 +204,7 @@ Signed-off-by: Jonathan Bell xhci_err(xhci, "Tried to move enqueue past ring segment\n"); return; } -@@ -3150,7 +3153,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd +@@ -3182,7 +3185,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd * that clears the EHB. */ while (xhci_handle_event(xhci) > 0) { @@ -213,7 +213,7 @@ Signed-off-by: Jonathan Bell continue; xhci_update_erst_dequeue(xhci, event_ring_deq); event_ring_deq = xhci->event_ring->dequeue; -@@ -3292,7 +3295,8 @@ static int prepare_ring(struct xhci_hcd +@@ -3324,7 +3327,8 @@ static int prepare_ring(struct xhci_hcd } } @@ -247,7 +247,7 @@ Signed-off-by: Jonathan Bell * when the cycle bit is set to 1. --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1634,6 +1634,7 @@ struct xhci_ring { +@@ -1640,6 +1640,7 @@ struct xhci_ring { unsigned int num_trbs_free; unsigned int num_trbs_free_temp; unsigned int bounce_buf_len; diff --git a/target/linux/bcm27xx/patches-6.1/950-0362-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch b/target/linux/bcm27xx/patches-6.1/950-0362-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch index 041f98a97..d7b4d2d77 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0362-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0362-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch @@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell cycle_state, type, max_packet, flags); --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -296,6 +296,7 @@ static void xhci_pci_quirks(struct devic +@@ -303,6 +303,7 @@ static void xhci_pci_quirks(struct devic if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_AVOID_DQ_ON_LINK; @@ -63,7 +63,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1904,6 +1904,7 @@ struct xhci_hcd { +@@ -1910,6 +1910,7 @@ struct xhci_hcd { #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) #define XHCI_ZHAOXIN_HOST BIT_ULL(46) #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47) diff --git a/target/linux/bcm27xx/patches-6.1/950-0383-drm-panel-simple-add-Geekworm-MZP280-Panel.patch b/target/linux/bcm27xx/patches-6.1/950-0383-drm-panel-simple-add-Geekworm-MZP280-Panel.patch index fa850a4fd..904df714d 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0383-drm-panel-simple-add-Geekworm-MZP280-Panel.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0383-drm-panel-simple-add-Geekworm-MZP280-Panel.patch @@ -46,7 +46,7 @@ Acked-by: Maxime Ripard static const struct drm_display_mode giantplus_gpg482739qs5_mode = { .clock = 9000, .hdisplay = 480, -@@ -4110,6 +4136,9 @@ static const struct of_device_id platfor +@@ -4113,6 +4139,9 @@ static const struct of_device_id platfor .compatible = "friendlyarm,hd702e", .data = &friendlyarm_hd702e, }, { diff --git a/target/linux/bcm27xx/patches-6.1/950-0390-usb-xhci-add-a-quirk-for-Superspeed-bulk-OUT-transfe.patch b/target/linux/bcm27xx/patches-6.1/950-0390-usb-xhci-add-a-quirk-for-Superspeed-bulk-OUT-transfe.patch index 0dd7b78b3..ecca778d1 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0390-usb-xhci-add-a-quirk-for-Superspeed-bulk-OUT-transfe.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0390-usb-xhci-add-a-quirk-for-Superspeed-bulk-OUT-transfe.patch @@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -297,6 +297,7 @@ static void xhci_pci_quirks(struct devic +@@ -304,6 +304,7 @@ static void xhci_pci_quirks(struct devic xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_AVOID_DQ_ON_LINK; xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG; @@ -36,7 +36,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3605,14 +3605,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3637,14 +3637,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd * unsigned int num_trbs; unsigned int start_cycle, num_sgs = 0; unsigned int enqd_len, block_len, trb_buff_len, full_len; @@ -54,7 +54,7 @@ Signed-off-by: Jonathan Bell full_len = urb->transfer_buffer_length; /* If we have scatter/gather list, we use it. */ if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) { -@@ -3649,6 +3650,17 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3681,6 +3682,17 @@ int xhci_queue_bulk_tx(struct xhci_hcd * start_cycle = ring->cycle_state; send_addr = addr; @@ -72,7 +72,7 @@ Signed-off-by: Jonathan Bell /* Queue the TRBs, even if they are zero-length */ for (enqd_len = 0; first_trb || enqd_len < full_len; enqd_len += trb_buff_len) { -@@ -3661,6 +3673,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3693,6 +3705,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd * if (enqd_len + trb_buff_len > full_len) trb_buff_len = full_len - enqd_len; @@ -86,7 +86,7 @@ Signed-off-by: Jonathan Bell first_trb = false; --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1905,6 +1905,7 @@ struct xhci_hcd { +@@ -1911,6 +1911,7 @@ struct xhci_hcd { #define XHCI_ZHAOXIN_HOST BIT_ULL(46) #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47) #define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(48) diff --git a/target/linux/bcm27xx/patches-6.1/950-0392-usb-xhci-rework-XHCI_VLI_SS_BULK_OUT_BUG-quirk.patch b/target/linux/bcm27xx/patches-6.1/950-0392-usb-xhci-rework-XHCI_VLI_SS_BULK_OUT_BUG-quirk.patch index e3f1848ad..471f420e0 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0392-usb-xhci-rework-XHCI_VLI_SS_BULK_OUT_BUG-quirk.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0392-usb-xhci-rework-XHCI_VLI_SS_BULK_OUT_BUG-quirk.patch @@ -13,7 +13,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3605,7 +3605,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3637,7 +3637,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * unsigned int num_trbs; unsigned int start_cycle, num_sgs = 0; unsigned int enqd_len, block_len, trb_buff_len, full_len; @@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell u32 field, length_field, remainder, maxpacket; u64 addr, send_addr; -@@ -3651,14 +3651,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3683,14 +3683,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd * send_addr = addr; if (xhci->quirks & XHCI_VLI_SS_BULK_OUT_BUG && @@ -40,7 +40,7 @@ Signed-off-by: Jonathan Bell } /* Queue the TRBs, even if they are zero-length */ -@@ -3673,7 +3668,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3705,7 +3700,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * if (enqd_len + trb_buff_len > full_len) trb_buff_len = full_len - enqd_len; diff --git a/target/linux/bcm27xx/patches-6.1/950-0418-mmc-block-Don-t-do-single-sector-reads-during-recove.patch b/target/linux/bcm27xx/patches-6.1/950-0418-mmc-block-Don-t-do-single-sector-reads-during-recove.patch index 8fa58f832..44dfc2ba5 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0418-mmc-block-Don-t-do-single-sector-reads-during-recove.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0418-mmc-block-Don-t-do-single-sector-reads-during-recove.patch @@ -23,7 +23,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c -@@ -1970,7 +1970,7 @@ static void mmc_blk_mq_rw_recovery(struc +@@ -1972,7 +1972,7 @@ static void mmc_blk_mq_rw_recovery(struc return; } diff --git a/target/linux/bcm27xx/patches-6.1/950-0438-usb-xhci-account-for-num_trbs_free-when-invalidating.patch b/target/linux/bcm27xx/patches-6.1/950-0438-usb-xhci-account-for-num_trbs_free-when-invalidating.patch index f604759c2..025524ff3 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0438-usb-xhci-account-for-num_trbs_free-when-invalidating.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0438-usb-xhci-account-for-num_trbs_free-when-invalidating.patch @@ -31,9 +31,9 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -1012,11 +1012,13 @@ static int xhci_invalidate_cancelled_tds - td->urb->stream_id, td->urb, - cached_td->urb->stream_id, cached_td->urb); +@@ -1027,11 +1027,13 @@ static int xhci_invalidate_cancelled_tds + + td->cancel_status = TD_CLEARING_CACHE; cached_td = td; + ring->num_trbs_free += td->num_trbs; break; @@ -45,7 +45,7 @@ Signed-off-by: Jonathan Bell } } -@@ -1264,10 +1266,7 @@ static void update_ring_for_set_deq_comp +@@ -1285,10 +1287,7 @@ static void update_ring_for_set_deq_comp unsigned int ep_index) { union xhci_trb *dequeue_temp; @@ -56,7 +56,7 @@ Signed-off-by: Jonathan Bell dequeue_temp = ep_ring->dequeue; /* If we get two back-to-back stalls, and the first stalled transfer -@@ -1282,8 +1281,6 @@ static void update_ring_for_set_deq_comp +@@ -1303,8 +1302,6 @@ static void update_ring_for_set_deq_comp } while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) { @@ -65,7 +65,7 @@ Signed-off-by: Jonathan Bell ep_ring->dequeue++; if (trb_is_link(ep_ring->dequeue)) { if (ep_ring->dequeue == -@@ -1293,15 +1290,10 @@ static void update_ring_for_set_deq_comp +@@ -1314,15 +1311,10 @@ static void update_ring_for_set_deq_comp ep_ring->dequeue = ep_ring->deq_seg->trbs; } if (ep_ring->dequeue == dequeue_temp) { diff --git a/target/linux/bcm27xx/patches-6.1/950-0450-firmware-raspberrypi-Introduce-rpi_firmware_find_nod.patch b/target/linux/bcm27xx/patches-6.1/950-0450-firmware-raspberrypi-Introduce-rpi_firmware_find_nod.patch index 9feea59a3..742b9d285 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0450-firmware-raspberrypi-Introduce-rpi_firmware_find_nod.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0450-firmware-raspberrypi-Introduce-rpi_firmware_find_nod.patch @@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -429,6 +429,18 @@ static int rpi_firmware_remove(struct pl +@@ -430,6 +430,18 @@ static int rpi_firmware_remove(struct pl return 0; } @@ -38,7 +38,7 @@ Signed-off-by: Maxime Ripard /** * rpi_firmware_get - Get pointer to rpi_firmware structure. * @firmware_node: Pointer to the firmware Device Tree node. -@@ -484,12 +496,6 @@ struct rpi_firmware *devm_rpi_firmware_g +@@ -485,12 +497,6 @@ struct rpi_firmware *devm_rpi_firmware_g } EXPORT_SYMBOL_GPL(devm_rpi_firmware_get); diff --git a/target/linux/bcm27xx/patches-6.1/950-0452-firmware-raspberrypi-Provide-a-helper-to-query-a-clo.patch b/target/linux/bcm27xx/patches-6.1/950-0452-firmware-raspberrypi-Provide-a-helper-to-query-a-clo.patch index da30d5781..d5ac2e941 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0452-firmware-raspberrypi-Provide-a-helper-to-query-a-clo.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0452-firmware-raspberrypi-Provide-a-helper-to-query-a-clo.patch @@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c -@@ -342,6 +342,26 @@ static void rpi_register_clk_driver(stru +@@ -343,6 +343,26 @@ static void rpi_register_clk_driver(stru -1, NULL, 0); } diff --git a/target/linux/bcm27xx/patches-6.1/950-0453-drm-vc4-hdmi-Fix-hdmi_enable_4kp60-detection.patch b/target/linux/bcm27xx/patches-6.1/950-0453-drm-vc4-hdmi-Fix-hdmi_enable_4kp60-detection.patch index 2dac12b8a..be8676e2f 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0453-drm-vc4-hdmi-Fix-hdmi_enable_4kp60-detection.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0453-drm-vc4-hdmi-Fix-hdmi_enable_4kp60-detection.patch @@ -36,7 +36,7 @@ Signed-off-by: Maxime Ripard #include #include #include -@@ -3695,7 +3696,7 @@ static int vc4_hdmi_bind(struct device * +@@ -3697,7 +3698,7 @@ static int vc4_hdmi_bind(struct device * if (variant->max_pixel_clock == 600000000) { struct vc4_dev *vc4 = to_vc4_dev(drm); diff --git a/target/linux/bcm27xx/patches-6.1/950-0454-drm-vc4-hdmi-Rework-hdmi_enable_4kp60-detection-code.patch b/target/linux/bcm27xx/patches-6.1/950-0454-drm-vc4-hdmi-Rework-hdmi_enable_4kp60-detection-code.patch index 4b77fe351..d8522d4ff 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0454-drm-vc4-hdmi-Rework-hdmi_enable_4kp60-detection-code.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0454-drm-vc4-hdmi-Rework-hdmi_enable_4kp60-detection-code.patch @@ -91,7 +91,7 @@ Signed-off-by: Maxime Ripard return MODE_CLOCK_HIGH; if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000)) -@@ -3694,14 +3695,6 @@ static int vc4_hdmi_bind(struct device * +@@ -3696,14 +3697,6 @@ static int vc4_hdmi_bind(struct device * vc4_hdmi->disable_wifi_frequencies = of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence"); diff --git a/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch b/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch index ade55cf33..2d987bc7e 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch @@ -30,7 +30,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -298,6 +298,7 @@ static void xhci_pci_quirks(struct devic +@@ -305,6 +305,7 @@ static void xhci_pci_quirks(struct devic xhci->quirks |= XHCI_AVOID_DQ_ON_LINK; xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG; xhci->quirks |= XHCI_VLI_SS_BULK_OUT_BUG; @@ -40,7 +40,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3582,6 +3582,48 @@ static int xhci_align_td(struct xhci_hcd +@@ -3614,6 +3614,48 @@ static int xhci_align_td(struct xhci_hcd return 1; } @@ -89,7 +89,7 @@ Signed-off-by: Jonathan Bell /* This is very similar to what ehci-q.c qtd_fill() does */ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index) -@@ -3750,6 +3792,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3782,6 +3824,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * } check_trb_math(urb, enqd_len); @@ -98,7 +98,7 @@ Signed-off-by: Jonathan Bell giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, start_cycle, start_trb); return 0; -@@ -3885,6 +3929,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * +@@ -3917,6 +3961,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * /* Event on completion */ field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state); @@ -109,7 +109,7 @@ Signed-off-by: Jonathan Bell return 0; --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1906,6 +1906,7 @@ struct xhci_hcd { +@@ -1912,6 +1912,7 @@ struct xhci_hcd { #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47) #define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(48) #define XHCI_VLI_SS_BULK_OUT_BUG BIT_ULL(49) diff --git a/target/linux/bcm27xx/patches-6.1/950-0513-net-bcmgenet-Add-eee-module-parameter.patch b/target/linux/bcm27xx/patches-6.1/950-0513-net-bcmgenet-Add-eee-module-parameter.patch index cd9820fc9..1d035c105 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0513-net-bcmgenet-Add-eee-module-parameter.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0513-net-bcmgenet-Add-eee-module-parameter.patch @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell static inline void bcmgenet_writel(u32 value, void __iomem *offset) { -@@ -3440,6 +3443,17 @@ static int bcmgenet_open(struct net_devi +@@ -3448,6 +3451,17 @@ static int bcmgenet_open(struct net_devi bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause); diff --git a/target/linux/bcm27xx/patches-6.1/950-0520-xhci-constrain-XHCI_VLI_HUB_TT_QUIRK-to-old-firmware.patch b/target/linux/bcm27xx/patches-6.1/950-0520-xhci-constrain-XHCI_VLI_HUB_TT_QUIRK-to-old-firmware.patch index b35584c78..4f6a811c9 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0520-xhci-constrain-XHCI_VLI_HUB_TT_QUIRK-to-old-firmware.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0520-xhci-constrain-XHCI_VLI_HUB_TT_QUIRK-to-old-firmware.patch @@ -24,7 +24,7 @@ Signed-off-by: Jonathan Bell /* Device for a quirk */ #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 -@@ -104,6 +106,16 @@ static int xhci_pci_reinit(struct xhci_h +@@ -105,6 +107,16 @@ static int xhci_pci_reinit(struct xhci_h return 0; } @@ -41,7 +41,7 @@ Signed-off-by: Jonathan Bell static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) { struct pci_dev *pdev = to_pci_dev(dev); -@@ -298,7 +310,8 @@ static void xhci_pci_quirks(struct devic +@@ -305,7 +317,8 @@ static void xhci_pci_quirks(struct devic xhci->quirks |= XHCI_AVOID_DQ_ON_LINK; xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG; xhci->quirks |= XHCI_VLI_SS_BULK_OUT_BUG; diff --git a/target/linux/bcm27xx/patches-6.1/950-0521-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch b/target/linux/bcm27xx/patches-6.1/950-0521-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch index 93da3ce94..9abd05b5e 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0521-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0521-drm-panel-simple-Add-Innolux-AT056tN53V1-5.6-VGA.patch @@ -165,7 +165,7 @@ Signed-off-by: Phil Elwell static const struct drm_display_mode innolux_at070tn92_mode = { .clock = 33333, .hdisplay = 800, -@@ -4146,6 +4178,9 @@ static const struct of_device_id platfor +@@ -4149,6 +4181,9 @@ static const struct of_device_id platfor .compatible = "innolux,at043tn24", .data = &innolux_at043tn24, }, { diff --git a/target/linux/bcm27xx/patches-6.1/950-0671-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch b/target/linux/bcm27xx/patches-6.1/950-0671-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch index 0146bbd61..b852bad90 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0671-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0671-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch @@ -19,7 +19,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1730,7 +1730,7 @@ static void xhci_fixup_endpoint(struct u +@@ -1732,7 +1732,7 @@ static void xhci_fixup_endpoint(struct u return; } ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); diff --git a/target/linux/bcm27xx/patches-6.1/950-0698-serial-8250-Add-NOMSI-bug-for-bcm2835aux.patch b/target/linux/bcm27xx/patches-6.1/950-0698-serial-8250-Add-NOMSI-bug-for-bcm2835aux.patch index 6f62736b0..728e433fb 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0698-serial-8250-Add-NOMSI-bug-for-bcm2835aux.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0698-serial-8250-Add-NOMSI-bug-for-bcm2835aux.patch @@ -71,7 +71,7 @@ Signed-off-by: Phil Elwell * hardware interrupt, we use a timer-based system. The original --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -1559,6 +1559,9 @@ static void serial8250_stop_tx(struct ua +@@ -1553,6 +1553,9 @@ static void serial8250_stop_tx(struct ua serial_icr_write(up, UART_ACR, up->acr); } serial8250_rpm_put(up); @@ -81,7 +81,7 @@ Signed-off-by: Phil Elwell } static inline void __start_tx(struct uart_port *port) -@@ -1669,6 +1672,9 @@ static void serial8250_start_tx(struct u +@@ -1663,6 +1666,9 @@ static void serial8250_start_tx(struct u struct uart_8250_port *up = up_to_u8250p(port); struct uart_8250_em485 *em485 = up->em485; @@ -91,7 +91,7 @@ Signed-off-by: Phil Elwell if (!port->x_char && uart_circ_empty(&port->state->xmit)) return; -@@ -1889,6 +1895,9 @@ unsigned int serial8250_modem_status(str +@@ -1883,6 +1889,9 @@ unsigned int serial8250_modem_status(str uart_handle_cts_change(port, status & UART_MSR_CTS); wake_up_interruptible(&port->state->port.delta_msr_wait); diff --git a/target/linux/bcm27xx/patches-6.1/950-0712-drm-vc4-Use-phys-addresses-for-slave-DMA-config.patch b/target/linux/bcm27xx/patches-6.1/950-0712-drm-vc4-Use-phys-addresses-for-slave-DMA-config.patch index 2c83a8083..04967b529 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0712-drm-vc4-Use-phys-addresses-for-slave-DMA-config.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0712-drm-vc4-Use-phys-addresses-for-slave-DMA-config.patch @@ -8,8 +8,8 @@ Slave addresses for DMA are meant to be supplied as physical addresses Signed-off-by: Phil Elwell --- - drivers/gpu/drm/vc4/vc4_hdmi.c | 13 ++++--------- - 1 file changed, 4 insertions(+), 9 deletions(-) + drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell int index, len; int ret; -@@ -2755,20 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc +@@ -2755,22 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc } /* @@ -40,6 +40,8 @@ Signed-off-by: Phil Elwell + iomem = platform_get_resource(vc4_hdmi->pdev, IORESOURCE_MEM, index); - addr = of_get_address(dev->of_node, index, NULL, NULL); +- if (!addr) +- return -EINVAL; - - vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset; + vc4_hdmi->audio.dma_data.addr = iomem->start + mai_data->offset; diff --git a/target/linux/bcm27xx/patches-6.1/950-0791-serial-sc16is7xx-Read-modem-line-state-at-startup.patch b/target/linux/bcm27xx/patches-6.1/950-0791-serial-sc16is7xx-Read-modem-line-state-at-startup.patch index 291302306..ef2847fcd 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0791-serial-sc16is7xx-Read-modem-line-state-at-startup.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0791-serial-sc16is7xx-Read-modem-line-state-at-startup.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -1193,6 +1193,9 @@ static int sc16is7xx_startup(struct uart +@@ -1206,6 +1206,9 @@ static int sc16is7xx_startup(struct uart SC16IS7XX_IER_MSI_BIT; sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); diff --git a/target/linux/bcm27xx/patches-6.1/950-0804-fixup-Allow-mac-address-to-be-set-in-smsc95xx.patch b/target/linux/bcm27xx/patches-6.1/950-0804-fixup-Allow-mac-address-to-be-set-in-smsc95xx.patch index 9265e931f..7dc9ee9af 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0804-fixup-Allow-mac-address-to-be-set-in-smsc95xx.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0804-fixup-Allow-mac-address-to-be-set-in-smsc95xx.patch @@ -43,7 +43,7 @@ Signed-off-by: Lukas Wunner --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -814,49 +814,18 @@ static int smsc95xx_ioctl(struct net_dev +@@ -810,49 +810,18 @@ static int smsc95xx_ioctl(struct net_dev } /* Check the macaddr module parameter for a MAC address */ @@ -103,7 +103,7 @@ Signed-off-by: Lukas Wunner } static void smsc95xx_init_mac_address(struct usbnet *dev) -@@ -883,8 +852,12 @@ static void smsc95xx_init_mac_address(st +@@ -879,8 +848,12 @@ static void smsc95xx_init_mac_address(st } /* Check module parameters */ diff --git a/target/linux/bcm27xx/patches-6.1/950-0842-f2fs-fix-to-avoid-NULL-pointer-dereference-in-f2fs_i.patch b/target/linux/bcm27xx/patches-6.1/950-0842-f2fs-fix-to-avoid-NULL-pointer-dereference-in-f2fs_i.patch index 33150551b..1e2119c88 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0842-f2fs-fix-to-avoid-NULL-pointer-dereference-in-f2fs_i.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0842-f2fs-fix-to-avoid-NULL-pointer-dereference-in-f2fs_i.patch @@ -35,7 +35,7 @@ Signed-off-by: Jaegeuk Kim --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c -@@ -663,9 +663,7 @@ init_thread: +@@ -665,9 +665,7 @@ init_thread: "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); if (IS_ERR(fcc->f2fs_issue_flush)) { err = PTR_ERR(fcc->f2fs_issue_flush); @@ -46,7 +46,7 @@ Signed-off-by: Jaegeuk Kim } return err; -@@ -5062,11 +5060,9 @@ int f2fs_build_segment_manager(struct f2 +@@ -5064,11 +5062,9 @@ int f2fs_build_segment_manager(struct f2 init_f2fs_rwsem(&sm_info->curseg_lock); diff --git a/target/linux/bcm27xx/patches-6.1/950-0860-sdhci-Add-SD-Express-hook.patch b/target/linux/bcm27xx/patches-6.1/950-0860-sdhci-Add-SD-Express-hook.patch index 1aea0b3bc..c7d53f977 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0860-sdhci-Add-SD-Express-hook.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0860-sdhci-Add-SD-Express-hook.patch @@ -50,7 +50,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR }; /*****************************************************************************\ -@@ -4605,6 +4615,15 @@ int sdhci_setup_host(struct sdhci_host * +@@ -4611,6 +4621,15 @@ int sdhci_setup_host(struct sdhci_host * !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50)) mmc->caps |= MMC_CAP_UHS_DDR50; @@ -68,7 +68,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR host->flags |= SDHCI_SDR50_NEEDS_TUNING; --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h -@@ -481,6 +481,11 @@ struct sdhci_host { +@@ -482,6 +482,11 @@ struct sdhci_host { /* Issue CMD and DATA reset together */ #define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19) @@ -80,7 +80,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ phys_addr_t mapbase; /* physical address base */ -@@ -663,6 +668,7 @@ struct sdhci_ops { +@@ -664,6 +669,7 @@ struct sdhci_ops { void (*request_done)(struct sdhci_host *host, struct mmc_request *mrq); void (*dump_vendor_regs)(struct sdhci_host *host); diff --git a/target/linux/bcm27xx/patches-6.1/950-0865-usb-dwc3-Set-DMA-and-coherent-masks-early.patch b/target/linux/bcm27xx/patches-6.1/950-0865-usb-dwc3-Set-DMA-and-coherent-masks-early.patch index e67cb6688..cf92da67a 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0865-usb-dwc3-Set-DMA-and-coherent-masks-early.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0865-usb-dwc3-Set-DMA-and-coherent-masks-early.patch @@ -212,7 +212,7 @@ Signed-off-by: Jonathan Bell }, --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -1179,6 +1179,24 @@ static void dwc3_config_threshold(struct +@@ -1180,6 +1180,24 @@ static void dwc3_config_threshold(struct } } @@ -237,7 +237,7 @@ Signed-off-by: Jonathan Bell /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure -@@ -1271,6 +1289,8 @@ static int dwc3_core_init(struct dwc3 *d +@@ -1257,6 +1275,8 @@ static int dwc3_core_init(struct dwc3 *d dwc3_set_incr_burst_type(dwc); @@ -246,7 +246,7 @@ Signed-off-by: Jonathan Bell usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); -@@ -1504,6 +1524,7 @@ static void dwc3_get_properties(struct d +@@ -1490,6 +1510,7 @@ static void dwc3_get_properties(struct d u8 tx_thr_num_pkt_prd = 0; u8 tx_max_burst_prd = 0; u8 tx_fifo_resize_max_num; @@ -254,7 +254,7 @@ Signed-off-by: Jonathan Bell const char *usb_psy_name; int ret; -@@ -1526,6 +1547,9 @@ static void dwc3_get_properties(struct d +@@ -1512,6 +1533,9 @@ static void dwc3_get_properties(struct d */ tx_fifo_resize_max_num = 6; @@ -264,7 +264,7 @@ Signed-off-by: Jonathan Bell dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); dwc->dr_mode = usb_get_dr_mode(dev); -@@ -1641,6 +1665,9 @@ static void dwc3_get_properties(struct d +@@ -1627,6 +1651,9 @@ static void dwc3_get_properties(struct d dwc->dis_split_quirk = device_property_read_bool(dev, "snps,dis-split-quirk"); @@ -274,7 +274,7 @@ Signed-off-by: Jonathan Bell dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; -@@ -1658,6 +1685,8 @@ static void dwc3_get_properties(struct d +@@ -1644,6 +1671,8 @@ static void dwc3_get_properties(struct d dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd; dwc->tx_max_burst_prd = tx_max_burst_prd; @@ -283,7 +283,7 @@ Signed-off-by: Jonathan Bell dwc->imod_interval = 0; dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; -@@ -1866,6 +1895,12 @@ static int dwc3_probe(struct platform_de +@@ -1852,6 +1881,12 @@ static int dwc3_probe(struct platform_de dwc3_get_properties(dwc); @@ -326,7 +326,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c -@@ -30,10 +30,10 @@ static void dwc3_host_fill_xhci_irq_res( +@@ -51,10 +51,10 @@ static void dwc3_host_fill_xhci_irq_res( static int dwc3_host_get_irq(struct dwc3 *dwc) { @@ -339,7 +339,7 @@ Signed-off-by: Jonathan Bell if (irq > 0) { dwc3_host_fill_xhci_irq_res(dwc, irq, "host"); goto out; -@@ -42,7 +42,7 @@ static int dwc3_host_get_irq(struct dwc3 +@@ -63,7 +63,7 @@ static int dwc3_host_get_irq(struct dwc3 if (irq == -EPROBE_DEFER) goto out; @@ -348,7 +348,7 @@ Signed-off-by: Jonathan Bell if (irq > 0) { dwc3_host_fill_xhci_irq_res(dwc, irq, "dwc_usb3"); goto out; -@@ -51,7 +51,7 @@ static int dwc3_host_get_irq(struct dwc3 +@@ -72,7 +72,7 @@ static int dwc3_host_get_irq(struct dwc3 if (irq == -EPROBE_DEFER) goto out; @@ -357,7 +357,7 @@ Signed-off-by: Jonathan Bell if (irq > 0) { dwc3_host_fill_xhci_irq_res(dwc, irq, NULL); goto out; -@@ -66,16 +66,23 @@ out: +@@ -87,16 +87,23 @@ out: int dwc3_host_init(struct dwc3 *dwc) { diff --git a/target/linux/bcm27xx/patches-6.1/950-0938-drm-vc4-Introduce-generation-number-enum.patch b/target/linux/bcm27xx/patches-6.1/950-0938-drm-vc4-Introduce-generation-number-enum.patch index 9314c797a..d904c3d78 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0938-drm-vc4-Introduce-generation-number-enum.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0938-drm-vc4-Introduce-generation-number-enum.patch @@ -902,7 +902,7 @@ Signed-off-by: Maxime Ripard /* Control word */ vc4_dlist_write(vc4_state, SCALER_CTL0_VALID | -@@ -1717,7 +1717,7 @@ struct drm_plane *vc4_plane_init(struct +@@ -1714,7 +1714,7 @@ struct drm_plane *vc4_plane_init(struct }; for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { @@ -911,7 +911,7 @@ Signed-off-by: Maxime Ripard formats[num_formats] = hvs_formats[i].drm; num_formats++; } -@@ -1732,7 +1732,7 @@ struct drm_plane *vc4_plane_init(struct +@@ -1729,7 +1729,7 @@ struct drm_plane *vc4_plane_init(struct return ERR_CAST(vc4_plane); plane = &vc4_plane->base; diff --git a/target/linux/bcm27xx/patches-6.1/950-0963-drm-vc4-hvs-Support-BCM2712-HVS.patch b/target/linux/bcm27xx/patches-6.1/950-0963-drm-vc4-hvs-Support-BCM2712-HVS.patch index 965943229..5cbc30461 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0963-drm-vc4-hvs-Support-BCM2712-HVS.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0963-drm-vc4-hvs-Support-BCM2712-HVS.patch @@ -1924,7 +1924,7 @@ Signed-off-by: Maxime Ripard return 0; } -@@ -1716,7 +2345,7 @@ struct drm_plane *vc4_plane_init(struct +@@ -1713,7 +2342,7 @@ struct drm_plane *vc4_plane_init(struct }; for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { @@ -1933,7 +1933,7 @@ Signed-off-by: Maxime Ripard formats[num_formats] = hvs_formats[i].drm; num_formats++; } -@@ -1731,7 +2360,7 @@ struct drm_plane *vc4_plane_init(struct +@@ -1728,7 +2357,7 @@ struct drm_plane *vc4_plane_init(struct return ERR_CAST(vc4_plane); plane = &vc4_plane->base; diff --git a/target/linux/bcm27xx/patches-6.1/950-0989-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch b/target/linux/bcm27xx/patches-6.1/950-0989-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch index ef70de7ee..42f426668 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0989-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0989-drm-panel-simple-Alter-the-timing-for-the-Pi-7-DSI-d.patch @@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c -@@ -3241,11 +3241,11 @@ static const struct panel_desc qishenglo +@@ -3244,11 +3244,11 @@ static const struct panel_desc qishenglo }; static const struct drm_display_mode raspberrypi_7inch_mode = { diff --git a/target/linux/bcm27xx/patches-6.1/950-1075-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch b/target/linux/bcm27xx/patches-6.1/950-1075-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch index 2ab224df0..5b3b66c1f 100644 --- a/target/linux/bcm27xx/patches-6.1/950-1075-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch +++ b/target/linux/bcm27xx/patches-6.1/950-1075-drivers-mmc-sdhci-add-SPURIOUS_INT_RESP-quirk.patch @@ -50,7 +50,7 @@ Signed-off-by: Jonathan Bell if (!mmc_op_tuning(host->cmd->opcode)) --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h -@@ -486,6 +486,9 @@ struct sdhci_host { +@@ -487,6 +487,9 @@ struct sdhci_host { #define SDHCI_QUIRK2_NO_SDR50 (1<<20) #define SDHCI_QUIRK2_NO_SDR104 (1<<21) diff --git a/target/linux/bcm27xx/patches-6.1/950-1182-drm-panel-add-panel-dsi.patch b/target/linux/bcm27xx/patches-6.1/950-1182-drm-panel-add-panel-dsi.patch index 9122d7347..a46d6d3f1 100644 --- a/target/linux/bcm27xx/patches-6.1/950-1182-drm-panel-add-panel-dsi.patch +++ b/target/linux/bcm27xx/patches-6.1/950-1182-drm-panel-add-panel-dsi.patch @@ -23,7 +23,7 @@ Signed-off-by: Timon Skerutsch /** * struct panel_desc - Describes a simple panel. -@@ -4662,6 +4663,9 @@ static const struct panel_desc_dsi osd10 +@@ -4665,6 +4666,9 @@ static const struct panel_desc_dsi osd10 .lanes = 4, }; @@ -33,7 +33,7 @@ Signed-off-by: Timon Skerutsch static const struct of_device_id dsi_of_match[] = { { .compatible = "auo,b080uan01", -@@ -4685,14 +4689,118 @@ static const struct of_device_id dsi_of_ +@@ -4688,14 +4692,118 @@ static const struct of_device_id dsi_of_ .compatible = "osddisplays,osd101t2045-53ts", .data = &osd101t2045_53ts }, { @@ -152,7 +152,7 @@ Signed-off-by: Timon Skerutsch const struct of_device_id *id; int err; -@@ -4700,7 +4808,20 @@ static int panel_simple_dsi_probe(struct +@@ -4703,7 +4811,20 @@ static int panel_simple_dsi_probe(struct if (!id) return -ENODEV; diff --git a/target/linux/bcm27xx/patches-6.1/950-1235-drm-vc4-don-t-check-if-plane-state-fb-state-fb.patch b/target/linux/bcm27xx/patches-6.1/950-1235-drm-vc4-don-t-check-if-plane-state-fb-state-fb.patch deleted file mode 100644 index 7c7c05c5e..000000000 --- a/target/linux/bcm27xx/patches-6.1/950-1235-drm-vc4-don-t-check-if-plane-state-fb-state-fb.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 146bbf9627f6c37816939de29538ec8ee9a7be1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ma=C3=ADra=20Canal?= -Date: Fri, 5 Jan 2024 15:07:34 -0300 -Subject: [PATCH] drm/vc4: don't check if plane->state->fb == state->fb -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently, when using non-blocking commits, we can see the following -kernel warning: - -[ 110.908514] ------------[ cut here ]------------ -[ 110.908529] refcount_t: underflow; use-after-free. -[ 110.908620] WARNING: CPU: 0 PID: 1866 at lib/refcount.c:87 refcount_dec_not_one+0xb8/0xc0 -[ 110.908664] Modules linked in: rfcomm snd_seq_dummy snd_hrtimer snd_seq snd_seq_device cmac algif_hash aes_arm64 aes_generic algif_skcipher af_alg bnep hid_logitech_hidpp vc4 brcmfmac hci_uart btbcm brcmutil bluetooth snd_soc_hdmi_codec cfg80211 cec drm_display_helper drm_dma_helper drm_kms_helper snd_soc_core snd_compress snd_pcm_dmaengine fb_sys_fops sysimgblt syscopyarea sysfillrect raspberrypi_hwmon ecdh_generic ecc rfkill libaes i2c_bcm2835 binfmt_misc joydev snd_bcm2835(C) bcm2835_codec(C) bcm2835_isp(C) v4l2_mem2mem videobuf2_dma_contig snd_pcm bcm2835_v4l2(C) raspberrypi_gpiomem bcm2835_mmal_vchiq(C) videobuf2_v4l2 snd_timer videobuf2_vmalloc videobuf2_memops videobuf2_common snd videodev vc_sm_cma(C) mc hid_logitech_dj uio_pdrv_genirq uio i2c_dev drm fuse dm_mod drm_panel_orientation_quirks backlight ip_tables x_tables ipv6 -[ 110.909086] CPU: 0 PID: 1866 Comm: kodi.bin Tainted: G C 6.1.66-v8+ #32 -[ 110.909104] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT) -[ 110.909114] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 110.909132] pc : refcount_dec_not_one+0xb8/0xc0 -[ 110.909152] lr : refcount_dec_not_one+0xb4/0xc0 -[ 110.909170] sp : ffffffc00913b9c0 -[ 110.909177] x29: ffffffc00913b9c0 x28: 000000556969bbb0 x27: 000000556990df60 -[ 110.909205] x26: 0000000000000002 x25: 0000000000000004 x24: ffffff8004448480 -[ 110.909230] x23: ffffff800570b500 x22: ffffff802e03a7bc x21: ffffffecfca68c78 -[ 110.909257] x20: ffffff8002b42000 x19: ffffff802e03a600 x18: 0000000000000000 -[ 110.909283] x17: 0000000000000011 x16: ffffffffffffffff x15: 0000000000000004 -[ 110.909308] x14: 0000000000000fff x13: ffffffed577e47e0 x12: 0000000000000003 -[ 110.909333] x11: 0000000000000000 x10: 0000000000000027 x9 : c912d0d083728c00 -[ 110.909359] x8 : c912d0d083728c00 x7 : 65646e75203a745f x6 : 746e756f63666572 -[ 110.909384] x5 : ffffffed579f62ee x4 : ffffffed579eb01e x3 : 0000000000000000 -[ 110.909409] x2 : 0000000000000000 x1 : ffffffc00913b750 x0 : 0000000000000001 -[ 110.909434] Call trace: -[ 110.909441] refcount_dec_not_one+0xb8/0xc0 -[ 110.909461] vc4_bo_dec_usecnt+0x4c/0x1b0 [vc4] -[ 110.909903] vc4_cleanup_fb+0x44/0x50 [vc4] -[ 110.910315] drm_atomic_helper_cleanup_planes+0x88/0xa4 [drm_kms_helper] -[ 110.910669] vc4_atomic_commit_tail+0x390/0x9dc [vc4] -[ 110.911079] commit_tail+0xb0/0x164 [drm_kms_helper] -[ 110.911397] drm_atomic_helper_commit+0x1d0/0x1f0 [drm_kms_helper] -[ 110.911716] drm_atomic_commit+0xb0/0xdc [drm] -[ 110.912569] drm_mode_atomic_ioctl+0x348/0x4b8 [drm] -[ 110.913330] drm_ioctl_kernel+0xec/0x15c [drm] -[ 110.914091] drm_ioctl+0x24c/0x3b0 [drm] -[ 110.914850] __arm64_sys_ioctl+0x9c/0xd4 -[ 110.914873] invoke_syscall+0x4c/0x114 -[ 110.914897] el0_svc_common+0xd0/0x118 -[ 110.914917] do_el0_svc+0x38/0xd0 -[ 110.914936] el0_svc+0x30/0x8c -[ 110.914958] el0t_64_sync_handler+0x84/0xf0 -[ 110.914979] el0t_64_sync+0x18c/0x190 -[ 110.914996] ---[ end trace 0000000000000000 ]--- - -This happens because, although `prepare_fb` and `cleanup_fb` are -perfectly balanced, we cannot guarantee consistency in the check -plane->state->fb == state->fb. This means that sometimes we can increase -the refcount in `prepare_fb` and don't decrease it in `cleanup_fb`. The -opposite can also be true. - -In fact, the struct drm_plane .state shouldn't be accessed directly -but instead, the `drm_atomic_get_new_plane_state()` helper function should -be used. So, we could stick to this check, but using -`drm_atomic_get_new_plane_state()`. But actually, this check is not really -needed. We can increase and decrease the refcount symmetrically without -problems. - -This is going to make the code more simple and consistent. - -Signed-off-by: Maíra Canal ---- - drivers/gpu/drm/vc4/vc4_plane.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -2225,9 +2225,6 @@ static int vc4_prepare_fb(struct drm_pla - - drm_gem_plane_helper_prepare_fb(plane, state); - -- if (plane->state->fb == state->fb) -- return 0; -- - return vc4_bo_inc_usecnt(bo); - } - -@@ -2236,7 +2233,7 @@ static void vc4_cleanup_fb(struct drm_pl - { - struct vc4_bo *bo; - -- if (plane->state->fb == state->fb || !state->fb) -+ if (!state->fb) - return; - - bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); diff --git a/target/linux/bcm47xx/patches-5.4/209-b44-register-adm-switch.patch b/target/linux/bcm47xx/patches-5.4/209-b44-register-adm-switch.patch index 2b4750145..cc6e8fc03 100644 --- a/target/linux/bcm47xx/patches-5.4/209-b44-register-adm-switch.patch +++ b/target/linux/bcm47xx/patches-5.4/209-b44-register-adm-switch.patch @@ -19,7 +19,7 @@ Subject: [PATCH 210/210] b44: register adm switch #include #include -@@ -2249,6 +2251,69 @@ static void b44_adjust_link(struct net_d +@@ -2251,6 +2253,69 @@ static void b44_adjust_link(struct net_d } } @@ -89,7 +89,7 @@ Subject: [PATCH 210/210] b44: register adm switch static int b44_register_phy_one(struct b44 *bp) { __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -@@ -2285,6 +2350,9 @@ static int b44_register_phy_one(struct b +@@ -2287,6 +2352,9 @@ static int b44_register_phy_one(struct b if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) && (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { @@ -99,7 +99,7 @@ Subject: [PATCH 210/210] b44: register adm switch dev_info(sdev->dev, "could not find PHY at %i, use fixed one\n", bp->phy_addr); -@@ -2481,6 +2549,7 @@ static void b44_remove_one(struct ssb_de +@@ -2483,6 +2551,7 @@ static void b44_remove_one(struct ssb_de unregister_netdev(dev); if (bp->flags & B44_FLAG_EXTERNAL_PHY) b44_unregister_phy_one(bp); diff --git a/target/linux/bcm47xx/patches-5.4/210-b44_phy_fix.patch b/target/linux/bcm47xx/patches-5.4/210-b44_phy_fix.patch index 8c7a73ac0..bff605210 100644 --- a/target/linux/bcm47xx/patches-5.4/210-b44_phy_fix.patch +++ b/target/linux/bcm47xx/patches-5.4/210-b44_phy_fix.patch @@ -43,7 +43,7 @@ if (bp->flags & B44_FLAG_EXTERNAL_PHY) return 0; -@@ -2179,6 +2204,8 @@ static int b44_get_invariants(struct b44 +@@ -2181,6 +2206,8 @@ static int b44_get_invariants(struct b44 * valid PHY address. */ bp->phy_addr &= 0x1F; diff --git a/target/linux/generic/backport-5.10/350-v5.12-NFSv4_2-SSC-helper-should-use-its-own-config.patch b/target/linux/generic/backport-5.10/350-v5.12-NFSv4_2-SSC-helper-should-use-its-own-config.patch deleted file mode 100644 index 8517bd7bb..000000000 --- a/target/linux/generic/backport-5.10/350-v5.12-NFSv4_2-SSC-helper-should-use-its-own-config.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 02591f9febd5f69bb4c266a4abf899c4cf21964f Mon Sep 17 00:00:00 2001 -From: Dai Ngo -Date: Thu, 28 Jan 2021 01:42:26 -0500 -Subject: [PATCH] NFSv4_2: SSC helper should use its own config. - -Currently NFSv4_2 SSC helper, nfs_ssc, incorrectly uses GRACE_PERIOD -as its config. Fix by adding new config NFS_V4_2_SSC_HELPER which -depends on NFS_V4_2 and is automatically selected when NFSD_V4 is -enabled. Also removed the file name from a comment in nfs_ssc.c. - -Signed-off-by: Dai Ngo -Signed-off-by: Chuck Lever ---- - fs/Kconfig | 4 ++++ - fs/nfs/nfs4file.c | 4 ++++ - fs/nfs/super.c | 12 ++++++++++++ - fs/nfs_common/Makefile | 2 +- - fs/nfs_common/nfs_ssc.c | 2 -- - fs/nfsd/Kconfig | 1 + - 6 files changed, 22 insertions(+), 3 deletions(-) - ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -333,6 +333,10 @@ config NFS_COMMON - depends on NFSD || NFS_FS || LOCKD - default y - -+config NFS_V4_2_SSC_HELPER -+ tristate -+ default y if NFS_V4=y || NFS_FS=y -+ - source "net/sunrpc/Kconfig" - source "fs/ceph/Kconfig" - source "fs/cifs/Kconfig" ---- a/fs/nfs/nfs4file.c -+++ b/fs/nfs/nfs4file.c -@@ -430,7 +430,9 @@ static const struct nfs4_ssc_client_ops - */ - void nfs42_ssc_register_ops(void) - { -+#ifdef CONFIG_NFSD_V4 - nfs42_ssc_register(&nfs4_ssc_clnt_ops_tbl); -+#endif - } - - /** -@@ -441,7 +443,9 @@ void nfs42_ssc_register_ops(void) - */ - void nfs42_ssc_unregister_ops(void) - { -+#ifdef CONFIG_NFSD_V4 - nfs42_ssc_unregister(&nfs4_ssc_clnt_ops_tbl); -+#endif - } - #endif /* CONFIG_NFS_V4_2 */ - ---- a/fs/nfs/super.c -+++ b/fs/nfs/super.c -@@ -86,9 +86,11 @@ const struct super_operations nfs_sops = - }; - EXPORT_SYMBOL_GPL(nfs_sops); - -+#ifdef CONFIG_NFS_V4_2 - static const struct nfs_ssc_client_ops nfs_ssc_clnt_ops_tbl = { - .sco_sb_deactive = nfs_sb_deactive, - }; -+#endif - - #if IS_ENABLED(CONFIG_NFS_V4) - static int __init register_nfs4_fs(void) -@@ -111,15 +113,21 @@ static void unregister_nfs4_fs(void) - } - #endif - -+#ifdef CONFIG_NFS_V4_2 - static void nfs_ssc_register_ops(void) - { -+#ifdef CONFIG_NFSD_V4 - nfs_ssc_register(&nfs_ssc_clnt_ops_tbl); -+#endif - } - - static void nfs_ssc_unregister_ops(void) - { -+#ifdef CONFIG_NFSD_V4 - nfs_ssc_unregister(&nfs_ssc_clnt_ops_tbl); -+#endif - } -+#endif /* CONFIG_NFS_V4_2 */ - - static struct shrinker acl_shrinker = { - .count_objects = nfs_access_cache_count, -@@ -148,7 +156,9 @@ int __init register_nfs_fs(void) - ret = register_shrinker(&acl_shrinker); - if (ret < 0) - goto error_3; -+#ifdef CONFIG_NFS_V4_2 - nfs_ssc_register_ops(); -+#endif - return 0; - error_3: - nfs_unregister_sysctl(); -@@ -168,7 +178,9 @@ void __exit unregister_nfs_fs(void) - unregister_shrinker(&acl_shrinker); - nfs_unregister_sysctl(); - unregister_nfs4_fs(); -+#ifdef CONFIG_NFS_V4_2 - nfs_ssc_unregister_ops(); -+#endif - unregister_filesystem(&nfs_fs_type); - } - ---- a/fs/nfs_common/Makefile -+++ b/fs/nfs_common/Makefile -@@ -7,4 +7,4 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl - nfs_acl-objs := nfsacl.o - - obj-$(CONFIG_GRACE_PERIOD) += grace.o --obj-$(CONFIG_GRACE_PERIOD) += nfs_ssc.o -+obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o ---- a/fs/nfs_common/nfs_ssc.c -+++ b/fs/nfs_common/nfs_ssc.c -@@ -1,7 +1,5 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* -- * fs/nfs_common/nfs_ssc_comm.c -- * - * Helper for knfsd's SSC to access ops in NFS client modules - * - * Author: Dai Ngo ---- a/fs/nfsd/Kconfig -+++ b/fs/nfsd/Kconfig -@@ -77,6 +77,7 @@ config NFSD_V4 - select CRYPTO_MD5 - select CRYPTO_SHA256 - select GRACE_PERIOD -+ select NFS_V4_2_SSC_HELPER if NFS_V4_2 - help - This option enables support in your system's NFS server for - version 4 of the NFS protocol (RFC 3530). diff --git a/target/linux/generic/backport-5.10/351-v5.13-NFSv4_2-Remove-ifdef-CONFIG_NFSD-from-client-SSC.patch b/target/linux/generic/backport-5.10/351-v5.13-NFSv4_2-Remove-ifdef-CONFIG_NFSD-from-client-SSC.patch deleted file mode 100644 index 84c68e142..000000000 --- a/target/linux/generic/backport-5.10/351-v5.13-NFSv4_2-Remove-ifdef-CONFIG_NFSD-from-client-SSC.patch +++ /dev/null @@ -1,84 +0,0 @@ -From d9092b4bb2109502eb8972021a3f74febc931a63 Mon Sep 17 00:00:00 2001 -From: Dai Ngo -Date: Thu, 22 Apr 2021 03:37:49 -0400 -Subject: [PATCH] NFSv4.2: Remove ifdef CONFIG_NFSD from NFSv4.2 client SSC - code. - -The client SSC code should not depend on any of the CONFIG_NFSD config. -This patch removes all CONFIG_NFSD from NFSv4.2 client SSC code and -simplifies the config of CONFIG_NFS_V4_2_SSC_HELPER, NFSD_V4_2_INTER_SSC. - -Signed-off-by: Dai Ngo -Signed-off-by: Trond Myklebust ---- - fs/Kconfig | 4 ++-- - fs/nfs/nfs4file.c | 4 ---- - fs/nfs/super.c | 4 ---- - fs/nfsd/Kconfig | 2 +- - 4 files changed, 3 insertions(+), 11 deletions(-) - ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -334,8 +334,8 @@ config NFS_COMMON - default y - - config NFS_V4_2_SSC_HELPER -- tristate -- default y if NFS_V4=y || NFS_FS=y -+ bool -+ default y if NFS_V4_2 - - source "net/sunrpc/Kconfig" - source "fs/ceph/Kconfig" ---- a/fs/nfs/nfs4file.c -+++ b/fs/nfs/nfs4file.c -@@ -430,9 +430,7 @@ static const struct nfs4_ssc_client_ops - */ - void nfs42_ssc_register_ops(void) - { --#ifdef CONFIG_NFSD_V4 - nfs42_ssc_register(&nfs4_ssc_clnt_ops_tbl); --#endif - } - - /** -@@ -443,9 +441,7 @@ void nfs42_ssc_register_ops(void) - */ - void nfs42_ssc_unregister_ops(void) - { --#ifdef CONFIG_NFSD_V4 - nfs42_ssc_unregister(&nfs4_ssc_clnt_ops_tbl); --#endif - } - #endif /* CONFIG_NFS_V4_2 */ - ---- a/fs/nfs/super.c -+++ b/fs/nfs/super.c -@@ -116,16 +116,12 @@ static void unregister_nfs4_fs(void) - #ifdef CONFIG_NFS_V4_2 - static void nfs_ssc_register_ops(void) - { --#ifdef CONFIG_NFSD_V4 - nfs_ssc_register(&nfs_ssc_clnt_ops_tbl); --#endif - } - - static void nfs_ssc_unregister_ops(void) - { --#ifdef CONFIG_NFSD_V4 - nfs_ssc_unregister(&nfs_ssc_clnt_ops_tbl); --#endif - } - #endif /* CONFIG_NFS_V4_2 */ - ---- a/fs/nfsd/Kconfig -+++ b/fs/nfsd/Kconfig -@@ -138,7 +138,7 @@ config NFSD_FLEXFILELAYOUT - - config NFSD_V4_2_INTER_SSC - bool "NFSv4.2 inter server to server COPY" -- depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 -+ depends on NFSD_V4 && NFS_V4_2 - help - This option enables support for NFSv4.2 inter server to - server copy where the destination server calls the NFSv4.2 diff --git a/target/linux/generic/backport-5.10/630-v5.15-page_pool_frag_support.patch b/target/linux/generic/backport-5.10/630-v5.15-page_pool_frag_support.patch index 60075af2c..bc5be29bd 100644 --- a/target/linux/generic/backport-5.10/630-v5.15-page_pool_frag_support.patch +++ b/target/linux/generic/backport-5.10/630-v5.15-page_pool_frag_support.patch @@ -574,7 +574,7 @@ union { --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -594,13 +594,22 @@ static void skb_clone_fraglist(struct sk +@@ -595,13 +595,22 @@ static void skb_clone_fraglist(struct sk skb_get(list); } @@ -599,7 +599,7 @@ kfree(head); } -@@ -612,16 +621,27 @@ static void skb_release_data(struct sk_b +@@ -613,16 +622,27 @@ static void skb_release_data(struct sk_b if (skb->cloned && atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, &shinfo->dataref)) @@ -629,7 +629,7 @@ } /* -@@ -1002,6 +1022,7 @@ static struct sk_buff *__skb_clone(struc +@@ -1003,6 +1023,7 @@ static struct sk_buff *__skb_clone(struc n->nohdr = 0; n->peeked = 0; C(pfmemalloc); @@ -637,7 +637,7 @@ n->destructor = NULL; C(tail); C(end); -@@ -3420,7 +3441,7 @@ int skb_shift(struct sk_buff *tgt, struc +@@ -3432,7 +3453,7 @@ int skb_shift(struct sk_buff *tgt, struc fragto = &skb_shinfo(tgt)->frags[merge]; skb_frag_size_add(fragto, skb_frag_size(fragfrom)); @@ -646,7 +646,7 @@ } /* Reposition in the original skb */ -@@ -5204,6 +5225,20 @@ bool skb_try_coalesce(struct sk_buff *to +@@ -5216,6 +5237,20 @@ bool skb_try_coalesce(struct sk_buff *to if (skb_cloned(to)) return false; @@ -687,7 +687,7 @@ #ifdef CONFIG_SKB_EXTENSIONS __u8 active_extensions; #endif -@@ -3030,9 +3032,15 @@ static inline void skb_frag_ref(struct s +@@ -3045,9 +3047,15 @@ static inline void skb_frag_ref(struct s * * Releases a reference on the paged fragment @frag. */ @@ -705,7 +705,7 @@ } /** -@@ -3044,7 +3052,7 @@ static inline void __skb_frag_unref(skb_ +@@ -3059,7 +3067,7 @@ static inline void __skb_frag_unref(skb_ */ static inline void skb_frag_unref(struct sk_buff *skb, int f) { @@ -714,7 +714,7 @@ } /** -@@ -4643,5 +4651,12 @@ static inline u64 skb_get_kcov_handle(st +@@ -4658,5 +4666,12 @@ static inline u64 skb_get_kcov_handle(st #endif } diff --git a/target/linux/generic/backport-5.10/633-v6.3-skbuff-Fix-a-race-between-coalescing-and-releasing-S.patch b/target/linux/generic/backport-5.10/633-v6.3-skbuff-Fix-a-race-between-coalescing-and-releasing-S.patch index a461734b6..57230fcd1 100644 --- a/target/linux/generic/backport-5.10/633-v6.3-skbuff-Fix-a-race-between-coalescing-and-releasing-S.patch +++ b/target/linux/generic/backport-5.10/633-v6.3-skbuff-Fix-a-race-between-coalescing-and-releasing-S.patch @@ -56,7 +56,7 @@ Signed-off-by: Jakub Kicinski --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -5225,18 +5225,18 @@ bool skb_try_coalesce(struct sk_buff *to +@@ -5237,18 +5237,18 @@ bool skb_try_coalesce(struct sk_buff *to if (skb_cloned(to)) return false; diff --git a/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch index c94224cbd..8fd5094e8 100644 --- a/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch +++ b/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch @@ -1036,7 +1036,7 @@ Signed-off-by: David S. Miller u32 mahr = ravb_read(ndev, MAHR); u32 malr = ravb_read(ndev, MALR); -@@ -2202,7 +2204,7 @@ static int ravb_probe(struct platform_de +@@ -2205,7 +2207,7 @@ static int ravb_probe(struct platform_de priv->msg_enable = RAVB_DEF_MSG_ENABLE; /* Read and set MAC address */ @@ -1913,7 +1913,7 @@ Signed-off-by: David S. Miller eth_hw_addr_inherit(slave_dev, master); --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c -@@ -506,13 +506,14 @@ unsigned char * __weak arch_get_platform +@@ -496,13 +496,14 @@ unsigned char * __weak arch_get_platform int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr) { diff --git a/target/linux/generic/backport-5.10/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch b/target/linux/generic/backport-5.10/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch index a2168aaba..5402109e3 100644 --- a/target/linux/generic/backport-5.10/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch +++ b/target/linux/generic/backport-5.10/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | -@@ -1587,17 +1588,19 @@ ax88179_tx_fixup(struct usbnet *dev, str +@@ -1582,17 +1583,19 @@ ax88179_tx_fixup(struct usbnet *dev, str { u32 tx_hdr1, tx_hdr2; int frame_size = dev->maxpacket; @@ -57,7 +57,7 @@ Signed-off-by: David S. Miller if ((skb_header_cloned(skb) || headroom < 0) && pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) { dev_kfree_skb_any(skb); -@@ -1608,6 +1611,8 @@ ax88179_tx_fixup(struct usbnet *dev, str +@@ -1603,6 +1606,8 @@ ax88179_tx_fixup(struct usbnet *dev, str put_unaligned_le32(tx_hdr1, ptr); put_unaligned_le32(tx_hdr2, ptr + 4); diff --git a/target/linux/generic/backport-5.10/821-v5.13-let-pci-host-bridges-declar-their-reliance-on-msi-domains.patch b/target/linux/generic/backport-5.10/821-v5.13-let-pci-host-bridges-declar-their-reliance-on-msi-domains.patch index ee1acf4b9..9c3183c29 100644 --- a/target/linux/generic/backport-5.10/821-v5.13-let-pci-host-bridges-declar-their-reliance-on-msi-domains.patch +++ b/target/linux/generic/backport-5.10/821-v5.13-let-pci-host-bridges-declar-their-reliance-on-msi-domains.patch @@ -23,7 +23,7 @@ Acked-by: Bjorn Helgaas --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c -@@ -925,6 +925,8 @@ static int pci_register_host_bridge(stru +@@ -926,6 +926,8 @@ static int pci_register_host_bridge(stru device_enable_async_suspend(bus->bridge); pci_set_bus_of_node(bus); pci_set_bus_msi_domain(bus); @@ -34,7 +34,7 @@ Acked-by: Bjorn Helgaas set_dev_node(bus->bridge, pcibus_to_node(bus)); --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -548,6 +548,7 @@ struct pci_host_bridge { +@@ -554,6 +554,7 @@ struct pci_host_bridge { unsigned int native_dpc:1; /* OS may use PCIe DPC */ unsigned int preserve_config:1; /* Preserve FW resource setup */ unsigned int size_windows:1; /* Enable root bus sizing */ diff --git a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch b/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch index 2ea2e2497..8e4de36db 100644 --- a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch +++ b/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch @@ -73,7 +73,7 @@ Signed-off-by: Andrew Morton --- a/arch/Kconfig +++ b/arch/Kconfig -@@ -1299,6 +1299,14 @@ config ARCH_HAS_ELFCORE_COMPAT +@@ -1307,6 +1307,14 @@ config ARCH_HAS_ELFCORE_COMPAT config ARCH_HAS_PARANOID_L1D_FLUSH bool @@ -90,7 +90,7 @@ Signed-off-by: Andrew Morton source "scripts/gcc-plugins/Kconfig" --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -85,6 +85,7 @@ config X86 +@@ -86,6 +86,7 @@ config X86 select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL diff --git a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch b/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch index 85710eb79..ff4bb4df3 100644 --- a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch +++ b/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch @@ -552,7 +552,7 @@ Signed-off-by: Andrew Morton --- a/kernel/bounds.c +++ b/kernel/bounds.c @@ -22,6 +22,11 @@ int main(void) - DEFINE(NR_CPUS_BITS, bits_per(CONFIG_NR_CPUS)); + DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS)); #endif DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); +#ifdef CONFIG_LRU_GEN diff --git a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch b/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch index 8cd86e0fc..0c2822146 100644 --- a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch +++ b/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch @@ -156,7 +156,7 @@ Signed-off-by: Vinod Koul if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h -@@ -13,7 +13,6 @@ +@@ -15,7 +15,6 @@ struct usb_hcd; struct xhci_plat_priv { const char *firmware_name; unsigned long long quirks; diff --git a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch b/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch index a67669acf..c4b5c9e59 100644 --- a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch +++ b/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch @@ -25,7 +25,7 @@ Signed-off-by: Srinivas Kandagatla --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c -@@ -1175,6 +1175,34 @@ int __get_mtd_device(struct mtd_info *mt +@@ -1177,6 +1177,34 @@ int __get_mtd_device(struct mtd_info *mt EXPORT_SYMBOL_GPL(__get_mtd_device); /** diff --git a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch index f56a96858..8e5c71804 100644 --- a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch +++ b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch @@ -124,7 +124,7 @@ Signed-off-by: David S. Miller list_del(&dst->list); kfree(dst); } -@@ -805,7 +809,7 @@ static int dsa_switch_setup_tag_protocol +@@ -827,7 +831,7 @@ static int dsa_switch_setup_tag_protocol int port, err; if (tag_ops->proto == dst->default_proto) @@ -133,7 +133,7 @@ Signed-off-by: David S. Miller for (port = 0; port < ds->num_ports; port++) { if (!dsa_is_cpu_port(ds, port)) -@@ -821,6 +825,17 @@ static int dsa_switch_setup_tag_protocol +@@ -843,6 +847,17 @@ static int dsa_switch_setup_tag_protocol } } @@ -151,7 +151,7 @@ Signed-off-by: David S. Miller return 0; } -@@ -1132,6 +1147,46 @@ static void dsa_tree_teardown(struct dsa +@@ -1154,6 +1169,46 @@ static void dsa_tree_teardown(struct dsa dst->setup = false; } @@ -198,7 +198,7 @@ Signed-off-by: David S. Miller /* Since the dsa/tagging sysfs device attribute is per master, the assumption * is that all DSA switches within a tree share the same tagger, otherwise * they would have formed disjoint trees (different "dsa,member" values). -@@ -1164,12 +1219,15 @@ int dsa_tree_change_tag_proto(struct dsa +@@ -1186,12 +1241,15 @@ int dsa_tree_change_tag_proto(struct dsa goto out_unlock; } @@ -216,7 +216,7 @@ Signed-off-by: David S. Miller rtnl_unlock(); -@@ -1257,6 +1315,7 @@ static int dsa_port_parse_cpu(struct dsa +@@ -1279,6 +1337,7 @@ static int dsa_port_parse_cpu(struct dsa struct dsa_switch *ds = dp->ds; struct dsa_switch_tree *dst = ds->dst; enum dsa_tag_protocol default_proto; @@ -224,7 +224,7 @@ Signed-off-by: David S. Miller /* Find out which protocol the switch would prefer. */ default_proto = dsa_get_tag_protocol(dp, master); -@@ -1311,6 +1370,12 @@ static int dsa_port_parse_cpu(struct dsa +@@ -1333,6 +1392,12 @@ static int dsa_port_parse_cpu(struct dsa */ dsa_tag_driver_put(tag_ops); } else { diff --git a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch b/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch index 0c50ae6fb..8c81ebc7f 100644 --- a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch +++ b/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch @@ -101,7 +101,7 @@ Signed-off-by: David S. Miller list_del(&dst->list); kfree(dst); } -@@ -826,17 +822,29 @@ static int dsa_switch_setup_tag_protocol +@@ -848,17 +844,29 @@ static int dsa_switch_setup_tag_protocol } connect: @@ -132,7 +132,7 @@ Signed-off-by: David S. Miller } static int dsa_switch_setup(struct dsa_switch *ds) -@@ -1156,13 +1164,6 @@ static int dsa_tree_bind_tag_proto(struc +@@ -1178,13 +1186,6 @@ static int dsa_tree_bind_tag_proto(struc dst->tag_ops = tag_ops; @@ -146,7 +146,7 @@ Signed-off-by: David S. Miller /* Notify the switches from this tree about the connection * to the new tagger */ -@@ -1172,16 +1173,14 @@ static int dsa_tree_bind_tag_proto(struc +@@ -1194,16 +1195,14 @@ static int dsa_tree_bind_tag_proto(struc goto out_disconnect; /* Notify the old tagger about the disconnection from this tree */ @@ -167,7 +167,7 @@ Signed-off-by: David S. Miller dst->tag_ops = old_tag_ops; return err; -@@ -1315,7 +1314,6 @@ static int dsa_port_parse_cpu(struct dsa +@@ -1337,7 +1336,6 @@ static int dsa_port_parse_cpu(struct dsa struct dsa_switch *ds = dp->ds; struct dsa_switch_tree *dst = ds->dst; enum dsa_tag_protocol default_proto; @@ -175,7 +175,7 @@ Signed-off-by: David S. Miller /* Find out which protocol the switch would prefer. */ default_proto = dsa_get_tag_protocol(dp, master); -@@ -1370,12 +1368,6 @@ static int dsa_port_parse_cpu(struct dsa +@@ -1392,12 +1390,6 @@ static int dsa_port_parse_cpu(struct dsa */ dsa_tag_driver_put(tag_ops); } else { diff --git a/target/linux/generic/backport-5.15/702-v5.19-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch b/target/linux/generic/backport-5.15/702-v5.19-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch deleted file mode 100644 index 9f2512a1d..000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Mon, 7 Feb 2022 10:27:22 +0100 -Subject: [PATCH] arm64: dts: mediatek: mt7622: add support for coherent - DMA - -It improves performance by eliminating the need for a cache flush on rx and tx - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -357,7 +357,7 @@ - }; - - cci_control2: slave-if@5000 { -- compatible = "arm,cci-400-ctrl-if"; -+ compatible = "arm,cci-400-ctrl-if", "syscon"; - interface-type = "ace"; - reg = <0x5000 0x1000>; - }; -@@ -938,6 +938,8 @@ - power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; - mediatek,ethsys = <ðsys>; - mediatek,sgmiisys = <&sgmiisys>; -+ mediatek,cci-control = <&cci_control2>; -+ dma-coherent; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; diff --git a/target/linux/generic/backport-5.15/702-v5.19-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch b/target/linux/generic/backport-5.15/702-v5.19-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch deleted file mode 100644 index 2c6e3fd3c..000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Felix Fietkau -Date: Sat, 5 Feb 2022 18:36:36 +0100 -Subject: [PATCH] arm64: dts: mediatek: mt7622: introduce nodes for - Wireless Ethernet Dispatch - -Introduce wed0 and wed1 nodes in order to enable offloading forwarding -between ethernet and wireless devices on the mt7622 chipset. - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -894,6 +894,11 @@ - }; - }; - -+ hifsys: syscon@1af00000 { -+ compatible = "mediatek,mt7622-hifsys", "syscon"; -+ reg = <0 0x1af00000 0 0x70>; -+ }; -+ - ethsys: syscon@1b000000 { - compatible = "mediatek,mt7622-ethsys", - "syscon"; -@@ -912,6 +917,26 @@ - #dma-cells = <1>; - }; - -+ pcie_mirror: pcie-mirror@10000400 { -+ compatible = "mediatek,mt7622-pcie-mirror", -+ "syscon"; -+ reg = <0 0x10000400 0 0x10>; -+ }; -+ -+ wed0: wed@1020a000 { -+ compatible = "mediatek,mt7622-wed", -+ "syscon"; -+ reg = <0 0x1020a000 0 0x1000>; -+ interrupts = ; -+ }; -+ -+ wed1: wed@1020b000 { -+ compatible = "mediatek,mt7622-wed", -+ "syscon"; -+ reg = <0 0x1020b000 0 0x1000>; -+ interrupts = ; -+ }; -+ - eth: ethernet@1b100000 { - compatible = "mediatek,mt7622-eth", - "mediatek,mt2701-eth", -@@ -939,6 +964,9 @@ - mediatek,ethsys = <ðsys>; - mediatek,sgmiisys = <&sgmiisys>; - mediatek,cci-control = <&cci_control2>; -+ mediatek,wed = <&wed0>, <&wed1>; -+ mediatek,pcie-mirror = <&pcie_mirror>; -+ mediatek,hifsys = <&hifsys>; - dma-coherent; - #address-cells = <1>; - #size-cells = <0>; diff --git a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch b/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch index 70d46c16c..22125a454 100644 --- a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch +++ b/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch @@ -13,7 +13,7 @@ Signed-off-by: David S. Miller --- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -963,7 +963,7 @@ +@@ -957,7 +957,7 @@ power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; mediatek,ethsys = <ðsys>; mediatek,sgmiisys = <&sgmiisys>; diff --git a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch b/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch index bdb4a8315..f65b0cafa 100644 --- a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch +++ b/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch @@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -1404,27 +1404,31 @@ static int +@@ -1425,27 +1425,31 @@ static int mt7530_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *bridge) { @@ -65,7 +65,7 @@ Signed-off-by: Jakub Kicinski } /* Add the all other ports to this port matrix. */ -@@ -1529,24 +1533,28 @@ static void +@@ -1550,24 +1554,28 @@ static void mt7530_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *bridge) { diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch index 3f5b953a2..e04bb11e8 100644 --- a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch +++ b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2660,6 +2660,32 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2687,6 +2687,32 @@ mt7531_setup(struct dsa_switch *ds) return 0; } @@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni static bool mt7530_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -2696,6 +2722,37 @@ static bool mt7531_is_rgmii_port(struct +@@ -2723,6 +2749,37 @@ static bool mt7531_is_rgmii_port(struct return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); } @@ -94,7 +94,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -3172,6 +3229,18 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -3199,6 +3256,18 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, unsigned long *supported) -@@ -3407,6 +3476,7 @@ static const struct dsa_switch_ops mt753 +@@ -3435,6 +3504,7 @@ static const struct dsa_switch_ops mt753 .port_vlan_del = mt7530_port_vlan_del, .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .phylink_validate = mt753x_phylink_validate, .phylink_mac_link_state = mt753x_phylink_mac_link_state, .phylink_mac_config = mt753x_phylink_mac_config, -@@ -3424,6 +3494,7 @@ static const struct mt753x_info mt753x_t +@@ -3452,6 +3522,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -129,7 +129,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3435,6 +3506,7 @@ static const struct mt753x_info mt753x_t +@@ -3463,6 +3534,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -137,7 +137,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3447,6 +3519,7 @@ static const struct mt753x_info mt753x_t +@@ -3475,6 +3547,7 @@ static const struct mt753x_info mt753x_t .phy_write = mt7531_ind_phy_write, .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, @@ -145,7 +145,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7531_phy_mode_supported, .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, -@@ -3509,6 +3582,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3537,6 +3610,7 @@ mt7530_probe(struct mdio_device *mdiodev */ if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || @@ -155,7 +155,7 @@ Signed-off-by: Paolo Abeni !priv->info->mac_port_get_state || !priv->info->mac_port_config) --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -801,6 +801,8 @@ struct mt753x_info { +@@ -807,6 +807,8 @@ struct mt753x_info { int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface); int (*cpu_port_config)(struct dsa_switch *ds, int port); diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch index 60634aa0d..31be0e7be 100644 --- a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch +++ b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch @@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2686,37 +2686,6 @@ static void mt7530_mac_port_get_caps(str +@@ -2713,37 +2713,6 @@ static void mt7530_mac_port_get_caps(str } } @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) { return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); -@@ -2753,44 +2722,6 @@ static void mt7531_mac_port_get_caps(str +@@ -2780,44 +2749,6 @@ static void mt7531_mac_port_get_caps(str } } @@ -104,7 +104,7 @@ Signed-off-by: Paolo Abeni static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -3045,9 +2976,6 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -3072,9 +3003,6 @@ mt753x_phylink_mac_config(struct dsa_swi struct mt7530_priv *priv = ds->priv; u32 mcr_cur, mcr_new; @@ -114,7 +114,7 @@ Signed-off-by: Paolo Abeni switch (port) { case 0 ... 4: /* Internal phy */ if (state->interface != PHY_INTERFACE_MODE_GMII) -@@ -3263,12 +3191,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3290,12 +3218,6 @@ mt753x_phylink_validate(struct dsa_switc __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; struct mt7530_priv *priv = ds->priv; @@ -127,7 +127,7 @@ Signed-off-by: Paolo Abeni phylink_set_port_modes(mask); if (state->interface != PHY_INTERFACE_MODE_TRGMII && -@@ -3495,7 +3417,6 @@ static const struct mt753x_info mt753x_t +@@ -3523,7 +3445,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -135,7 +135,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3507,7 +3428,6 @@ static const struct mt753x_info mt753x_t +@@ -3535,7 +3456,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -143,7 +143,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3520,7 +3440,6 @@ static const struct mt753x_info mt753x_t +@@ -3548,7 +3468,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -151,7 +151,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, -@@ -3583,7 +3502,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3611,7 +3530,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || @@ -161,7 +161,7 @@ Signed-off-by: Paolo Abeni return -EINVAL; --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -803,8 +803,6 @@ struct mt753x_info { +@@ -809,8 +809,6 @@ struct mt753x_info { int (*cpu_port_config)(struct dsa_switch *ds, int port); void (*mac_port_get_caps)(struct dsa_switch *ds, int port, struct phylink_config *config); diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch index f98cf4c79..2a5d5ae9d 100644 --- a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch +++ b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3215,11 +3215,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3242,11 +3242,6 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch index a499b8e5b..ad672312e 100644 --- a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch +++ b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2793,12 +2793,13 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2820,12 +2820,13 @@ static int mt7531_rgmii_setup(struct mt7 } static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, @@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni phylink_set(supported, 2500baseX_Full); phylink_set(supported, 2500baseT_Full); } -@@ -3171,16 +3172,18 @@ static void mt753x_phylink_get_caps(stru +@@ -3198,16 +3199,18 @@ static void mt753x_phylink_get_caps(stru static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, @@ -58,7 +58,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -3203,12 +3206,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3230,12 +3233,13 @@ mt753x_phylink_validate(struct dsa_switc } /* This switch only supports 1G full-duplex. */ @@ -76,7 +76,7 @@ Signed-off-by: Paolo Abeni phylink_set(mask, Asym_Pause); --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -804,6 +804,7 @@ struct mt753x_info { +@@ -810,6 +810,7 @@ struct mt753x_info { void (*mac_port_get_caps)(struct dsa_switch *ds, int port, struct phylink_config *config); void (*mac_port_validate)(struct dsa_switch *ds, int port, diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch index b7fc06106..8d9802f1e 100644 --- a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch +++ b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2792,19 +2792,6 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2819,19 +2819,6 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -40,7 +40,7 @@ Signed-off-by: Paolo Abeni static void mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface, -@@ -3171,51 +3158,21 @@ static void mt753x_phylink_get_caps(stru +@@ -3198,51 +3185,21 @@ static void mt753x_phylink_get_caps(stru } static void @@ -97,7 +97,7 @@ Signed-off-by: Paolo Abeni linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); -@@ -3416,7 +3373,6 @@ static const struct mt753x_info mt753x_t +@@ -3444,7 +3401,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3427,7 +3383,6 @@ static const struct mt753x_info mt753x_t +@@ -3455,7 +3411,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3439,7 +3394,6 @@ static const struct mt753x_info mt753x_t +@@ -3467,7 +3422,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, .mac_pcs_an_restart = mt7531_sgmii_restart_an, -@@ -3501,7 +3455,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3529,7 +3483,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch index 7afa5be3d..149c12c1f 100644 --- a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch +++ b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch @@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni /* String, offset, and register size in bytes if different from 4 bytes */ static const struct mt7530_mib_desc mt7530_mib[] = { MIB_DESC(1, 0x00, "TxDrop"), -@@ -2792,12 +2797,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2819,12 +2824,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni unsigned int val; /* For adjusting speed and duplex of SGMII force mode. */ -@@ -2823,6 +2827,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw +@@ -2850,6 +2854,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw /* MT7531 SGMII 1G force mode can only work in full duplex mode, * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. @@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni */ if ((speed == SPEED_10 || speed == SPEED_100) && duplex != DUPLEX_FULL) -@@ -2898,9 +2905,10 @@ static int mt7531_sgmii_setup_mode_an(st +@@ -2925,9 +2932,10 @@ static int mt7531_sgmii_setup_mode_an(st return 0; } @@ -73,7 +73,7 @@ Signed-off-by: Paolo Abeni u32 val; /* Only restart AN when AN is enabled */ -@@ -2957,6 +2965,24 @@ mt753x_mac_config(struct dsa_switch *ds, +@@ -2984,6 +2992,24 @@ mt753x_mac_config(struct dsa_switch *ds, return priv->info->mac_port_config(ds, port, mode, state->interface); } @@ -98,7 +98,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state) -@@ -3018,17 +3044,6 @@ unsupported: +@@ -3045,17 +3071,6 @@ unsupported: mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); } @@ -116,7 +116,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -3038,16 +3053,13 @@ static void mt753x_phylink_mac_link_down +@@ -3065,16 +3080,13 @@ static void mt753x_phylink_mac_link_down mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); } @@ -139,7 +139,7 @@ Signed-off-by: Paolo Abeni } static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, -@@ -3060,8 +3072,6 @@ static void mt753x_phylink_mac_link_up(s +@@ -3087,8 +3099,6 @@ static void mt753x_phylink_mac_link_up(s struct mt7530_priv *priv = ds->priv; u32 mcr; @@ -148,7 +148,7 @@ Signed-off-by: Paolo Abeni mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; /* MT753x MAC works in 1G full duplex mode for all up-clocked -@@ -3139,6 +3149,8 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -3166,6 +3176,8 @@ mt7531_cpu_port_config(struct dsa_switch return ret; mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPU_PORT_SETTING(priv->id)); @@ -157,7 +157,7 @@ Signed-off-by: Paolo Abeni mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, speed, DUPLEX_FULL, true, true); -@@ -3178,16 +3190,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3205,16 +3217,13 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(state->advertising, state->advertising, mask); } @@ -178,7 +178,7 @@ Signed-off-by: Paolo Abeni pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); state->link = (pmsr & PMSR_LINK); -@@ -3214,8 +3223,6 @@ mt7530_phylink_mac_link_state(struct dsa +@@ -3241,8 +3250,6 @@ mt7530_phylink_mac_link_state(struct dsa state->pause |= MLO_PAUSE_RX; if (pmsr & PMSR_TX_FC) state->pause |= MLO_PAUSE_TX; @@ -187,7 +187,7 @@ Signed-off-by: Paolo Abeni } static int -@@ -3257,32 +3264,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3284,32 +3291,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -249,7 +249,7 @@ Signed-off-by: Paolo Abeni if (ret) return ret; -@@ -3295,6 +3319,13 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3322,6 +3346,13 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -263,7 +263,7 @@ Signed-off-by: Paolo Abeni return ret; } -@@ -3356,9 +3387,8 @@ static const struct dsa_switch_ops mt753 +@@ -3384,9 +3415,8 @@ static const struct dsa_switch_ops mt753 .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, .phylink_validate = mt753x_phylink_validate, @@ -274,7 +274,7 @@ Signed-off-by: Paolo Abeni .phylink_mac_link_down = mt753x_phylink_mac_link_down, .phylink_mac_link_up = mt753x_phylink_mac_link_up, .get_mac_eee = mt753x_get_mac_eee, -@@ -3368,36 +3398,34 @@ static const struct dsa_switch_ops mt753 +@@ -3396,36 +3426,34 @@ static const struct dsa_switch_ops mt753 static const struct mt753x_info mt753x_table[] = { [ID_MT7621] = { .id = ID_MT7621, @@ -314,7 +314,7 @@ Signed-off-by: Paolo Abeni }, }; -@@ -3455,7 +3483,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3483,7 +3511,7 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || @@ -325,7 +325,7 @@ Signed-off-by: Paolo Abeni priv->id = priv->info->id; --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -773,6 +773,12 @@ static const char *p5_intf_modes(unsigne +@@ -779,6 +779,12 @@ static const char *p5_intf_modes(unsigne struct mt7530_priv; @@ -338,7 +338,7 @@ Signed-off-by: Paolo Abeni /* struct mt753x_info - This is the main data structure for holding the specific * part for each supported device * @sw_setup: Holding the handler to a device initialization -@@ -784,18 +790,14 @@ struct mt7530_priv; +@@ -790,18 +796,14 @@ struct mt7530_priv; * port * @mac_port_validate: Holding the way to set addition validate type for a * certan MAC port @@ -359,7 +359,7 @@ Signed-off-by: Paolo Abeni int (*sw_setup)(struct dsa_switch *ds); int (*phy_read)(struct mt7530_priv *priv, int port, int regnum); int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); -@@ -806,15 +808,9 @@ struct mt753x_info { +@@ -812,15 +814,9 @@ struct mt753x_info { void (*mac_port_validate)(struct dsa_switch *ds, int port, phy_interface_t interface, unsigned long *supported); @@ -375,7 +375,7 @@ Signed-off-by: Paolo Abeni }; /* struct mt7530_priv - This is the main data structure for holding the state -@@ -856,6 +852,7 @@ struct mt7530_priv { +@@ -862,6 +858,7 @@ struct mt7530_priv { u8 mirror_tx; struct mt7530_port ports[MT7530_NUM_PORTS]; diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch index 7731c16c9..6e406ace0 100644 --- a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch +++ b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3169,25 +3169,16 @@ static void mt753x_phylink_get_caps(stru +@@ -3196,25 +3196,16 @@ static void mt753x_phylink_get_caps(stru priv->info->mac_port_get_caps(ds, port, config); } @@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni } static void mt7530_pcs_get_state(struct phylink_pcs *pcs, -@@ -3289,12 +3280,14 @@ static void mt7530_pcs_an_restart(struct +@@ -3316,12 +3307,14 @@ static void mt7530_pcs_an_restart(struct } static const struct phylink_pcs_ops mt7530_pcs_ops = { @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni .pcs_get_state = mt7531_pcs_get_state, .pcs_config = mt753x_pcs_config, .pcs_an_restart = mt7531_pcs_an_restart, -@@ -3386,7 +3379,6 @@ static const struct dsa_switch_ops mt753 +@@ -3414,7 +3407,6 @@ static const struct dsa_switch_ops mt753 .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch index bd35cb104..afcfcaba3 100644 --- a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch +++ b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch @@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3166,6 +3166,12 @@ static void mt753x_phylink_get_caps(stru +@@ -3193,6 +3193,12 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch index cff22b5ea..bf2938d03 100644 --- a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch +++ b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch @@ -81,7 +81,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3304,9 +3304,16 @@ static int +@@ -3331,9 +3331,16 @@ static int mt753x_setup(struct dsa_switch *ds) { struct mt7530_priv *priv = ds->priv; @@ -100,7 +100,7 @@ Signed-off-by: Jakub Kicinski if (ret) return ret; -@@ -3318,13 +3325,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3345,13 +3352,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch b/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch index c9f830381..320b5c1ef 100644 --- a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch +++ b/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch @@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -1750,11 +1750,11 @@ static void +@@ -1771,11 +1771,11 @@ static void mt7530_hw_vlan_add(struct mt7530_priv *priv, struct mt7530_hw_vlan_entry *entry) { @@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski /* Validate the entry with independent learning, create egress tag per * VLAN and joining the port as one of the port members. -@@ -1765,22 +1765,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p +@@ -1786,22 +1786,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p /* Decide whether adding tag or not for those outgoing packets from the * port inside the VLAN. @@ -72,7 +72,7 @@ Signed-off-by: Jakub Kicinski } static void -@@ -1799,11 +1797,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p +@@ -1820,11 +1818,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p return; } diff --git a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch b/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch index bb36302f2..eef19b4cb 100644 --- a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch +++ b/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch @@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -1254,6 +1254,7 @@ static int +@@ -1275,6 +1275,7 @@ static int mt7530_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy) { @@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski struct mt7530_priv *priv = ds->priv; mutex_lock(&priv->reg_mutex); -@@ -1262,7 +1263,11 @@ mt7530_port_enable(struct dsa_switch *ds +@@ -1283,7 +1284,11 @@ mt7530_port_enable(struct dsa_switch *ds * restore the port matrix if the port is the member of a certain * bridge. */ @@ -42,7 +42,7 @@ Signed-off-by: Jakub Kicinski priv->ports[port].enable = true; mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, priv->ports[port].pm); -@@ -1410,7 +1415,8 @@ mt7530_port_bridge_join(struct dsa_switc +@@ -1431,7 +1436,8 @@ mt7530_port_bridge_join(struct dsa_switc struct net_device *bridge) { struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; @@ -52,7 +52,7 @@ Signed-off-by: Jakub Kicinski struct mt7530_priv *priv = ds->priv; mutex_lock(&priv->reg_mutex); -@@ -1487,9 +1493,12 @@ mt7530_port_set_vlan_unaware(struct dsa_ +@@ -1508,9 +1514,12 @@ mt7530_port_set_vlan_unaware(struct dsa_ * the CPU port get out of VLAN filtering mode. */ if (all_user_ports_removed) { @@ -67,7 +67,7 @@ Signed-off-by: Jakub Kicinski | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); } } -@@ -1539,6 +1548,7 @@ mt7530_port_bridge_leave(struct dsa_swit +@@ -1560,6 +1569,7 @@ mt7530_port_bridge_leave(struct dsa_swit struct net_device *bridge) { struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; @@ -75,7 +75,7 @@ Signed-off-by: Jakub Kicinski struct mt7530_priv *priv = ds->priv; mutex_lock(&priv->reg_mutex); -@@ -1567,8 +1577,8 @@ mt7530_port_bridge_leave(struct dsa_swit +@@ -1588,8 +1598,8 @@ mt7530_port_bridge_leave(struct dsa_swit */ if (priv->ports[port].enable) mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, @@ -86,7 +86,7 @@ Signed-off-by: Jakub Kicinski /* When a port is removed from the bridge, the port would be set up * back to the default as is at initial boot which is a VLAN-unaware -@@ -1731,6 +1741,9 @@ static int +@@ -1752,6 +1762,9 @@ static int mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, struct netlink_ext_ack *extack) { @@ -96,7 +96,7 @@ Signed-off-by: Jakub Kicinski if (vlan_filtering) { /* The port is being kept as VLAN-unaware port when bridge is * set up with vlan_filtering not being set, Otherwise, the -@@ -1738,7 +1751,7 @@ mt7530_port_vlan_filtering(struct dsa_sw +@@ -1759,7 +1772,7 @@ mt7530_port_vlan_filtering(struct dsa_sw * for becoming a VLAN-aware port. */ mt7530_port_set_vlan_aware(ds, port); diff --git a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch b/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch new file mode 100644 index 000000000..e2a204644 --- /dev/null +++ b/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch @@ -0,0 +1,35 @@ +From 8110437e59616293228cd781c486d8495a61e36a Mon Sep 17 00:00:00 2001 +From: Yan Cangang +Date: Sun, 20 Nov 2022 13:52:58 +0800 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix resource leak in error path + +In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() failed, +mtk_mdio_cleanup() isn't called. Fix it. + +Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE") +Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support") +Signed-off-by: Yan Cangang +Reviewed-by: Leon Romanovsky +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev + eth->soc->offload_version, i); + if (!eth->ppe[i]) { + err = -ENOMEM; +- goto err_free_dev; ++ goto err_deinit_mdio; + } + } + + err = mtk_eth_offload_init(eth); + if (err) +- goto err_free_dev; ++ goto err_deinit_mdio; + } + + for (i = 0; i < MTK_MAX_DEVS; i++) { diff --git a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch b/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch new file mode 100644 index 000000000..13f0ed5a5 --- /dev/null +++ b/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch @@ -0,0 +1,107 @@ +From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001 +From: Yan Cangang +Date: Sun, 20 Nov 2022 13:52:59 +0800 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path + +In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed, +the rhashtable ppe->l2_flows isn't destroyed. Fix it. + +In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or +register_netdev() failed, have the same problem. Fix it. + +Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries") +Signed-off-by: Yan Cangang +Reviewed-by: Leon Romanovsky +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++---- + drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_ppe.h | 1 + + 3 files changed, 23 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev + eth->soc->offload_version, i); + if (!eth->ppe[i]) { + err = -ENOMEM; +- goto err_deinit_mdio; ++ goto err_deinit_ppe; + } + } + + err = mtk_eth_offload_init(eth); + if (err) +- goto err_deinit_mdio; ++ goto err_deinit_ppe; + } + + for (i = 0; i < MTK_MAX_DEVS; i++) { +@@ -4105,7 +4105,7 @@ static int mtk_probe(struct platform_dev + err = register_netdev(eth->netdev[i]); + if (err) { + dev_err(eth->dev, "error bringing up device\n"); +- goto err_deinit_mdio; ++ goto err_deinit_ppe; + } else + netif_info(eth, probe, eth->netdev[i], + "mediatek frame engine at 0x%08lx, irq %d\n", +@@ -4125,7 +4125,8 @@ static int mtk_probe(struct platform_dev + + return 0; + +-err_deinit_mdio: ++err_deinit_ppe: ++ mtk_ppe_deinit(eth); + mtk_mdio_cleanup(eth); + err_free_dev: + mtk_free_dev(eth); +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + MTK_PPE_ENTRIES * soc->foe_entry_size, + &ppe->foe_phys, GFP_KERNEL); + if (!foe) +- return NULL; ++ goto err_free_l2_flows; + + ppe->foe_table = foe; + +@@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + sizeof(*ppe->foe_flow); + ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL); + if (!ppe->foe_flow) +- return NULL; ++ goto err_free_l2_flows; + + mtk_ppe_debugfs_init(ppe, index); + + return ppe; ++ ++err_free_l2_flows: ++ rhashtable_destroy(&ppe->l2_flows); ++ return NULL; ++} ++ ++void mtk_ppe_deinit(struct mtk_eth *eth) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) { ++ if (!eth->ppe[i]) ++ return; ++ rhashtable_destroy(ð->ppe[i]->l2_flows); ++ } + } + + static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -304,6 +304,7 @@ struct mtk_ppe { + + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, + int version, int index); ++void mtk_ppe_deinit(struct mtk_eth *eth); + void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); + diff --git a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch index 5ab86bdd6..e75a4cc0d 100644 --- a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch +++ b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch @@ -237,8 +237,8 @@ Signed-off-by: Paolo Abeni { --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - int version, int index); +@@ -307,6 +307,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + void mtk_ppe_deinit(struct mtk_eth *eth); void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); +int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); diff --git a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch index 51e23f22e..34aa7b14c 100644 --- a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch +++ b/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4423,7 +4423,7 @@ static const struct mtk_soc_data mt7621_ +@@ -4424,7 +4424,7 @@ static const struct mtk_soc_data mt7621_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7621_CLKS_BITMAP, .required_pctl = false, @@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau .hash_offset = 2, .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { -@@ -4462,7 +4462,7 @@ static const struct mtk_soc_data mt7623_ +@@ -4463,7 +4463,7 @@ static const struct mtk_soc_data mt7623_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, diff --git a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch index 8935eb673..e05042c20 100644 --- a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch +++ b/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) #define MTK_FOE_IB2_MULTICAST_V2 BIT(13) #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e +@@ -352,6 +354,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e int sid); int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, int wdma_idx, int txq, int bss, int wcid); diff --git a/target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch deleted file mode 100644 index 44af9128b..000000000 --- a/target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code - on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -917,7 +917,13 @@ enum mkt_eth_capabilities { - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - --#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) -+#ifdef CONFIG_SOC_MT7621 -+#define MTK_CAP_MASK MTK_NETSYS_V2 -+#else -+#define MTK_CAP_MASK 0 -+#endif -+ -+#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x)) - - #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ - MTK_GMAC2_RGMII | MTK_SHARED_INT | \ diff --git a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch index e060d1d1a..b64f43436 100644 --- a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ b/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch @@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau /* CDMP Ingress Control Register */ #define MTK_CDMP_IG_CTRL 0x400 #define MTK_CDMP_STAG_EN BIT(0) -@@ -1166,6 +1172,8 @@ struct mtk_eth { +@@ -1160,6 +1166,8 @@ struct mtk_eth { int ip_align; diff --git a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch index 8d2991f45..598788d99 100644 --- a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch +++ b/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch @@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1070,11 +1070,13 @@ struct mtk_soc_data { +@@ -1064,11 +1064,13 @@ struct mtk_soc_data { * @regmap: The register map pointing at the range used to setup * SGMII modes * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap diff --git a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch index fda2d71f4..20a928f09 100644 --- a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch +++ b/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch @@ -34,7 +34,7 @@ mtk_eth_path_name(path), __func__, updated); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4750,6 +4750,26 @@ static const struct mtk_soc_data mt7629_ +@@ -4751,6 +4751,26 @@ static const struct mtk_soc_data mt7629_ }, }; @@ -61,7 +61,7 @@ static const struct mtk_soc_data mt7986_data = { .reg_map = &mt7986_reg_map, .ana_rgc3 = 0x128, -@@ -4792,6 +4812,7 @@ const struct of_device_id of_mtk_match[] +@@ -4793,6 +4813,7 @@ const struct of_device_id of_mtk_match[] { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, @@ -128,7 +128,7 @@ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -963,6 +987,11 @@ enum mkt_eth_capabilities { +@@ -957,6 +981,11 @@ enum mkt_eth_capabilities { MTK_MUX_U3_GMAC2_TO_QPHY | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) @@ -140,7 +140,7 @@ #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -@@ -1076,12 +1105,14 @@ struct mtk_soc_data { +@@ -1070,12 +1099,14 @@ struct mtk_soc_data { * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap * @interface: Currently configured interface mode * @pcs: Phylink PCS structure diff --git a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch index 8edfb7633..8f7620616 100644 --- a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch +++ b/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch @@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski } if (eth->soc->offload_version) { -@@ -4650,6 +4687,8 @@ err_deinit_hw: +@@ -4651,6 +4688,8 @@ err_deinit_hw: mtk_hw_deinit(eth); err_wed_exit: mtk_wed_exit(); @@ -228,7 +228,7 @@ Signed-off-by: Jakub Kicinski /* Infrasys subsystem config registers */ #define INFRA_MISC2 0x70c #define CO_QPHY_SEL BIT(0) -@@ -1105,31 +1046,6 @@ struct mtk_soc_data { +@@ -1099,31 +1040,6 @@ struct mtk_soc_data { /* currently no SoC has more than 2 macs */ #define MTK_MAX_DEVS 2 @@ -260,7 +260,7 @@ Signed-off-by: Jakub Kicinski /* struct mtk_eth - This is the main datasructure for holding the state * of the driver * @dev: The device pointer -@@ -1149,6 +1065,7 @@ struct mtk_sgmii { +@@ -1143,6 +1059,7 @@ struct mtk_sgmii { * MII modes * @infra: The register map pointing at the range used to setup * SGMII and GePHY path @@ -268,7 +268,7 @@ Signed-off-by: Jakub Kicinski * @pctl: The register map pointing at the range used to setup * GMAC port drive/slew values * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1189,8 +1106,8 @@ struct mtk_eth { +@@ -1183,8 +1100,8 @@ struct mtk_eth { u32 msg_enable; unsigned long sysclk; struct regmap *ethsys; @@ -279,7 +279,7 @@ Signed-off-by: Jakub Kicinski struct regmap *pctl; bool hwlro; refcount_t dma_refcnt; -@@ -1352,10 +1269,6 @@ void mtk_stats_update_mac(struct mtk_mac +@@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); u32 mtk_r32(struct mtk_eth *eth, unsigned reg); diff --git a/target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch b/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch similarity index 90% rename from target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch rename to target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch index 30839319c..7742b0925 100644 --- a/target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch +++ b/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -523,6 +523,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp +@@ -464,6 +464,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp hwe->ib1 &= ~MTK_FOE_IB1_STATE; hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); dma_wmb(); diff --git a/target/linux/generic/backport-5.15/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch similarity index 100% rename from target/linux/generic/backport-5.15/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch rename to target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch diff --git a/target/linux/generic/backport-5.15/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch similarity index 100% rename from target/linux/generic/backport-5.15/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch rename to target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch diff --git a/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch similarity index 94% rename from target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch rename to target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch index c830034c4..e4022ffbd 100644 --- a/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch +++ b/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch @@ -53,7 +53,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4691,8 +4691,8 @@ static int mtk_probe(struct platform_dev +@@ -4637,8 +4637,8 @@ static int mtk_probe(struct platform_dev for (i = 0; i < num_ppe; i++) { u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; @@ -64,7 +64,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov if (!eth->ppe[i]) { err = -ENOMEM; goto err_deinit_ppe; -@@ -4818,6 +4818,7 @@ static const struct mtk_soc_data mt7622_ +@@ -4764,6 +4764,7 @@ static const struct mtk_soc_data mt7622_ .required_pctl = false, .offload_version = 2, .hash_offset = 2, @@ -72,7 +72,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), -@@ -4855,6 +4856,7 @@ static const struct mtk_soc_data mt7629_ +@@ -4801,6 +4802,7 @@ static const struct mtk_soc_data mt7629_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7629_CLKS_BITMAP, .required_pctl = false, @@ -80,7 +80,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4875,6 +4877,7 @@ static const struct mtk_soc_data mt7981_ +@@ -4821,6 +4823,7 @@ static const struct mtk_soc_data mt7981_ .offload_version = 2, .hash_offset = 4, .foe_entry_size = sizeof(struct mtk_foe_entry), @@ -88,7 +88,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .txrx = { .txd_size = sizeof(struct mtk_tx_dma_v2), .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4895,6 +4898,7 @@ static const struct mtk_soc_data mt7986_ +@@ -4841,6 +4844,7 @@ static const struct mtk_soc_data mt7986_ .offload_version = 2, .hash_offset = 4, .foe_entry_size = sizeof(struct mtk_foe_entry), @@ -98,7 +98,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .rxd_size = sizeof(struct mtk_rx_dma_v2), --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1017,6 +1017,8 @@ struct mtk_reg_map { +@@ -1008,6 +1008,8 @@ struct mtk_reg_map { * the extra setup for those pins used by GMAC. * @hash_offset Flow table hash offset. * @foe_entry_size Foe table entry size. @@ -107,7 +107,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov * @txd_size Tx DMA descriptor size. * @rxd_size Rx DMA descriptor size. * @rx_irq_done_mask Rx irq done register mask. -@@ -1034,6 +1036,7 @@ struct mtk_soc_data { +@@ -1025,6 +1027,7 @@ struct mtk_soc_data { u8 hash_offset; u16 foe_entry_size; netdev_features_t hw_features; @@ -166,7 +166,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) { ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); -@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp +@@ -465,6 +507,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); dma_wmb(); mtk_ppe_cache_clear(ppe); @@ -180,7 +180,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov } entry->hash = 0xffff; -@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -572,6 +621,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p wmb(); hwe->ib1 = entry->ib1; @@ -190,7 +190,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov dma_wmb(); mtk_ppe_cache_clear(ppe); -@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe +@@ -763,11 +815,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe return mtk_ppe_wait_busy(ppe); } @@ -232,7 +232,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov struct mtk_ppe *ppe; u32 foe_flow_size; void *foe; -@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -784,7 +864,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ ppe->base = base; ppe->eth = eth; ppe->dev = dev; @@ -242,7 +242,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * soc->foe_entry_size, -@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -800,6 +881,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ if (!ppe->foe_flow) goto err_free_l2_flows; @@ -266,7 +266,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov mtk_ppe_debugfs_init(ppe, index); return ppe; -@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) +@@ -929,6 +1027,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); } diff --git a/target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch similarity index 92% rename from target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch rename to target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch index 3dfa193e7..3a02c3a71 100644 --- a/target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch +++ b/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -646,6 +646,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -605,6 +605,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p struct mtk_eth *eth = ppe->eth; u16 timestamp = mtk_eth_timestamp(eth); struct mtk_foe_entry *hwe; @@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -@@ -662,8 +663,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -621,8 +622,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p wmb(); hwe->ib1 = entry->ib1; diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch similarity index 100% rename from target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch rename to target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch diff --git a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch new file mode 100644 index 000000000..2704faec1 --- /dev/null +++ b/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch @@ -0,0 +1,31 @@ +From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 19 Jul 2023 01:39:36 +0100 +Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always + mtk_get_ib1_pkt_type + +entries and bind debugfs files would display wrong data on NETSYS_V2 and +later because instead of using mtk_get_ib1_pkt_type the driver would use +MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs. +Use mtk_get_ib1_pkt_type so entries and bind records display correctly. + +Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986") +Signed-off-by: Daniel Golle +Acked-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file + + acct = mtk_foe_entry_get_mib(ppe, i, NULL); + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); + seq_printf(m, "%05x %s %7s", i, + mtk_foe_entry_state_str(state), + mtk_foe_pkt_type_str(type)); diff --git a/target/linux/generic/backport-5.15/741-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch b/target/linux/generic/backport-5.15/741-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch deleted file mode 100644 index 02407da8a..000000000 --- a/target/linux/generic/backport-5.15/741-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch +++ /dev/null @@ -1,85 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:28:59 +0200 -Subject: [PATCH] netfilter: flowtable: validate pppoe header - -Ensure there is sufficient room to access the protocol field of the -PPPoe header. Validate it once before the flowtable lookup, then use a -helper function to access protocol field. - -Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -318,7 +318,7 @@ int nf_flow_rule_route_ipv6(struct net * - int nf_flow_table_offload_init(void); - void nf_flow_table_offload_exit(void); - --static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb) -+static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb) - { - __be16 proto; - -@@ -334,4 +334,14 @@ static inline __be16 nf_flow_pppoe_proto - return 0; - } - -+static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto) -+{ -+ if (!pskb_may_pull(skb, PPPOE_SES_HLEN)) -+ return false; -+ -+ *inner_proto = __nf_flow_pppoe_proto(skb); -+ -+ return true; -+} -+ - #endif /* _NF_FLOW_TABLE_H */ ---- a/net/netfilter/nf_flow_table_inet.c -+++ b/net/netfilter/nf_flow_table_inet.c -@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st - proto = veth->h_vlan_encapsulated_proto; - break; - case htons(ETH_P_PPP_SES): -- proto = nf_flow_pppoe_proto(skb); -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; - break; - default: - proto = skb->protocol; ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -246,10 +246,11 @@ static unsigned int nf_flow_xmit_xfrm(st - return NF_STOLEN; - } - --static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto, -+static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto, - u32 *offset) - { - struct vlan_ethhdr *veth; -+ __be16 inner_proto; - - switch (skb->protocol) { - case htons(ETH_P_8021Q): -@@ -260,7 +261,8 @@ static bool nf_flow_skb_encap_protocol(c - } - break; - case htons(ETH_P_PPP_SES): -- if (nf_flow_pppoe_proto(skb) == proto) { -+ if (nf_flow_pppoe_proto(skb, &inner_proto) && -+ inner_proto == proto) { - *offset += PPPOE_SES_HLEN; - return true; - } -@@ -289,7 +291,7 @@ static void nf_flow_encap_pop(struct sk_ - skb_reset_network_header(skb); - break; - case htons(ETH_P_PPP_SES): -- skb->protocol = nf_flow_pppoe_proto(skb); -+ skb->protocol = __nf_flow_pppoe_proto(skb); - skb_pull(skb, PPPOE_SES_HLEN); - skb_reset_network_header(skb); - break; diff --git a/target/linux/generic/backport-5.15/741-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch b/target/linux/generic/backport-5.15/741-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch deleted file mode 100644 index 3b822b169..000000000 --- a/target/linux/generic/backport-5.15/741-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:29:00 +0200 -Subject: [PATCH] netfilter: flowtable: incorrect pppoe tuple - -pppoe traffic reaching ingress path does not match the flowtable entry -because the pppoe header is expected to be at the network header offset. -This bug causes a mismatch in the flow table lookup, so pppoe packets -enter the classical forwarding path. - -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -156,7 +156,7 @@ static void nf_flow_tuple_encap(struct s - tuple->encap[i].proto = skb->protocol; - break; - case htons(ETH_P_PPP_SES): -- phdr = (struct pppoe_hdr *)skb_mac_header(skb); -+ phdr = (struct pppoe_hdr *)skb_network_header(skb); - tuple->encap[i].id = ntohs(phdr->sid); - tuple->encap[i].proto = skb->protocol; - break; diff --git a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch new file mode 100644 index 000000000..25ac8db91 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch @@ -0,0 +1,78 @@ +From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 19 Jul 2023 12:29:49 +0200 +Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE + macros + +Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more +explicit foe_entry size for different chipset revisions. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++----- + drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4713,7 +4713,7 @@ static const struct mtk_soc_data mt7621_ + .required_pctl = false, + .offload_version = 1, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4734,7 +4734,7 @@ static const struct mtk_soc_data mt7622_ + .offload_version = 2, + .hash_offset = 2, + .has_accounting = true, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4753,7 +4753,7 @@ static const struct mtk_soc_data mt7623_ + .required_pctl = true, + .offload_version = 1, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4791,8 +4791,8 @@ static const struct mtk_soc_data mt7981_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 4, +- .foe_entry_size = sizeof(struct mtk_foe_entry), + .has_accounting = true, ++ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +@@ -4812,8 +4812,8 @@ static const struct mtk_soc_data mt7986_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 4, +- .foe_entry_size = sizeof(struct mtk_foe_entry), + .has_accounting = true, ++ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd { + struct mtk_foe_mac_info l2; + }; + ++#define MTK_FOE_ENTRY_V1_SIZE 80 ++#define MTK_FOE_ENTRY_V2_SIZE 96 ++ + struct mtk_foe_entry { + u32 ib1; + diff --git a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch new file mode 100644 index 000000000..97209958a --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch @@ -0,0 +1,141 @@ +From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Sat, 22 Jul 2023 21:32:49 +0100 +Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL + configuration + +MT7623 GMAC0 attempts to configure the system clocking according to the +required speed in the .mac_config callback for non-SGMII, non-baseX and +non-TRGMII modes. + +state->speed setting has never been reliable in the .mac_config +callback - there are cases where this is not the link speed, +particularly via ethtool paths, so this has always been unreliable (as +detailed in phylink's documentation.) + +There is the additional issue that mtk_gmac0_rgmii_adjust() will only +be called if state->interface changes, which means it only configures +the system clocking on the very first .mac_config call, which will be +made when the network device is first brought up before any link is +established. + +Essentially, this code is incredibly buggy, and probably never worked. + +Moreover, checking the in-kernel DT files, it seems no platform makes +use of this code path. + +Therefore, let's remove it, and disable interface modes for port 0 that +are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623. + +Reviewed-by: Daniel Golle +Tested-by: Daniel Golle +Tested-by: Frank Wunderlich +Signed-off-by: Russell King (Oracle) +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++--------------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + + 2 files changed, 17 insertions(+), 38 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -309,7 +309,7 @@ static int mt7621_gmac0_rgmii_adjust(str + } + + static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, +- phy_interface_t interface, int speed) ++ phy_interface_t interface) + { + u32 val; + int ret; +@@ -323,26 +323,7 @@ static void mtk_gmac0_rgmii_adjust(struc + return; + } + +- val = (speed == SPEED_1000) ? +- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100; +- mtk_w32(eth, val, INTF_MODE); +- +- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0, +- ETHSYS_TRGMII_CLK_SEL362_5, +- ETHSYS_TRGMII_CLK_SEL362_5); +- +- val = (speed == SPEED_1000) ? 250000000 : 500000000; +- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val); +- if (ret) +- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret); +- +- val = (speed == SPEED_1000) ? +- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100; +- mtk_w32(eth, val, TRGMII_RCK_CTRL); +- +- val = (speed == SPEED_1000) ? +- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100; +- mtk_w32(eth, val, TRGMII_TCK_CTRL); ++ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); + } + + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, +@@ -428,17 +409,8 @@ static void mtk_mac_config(struct phylin + state->interface)) + goto err_phy; + } else { +- /* FIXME: this is incorrect. Not only does it +- * use state->speed (which is not guaranteed +- * to be correct) but it also makes use of it +- * in a code path that will only be reachable +- * when the PHY interface mode changes, not +- * when the speed changes. Consequently, RGMII +- * is probably broken. +- */ + mtk_gmac0_rgmii_adjust(mac->hw, +- state->interface, +- state->speed); ++ state->interface); + + /* mt7623_pad_clk_setup */ + for (i = 0 ; i < NUM_TRGMII_CTRL; i++) +@@ -4288,13 +4260,19 @@ static int mtk_add_mac(struct mtk_eth *e + mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; + +- __set_bit(PHY_INTERFACE_MODE_MII, +- mac->phylink_config.supported_interfaces); +- __set_bit(PHY_INTERFACE_MODE_GMII, +- mac->phylink_config.supported_interfaces); ++ /* MT7623 gmac0 is now missing its speed-specific PLL configuration ++ * in its .mac_config method (since state->speed is not valid there. ++ * Disable support for MII, GMII and RGMII. ++ */ ++ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) { ++ __set_bit(PHY_INTERFACE_MODE_MII, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_GMII, ++ mac->phylink_config.supported_interfaces); + +- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) +- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); ++ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) ++ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); ++ } + + if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id) + __set_bit(PHY_INTERFACE_MODE_TRGMII, +@@ -4754,6 +4732,7 @@ static const struct mtk_soc_data mt7623_ + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, ++ .disable_pll_modes = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1027,6 +1027,7 @@ struct mtk_soc_data { + u16 foe_entry_size; + netdev_features_t hw_features; + bool has_accounting; ++ bool disable_pll_modes; + struct { + u32 txd_size; + u32 rxd_size; diff --git a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch new file mode 100644 index 000000000..e1b12725b --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch @@ -0,0 +1,81 @@ +From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Sat, 22 Jul 2023 21:32:54 +0100 +Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state + and modernise + +Remove the .mac_pcs_get_state function, since as far as I can tell is +never called - no DT appears to specify an in-band-status management +nor SFP support for this driver. + +Removal of this, along with the previous patch to remove the incorrect +clocking configuration, means that the driver becomes non-legacy, so +we can remove the "legacy_pre_march2020" status from this driver. + +Reviewed-by: Daniel Golle +Tested-by: Daniel Golle +Tested-by: Frank Wunderlich +Signed-off-by: Russell King (Oracle) +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 --------------------- + 1 file changed, 35 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -511,38 +511,6 @@ static int mtk_mac_finish(struct phylink + return 0; + } + +-static void mtk_mac_pcs_get_state(struct phylink_config *config, +- struct phylink_link_state *state) +-{ +- struct mtk_mac *mac = container_of(config, struct mtk_mac, +- phylink_config); +- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); +- +- state->link = (pmsr & MAC_MSR_LINK); +- state->duplex = (pmsr & MAC_MSR_DPX) >> 1; +- +- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) { +- case 0: +- state->speed = SPEED_10; +- break; +- case MAC_MSR_SPEED_100: +- state->speed = SPEED_100; +- break; +- case MAC_MSR_SPEED_1000: +- state->speed = SPEED_1000; +- break; +- default: +- state->speed = SPEED_UNKNOWN; +- break; +- } +- +- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); +- if (pmsr & MAC_MSR_RX_FC) +- state->pause |= MLO_PAUSE_RX; +- if (pmsr & MAC_MSR_TX_FC) +- state->pause |= MLO_PAUSE_TX; +-} +- + static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, + phy_interface_t interface) + { +@@ -665,7 +633,6 @@ static void mtk_mac_link_up(struct phyli + static const struct phylink_mac_ops mtk_phylink_ops = { + .validate = phylink_generic_validate, + .mac_select_pcs = mtk_mac_select_pcs, +- .mac_pcs_get_state = mtk_mac_pcs_get_state, + .mac_config = mtk_mac_config, + .mac_finish = mtk_mac_finish, + .mac_link_down = mtk_mac_link_down, +@@ -4255,8 +4222,6 @@ static int mtk_add_mac(struct mtk_eth *e + + mac->phylink_config.dev = ð->netdev[id]->dev; + mac->phylink_config.type = PHYLINK_NETDEV; +- /* This driver makes use of state->speed in mac_config */ +- mac->phylink_config.legacy_pre_march2020 = true; + mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; + diff --git a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch new file mode 100644 index 000000000..5875401b4 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch @@ -0,0 +1,550 @@ +From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:52:02 +0100 +Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in + mtk_soc_data + +Introduce version field in mtk_soc_data data structure in order to +make mtk_eth driver easier to maintain for chipset configuration +codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities. +This is a preliminary patch to introduce support for MT7988 SoC. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++-------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++----- + drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++--- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +- + drivers/net/ethernet/mediatek/mtk_wed.c | 4 +- + 5 files changed, 66 insertions(+), 49 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -536,7 +536,7 @@ static void mtk_set_queue_speed(struct m + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v1(eth)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + + if (IS_ENABLED(CONFIG_SOC_MT7621)) { +@@ -911,7 +911,7 @@ static bool mtk_rx_get_desc(struct mtk_e + rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); + rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); + rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); + rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); + } +@@ -969,7 +969,7 @@ static int mtk_init_fq_dma(struct mtk_et + + txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); + txd->txd4 = 0; +- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + txd->txd5 = 0; + txd->txd6 = 0; + txd->txd7 = 0; +@@ -1158,7 +1158,7 @@ static void mtk_tx_set_dma_desc(struct n + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mtk_tx_set_dma_desc_v2(dev, txd, info); + else + mtk_tx_set_dma_desc_v1(dev, txd, info); +@@ -1465,7 +1465,7 @@ static void mtk_update_rx_cpu_idx(struct + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) + { +- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); ++ return eth->soc->version == 2; + } + + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, +@@ -1805,7 +1805,7 @@ static int mtk_poll_rx(struct napi_struc + break; + + /* find out which mac the packet come from. values start at 1 */ +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; + else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && + !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) +@@ -1901,7 +1901,7 @@ static int mtk_poll_rx(struct napi_struc + skb->dev = netdev; + bytes += skb->len; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); + hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; + if (hash != MTK_RXD5_FOE_ENTRY) +@@ -1926,8 +1926,8 @@ static int mtk_poll_rx(struct napi_struc + /* When using VLAN untagging in combination with DSA, the + * hardware treats the MTK special tag as a VLAN and untags it. + */ +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && +- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { ++ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) && ++ netdev_uses_dsa(netdev)) { + unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); + + if (port < ARRAY_SIZE(eth->dsa_meta) && +@@ -2231,7 +2231,7 @@ static int mtk_tx_alloc(struct mtk_eth * + txd->txd2 = next_ptr; + txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; + txd->txd4 = 0; +- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + txd->txd5 = 0; + txd->txd6 = 0; + txd->txd7 = 0; +@@ -2284,14 +2284,14 @@ static int mtk_tx_alloc(struct mtk_eth * + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v1(eth)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); + ofs += MTK_QTX_OFFSET; + } + val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); + } else { + mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); +@@ -2418,7 +2418,7 @@ static int mtk_rx_alloc(struct mtk_eth * + + rxd->rxd3 = 0; + rxd->rxd4 = 0; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + rxd->rxd5 = 0; + rxd->rxd6 = 0; + rxd->rxd7 = 0; +@@ -2969,7 +2969,7 @@ static int mtk_start_dma(struct mtk_eth + MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | + MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + val |= MTK_MUTLI_CNT | MTK_RESV_BUF | + MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | + MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; +@@ -3113,7 +3113,7 @@ static int mtk_open(struct net_device *d + phylink_start(mac->phylink); + netif_tx_start_all_queues(dev); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return 0; + + if (mtk_uses_dsa(dev) && !eth->prog) { +@@ -3378,7 +3378,7 @@ static void mtk_hw_reset(struct mtk_eth + { + u32 val; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); + val = RSTCTRL_PPE0_V2; + } else { +@@ -3390,7 +3390,7 @@ static void mtk_hw_reset(struct mtk_eth + + ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, + 0x3ffffff); + } +@@ -3416,7 +3416,7 @@ static void mtk_hw_warm_reset(struct mtk + return; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; + else + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; +@@ -3586,7 +3586,7 @@ static int mtk_hw_init(struct mtk_eth *e + else + mtk_hw_reset(eth); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + /* Set FE to PDMAv2 if necessary */ + val = mtk_r32(eth, MTK_FE_GLO_MISC); + mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); +@@ -3623,7 +3623,7 @@ static int mtk_hw_init(struct mtk_eth *e + */ + val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); + mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v1(eth)) { + val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); + +@@ -3645,7 +3645,7 @@ static int mtk_hw_init(struct mtk_eth *e + mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); + mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + /* PSE should not drop port8 and port9 packets from WDMA Tx */ + mtk_w32(eth, 0x00000300, PSE_DROP_CFG); + +@@ -4434,7 +4434,7 @@ static int mtk_probe(struct platform_dev + } + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; +@@ -4542,9 +4542,8 @@ static int mtk_probe(struct platform_dev + } + + if (eth->soc->offload_version) { +- u32 num_ppe; ++ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1; + +- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; + num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); + for (i = 0; i < num_ppe; i++) { + u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; +@@ -4638,6 +4637,7 @@ static const struct mtk_soc_data mt2701_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4654,6 +4654,7 @@ static const struct mtk_soc_data mt7621_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7621_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, +@@ -4674,6 +4675,7 @@ static const struct mtk_soc_data mt7622_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7622_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .offload_version = 2, + .hash_offset = 2, + .has_accounting = true, +@@ -4694,6 +4696,7 @@ static const struct mtk_soc_data mt7623_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, ++ .version = 1, + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, +@@ -4716,6 +4719,7 @@ static const struct mtk_soc_data mt7629_ + .required_clks = MT7629_CLKS_BITMAP, + .required_pctl = false, + .has_accounting = true, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4733,6 +4737,7 @@ static const struct mtk_soc_data mt7981_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7981_CLKS_BITMAP, + .required_pctl = false, ++ .version = 2, + .offload_version = 2, + .hash_offset = 4, + .has_accounting = true, +@@ -4754,6 +4759,7 @@ static const struct mtk_soc_data mt7986_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, ++ .version = 2, + .offload_version = 2, + .hash_offset = 4, + .has_accounting = true, +@@ -4774,6 +4780,7 @@ static const struct mtk_soc_data rt5350_ + .hw_features = MTK_HW_FEATURES_MT7628, + .required_clks = MT7628_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -817,7 +817,6 @@ enum mkt_eth_capabilities { + MTK_SHARED_INT_BIT, + MTK_TRGMII_MT7621_CLK_BIT, + MTK_QDMA_BIT, +- MTK_NETSYS_V2_BIT, + MTK_SOC_MT7628_BIT, + MTK_RSTCTRL_PPE1_BIT, + MTK_U3_COPHY_V2_BIT, +@@ -852,7 +851,6 @@ enum mkt_eth_capabilities { + #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) + #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) + #define MTK_QDMA BIT(MTK_QDMA_BIT) +-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) + #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) + #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) + #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) +@@ -931,11 +929,11 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1006,6 +1004,7 @@ struct mtk_reg_map { + * @required_pctl A bool value to show whether the SoC requires + * the extra setup for those pins used by GMAC. + * @hash_offset Flow table hash offset. ++ * @version SoC version. + * @foe_entry_size Foe table entry size. + * @has_accounting Bool indicating support for accounting of + * offloaded flows. +@@ -1024,6 +1023,7 @@ struct mtk_soc_data { + bool required_pctl; + u8 offload_version; + u8 hash_offset; ++ u8 version; + u16 foe_entry_size; + netdev_features_t hw_features; + bool has_accounting; +@@ -1180,6 +1180,16 @@ struct mtk_mac { + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; + ++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) ++{ ++ return eth->soc->version == 1; ++} ++ ++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) ++{ ++ return eth->soc->version > 1; ++} ++ + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) + { +@@ -1190,7 +1200,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u + + static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_TIMESTAMP_V2; + + return MTK_FOE_IB1_BIND_TIMESTAMP; +@@ -1198,7 +1208,7 @@ static inline u32 mtk_get_ib1_ts_mask(st + + static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_PPPOE_V2; + + return MTK_FOE_IB1_BIND_PPPOE; +@@ -1206,7 +1216,7 @@ static inline u32 mtk_get_ib1_ppoe_mask( + + static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_VLAN_TAG_V2; + + return MTK_FOE_IB1_BIND_VLAN_TAG; +@@ -1214,7 +1224,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m + + static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; + + return MTK_FOE_IB1_BIND_VLAN_LAYER; +@@ -1222,7 +1232,7 @@ static inline u32 mtk_get_ib1_vlan_layer + + static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); + + return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); +@@ -1230,7 +1240,7 @@ static inline u32 mtk_prep_ib1_vlan_laye + + static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); + + return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); +@@ -1238,7 +1248,7 @@ static inline u32 mtk_get_ib1_vlan_layer + + static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_PACKET_TYPE_V2; + + return MTK_FOE_IB1_PACKET_TYPE; +@@ -1246,7 +1256,7 @@ static inline u32 mtk_get_ib1_pkt_type_m + + static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); + + return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); +@@ -1254,7 +1264,7 @@ static inline u32 mtk_get_ib1_pkt_type(s + + static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB2_MULTICAST_V2; + + return MTK_FOE_IB2_MULTICAST; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth + + memset(entry, 0, sizeof(*entry)); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | + FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | + FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + u32 val = *ib2; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + val &= ~MTK_FOE_IB2_DEST_PORT_V2; + val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); + } else { +@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et + struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | + MTK_FOE_IB2_WDMA_WINFO_V2; +@@ -452,7 +452,7 @@ int mtk_foe_entry_set_queue(struct mtk_e + { + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + *ib2 &= ~MTK_FOE_IB2_QID_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); + *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; +@@ -607,7 +607,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + struct mtk_foe_entry *hwe; + u32 val; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; + entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, + timestamp); +@@ -623,7 +623,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + hwe->ib1 = entry->ib1; + + if (ppe->accounting) { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + val = MTK_FOE_IB2_MIB_CNT_V2; + else + val = MTK_FOE_IB2_MIB_CNT; +@@ -971,7 +971,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_SCAN_MODE_CHECK_AGE) | + FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, + MTK_PPE_ENTRIES_SHIFT); +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_TB_CFG_INFO_SEL; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + +@@ -987,7 +987,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_FLOW_CFG_IP4_NAPT | + MTK_PPE_FLOW_CFG_IP4_DSLITE | + MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | + MTK_PPE_MD_TOAP_BYP_CRSN1 | + MTK_PPE_MD_TOAP_BYP_CRSN2 | +@@ -1029,7 +1029,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); + +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) { + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); + ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); + } +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et + if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { + mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, + info.bss, info.wcid); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + switch (info.wdma_idx) { + case 0: + pse_port = 8; +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1091,7 +1091,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * + } else { + struct mtk_eth *eth = dev->hw->eth; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + wed_set(dev, MTK_WED_RESET_IDX, + MTK_WED_RESET_IDX_RX_V2); + else +@@ -1813,7 +1813,7 @@ void mtk_wed_add_hw(struct device_node * + hw->wdma = wdma; + hw->index = index; + hw->irq = irq; +- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; ++ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; + + if (hw->version == 1) { + hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, diff --git a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch new file mode 100644 index 000000000..5a08b9ddd --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch @@ -0,0 +1,29 @@ +From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:52:27 +0100 +Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3 + +This is a preliminary patch to add MT7988 SoC support since it runs 3 +macs instead of 2. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1040,8 +1040,8 @@ struct mtk_soc_data { + + #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) + +-/* currently no SoC has more than 2 macs */ +-#define MTK_MAX_DEVS 2 ++/* currently no SoC has more than 3 macs */ ++#define MTK_MAX_DEVS 3 + + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver diff --git a/target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch b/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch similarity index 50% rename from target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch rename to target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch index ade8e8936..faa8734c2 100644 --- a/target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch +++ b/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch @@ -1,143 +1,176 @@ -From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001 +From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:35 +0000 -Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove - MTK_MAC_COUNT +Date: Tue, 25 Jul 2023 01:52:44 +0100 +Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and + remove MTK_MAC_COUNT -Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs. +Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++----------- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++--------- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 15 insertions(+), 16 deletions(-) + 2 files changed, 27 insertions(+), 23 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -943,7 +943,7 @@ static void mtk_stats_update(struct mtk_ +@@ -837,7 +837,7 @@ static void mtk_stats_update(struct mtk_ { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->mac[i] || !eth->mac[i]->hw_stats) continue; if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) { -@@ -1448,7 +1448,7 @@ static int mtk_queue_stopped(struct mtk_ +@@ -1340,7 +1340,7 @@ static int mtk_queue_stopped(struct mtk_ { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; if (netif_queue_stopped(eth->netdev[i])) -@@ -1462,7 +1462,7 @@ static void mtk_wake_queue(struct mtk_et +@@ -1354,7 +1354,7 @@ static void mtk_wake_queue(struct mtk_et { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; netif_tx_wake_all_queues(eth->netdev[i]); -@@ -1955,7 +1955,7 @@ static int mtk_poll_rx(struct napi_struc +@@ -1811,7 +1811,7 @@ static int mtk_poll_rx(struct napi_struc !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; - if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || -+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs || ++ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || !eth->netdev[mac])) goto release_desc; -@@ -2995,7 +2995,7 @@ static void mtk_dma_free(struct mtk_eth +@@ -2843,7 +2843,7 @@ static void mtk_dma_free(struct mtk_eth const struct mtk_soc_data *soc = eth->soc; int i; - for (i = 0; i < MTK_MAC_COUNT; i++) -+ for (i = 0; i < soc->num_devs; i++) ++ for (i = 0; i < MTK_MAX_DEVS; i++) if (eth->netdev[i]) netdev_reset_queue(eth->netdev[i]); if (eth->scratch_ring) { -@@ -3149,7 +3149,7 @@ static void mtk_gdm_config(struct mtk_et +@@ -2997,8 +2997,13 @@ static void mtk_gdm_config(struct mtk_et if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) return; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); +- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ u32 val; ++ ++ if (!eth->netdev[i]) ++ continue; ++ ++ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); /* default setup the forward port to send frame to PDMA */ -@@ -3760,7 +3760,7 @@ static int mtk_hw_init(struct mtk_eth *e + val &= ~0xffff; +@@ -3008,7 +3013,7 @@ static void mtk_gdm_config(struct mtk_et + + val |= config; + +- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) ++ if (netdev_uses_dsa(eth->netdev[i])) + val |= MTK_GDMA_SPECIAL_TAG; + + mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); +@@ -3607,15 +3612,15 @@ static int mtk_hw_init(struct mtk_eth *e * up with the more appropriate value when mtk_mac_config call is being * invoked. */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { struct net_device *dev = eth->netdev[i]; - mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -@@ -3948,7 +3948,7 @@ static void mtk_pending_work(struct work +- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); +- if (dev) { +- struct mtk_mac *mac = netdev_priv(dev); ++ if (!dev) ++ continue; + +- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); +- } ++ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); ++ mtk_set_mcr_max_rx(netdev_priv(dev), ++ dev->mtu + MTK_RX_ETH_HLEN); + } + + /* Indicates CDM to parse the MTK special tag from CPU +@@ -3795,7 +3800,7 @@ static void mtk_pending_work(struct work mtk_prepare_for_reset(eth); /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i] || !netif_running(eth->netdev[i])) continue; -@@ -3964,7 +3964,7 @@ static void mtk_pending_work(struct work +@@ -3811,8 +3816,8 @@ static void mtk_pending_work(struct work mtk_hw_init(eth, true); /* restart DMA and enable IRQs */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - if (!test_bit(i, &restart)) +- if (!test_bit(i, &restart)) ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->netdev[i] || !test_bit(i, &restart)) continue; -@@ -3992,7 +3992,7 @@ static int mtk_free_dev(struct mtk_eth * + if (mtk_open(eth->netdev[i])) { +@@ -3839,7 +3844,7 @@ static int mtk_free_dev(struct mtk_eth * { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; free_netdev(eth->netdev[i]); -@@ -4011,7 +4011,7 @@ static int mtk_unreg_dev(struct mtk_eth +@@ -3858,7 +3863,7 @@ static int mtk_unreg_dev(struct mtk_eth { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { struct mtk_mac *mac; if (!eth->netdev[i]) continue; -@@ -4315,7 +4315,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4159,7 +4164,7 @@ static int mtk_add_mac(struct mtk_eth *e } id = be32_to_cpup(_id); - if (id >= MTK_MAC_COUNT) { -+ if (id >= eth->soc->num_devs) { ++ if (id >= MTK_MAX_DEVS) { dev_err(eth->dev, "%d is not a valid mac id\n", id); return -EINVAL; } -@@ -4456,7 +4456,7 @@ void mtk_eth_set_dma_device(struct mtk_e +@@ -4304,7 +4309,7 @@ void mtk_eth_set_dma_device(struct mtk_e rtnl_lock(); - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { dev = eth->netdev[i]; if (!dev || !(dev->flags & IFF_UP)) -@@ -4782,7 +4782,7 @@ static int mtk_remove(struct platform_de +@@ -4612,7 +4617,7 @@ static int mtk_remove(struct platform_de int i; /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; mtk_stop(eth->netdev[i]); diff --git a/target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch b/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch similarity index 63% rename from target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch rename to target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch index 89fd441e1..c22b55c6f 100644 --- a/target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch +++ b/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch @@ -1,22 +1,24 @@ -From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001 +From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:47 +0000 -Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability - bit +Date: Tue, 25 Jul 2023 01:52:59 +0100 +Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version + support -Introduce MTK_NETSYS_V3 bit in the device capabilities. +Introduce NETSYS_V3 chipset version support. This is a preliminary patch to introduce support for MT7988 SoC. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++- - 2 files changed, 134 insertions(+), 25 deletions(-) + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++-- + 2 files changed, 116 insertions(+), 37 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -879,17 +879,32 @@ void mtk_stats_update_mac(struct mtk_mac +@@ -817,17 +817,32 @@ void mtk_stats_update_mac(struct mtk_mac mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); hw_stats->rx_flow_control_packets += mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); @@ -32,7 +34,7 @@ Signed-off-by: Daniel Golle - hw_stats->tx_packets += - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); + -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { + hw_stats->tx_skip += + mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs); + hw_stats->tx_collisions += @@ -60,7 +62,7 @@ Signed-off-by: Daniel Golle } u64_stats_update_end(&hw_stats->syncp); -@@ -1191,7 +1206,10 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1129,7 +1144,10 @@ static void mtk_tx_set_dma_desc_v2(struc data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); @@ -72,57 +74,53 @@ Signed-off-by: Daniel Golle data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); WRITE_ONCE(desc->txd4, data); -@@ -1202,6 +1220,9 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1140,6 +1158,8 @@ static void mtk_tx_set_dma_desc_v2(struc /* tx checksum offload */ if (info->csum) data |= TX_DMA_CHKSUM_V2; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ netdev_uses_dsa(dev)) ++ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev)) + data |= TX_DMA_SPTAG_V3; } WRITE_ONCE(desc->txd5, data); -@@ -1267,8 +1288,13 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1205,8 +1225,7 @@ static int mtk_tx_map(struct sk_buff *sk mtk_tx_set_dma_desc(dev, itxd, &txd_info); itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -+ if (mac->id == MTK_GMAC1_ID) -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0; -+ else if (mac->id == MTK_GMAC2_ID) -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1; -+ else -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2; -+ ++ itx_buf->mac_id = mac->id; setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, k++); -@@ -1316,8 +1342,13 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1254,8 +1273,7 @@ static int mtk_tx_map(struct sk_buff *sk memset(tx_buf, 0, sizeof(*tx_buf)); tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; tx_buf->flags |= MTK_TX_FLAGS_PAGE0; - tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0; -+ else if (mac->id == MTK_GMAC2_ID) -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1; -+ else -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2; ++ tx_buf->mac_id = mac->id; setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, k++); -@@ -1901,11 +1932,24 @@ static int mtk_poll_rx(struct napi_struc +@@ -1557,7 +1575,7 @@ static int mtk_xdp_frame_map(struct mtk_ + } + mtk_tx_set_dma_desc(dev, txd, txd_info); + +- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; ++ tx_buf->mac_id = mac->id; + tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; + tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; + +@@ -1805,11 +1823,24 @@ static int mtk_poll_rx(struct napi_struc break; /* find out which mac the packet come from. values start at 1 */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) +- if (mtk_is_netsys_v2_or_greater(eth)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); + + switch (val) { @@ -137,29 +135,44 @@ Signed-off-by: Daniel Golle + break; + } + } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { ++ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; + } - if (unlikely(mac < 0 || mac >= eth->soc->num_devs || + if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || !eth->netdev[mac])) -@@ -2134,7 +2178,9 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -2029,7 +2060,6 @@ static int mtk_poll_tx_qdma(struct mtk_e + + while ((cpu != dma) && budget) { + u32 next_cpu = desc->txd2; +- int mac = 0; + + desc = mtk_qdma_phys_to_virt(ring, desc->txd2); + if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) +@@ -2037,15 +2067,13 @@ static int mtk_poll_tx_qdma(struct mtk_e + tx_buf = mtk_desc_to_tx_buf(ring, desc, eth->soc->txrx.txd_size); - if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) +- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) - mac = 1; -+ mac = MTK_GMAC2_ID; -+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2) -+ mac = MTK_GMAC3_ID; - +- if (!tx_buf->data) break; -@@ -3744,7 +3790,26 @@ static int mtk_hw_init(struct mtk_eth *e + + if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { + if (tx_buf->type == MTK_TYPE_SKB) +- mtk_poll_tx_done(eth, state, mac, tx_buf->data); ++ mtk_poll_tx_done(eth, state, tx_buf->mac_id, ++ tx_buf->data); + + budget--; + } +@@ -3650,7 +3678,24 @@ static int mtk_hw_init(struct mtk_eth *e mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { + /* PSE should not drop port1, port8 and port9 packets */ + mtk_w32(eth, 0x00000302, PSE_DROP_CFG); + @@ -168,9 +181,7 @@ Signed-off-by: Daniel Golle + mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES); + + /* Disable GDM1 RX CRC stripping */ -+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0)); -+ val &= ~MTK_GDMA_STRP_CRC; -+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0)); ++ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0)); + + /* PSE GDM3 MIB counter has incorrect hw default values, + * so the driver ought to read clear the values beforehand @@ -178,17 +189,17 @@ Signed-off-by: Daniel Golle + */ + for (i = 0; i < 0x80; i += 0x4) + mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i); -+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ } else if (!mtk_is_netsys_v1(eth)) { /* PSE should not drop port8 and port9 packets from WDMA Tx */ mtk_w32(eth, 0x00000300, PSE_DROP_CFG); -@@ -4309,7 +4374,11 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4212,7 +4257,11 @@ static int mtk_add_mac(struct mtk_eth *e } spin_lock_init(&mac->hw_stats->stats_lock); u64_stats_init(&mac->hw_stats->syncp); - mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; + -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) ++ if (mtk_is_netsys_v3_or_greater(eth)) + mac->hw_stats->reg_offset = id * 0x80; + else + mac->hw_stats->reg_offset = id * 0x40; @@ -197,7 +208,7 @@ Signed-off-by: Daniel Golle err = of_get_phy_mode(np, &phy_mode); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -121,6 +121,7 @@ +@@ -122,6 +122,7 @@ #define MTK_GDMA_ICS_EN BIT(22) #define MTK_GDMA_TCS_EN BIT(21) #define MTK_GDMA_UCS_EN BIT(20) @@ -205,7 +216,7 @@ Signed-off-by: Daniel Golle #define MTK_GDMA_TO_PDMA 0x0 #define MTK_GDMA_DROP_ALL 0x7777 -@@ -286,8 +287,6 @@ +@@ -287,8 +288,6 @@ /* QDMA Interrupt grouping registers */ #define MTK_RLS_DONE_INT BIT(0) @@ -214,7 +225,7 @@ Signed-off-by: Daniel Golle /* QDMA TX NUM */ #define QID_BITS_V2(x) (((x) & 0x3f) << 16) #define MTK_QDMA_GMAC2_QID 8 -@@ -300,6 +299,8 @@ +@@ -301,6 +300,8 @@ #define TX_DMA_CHKSUM_V2 (0x7 << 28) #define TX_DMA_TSO_V2 BIT(31) @@ -223,15 +234,20 @@ Signed-off-by: Daniel Golle /* QDMA V2 descriptor txd4 */ #define TX_DMA_FPORT_SHIFT_V2 8 #define TX_DMA_FPORT_MASK_V2 0xf -@@ -636,6 +637,7 @@ enum mtk_tx_flags { +@@ -631,12 +632,6 @@ enum mtk_tx_flags { */ - MTK_TX_FLAGS_FPORT0 = 0x04, - MTK_TX_FLAGS_FPORT1 = 0x08, -+ MTK_TX_FLAGS_FPORT2 = 0x10, + MTK_TX_FLAGS_SINGLE0 = 0x01, + MTK_TX_FLAGS_PAGE0 = 0x02, +- +- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted +- * SKB out instead of looking up through hardware TX descriptor. +- */ +- MTK_TX_FLAGS_FPORT0 = 0x04, +- MTK_TX_FLAGS_FPORT1 = 0x08, }; /* This enum allows us to identify how the clock is defined on the array of the -@@ -721,6 +723,42 @@ enum mtk_dev_state { +@@ -722,6 +717,35 @@ enum mtk_dev_state { MTK_RESETTING }; @@ -263,30 +279,29 @@ Signed-off-by: Daniel Golle + MTK_GMAC3_ID, + MTK_GMAC_ID_MAX +}; -+ -+/* GDM Type */ -+enum mtk_gdm_type { -+ MTK_GDM_TYPE = 0, -+ MTK_XGDM_TYPE, -+ MTK_GDM_TYPE_MAX -+}; + enum mtk_tx_buf_type { MTK_TYPE_SKB, MTK_TYPE_XDP_TX, -@@ -817,6 +855,7 @@ enum mkt_eth_capabilities { - MTK_QDMA_BIT, - MTK_NETSYS_V1_BIT, - MTK_NETSYS_V2_BIT, -+ MTK_NETSYS_V3_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, - MTK_U3_COPHY_V2_BIT, -@@ -853,6 +892,7 @@ enum mkt_eth_capabilities { - #define MTK_QDMA BIT(MTK_QDMA_BIT) - #define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) -+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) - #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) +@@ -740,7 +764,8 @@ struct mtk_tx_buf { + enum mtk_tx_buf_type type; + void *data; + +- u32 flags; ++ u16 mac_id; ++ u16 flags; + DEFINE_DMA_UNMAP_ADDR(dma_addr0); + DEFINE_DMA_UNMAP_LEN(dma_len0); + DEFINE_DMA_UNMAP_ADDR(dma_addr1); +@@ -1189,6 +1214,11 @@ static inline bool mtk_is_netsys_v2_or_g + return eth->soc->version > 1; + } + ++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) ++{ ++ return eth->soc->version > 2; ++} ++ + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) + { diff --git a/target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch similarity index 89% rename from target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch rename to target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch index 068201cf7..0a72eec2f 100644 --- a/target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch +++ b/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch @@ -1,17 +1,19 @@ -From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001 +From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:56:00 +0000 -Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data - struct to u64 +Date: Tue, 25 Jul 2023 01:53:13 +0100 +Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in + mtk_soc_data struct to u64 This is a preliminary patch to introduce support for MT7988 SoC. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++---------- - 2 files changed, 42 insertions(+), 42 deletions(-) + drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++---- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++---------- + 2 files changed, 39 insertions(+), 39 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_path.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c @@ -111,7 +113,7 @@ Signed-off-by: Daniel Golle MTK_ETH_PATH_GMAC2_RGMII; --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -881,44 +881,44 @@ enum mkt_eth_capabilities { +@@ -863,41 +863,41 @@ enum mkt_eth_capabilities { }; /* Supported hardware group on SoCs */ @@ -127,9 +129,6 @@ Signed-off-by: Daniel Golle -#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) -#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) -#define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) --#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) --#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT) -#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) -#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) @@ -145,9 +144,6 @@ Signed-off-by: Daniel Golle +#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT) +#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT) +#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) -+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT) -+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT) -+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT) +#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) +#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) +#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) @@ -186,7 +182,7 @@ Signed-off-by: Daniel Golle #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1074,7 +1074,7 @@ struct mtk_reg_map { +@@ -1042,7 +1042,7 @@ struct mtk_reg_map { struct mtk_soc_data { const struct mtk_reg_map *reg_map; u32 ana_rgc3; diff --git a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch new file mode 100644 index 000000000..4e5b857d4 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch @@ -0,0 +1,132 @@ +From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 25 Jul 2023 01:53:28 +0100 +Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to + u64 + +The to-be-added MT7988 SoC adds many new clocks which need to be +controlled by the Ethernet driver, which will result in their total +number exceeding 32. +Prepare by converting clock bitmaps into 64-bit types. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++---------- + 1 file changed, 49 insertions(+), 47 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -663,54 +663,56 @@ enum mtk_clks_map { + MTK_CLK_MAX + }; + +-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ +- BIT(MTK_CLK_TRGPLL)) +-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_GP2) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK) | \ +- BIT(MTK_CLK_ETH2PLL)) ++#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_TRGPLL)) ++#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK) | \ ++ BIT_ULL(MTK_CLK_ETH2PLL)) + #define MT7621_CLKS_BITMAP (0) + #define MT7628_CLKS_BITMAP (0) +-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK) | \ +- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) +-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_WOCPU0) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK)) +-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB)) ++#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK) | \ ++ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) ++#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK)) ++#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) + + enum mtk_dev_state { + MTK_HW_INIT, +@@ -1043,7 +1045,7 @@ struct mtk_soc_data { + const struct mtk_reg_map *reg_map; + u32 ana_rgc3; + u64 caps; +- u32 required_clks; ++ u64 required_clks; + bool required_pctl; + u8 offload_version; + u8 hash_offset; diff --git a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch new file mode 100644 index 000000000..58b9cec62 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch @@ -0,0 +1,477 @@ +From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:57:42 +0100 +Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for + MT7988 SoC + +Introduce support for ethernet chip available in MT7988 SoC to +mtk_eth_soc driver. As a first step support only the first GMAC which +is hard-wired to the internal DSA switch having 4 built-in gigabit +Ethernet PHYs. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++- + 3 files changed, 273 insertions(+), 28 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64 + static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) + { + bool updated = true; +- u32 val, mask, set; ++ u32 mask, set, reg; + + switch (path) { + case MTK_ETH_PATH_GMAC1_SGMII: +@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str + break; + } + +- if (updated) { +- val = mtk_r32(eth, MTK_MAC_MISC); +- val = (val & mask) | set; +- mtk_w32(eth, val, MTK_MAC_MISC); +- } ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ reg = MTK_MAC_MISC_V3; ++ else ++ reg = MTK_MAC_MISC; ++ ++ if (updated) ++ mtk_m32(eth, mask, set, reg); + + dev_dbg(eth->dev, "path %s in %s updated = %d\n", + mtk_eth_path_name(path), __func__, updated); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r + .pse_oq_sta = 0x01a0, + }; + ++static const struct mtk_reg_map mt7988_reg_map = { ++ .tx_irq_mask = 0x461c, ++ .tx_irq_status = 0x4618, ++ .pdma = { ++ .rx_ptr = 0x6900, ++ .rx_cnt_cfg = 0x6904, ++ .pcrx_ptr = 0x6908, ++ .glo_cfg = 0x6a04, ++ .rst_idx = 0x6a08, ++ .delay_irq = 0x6a0c, ++ .irq_status = 0x6a20, ++ .irq_mask = 0x6a28, ++ .adma_rx_dbg0 = 0x6a38, ++ .int_grp = 0x6a50, ++ }, ++ .qdma = { ++ .qtx_cfg = 0x4400, ++ .qtx_sch = 0x4404, ++ .rx_ptr = 0x4500, ++ .rx_cnt_cfg = 0x4504, ++ .qcrx_ptr = 0x4508, ++ .glo_cfg = 0x4604, ++ .rst_idx = 0x4608, ++ .delay_irq = 0x460c, ++ .fc_th = 0x4610, ++ .int_grp = 0x4620, ++ .hred = 0x4644, ++ .ctx_ptr = 0x4700, ++ .dtx_ptr = 0x4704, ++ .crx_ptr = 0x4710, ++ .drx_ptr = 0x4714, ++ .fq_head = 0x4720, ++ .fq_tail = 0x4724, ++ .fq_count = 0x4728, ++ .fq_blen = 0x472c, ++ .tx_sch_rate = 0x4798, ++ }, ++ .gdm1_cnt = 0x1c00, ++ .gdma_to_ppe0 = 0x3333, ++ .ppe_base = 0x2000, ++ .wdma_base = { ++ [0] = 0x4800, ++ [1] = 0x4c00, ++ }, ++ .pse_iq_sta = 0x0180, ++ .pse_oq_sta = 0x01a0, ++}; ++ + /* strings used by ethtool */ + static const struct mtk_ethtool_stats { + char str[ETH_GSTRING_LEN]; +@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { + }; + + static const char * const mtk_clks_source_name[] = { +- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", +- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", +- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", +- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" ++ "ethif", ++ "sgmiitop", ++ "esw", ++ "gp0", ++ "gp1", ++ "gp2", ++ "gp3", ++ "xgp1", ++ "xgp2", ++ "xgp3", ++ "crypto", ++ "fe", ++ "trgpll", ++ "sgmii_tx250m", ++ "sgmii_rx250m", ++ "sgmii_cdr_ref", ++ "sgmii_cdr_fb", ++ "sgmii2_tx250m", ++ "sgmii2_rx250m", ++ "sgmii2_cdr_ref", ++ "sgmii2_cdr_fb", ++ "sgmii_ck", ++ "eth2pll", ++ "wocpu0", ++ "wocpu1", ++ "netsys0", ++ "netsys1", ++ "ethwarp_wocpu2", ++ "ethwarp_wocpu1", ++ "ethwarp_wocpu0", ++ "top_usxgmii0_sel", ++ "top_usxgmii1_sel", ++ "top_sgm0_sel", ++ "top_sgm1_sel", ++ "top_xfi_phy0_xtal_sel", ++ "top_xfi_phy1_xtal_sel", ++ "top_eth_gmii_sel", ++ "top_eth_refck_50m_sel", ++ "top_eth_sys_200m_sel", ++ "top_eth_sys_sel", ++ "top_eth_xgmii_sel", ++ "top_eth_mii_sel", ++ "top_netsys_sel", ++ "top_netsys_500m_sel", ++ "top_netsys_pao_2x_sel", ++ "top_netsys_sync_250m_sel", ++ "top_netsys_ppefb_250m_sel", ++ "top_netsys_warp_sel", + }; + + void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) +@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne + return __raw_readl(eth->base + reg); + } + +-static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg) ++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg) + { + u32 val; + +@@ -326,6 +418,19 @@ static void mtk_gmac0_rgmii_adjust(struc + dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); + } + ++static void mtk_setup_bridge_switch(struct mtk_eth *eth) ++{ ++ /* Force Port1 XGMAC Link Up */ ++ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), ++ MTK_XGMAC_STS(MTK_GMAC1_ID)); ++ ++ /* Adjust GSW bridge IPG to 11 */ ++ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK, ++ (GSW_IPG_11 << GSWTX_IPG_SHIFT) | ++ (GSW_IPG_11 << GSWRX_IPG_SHIFT), ++ MTK_GSW_CFG); ++} ++ + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) + { +@@ -395,6 +500,8 @@ static void mtk_mac_config(struct phylin + goto init_err; + } + break; ++ case PHY_INTERFACE_MODE_INTERNAL: ++ break; + default: + goto err_phy; + } +@@ -472,6 +579,15 @@ static void mtk_mac_config(struct phylin + return; + } + ++ /* Setup gmac */ ++ if (mtk_is_netsys_v3_or_greater(eth) && ++ mac->interface == PHY_INTERFACE_MODE_INTERNAL) { ++ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); ++ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ ++ mtk_setup_bridge_switch(eth); ++ } ++ + return; + + err_phy: +@@ -681,11 +797,15 @@ static int mtk_mdio_init(struct mtk_eth + } + divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); + ++ /* Configure MDC Turbo Mode */ ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3); ++ + /* Configure MDC Divider */ +- val = mtk_r32(eth, MTK_PPSC); +- val &= ~PPSC_MDC_CFG; +- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; +- mtk_w32(eth, val, MTK_PPSC); ++ val = FIELD_PREP(PPSC_MDC_CFG, divider); ++ if (!mtk_is_netsys_v3_or_greater(eth)) ++ val |= PPSC_MDC_TURBO; ++ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC); + + dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); + +@@ -1144,10 +1264,19 @@ static void mtk_tx_set_dma_desc_v2(struc + data |= TX_DMA_LS0; + WRITE_ONCE(desc->txd3, data); + +- if (mac->id == MTK_GMAC3_ID) +- data = PSE_GDM3_PORT; +- else +- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ ++ /* set forward port */ ++ switch (mac->id) { ++ case MTK_GMAC1_ID: ++ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ case MTK_GMAC2_ID: ++ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ case MTK_GMAC3_ID: ++ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ } ++ + data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); + WRITE_ONCE(desc->txd4, data); + +@@ -4306,6 +4435,17 @@ static int mtk_add_mac(struct mtk_eth *e + mac->phylink_config.supported_interfaces); + } + ++ if (mtk_is_netsys_v3_or_greater(mac->hw) && ++ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) && ++ id == MTK_GMAC1_ID) { ++ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | ++ MAC_SYM_PAUSE | ++ MAC_10000FD; ++ phy_interface_zero(mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_INTERNAL, ++ mac->phylink_config.supported_interfaces); ++ } ++ + phylink = phylink_create(&mac->phylink_config, + of_fwnode_handle(mac->of_node), + phy_mode, &mtk_phylink_ops); +@@ -4828,6 +4968,24 @@ static const struct mtk_soc_data mt7986_ + }, + }; + ++static const struct mtk_soc_data mt7988_data = { ++ .reg_map = &mt7988_reg_map, ++ .ana_rgc3 = 0x128, ++ .caps = MT7988_CAPS, ++ .hw_features = MTK_HW_FEATURES, ++ .required_clks = MT7988_CLKS_BITMAP, ++ .required_pctl = false, ++ .version = 3, ++ .txrx = { ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, ++ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, ++ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, ++ .dma_len_offset = 8, ++ }, ++}; ++ + static const struct mtk_soc_data rt5350_data = { + .reg_map = &mt7628_reg_map, + .caps = MT7628_CAPS, +@@ -4846,14 +5004,15 @@ static const struct mtk_soc_data rt5350_ + }; + + const struct of_device_id of_mtk_match[] = { +- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, +- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, +- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, +- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, +- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, +- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, +- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, +- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, ++ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, ++ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, ++ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, ++ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, ++ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, ++ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, ++ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, ++ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, ++ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, of_mtk_match); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -117,7 +117,8 @@ + #define MTK_CDMP_EG_CTRL 0x404 + + /* GDM Exgress Control Register */ +-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) ++#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x540 : 0x500 + (_x * 0x1000); }) + #define MTK_GDMA_SPECIAL_TAG BIT(24) + #define MTK_GDMA_ICS_EN BIT(22) + #define MTK_GDMA_TCS_EN BIT(21) +@@ -126,6 +127,11 @@ + #define MTK_GDMA_TO_PDMA 0x0 + #define MTK_GDMA_DROP_ALL 0x7777 + ++/* GDM Egress Control Register */ ++#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x544 : 0x504 + (_x * 0x1000); }) ++#define MTK_GDMA_XGDM_SEL BIT(31) ++ + /* Unicast Filter MAC Address Register - Low */ + #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) + +@@ -386,7 +392,26 @@ + #define PHY_IAC_TIMEOUT HZ + + #define MTK_MAC_MISC 0x1000c ++#define MTK_MAC_MISC_V3 0x10010 + #define MTK_MUX_TO_ESW BIT(0) ++#define MISC_MDC_TURBO BIT(4) ++ ++/* XMAC status registers */ ++#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) ++#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) ++#define MTK_USXGMII_PCS_LINK BIT(8) ++#define MTK_XGMAC_RX_FC BIT(5) ++#define MTK_XGMAC_TX_FC BIT(4) ++#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) ++#define MTK_XGMAC_LINK_STS BIT(0) ++ ++/* GSW bridge registers */ ++#define MTK_GSW_CFG (0x10080) ++#define GSWTX_IPG_MASK GENMASK(19, 16) ++#define GSWTX_IPG_SHIFT 16 ++#define GSWRX_IPG_MASK GENMASK(3, 0) ++#define GSWRX_IPG_SHIFT 0 ++#define GSW_IPG_11 11 + + /* Mac control registers */ + #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) +@@ -644,6 +669,11 @@ enum mtk_clks_map { + MTK_CLK_GP0, + MTK_CLK_GP1, + MTK_CLK_GP2, ++ MTK_CLK_GP3, ++ MTK_CLK_XGP1, ++ MTK_CLK_XGP2, ++ MTK_CLK_XGP3, ++ MTK_CLK_CRYPTO, + MTK_CLK_FE, + MTK_CLK_TRGPLL, + MTK_CLK_SGMII_TX_250M, +@@ -660,6 +690,27 @@ enum mtk_clks_map { + MTK_CLK_WOCPU1, + MTK_CLK_NETSYS0, + MTK_CLK_NETSYS1, ++ MTK_CLK_ETHWARP_WOCPU2, ++ MTK_CLK_ETHWARP_WOCPU1, ++ MTK_CLK_ETHWARP_WOCPU0, ++ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, ++ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, ++ MTK_CLK_TOP_SGM_0_SEL, ++ MTK_CLK_TOP_SGM_1_SEL, ++ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, ++ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, ++ MTK_CLK_TOP_ETH_GMII_SEL, ++ MTK_CLK_TOP_ETH_REFCK_50M_SEL, ++ MTK_CLK_TOP_ETH_SYS_200M_SEL, ++ MTK_CLK_TOP_ETH_SYS_SEL, ++ MTK_CLK_TOP_ETH_XGMII_SEL, ++ MTK_CLK_TOP_ETH_MII_SEL, ++ MTK_CLK_TOP_NETSYS_SEL, ++ MTK_CLK_TOP_NETSYS_500M_SEL, ++ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, ++ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, ++ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, ++ MTK_CLK_TOP_NETSYS_WARP_SEL, + MTK_CLK_MAX + }; + +@@ -713,6 +764,36 @@ enum mtk_clks_map { + BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ + BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ + BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) ++#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ ++ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ ++ BIT_ULL(MTK_CLK_CRYPTO) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) + + enum mtk_dev_state { + MTK_HW_INIT, +@@ -961,6 +1042,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1) + ++#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) ++ + struct mtk_tx_dma_desc_info { + dma_addr_t addr; + u32 size; +@@ -1306,6 +1389,7 @@ void mtk_stats_update_mac(struct mtk_mac + + void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); + u32 mtk_r32(struct mtk_eth *eth, unsigned reg); ++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); + + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); diff --git a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch new file mode 100644 index 000000000..95bf60da8 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch @@ -0,0 +1,27 @@ +From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 27 Jul 2023 09:02:26 +0200 +Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support + for MT7988 SoC + +In order to recycle pages, enable page_pool allocator for MT7988 SoC. + +Tested-by: Daniel Golle +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1612,7 +1612,7 @@ static void mtk_update_rx_cpu_idx(struct + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) + { +- return eth->soc->version == 2; ++ return mtk_is_netsys_v2_or_greater(eth); + } + + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch new file mode 100644 index 000000000..5205914c4 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch @@ -0,0 +1,135 @@ +From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 27 Jul 2023 09:07:28 +0200 +Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw + flowtable_offload for MT7988 SoC + +Enable hw Packet Process Engine (PPE) for MT7988 SoC. + +Tested-by: Daniel Golle +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++---- + drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++- + 3 files changed, 36 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4976,6 +4976,9 @@ static const struct mtk_soc_data mt7988_ + .required_clks = MT7988_CLKS_BITMAP, + .required_pctl = false, + .version = 3, ++ .offload_version = 2, ++ .hash_offset = 4, ++ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et + struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ switch (eth->soc->version) { ++ case 3: ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | ++ MTK_FOE_IB2_WDMA_WINFO_V2; ++ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | ++ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); ++ break; ++ case 2: + *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | + MTK_FOE_IB2_WDMA_WINFO_V2; + l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | + FIELD_PREP(MTK_FOE_WINFO_BSS, bss); +- } else { ++ break; ++ default: + *ib2 &= ~MTK_FOE_IB2_PORT_MG; + *ib2 |= MTK_FOE_IB2_WDMA_WINFO; + if (wdma_idx) +@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et + l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | + FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | + FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ break; + } + + return 0; +@@ -956,8 +966,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + mtk_ppe_init_foe_table(ppe); + ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); + +- val = MTK_PPE_TB_CFG_ENTRY_80B | +- MTK_PPE_TB_CFG_AGE_NON_L4 | ++ val = MTK_PPE_TB_CFG_AGE_NON_L4 | + MTK_PPE_TB_CFG_AGE_UNBIND | + MTK_PPE_TB_CFG_AGE_TCP | + MTK_PPE_TB_CFG_AGE_UDP | +@@ -973,6 +982,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_ENTRIES_SHIFT); + if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_TB_CFG_INFO_SEL; ++ if (!mtk_is_netsys_v3_or_greater(ppe->eth)) ++ val |= MTK_PPE_TB_CFG_ENTRY_80B; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + + ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -85,6 +85,17 @@ enum { + #define MTK_FOE_WINFO_BSS GENMASK(5, 0) + #define MTK_FOE_WINFO_WCID GENMASK(15, 6) + ++#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) ++#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) ++ ++#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) ++#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) ++#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) ++#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) ++#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) ++#define MTK_FOE_WINFO_PAO_HF BIT(23) ++#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) ++ + enum { + MTK_FOE_STATE_INVALID, + MTK_FOE_STATE_UNBIND, +@@ -106,8 +117,13 @@ struct mtk_foe_mac_info { + u16 pppoe_id; + u16 src_mac_lo; + ++ /* netsys_v2 */ + u16 minfo; + u16 winfo; ++ ++ /* netsys_v3 */ ++ u32 w3info; ++ u32 wpao; + }; + + /* software-only entry type */ +@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd { + + #define MTK_FOE_ENTRY_V1_SIZE 80 + #define MTK_FOE_ENTRY_V2_SIZE 96 ++#define MTK_FOE_ENTRY_V3_SIZE 128 + + struct mtk_foe_entry { + u32 ib1; +@@ -228,7 +245,7 @@ struct mtk_foe_entry { + struct mtk_foe_ipv4_dslite dslite; + struct mtk_foe_ipv6 ipv6; + struct mtk_foe_ipv6_6rd ipv6_6rd; +- u32 data[23]; ++ u32 data[31]; + }; + }; + diff --git a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch new file mode 100644 index 000000000..8a4897612 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch @@ -0,0 +1,78 @@ +From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 2 Aug 2023 04:31:09 +0100 +Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow + accounting on MT7988 + +NETSYS_V3 uses 64 bits for each counters while older SoCs are using +48/40 bits for each counter. +Support reading per-flow byte and package counters on NETSYS_V3. + +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + + drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++------- + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++ + 3 files changed, 17 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4978,6 +4978,7 @@ static const struct mtk_soc_data mt7988_ + .version = 3, + .offload_version = 2, + .hash_offset = 4, ++ .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct + + static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) + { +- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; + u32 val, cnt_r0, cnt_r1, cnt_r2; + int ret; + +@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk + cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); + cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); + +- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); +- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); +- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); +- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); +- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; +- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ if (mtk_is_netsys_v3_or_greater(ppe->eth)) { ++ /* 64 bit for each counter */ ++ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); ++ *bytes = ((u64)cnt_r1 << 32) | cnt_r0; ++ *packets = ((u64)cnt_r3 << 32) | cnt_r2; ++ } else { ++ /* 48 bit byte counter, 40 bit packet counter */ ++ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); ++ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); ++ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); ++ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); ++ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ } + + return 0; + } +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -163,6 +163,8 @@ enum { + #define MTK_PPE_MIB_SER_R2 0x348 + #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) + ++#define MTK_PPE_MIB_SER_R3 0x34c ++ + #define MTK_PPE_MIB_CACHE_CTL 0x350 + #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) + #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch new file mode 100644 index 000000000..6f1639a57 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch @@ -0,0 +1,52 @@ +From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 21 Aug 2023 17:12:44 +0100 +Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw + reset + +When a hardware reset is triggered on devices not initializing WED the +calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a +pointer on uninitialized stack memory. +Break out of both functions in case a hw_list entry is 0. + +Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Acked-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void) + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; +- struct mtk_wed_device *dev = hw->wed_dev; ++ struct mtk_wed_device *dev; + int err; + ++ if (!hw) ++ break; ++ ++ dev = hw->wed_dev; + if (!dev || !dev->wlan.reset) + continue; + +@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void) + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; +- struct mtk_wed_device *dev = hw->wed_dev; ++ struct mtk_wed_device *dev; ++ ++ if (!hw) ++ break; + ++ dev = hw->wed_dev; + if (!dev || !dev->wlan.reset_complete) + continue; + diff --git a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch new file mode 100644 index 000000000..35977946d --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch @@ -0,0 +1,44 @@ +From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:31:24 +0100 +Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions + for MT7988 + +More register macros need to be adjusted for the 3rd GMAC on MT7988. +Account for added bit in SYSCFG0_SGMII_MASK. + +Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -133,10 +133,12 @@ + #define MTK_GDMA_XGDM_SEL BIT(31) + + /* Unicast Filter MAC Address Register - Low */ +-#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) ++#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x548 : 0x508 + (_x * 0x1000); }) + + /* Unicast Filter MAC Address Register - High */ +-#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) ++#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x54C : 0x50C + (_x * 0x1000); }) + + /* FE global misc reg*/ + #define MTK_FE_GLO_MISC 0x124 +@@ -500,7 +502,7 @@ + #define ETHSYS_SYSCFG0 0x14 + #define SYSCFG0_GE_MASK 0x3 + #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2))) +-#define SYSCFG0_SGMII_MASK GENMASK(9, 8) ++#define SYSCFG0_SGMII_MASK GENMASK(9, 7) + #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) diff --git a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch new file mode 100644 index 000000000..963807aa4 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch @@ -0,0 +1,188 @@ +From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:32:03 +0100 +Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988 + +Add bits needed to reset the frame engine on MT7988. + +Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++-- + 2 files changed, 68 insertions(+), 24 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3540,19 +3540,34 @@ static void mtk_hw_reset(struct mtk_eth + { + u32 val; + +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ val = RSTCTRL_PPE0_V3; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1_V3; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val |= RSTCTRL_PPE2; ++ ++ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; ++ } else if (mtk_is_netsys_v2_or_greater(eth)) { + val = RSTCTRL_PPE0_V2; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1; + } else { + val = RSTCTRL_PPE0; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= RSTCTRL_PPE1; +- + ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + +- if (mtk_is_netsys_v2_or_greater(eth)) ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, ++ 0x6f8ff); ++ else if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, + 0x3ffffff); + } +@@ -3578,13 +3593,21 @@ static void mtk_hw_warm_reset(struct mtk + return; + } + +- if (mtk_is_netsys_v2_or_greater(eth)) ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1_V3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ rst_mask |= RSTCTRL_PPE2; ++ ++ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; ++ } else if (mtk_is_netsys_v2_or_greater(eth)) { + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; +- else ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1; ++ } else { + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- rst_mask |= RSTCTRL_PPE1; ++ } + + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); + +@@ -3936,11 +3959,17 @@ static void mtk_prepare_for_reset(struct + u32 val; + int i; + +- /* disabe FE P3 and P4 */ +- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= MTK_FE_LINK_DOWN_P4; +- mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ /* set FE PPE ports link down */ ++ for (i = MTK_GMAC1_ID; ++ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); ++ i += 2) { ++ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); ++ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); ++ } + + /* adjust PPE configurations to prepare for reset */ + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) +@@ -4001,11 +4030,18 @@ static void mtk_pending_work(struct work + } + } + +- /* enabe FE P3 and P4 */ +- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val &= ~MTK_FE_LINK_DOWN_P4; +- mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ /* set FE PPE ports link up */ ++ for (i = MTK_GMAC1_ID; ++ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); ++ i += 2) { ++ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); ++ ++ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); ++ } + + clear_bit(MTK_RESETTING, ð->state); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -76,9 +76,8 @@ + #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 + + /* Frame Engine Global Configuration */ +-#define MTK_FE_GLO_CFG 0x00 +-#define MTK_FE_LINK_DOWN_P3 BIT(11) +-#define MTK_FE_LINK_DOWN_P4 BIT(12) ++#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00) ++#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16) + + /* Frame Engine Global Reset Register */ + #define MTK_RST_GL 0x04 +@@ -519,9 +518,15 @@ + /* ethernet reset control register */ + #define ETHSYS_RSTCTRL 0x34 + #define RSTCTRL_FE BIT(6) ++#define RSTCTRL_WDMA0 BIT(24) ++#define RSTCTRL_WDMA1 BIT(25) ++#define RSTCTRL_WDMA2 BIT(26) + #define RSTCTRL_PPE0 BIT(31) + #define RSTCTRL_PPE0_V2 BIT(30) + #define RSTCTRL_PPE1 BIT(31) ++#define RSTCTRL_PPE0_V3 BIT(29) ++#define RSTCTRL_PPE1_V3 BIT(30) ++#define RSTCTRL_PPE2 BIT(31) + #define RSTCTRL_ETH BIT(23) + + /* ethernet reset check idle register */ +@@ -928,6 +933,7 @@ enum mkt_eth_capabilities { + MTK_QDMA_BIT, + MTK_SOC_MT7628_BIT, + MTK_RSTCTRL_PPE1_BIT, ++ MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, + + /* MUX BITS*/ +@@ -962,6 +968,7 @@ enum mkt_eth_capabilities { + #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) + #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) + #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) ++#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ +@@ -1044,7 +1051,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1) + +-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) ++#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ ++ MTK_RSTCTRL_PPE2) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; diff --git a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch new file mode 100644 index 000000000..e224443e4 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch @@ -0,0 +1,254 @@ +From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:32:54 +0100 +Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC + SRAM + +MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet +DMA rings. Support using the SRAM without breaking existing device tree +bindings, ie. only new SoC starting from MT7988 will have the SRAM +declared as additional resource in device tree. For MT7981 and MT7986 +an offset on top of the main I/O base is used. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++----- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++- + 2 files changed, 78 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1074,10 +1074,13 @@ static int mtk_init_fq_dma(struct mtk_et + dma_addr_t dma_addr; + int i; + +- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, +- cnt * soc->txrx.txd_size, +- ð->phy_scratch_ring, +- GFP_KERNEL); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) ++ eth->scratch_ring = eth->sram_base; ++ else ++ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, ++ cnt * soc->txrx.txd_size, ++ ð->phy_scratch_ring, ++ GFP_KERNEL); + if (unlikely(!eth->scratch_ring)) + return -ENOMEM; + +@@ -2375,8 +2378,14 @@ static int mtk_tx_alloc(struct mtk_eth * + if (!ring->buf) + goto no_tx_mem; + +- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, +- &ring->phys, GFP_KERNEL); ++ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) { ++ ring->dma = eth->sram_base + ring_size * sz; ++ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz; ++ } else { ++ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, ++ &ring->phys, GFP_KERNEL); ++ } ++ + if (!ring->dma) + goto no_tx_mem; + +@@ -2475,8 +2484,7 @@ static void mtk_tx_clean(struct mtk_eth + kfree(ring->buf); + ring->buf = NULL; + } +- +- if (ring->dma) { ++ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { + dma_free_coherent(eth->dma_dev, + ring->dma_size * soc->txrx.txd_size, + ring->dma, ring->phys); +@@ -2495,9 +2503,14 @@ static int mtk_rx_alloc(struct mtk_eth * + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + struct mtk_rx_ring *ring; +- int rx_data_len, rx_dma_size; ++ int rx_data_len, rx_dma_size, tx_ring_size; + int i; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ tx_ring_size = MTK_QDMA_RING_SIZE; ++ else ++ tx_ring_size = MTK_DMA_SIZE; ++ + if (rx_flag == MTK_RX_FLAGS_QDMA) { + if (ring_no) + return -EINVAL; +@@ -2532,9 +2545,20 @@ static int mtk_rx_alloc(struct mtk_eth * + ring->page_pool = pp; + } + +- ring->dma = dma_alloc_coherent(eth->dma_dev, +- rx_dma_size * eth->soc->txrx.rxd_size, +- &ring->phys, GFP_KERNEL); ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || ++ rx_flag != MTK_RX_FLAGS_NORMAL) { ++ ring->dma = dma_alloc_coherent(eth->dma_dev, ++ rx_dma_size * eth->soc->txrx.rxd_size, ++ &ring->phys, GFP_KERNEL); ++ } else { ++ struct mtk_tx_ring *tx_ring = ð->tx_ring; ++ ++ ring->dma = tx_ring->dma + tx_ring_size * ++ eth->soc->txrx.txd_size * (ring_no + 1); ++ ring->phys = tx_ring->phys + tx_ring_size * ++ eth->soc->txrx.txd_size * (ring_no + 1); ++ } ++ + if (!ring->dma) + return -ENOMEM; + +@@ -2617,7 +2641,7 @@ static int mtk_rx_alloc(struct mtk_eth * + return 0; + } + +-static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) ++static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) + { + int i; + +@@ -2640,7 +2664,7 @@ static void mtk_rx_clean(struct mtk_eth + ring->data = NULL; + } + +- if (ring->dma) { ++ if (!in_sram && ring->dma) { + dma_free_coherent(eth->dma_dev, + ring->dma_size * eth->soc->txrx.rxd_size, + ring->dma, ring->phys); +@@ -3003,7 +3027,7 @@ static void mtk_dma_free(struct mtk_eth + for (i = 0; i < MTK_MAX_DEVS; i++) + if (eth->netdev[i]) + netdev_reset_queue(eth->netdev[i]); +- if (eth->scratch_ring) { ++ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { + dma_free_coherent(eth->dma_dev, + MTK_QDMA_RING_SIZE * soc->txrx.txd_size, + eth->scratch_ring, eth->phy_scratch_ring); +@@ -3011,13 +3035,13 @@ static void mtk_dma_free(struct mtk_eth + eth->phy_scratch_ring = 0; + } + mtk_tx_clean(eth); +- mtk_rx_clean(eth, ð->rx_ring[0]); +- mtk_rx_clean(eth, ð->rx_ring_qdma); ++ mtk_rx_clean(eth, ð->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM)); ++ mtk_rx_clean(eth, ð->rx_ring_qdma, false); + + if (eth->hwlro) { + mtk_hwlro_rx_uninit(eth); + for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) +- mtk_rx_clean(eth, ð->rx_ring[i]); ++ mtk_rx_clean(eth, ð->rx_ring[i], false); + } + + kfree(eth->scratch_head); +@@ -4587,7 +4611,7 @@ static int mtk_sgmii_init(struct mtk_eth + + static int mtk_probe(struct platform_device *pdev) + { +- struct resource *res = NULL; ++ struct resource *res = NULL, *res_sram; + struct device_node *mac_np; + struct mtk_eth *eth; + int err, i; +@@ -4607,6 +4631,20 @@ static int mtk_probe(struct platform_dev + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + eth->ip_align = NET_IP_ALIGN; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { ++ /* SRAM is actual memory and supports transparent access just like DRAM. ++ * Hence we don't require __iomem being set and don't need to use accessor ++ * functions to read from or write to SRAM. ++ */ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1); ++ if (IS_ERR(eth->sram_base)) ++ return PTR_ERR(eth->sram_base); ++ } else { ++ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET; ++ } ++ } ++ + spin_lock_init(ð->page_lock); + spin_lock_init(ð->tx_irq_lock); + spin_lock_init(ð->rx_irq_lock); +@@ -4670,6 +4708,18 @@ static int mtk_probe(struct platform_dev + err = -EINVAL; + goto err_destroy_sgmii; + } ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res_sram) { ++ err = -EINVAL; ++ goto err_destroy_sgmii; ++ } ++ eth->phy_scratch_ring = res_sram->start; ++ } else { ++ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET; ++ } ++ } + } + + if (eth->soc->offload_version) { +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -139,6 +139,9 @@ + #define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ + 0x54C : 0x50C + (_x * 0x1000); }) + ++/* Internal SRAM offset */ ++#define MTK_ETH_SRAM_OFFSET 0x40000 ++ + /* FE global misc reg*/ + #define MTK_FE_GLO_MISC 0x124 + +@@ -935,6 +938,7 @@ enum mkt_eth_capabilities { + MTK_RSTCTRL_PPE1_BIT, + MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, ++ MTK_SRAM_BIT, + + /* MUX BITS*/ + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, +@@ -970,6 +974,7 @@ enum mkt_eth_capabilities { + #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) + #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) ++#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ + BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) +@@ -1045,14 +1050,14 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM) + + #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ +- MTK_RSTCTRL_PPE2) ++ MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1212,6 +1217,7 @@ struct mtk_eth { + struct device *dev; + struct device *dma_dev; + void __iomem *base; ++ void *sram_base; + spinlock_t page_lock; + spinlock_t tx_irq_lock; + spinlock_t rx_irq_lock; diff --git a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch new file mode 100644 index 000000000..528f9a3e5 --- /dev/null +++ b/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch @@ -0,0 +1,166 @@ +From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:33:12 +0100 +Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA + addressing on MT7988 + +Systems having 4 GiB of RAM and more require DMA addressing beyond the +current 32-bit limit. Starting from MT7988 the hardware now supports +36-bit DMA addressing, let's use that new capability in the driver to +avoid running into swiotlb on systems with 4 GiB of RAM or more. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++-- + 2 files changed, 48 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1265,6 +1265,10 @@ static void mtk_tx_set_dma_desc_v2(struc + data = TX_DMA_PLEN0(info->size); + if (info->last) + data |= TX_DMA_LS0; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ data |= TX_DMA_PREP_ADDR64(info->addr); ++ + WRITE_ONCE(desc->txd3, data); + + /* set forward port */ +@@ -1932,6 +1936,7 @@ static int mtk_poll_rx(struct napi_struc + bool xdp_flush = false; + int idx; + struct sk_buff *skb; ++ u64 addr64 = 0; + u8 *data, *new_data; + struct mtk_rx_dma_v2 *rxd, trxd; + int done = 0, bytes = 0; +@@ -2047,7 +2052,10 @@ static int mtk_poll_rx(struct napi_struc + goto release_desc; + } + +- dma_unmap_single(eth->dma_dev, trxd.rxd1, ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2); ++ ++ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64), + ring->buf_size, DMA_FROM_DEVICE); + + skb = build_skb(data, ring->frag_size); +@@ -2113,6 +2121,9 @@ release_desc: + else + rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ + ring->calc_idx = idx; + done++; + } +@@ -2597,6 +2608,9 @@ static int mtk_rx_alloc(struct mtk_eth * + else + rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ + rxd->rxd3 = 0; + rxd->rxd4 = 0; + if (mtk_is_netsys_v2_or_greater(eth)) { +@@ -2643,6 +2657,7 @@ static int mtk_rx_alloc(struct mtk_eth * + + static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) + { ++ u64 addr64 = 0; + int i; + + if (ring->data && ring->dma) { +@@ -2656,7 +2671,10 @@ static void mtk_rx_clean(struct mtk_eth + if (!rxd->rxd1) + continue; + +- dma_unmap_single(eth->dma_dev, rxd->rxd1, ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2); ++ ++ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64), + ring->buf_size, DMA_FROM_DEVICE); + mtk_rx_put_buff(ring, ring->data[i], false); + } +@@ -4645,6 +4663,14 @@ static int mtk_probe(struct platform_dev + } + } + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); ++ if (err) { ++ dev_err(&pdev->dev, "Wrong DMA config\n"); ++ return -EINVAL; ++ } ++ } ++ + spin_lock_init(ð->page_lock); + spin_lock_init(ð->tx_irq_lock); + spin_lock_init(ð->rx_irq_lock); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -331,6 +331,14 @@ + #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) + #define TX_DMA_SWC BIT(14) + #define TX_DMA_PQID GENMASK(3, 0) ++#define TX_DMA_ADDR64_MASK GENMASK(3, 0) ++#if IS_ENABLED(CONFIG_64BIT) ++# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32) ++# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32)) ++#else ++# define TX_DMA_GET_ADDR64(x) (0) ++# define TX_DMA_PREP_ADDR64(x) (0) ++#endif + + /* PDMA on MT7628 */ + #define TX_DMA_DONE BIT(31) +@@ -343,6 +351,14 @@ + #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) + #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) + #define RX_DMA_VTAG BIT(15) ++#define RX_DMA_ADDR64_MASK GENMASK(3, 0) ++#if IS_ENABLED(CONFIG_64BIT) ++# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32) ++# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32)) ++#else ++# define RX_DMA_GET_ADDR64(x) (0) ++# define RX_DMA_PREP_ADDR64(x) (0) ++#endif + + /* QDMA descriptor rxd3 */ + #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK) +@@ -939,6 +955,7 @@ enum mkt_eth_capabilities { + MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, + MTK_SRAM_BIT, ++ MTK_36BIT_DMA_BIT, + + /* MUX BITS*/ + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, +@@ -975,6 +992,7 @@ enum mkt_eth_capabilities { + #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) + #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) ++#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ + BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) +@@ -1056,8 +1074,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1 | MTK_SRAM) + +-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ +- MTK_RSTCTRL_PPE2 | MTK_SRAM) ++#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ ++ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; diff --git a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch b/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch index e331226fc..dbc28efc9 100644 --- a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch +++ b/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch @@ -30,7 +30,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c -@@ -1034,6 +1034,8 @@ static int dsa_tree_setup_master(struct +@@ -1056,6 +1056,8 @@ static int dsa_tree_setup_master(struct struct dsa_port *dp; int err; @@ -39,7 +39,7 @@ Signed-off-by: David S. Miller list_for_each_entry(dp, &dst->ports, list) { if (dsa_port_is_cpu(dp)) { err = dsa_master_setup(dp->master, dp); -@@ -1042,6 +1044,8 @@ static int dsa_tree_setup_master(struct +@@ -1064,6 +1066,8 @@ static int dsa_tree_setup_master(struct } } @@ -48,7 +48,7 @@ Signed-off-by: David S. Miller return 0; } -@@ -1049,9 +1053,13 @@ static void dsa_tree_teardown_master(str +@@ -1071,9 +1075,13 @@ static void dsa_tree_teardown_master(str { struct dsa_port *dp; diff --git a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch b/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch index e6472c61d..fbb9c94ec 100644 --- a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch +++ b/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch @@ -27,7 +27,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c -@@ -999,23 +999,28 @@ static void dsa_tree_teardown_switches(s +@@ -1021,23 +1021,28 @@ static void dsa_tree_teardown_switches(s dsa_switch_teardown(dp->ds); } @@ -66,7 +66,7 @@ Signed-off-by: David S. Miller } } -@@ -1024,7 +1029,21 @@ static int dsa_tree_setup_switches(struc +@@ -1046,7 +1051,21 @@ static int dsa_tree_setup_switches(struc teardown: dsa_tree_teardown_ports(dst); @@ -89,7 +89,7 @@ Signed-off-by: David S. Miller return err; } -@@ -1111,10 +1130,14 @@ static int dsa_tree_setup(struct dsa_swi +@@ -1133,10 +1152,14 @@ static int dsa_tree_setup(struct dsa_swi if (err) goto teardown_cpu_ports; @@ -105,7 +105,7 @@ Signed-off-by: David S. Miller err = dsa_tree_setup_lags(dst); if (err) goto teardown_master; -@@ -1127,8 +1150,9 @@ static int dsa_tree_setup(struct dsa_swi +@@ -1149,8 +1172,9 @@ static int dsa_tree_setup(struct dsa_swi teardown_master: dsa_tree_teardown_master(dst); diff --git a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch b/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch index 93cad0c98..a46e06ef8 100644 --- a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch +++ b/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c -@@ -545,6 +545,7 @@ static void dsa_port_teardown(struct dsa +@@ -567,6 +567,7 @@ static void dsa_port_teardown(struct dsa struct devlink_port *dlp = &dp->devlink_port; struct dsa_switch *ds = dp->ds; struct dsa_mac_addr *a, *tmp; @@ -51,7 +51,7 @@ Signed-off-by: David S. Miller if (!dp->setup) return; -@@ -566,9 +567,11 @@ static void dsa_port_teardown(struct dsa +@@ -588,9 +589,11 @@ static void dsa_port_teardown(struct dsa dsa_port_link_unregister_of(dp); break; case DSA_PORT_TYPE_USER: @@ -65,7 +65,7 @@ Signed-off-by: David S. Miller } break; } -@@ -1130,17 +1133,17 @@ static int dsa_tree_setup(struct dsa_swi +@@ -1152,17 +1155,17 @@ static int dsa_tree_setup(struct dsa_swi if (err) goto teardown_cpu_ports; @@ -87,7 +87,7 @@ Signed-off-by: David S. Miller dst->setup = true; -@@ -1148,10 +1151,10 @@ static int dsa_tree_setup(struct dsa_swi +@@ -1170,10 +1173,10 @@ static int dsa_tree_setup(struct dsa_swi return 0; @@ -100,7 +100,7 @@ Signed-off-by: David S. Miller teardown_switches: dsa_tree_teardown_switches(dst); teardown_cpu_ports: -@@ -1169,10 +1172,10 @@ static void dsa_tree_teardown(struct dsa +@@ -1191,10 +1194,10 @@ static void dsa_tree_teardown(struct dsa dsa_tree_teardown_lags(dst); diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch index bffdcb288..15122950c 100644 --- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch +++ b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch @@ -68,7 +68,7 @@ Signed-off-by: David S. Miller static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) { return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED; -@@ -949,6 +959,13 @@ struct dsa_switch_ops { +@@ -957,6 +967,13 @@ struct dsa_switch_ops { int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags); int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); @@ -84,7 +84,7 @@ Signed-off-by: David S. Miller #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c -@@ -1275,6 +1275,52 @@ out_unlock: +@@ -1297,6 +1297,52 @@ out_unlock: return err; } diff --git a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch b/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch index 6478d580c..c55c5271d 100644 --- a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch +++ b/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch @@ -44,7 +44,7 @@ Signed-off-by: David S. Miller #include "dsa_priv.h" -@@ -1060,9 +1061,18 @@ static int dsa_tree_setup_master(struct +@@ -1082,9 +1083,18 @@ static int dsa_tree_setup_master(struct list_for_each_entry(dp, &dst->ports, list) { if (dsa_port_is_cpu(dp)) { @@ -64,7 +64,7 @@ Signed-off-by: David S. Miller } } -@@ -1077,9 +1087,19 @@ static void dsa_tree_teardown_master(str +@@ -1099,9 +1109,19 @@ static void dsa_tree_teardown_master(str rtnl_lock(); diff --git a/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch b/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch new file mode 100644 index 000000000..34607c223 --- /dev/null +++ b/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch @@ -0,0 +1,28 @@ +From c3664d913dc115cab4a5fdb5634df4887048000e Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 4 Feb 2022 13:03:36 +0300 +Subject: [PATCH 1/1] net: dsa: qca8k: check correct variable in + qca8k_phy_eth_command() + +This is a copy and paste bug. It was supposed to check "clear_skb" +instead of "write_skb". + +Fixes: 2cd548566384 ("net: dsa: qca8k: add support for phy read/write with mgmt Ethernet") +Signed-off-by: Dan Carpenter +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -1018,7 +1018,7 @@ qca8k_phy_eth_command(struct qca8k_priv + + clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, + QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); +- if (!write_skb) { ++ if (!clear_skb) { + ret = -ENOMEM; + goto err_clear_skb; + } diff --git a/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch b/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch new file mode 100644 index 000000000..d8cf26630 --- /dev/null +++ b/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch @@ -0,0 +1,34 @@ +From 4f5e483b8c7a644733db941a1ae00173baa7b463 Mon Sep 17 00:00:00 2001 +From: kernel test robot +Date: Thu, 10 Feb 2022 06:13:04 +0800 +Subject: [PATCH 1/1] net: dsa: qca8k: fix noderef.cocci warnings + +drivers/net/dsa/qca8k.c:422:37-43: ERROR: application of sizeof to pointer + + sizeof when applied to a pointer typed expression gives the size of + the pointer + +Generated by: scripts/coccinelle/misc/noderef.cocci + +Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet") +CC: Ansuel Smith +Reported-by: kernel test robot +Signed-off-by: kernel test robot +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20220209221304.GA17529@d2214a582157 +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca8k.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -456,7 +456,7 @@ qca8k_regmap_read(void *ctx, uint32_t re + u16 r1, r2, page; + int ret; + +- if (!qca8k_read_eth(priv, reg, val, sizeof(val))) ++ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) + return 0; + + qca8k_split_addr(reg, &r1, &r2, &page); diff --git a/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch new file mode 100644 index 000000000..57df4c126 --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch @@ -0,0 +1,79 @@ +From 69fd055957a02309ffdc23d887a01988b6e5bab1 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:12 +0200 +Subject: [PATCH 1/6] net: dsa: qca8k: drop MTU tracking from qca8k_priv + +DSA set the CPU port based on the largest MTU of all the slave ports. +Based on this we can drop the MTU array from qca8k_priv and set the +port_change_mtu logic on DSA changing MTU of the CPU port as the switch +have a global MTU settingfor each port. + +Signed-off-by: Ansuel Smith +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 26 +++++++++----------------- + drivers/net/dsa/qca8k.h | 1 - + 2 files changed, 9 insertions(+), 18 deletions(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -1803,16 +1803,6 @@ qca8k_setup(struct dsa_switch *ds) + QCA8K_PORT_HOL_CTRL1_WRED_EN, + mask); + } +- +- /* Set initial MTU for every port. +- * We have only have a general MTU setting. So track +- * every port and set the max across all port. +- * Set per port MTU to 1500 as the MTU change function +- * will add the overhead and if its set to 1518 then it +- * will apply the overhead again and we will end up with +- * MTU of 1536 instead of 1518 +- */ +- priv->port_mtu[i] = ETH_DATA_LEN; + } + + /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ +@@ -2525,13 +2515,16 @@ static int + qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) + { + struct qca8k_priv *priv = ds->priv; +- int ret, i, mtu = 0; +- +- priv->port_mtu[port] = new_mtu; ++ int ret; + +- for (i = 0; i < QCA8K_NUM_PORTS; i++) +- if (priv->port_mtu[i] > mtu) +- mtu = priv->port_mtu[i]; ++ /* We have only have a general MTU setting. ++ * DSA always set the CPU port's MTU to the largest MTU of the slave ++ * ports. ++ * Setting MTU just for the CPU port is sufficient to correctly set a ++ * value for every port. ++ */ ++ if (!dsa_is_cpu_port(ds, port)) ++ return 0; + + /* To change the MAX_FRAME_SIZE the cpu ports must be off or + * the switch panics. +@@ -2545,7 +2538,7 @@ qca8k_port_change_mtu(struct dsa_switch + qca8k_port_set_status(priv, 6, 0); + + /* Include L2 header / FCS length */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); + + if (priv->port_sts[0].enabled) + qca8k_port_set_status(priv, 0, 1); +--- a/drivers/net/dsa/qca8k.h ++++ b/drivers/net/dsa/qca8k.h +@@ -392,7 +392,6 @@ struct qca8k_priv { + struct device *dev; + struct dsa_switch_ops ops; + struct gpio_desc *reset_gpio; +- unsigned int port_mtu[QCA8K_NUM_PORTS]; + struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ + struct qca8k_mgmt_eth_data mgmt_eth_data; + struct qca8k_mib_eth_data mib_eth_data; diff --git a/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch new file mode 100644 index 000000000..3cacd7e4f --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch @@ -0,0 +1,116 @@ +From 2b8fd87af7f156942971789abac8ee2bb60c03bc Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:13 +0200 +Subject: [PATCH 2/6] net: dsa: qca8k: drop port_sts from qca8k_priv + +Port_sts is a thing of the past for this driver. It was something +present on the initial implementation of this driver and parts of the +original struct were dropped over time. Using an array of int to store if +a port is enabled or not to handle PM operation seems overkill. Switch +and use a simple u8 to store the port status where each bit correspond +to a port. (bit is set port is enabled, bit is not set, port is disabled) +Also add some comments to better describe why we need to track port +status. + +Signed-off-by: Ansuel Smith +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 15 +++++++++------ + drivers/net/dsa/qca8k.h | 9 ++++----- + 2 files changed, 13 insertions(+), 11 deletions(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -2494,7 +2494,7 @@ qca8k_port_enable(struct dsa_switch *ds, + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + + qca8k_port_set_status(priv, port, 1); +- priv->port_sts[port].enabled = 1; ++ priv->port_enabled_map |= BIT(port); + + if (dsa_is_user_port(ds, port)) + phy_support_asym_pause(phy); +@@ -2508,7 +2508,7 @@ qca8k_port_disable(struct dsa_switch *ds + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; + + qca8k_port_set_status(priv, port, 0); +- priv->port_sts[port].enabled = 0; ++ priv->port_enabled_map &= ~BIT(port); + } + + static int +@@ -2531,19 +2531,19 @@ qca8k_port_change_mtu(struct dsa_switch + * Turn off both cpu ports before applying the new value to prevent + * this. + */ +- if (priv->port_sts[0].enabled) ++ if (priv->port_enabled_map & BIT(0)) + qca8k_port_set_status(priv, 0, 0); + +- if (priv->port_sts[6].enabled) ++ if (priv->port_enabled_map & BIT(6)) + qca8k_port_set_status(priv, 6, 0); + + /* Include L2 header / FCS length */ + ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); + +- if (priv->port_sts[0].enabled) ++ if (priv->port_enabled_map & BIT(0)) + qca8k_port_set_status(priv, 0, 1); + +- if (priv->port_sts[6].enabled) ++ if (priv->port_enabled_map & BIT(6)) + qca8k_port_set_status(priv, 6, 1); + + return ret; +@@ -3199,13 +3199,16 @@ static void qca8k_sw_shutdown(struct mdi + static void + qca8k_set_pm(struct qca8k_priv *priv, int enable) + { +- int i; ++ int port; + +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (!priv->port_sts[i].enabled) ++ for (port = 0; port < QCA8K_NUM_PORTS; port++) { ++ /* Do not enable on resume if the port was ++ * disabled before. ++ */ ++ if (!(priv->port_enabled_map & BIT(port))) + continue; + +- qca8k_port_set_status(priv, i, enable); ++ qca8k_port_set_status(priv, port, enable); + } + } + +--- a/drivers/net/dsa/qca8k.h ++++ b/drivers/net/dsa/qca8k.h +@@ -324,10 +324,6 @@ enum qca8k_mid_cmd { + QCA8K_MIB_CAST = 3, + }; + +-struct ar8xxx_port_status { +- int enabled; +-}; +- + struct qca8k_match_data { + u8 id; + bool reduced_package; +@@ -382,11 +378,14 @@ struct qca8k_priv { + u8 mirror_rx; + u8 mirror_tx; + u8 lag_hash_mode; ++ /* Each bit correspond to a port. This switch can support a max of 7 port. ++ * Bit 1: port enabled. Bit 0: port disabled. ++ */ ++ u8 port_enabled_map; + bool legacy_phy_port_mapping; + struct qca8k_ports_config ports_config; + struct regmap *regmap; + struct mii_bus *bus; +- struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS]; + struct dsa_switch *ds; + struct mutex reg_mutex; + struct device *dev; diff --git a/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch b/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch new file mode 100644 index 000000000..12c322107 --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch @@ -0,0 +1,173 @@ +From 8255212e4130bd2dc1463286a3dddb74797bbdc1 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:14 +0200 +Subject: [PATCH 3/6] net: dsa: qca8k: rework and simplify mdiobus logic + +In an attempt to reduce qca8k_priv space, rework and simplify mdiobus +logic. +We now declare a mdiobus instead of relying on DSA phy_read/write even +if a mdio node is not present. This is all to make the qca8k ops static +and not switch specific. With a legacy implementation where port doesn't +have a phy map declared in the dts with a mdio node, we declare a +'qca8k-legacy' mdiobus. The conversion logic is used as legacy read and +write ops are used instead of the internal one. +Also drop the legacy_phy_port_mapping as we now declare mdiobus with ops +that already address the workaround. + +Signed-off-by: Ansuel Smith +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 95 +++++++++++++---------------------------- + drivers/net/dsa/qca8k.h | 1 - + 2 files changed, 29 insertions(+), 67 deletions(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -1291,83 +1291,63 @@ qca8k_internal_mdio_read(struct mii_bus + } + + static int +-qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data) ++qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) + { +- struct qca8k_priv *priv = ds->priv; +- int ret; ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; + +- /* Check if the legacy mapping should be used and the +- * port is not correctly mapped to the right PHY in the +- * devicetree +- */ +- if (priv->legacy_phy_port_mapping) +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, false, port, regnum, 0); +- if (!ret) +- return ret; +- +- return qca8k_mdio_write(priv, port, regnum, data); ++ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); + } + + static int +-qca8k_phy_read(struct dsa_switch *ds, int port, int regnum) ++qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) + { +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- /* Check if the legacy mapping should be used and the +- * port is not correctly mapped to the right PHY in the +- * devicetree +- */ +- if (priv->legacy_phy_port_mapping) +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, true, port, regnum, 0); +- if (ret >= 0) +- return ret; +- +- ret = qca8k_mdio_read(priv, port, regnum); +- +- if (ret < 0) +- return 0xffff; ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; + +- return ret; ++ return qca8k_internal_mdio_read(slave_bus, port, regnum); + } + + static int +-qca8k_mdio_register(struct qca8k_priv *priv, struct device_node *mdio) ++qca8k_mdio_register(struct qca8k_priv *priv) + { + struct dsa_switch *ds = priv->ds; ++ struct device_node *mdio; + struct mii_bus *bus; + + bus = devm_mdiobus_alloc(ds->dev); +- + if (!bus) + return -ENOMEM; + + bus->priv = (void *)priv; +- bus->name = "qca8k slave mii"; +- bus->read = qca8k_internal_mdio_read; +- bus->write = qca8k_internal_mdio_write; +- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", +- ds->index); +- + bus->parent = ds->dev; + bus->phy_mask = ~ds->phys_mii_mask; +- + ds->slave_mii_bus = bus; + +- return devm_of_mdiobus_register(priv->dev, bus, mdio); ++ /* Check if the devicetree declare the port:phy mapping */ ++ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); ++ if (of_device_is_available(mdio)) { ++ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index); ++ bus->name = "qca8k slave mii"; ++ bus->read = qca8k_internal_mdio_read; ++ bus->write = qca8k_internal_mdio_write; ++ return devm_of_mdiobus_register(priv->dev, bus, mdio); ++ } ++ ++ /* If a mapping can't be found the legacy mapping is used, ++ * using the qca8k_port_to_phy function ++ */ ++ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", ++ ds->dst->index, ds->index); ++ bus->name = "qca8k-legacy slave mii"; ++ bus->read = qca8k_legacy_mdio_read; ++ bus->write = qca8k_legacy_mdio_write; ++ return devm_mdiobus_register(priv->dev, bus); + } + + static int + qca8k_setup_mdio_bus(struct qca8k_priv *priv) + { + u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; +- struct device_node *ports, *port, *mdio; ++ struct device_node *ports, *port; + phy_interface_t mode; + int err; + +@@ -1429,24 +1409,7 @@ qca8k_setup_mdio_bus(struct qca8k_priv * + QCA8K_MDIO_MASTER_EN); + } + +- /* Check if the devicetree declare the port:phy mapping */ +- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); +- if (of_device_is_available(mdio)) { +- err = qca8k_mdio_register(priv, mdio); +- if (err) +- of_node_put(mdio); +- +- return err; +- } +- +- /* If a mapping can't be found the legacy mapping is used, +- * using the qca8k_port_to_phy function +- */ +- priv->legacy_phy_port_mapping = true; +- priv->ops.phy_read = qca8k_phy_read; +- priv->ops.phy_write = qca8k_phy_write; +- +- return 0; ++ return qca8k_mdio_register(priv); + } + + static int +--- a/drivers/net/dsa/qca8k.h ++++ b/drivers/net/dsa/qca8k.h +@@ -382,7 +382,6 @@ struct qca8k_priv { + * Bit 1: port enabled. Bit 0: port disabled. + */ + u8 port_enabled_map; +- bool legacy_phy_port_mapping; + struct qca8k_ports_config ports_config; + struct regmap *regmap; + struct mii_bus *bus; diff --git a/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch new file mode 100644 index 000000000..8641000ab --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch @@ -0,0 +1,39 @@ +From 2349b83a2486c55b9dd225326f0172a84a43c5e4 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:15 +0200 +Subject: [PATCH 4/6] net: dsa: qca8k: drop dsa_switch_ops from qca8k_priv + +Now that dsa_switch_ops is not switch specific anymore, we can drop it +from qca8k_priv and use the static ops directly for the dsa_switch +pointer. + +Signed-off-by: Ansuel Smith +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 3 +-- + drivers/net/dsa/qca8k.h | 1 - + 2 files changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -3121,8 +3121,7 @@ qca8k_sw_probe(struct mdio_device *mdiod + priv->ds->dev = &mdiodev->dev; + priv->ds->num_ports = QCA8K_NUM_PORTS; + priv->ds->priv = priv; +- priv->ops = qca8k_switch_ops; +- priv->ds->ops = &priv->ops; ++ priv->ds->ops = &qca8k_switch_ops; + mutex_init(&priv->reg_mutex); + dev_set_drvdata(&mdiodev->dev, priv); + +--- a/drivers/net/dsa/qca8k.h ++++ b/drivers/net/dsa/qca8k.h +@@ -388,7 +388,6 @@ struct qca8k_priv { + struct dsa_switch *ds; + struct mutex reg_mutex; + struct device *dev; +- struct dsa_switch_ops ops; + struct gpio_desc *reset_gpio; + struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ + struct qca8k_mgmt_eth_data mgmt_eth_data; diff --git a/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch b/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch new file mode 100644 index 000000000..b14b22091 --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch @@ -0,0 +1,33 @@ +From 6cfc03b602200c5cbbd8d906fd905547814e83df Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:16 +0200 +Subject: [PATCH 5/6] net: dsa: qca8k: correctly handle mdio read error + +Restore original way to handle mdio read error by returning 0xffff. +This was wrongly changed when the internal_mdio_read was introduced, +now that both legacy and internal use the same function, make sure that +they behave the same way. + +Fixes: ce062a0adbfe ("net: dsa: qca8k: fix kernel panic with legacy mdio mapping") +Signed-off-by: Ansuel Smith +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -1287,7 +1287,12 @@ qca8k_internal_mdio_read(struct mii_bus + if (ret >= 0) + return ret; + +- return qca8k_mdio_read(priv, phy, regnum); ++ ret = qca8k_mdio_read(priv, phy, regnum); ++ ++ if (ret < 0) ++ return 0xffff; ++ ++ return ret; + } + + static int diff --git a/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch b/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch new file mode 100644 index 000000000..094686f11 --- /dev/null +++ b/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch @@ -0,0 +1,44 @@ +From 8d1af50842bf2774f4edc57054206e909117469b Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 16 Apr 2022 01:30:17 +0200 +Subject: [PATCH 6/6] net: dsa: qca8k: unify bus id naming with legacy and OF + mdio bus + +Add support for multiple switch with OF mdio bus declaration. +Unify the bus id naming and use the same logic for both legacy and OF +mdio bus. + +Signed-off-by: Ansuel Smith +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca8k.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/net/dsa/qca8k.c ++++ b/drivers/net/dsa/qca8k.c +@@ -1323,6 +1323,8 @@ qca8k_mdio_register(struct qca8k_priv *p + return -ENOMEM; + + bus->priv = (void *)priv; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", ++ ds->dst->index, ds->index); + bus->parent = ds->dev; + bus->phy_mask = ~ds->phys_mii_mask; + ds->slave_mii_bus = bus; +@@ -1330,7 +1332,6 @@ qca8k_mdio_register(struct qca8k_priv *p + /* Check if the devicetree declare the port:phy mapping */ + mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); + if (of_device_is_available(mdio)) { +- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index); + bus->name = "qca8k slave mii"; + bus->read = qca8k_internal_mdio_read; + bus->write = qca8k_internal_mdio_write; +@@ -1340,8 +1341,6 @@ qca8k_mdio_register(struct qca8k_priv *p + /* If a mapping can't be found the legacy mapping is used, + * using the qca8k_port_to_phy function + */ +- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", +- ds->dst->index, ds->index); + bus->name = "qca8k-legacy slave mii"; + bus->read = qca8k_legacy_mdio_read; + bus->write = qca8k_legacy_mdio_write; diff --git a/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch b/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch new file mode 100644 index 000000000..1534113f1 --- /dev/null +++ b/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch @@ -0,0 +1,7389 @@ +From 4bbaf764e1e1786eb937fdb62172f656f512e116 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 13 Jul 2022 22:53:50 +0200 +Subject: [PATCH 1/1] net: dsa: qca8k: move driver to qca dir + +Move qca8k driver to qca dir in preparation for code split and +introduction of ipq4019 switch based on qca8k. + +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/Kconfig | 8 -------- + drivers/net/dsa/Makefile | 1 - + drivers/net/dsa/qca/Kconfig | 8 ++++++++ + drivers/net/dsa/qca/Makefile | 1 + + drivers/net/dsa/{ => qca}/qca8k.c | 0 + drivers/net/dsa/{ => qca}/qca8k.h | 0 + 6 files changed, 9 insertions(+), 9 deletions(-) + rename drivers/net/dsa/{ => qca}/qca8k.c (100%) + rename drivers/net/dsa/{ => qca}/qca8k.h (100%) + +--- a/drivers/net/dsa/Kconfig ++++ b/drivers/net/dsa/Kconfig +@@ -60,14 +60,6 @@ source "drivers/net/dsa/sja1105/Kconfig" + + source "drivers/net/dsa/xrs700x/Kconfig" + +-config NET_DSA_QCA8K +- tristate "Qualcomm Atheros QCA8K Ethernet switch family support" +- select NET_DSA_TAG_QCA +- select REGMAP +- help +- This enables support for the Qualcomm Atheros QCA8K Ethernet +- switch chips. +- + config NET_DSA_REALTEK_SMI + tristate "Realtek SMI Ethernet switch family support" + select NET_DSA_TAG_RTL4_A +--- a/drivers/net/dsa/Makefile ++++ b/drivers/net/dsa/Makefile +@@ -8,7 +8,6 @@ endif + obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o + obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o + obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o +-obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o + obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o + realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o + obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o +--- a/drivers/net/dsa/qca/Kconfig ++++ b/drivers/net/dsa/qca/Kconfig +@@ -7,3 +7,11 @@ config NET_DSA_AR9331 + help + This enables support for the Qualcomm Atheros AR9331 built-in Ethernet + switch. ++ ++config NET_DSA_QCA8K ++ tristate "Qualcomm Atheros QCA8K Ethernet switch family support" ++ select NET_DSA_TAG_QCA ++ select REGMAP ++ help ++ This enables support for the Qualcomm Atheros QCA8K Ethernet ++ switch chips. +--- a/drivers/net/dsa/qca/Makefile ++++ b/drivers/net/dsa/qca/Makefile +@@ -1,2 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o ++obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k.c +@@ -0,0 +1,3243 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2009 Felix Fietkau ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2016 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qca8k.h" ++ ++#define MIB_DESC(_s, _o, _n) \ ++ { \ ++ .size = (_s), \ ++ .offset = (_o), \ ++ .name = (_n), \ ++ } ++ ++static const struct qca8k_mib_desc ar8327_mib[] = { ++ MIB_DESC(1, 0x00, "RxBroad"), ++ MIB_DESC(1, 0x04, "RxPause"), ++ MIB_DESC(1, 0x08, "RxMulti"), ++ MIB_DESC(1, 0x0c, "RxFcsErr"), ++ MIB_DESC(1, 0x10, "RxAlignErr"), ++ MIB_DESC(1, 0x14, "RxRunt"), ++ MIB_DESC(1, 0x18, "RxFragment"), ++ MIB_DESC(1, 0x1c, "Rx64Byte"), ++ MIB_DESC(1, 0x20, "Rx128Byte"), ++ MIB_DESC(1, 0x24, "Rx256Byte"), ++ MIB_DESC(1, 0x28, "Rx512Byte"), ++ MIB_DESC(1, 0x2c, "Rx1024Byte"), ++ MIB_DESC(1, 0x30, "Rx1518Byte"), ++ MIB_DESC(1, 0x34, "RxMaxByte"), ++ MIB_DESC(1, 0x38, "RxTooLong"), ++ MIB_DESC(2, 0x3c, "RxGoodByte"), ++ MIB_DESC(2, 0x44, "RxBadByte"), ++ MIB_DESC(1, 0x4c, "RxOverFlow"), ++ MIB_DESC(1, 0x50, "Filtered"), ++ MIB_DESC(1, 0x54, "TxBroad"), ++ MIB_DESC(1, 0x58, "TxPause"), ++ MIB_DESC(1, 0x5c, "TxMulti"), ++ MIB_DESC(1, 0x60, "TxUnderRun"), ++ MIB_DESC(1, 0x64, "Tx64Byte"), ++ MIB_DESC(1, 0x68, "Tx128Byte"), ++ MIB_DESC(1, 0x6c, "Tx256Byte"), ++ MIB_DESC(1, 0x70, "Tx512Byte"), ++ MIB_DESC(1, 0x74, "Tx1024Byte"), ++ MIB_DESC(1, 0x78, "Tx1518Byte"), ++ MIB_DESC(1, 0x7c, "TxMaxByte"), ++ MIB_DESC(1, 0x80, "TxOverSize"), ++ MIB_DESC(2, 0x84, "TxByte"), ++ MIB_DESC(1, 0x8c, "TxCollision"), ++ MIB_DESC(1, 0x90, "TxAbortCol"), ++ MIB_DESC(1, 0x94, "TxMultiCol"), ++ MIB_DESC(1, 0x98, "TxSingleCol"), ++ MIB_DESC(1, 0x9c, "TxExcDefer"), ++ MIB_DESC(1, 0xa0, "TxDefer"), ++ MIB_DESC(1, 0xa4, "TxLateCol"), ++ MIB_DESC(1, 0xa8, "RXUnicast"), ++ MIB_DESC(1, 0xac, "TXUnicast"), ++}; ++ ++static void ++qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) ++{ ++ regaddr >>= 1; ++ *r1 = regaddr & 0x1e; ++ ++ regaddr >>= 5; ++ *r2 = regaddr & 0x7; ++ ++ regaddr >>= 3; ++ *page = regaddr & 0x3ff; ++} ++ ++static int ++qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) ++{ ++ u16 *cached_lo = &priv->mdio_cache.lo; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (lo == *cached_lo) ++ return 0; ++ ++ ret = bus->write(bus, phy_id, regnum, lo); ++ if (ret < 0) ++ dev_err_ratelimited(&bus->dev, ++ "failed to write qca8k 32bit lo register\n"); ++ ++ *cached_lo = lo; ++ return 0; ++} ++ ++static int ++qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) ++{ ++ u16 *cached_hi = &priv->mdio_cache.hi; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (hi == *cached_hi) ++ return 0; ++ ++ ret = bus->write(bus, phy_id, regnum, hi); ++ if (ret < 0) ++ dev_err_ratelimited(&bus->dev, ++ "failed to write qca8k 32bit hi register\n"); ++ ++ *cached_hi = hi; ++ return 0; ++} ++ ++static int ++qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) ++{ ++ int ret; ++ ++ ret = bus->read(bus, phy_id, regnum); ++ if (ret >= 0) { ++ *val = ret; ++ ret = bus->read(bus, phy_id, regnum + 1); ++ *val |= ret << 16; ++ } ++ ++ if (ret < 0) { ++ dev_err_ratelimited(&bus->dev, ++ "failed to read qca8k 32bit register\n"); ++ *val = 0; ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void ++qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) ++{ ++ u16 lo, hi; ++ int ret; ++ ++ lo = val & 0xffff; ++ hi = (u16)(val >> 16); ++ ++ ret = qca8k_set_lo(priv, phy_id, regnum, lo); ++ if (ret >= 0) ++ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); ++} ++ ++static int ++qca8k_set_page(struct qca8k_priv *priv, u16 page) ++{ ++ u16 *cached_page = &priv->mdio_cache.page; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (page == *cached_page) ++ return 0; ++ ++ ret = bus->write(bus, 0x18, 0, page); ++ if (ret < 0) { ++ dev_err_ratelimited(&bus->dev, ++ "failed to set qca8k page\n"); ++ return ret; ++ } ++ ++ *cached_page = page; ++ usleep_range(1000, 2000); ++ return 0; ++} ++ ++static int ++qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) ++{ ++ return regmap_read(priv->regmap, reg, val); ++} ++ ++static int ++qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) ++{ ++ return regmap_write(priv->regmap, reg, val); ++} ++ ++static int ++qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) ++{ ++ return regmap_update_bits(priv->regmap, reg, mask, write_val); ++} ++ ++static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u8 len, cmd; ++ ++ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); ++ mgmt_eth_data = &priv->mgmt_eth_data; ++ ++ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); ++ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); ++ ++ /* Make sure the seq match the requested packet */ ++ if (mgmt_ethhdr->seq == mgmt_eth_data->seq) ++ mgmt_eth_data->ack = true; ++ ++ if (cmd == MDIO_READ) { ++ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; ++ ++ /* Get the rest of the 12 byte of data. ++ * The read/write function will extract the requested data. ++ */ ++ if (len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(mgmt_eth_data->data + 1, skb->data, ++ QCA_HDR_MGMT_DATA2_LEN); ++ } ++ ++ complete(&mgmt_eth_data->rw_done); ++} ++ ++static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, ++ int priority, unsigned int len) ++{ ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ unsigned int real_len; ++ struct sk_buff *skb; ++ u32 *data2; ++ u16 hdr; ++ ++ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); ++ if (!skb) ++ return NULL; ++ ++ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte ++ * Actually for some reason the steps are: ++ * 0: nothing ++ * 1-4: first 4 byte ++ * 5-6: first 12 byte ++ * 7-15: all 16 byte ++ */ ++ if (len == 16) ++ real_len = 15; ++ else ++ real_len = len; ++ ++ skb_reset_mac_header(skb); ++ skb_set_network_header(skb, skb->len); ++ ++ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); ++ ++ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); ++ hdr |= QCA_HDR_XMIT_FROM_CPU; ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); ++ ++ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, ++ QCA_HDR_MGMT_CHECK_CODE_VAL); ++ ++ if (cmd == MDIO_WRITE) ++ mgmt_ethhdr->mdio_data = *val; ++ ++ mgmt_ethhdr->hdr = htons(hdr); ++ ++ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); ++ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ return skb; ++} ++ ++static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) ++{ ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ ++ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; ++ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); ++} ++ ++static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; ++ struct sk_buff *skb; ++ bool ack; ++ int ret; ++ ++ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, ++ QCA8K_ETHERNET_MDIO_PRIORITY, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check mgmt_master if is operational */ ++ if (!priv->mgmt_master) { ++ kfree_skb(skb); ++ mutex_unlock(&mgmt_eth_data->mutex); ++ return -EINVAL; ++ } ++ ++ skb->dev = priv->mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the mdio pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); ++ ++ *val = mgmt_eth_data->data[0]; ++ if (len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ ack = mgmt_eth_data->ack; ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; ++ struct sk_buff *skb; ++ bool ack; ++ int ret; ++ ++ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, ++ QCA8K_ETHERNET_MDIO_PRIORITY, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check mgmt_master if is operational */ ++ if (!priv->mgmt_master) { ++ kfree_skb(skb); ++ mutex_unlock(&mgmt_eth_data->mutex); ++ return -EINVAL; ++ } ++ ++ skb->dev = priv->mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the mdio pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); ++ ++ ack = mgmt_eth_data->ack; ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int ++qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) ++{ ++ u32 val = 0; ++ int ret; ++ ++ ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); ++ if (ret) ++ return ret; ++ ++ val &= ~mask; ++ val |= write_val; ++ ++ return qca8k_write_eth(priv, reg, &val, sizeof(val)); ++} ++ ++static int ++qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ ++ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ u32 tmp; ++ ++ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ tmp = val[i]; ++ ++ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ int ret; ++ ++ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ return ret; ++} ++ ++static int ++qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ int ret; ++ ++ if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ return ret; ++} ++ ++static int ++qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); ++ if (ret < 0) ++ goto exit; ++ ++ val &= ~mask; ++ val |= write_val; ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static const struct regmap_range qca8k_readable_ranges[] = { ++ regmap_reg_range(0x0000, 0x00e4), /* Global control */ ++ regmap_reg_range(0x0100, 0x0168), /* EEE control */ ++ regmap_reg_range(0x0200, 0x0270), /* Parser control */ ++ regmap_reg_range(0x0400, 0x0454), /* ACL */ ++ regmap_reg_range(0x0600, 0x0718), /* Lookup */ ++ regmap_reg_range(0x0800, 0x0b70), /* QM */ ++ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ ++ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ ++ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ ++ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ ++ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ ++ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ ++ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ ++ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ ++ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ ++ ++}; ++ ++static const struct regmap_access_table qca8k_readable_table = { ++ .yes_ranges = qca8k_readable_ranges, ++ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), ++}; ++ ++static struct regmap_config qca8k_regmap_config = { ++ .reg_bits = 16, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x16ac, /* end MIB - Port6 range */ ++ .reg_read = qca8k_regmap_read, ++ .reg_write = qca8k_regmap_write, ++ .reg_update_bits = qca8k_regmap_update_bits, ++ .rd_table = &qca8k_readable_table, ++ .disable_locking = true, /* Locking is handled by qca8k read/write */ ++ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ ++}; ++ ++static int ++qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) ++{ ++ u32 val; ++ ++ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); ++} ++ ++static int ++qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) ++{ ++ u32 reg[3]; ++ int ret; ++ ++ /* load the ARL table into an array */ ++ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++ if (ret) ++ return ret; ++ ++ /* vid - 83:72 */ ++ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); ++ /* aging - 67:64 */ ++ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); ++ /* portmask - 54:48 */ ++ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); ++ /* mac - 47:0 */ ++ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); ++ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); ++ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); ++ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); ++ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); ++ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); ++ ++ return 0; ++} ++ ++static void ++qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, ++ u8 aging) ++{ ++ u32 reg[3] = { 0 }; ++ ++ /* vid - 83:72 */ ++ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); ++ /* aging - 67:64 */ ++ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); ++ /* portmask - 54:48 */ ++ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); ++ /* mac - 47:0 */ ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); ++ ++ /* load the array into the ARL table */ ++ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++} ++ ++static int ++qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and FDB index */ ++ reg = QCA8K_ATU_FUNC_BUSY; ++ reg |= cmd; ++ if (port >= 0) { ++ reg |= QCA8K_ATU_FUNC_PORT_EN; ++ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); ++ } ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_FDB_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_ATU_FUNC_FULL) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) ++{ ++ int ret; ++ ++ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); ++ if (ret < 0) ++ return ret; ++ ++ return qca8k_fdb_read(priv, fdb); ++} ++ ++static int ++qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, ++ u16 vid, u8 aging) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static void ++qca8k_fdb_flush(struct qca8k_priv *priv) ++{ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); ++ mutex_unlock(&priv->reg_mutex); ++} ++ ++static int ++qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_fdb_read(priv, &fdb); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule exist. Delete first */ ++ if (!fdb.aging) { ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ } ++ ++ /* Add port to fdb portmask */ ++ fdb.port_mask |= port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule doesn't exist. Why delete? */ ++ if (!fdb.aging) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ ++ /* Only port in the rule is this port. Don't re insert */ ++ if (fdb.port_mask == port_mask) ++ goto exit; ++ ++ /* Remove port from port mask */ ++ fdb.port_mask &= ~port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and VLAN index */ ++ reg = QCA8K_VTU_FUNC1_BUSY; ++ reg |= cmd; ++ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_VLAN_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_VTU_FUNC1_FULL) ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) ++{ ++ u32 reg; ++ int ret; ++ ++ /* ++ We do the right thing with VLAN 0 and treat it as untagged while ++ preserving the tag on egress. ++ */ ++ if (vid == 0) ++ return 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ if (untagged) ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); ++ else ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); ++ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) ++{ ++ u32 reg, mask; ++ int ret, i; ++ bool del; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); ++ ++ /* Check if we're the last member to be removed */ ++ del = true; ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); ++ ++ if ((reg & mask) != mask) { ++ del = false; ++ break; ++ } ++ } ++ ++ if (del) { ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); ++ } else { ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ } ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_mib_init(struct qca8k_priv *priv) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, ++ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, ++ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | ++ QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static void ++qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) ++{ ++ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; ++ ++ /* Port 0 and 6 have no internal PHY */ ++ if (port > 0 && port < 6) ++ mask |= QCA8K_PORT_STATUS_LINK_AUTO; ++ ++ if (enable) ++ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++ else ++ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++} ++ ++static int ++qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, ++ struct sk_buff *read_skb, u32 *val) ++{ ++ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); ++ bool ack; ++ int ret; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the copy pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ *val = mgmt_eth_data->data[0]; ++ ++ return 0; ++} ++ ++static int ++qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, ++ int regnum, u16 data) ++{ ++ struct sk_buff *write_skb, *clear_skb, *read_skb; ++ struct qca8k_mgmt_eth_data *mgmt_eth_data; ++ u32 write_val, clear_val = 0, val; ++ struct net_device *mgmt_master; ++ int ret, ret1; ++ bool ack; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ mgmt_eth_data = &priv->mgmt_eth_data; ++ ++ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum); ++ ++ if (read) { ++ write_val |= QCA8K_MDIO_MASTER_READ; ++ } else { ++ write_val |= QCA8K_MDIO_MASTER_WRITE; ++ write_val |= QCA8K_MDIO_MASTER_DATA(data); ++ } ++ ++ /* Prealloc all the needed skb before the lock */ ++ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); ++ if (!write_skb) ++ return -ENOMEM; ++ ++ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); ++ if (!clear_skb) { ++ ret = -ENOMEM; ++ goto err_clear_skb; ++ } ++ ++ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); ++ if (!read_skb) { ++ ret = -ENOMEM; ++ goto err_read_skb; ++ } ++ ++ /* Actually start the request: ++ * 1. Send mdio master packet ++ * 2. Busy Wait for mdio master command ++ * 3. Get the data if we are reading ++ * 4. Reset the mdio master (even with error) ++ */ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check if mgmt_master is operational */ ++ mgmt_master = priv->mgmt_master; ++ if (!mgmt_master) { ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ret = -EINVAL; ++ goto err_mgmt_master; ++ } ++ ++ read_skb->dev = mgmt_master; ++ clear_skb->dev = mgmt_master; ++ write_skb->dev = mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the write pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(write_skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) { ++ ret = -ETIMEDOUT; ++ kfree_skb(read_skb); ++ goto exit; ++ } ++ ++ if (!ack) { ++ ret = -EINVAL; ++ kfree_skb(read_skb); ++ goto exit; ++ } ++ ++ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, ++ !(val & QCA8K_MDIO_MASTER_BUSY), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, ++ mgmt_eth_data, read_skb, &val); ++ ++ if (ret < 0 && ret1 < 0) { ++ ret = ret1; ++ goto exit; ++ } ++ ++ if (read) { ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the read pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(read_skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) { ++ ret = -ETIMEDOUT; ++ goto exit; ++ } ++ ++ if (!ack) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; ++ } else { ++ kfree_skb(read_skb); ++ } ++exit: ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the clear pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(clear_skb); ++ ++ wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ return ret; ++ ++ /* Error handling before lock */ ++err_mgmt_master: ++ kfree_skb(read_skb); ++err_read_skb: ++ kfree_skb(clear_skb); ++err_clear_skb: ++ kfree_skb(write_skb); ++ ++ return ret; ++} ++ ++static u32 ++qca8k_port_to_phy(int port) ++{ ++ /* From Andrew Lunn: ++ * Port 0 has no internal phy. ++ * Port 1 has an internal PHY at MDIO address 0. ++ * Port 2 has an internal PHY at MDIO address 1. ++ * ... ++ * Port 5 has an internal PHY at MDIO address 4. ++ * Port 6 has no internal PHY. ++ */ ++ ++ return port - 1; ++} ++ ++static int ++qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) ++{ ++ u16 r1, r2, page; ++ u32 val; ++ int ret, ret1; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, ++ bus, 0x10 | r2, r1, &val); ++ ++ /* Check if qca8k_read has failed for a different reason ++ * before returnting -ETIMEDOUT ++ */ ++ if (ret < 0 && ret1 < 0) ++ return ret1; ++ ++ return ret; ++} ++ ++static int ++qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) ++{ ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum) | ++ QCA8K_MDIO_MASTER_DATA(data); ++ ++ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_BUSY); ++ ++exit: ++ /* even if the busy_wait timeouts try to clear the MASTER_EN */ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) ++{ ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum); ++ ++ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); ++ ++exit: ++ /* even if the busy_wait timeouts try to clear the MASTER_EN */ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ if (ret >= 0) ++ ret = val & QCA8K_MDIO_MASTER_DATA_MASK; ++ ++ return ret; ++} ++ ++static int ++qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) ++{ ++ struct qca8k_priv *priv = slave_bus->priv; ++ int ret; ++ ++ /* Use mdio Ethernet when available, fallback to legacy one on error */ ++ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); ++ if (!ret) ++ return 0; ++ ++ return qca8k_mdio_write(priv, phy, regnum, data); ++} ++ ++static int ++qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) ++{ ++ struct qca8k_priv *priv = slave_bus->priv; ++ int ret; ++ ++ /* Use mdio Ethernet when available, fallback to legacy one on error */ ++ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); ++ if (ret >= 0) ++ return ret; ++ ++ ret = qca8k_mdio_read(priv, phy, regnum); ++ ++ if (ret < 0) ++ return 0xffff; ++ ++ return ret; ++} ++ ++static int ++qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) ++{ ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; ++ ++ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); ++} ++ ++static int ++qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) ++{ ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; ++ ++ return qca8k_internal_mdio_read(slave_bus, port, regnum); ++} ++ ++static int ++qca8k_mdio_register(struct qca8k_priv *priv) ++{ ++ struct dsa_switch *ds = priv->ds; ++ struct device_node *mdio; ++ struct mii_bus *bus; ++ ++ bus = devm_mdiobus_alloc(ds->dev); ++ if (!bus) ++ return -ENOMEM; ++ ++ bus->priv = (void *)priv; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", ++ ds->dst->index, ds->index); ++ bus->parent = ds->dev; ++ bus->phy_mask = ~ds->phys_mii_mask; ++ ds->slave_mii_bus = bus; ++ ++ /* Check if the devicetree declare the port:phy mapping */ ++ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); ++ if (of_device_is_available(mdio)) { ++ bus->name = "qca8k slave mii"; ++ bus->read = qca8k_internal_mdio_read; ++ bus->write = qca8k_internal_mdio_write; ++ return devm_of_mdiobus_register(priv->dev, bus, mdio); ++ } ++ ++ /* If a mapping can't be found the legacy mapping is used, ++ * using the qca8k_port_to_phy function ++ */ ++ bus->name = "qca8k-legacy slave mii"; ++ bus->read = qca8k_legacy_mdio_read; ++ bus->write = qca8k_legacy_mdio_write; ++ return devm_mdiobus_register(priv->dev, bus); ++} ++ ++static int ++qca8k_setup_mdio_bus(struct qca8k_priv *priv) ++{ ++ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; ++ struct device_node *ports, *port; ++ phy_interface_t mode; ++ int err; ++ ++ ports = of_get_child_by_name(priv->dev->of_node, "ports"); ++ if (!ports) ++ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); ++ ++ if (!ports) ++ return -EINVAL; ++ ++ for_each_available_child_of_node(ports, port) { ++ err = of_property_read_u32(port, "reg", ®); ++ if (err) { ++ of_node_put(port); ++ of_node_put(ports); ++ return err; ++ } ++ ++ if (!dsa_is_user_port(priv->ds, reg)) ++ continue; ++ ++ of_get_phy_mode(port, &mode); ++ ++ if (of_property_read_bool(port, "phy-handle") && ++ mode != PHY_INTERFACE_MODE_INTERNAL) ++ external_mdio_mask |= BIT(reg); ++ else ++ internal_mdio_mask |= BIT(reg); ++ } ++ ++ of_node_put(ports); ++ if (!external_mdio_mask && !internal_mdio_mask) { ++ dev_err(priv->dev, "no PHYs are defined.\n"); ++ return -EINVAL; ++ } ++ ++ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through ++ * the MDIO_MASTER register also _disconnects_ the external MDC ++ * passthrough to the internal PHYs. It's not possible to use both ++ * configurations at the same time! ++ * ++ * Because this came up during the review process: ++ * If the external mdio-bus driver is capable magically disabling ++ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's ++ * accessors for the time being, it would be possible to pull this ++ * off. ++ */ ++ if (!!external_mdio_mask && !!internal_mdio_mask) { ++ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); ++ return -EINVAL; ++ } ++ ++ if (external_mdio_mask) { ++ /* Make sure to disable the internal mdio bus in cases ++ * a dt-overlay and driver reload changed the configuration ++ */ ++ ++ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_EN); ++ } ++ ++ return qca8k_mdio_register(priv); ++} ++ ++static int ++qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) ++{ ++ u32 mask = 0; ++ int ret = 0; ++ ++ /* SoC specific settings for ipq8064. ++ * If more device require this consider adding ++ * a dedicated binding. ++ */ ++ if (of_machine_is_compatible("qcom,ipq8064")) ++ mask |= QCA8K_MAC_PWR_RGMII0_1_8V; ++ ++ /* SoC specific settings for ipq8065 */ ++ if (of_machine_is_compatible("qcom,ipq8065")) ++ mask |= QCA8K_MAC_PWR_RGMII1_1_8V; ++ ++ if (mask) { ++ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, ++ QCA8K_MAC_PWR_RGMII0_1_8V | ++ QCA8K_MAC_PWR_RGMII1_1_8V, ++ mask); ++ } ++ ++ return ret; ++} ++ ++static int qca8k_find_cpu_port(struct dsa_switch *ds) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Find the connected cpu port. Valid port are 0 or 6 */ ++ if (dsa_is_cpu_port(ds, 0)) ++ return 0; ++ ++ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); ++ ++ if (dsa_is_cpu_port(ds, 6)) ++ return 6; ++ ++ return -EINVAL; ++} ++ ++static int ++qca8k_setup_of_pws_reg(struct qca8k_priv *priv) ++{ ++ struct device_node *node = priv->dev->of_node; ++ const struct qca8k_match_data *data; ++ u32 val = 0; ++ int ret; ++ ++ /* QCA8327 require to set to the correct mode. ++ * His bigger brother QCA8328 have the 172 pin layout. ++ * Should be applied by default but we set this just to make sure. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ data = of_device_get_match_data(priv->dev); ++ ++ /* Set the correct package of 148 pin for QCA8327 */ ++ if (data->reduced_package) ++ val |= QCA8327_PWS_PACKAGE148_EN; ++ ++ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, ++ val); ++ if (ret) ++ return ret; ++ } ++ ++ if (of_property_read_bool(node, "qca,ignore-power-on-sel")) ++ val |= QCA8K_PWS_POWER_ON_SEL; ++ ++ if (of_property_read_bool(node, "qca,led-open-drain")) { ++ if (!(val & QCA8K_PWS_POWER_ON_SEL)) { ++ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); ++ return -EINVAL; ++ } ++ ++ val |= QCA8K_PWS_LED_OPEN_EN_CSR; ++ } ++ ++ return qca8k_rmw(priv, QCA8K_REG_PWS, ++ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, ++ val); ++} ++ ++static int ++qca8k_parse_port_config(struct qca8k_priv *priv) ++{ ++ int port, cpu_port_index = -1, ret; ++ struct device_node *port_dn; ++ phy_interface_t mode; ++ struct dsa_port *dp; ++ u32 delay; ++ ++ /* We have 2 CPU port. Check them */ ++ for (port = 0; port < QCA8K_NUM_PORTS; port++) { ++ /* Skip every other port */ ++ if (port != 0 && port != 6) ++ continue; ++ ++ dp = dsa_to_port(priv->ds, port); ++ port_dn = dp->dn; ++ cpu_port_index++; ++ ++ if (!of_device_is_available(port_dn)) ++ continue; ++ ++ ret = of_get_phy_mode(port_dn, &mode); ++ if (ret) ++ continue; ++ ++ switch (mode) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_SGMII: ++ delay = 0; ++ ++ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) ++ /* Switch regs accept value in ns, convert ps to ns */ ++ delay = delay / 1000; ++ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_TXID) ++ delay = 1; ++ ++ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { ++ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); ++ delay = 3; ++ } ++ ++ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; ++ ++ delay = 0; ++ ++ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) ++ /* Switch regs accept value in ns, convert ps to ns */ ++ delay = delay / 1000; ++ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_RXID) ++ delay = 2; ++ ++ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { ++ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); ++ delay = 3; ++ } ++ ++ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; ++ ++ /* Skip sgmii parsing for rgmii* mode */ ++ if (mode == PHY_INTERFACE_MODE_RGMII || ++ mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_TXID || ++ mode == PHY_INTERFACE_MODE_RGMII_RXID) ++ break; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) ++ priv->ports_config.sgmii_tx_clk_falling_edge = true; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) ++ priv->ports_config.sgmii_rx_clk_falling_edge = true; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { ++ priv->ports_config.sgmii_enable_pll = true; ++ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); ++ priv->ports_config.sgmii_enable_pll = false; ++ } ++ ++ if (priv->switch_revision < 2) ++ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); ++ } ++ ++ break; ++ default: ++ continue; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_setup(struct dsa_switch *ds) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int cpu_port, ret, i; ++ u32 mask; ++ ++ cpu_port = qca8k_find_cpu_port(ds); ++ if (cpu_port < 0) { ++ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); ++ return cpu_port; ++ } ++ ++ /* Parse CPU port config to be later used in phy_link mac_config */ ++ ret = qca8k_parse_port_config(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_mdio_bus(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_of_pws_reg(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_mac_pwr_sel(priv); ++ if (ret) ++ return ret; ++ ++ /* Make sure MAC06 is disabled */ ++ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, ++ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); ++ if (ret) { ++ dev_err(priv->dev, "failed disabling MAC06 exchange"); ++ return ret; ++ } ++ ++ /* Enable CPU Port */ ++ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); ++ if (ret) { ++ dev_err(priv->dev, "failed enabling CPU port"); ++ return ret; ++ } ++ ++ /* Enable MIB counters */ ++ ret = qca8k_mib_init(priv); ++ if (ret) ++ dev_warn(priv->dev, "mib init failed"); ++ ++ /* Initial setup of all ports */ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ /* Disable forwarding by default on all ports */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, 0); ++ if (ret) ++ return ret; ++ ++ /* Enable QCA header mode on all cpu ports */ ++ if (dsa_is_cpu_port(ds, i)) { ++ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), ++ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | ++ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); ++ if (ret) { ++ dev_err(priv->dev, "failed enabling QCA header mode"); ++ return ret; ++ } ++ } ++ ++ /* Disable MAC by default on all user ports */ ++ if (dsa_is_user_port(ds, i)) ++ qca8k_port_set_status(priv, i, 0); ++ } ++ ++ /* Forward all unknown frames to CPU port for Linux processing ++ * Notice that in multi-cpu config only one port should be set ++ * for igmp, unknown, multicast and broadcast packet ++ */ ++ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); ++ if (ret) ++ return ret; ++ ++ /* Setup connection between CPU port & user ports ++ * Configure specific switch configuration for ports ++ */ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ /* CPU port gets connected to all user ports of the switch */ ++ if (dsa_is_cpu_port(ds, i)) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); ++ if (ret) ++ return ret; ++ } ++ ++ /* Individual user ports get connected to CPU port only */ ++ if (dsa_is_user_port(ds, i)) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, ++ BIT(cpu_port)); ++ if (ret) ++ return ret; ++ ++ /* Enable ARP Auto-learning by default */ ++ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_LEARN); ++ if (ret) ++ return ret; ++ ++ /* For port based vlans to work we need to set the ++ * default egress vid ++ */ ++ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), ++ QCA8K_EGREES_VLAN_PORT_MASK(i), ++ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), ++ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | ++ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); ++ if (ret) ++ return ret; ++ } ++ ++ /* The port 5 of the qca8337 have some problem in flood condition. The ++ * original legacy driver had some specific buffer and priority settings ++ * for the different port suggested by the QCA switch team. Add this ++ * missing settings to improve switch stability under load condition. ++ * This problem is limited to qca8337 and other qca8k switch are not affected. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8337) { ++ switch (i) { ++ /* The 2 CPU port and port 5 requires some different ++ * priority than any other ports. ++ */ ++ case 0: ++ case 5: ++ case 6: ++ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | ++ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); ++ break; ++ default: ++ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | ++ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); ++ } ++ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); ++ ++ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | ++ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_WRED_EN; ++ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), ++ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | ++ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_WRED_EN, ++ mask); ++ } ++ } ++ ++ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | ++ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); ++ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, ++ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | ++ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, ++ mask); ++ } ++ ++ /* Setup our port MTUs to match power on defaults */ ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); ++ if (ret) ++ dev_warn(priv->dev, "failed setting MTU settings"); ++ ++ /* Flush the FDB table */ ++ qca8k_fdb_flush(priv); ++ ++ /* We don't have interrupts for link changes, so we need to poll */ ++ ds->pcs_poll = true; ++ ++ /* Set min a max ageing value supported */ ++ ds->ageing_time_min = 7000; ++ ds->ageing_time_max = 458745000; ++ ++ /* Set max number of LAGs supported */ ++ ds->num_lag_ids = QCA8K_NUM_LAGS; ++ ++ return 0; ++} ++ ++static void ++qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, ++ u32 reg) ++{ ++ u32 delay, val = 0; ++ int ret; ++ ++ /* Delay can be declared in 3 different way. ++ * Mode to rgmii and internal-delay standard binding defined ++ * rgmii-id or rgmii-tx/rx phy mode set. ++ * The parse logic set a delay different than 0 only when one ++ * of the 3 different way is used. In all other case delay is ++ * not enabled. With ID or TX/RXID delay is enabled and set ++ * to the default and recommended value. ++ */ ++ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { ++ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; ++ ++ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; ++ } ++ ++ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { ++ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; ++ ++ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; ++ } ++ ++ /* Set RGMII delay based on the selected values */ ++ ret = qca8k_rmw(priv, reg, ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, ++ val); ++ if (ret) ++ dev_err(priv->dev, "Failed to set internal delay for CPU port%d", ++ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); ++} ++ ++static void ++qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int cpu_port_index, ret; ++ u32 reg, val; ++ ++ switch (port) { ++ case 0: /* 1st CPU port */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII) ++ return; ++ ++ reg = QCA8K_REG_PORT0_PAD_CTRL; ++ cpu_port_index = QCA8K_CPU_PORT0; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ /* Internal PHY, nothing to do */ ++ return; ++ case 6: /* 2nd CPU port / external PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII && ++ state->interface != PHY_INTERFACE_MODE_1000BASEX) ++ return; ++ ++ reg = QCA8K_REG_PORT6_PAD_CTRL; ++ cpu_port_index = QCA8K_CPU_PORT6; ++ break; ++ default: ++ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); ++ return; ++ } ++ ++ if (port != 6 && phylink_autoneg_inband(mode)) { ++ dev_err(ds->dev, "%s: in-band negotiation unsupported\n", ++ __func__); ++ return; ++ } ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); ++ ++ /* Configure rgmii delay */ ++ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); ++ ++ /* QCA8337 requires to set rgmii rx delay for all ports. ++ * This is enabled through PORT5_PAD_CTRL for all ports, ++ * rather than individual port registers. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8337) ++ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ /* Enable SGMII on the port */ ++ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); ++ ++ /* Enable/disable SerDes auto-negotiation as necessary */ ++ ret = qca8k_read(priv, QCA8K_REG_PWS, &val); ++ if (ret) ++ return; ++ if (phylink_autoneg_inband(mode)) ++ val &= ~QCA8K_PWS_SERDES_AEN_DIS; ++ else ++ val |= QCA8K_PWS_SERDES_AEN_DIS; ++ qca8k_write(priv, QCA8K_REG_PWS, val); ++ ++ /* Configure the SGMII parameters */ ++ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); ++ if (ret) ++ return; ++ ++ val |= QCA8K_SGMII_EN_SD; ++ ++ if (priv->ports_config.sgmii_enable_pll) ++ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | ++ QCA8K_SGMII_EN_TX; ++ ++ if (dsa_is_cpu_port(ds, port)) { ++ /* CPU port, we're talking to the CPU MAC, be a PHY */ ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_PHY; ++ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_MAC; ++ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_BASEX; ++ } ++ ++ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); ++ ++ /* From original code is reported port instability as SGMII also ++ * require delay set. Apply advised values here or take them from DT. ++ */ ++ if (state->interface == PHY_INTERFACE_MODE_SGMII) ++ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); ++ ++ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and ++ * falling edge is set writing in the PORT0 PAD reg ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8327 || ++ priv->switch_id == QCA8K_ID_QCA8337) ++ reg = QCA8K_REG_PORT0_PAD_CTRL; ++ ++ val = 0; ++ ++ /* SGMII Clock phase configuration */ ++ if (priv->ports_config.sgmii_rx_clk_falling_edge) ++ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; ++ ++ if (priv->ports_config.sgmii_tx_clk_falling_edge) ++ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; ++ ++ if (val) ++ ret = qca8k_rmw(priv, reg, ++ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | ++ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, ++ val); ++ ++ break; ++ default: ++ dev_err(ds->dev, "xMII mode %s not supported for port %d\n", ++ phy_modes(state->interface), port); ++ return; ++ } ++} ++ ++static void ++qca8k_phylink_validate(struct dsa_switch *ds, int port, ++ unsigned long *supported, ++ struct phylink_link_state *state) ++{ ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; ++ ++ switch (port) { ++ case 0: /* 1st CPU port */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII) ++ goto unsupported; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ /* Internal PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_GMII && ++ state->interface != PHY_INTERFACE_MODE_INTERNAL) ++ goto unsupported; ++ break; ++ case 6: /* 2nd CPU port / external PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII && ++ state->interface != PHY_INTERFACE_MODE_1000BASEX) ++ goto unsupported; ++ break; ++ default: ++unsupported: ++ linkmode_zero(supported); ++ return; ++ } ++ ++ phylink_set_port_modes(mask); ++ phylink_set(mask, Autoneg); ++ ++ phylink_set(mask, 1000baseT_Full); ++ phylink_set(mask, 10baseT_Half); ++ phylink_set(mask, 10baseT_Full); ++ phylink_set(mask, 100baseT_Half); ++ phylink_set(mask, 100baseT_Full); ++ ++ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) ++ phylink_set(mask, 1000baseX_Full); ++ ++ phylink_set(mask, Pause); ++ phylink_set(mask, Asym_Pause); ++ ++ linkmode_and(supported, supported, mask); ++ linkmode_and(state->advertising, state->advertising, mask); ++} ++ ++static int ++qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, ++ struct phylink_link_state *state) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg; ++ int ret; ++ ++ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); ++ if (ret < 0) ++ return ret; ++ ++ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); ++ state->an_complete = state->link; ++ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); ++ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : ++ DUPLEX_HALF; ++ ++ switch (reg & QCA8K_PORT_STATUS_SPEED) { ++ case QCA8K_PORT_STATUS_SPEED_10: ++ state->speed = SPEED_10; ++ break; ++ case QCA8K_PORT_STATUS_SPEED_100: ++ state->speed = SPEED_100; ++ break; ++ case QCA8K_PORT_STATUS_SPEED_1000: ++ state->speed = SPEED_1000; ++ break; ++ default: ++ state->speed = SPEED_UNKNOWN; ++ break; ++ } ++ ++ state->pause = MLO_PAUSE_NONE; ++ if (reg & QCA8K_PORT_STATUS_RXFLOW) ++ state->pause |= MLO_PAUSE_RX; ++ if (reg & QCA8K_PORT_STATUS_TXFLOW) ++ state->pause |= MLO_PAUSE_TX; ++ ++ return 1; ++} ++ ++static void ++qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ qca8k_port_set_status(priv, port, 0); ++} ++ ++static void ++qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface, struct phy_device *phydev, ++ int speed, int duplex, bool tx_pause, bool rx_pause) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg; ++ ++ if (phylink_autoneg_inband(mode)) { ++ reg = QCA8K_PORT_STATUS_LINK_AUTO; ++ } else { ++ switch (speed) { ++ case SPEED_10: ++ reg = QCA8K_PORT_STATUS_SPEED_10; ++ break; ++ case SPEED_100: ++ reg = QCA8K_PORT_STATUS_SPEED_100; ++ break; ++ case SPEED_1000: ++ reg = QCA8K_PORT_STATUS_SPEED_1000; ++ break; ++ default: ++ reg = QCA8K_PORT_STATUS_LINK_AUTO; ++ break; ++ } ++ ++ if (duplex == DUPLEX_FULL) ++ reg |= QCA8K_PORT_STATUS_DUPLEX; ++ ++ if (rx_pause || dsa_is_cpu_port(ds, port)) ++ reg |= QCA8K_PORT_STATUS_RXFLOW; ++ ++ if (tx_pause || dsa_is_cpu_port(ds, port)) ++ reg |= QCA8K_PORT_STATUS_TXFLOW; ++ } ++ ++ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; ++ ++ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); ++} ++ ++static void ++qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) ++{ ++ const struct qca8k_match_data *match_data; ++ struct qca8k_priv *priv = ds->priv; ++ int i; ++ ++ if (stringset != ETH_SS_STATS) ++ return; ++ ++ match_data = of_device_get_match_data(priv->dev); ++ ++ for (i = 0; i < match_data->mib_count; i++) ++ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, ++ ETH_GSTRING_LEN); ++} ++ ++static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) ++{ ++ const struct qca8k_match_data *match_data; ++ struct qca8k_mib_eth_data *mib_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ const struct qca8k_mib_desc *mib; ++ struct mib_ethhdr *mib_ethhdr; ++ int i, mib_len, offset = 0; ++ u64 *data; ++ u8 port; ++ ++ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); ++ mib_eth_data = &priv->mib_eth_data; ++ ++ /* The switch autocast every port. Ignore other packet and ++ * parse only the requested one. ++ */ ++ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); ++ if (port != mib_eth_data->req_port) ++ goto exit; ++ ++ match_data = device_get_match_data(priv->dev); ++ data = mib_eth_data->data; ++ ++ for (i = 0; i < match_data->mib_count; i++) { ++ mib = &ar8327_mib[i]; ++ ++ /* First 3 mib are present in the skb head */ ++ if (i < 3) { ++ data[i] = mib_ethhdr->data[i]; ++ continue; ++ } ++ ++ mib_len = sizeof(uint32_t); ++ ++ /* Some mib are 64 bit wide */ ++ if (mib->size == 2) ++ mib_len = sizeof(uint64_t); ++ ++ /* Copy the mib value from packet to the */ ++ memcpy(data + i, skb->data + offset, mib_len); ++ ++ /* Set the offset for the next mib */ ++ offset += mib_len; ++ } ++ ++exit: ++ /* Complete on receiving all the mib packet */ ++ if (refcount_dec_and_test(&mib_eth_data->port_parsed)) ++ complete(&mib_eth_data->rw_done); ++} ++ ++static int ++qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) ++{ ++ struct dsa_port *dp = dsa_to_port(ds, port); ++ struct qca8k_mib_eth_data *mib_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ mib_eth_data = &priv->mib_eth_data; ++ ++ mutex_lock(&mib_eth_data->mutex); ++ ++ reinit_completion(&mib_eth_data->rw_done); ++ ++ mib_eth_data->req_port = dp->index; ++ mib_eth_data->data = data; ++ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ /* Send mib autocast request */ ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, ++ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, ++ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | ++ QCA8K_MIB_BUSY); ++ ++ mutex_unlock(&priv->reg_mutex); ++ ++ if (ret) ++ goto exit; ++ ++ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); ++ ++exit: ++ mutex_unlock(&mib_eth_data->mutex); ++ ++ return ret; ++} ++ ++static void ++qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, ++ uint64_t *data) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ const struct qca8k_match_data *match_data; ++ const struct qca8k_mib_desc *mib; ++ u32 reg, i, val; ++ u32 hi = 0; ++ int ret; ++ ++ if (priv->mgmt_master && ++ qca8k_get_ethtool_stats_eth(ds, port, data) > 0) ++ return; ++ ++ match_data = of_device_get_match_data(priv->dev); ++ ++ for (i = 0; i < match_data->mib_count; i++) { ++ mib = &ar8327_mib[i]; ++ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; ++ ++ ret = qca8k_read(priv, reg, &val); ++ if (ret < 0) ++ continue; ++ ++ if (mib->size == 2) { ++ ret = qca8k_read(priv, reg + 4, &hi); ++ if (ret < 0) ++ continue; ++ } ++ ++ data[i] = val; ++ if (mib->size == 2) ++ data[i] |= (u64)hi << 32; ++ } ++} ++ ++static int ++qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) ++{ ++ const struct qca8k_match_data *match_data; ++ struct qca8k_priv *priv = ds->priv; ++ ++ if (sset != ETH_SS_STATS) ++ return 0; ++ ++ match_data = of_device_get_match_data(priv->dev); ++ ++ return match_data->mib_count; ++} ++ ++static int ++qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); ++ u32 reg; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); ++ if (ret < 0) ++ goto exit; ++ ++ if (eee->eee_enabled) ++ reg |= lpi_en; ++ else ++ reg &= ~lpi_en; ++ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) ++{ ++ /* Nothing to do on the port's MAC */ ++ return 0; ++} ++ ++static void ++qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u32 stp_state; ++ ++ switch (state) { ++ case BR_STATE_DISABLED: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; ++ break; ++ case BR_STATE_BLOCKING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; ++ break; ++ case BR_STATE_LISTENING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; ++ break; ++ case BR_STATE_LEARNING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; ++ break; ++ case BR_STATE_FORWARDING: ++ default: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; ++ break; ++ } ++ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); ++} ++ ++static int ++qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int port_mask, cpu_port; ++ int i, ret; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ port_mask = BIT(cpu_port); ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Add this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ ret = regmap_set_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ if (ret) ++ return ret; ++ if (i != port) ++ port_mask |= BIT(i); ++ } ++ ++ /* Add all other ports to this ports portvlan mask */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, port_mask); ++ ++ return ret; ++} ++ ++static void ++qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int cpu_port, i; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Remove this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ regmap_clear_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ } ++ ++ /* Set the cpu port to be the only one in the portvlan mask of ++ * this port ++ */ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); ++} ++ ++static void ++qca8k_port_fast_age(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); ++ mutex_unlock(&priv->reg_mutex); ++} ++ ++static int ++qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ unsigned int secs = msecs / 1000; ++ u32 val; ++ ++ /* AGE_TIME reg is set in 7s step */ ++ val = secs / 7; ++ ++ /* Handle case with 0 as val to NOT disable ++ * learning ++ */ ++ if (!val) ++ val = 1; ++ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, ++ QCA8K_ATU_AGE_TIME(val)); ++} ++ ++static int ++qca8k_port_enable(struct dsa_switch *ds, int port, ++ struct phy_device *phy) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ ++ qca8k_port_set_status(priv, port, 1); ++ priv->port_enabled_map |= BIT(port); ++ ++ if (dsa_is_user_port(ds, port)) ++ phy_support_asym_pause(phy); ++ ++ return 0; ++} ++ ++static void ++qca8k_port_disable(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ ++ qca8k_port_set_status(priv, port, 0); ++ priv->port_enabled_map &= ~BIT(port); ++} ++ ++static int ++qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ /* We have only have a general MTU setting. ++ * DSA always set the CPU port's MTU to the largest MTU of the slave ++ * ports. ++ * Setting MTU just for the CPU port is sufficient to correctly set a ++ * value for every port. ++ */ ++ if (!dsa_is_cpu_port(ds, port)) ++ return 0; ++ ++ /* To change the MAX_FRAME_SIZE the cpu ports must be off or ++ * the switch panics. ++ * Turn off both cpu ports before applying the new value to prevent ++ * this. ++ */ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 0); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 0); ++ ++ /* Include L2 header / FCS length */ ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); ++ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 1); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 1); ++ ++ return ret; ++} ++ ++static int ++qca8k_port_max_mtu(struct dsa_switch *ds, int port) ++{ ++ return QCA8K_MAX_MTU; ++} ++ ++static int ++qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, ++ u16 port_mask, u16 vid) ++{ ++ /* Set the vid to the port vlan id if no vid is set */ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_add(priv, addr, port_mask, vid, ++ QCA8K_ATU_STATUS_STATIC); ++} ++ ++static int ++qca8k_port_fdb_add(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); ++} ++ ++static int ++qca8k_port_fdb_del(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_del(priv, addr, port_mask, vid); ++} ++ ++static int ++qca8k_port_fdb_dump(struct dsa_switch *ds, int port, ++ dsa_fdb_dump_cb_t *cb, void *data) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ struct qca8k_fdb _fdb = { 0 }; ++ int cnt = QCA8K_NUM_FDB_RECORDS; ++ bool is_static; ++ int ret = 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { ++ if (!_fdb.aging) ++ break; ++ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); ++ ret = cb(_fdb.mac, _fdb.vid, is_static, data); ++ if (ret) ++ break; ++ } ++ mutex_unlock(&priv->reg_mutex); ++ ++ return 0; ++} ++ ++static int ++qca8k_port_mdb_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); ++} ++ ++static int ++qca8k_port_mdb_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); ++} ++ ++static int ++qca8k_port_mirror_add(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror, ++ bool ingress) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int monitor_port, ret; ++ u32 reg, val; ++ ++ /* Check for existent entry */ ++ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) ++ return -EEXIST; ++ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* QCA83xx can have only one port set to mirror mode. ++ * Check that the correct port is requested and return error otherwise. ++ * When no mirror port is set, the values is set to 0xF ++ */ ++ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) ++ return -EEXIST; ++ ++ /* Set the monitor port */ ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, ++ mirror->to_local_port); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ return ret; ++ ++ if (ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_update_bits(priv->regmap, reg, val, val); ++ if (ret) ++ return ret; ++ ++ /* Track mirror port for tx and rx to decide when the ++ * mirror port has to be disabled. ++ */ ++ if (ingress) ++ priv->mirror_rx |= BIT(port); ++ else ++ priv->mirror_tx |= BIT(port); ++ ++ return 0; ++} ++ ++static void ++qca8k_port_mirror_del(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg, val; ++ int ret; ++ ++ if (mirror->ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_clear_bits(priv->regmap, reg, val); ++ if (ret) ++ goto err; ++ ++ if (mirror->ingress) ++ priv->mirror_rx &= ~BIT(port); ++ else ++ priv->mirror_tx &= ~BIT(port); ++ ++ /* No port set to send packet to mirror port. Disable mirror port */ ++ if (!priv->mirror_rx && !priv->mirror_tx) { ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ goto err; ++ } ++err: ++ dev_err(priv->dev, "Failed to del mirror port from %d", port); ++} ++ ++static int ++qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, ++ struct netlink_ext_ack *extack) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ if (vlan_filtering) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); ++ } else { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); ++ } ++ ++ return ret; ++} ++ ++static int ++qca8k_port_vlan_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan, ++ struct netlink_ext_ack *extack) ++{ ++ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; ++ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); ++ if (ret) { ++ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); ++ return ret; ++ } ++ ++ if (pvid) { ++ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), ++ QCA8K_EGREES_VLAN_PORT_MASK(port), ++ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), ++ QCA8K_PORT_VLAN_CVID(vlan->vid) | ++ QCA8K_PORT_VLAN_SVID(vlan->vid)); ++ } ++ ++ return ret; ++} ++ ++static int ++qca8k_port_vlan_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_del(priv, port, vlan->vid); ++ if (ret) ++ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); ++ ++ return ret; ++} ++ ++static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Communicate to the phy internal driver the switch revision. ++ * Based on the switch revision different values needs to be ++ * set to the dbg and mmd reg on the phy. ++ * The first 2 bit are used to communicate the switch revision ++ * to the phy driver. ++ */ ++ if (port > 0 && port < 6) ++ return priv->switch_revision; ++ ++ return 0; ++} ++ ++static enum dsa_tag_protocol ++qca8k_get_tag_protocol(struct dsa_switch *ds, int port, ++ enum dsa_tag_protocol mp) ++{ ++ return DSA_TAG_PROTO_QCA; ++} ++ ++static bool ++qca8k_lag_can_offload(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct dsa_port *dp; ++ int id, members = 0; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ if (id < 0 || id >= ds->num_lag_ids) ++ return false; ++ ++ dsa_lag_foreach_port(dp, ds->dst, lag) ++ /* Includes the port joining the LAG */ ++ members++; ++ ++ if (members > QCA8K_NUM_PORTS_FOR_LAG) ++ return false; ++ ++ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) ++ return false; ++ ++ if (info->hash_type != NETDEV_LAG_HASH_L2 && ++ info->hash_type != NETDEV_LAG_HASH_L23) ++ return false; ++ ++ return true; ++} ++ ++static int ++qca8k_lag_setup_hash(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ bool unique_lag = true; ++ u32 hash = 0; ++ int i, id; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ switch (info->hash_type) { ++ case NETDEV_LAG_HASH_L23: ++ hash |= QCA8K_TRUNK_HASH_SIP_EN; ++ hash |= QCA8K_TRUNK_HASH_DIP_EN; ++ fallthrough; ++ case NETDEV_LAG_HASH_L2: ++ hash |= QCA8K_TRUNK_HASH_SA_EN; ++ hash |= QCA8K_TRUNK_HASH_DA_EN; ++ break; ++ default: /* We should NEVER reach this */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* Check if we are the unique configured LAG */ ++ dsa_lags_foreach_id(i, ds->dst) ++ if (i != id && dsa_lag_dev(ds->dst, i)) { ++ unique_lag = false; ++ break; ++ } ++ ++ /* Hash Mode is global. Make sure the same Hash Mode ++ * is set to all the 4 possible lag. ++ * If we are the unique LAG we can set whatever hash ++ * mode we want. ++ * To change hash mode it's needed to remove all LAG ++ * and change the mode with the latest. ++ */ ++ if (unique_lag) { ++ priv->lag_hash_mode = hash; ++ } else if (priv->lag_hash_mode != hash) { ++ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, ++ QCA8K_TRUNK_HASH_MASK, hash); ++} ++ ++static int ++qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, ++ struct net_device *lag, bool delete) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret, id, i; ++ u32 val; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ /* Read current port member */ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* Shift val to the correct trunk */ ++ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); ++ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; ++ if (delete) ++ val &= ~BIT(port); ++ else ++ val |= BIT(port); ++ ++ /* Update port member. With empty portmap disable trunk */ ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, ++ QCA8K_REG_GOL_TRUNK_MEMBER(id) | ++ QCA8K_REG_GOL_TRUNK_EN(id), ++ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | ++ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); ++ ++ /* Search empty member if adding or port on deleting */ ++ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); ++ if (ret) ++ return ret; ++ ++ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; ++ ++ if (delete) { ++ /* If port flagged to be disabled assume this member is ++ * empty ++ */ ++ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; ++ if (val != port) ++ continue; ++ } else { ++ /* If port flagged to be enabled assume this member is ++ * already set ++ */ ++ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ } ++ ++ /* We have found the member to add/remove */ ++ break; ++ } ++ ++ /* Set port in the correct port mask or disable port if in delete mode */ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), ++ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | ++ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); ++} ++ ++static int ++qca8k_port_lag_join(struct dsa_switch *ds, int port, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ int ret; ++ ++ if (!qca8k_lag_can_offload(ds, lag, info)) ++ return -EOPNOTSUPP; ++ ++ ret = qca8k_lag_setup_hash(ds, lag, info); ++ if (ret) ++ return ret; ++ ++ return qca8k_lag_refresh_portmap(ds, port, lag, false); ++} ++ ++static int ++qca8k_port_lag_leave(struct dsa_switch *ds, int port, ++ struct net_device *lag) ++{ ++ return qca8k_lag_refresh_portmap(ds, port, lag, true); ++} ++ ++static void ++qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, ++ bool operational) ++{ ++ struct dsa_port *dp = master->dsa_ptr; ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Ethernet MIB/MDIO is only supported for CPU port 0 */ ++ if (dp->index != 0) ++ return; ++ ++ mutex_lock(&priv->mgmt_eth_data.mutex); ++ mutex_lock(&priv->mib_eth_data.mutex); ++ ++ priv->mgmt_master = operational ? (struct net_device *)master : NULL; ++ ++ mutex_unlock(&priv->mib_eth_data.mutex); ++ mutex_unlock(&priv->mgmt_eth_data.mutex); ++} ++ ++static int qca8k_connect_tag_protocol(struct dsa_switch *ds, ++ enum dsa_tag_protocol proto) ++{ ++ struct qca_tagger_data *tagger_data; ++ ++ switch (proto) { ++ case DSA_TAG_PROTO_QCA: ++ tagger_data = ds->tagger_data; ++ ++ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; ++ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; ++ ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static const struct dsa_switch_ops qca8k_switch_ops = { ++ .get_tag_protocol = qca8k_get_tag_protocol, ++ .setup = qca8k_setup, ++ .get_strings = qca8k_get_strings, ++ .get_ethtool_stats = qca8k_get_ethtool_stats, ++ .get_sset_count = qca8k_get_sset_count, ++ .set_ageing_time = qca8k_set_ageing_time, ++ .get_mac_eee = qca8k_get_mac_eee, ++ .set_mac_eee = qca8k_set_mac_eee, ++ .port_enable = qca8k_port_enable, ++ .port_disable = qca8k_port_disable, ++ .port_change_mtu = qca8k_port_change_mtu, ++ .port_max_mtu = qca8k_port_max_mtu, ++ .port_stp_state_set = qca8k_port_stp_state_set, ++ .port_bridge_join = qca8k_port_bridge_join, ++ .port_bridge_leave = qca8k_port_bridge_leave, ++ .port_fast_age = qca8k_port_fast_age, ++ .port_fdb_add = qca8k_port_fdb_add, ++ .port_fdb_del = qca8k_port_fdb_del, ++ .port_fdb_dump = qca8k_port_fdb_dump, ++ .port_mdb_add = qca8k_port_mdb_add, ++ .port_mdb_del = qca8k_port_mdb_del, ++ .port_mirror_add = qca8k_port_mirror_add, ++ .port_mirror_del = qca8k_port_mirror_del, ++ .port_vlan_filtering = qca8k_port_vlan_filtering, ++ .port_vlan_add = qca8k_port_vlan_add, ++ .port_vlan_del = qca8k_port_vlan_del, ++ .phylink_validate = qca8k_phylink_validate, ++ .phylink_mac_link_state = qca8k_phylink_mac_link_state, ++ .phylink_mac_config = qca8k_phylink_mac_config, ++ .phylink_mac_link_down = qca8k_phylink_mac_link_down, ++ .phylink_mac_link_up = qca8k_phylink_mac_link_up, ++ .get_phy_flags = qca8k_get_phy_flags, ++ .port_lag_join = qca8k_port_lag_join, ++ .port_lag_leave = qca8k_port_lag_leave, ++ .master_state_change = qca8k_master_change, ++ .connect_tag_protocol = qca8k_connect_tag_protocol, ++}; ++ ++static int qca8k_read_switch_id(struct qca8k_priv *priv) ++{ ++ const struct qca8k_match_data *data; ++ u32 val; ++ u8 id; ++ int ret; ++ ++ /* get the switches ID from the compatible */ ++ data = of_device_get_match_data(priv->dev); ++ if (!data) ++ return -ENODEV; ++ ++ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); ++ if (ret < 0) ++ return -ENODEV; ++ ++ id = QCA8K_MASK_CTRL_DEVICE_ID(val); ++ if (id != data->id) { ++ dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); ++ return -ENODEV; ++ } ++ ++ priv->switch_id = id; ++ ++ /* Save revision to communicate to the internal PHY driver */ ++ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); ++ ++ return 0; ++} ++ ++static int ++qca8k_sw_probe(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv; ++ int ret; ++ ++ /* allocate the private data struct so that we can probe the switches ++ * ID register ++ */ ++ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->bus = mdiodev->bus; ++ priv->dev = &mdiodev->dev; ++ ++ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", ++ GPIOD_ASIS); ++ if (IS_ERR(priv->reset_gpio)) ++ return PTR_ERR(priv->reset_gpio); ++ ++ if (priv->reset_gpio) { ++ gpiod_set_value_cansleep(priv->reset_gpio, 1); ++ /* The active low duration must be greater than 10 ms ++ * and checkpatch.pl wants 20 ms. ++ */ ++ msleep(20); ++ gpiod_set_value_cansleep(priv->reset_gpio, 0); ++ } ++ ++ /* Start by setting up the register mapping */ ++ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, ++ &qca8k_regmap_config); ++ if (IS_ERR(priv->regmap)) { ++ dev_err(priv->dev, "regmap initialization failed"); ++ return PTR_ERR(priv->regmap); ++ } ++ ++ priv->mdio_cache.page = 0xffff; ++ priv->mdio_cache.lo = 0xffff; ++ priv->mdio_cache.hi = 0xffff; ++ ++ /* Check the detected switch id */ ++ ret = qca8k_read_switch_id(priv); ++ if (ret) ++ return ret; ++ ++ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); ++ if (!priv->ds) ++ return -ENOMEM; ++ ++ mutex_init(&priv->mgmt_eth_data.mutex); ++ init_completion(&priv->mgmt_eth_data.rw_done); ++ ++ mutex_init(&priv->mib_eth_data.mutex); ++ init_completion(&priv->mib_eth_data.rw_done); ++ ++ priv->ds->dev = &mdiodev->dev; ++ priv->ds->num_ports = QCA8K_NUM_PORTS; ++ priv->ds->priv = priv; ++ priv->ds->ops = &qca8k_switch_ops; ++ mutex_init(&priv->reg_mutex); ++ dev_set_drvdata(&mdiodev->dev, priv); ++ ++ return dsa_register_switch(priv->ds); ++} ++ ++static void ++qca8k_sw_remove(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); ++ int i; ++ ++ if (!priv) ++ return; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) ++ qca8k_port_set_status(priv, i, 0); ++ ++ dsa_unregister_switch(priv->ds); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++static void qca8k_sw_shutdown(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); ++ ++ if (!priv) ++ return; ++ ++ dsa_switch_shutdown(priv->ds); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static void ++qca8k_set_pm(struct qca8k_priv *priv, int enable) ++{ ++ int port; ++ ++ for (port = 0; port < QCA8K_NUM_PORTS; port++) { ++ /* Do not enable on resume if the port was ++ * disabled before. ++ */ ++ if (!(priv->port_enabled_map & BIT(port))) ++ continue; ++ ++ qca8k_port_set_status(priv, port, enable); ++ } ++} ++ ++static int qca8k_suspend(struct device *dev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(dev); ++ ++ qca8k_set_pm(priv, 0); ++ ++ return dsa_switch_suspend(priv->ds); ++} ++ ++static int qca8k_resume(struct device *dev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(dev); ++ ++ qca8k_set_pm(priv, 1); ++ ++ return dsa_switch_resume(priv->ds); ++} ++#endif /* CONFIG_PM_SLEEP */ ++ ++static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, ++ qca8k_suspend, qca8k_resume); ++ ++static const struct qca8k_match_data qca8327 = { ++ .id = QCA8K_ID_QCA8327, ++ .reduced_package = true, ++ .mib_count = QCA8K_QCA832X_MIB_COUNT, ++}; ++ ++static const struct qca8k_match_data qca8328 = { ++ .id = QCA8K_ID_QCA8327, ++ .mib_count = QCA8K_QCA832X_MIB_COUNT, ++}; ++ ++static const struct qca8k_match_data qca833x = { ++ .id = QCA8K_ID_QCA8337, ++ .mib_count = QCA8K_QCA833X_MIB_COUNT, ++}; ++ ++static const struct of_device_id qca8k_of_match[] = { ++ { .compatible = "qca,qca8327", .data = &qca8327 }, ++ { .compatible = "qca,qca8328", .data = &qca8328 }, ++ { .compatible = "qca,qca8334", .data = &qca833x }, ++ { .compatible = "qca,qca8337", .data = &qca833x }, ++ { /* sentinel */ }, ++}; ++ ++static struct mdio_driver qca8kmdio_driver = { ++ .probe = qca8k_sw_probe, ++ .remove = qca8k_sw_remove, ++ .shutdown = qca8k_sw_shutdown, ++ .mdiodrv.driver = { ++ .name = "qca8k", ++ .of_match_table = qca8k_of_match, ++ .pm = &qca8k_pm_ops, ++ }, ++}; ++ ++mdio_module_driver(qca8kmdio_driver); ++ ++MODULE_AUTHOR("Mathieu Olivari, John Crispin "); ++MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:qca8k"); +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -0,0 +1,411 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (C) 2009 Felix Fietkau ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * Copyright (c) 2015, The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef __QCA8K_H ++#define __QCA8K_H ++ ++#include ++#include ++#include ++#include ++ ++#define QCA8K_ETHERNET_MDIO_PRIORITY 7 ++#define QCA8K_ETHERNET_PHY_PRIORITY 6 ++#define QCA8K_ETHERNET_TIMEOUT 100 ++ ++#define QCA8K_NUM_PORTS 7 ++#define QCA8K_NUM_CPU_PORTS 2 ++#define QCA8K_MAX_MTU 9000 ++#define QCA8K_NUM_LAGS 4 ++#define QCA8K_NUM_PORTS_FOR_LAG 4 ++ ++#define PHY_ID_QCA8327 0x004dd034 ++#define QCA8K_ID_QCA8327 0x12 ++#define PHY_ID_QCA8337 0x004dd036 ++#define QCA8K_ID_QCA8337 0x13 ++ ++#define QCA8K_QCA832X_MIB_COUNT 39 ++#define QCA8K_QCA833X_MIB_COUNT 41 ++ ++#define QCA8K_BUSY_WAIT_TIMEOUT 2000 ++ ++#define QCA8K_NUM_FDB_RECORDS 2048 ++ ++#define QCA8K_PORT_VID_DEF 1 ++ ++/* Global control registers */ ++#define QCA8K_REG_MASK_CTRL 0x000 ++#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) ++#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) ++#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) ++#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) ++#define QCA8K_REG_PORT0_PAD_CTRL 0x004 ++#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) ++#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) ++#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) ++#define QCA8K_REG_PORT5_PAD_CTRL 0x008 ++#define QCA8K_REG_PORT6_PAD_CTRL 0x00c ++#define QCA8K_PORT_PAD_RGMII_EN BIT(26) ++#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) ++#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) ++#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) ++#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) ++#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) ++#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) ++#define QCA8K_PORT_PAD_SGMII_EN BIT(7) ++#define QCA8K_REG_PWS 0x010 ++#define QCA8K_PWS_POWER_ON_SEL BIT(31) ++/* This reg is only valid for QCA832x and toggle the package ++ * type from 176 pin (by default) to 148 pin used on QCA8327 ++ */ ++#define QCA8327_PWS_PACKAGE148_EN BIT(30) ++#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24) ++#define QCA8K_PWS_SERDES_AEN_DIS BIT(7) ++#define QCA8K_REG_MODULE_EN 0x030 ++#define QCA8K_MODULE_EN_MIB BIT(0) ++#define QCA8K_REG_MIB 0x034 ++#define QCA8K_MIB_FUNC GENMASK(26, 24) ++#define QCA8K_MIB_CPU_KEEP BIT(20) ++#define QCA8K_MIB_BUSY BIT(17) ++#define QCA8K_MDIO_MASTER_CTRL 0x3c ++#define QCA8K_MDIO_MASTER_BUSY BIT(31) ++#define QCA8K_MDIO_MASTER_EN BIT(30) ++#define QCA8K_MDIO_MASTER_READ BIT(27) ++#define QCA8K_MDIO_MASTER_WRITE 0 ++#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) ++#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) ++#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) ++#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) ++#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) ++#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) ++#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) ++#define QCA8K_MDIO_MASTER_MAX_PORTS 5 ++#define QCA8K_MDIO_MASTER_MAX_REG 32 ++#define QCA8K_GOL_MAC_ADDR0 0x60 ++#define QCA8K_GOL_MAC_ADDR1 0x64 ++#define QCA8K_MAX_FRAME_SIZE 0x78 ++#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) ++#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0) ++#define QCA8K_PORT_STATUS_SPEED_10 0 ++#define QCA8K_PORT_STATUS_SPEED_100 0x1 ++#define QCA8K_PORT_STATUS_SPEED_1000 0x2 ++#define QCA8K_PORT_STATUS_TXMAC BIT(2) ++#define QCA8K_PORT_STATUS_RXMAC BIT(3) ++#define QCA8K_PORT_STATUS_TXFLOW BIT(4) ++#define QCA8K_PORT_STATUS_RXFLOW BIT(5) ++#define QCA8K_PORT_STATUS_DUPLEX BIT(6) ++#define QCA8K_PORT_STATUS_LINK_UP BIT(8) ++#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9) ++#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10) ++#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) ++#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) ++#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) ++#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) ++#define QCA8K_PORT_HDR_CTRL_ALL 2 ++#define QCA8K_PORT_HDR_CTRL_MGMT 1 ++#define QCA8K_PORT_HDR_CTRL_NONE 0 ++#define QCA8K_REG_SGMII_CTRL 0x0e0 ++#define QCA8K_SGMII_EN_PLL BIT(1) ++#define QCA8K_SGMII_EN_RX BIT(2) ++#define QCA8K_SGMII_EN_TX BIT(3) ++#define QCA8K_SGMII_EN_SD BIT(4) ++#define QCA8K_SGMII_CLK125M_DELAY BIT(7) ++#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) ++#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) ++#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) ++#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) ++#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) ++ ++/* MAC_PWR_SEL registers */ ++#define QCA8K_REG_MAC_PWR_SEL 0x0e4 ++#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18) ++#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19) ++ ++/* EEE control registers */ ++#define QCA8K_REG_EEE_CTRL 0x100 ++#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) ++ ++/* TRUNK_HASH_EN registers */ ++#define QCA8K_TRUNK_HASH_EN_CTRL 0x270 ++#define QCA8K_TRUNK_HASH_SIP_EN BIT(3) ++#define QCA8K_TRUNK_HASH_DIP_EN BIT(2) ++#define QCA8K_TRUNK_HASH_SA_EN BIT(1) ++#define QCA8K_TRUNK_HASH_DA_EN BIT(0) ++#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0) ++ ++/* ACL registers */ ++#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) ++#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) ++#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) ++#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) ++#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) ++#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) ++#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 ++#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 ++ ++/* Lookup registers */ ++#define QCA8K_REG_ATU_DATA0 0x600 ++#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) ++#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) ++#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) ++#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) ++#define QCA8K_REG_ATU_DATA1 0x604 ++#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) ++#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) ++#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) ++#define QCA8K_REG_ATU_DATA2 0x608 ++#define QCA8K_ATU_VID_MASK GENMASK(19, 8) ++#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) ++#define QCA8K_ATU_STATUS_STATIC 0xf ++#define QCA8K_REG_ATU_FUNC 0x60c ++#define QCA8K_ATU_FUNC_BUSY BIT(31) ++#define QCA8K_ATU_FUNC_PORT_EN BIT(14) ++#define QCA8K_ATU_FUNC_MULTI_EN BIT(13) ++#define QCA8K_ATU_FUNC_FULL BIT(12) ++#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) ++#define QCA8K_REG_VTU_FUNC0 0x610 ++#define QCA8K_VTU_FUNC0_VALID BIT(20) ++#define QCA8K_VTU_FUNC0_IVL_EN BIT(19) ++/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) ++ * It does contain VLAN_MODE for each port [5:4] for port0, ++ * [7:6] for port1 ... [17:16] for port6. Use virtual port ++ * define to handle this. ++ */ ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) ++#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) ++#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) ++#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) ++#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) ++#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) ++#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) ++#define QCA8K_REG_VTU_FUNC1 0x614 ++#define QCA8K_VTU_FUNC1_BUSY BIT(31) ++#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) ++#define QCA8K_VTU_FUNC1_FULL BIT(4) ++#define QCA8K_REG_ATU_CTRL 0x618 ++#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) ++#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) ++#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 ++#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) ++#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) ++#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 ++#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) ++#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) ++#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) ++#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) ++#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) ++#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) ++#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) ++#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) ++#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) ++#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) ++#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) ++#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) ++#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) ++#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) ++#define QCA8K_PORT_LOOKUP_LEARN BIT(20) ++#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) ++ ++#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 ++/* 4 max trunk first ++ * first 6 bit for member bitmap ++ * 7th bit is to enable trunk port ++ */ ++#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) ++#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) ++#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) ++#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) ++#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) ++/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ ++#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) ++#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) ++#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) ++/* Complex shift: FIRST shift for port THEN shift for trunk */ ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) ++#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) ++ ++#define QCA8K_REG_GLOBAL_FC_THRESH 0x800 ++#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) ++#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) ++#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) ++#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) ++ ++#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) ++#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) ++#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) ++ ++#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) ++#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) ++#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) ++#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) ++#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) ++#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) ++#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) ++ ++/* Pkt edit registers */ ++#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) ++#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) ++#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) ++#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) ++ ++/* L3 registers */ ++#define QCA8K_HROUTER_CONTROL 0xe00 ++#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16) ++#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16 ++#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1 ++#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08 ++#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c ++#define QCA8K_HNAT_CONTROL 0xe38 ++ ++/* MIB registers */ ++#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) ++ ++/* QCA specific MII registers */ ++#define MII_ATH_MMD_ADDR 0x0d ++#define MII_ATH_MMD_DATA 0x0e ++ ++enum { ++ QCA8K_PORT_SPEED_10M = 0, ++ QCA8K_PORT_SPEED_100M = 1, ++ QCA8K_PORT_SPEED_1000M = 2, ++ QCA8K_PORT_SPEED_ERR = 3, ++}; ++ ++enum qca8k_fdb_cmd { ++ QCA8K_FDB_FLUSH = 1, ++ QCA8K_FDB_LOAD = 2, ++ QCA8K_FDB_PURGE = 3, ++ QCA8K_FDB_FLUSH_PORT = 5, ++ QCA8K_FDB_NEXT = 6, ++ QCA8K_FDB_SEARCH = 7, ++}; ++ ++enum qca8k_vlan_cmd { ++ QCA8K_VLAN_FLUSH = 1, ++ QCA8K_VLAN_LOAD = 2, ++ QCA8K_VLAN_PURGE = 3, ++ QCA8K_VLAN_REMOVE_PORT = 4, ++ QCA8K_VLAN_NEXT = 5, ++ QCA8K_VLAN_READ = 6, ++}; ++ ++enum qca8k_mid_cmd { ++ QCA8K_MIB_FLUSH = 1, ++ QCA8K_MIB_FLUSH_PORT = 2, ++ QCA8K_MIB_CAST = 3, ++}; ++ ++struct qca8k_match_data { ++ u8 id; ++ bool reduced_package; ++ u8 mib_count; ++}; ++ ++enum { ++ QCA8K_CPU_PORT0, ++ QCA8K_CPU_PORT6, ++}; ++ ++struct qca8k_mgmt_eth_data { ++ struct completion rw_done; ++ struct mutex mutex; /* Enforce one mdio read/write at time */ ++ bool ack; ++ u32 seq; ++ u32 data[4]; ++}; ++ ++struct qca8k_mib_eth_data { ++ struct completion rw_done; ++ struct mutex mutex; /* Process one command at time */ ++ refcount_t port_parsed; /* Counter to track parsed port */ ++ u8 req_port; ++ u64 *data; /* pointer to ethtool data */ ++}; ++ ++struct qca8k_ports_config { ++ bool sgmii_rx_clk_falling_edge; ++ bool sgmii_tx_clk_falling_edge; ++ bool sgmii_enable_pll; ++ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ ++ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ ++}; ++ ++struct qca8k_mdio_cache { ++/* The 32bit switch registers are accessed indirectly. To achieve this we need ++ * to set the page of the register. Track the last page that was set to reduce ++ * mdio writes ++ */ ++ u16 page; ++/* lo and hi can also be cached and from Documentation we can skip one ++ * extra mdio write if lo or hi is didn't change. ++ */ ++ u16 lo; ++ u16 hi; ++}; ++ ++struct qca8k_priv { ++ u8 switch_id; ++ u8 switch_revision; ++ u8 mirror_rx; ++ u8 mirror_tx; ++ u8 lag_hash_mode; ++ /* Each bit correspond to a port. This switch can support a max of 7 port. ++ * Bit 1: port enabled. Bit 0: port disabled. ++ */ ++ u8 port_enabled_map; ++ struct qca8k_ports_config ports_config; ++ struct regmap *regmap; ++ struct mii_bus *bus; ++ struct dsa_switch *ds; ++ struct mutex reg_mutex; ++ struct device *dev; ++ struct gpio_desc *reset_gpio; ++ struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ ++ struct qca8k_mgmt_eth_data mgmt_eth_data; ++ struct qca8k_mib_eth_data mib_eth_data; ++ struct qca8k_mdio_cache mdio_cache; ++}; ++ ++struct qca8k_mib_desc { ++ unsigned int size; ++ unsigned int offset; ++ const char *name; ++}; ++ ++struct qca8k_fdb { ++ u16 vid; ++ u8 port_mask; ++ u8 aging; ++ u8 mac[6]; ++}; ++ ++#endif /* __QCA8K_H */ +--- a/drivers/net/dsa/qca8k.c ++++ /dev/null +@@ -1,3243 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * Copyright (C) 2009 Felix Fietkau +- * Copyright (C) 2011-2012 Gabor Juhos +- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2016 John Crispin +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "qca8k.h" +- +-#define MIB_DESC(_s, _o, _n) \ +- { \ +- .size = (_s), \ +- .offset = (_o), \ +- .name = (_n), \ +- } +- +-static const struct qca8k_mib_desc ar8327_mib[] = { +- MIB_DESC(1, 0x00, "RxBroad"), +- MIB_DESC(1, 0x04, "RxPause"), +- MIB_DESC(1, 0x08, "RxMulti"), +- MIB_DESC(1, 0x0c, "RxFcsErr"), +- MIB_DESC(1, 0x10, "RxAlignErr"), +- MIB_DESC(1, 0x14, "RxRunt"), +- MIB_DESC(1, 0x18, "RxFragment"), +- MIB_DESC(1, 0x1c, "Rx64Byte"), +- MIB_DESC(1, 0x20, "Rx128Byte"), +- MIB_DESC(1, 0x24, "Rx256Byte"), +- MIB_DESC(1, 0x28, "Rx512Byte"), +- MIB_DESC(1, 0x2c, "Rx1024Byte"), +- MIB_DESC(1, 0x30, "Rx1518Byte"), +- MIB_DESC(1, 0x34, "RxMaxByte"), +- MIB_DESC(1, 0x38, "RxTooLong"), +- MIB_DESC(2, 0x3c, "RxGoodByte"), +- MIB_DESC(2, 0x44, "RxBadByte"), +- MIB_DESC(1, 0x4c, "RxOverFlow"), +- MIB_DESC(1, 0x50, "Filtered"), +- MIB_DESC(1, 0x54, "TxBroad"), +- MIB_DESC(1, 0x58, "TxPause"), +- MIB_DESC(1, 0x5c, "TxMulti"), +- MIB_DESC(1, 0x60, "TxUnderRun"), +- MIB_DESC(1, 0x64, "Tx64Byte"), +- MIB_DESC(1, 0x68, "Tx128Byte"), +- MIB_DESC(1, 0x6c, "Tx256Byte"), +- MIB_DESC(1, 0x70, "Tx512Byte"), +- MIB_DESC(1, 0x74, "Tx1024Byte"), +- MIB_DESC(1, 0x78, "Tx1518Byte"), +- MIB_DESC(1, 0x7c, "TxMaxByte"), +- MIB_DESC(1, 0x80, "TxOverSize"), +- MIB_DESC(2, 0x84, "TxByte"), +- MIB_DESC(1, 0x8c, "TxCollision"), +- MIB_DESC(1, 0x90, "TxAbortCol"), +- MIB_DESC(1, 0x94, "TxMultiCol"), +- MIB_DESC(1, 0x98, "TxSingleCol"), +- MIB_DESC(1, 0x9c, "TxExcDefer"), +- MIB_DESC(1, 0xa0, "TxDefer"), +- MIB_DESC(1, 0xa4, "TxLateCol"), +- MIB_DESC(1, 0xa8, "RXUnicast"), +- MIB_DESC(1, 0xac, "TXUnicast"), +-}; +- +-static void +-qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) +-{ +- regaddr >>= 1; +- *r1 = regaddr & 0x1e; +- +- regaddr >>= 5; +- *r2 = regaddr & 0x7; +- +- regaddr >>= 3; +- *page = regaddr & 0x3ff; +-} +- +-static int +-qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) +-{ +- u16 *cached_lo = &priv->mdio_cache.lo; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (lo == *cached_lo) +- return 0; +- +- ret = bus->write(bus, phy_id, regnum, lo); +- if (ret < 0) +- dev_err_ratelimited(&bus->dev, +- "failed to write qca8k 32bit lo register\n"); +- +- *cached_lo = lo; +- return 0; +-} +- +-static int +-qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) +-{ +- u16 *cached_hi = &priv->mdio_cache.hi; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (hi == *cached_hi) +- return 0; +- +- ret = bus->write(bus, phy_id, regnum, hi); +- if (ret < 0) +- dev_err_ratelimited(&bus->dev, +- "failed to write qca8k 32bit hi register\n"); +- +- *cached_hi = hi; +- return 0; +-} +- +-static int +-qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) +-{ +- int ret; +- +- ret = bus->read(bus, phy_id, regnum); +- if (ret >= 0) { +- *val = ret; +- ret = bus->read(bus, phy_id, regnum + 1); +- *val |= ret << 16; +- } +- +- if (ret < 0) { +- dev_err_ratelimited(&bus->dev, +- "failed to read qca8k 32bit register\n"); +- *val = 0; +- return ret; +- } +- +- return 0; +-} +- +-static void +-qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) +-{ +- u16 lo, hi; +- int ret; +- +- lo = val & 0xffff; +- hi = (u16)(val >> 16); +- +- ret = qca8k_set_lo(priv, phy_id, regnum, lo); +- if (ret >= 0) +- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); +-} +- +-static int +-qca8k_set_page(struct qca8k_priv *priv, u16 page) +-{ +- u16 *cached_page = &priv->mdio_cache.page; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (page == *cached_page) +- return 0; +- +- ret = bus->write(bus, 0x18, 0, page); +- if (ret < 0) { +- dev_err_ratelimited(&bus->dev, +- "failed to set qca8k page\n"); +- return ret; +- } +- +- *cached_page = page; +- usleep_range(1000, 2000); +- return 0; +-} +- +-static int +-qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) +-{ +- return regmap_read(priv->regmap, reg, val); +-} +- +-static int +-qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) +-{ +- return regmap_write(priv->regmap, reg, val); +-} +- +-static int +-qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +-{ +- return regmap_update_bits(priv->regmap, reg, mask, write_val); +-} +- +-static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data; +- struct qca8k_priv *priv = ds->priv; +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- u8 len, cmd; +- +- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); +- mgmt_eth_data = &priv->mgmt_eth_data; +- +- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); +- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); +- +- /* Make sure the seq match the requested packet */ +- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) +- mgmt_eth_data->ack = true; +- +- if (cmd == MDIO_READ) { +- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; +- +- /* Get the rest of the 12 byte of data. +- * The read/write function will extract the requested data. +- */ +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(mgmt_eth_data->data + 1, skb->data, +- QCA_HDR_MGMT_DATA2_LEN); +- } +- +- complete(&mgmt_eth_data->rw_done); +-} +- +-static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, +- int priority, unsigned int len) +-{ +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- unsigned int real_len; +- struct sk_buff *skb; +- u32 *data2; +- u16 hdr; +- +- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); +- if (!skb) +- return NULL; +- +- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte +- * Actually for some reason the steps are: +- * 0: nothing +- * 1-4: first 4 byte +- * 5-6: first 12 byte +- * 7-15: all 16 byte +- */ +- if (len == 16) +- real_len = 15; +- else +- real_len = len; +- +- skb_reset_mac_header(skb); +- skb_set_network_header(skb, skb->len); +- +- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); +- +- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); +- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); +- hdr |= QCA_HDR_XMIT_FROM_CPU; +- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); +- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); +- +- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, +- QCA_HDR_MGMT_CHECK_CODE_VAL); +- +- if (cmd == MDIO_WRITE) +- mgmt_ethhdr->mdio_data = *val; +- +- mgmt_ethhdr->hdr = htons(hdr); +- +- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); +- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); +- +- return skb; +-} +- +-static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) +-{ +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- +- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; +- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); +-} +- +-static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; +- struct sk_buff *skb; +- bool ack; +- int ret; +- +- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, +- QCA8K_ETHERNET_MDIO_PRIORITY, len); +- if (!skb) +- return -ENOMEM; +- +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check mgmt_master if is operational */ +- if (!priv->mgmt_master) { +- kfree_skb(skb); +- mutex_unlock(&mgmt_eth_data->mutex); +- return -EINVAL; +- } +- +- skb->dev = priv->mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the mdio pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); +- +- *val = mgmt_eth_data->data[0]; +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); +- +- ack = mgmt_eth_data->ack; +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- return 0; +-} +- +-static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; +- struct sk_buff *skb; +- bool ack; +- int ret; +- +- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, +- QCA8K_ETHERNET_MDIO_PRIORITY, len); +- if (!skb) +- return -ENOMEM; +- +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check mgmt_master if is operational */ +- if (!priv->mgmt_master) { +- kfree_skb(skb); +- mutex_unlock(&mgmt_eth_data->mutex); +- return -EINVAL; +- } +- +- skb->dev = priv->mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the mdio pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); +- +- ack = mgmt_eth_data->ack; +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- return 0; +-} +- +-static int +-qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +-{ +- u32 val = 0; +- int ret; +- +- ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); +- if (ret) +- return ret; +- +- val &= ~mask; +- val |= write_val; +- +- return qca8k_write_eth(priv, reg, &val, sizeof(val)); +-} +- +-static int +-qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- +- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int +-qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- u32 tmp; +- +- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- tmp = val[i]; +- +- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int +-qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- int ret; +- +- if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- return ret; +-} +- +-static int +-qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- int ret; +- +- if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- return ret; +-} +- +-static int +-qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); +- if (ret < 0) +- goto exit; +- +- val &= ~mask; +- val |= write_val; +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- +- return ret; +-} +- +-static const struct regmap_range qca8k_readable_ranges[] = { +- regmap_reg_range(0x0000, 0x00e4), /* Global control */ +- regmap_reg_range(0x0100, 0x0168), /* EEE control */ +- regmap_reg_range(0x0200, 0x0270), /* Parser control */ +- regmap_reg_range(0x0400, 0x0454), /* ACL */ +- regmap_reg_range(0x0600, 0x0718), /* Lookup */ +- regmap_reg_range(0x0800, 0x0b70), /* QM */ +- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ +- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ +- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ +- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ +- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ +- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ +- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ +- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ +- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ +- +-}; +- +-static const struct regmap_access_table qca8k_readable_table = { +- .yes_ranges = qca8k_readable_ranges, +- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), +-}; +- +-static struct regmap_config qca8k_regmap_config = { +- .reg_bits = 16, +- .val_bits = 32, +- .reg_stride = 4, +- .max_register = 0x16ac, /* end MIB - Port6 range */ +- .reg_read = qca8k_regmap_read, +- .reg_write = qca8k_regmap_write, +- .reg_update_bits = qca8k_regmap_update_bits, +- .rd_table = &qca8k_readable_table, +- .disable_locking = true, /* Locking is handled by qca8k read/write */ +- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ +-}; +- +-static int +-qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) +-{ +- u32 val; +- +- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); +-} +- +-static int +-qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) +-{ +- u32 reg[3]; +- int ret; +- +- /* load the ARL table into an array */ +- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +- if (ret) +- return ret; +- +- /* vid - 83:72 */ +- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); +- /* aging - 67:64 */ +- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); +- /* portmask - 54:48 */ +- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); +- /* mac - 47:0 */ +- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); +- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); +- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); +- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); +- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); +- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); +- +- return 0; +-} +- +-static void +-qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, +- u8 aging) +-{ +- u32 reg[3] = { 0 }; +- +- /* vid - 83:72 */ +- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); +- /* aging - 67:64 */ +- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); +- /* portmask - 54:48 */ +- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); +- /* mac - 47:0 */ +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); +- +- /* load the array into the ARL table */ +- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +-} +- +-static int +-qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and FDB index */ +- reg = QCA8K_ATU_FUNC_BUSY; +- reg |= cmd; +- if (port >= 0) { +- reg |= QCA8K_ATU_FUNC_PORT_EN; +- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); +- } +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_FDB_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_ATU_FUNC_FULL) +- return -1; +- } +- +- return 0; +-} +- +-static int +-qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) +-{ +- int ret; +- +- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); +- if (ret < 0) +- return ret; +- +- return qca8k_fdb_read(priv, fdb); +-} +- +-static int +-qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, +- u16 vid, u8 aging) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static void +-qca8k_fdb_flush(struct qca8k_priv *priv) +-{ +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_fdb_read(priv, &fdb); +- if (ret < 0) +- goto exit; +- +- /* Rule exist. Delete first */ +- if (!fdb.aging) { +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- } +- +- /* Add port to fdb portmask */ +- fdb.port_mask |= port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- /* Rule doesn't exist. Why delete? */ +- if (!fdb.aging) { +- ret = -EINVAL; +- goto exit; +- } +- +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- +- /* Only port in the rule is this port. Don't re insert */ +- if (fdb.port_mask == port_mask) +- goto exit; +- +- /* Remove port from port mask */ +- fdb.port_mask &= ~port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and VLAN index */ +- reg = QCA8K_VTU_FUNC1_BUSY; +- reg |= cmd; +- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_VLAN_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_VTU_FUNC1_FULL) +- return -ENOMEM; +- } +- +- return 0; +-} +- +-static int +-qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) +-{ +- u32 reg; +- int ret; +- +- /* +- We do the right thing with VLAN 0 and treat it as untagged while +- preserving the tag on egress. +- */ +- if (vid == 0) +- return 0; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- if (untagged) +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); +- else +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); +- +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) +-{ +- u32 reg, mask; +- int ret, i; +- bool del; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); +- +- /* Check if we're the last member to be removed */ +- del = true; +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); +- +- if ((reg & mask) != mask) { +- del = false; +- break; +- } +- } +- +- if (del) { +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); +- } else { +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- } +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_mib_init(struct qca8k_priv *priv) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, +- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, +- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | +- QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); +- if (ret) +- goto exit; +- +- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static void +-qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) +-{ +- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; +- +- /* Port 0 and 6 have no internal PHY */ +- if (port > 0 && port < 6) +- mask |= QCA8K_PORT_STATUS_LINK_AUTO; +- +- if (enable) +- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +- else +- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +-} +- +-static int +-qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, +- struct sk_buff *read_skb, u32 *val) +-{ +- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); +- bool ack; +- int ret; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the copy pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- *val = mgmt_eth_data->data[0]; +- +- return 0; +-} +- +-static int +-qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, +- int regnum, u16 data) +-{ +- struct sk_buff *write_skb, *clear_skb, *read_skb; +- struct qca8k_mgmt_eth_data *mgmt_eth_data; +- u32 write_val, clear_val = 0, val; +- struct net_device *mgmt_master; +- int ret, ret1; +- bool ack; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- mgmt_eth_data = &priv->mgmt_eth_data; +- +- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum); +- +- if (read) { +- write_val |= QCA8K_MDIO_MASTER_READ; +- } else { +- write_val |= QCA8K_MDIO_MASTER_WRITE; +- write_val |= QCA8K_MDIO_MASTER_DATA(data); +- } +- +- /* Prealloc all the needed skb before the lock */ +- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); +- if (!write_skb) +- return -ENOMEM; +- +- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); +- if (!clear_skb) { +- ret = -ENOMEM; +- goto err_clear_skb; +- } +- +- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); +- if (!read_skb) { +- ret = -ENOMEM; +- goto err_read_skb; +- } +- +- /* Actually start the request: +- * 1. Send mdio master packet +- * 2. Busy Wait for mdio master command +- * 3. Get the data if we are reading +- * 4. Reset the mdio master (even with error) +- */ +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check if mgmt_master is operational */ +- mgmt_master = priv->mgmt_master; +- if (!mgmt_master) { +- mutex_unlock(&mgmt_eth_data->mutex); +- ret = -EINVAL; +- goto err_mgmt_master; +- } +- +- read_skb->dev = mgmt_master; +- clear_skb->dev = mgmt_master; +- write_skb->dev = mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the write pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(write_skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) { +- ret = -ETIMEDOUT; +- kfree_skb(read_skb); +- goto exit; +- } +- +- if (!ack) { +- ret = -EINVAL; +- kfree_skb(read_skb); +- goto exit; +- } +- +- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, +- !(val & QCA8K_MDIO_MASTER_BUSY), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, +- mgmt_eth_data, read_skb, &val); +- +- if (ret < 0 && ret1 < 0) { +- ret = ret1; +- goto exit; +- } +- +- if (read) { +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the read pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(read_skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) { +- ret = -ETIMEDOUT; +- goto exit; +- } +- +- if (!ack) { +- ret = -EINVAL; +- goto exit; +- } +- +- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; +- } else { +- kfree_skb(read_skb); +- } +-exit: +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the clear pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(clear_skb); +- +- wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- return ret; +- +- /* Error handling before lock */ +-err_mgmt_master: +- kfree_skb(read_skb); +-err_read_skb: +- kfree_skb(clear_skb); +-err_clear_skb: +- kfree_skb(write_skb); +- +- return ret; +-} +- +-static u32 +-qca8k_port_to_phy(int port) +-{ +- /* From Andrew Lunn: +- * Port 0 has no internal phy. +- * Port 1 has an internal PHY at MDIO address 0. +- * Port 2 has an internal PHY at MDIO address 1. +- * ... +- * Port 5 has an internal PHY at MDIO address 4. +- * Port 6 has no internal PHY. +- */ +- +- return port - 1; +-} +- +-static int +-qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) +-{ +- u16 r1, r2, page; +- u32 val; +- int ret, ret1; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, +- bus, 0x10 | r2, r1, &val); +- +- /* Check if qca8k_read has failed for a different reason +- * before returnting -ETIMEDOUT +- */ +- if (ret < 0 && ret1 < 0) +- return ret1; +- +- return ret; +-} +- +-static int +-qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) +-{ +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum) | +- QCA8K_MDIO_MASTER_DATA(data); +- +- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_BUSY); +- +-exit: +- /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); +- +- mutex_unlock(&bus->mdio_lock); +- +- return ret; +-} +- +-static int +-qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) +-{ +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum); +- +- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_BUSY); +- if (ret) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); +- +-exit: +- /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); +- +- mutex_unlock(&bus->mdio_lock); +- +- if (ret >= 0) +- ret = val & QCA8K_MDIO_MASTER_DATA_MASK; +- +- return ret; +-} +- +-static int +-qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) +-{ +- struct qca8k_priv *priv = slave_bus->priv; +- int ret; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); +- if (!ret) +- return 0; +- +- return qca8k_mdio_write(priv, phy, regnum, data); +-} +- +-static int +-qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) +-{ +- struct qca8k_priv *priv = slave_bus->priv; +- int ret; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); +- if (ret >= 0) +- return ret; +- +- ret = qca8k_mdio_read(priv, phy, regnum); +- +- if (ret < 0) +- return 0xffff; +- +- return ret; +-} +- +-static int +-qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) +-{ +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- return qca8k_internal_mdio_write(slave_bus, port, regnum, data); +-} +- +-static int +-qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) +-{ +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- return qca8k_internal_mdio_read(slave_bus, port, regnum); +-} +- +-static int +-qca8k_mdio_register(struct qca8k_priv *priv) +-{ +- struct dsa_switch *ds = priv->ds; +- struct device_node *mdio; +- struct mii_bus *bus; +- +- bus = devm_mdiobus_alloc(ds->dev); +- if (!bus) +- return -ENOMEM; +- +- bus->priv = (void *)priv; +- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", +- ds->dst->index, ds->index); +- bus->parent = ds->dev; +- bus->phy_mask = ~ds->phys_mii_mask; +- ds->slave_mii_bus = bus; +- +- /* Check if the devicetree declare the port:phy mapping */ +- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); +- if (of_device_is_available(mdio)) { +- bus->name = "qca8k slave mii"; +- bus->read = qca8k_internal_mdio_read; +- bus->write = qca8k_internal_mdio_write; +- return devm_of_mdiobus_register(priv->dev, bus, mdio); +- } +- +- /* If a mapping can't be found the legacy mapping is used, +- * using the qca8k_port_to_phy function +- */ +- bus->name = "qca8k-legacy slave mii"; +- bus->read = qca8k_legacy_mdio_read; +- bus->write = qca8k_legacy_mdio_write; +- return devm_mdiobus_register(priv->dev, bus); +-} +- +-static int +-qca8k_setup_mdio_bus(struct qca8k_priv *priv) +-{ +- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; +- struct device_node *ports, *port; +- phy_interface_t mode; +- int err; +- +- ports = of_get_child_by_name(priv->dev->of_node, "ports"); +- if (!ports) +- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); +- +- if (!ports) +- return -EINVAL; +- +- for_each_available_child_of_node(ports, port) { +- err = of_property_read_u32(port, "reg", ®); +- if (err) { +- of_node_put(port); +- of_node_put(ports); +- return err; +- } +- +- if (!dsa_is_user_port(priv->ds, reg)) +- continue; +- +- of_get_phy_mode(port, &mode); +- +- if (of_property_read_bool(port, "phy-handle") && +- mode != PHY_INTERFACE_MODE_INTERNAL) +- external_mdio_mask |= BIT(reg); +- else +- internal_mdio_mask |= BIT(reg); +- } +- +- of_node_put(ports); +- if (!external_mdio_mask && !internal_mdio_mask) { +- dev_err(priv->dev, "no PHYs are defined.\n"); +- return -EINVAL; +- } +- +- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through +- * the MDIO_MASTER register also _disconnects_ the external MDC +- * passthrough to the internal PHYs. It's not possible to use both +- * configurations at the same time! +- * +- * Because this came up during the review process: +- * If the external mdio-bus driver is capable magically disabling +- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's +- * accessors for the time being, it would be possible to pull this +- * off. +- */ +- if (!!external_mdio_mask && !!internal_mdio_mask) { +- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); +- return -EINVAL; +- } +- +- if (external_mdio_mask) { +- /* Make sure to disable the internal mdio bus in cases +- * a dt-overlay and driver reload changed the configuration +- */ +- +- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_EN); +- } +- +- return qca8k_mdio_register(priv); +-} +- +-static int +-qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) +-{ +- u32 mask = 0; +- int ret = 0; +- +- /* SoC specific settings for ipq8064. +- * If more device require this consider adding +- * a dedicated binding. +- */ +- if (of_machine_is_compatible("qcom,ipq8064")) +- mask |= QCA8K_MAC_PWR_RGMII0_1_8V; +- +- /* SoC specific settings for ipq8065 */ +- if (of_machine_is_compatible("qcom,ipq8065")) +- mask |= QCA8K_MAC_PWR_RGMII1_1_8V; +- +- if (mask) { +- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, +- QCA8K_MAC_PWR_RGMII0_1_8V | +- QCA8K_MAC_PWR_RGMII1_1_8V, +- mask); +- } +- +- return ret; +-} +- +-static int qca8k_find_cpu_port(struct dsa_switch *ds) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- /* Find the connected cpu port. Valid port are 0 or 6 */ +- if (dsa_is_cpu_port(ds, 0)) +- return 0; +- +- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); +- +- if (dsa_is_cpu_port(ds, 6)) +- return 6; +- +- return -EINVAL; +-} +- +-static int +-qca8k_setup_of_pws_reg(struct qca8k_priv *priv) +-{ +- struct device_node *node = priv->dev->of_node; +- const struct qca8k_match_data *data; +- u32 val = 0; +- int ret; +- +- /* QCA8327 require to set to the correct mode. +- * His bigger brother QCA8328 have the 172 pin layout. +- * Should be applied by default but we set this just to make sure. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- data = of_device_get_match_data(priv->dev); +- +- /* Set the correct package of 148 pin for QCA8327 */ +- if (data->reduced_package) +- val |= QCA8327_PWS_PACKAGE148_EN; +- +- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, +- val); +- if (ret) +- return ret; +- } +- +- if (of_property_read_bool(node, "qca,ignore-power-on-sel")) +- val |= QCA8K_PWS_POWER_ON_SEL; +- +- if (of_property_read_bool(node, "qca,led-open-drain")) { +- if (!(val & QCA8K_PWS_POWER_ON_SEL)) { +- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); +- return -EINVAL; +- } +- +- val |= QCA8K_PWS_LED_OPEN_EN_CSR; +- } +- +- return qca8k_rmw(priv, QCA8K_REG_PWS, +- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, +- val); +-} +- +-static int +-qca8k_parse_port_config(struct qca8k_priv *priv) +-{ +- int port, cpu_port_index = -1, ret; +- struct device_node *port_dn; +- phy_interface_t mode; +- struct dsa_port *dp; +- u32 delay; +- +- /* We have 2 CPU port. Check them */ +- for (port = 0; port < QCA8K_NUM_PORTS; port++) { +- /* Skip every other port */ +- if (port != 0 && port != 6) +- continue; +- +- dp = dsa_to_port(priv->ds, port); +- port_dn = dp->dn; +- cpu_port_index++; +- +- if (!of_device_is_available(port_dn)) +- continue; +- +- ret = of_get_phy_mode(port_dn, &mode); +- if (ret) +- continue; +- +- switch (mode) { +- case PHY_INTERFACE_MODE_RGMII: +- case PHY_INTERFACE_MODE_RGMII_ID: +- case PHY_INTERFACE_MODE_RGMII_TXID: +- case PHY_INTERFACE_MODE_RGMII_RXID: +- case PHY_INTERFACE_MODE_SGMII: +- delay = 0; +- +- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) +- /* Switch regs accept value in ns, convert ps to ns */ +- delay = delay / 1000; +- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_TXID) +- delay = 1; +- +- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { +- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); +- delay = 3; +- } +- +- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; +- +- delay = 0; +- +- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) +- /* Switch regs accept value in ns, convert ps to ns */ +- delay = delay / 1000; +- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_RXID) +- delay = 2; +- +- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { +- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); +- delay = 3; +- } +- +- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; +- +- /* Skip sgmii parsing for rgmii* mode */ +- if (mode == PHY_INTERFACE_MODE_RGMII || +- mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_TXID || +- mode == PHY_INTERFACE_MODE_RGMII_RXID) +- break; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) +- priv->ports_config.sgmii_tx_clk_falling_edge = true; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) +- priv->ports_config.sgmii_rx_clk_falling_edge = true; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { +- priv->ports_config.sgmii_enable_pll = true; +- +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); +- priv->ports_config.sgmii_enable_pll = false; +- } +- +- if (priv->switch_revision < 2) +- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); +- } +- +- break; +- default: +- continue; +- } +- } +- +- return 0; +-} +- +-static int +-qca8k_setup(struct dsa_switch *ds) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int cpu_port, ret, i; +- u32 mask; +- +- cpu_port = qca8k_find_cpu_port(ds); +- if (cpu_port < 0) { +- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); +- return cpu_port; +- } +- +- /* Parse CPU port config to be later used in phy_link mac_config */ +- ret = qca8k_parse_port_config(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_mdio_bus(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_of_pws_reg(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_mac_pwr_sel(priv); +- if (ret) +- return ret; +- +- /* Make sure MAC06 is disabled */ +- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, +- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); +- if (ret) { +- dev_err(priv->dev, "failed disabling MAC06 exchange"); +- return ret; +- } +- +- /* Enable CPU Port */ +- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); +- if (ret) { +- dev_err(priv->dev, "failed enabling CPU port"); +- return ret; +- } +- +- /* Enable MIB counters */ +- ret = qca8k_mib_init(priv); +- if (ret) +- dev_warn(priv->dev, "mib init failed"); +- +- /* Initial setup of all ports */ +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- /* Disable forwarding by default on all ports */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, 0); +- if (ret) +- return ret; +- +- /* Enable QCA header mode on all cpu ports */ +- if (dsa_is_cpu_port(ds, i)) { +- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), +- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | +- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); +- if (ret) { +- dev_err(priv->dev, "failed enabling QCA header mode"); +- return ret; +- } +- } +- +- /* Disable MAC by default on all user ports */ +- if (dsa_is_user_port(ds, i)) +- qca8k_port_set_status(priv, i, 0); +- } +- +- /* Forward all unknown frames to CPU port for Linux processing +- * Notice that in multi-cpu config only one port should be set +- * for igmp, unknown, multicast and broadcast packet +- */ +- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); +- if (ret) +- return ret; +- +- /* Setup connection between CPU port & user ports +- * Configure specific switch configuration for ports +- */ +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- /* CPU port gets connected to all user ports of the switch */ +- if (dsa_is_cpu_port(ds, i)) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); +- if (ret) +- return ret; +- } +- +- /* Individual user ports get connected to CPU port only */ +- if (dsa_is_user_port(ds, i)) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, +- BIT(cpu_port)); +- if (ret) +- return ret; +- +- /* Enable ARP Auto-learning by default */ +- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_LEARN); +- if (ret) +- return ret; +- +- /* For port based vlans to work we need to set the +- * default egress vid +- */ +- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), +- QCA8K_EGREES_VLAN_PORT_MASK(i), +- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); +- if (ret) +- return ret; +- +- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), +- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | +- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); +- if (ret) +- return ret; +- } +- +- /* The port 5 of the qca8337 have some problem in flood condition. The +- * original legacy driver had some specific buffer and priority settings +- * for the different port suggested by the QCA switch team. Add this +- * missing settings to improve switch stability under load condition. +- * This problem is limited to qca8337 and other qca8k switch are not affected. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8337) { +- switch (i) { +- /* The 2 CPU port and port 5 requires some different +- * priority than any other ports. +- */ +- case 0: +- case 5: +- case 6: +- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | +- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); +- break; +- default: +- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | +- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); +- } +- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); +- +- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | +- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_WRED_EN; +- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), +- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | +- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_WRED_EN, +- mask); +- } +- } +- +- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | +- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); +- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, +- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | +- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, +- mask); +- } +- +- /* Setup our port MTUs to match power on defaults */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); +- if (ret) +- dev_warn(priv->dev, "failed setting MTU settings"); +- +- /* Flush the FDB table */ +- qca8k_fdb_flush(priv); +- +- /* We don't have interrupts for link changes, so we need to poll */ +- ds->pcs_poll = true; +- +- /* Set min a max ageing value supported */ +- ds->ageing_time_min = 7000; +- ds->ageing_time_max = 458745000; +- +- /* Set max number of LAGs supported */ +- ds->num_lag_ids = QCA8K_NUM_LAGS; +- +- return 0; +-} +- +-static void +-qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, +- u32 reg) +-{ +- u32 delay, val = 0; +- int ret; +- +- /* Delay can be declared in 3 different way. +- * Mode to rgmii and internal-delay standard binding defined +- * rgmii-id or rgmii-tx/rx phy mode set. +- * The parse logic set a delay different than 0 only when one +- * of the 3 different way is used. In all other case delay is +- * not enabled. With ID or TX/RXID delay is enabled and set +- * to the default and recommended value. +- */ +- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { +- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; +- +- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | +- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; +- } +- +- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { +- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; +- +- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; +- } +- +- /* Set RGMII delay based on the selected values */ +- ret = qca8k_rmw(priv, reg, +- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | +- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, +- val); +- if (ret) +- dev_err(priv->dev, "Failed to set internal delay for CPU port%d", +- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); +-} +- +-static void +-qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, +- const struct phylink_link_state *state) +-{ +- struct qca8k_priv *priv = ds->priv; +- int cpu_port_index, ret; +- u32 reg, val; +- +- switch (port) { +- case 0: /* 1st CPU port */ +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII) +- return; +- +- reg = QCA8K_REG_PORT0_PAD_CTRL; +- cpu_port_index = QCA8K_CPU_PORT0; +- break; +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- /* Internal PHY, nothing to do */ +- return; +- case 6: /* 2nd CPU port / external PHY */ +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII && +- state->interface != PHY_INTERFACE_MODE_1000BASEX) +- return; +- +- reg = QCA8K_REG_PORT6_PAD_CTRL; +- cpu_port_index = QCA8K_CPU_PORT6; +- break; +- default: +- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); +- return; +- } +- +- if (port != 6 && phylink_autoneg_inband(mode)) { +- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", +- __func__); +- return; +- } +- +- switch (state->interface) { +- case PHY_INTERFACE_MODE_RGMII: +- case PHY_INTERFACE_MODE_RGMII_ID: +- case PHY_INTERFACE_MODE_RGMII_TXID: +- case PHY_INTERFACE_MODE_RGMII_RXID: +- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); +- +- /* Configure rgmii delay */ +- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); +- +- /* QCA8337 requires to set rgmii rx delay for all ports. +- * This is enabled through PORT5_PAD_CTRL for all ports, +- * rather than individual port registers. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8337) +- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); +- break; +- case PHY_INTERFACE_MODE_SGMII: +- case PHY_INTERFACE_MODE_1000BASEX: +- /* Enable SGMII on the port */ +- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); +- +- /* Enable/disable SerDes auto-negotiation as necessary */ +- ret = qca8k_read(priv, QCA8K_REG_PWS, &val); +- if (ret) +- return; +- if (phylink_autoneg_inband(mode)) +- val &= ~QCA8K_PWS_SERDES_AEN_DIS; +- else +- val |= QCA8K_PWS_SERDES_AEN_DIS; +- qca8k_write(priv, QCA8K_REG_PWS, val); +- +- /* Configure the SGMII parameters */ +- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); +- if (ret) +- return; +- +- val |= QCA8K_SGMII_EN_SD; +- +- if (priv->ports_config.sgmii_enable_pll) +- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | +- QCA8K_SGMII_EN_TX; +- +- if (dsa_is_cpu_port(ds, port)) { +- /* CPU port, we're talking to the CPU MAC, be a PHY */ +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_PHY; +- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_MAC; +- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_BASEX; +- } +- +- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); +- +- /* From original code is reported port instability as SGMII also +- * require delay set. Apply advised values here or take them from DT. +- */ +- if (state->interface == PHY_INTERFACE_MODE_SGMII) +- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); +- +- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and +- * falling edge is set writing in the PORT0 PAD reg +- */ +- if (priv->switch_id == QCA8K_ID_QCA8327 || +- priv->switch_id == QCA8K_ID_QCA8337) +- reg = QCA8K_REG_PORT0_PAD_CTRL; +- +- val = 0; +- +- /* SGMII Clock phase configuration */ +- if (priv->ports_config.sgmii_rx_clk_falling_edge) +- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; +- +- if (priv->ports_config.sgmii_tx_clk_falling_edge) +- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; +- +- if (val) +- ret = qca8k_rmw(priv, reg, +- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | +- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, +- val); +- +- break; +- default: +- dev_err(ds->dev, "xMII mode %s not supported for port %d\n", +- phy_modes(state->interface), port); +- return; +- } +-} +- +-static void +-qca8k_phylink_validate(struct dsa_switch *ds, int port, +- unsigned long *supported, +- struct phylink_link_state *state) +-{ +- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; +- +- switch (port) { +- case 0: /* 1st CPU port */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII) +- goto unsupported; +- break; +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- /* Internal PHY */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_GMII && +- state->interface != PHY_INTERFACE_MODE_INTERNAL) +- goto unsupported; +- break; +- case 6: /* 2nd CPU port / external PHY */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII && +- state->interface != PHY_INTERFACE_MODE_1000BASEX) +- goto unsupported; +- break; +- default: +-unsupported: +- linkmode_zero(supported); +- return; +- } +- +- phylink_set_port_modes(mask); +- phylink_set(mask, Autoneg); +- +- phylink_set(mask, 1000baseT_Full); +- phylink_set(mask, 10baseT_Half); +- phylink_set(mask, 10baseT_Full); +- phylink_set(mask, 100baseT_Half); +- phylink_set(mask, 100baseT_Full); +- +- if (state->interface == PHY_INTERFACE_MODE_1000BASEX) +- phylink_set(mask, 1000baseX_Full); +- +- phylink_set(mask, Pause); +- phylink_set(mask, Asym_Pause); +- +- linkmode_and(supported, supported, mask); +- linkmode_and(state->advertising, state->advertising, mask); +-} +- +-static int +-qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, +- struct phylink_link_state *state) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg; +- int ret; +- +- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); +- if (ret < 0) +- return ret; +- +- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); +- state->an_complete = state->link; +- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); +- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : +- DUPLEX_HALF; +- +- switch (reg & QCA8K_PORT_STATUS_SPEED) { +- case QCA8K_PORT_STATUS_SPEED_10: +- state->speed = SPEED_10; +- break; +- case QCA8K_PORT_STATUS_SPEED_100: +- state->speed = SPEED_100; +- break; +- case QCA8K_PORT_STATUS_SPEED_1000: +- state->speed = SPEED_1000; +- break; +- default: +- state->speed = SPEED_UNKNOWN; +- break; +- } +- +- state->pause = MLO_PAUSE_NONE; +- if (reg & QCA8K_PORT_STATUS_RXFLOW) +- state->pause |= MLO_PAUSE_RX; +- if (reg & QCA8K_PORT_STATUS_TXFLOW) +- state->pause |= MLO_PAUSE_TX; +- +- return 1; +-} +- +-static void +-qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, +- phy_interface_t interface) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- qca8k_port_set_status(priv, port, 0); +-} +- +-static void +-qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, +- phy_interface_t interface, struct phy_device *phydev, +- int speed, int duplex, bool tx_pause, bool rx_pause) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg; +- +- if (phylink_autoneg_inband(mode)) { +- reg = QCA8K_PORT_STATUS_LINK_AUTO; +- } else { +- switch (speed) { +- case SPEED_10: +- reg = QCA8K_PORT_STATUS_SPEED_10; +- break; +- case SPEED_100: +- reg = QCA8K_PORT_STATUS_SPEED_100; +- break; +- case SPEED_1000: +- reg = QCA8K_PORT_STATUS_SPEED_1000; +- break; +- default: +- reg = QCA8K_PORT_STATUS_LINK_AUTO; +- break; +- } +- +- if (duplex == DUPLEX_FULL) +- reg |= QCA8K_PORT_STATUS_DUPLEX; +- +- if (rx_pause || dsa_is_cpu_port(ds, port)) +- reg |= QCA8K_PORT_STATUS_RXFLOW; +- +- if (tx_pause || dsa_is_cpu_port(ds, port)) +- reg |= QCA8K_PORT_STATUS_TXFLOW; +- } +- +- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; +- +- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); +-} +- +-static void +-qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) +-{ +- const struct qca8k_match_data *match_data; +- struct qca8k_priv *priv = ds->priv; +- int i; +- +- if (stringset != ETH_SS_STATS) +- return; +- +- match_data = of_device_get_match_data(priv->dev); +- +- for (i = 0; i < match_data->mib_count; i++) +- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, +- ETH_GSTRING_LEN); +-} +- +-static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) +-{ +- const struct qca8k_match_data *match_data; +- struct qca8k_mib_eth_data *mib_eth_data; +- struct qca8k_priv *priv = ds->priv; +- const struct qca8k_mib_desc *mib; +- struct mib_ethhdr *mib_ethhdr; +- int i, mib_len, offset = 0; +- u64 *data; +- u8 port; +- +- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); +- mib_eth_data = &priv->mib_eth_data; +- +- /* The switch autocast every port. Ignore other packet and +- * parse only the requested one. +- */ +- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); +- if (port != mib_eth_data->req_port) +- goto exit; +- +- match_data = device_get_match_data(priv->dev); +- data = mib_eth_data->data; +- +- for (i = 0; i < match_data->mib_count; i++) { +- mib = &ar8327_mib[i]; +- +- /* First 3 mib are present in the skb head */ +- if (i < 3) { +- data[i] = mib_ethhdr->data[i]; +- continue; +- } +- +- mib_len = sizeof(uint32_t); +- +- /* Some mib are 64 bit wide */ +- if (mib->size == 2) +- mib_len = sizeof(uint64_t); +- +- /* Copy the mib value from packet to the */ +- memcpy(data + i, skb->data + offset, mib_len); +- +- /* Set the offset for the next mib */ +- offset += mib_len; +- } +- +-exit: +- /* Complete on receiving all the mib packet */ +- if (refcount_dec_and_test(&mib_eth_data->port_parsed)) +- complete(&mib_eth_data->rw_done); +-} +- +-static int +-qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) +-{ +- struct dsa_port *dp = dsa_to_port(ds, port); +- struct qca8k_mib_eth_data *mib_eth_data; +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- mib_eth_data = &priv->mib_eth_data; +- +- mutex_lock(&mib_eth_data->mutex); +- +- reinit_completion(&mib_eth_data->rw_done); +- +- mib_eth_data->req_port = dp->index; +- mib_eth_data->data = data; +- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); +- +- mutex_lock(&priv->reg_mutex); +- +- /* Send mib autocast request */ +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, +- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, +- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | +- QCA8K_MIB_BUSY); +- +- mutex_unlock(&priv->reg_mutex); +- +- if (ret) +- goto exit; +- +- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); +- +-exit: +- mutex_unlock(&mib_eth_data->mutex); +- +- return ret; +-} +- +-static void +-qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, +- uint64_t *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- const struct qca8k_match_data *match_data; +- const struct qca8k_mib_desc *mib; +- u32 reg, i, val; +- u32 hi = 0; +- int ret; +- +- if (priv->mgmt_master && +- qca8k_get_ethtool_stats_eth(ds, port, data) > 0) +- return; +- +- match_data = of_device_get_match_data(priv->dev); +- +- for (i = 0; i < match_data->mib_count; i++) { +- mib = &ar8327_mib[i]; +- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; +- +- ret = qca8k_read(priv, reg, &val); +- if (ret < 0) +- continue; +- +- if (mib->size == 2) { +- ret = qca8k_read(priv, reg + 4, &hi); +- if (ret < 0) +- continue; +- } +- +- data[i] = val; +- if (mib->size == 2) +- data[i] |= (u64)hi << 32; +- } +-} +- +-static int +-qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) +-{ +- const struct qca8k_match_data *match_data; +- struct qca8k_priv *priv = ds->priv; +- +- if (sset != ETH_SS_STATS) +- return 0; +- +- match_data = of_device_get_match_data(priv->dev); +- +- return match_data->mib_count; +-} +- +-static int +-qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); +- u32 reg; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); +- if (ret < 0) +- goto exit; +- +- if (eee->eee_enabled) +- reg |= lpi_en; +- else +- reg &= ~lpi_en; +- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +-{ +- /* Nothing to do on the port's MAC */ +- return 0; +-} +- +-static void +-qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 stp_state; +- +- switch (state) { +- case BR_STATE_DISABLED: +- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; +- break; +- case BR_STATE_BLOCKING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; +- break; +- case BR_STATE_LISTENING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; +- break; +- case BR_STATE_LEARNING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; +- break; +- case BR_STATE_FORWARDING: +- default: +- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; +- break; +- } +- +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); +-} +- +-static int +-qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int port_mask, cpu_port; +- int i, ret; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- port_mask = BIT(cpu_port); +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Add this port to the portvlan mask of the other ports +- * in the bridge +- */ +- ret = regmap_set_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- if (ret) +- return ret; +- if (i != port) +- port_mask |= BIT(i); +- } +- +- /* Add all other ports to this ports portvlan mask */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, port_mask); +- +- return ret; +-} +- +-static void +-qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int cpu_port, i; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Remove this port to the portvlan mask of the other ports +- * in the bridge +- */ +- regmap_clear_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- } +- +- /* Set the cpu port to be the only one in the portvlan mask of +- * this port +- */ +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); +-} +- +-static void +-qca8k_port_fast_age(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +-{ +- struct qca8k_priv *priv = ds->priv; +- unsigned int secs = msecs / 1000; +- u32 val; +- +- /* AGE_TIME reg is set in 7s step */ +- val = secs / 7; +- +- /* Handle case with 0 as val to NOT disable +- * learning +- */ +- if (!val) +- val = 1; +- +- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, +- QCA8K_ATU_AGE_TIME(val)); +-} +- +-static int +-qca8k_port_enable(struct dsa_switch *ds, int port, +- struct phy_device *phy) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 1); +- priv->port_enabled_map |= BIT(port); +- +- if (dsa_is_user_port(ds, port)) +- phy_support_asym_pause(phy); +- +- return 0; +-} +- +-static void +-qca8k_port_disable(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 0); +- priv->port_enabled_map &= ~BIT(port); +-} +- +-static int +-qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- /* We have only have a general MTU setting. +- * DSA always set the CPU port's MTU to the largest MTU of the slave +- * ports. +- * Setting MTU just for the CPU port is sufficient to correctly set a +- * value for every port. +- */ +- if (!dsa_is_cpu_port(ds, port)) +- return 0; +- +- /* To change the MAX_FRAME_SIZE the cpu ports must be off or +- * the switch panics. +- * Turn off both cpu ports before applying the new value to prevent +- * this. +- */ +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 0); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 0); +- +- /* Include L2 header / FCS length */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); +- +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 1); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 1); +- +- return ret; +-} +- +-static int +-qca8k_port_max_mtu(struct dsa_switch *ds, int port) +-{ +- return QCA8K_MAX_MTU; +-} +- +-static int +-qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, +- u16 port_mask, u16 vid) +-{ +- /* Set the vid to the port vlan id if no vid is set */ +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_add(priv, addr, port_mask, vid, +- QCA8K_ATU_STATUS_STATIC); +-} +- +-static int +-qca8k_port_fdb_add(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_del(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_del(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_dump(struct dsa_switch *ds, int port, +- dsa_fdb_dump_cb_t *cb, void *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- struct qca8k_fdb _fdb = { 0 }; +- int cnt = QCA8K_NUM_FDB_RECORDS; +- bool is_static; +- int ret = 0; +- +- mutex_lock(&priv->reg_mutex); +- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { +- if (!_fdb.aging) +- break; +- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); +- ret = cb(_fdb.mac, _fdb.vid, is_static, data); +- if (ret) +- break; +- } +- mutex_unlock(&priv->reg_mutex); +- +- return 0; +-} +- +-static int +-qca8k_port_mdb_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); +-} +- +-static int +-qca8k_port_mdb_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); +-} +- +-static int +-qca8k_port_mirror_add(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror, +- bool ingress) +-{ +- struct qca8k_priv *priv = ds->priv; +- int monitor_port, ret; +- u32 reg, val; +- +- /* Check for existent entry */ +- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) +- return -EEXIST; +- +- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); +- if (ret) +- return ret; +- +- /* QCA83xx can have only one port set to mirror mode. +- * Check that the correct port is requested and return error otherwise. +- * When no mirror port is set, the values is set to 0xF +- */ +- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) +- return -EEXIST; +- +- /* Set the monitor port */ +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, +- mirror->to_local_port); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- return ret; +- +- if (ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_update_bits(priv->regmap, reg, val, val); +- if (ret) +- return ret; +- +- /* Track mirror port for tx and rx to decide when the +- * mirror port has to be disabled. +- */ +- if (ingress) +- priv->mirror_rx |= BIT(port); +- else +- priv->mirror_tx |= BIT(port); +- +- return 0; +-} +- +-static void +-qca8k_port_mirror_del(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg, val; +- int ret; +- +- if (mirror->ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_clear_bits(priv->regmap, reg, val); +- if (ret) +- goto err; +- +- if (mirror->ingress) +- priv->mirror_rx &= ~BIT(port); +- else +- priv->mirror_tx &= ~BIT(port); +- +- /* No port set to send packet to mirror port. Disable mirror port */ +- if (!priv->mirror_rx && !priv->mirror_tx) { +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- goto err; +- } +-err: +- dev_err(priv->dev, "Failed to del mirror port from %d", port); +-} +- +-static int +-qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, +- struct netlink_ext_ack *extack) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- if (vlan_filtering) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); +- } else { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan, +- struct netlink_ext_ack *extack) +-{ +- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); +- if (ret) { +- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); +- return ret; +- } +- +- if (pvid) { +- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), +- QCA8K_EGREES_VLAN_PORT_MASK(port), +- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); +- if (ret) +- return ret; +- +- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), +- QCA8K_PORT_VLAN_CVID(vlan->vid) | +- QCA8K_PORT_VLAN_SVID(vlan->vid)); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_del(priv, port, vlan->vid); +- if (ret) +- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); +- +- return ret; +-} +- +-static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- /* Communicate to the phy internal driver the switch revision. +- * Based on the switch revision different values needs to be +- * set to the dbg and mmd reg on the phy. +- * The first 2 bit are used to communicate the switch revision +- * to the phy driver. +- */ +- if (port > 0 && port < 6) +- return priv->switch_revision; +- +- return 0; +-} +- +-static enum dsa_tag_protocol +-qca8k_get_tag_protocol(struct dsa_switch *ds, int port, +- enum dsa_tag_protocol mp) +-{ +- return DSA_TAG_PROTO_QCA; +-} +- +-static bool +-qca8k_lag_can_offload(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct dsa_port *dp; +- int id, members = 0; +- +- id = dsa_lag_id(ds->dst, lag); +- if (id < 0 || id >= ds->num_lag_ids) +- return false; +- +- dsa_lag_foreach_port(dp, ds->dst, lag) +- /* Includes the port joining the LAG */ +- members++; +- +- if (members > QCA8K_NUM_PORTS_FOR_LAG) +- return false; +- +- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) +- return false; +- +- if (info->hash_type != NETDEV_LAG_HASH_L2 && +- info->hash_type != NETDEV_LAG_HASH_L23) +- return false; +- +- return true; +-} +- +-static int +-qca8k_lag_setup_hash(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct qca8k_priv *priv = ds->priv; +- bool unique_lag = true; +- u32 hash = 0; +- int i, id; +- +- id = dsa_lag_id(ds->dst, lag); +- +- switch (info->hash_type) { +- case NETDEV_LAG_HASH_L23: +- hash |= QCA8K_TRUNK_HASH_SIP_EN; +- hash |= QCA8K_TRUNK_HASH_DIP_EN; +- fallthrough; +- case NETDEV_LAG_HASH_L2: +- hash |= QCA8K_TRUNK_HASH_SA_EN; +- hash |= QCA8K_TRUNK_HASH_DA_EN; +- break; +- default: /* We should NEVER reach this */ +- return -EOPNOTSUPP; +- } +- +- /* Check if we are the unique configured LAG */ +- dsa_lags_foreach_id(i, ds->dst) +- if (i != id && dsa_lag_dev(ds->dst, i)) { +- unique_lag = false; +- break; +- } +- +- /* Hash Mode is global. Make sure the same Hash Mode +- * is set to all the 4 possible lag. +- * If we are the unique LAG we can set whatever hash +- * mode we want. +- * To change hash mode it's needed to remove all LAG +- * and change the mode with the latest. +- */ +- if (unique_lag) { +- priv->lag_hash_mode = hash; +- } else if (priv->lag_hash_mode != hash) { +- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); +- return -EOPNOTSUPP; +- } +- +- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, +- QCA8K_TRUNK_HASH_MASK, hash); +-} +- +-static int +-qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, +- struct net_device *lag, bool delete) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret, id, i; +- u32 val; +- +- id = dsa_lag_id(ds->dst, lag); +- +- /* Read current port member */ +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); +- if (ret) +- return ret; +- +- /* Shift val to the correct trunk */ +- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); +- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; +- if (delete) +- val &= ~BIT(port); +- else +- val |= BIT(port); +- +- /* Update port member. With empty portmap disable trunk */ +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, +- QCA8K_REG_GOL_TRUNK_MEMBER(id) | +- QCA8K_REG_GOL_TRUNK_EN(id), +- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | +- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); +- +- /* Search empty member if adding or port on deleting */ +- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); +- if (ret) +- return ret; +- +- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; +- +- if (delete) { +- /* If port flagged to be disabled assume this member is +- * empty +- */ +- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; +- if (val != port) +- continue; +- } else { +- /* If port flagged to be enabled assume this member is +- * already set +- */ +- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- } +- +- /* We have found the member to add/remove */ +- break; +- } +- +- /* Set port in the correct port mask or disable port if in delete mode */ +- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), +- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | +- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); +-} +- +-static int +-qca8k_port_lag_join(struct dsa_switch *ds, int port, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- int ret; +- +- if (!qca8k_lag_can_offload(ds, lag, info)) +- return -EOPNOTSUPP; +- +- ret = qca8k_lag_setup_hash(ds, lag, info); +- if (ret) +- return ret; +- +- return qca8k_lag_refresh_portmap(ds, port, lag, false); +-} +- +-static int +-qca8k_port_lag_leave(struct dsa_switch *ds, int port, +- struct net_device *lag) +-{ +- return qca8k_lag_refresh_portmap(ds, port, lag, true); +-} +- +-static void +-qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, +- bool operational) +-{ +- struct dsa_port *dp = master->dsa_ptr; +- struct qca8k_priv *priv = ds->priv; +- +- /* Ethernet MIB/MDIO is only supported for CPU port 0 */ +- if (dp->index != 0) +- return; +- +- mutex_lock(&priv->mgmt_eth_data.mutex); +- mutex_lock(&priv->mib_eth_data.mutex); +- +- priv->mgmt_master = operational ? (struct net_device *)master : NULL; +- +- mutex_unlock(&priv->mib_eth_data.mutex); +- mutex_unlock(&priv->mgmt_eth_data.mutex); +-} +- +-static int qca8k_connect_tag_protocol(struct dsa_switch *ds, +- enum dsa_tag_protocol proto) +-{ +- struct qca_tagger_data *tagger_data; +- +- switch (proto) { +- case DSA_TAG_PROTO_QCA: +- tagger_data = ds->tagger_data; +- +- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; +- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; +- +- break; +- default: +- return -EOPNOTSUPP; +- } +- +- return 0; +-} +- +-static const struct dsa_switch_ops qca8k_switch_ops = { +- .get_tag_protocol = qca8k_get_tag_protocol, +- .setup = qca8k_setup, +- .get_strings = qca8k_get_strings, +- .get_ethtool_stats = qca8k_get_ethtool_stats, +- .get_sset_count = qca8k_get_sset_count, +- .set_ageing_time = qca8k_set_ageing_time, +- .get_mac_eee = qca8k_get_mac_eee, +- .set_mac_eee = qca8k_set_mac_eee, +- .port_enable = qca8k_port_enable, +- .port_disable = qca8k_port_disable, +- .port_change_mtu = qca8k_port_change_mtu, +- .port_max_mtu = qca8k_port_max_mtu, +- .port_stp_state_set = qca8k_port_stp_state_set, +- .port_bridge_join = qca8k_port_bridge_join, +- .port_bridge_leave = qca8k_port_bridge_leave, +- .port_fast_age = qca8k_port_fast_age, +- .port_fdb_add = qca8k_port_fdb_add, +- .port_fdb_del = qca8k_port_fdb_del, +- .port_fdb_dump = qca8k_port_fdb_dump, +- .port_mdb_add = qca8k_port_mdb_add, +- .port_mdb_del = qca8k_port_mdb_del, +- .port_mirror_add = qca8k_port_mirror_add, +- .port_mirror_del = qca8k_port_mirror_del, +- .port_vlan_filtering = qca8k_port_vlan_filtering, +- .port_vlan_add = qca8k_port_vlan_add, +- .port_vlan_del = qca8k_port_vlan_del, +- .phylink_validate = qca8k_phylink_validate, +- .phylink_mac_link_state = qca8k_phylink_mac_link_state, +- .phylink_mac_config = qca8k_phylink_mac_config, +- .phylink_mac_link_down = qca8k_phylink_mac_link_down, +- .phylink_mac_link_up = qca8k_phylink_mac_link_up, +- .get_phy_flags = qca8k_get_phy_flags, +- .port_lag_join = qca8k_port_lag_join, +- .port_lag_leave = qca8k_port_lag_leave, +- .master_state_change = qca8k_master_change, +- .connect_tag_protocol = qca8k_connect_tag_protocol, +-}; +- +-static int qca8k_read_switch_id(struct qca8k_priv *priv) +-{ +- const struct qca8k_match_data *data; +- u32 val; +- u8 id; +- int ret; +- +- /* get the switches ID from the compatible */ +- data = of_device_get_match_data(priv->dev); +- if (!data) +- return -ENODEV; +- +- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); +- if (ret < 0) +- return -ENODEV; +- +- id = QCA8K_MASK_CTRL_DEVICE_ID(val); +- if (id != data->id) { +- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); +- return -ENODEV; +- } +- +- priv->switch_id = id; +- +- /* Save revision to communicate to the internal PHY driver */ +- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); +- +- return 0; +-} +- +-static int +-qca8k_sw_probe(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv; +- int ret; +- +- /* allocate the private data struct so that we can probe the switches +- * ID register +- */ +- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- +- priv->bus = mdiodev->bus; +- priv->dev = &mdiodev->dev; +- +- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", +- GPIOD_ASIS); +- if (IS_ERR(priv->reset_gpio)) +- return PTR_ERR(priv->reset_gpio); +- +- if (priv->reset_gpio) { +- gpiod_set_value_cansleep(priv->reset_gpio, 1); +- /* The active low duration must be greater than 10 ms +- * and checkpatch.pl wants 20 ms. +- */ +- msleep(20); +- gpiod_set_value_cansleep(priv->reset_gpio, 0); +- } +- +- /* Start by setting up the register mapping */ +- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, +- &qca8k_regmap_config); +- if (IS_ERR(priv->regmap)) { +- dev_err(priv->dev, "regmap initialization failed"); +- return PTR_ERR(priv->regmap); +- } +- +- priv->mdio_cache.page = 0xffff; +- priv->mdio_cache.lo = 0xffff; +- priv->mdio_cache.hi = 0xffff; +- +- /* Check the detected switch id */ +- ret = qca8k_read_switch_id(priv); +- if (ret) +- return ret; +- +- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); +- if (!priv->ds) +- return -ENOMEM; +- +- mutex_init(&priv->mgmt_eth_data.mutex); +- init_completion(&priv->mgmt_eth_data.rw_done); +- +- mutex_init(&priv->mib_eth_data.mutex); +- init_completion(&priv->mib_eth_data.rw_done); +- +- priv->ds->dev = &mdiodev->dev; +- priv->ds->num_ports = QCA8K_NUM_PORTS; +- priv->ds->priv = priv; +- priv->ds->ops = &qca8k_switch_ops; +- mutex_init(&priv->reg_mutex); +- dev_set_drvdata(&mdiodev->dev, priv); +- +- return dsa_register_switch(priv->ds); +-} +- +-static void +-qca8k_sw_remove(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); +- int i; +- +- if (!priv) +- return; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) +- qca8k_port_set_status(priv, i, 0); +- +- dsa_unregister_switch(priv->ds); +- +- dev_set_drvdata(&mdiodev->dev, NULL); +-} +- +-static void qca8k_sw_shutdown(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); +- +- if (!priv) +- return; +- +- dsa_switch_shutdown(priv->ds); +- +- dev_set_drvdata(&mdiodev->dev, NULL); +-} +- +-#ifdef CONFIG_PM_SLEEP +-static void +-qca8k_set_pm(struct qca8k_priv *priv, int enable) +-{ +- int port; +- +- for (port = 0; port < QCA8K_NUM_PORTS; port++) { +- /* Do not enable on resume if the port was +- * disabled before. +- */ +- if (!(priv->port_enabled_map & BIT(port))) +- continue; +- +- qca8k_port_set_status(priv, port, enable); +- } +-} +- +-static int qca8k_suspend(struct device *dev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(dev); +- +- qca8k_set_pm(priv, 0); +- +- return dsa_switch_suspend(priv->ds); +-} +- +-static int qca8k_resume(struct device *dev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(dev); +- +- qca8k_set_pm(priv, 1); +- +- return dsa_switch_resume(priv->ds); +-} +-#endif /* CONFIG_PM_SLEEP */ +- +-static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, +- qca8k_suspend, qca8k_resume); +- +-static const struct qca8k_match_data qca8327 = { +- .id = QCA8K_ID_QCA8327, +- .reduced_package = true, +- .mib_count = QCA8K_QCA832X_MIB_COUNT, +-}; +- +-static const struct qca8k_match_data qca8328 = { +- .id = QCA8K_ID_QCA8327, +- .mib_count = QCA8K_QCA832X_MIB_COUNT, +-}; +- +-static const struct qca8k_match_data qca833x = { +- .id = QCA8K_ID_QCA8337, +- .mib_count = QCA8K_QCA833X_MIB_COUNT, +-}; +- +-static const struct of_device_id qca8k_of_match[] = { +- { .compatible = "qca,qca8327", .data = &qca8327 }, +- { .compatible = "qca,qca8328", .data = &qca8328 }, +- { .compatible = "qca,qca8334", .data = &qca833x }, +- { .compatible = "qca,qca8337", .data = &qca833x }, +- { /* sentinel */ }, +-}; +- +-static struct mdio_driver qca8kmdio_driver = { +- .probe = qca8k_sw_probe, +- .remove = qca8k_sw_remove, +- .shutdown = qca8k_sw_shutdown, +- .mdiodrv.driver = { +- .name = "qca8k", +- .of_match_table = qca8k_of_match, +- .pm = &qca8k_pm_ops, +- }, +-}; +- +-mdio_module_driver(qca8kmdio_driver); +- +-MODULE_AUTHOR("Mathieu Olivari, John Crispin "); +-MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); +-MODULE_LICENSE("GPL v2"); +-MODULE_ALIAS("platform:qca8k"); +--- a/drivers/net/dsa/qca8k.h ++++ /dev/null +@@ -1,411 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * Copyright (C) 2009 Felix Fietkau +- * Copyright (C) 2011-2012 Gabor Juhos +- * Copyright (c) 2015, The Linux Foundation. All rights reserved. +- */ +- +-#ifndef __QCA8K_H +-#define __QCA8K_H +- +-#include +-#include +-#include +-#include +- +-#define QCA8K_ETHERNET_MDIO_PRIORITY 7 +-#define QCA8K_ETHERNET_PHY_PRIORITY 6 +-#define QCA8K_ETHERNET_TIMEOUT 100 +- +-#define QCA8K_NUM_PORTS 7 +-#define QCA8K_NUM_CPU_PORTS 2 +-#define QCA8K_MAX_MTU 9000 +-#define QCA8K_NUM_LAGS 4 +-#define QCA8K_NUM_PORTS_FOR_LAG 4 +- +-#define PHY_ID_QCA8327 0x004dd034 +-#define QCA8K_ID_QCA8327 0x12 +-#define PHY_ID_QCA8337 0x004dd036 +-#define QCA8K_ID_QCA8337 0x13 +- +-#define QCA8K_QCA832X_MIB_COUNT 39 +-#define QCA8K_QCA833X_MIB_COUNT 41 +- +-#define QCA8K_BUSY_WAIT_TIMEOUT 2000 +- +-#define QCA8K_NUM_FDB_RECORDS 2048 +- +-#define QCA8K_PORT_VID_DEF 1 +- +-/* Global control registers */ +-#define QCA8K_REG_MASK_CTRL 0x000 +-#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) +-#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) +-#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) +-#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) +-#define QCA8K_REG_PORT0_PAD_CTRL 0x004 +-#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) +-#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) +-#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) +-#define QCA8K_REG_PORT5_PAD_CTRL 0x008 +-#define QCA8K_REG_PORT6_PAD_CTRL 0x00c +-#define QCA8K_PORT_PAD_RGMII_EN BIT(26) +-#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) +-#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) +-#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) +-#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) +-#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) +-#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) +-#define QCA8K_PORT_PAD_SGMII_EN BIT(7) +-#define QCA8K_REG_PWS 0x010 +-#define QCA8K_PWS_POWER_ON_SEL BIT(31) +-/* This reg is only valid for QCA832x and toggle the package +- * type from 176 pin (by default) to 148 pin used on QCA8327 +- */ +-#define QCA8327_PWS_PACKAGE148_EN BIT(30) +-#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24) +-#define QCA8K_PWS_SERDES_AEN_DIS BIT(7) +-#define QCA8K_REG_MODULE_EN 0x030 +-#define QCA8K_MODULE_EN_MIB BIT(0) +-#define QCA8K_REG_MIB 0x034 +-#define QCA8K_MIB_FUNC GENMASK(26, 24) +-#define QCA8K_MIB_CPU_KEEP BIT(20) +-#define QCA8K_MIB_BUSY BIT(17) +-#define QCA8K_MDIO_MASTER_CTRL 0x3c +-#define QCA8K_MDIO_MASTER_BUSY BIT(31) +-#define QCA8K_MDIO_MASTER_EN BIT(30) +-#define QCA8K_MDIO_MASTER_READ BIT(27) +-#define QCA8K_MDIO_MASTER_WRITE 0 +-#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) +-#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) +-#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) +-#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) +-#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) +-#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) +-#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) +-#define QCA8K_MDIO_MASTER_MAX_PORTS 5 +-#define QCA8K_MDIO_MASTER_MAX_REG 32 +-#define QCA8K_GOL_MAC_ADDR0 0x60 +-#define QCA8K_GOL_MAC_ADDR1 0x64 +-#define QCA8K_MAX_FRAME_SIZE 0x78 +-#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) +-#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0) +-#define QCA8K_PORT_STATUS_SPEED_10 0 +-#define QCA8K_PORT_STATUS_SPEED_100 0x1 +-#define QCA8K_PORT_STATUS_SPEED_1000 0x2 +-#define QCA8K_PORT_STATUS_TXMAC BIT(2) +-#define QCA8K_PORT_STATUS_RXMAC BIT(3) +-#define QCA8K_PORT_STATUS_TXFLOW BIT(4) +-#define QCA8K_PORT_STATUS_RXFLOW BIT(5) +-#define QCA8K_PORT_STATUS_DUPLEX BIT(6) +-#define QCA8K_PORT_STATUS_LINK_UP BIT(8) +-#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9) +-#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10) +-#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) +-#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) +-#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) +-#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) +-#define QCA8K_PORT_HDR_CTRL_ALL 2 +-#define QCA8K_PORT_HDR_CTRL_MGMT 1 +-#define QCA8K_PORT_HDR_CTRL_NONE 0 +-#define QCA8K_REG_SGMII_CTRL 0x0e0 +-#define QCA8K_SGMII_EN_PLL BIT(1) +-#define QCA8K_SGMII_EN_RX BIT(2) +-#define QCA8K_SGMII_EN_TX BIT(3) +-#define QCA8K_SGMII_EN_SD BIT(4) +-#define QCA8K_SGMII_CLK125M_DELAY BIT(7) +-#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) +-#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) +-#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) +-#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) +-#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) +- +-/* MAC_PWR_SEL registers */ +-#define QCA8K_REG_MAC_PWR_SEL 0x0e4 +-#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18) +-#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19) +- +-/* EEE control registers */ +-#define QCA8K_REG_EEE_CTRL 0x100 +-#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) +- +-/* TRUNK_HASH_EN registers */ +-#define QCA8K_TRUNK_HASH_EN_CTRL 0x270 +-#define QCA8K_TRUNK_HASH_SIP_EN BIT(3) +-#define QCA8K_TRUNK_HASH_DIP_EN BIT(2) +-#define QCA8K_TRUNK_HASH_SA_EN BIT(1) +-#define QCA8K_TRUNK_HASH_DA_EN BIT(0) +-#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0) +- +-/* ACL registers */ +-#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) +-#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) +-#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) +-#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) +-#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) +-#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) +-#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 +-#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 +- +-/* Lookup registers */ +-#define QCA8K_REG_ATU_DATA0 0x600 +-#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) +-#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) +-#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) +-#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) +-#define QCA8K_REG_ATU_DATA1 0x604 +-#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) +-#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) +-#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) +-#define QCA8K_REG_ATU_DATA2 0x608 +-#define QCA8K_ATU_VID_MASK GENMASK(19, 8) +-#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) +-#define QCA8K_ATU_STATUS_STATIC 0xf +-#define QCA8K_REG_ATU_FUNC 0x60c +-#define QCA8K_ATU_FUNC_BUSY BIT(31) +-#define QCA8K_ATU_FUNC_PORT_EN BIT(14) +-#define QCA8K_ATU_FUNC_MULTI_EN BIT(13) +-#define QCA8K_ATU_FUNC_FULL BIT(12) +-#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) +-#define QCA8K_REG_VTU_FUNC0 0x610 +-#define QCA8K_VTU_FUNC0_VALID BIT(20) +-#define QCA8K_VTU_FUNC0_IVL_EN BIT(19) +-/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) +- * It does contain VLAN_MODE for each port [5:4] for port0, +- * [7:6] for port1 ... [17:16] for port6. Use virtual port +- * define to handle this. +- */ +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) +-#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +-#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +-#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +-#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +-#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) +-#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) +-#define QCA8K_REG_VTU_FUNC1 0x614 +-#define QCA8K_VTU_FUNC1_BUSY BIT(31) +-#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) +-#define QCA8K_VTU_FUNC1_FULL BIT(4) +-#define QCA8K_REG_ATU_CTRL 0x618 +-#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) +-#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) +-#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 +-#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) +-#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) +-#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 +-#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) +-#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) +-#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) +-#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) +-#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) +-#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) +-#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) +-#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) +-#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) +-#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) +-#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) +-#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) +-#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) +-#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) +-#define QCA8K_PORT_LOOKUP_LEARN BIT(20) +-#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) +- +-#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 +-/* 4 max trunk first +- * first 6 bit for member bitmap +- * 7th bit is to enable trunk port +- */ +-#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) +-#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) +-#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) +-#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) +-#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) +-/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ +-#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) +-#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) +-#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) +-/* Complex shift: FIRST shift for port THEN shift for trunk */ +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) +-#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) +- +-#define QCA8K_REG_GLOBAL_FC_THRESH 0x800 +-#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) +-#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) +-#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) +-#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) +- +-#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) +-#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) +-#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) +- +-#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) +-#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) +-#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) +-#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) +-#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) +-#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) +-#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) +- +-/* Pkt edit registers */ +-#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) +-#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) +-#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) +-#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) +- +-/* L3 registers */ +-#define QCA8K_HROUTER_CONTROL 0xe00 +-#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16) +-#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16 +-#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1 +-#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08 +-#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c +-#define QCA8K_HNAT_CONTROL 0xe38 +- +-/* MIB registers */ +-#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) +- +-/* QCA specific MII registers */ +-#define MII_ATH_MMD_ADDR 0x0d +-#define MII_ATH_MMD_DATA 0x0e +- +-enum { +- QCA8K_PORT_SPEED_10M = 0, +- QCA8K_PORT_SPEED_100M = 1, +- QCA8K_PORT_SPEED_1000M = 2, +- QCA8K_PORT_SPEED_ERR = 3, +-}; +- +-enum qca8k_fdb_cmd { +- QCA8K_FDB_FLUSH = 1, +- QCA8K_FDB_LOAD = 2, +- QCA8K_FDB_PURGE = 3, +- QCA8K_FDB_FLUSH_PORT = 5, +- QCA8K_FDB_NEXT = 6, +- QCA8K_FDB_SEARCH = 7, +-}; +- +-enum qca8k_vlan_cmd { +- QCA8K_VLAN_FLUSH = 1, +- QCA8K_VLAN_LOAD = 2, +- QCA8K_VLAN_PURGE = 3, +- QCA8K_VLAN_REMOVE_PORT = 4, +- QCA8K_VLAN_NEXT = 5, +- QCA8K_VLAN_READ = 6, +-}; +- +-enum qca8k_mid_cmd { +- QCA8K_MIB_FLUSH = 1, +- QCA8K_MIB_FLUSH_PORT = 2, +- QCA8K_MIB_CAST = 3, +-}; +- +-struct qca8k_match_data { +- u8 id; +- bool reduced_package; +- u8 mib_count; +-}; +- +-enum { +- QCA8K_CPU_PORT0, +- QCA8K_CPU_PORT6, +-}; +- +-struct qca8k_mgmt_eth_data { +- struct completion rw_done; +- struct mutex mutex; /* Enforce one mdio read/write at time */ +- bool ack; +- u32 seq; +- u32 data[4]; +-}; +- +-struct qca8k_mib_eth_data { +- struct completion rw_done; +- struct mutex mutex; /* Process one command at time */ +- refcount_t port_parsed; /* Counter to track parsed port */ +- u8 req_port; +- u64 *data; /* pointer to ethtool data */ +-}; +- +-struct qca8k_ports_config { +- bool sgmii_rx_clk_falling_edge; +- bool sgmii_tx_clk_falling_edge; +- bool sgmii_enable_pll; +- u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ +- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ +-}; +- +-struct qca8k_mdio_cache { +-/* The 32bit switch registers are accessed indirectly. To achieve this we need +- * to set the page of the register. Track the last page that was set to reduce +- * mdio writes +- */ +- u16 page; +-/* lo and hi can also be cached and from Documentation we can skip one +- * extra mdio write if lo or hi is didn't change. +- */ +- u16 lo; +- u16 hi; +-}; +- +-struct qca8k_priv { +- u8 switch_id; +- u8 switch_revision; +- u8 mirror_rx; +- u8 mirror_tx; +- u8 lag_hash_mode; +- /* Each bit correspond to a port. This switch can support a max of 7 port. +- * Bit 1: port enabled. Bit 0: port disabled. +- */ +- u8 port_enabled_map; +- struct qca8k_ports_config ports_config; +- struct regmap *regmap; +- struct mii_bus *bus; +- struct dsa_switch *ds; +- struct mutex reg_mutex; +- struct device *dev; +- struct gpio_desc *reset_gpio; +- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ +- struct qca8k_mgmt_eth_data mgmt_eth_data; +- struct qca8k_mib_eth_data mib_eth_data; +- struct qca8k_mdio_cache mdio_cache; +-}; +- +-struct qca8k_mib_desc { +- unsigned int size; +- unsigned int offset; +- const char *name; +-}; +- +-struct qca8k_fdb { +- u16 vid; +- u8 port_mask; +- u8 aging; +- u8 mac[6]; +-}; +- +-#endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch b/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch new file mode 100644 index 000000000..77fe64632 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch @@ -0,0 +1,157 @@ +From 3bb0844e7bcd0fb0bcfab6202b5edd349ef5250a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:10 +0200 +Subject: [PATCH 01/14] net: dsa: qca8k: cache match data to speed up access + +Using of_device_get_match_data is expensive. Cache match data to speed +up access and rework user of match data to use the new cached value. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k.c | 35 +++++++++++------------------------ + drivers/net/dsa/qca/qca8k.h | 1 + + 2 files changed, 12 insertions(+), 24 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k.c ++++ b/drivers/net/dsa/qca/qca8k.c +@@ -1462,8 +1462,8 @@ static int qca8k_find_cpu_port(struct ds + static int + qca8k_setup_of_pws_reg(struct qca8k_priv *priv) + { ++ const struct qca8k_match_data *data = priv->info; + struct device_node *node = priv->dev->of_node; +- const struct qca8k_match_data *data; + u32 val = 0; + int ret; + +@@ -1472,8 +1472,6 @@ qca8k_setup_of_pws_reg(struct qca8k_priv + * Should be applied by default but we set this just to make sure. + */ + if (priv->switch_id == QCA8K_ID_QCA8327) { +- data = of_device_get_match_data(priv->dev); +- + /* Set the correct package of 148 pin for QCA8327 */ + if (data->reduced_package) + val |= QCA8327_PWS_PACKAGE148_EN; +@@ -2146,23 +2144,19 @@ qca8k_phylink_mac_link_up(struct dsa_swi + static void + qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) + { +- const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; + int i; + + if (stringset != ETH_SS_STATS) + return; + +- match_data = of_device_get_match_data(priv->dev); +- +- for (i = 0; i < match_data->mib_count; i++) ++ for (i = 0; i < priv->info->mib_count; i++) + strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, + ETH_GSTRING_LEN); + } + + static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) + { +- const struct qca8k_match_data *match_data; + struct qca8k_mib_eth_data *mib_eth_data; + struct qca8k_priv *priv = ds->priv; + const struct qca8k_mib_desc *mib; +@@ -2181,10 +2175,9 @@ static void qca8k_mib_autocast_handler(s + if (port != mib_eth_data->req_port) + goto exit; + +- match_data = device_get_match_data(priv->dev); + data = mib_eth_data->data; + +- for (i = 0; i < match_data->mib_count; i++) { ++ for (i = 0; i < priv->info->mib_count; i++) { + mib = &ar8327_mib[i]; + + /* First 3 mib are present in the skb head */ +@@ -2256,7 +2249,6 @@ qca8k_get_ethtool_stats(struct dsa_switc + uint64_t *data) + { + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- const struct qca8k_match_data *match_data; + const struct qca8k_mib_desc *mib; + u32 reg, i, val; + u32 hi = 0; +@@ -2266,9 +2258,7 @@ qca8k_get_ethtool_stats(struct dsa_switc + qca8k_get_ethtool_stats_eth(ds, port, data) > 0) + return; + +- match_data = of_device_get_match_data(priv->dev); +- +- for (i = 0; i < match_data->mib_count; i++) { ++ for (i = 0; i < priv->info->mib_count; i++) { + mib = &ar8327_mib[i]; + reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; + +@@ -2291,15 +2281,12 @@ qca8k_get_ethtool_stats(struct dsa_switc + static int + qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) + { +- const struct qca8k_match_data *match_data; + struct qca8k_priv *priv = ds->priv; + + if (sset != ETH_SS_STATS) + return 0; + +- match_data = of_device_get_match_data(priv->dev); +- +- return match_data->mib_count; ++ return priv->info->mib_count; + } + + static int +@@ -3037,14 +3024,11 @@ static const struct dsa_switch_ops qca8k + + static int qca8k_read_switch_id(struct qca8k_priv *priv) + { +- const struct qca8k_match_data *data; + u32 val; + u8 id; + int ret; + +- /* get the switches ID from the compatible */ +- data = of_device_get_match_data(priv->dev); +- if (!data) ++ if (!priv->info) + return -ENODEV; + + ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); +@@ -3052,8 +3036,10 @@ static int qca8k_read_switch_id(struct q + return -ENODEV; + + id = QCA8K_MASK_CTRL_DEVICE_ID(val); +- if (id != data->id) { +- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); ++ if (id != priv->info->id) { ++ dev_err(priv->dev, ++ "Switch id detected %x but expected %x", ++ id, priv->info->id); + return -ENODEV; + } + +@@ -3078,6 +3064,7 @@ qca8k_sw_probe(struct mdio_device *mdiod + if (!priv) + return -ENOMEM; + ++ priv->info = of_device_get_match_data(priv->dev); + priv->bus = mdiodev->bus; + priv->dev = &mdiodev->dev; + +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -393,6 +393,7 @@ struct qca8k_priv { + struct qca8k_mgmt_eth_data mgmt_eth_data; + struct qca8k_mib_eth_data mib_eth_data; + struct qca8k_mdio_cache mdio_cache; ++ const struct qca8k_match_data *info; + }; + + struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch b/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch new file mode 100644 index 000000000..5b2dce4c5 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch @@ -0,0 +1,77 @@ +From 533c64bca62a8654f00698bc893f639013e38c7b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:11 +0200 +Subject: [PATCH 02/14] net: dsa: qca8k: make mib autocast feature optional + +Some switch may not support mib autocast feature and require the legacy +way of reading the regs directly. +Make the mib autocast feature optional and permit to declare support for +it using match_data struct in a dedicated qca8k_info_ops struct. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k.c | 11 +++++++++-- + drivers/net/dsa/qca/qca8k.h | 5 +++++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k.c ++++ b/drivers/net/dsa/qca/qca8k.c +@@ -2254,8 +2254,8 @@ qca8k_get_ethtool_stats(struct dsa_switc + u32 hi = 0; + int ret; + +- if (priv->mgmt_master && +- qca8k_get_ethtool_stats_eth(ds, port, data) > 0) ++ if (priv->mgmt_master && priv->info->ops->autocast_mib && ++ priv->info->ops->autocast_mib(ds, port, data) > 0) + return; + + for (i = 0; i < priv->info->mib_count; i++) { +@@ -3187,20 +3187,27 @@ static int qca8k_resume(struct device *d + static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, + qca8k_suspend, qca8k_resume); + ++static const struct qca8k_info_ops qca8xxx_ops = { ++ .autocast_mib = qca8k_get_ethtool_stats_eth, ++}; ++ + static const struct qca8k_match_data qca8327 = { + .id = QCA8K_ID_QCA8327, + .reduced_package = true, + .mib_count = QCA8K_QCA832X_MIB_COUNT, ++ .ops = &qca8xxx_ops, + }; + + static const struct qca8k_match_data qca8328 = { + .id = QCA8K_ID_QCA8327, + .mib_count = QCA8K_QCA832X_MIB_COUNT, ++ .ops = &qca8xxx_ops, + }; + + static const struct qca8k_match_data qca833x = { + .id = QCA8K_ID_QCA8337, + .mib_count = QCA8K_QCA833X_MIB_COUNT, ++ .ops = &qca8xxx_ops, + }; + + static const struct of_device_id qca8k_of_match[] = { +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -324,10 +324,15 @@ enum qca8k_mid_cmd { + QCA8K_MIB_CAST = 3, + }; + ++struct qca8k_info_ops { ++ int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); ++}; ++ + struct qca8k_match_data { + u8 id; + bool reduced_package; + u8 mib_count; ++ const struct qca8k_info_ops *ops; + }; + + enum { diff --git a/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch new file mode 100644 index 000000000..afa466693 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch @@ -0,0 +1,6532 @@ +From 027152b830434e3632ad5dd678cc5d4740358dbb Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:12 +0200 +Subject: [PATCH 03/14] net: dsa: qca8k: move mib struct to common code + +The same MIB struct is used by drivers based on qca8k family switch. Move +it to common code to make it accessible also by other drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/Makefile | 1 + + drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} | 51 --------------- + drivers/net/dsa/qca/qca8k-common.c | 63 +++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 3 + + 4 files changed, 67 insertions(+), 51 deletions(-) + rename drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} (98%) + create mode 100644 drivers/net/dsa/qca/qca8k-common.c + +--- a/drivers/net/dsa/qca/Makefile ++++ b/drivers/net/dsa/qca/Makefile +@@ -1,3 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o + obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o ++qca8k-y += qca8k-common.o qca8k-8xxx.o +--- a/drivers/net/dsa/qca/qca8k.c ++++ /dev/null +@@ -1,3237 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * Copyright (C) 2009 Felix Fietkau +- * Copyright (C) 2011-2012 Gabor Juhos +- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2016 John Crispin +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "qca8k.h" +- +-#define MIB_DESC(_s, _o, _n) \ +- { \ +- .size = (_s), \ +- .offset = (_o), \ +- .name = (_n), \ +- } +- +-static const struct qca8k_mib_desc ar8327_mib[] = { +- MIB_DESC(1, 0x00, "RxBroad"), +- MIB_DESC(1, 0x04, "RxPause"), +- MIB_DESC(1, 0x08, "RxMulti"), +- MIB_DESC(1, 0x0c, "RxFcsErr"), +- MIB_DESC(1, 0x10, "RxAlignErr"), +- MIB_DESC(1, 0x14, "RxRunt"), +- MIB_DESC(1, 0x18, "RxFragment"), +- MIB_DESC(1, 0x1c, "Rx64Byte"), +- MIB_DESC(1, 0x20, "Rx128Byte"), +- MIB_DESC(1, 0x24, "Rx256Byte"), +- MIB_DESC(1, 0x28, "Rx512Byte"), +- MIB_DESC(1, 0x2c, "Rx1024Byte"), +- MIB_DESC(1, 0x30, "Rx1518Byte"), +- MIB_DESC(1, 0x34, "RxMaxByte"), +- MIB_DESC(1, 0x38, "RxTooLong"), +- MIB_DESC(2, 0x3c, "RxGoodByte"), +- MIB_DESC(2, 0x44, "RxBadByte"), +- MIB_DESC(1, 0x4c, "RxOverFlow"), +- MIB_DESC(1, 0x50, "Filtered"), +- MIB_DESC(1, 0x54, "TxBroad"), +- MIB_DESC(1, 0x58, "TxPause"), +- MIB_DESC(1, 0x5c, "TxMulti"), +- MIB_DESC(1, 0x60, "TxUnderRun"), +- MIB_DESC(1, 0x64, "Tx64Byte"), +- MIB_DESC(1, 0x68, "Tx128Byte"), +- MIB_DESC(1, 0x6c, "Tx256Byte"), +- MIB_DESC(1, 0x70, "Tx512Byte"), +- MIB_DESC(1, 0x74, "Tx1024Byte"), +- MIB_DESC(1, 0x78, "Tx1518Byte"), +- MIB_DESC(1, 0x7c, "TxMaxByte"), +- MIB_DESC(1, 0x80, "TxOverSize"), +- MIB_DESC(2, 0x84, "TxByte"), +- MIB_DESC(1, 0x8c, "TxCollision"), +- MIB_DESC(1, 0x90, "TxAbortCol"), +- MIB_DESC(1, 0x94, "TxMultiCol"), +- MIB_DESC(1, 0x98, "TxSingleCol"), +- MIB_DESC(1, 0x9c, "TxExcDefer"), +- MIB_DESC(1, 0xa0, "TxDefer"), +- MIB_DESC(1, 0xa4, "TxLateCol"), +- MIB_DESC(1, 0xa8, "RXUnicast"), +- MIB_DESC(1, 0xac, "TXUnicast"), +-}; +- +-static void +-qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) +-{ +- regaddr >>= 1; +- *r1 = regaddr & 0x1e; +- +- regaddr >>= 5; +- *r2 = regaddr & 0x7; +- +- regaddr >>= 3; +- *page = regaddr & 0x3ff; +-} +- +-static int +-qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) +-{ +- u16 *cached_lo = &priv->mdio_cache.lo; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (lo == *cached_lo) +- return 0; +- +- ret = bus->write(bus, phy_id, regnum, lo); +- if (ret < 0) +- dev_err_ratelimited(&bus->dev, +- "failed to write qca8k 32bit lo register\n"); +- +- *cached_lo = lo; +- return 0; +-} +- +-static int +-qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) +-{ +- u16 *cached_hi = &priv->mdio_cache.hi; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (hi == *cached_hi) +- return 0; +- +- ret = bus->write(bus, phy_id, regnum, hi); +- if (ret < 0) +- dev_err_ratelimited(&bus->dev, +- "failed to write qca8k 32bit hi register\n"); +- +- *cached_hi = hi; +- return 0; +-} +- +-static int +-qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) +-{ +- int ret; +- +- ret = bus->read(bus, phy_id, regnum); +- if (ret >= 0) { +- *val = ret; +- ret = bus->read(bus, phy_id, regnum + 1); +- *val |= ret << 16; +- } +- +- if (ret < 0) { +- dev_err_ratelimited(&bus->dev, +- "failed to read qca8k 32bit register\n"); +- *val = 0; +- return ret; +- } +- +- return 0; +-} +- +-static void +-qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) +-{ +- u16 lo, hi; +- int ret; +- +- lo = val & 0xffff; +- hi = (u16)(val >> 16); +- +- ret = qca8k_set_lo(priv, phy_id, regnum, lo); +- if (ret >= 0) +- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); +-} +- +-static int +-qca8k_set_page(struct qca8k_priv *priv, u16 page) +-{ +- u16 *cached_page = &priv->mdio_cache.page; +- struct mii_bus *bus = priv->bus; +- int ret; +- +- if (page == *cached_page) +- return 0; +- +- ret = bus->write(bus, 0x18, 0, page); +- if (ret < 0) { +- dev_err_ratelimited(&bus->dev, +- "failed to set qca8k page\n"); +- return ret; +- } +- +- *cached_page = page; +- usleep_range(1000, 2000); +- return 0; +-} +- +-static int +-qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) +-{ +- return regmap_read(priv->regmap, reg, val); +-} +- +-static int +-qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) +-{ +- return regmap_write(priv->regmap, reg, val); +-} +- +-static int +-qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +-{ +- return regmap_update_bits(priv->regmap, reg, mask, write_val); +-} +- +-static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data; +- struct qca8k_priv *priv = ds->priv; +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- u8 len, cmd; +- +- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); +- mgmt_eth_data = &priv->mgmt_eth_data; +- +- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); +- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); +- +- /* Make sure the seq match the requested packet */ +- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) +- mgmt_eth_data->ack = true; +- +- if (cmd == MDIO_READ) { +- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; +- +- /* Get the rest of the 12 byte of data. +- * The read/write function will extract the requested data. +- */ +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(mgmt_eth_data->data + 1, skb->data, +- QCA_HDR_MGMT_DATA2_LEN); +- } +- +- complete(&mgmt_eth_data->rw_done); +-} +- +-static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, +- int priority, unsigned int len) +-{ +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- unsigned int real_len; +- struct sk_buff *skb; +- u32 *data2; +- u16 hdr; +- +- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); +- if (!skb) +- return NULL; +- +- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte +- * Actually for some reason the steps are: +- * 0: nothing +- * 1-4: first 4 byte +- * 5-6: first 12 byte +- * 7-15: all 16 byte +- */ +- if (len == 16) +- real_len = 15; +- else +- real_len = len; +- +- skb_reset_mac_header(skb); +- skb_set_network_header(skb, skb->len); +- +- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); +- +- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); +- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); +- hdr |= QCA_HDR_XMIT_FROM_CPU; +- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); +- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); +- +- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, +- QCA_HDR_MGMT_CHECK_CODE_VAL); +- +- if (cmd == MDIO_WRITE) +- mgmt_ethhdr->mdio_data = *val; +- +- mgmt_ethhdr->hdr = htons(hdr); +- +- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); +- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); +- +- return skb; +-} +- +-static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) +-{ +- struct qca_mgmt_ethhdr *mgmt_ethhdr; +- +- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; +- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); +-} +- +-static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; +- struct sk_buff *skb; +- bool ack; +- int ret; +- +- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, +- QCA8K_ETHERNET_MDIO_PRIORITY, len); +- if (!skb) +- return -ENOMEM; +- +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check mgmt_master if is operational */ +- if (!priv->mgmt_master) { +- kfree_skb(skb); +- mutex_unlock(&mgmt_eth_data->mutex); +- return -EINVAL; +- } +- +- skb->dev = priv->mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the mdio pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); +- +- *val = mgmt_eth_data->data[0]; +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); +- +- ack = mgmt_eth_data->ack; +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- return 0; +-} +- +-static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; +- struct sk_buff *skb; +- bool ack; +- int ret; +- +- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, +- QCA8K_ETHERNET_MDIO_PRIORITY, len); +- if (!skb) +- return -ENOMEM; +- +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check mgmt_master if is operational */ +- if (!priv->mgmt_master) { +- kfree_skb(skb); +- mutex_unlock(&mgmt_eth_data->mutex); +- return -EINVAL; +- } +- +- skb->dev = priv->mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the mdio pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); +- +- ack = mgmt_eth_data->ack; +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- return 0; +-} +- +-static int +-qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +-{ +- u32 val = 0; +- int ret; +- +- ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); +- if (ret) +- return ret; +- +- val &= ~mask; +- val |= write_val; +- +- return qca8k_write_eth(priv, reg, &val, sizeof(val)); +-} +- +-static int +-qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- +- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int +-qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- u32 tmp; +- +- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- tmp = val[i]; +- +- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int +-qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- int ret; +- +- if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- return ret; +-} +- +-static int +-qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- int ret; +- +- if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- return ret; +-} +- +-static int +-qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) +- return 0; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); +- if (ret < 0) +- goto exit; +- +- val &= ~mask; +- val |= write_val; +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +-exit: +- mutex_unlock(&bus->mdio_lock); +- +- return ret; +-} +- +-static const struct regmap_range qca8k_readable_ranges[] = { +- regmap_reg_range(0x0000, 0x00e4), /* Global control */ +- regmap_reg_range(0x0100, 0x0168), /* EEE control */ +- regmap_reg_range(0x0200, 0x0270), /* Parser control */ +- regmap_reg_range(0x0400, 0x0454), /* ACL */ +- regmap_reg_range(0x0600, 0x0718), /* Lookup */ +- regmap_reg_range(0x0800, 0x0b70), /* QM */ +- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ +- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ +- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ +- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ +- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ +- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ +- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ +- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ +- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ +- +-}; +- +-static const struct regmap_access_table qca8k_readable_table = { +- .yes_ranges = qca8k_readable_ranges, +- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), +-}; +- +-static struct regmap_config qca8k_regmap_config = { +- .reg_bits = 16, +- .val_bits = 32, +- .reg_stride = 4, +- .max_register = 0x16ac, /* end MIB - Port6 range */ +- .reg_read = qca8k_regmap_read, +- .reg_write = qca8k_regmap_write, +- .reg_update_bits = qca8k_regmap_update_bits, +- .rd_table = &qca8k_readable_table, +- .disable_locking = true, /* Locking is handled by qca8k read/write */ +- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ +-}; +- +-static int +-qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) +-{ +- u32 val; +- +- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); +-} +- +-static int +-qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) +-{ +- u32 reg[3]; +- int ret; +- +- /* load the ARL table into an array */ +- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +- if (ret) +- return ret; +- +- /* vid - 83:72 */ +- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); +- /* aging - 67:64 */ +- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); +- /* portmask - 54:48 */ +- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); +- /* mac - 47:0 */ +- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); +- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); +- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); +- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); +- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); +- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); +- +- return 0; +-} +- +-static void +-qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, +- u8 aging) +-{ +- u32 reg[3] = { 0 }; +- +- /* vid - 83:72 */ +- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); +- /* aging - 67:64 */ +- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); +- /* portmask - 54:48 */ +- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); +- /* mac - 47:0 */ +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); +- +- /* load the array into the ARL table */ +- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +-} +- +-static int +-qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and FDB index */ +- reg = QCA8K_ATU_FUNC_BUSY; +- reg |= cmd; +- if (port >= 0) { +- reg |= QCA8K_ATU_FUNC_PORT_EN; +- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); +- } +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_FDB_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_ATU_FUNC_FULL) +- return -1; +- } +- +- return 0; +-} +- +-static int +-qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) +-{ +- int ret; +- +- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); +- if (ret < 0) +- return ret; +- +- return qca8k_fdb_read(priv, fdb); +-} +- +-static int +-qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, +- u16 vid, u8 aging) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static void +-qca8k_fdb_flush(struct qca8k_priv *priv) +-{ +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_fdb_read(priv, &fdb); +- if (ret < 0) +- goto exit; +- +- /* Rule exist. Delete first */ +- if (!fdb.aging) { +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- } +- +- /* Add port to fdb portmask */ +- fdb.port_mask |= port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- /* Rule doesn't exist. Why delete? */ +- if (!fdb.aging) { +- ret = -EINVAL; +- goto exit; +- } +- +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- +- /* Only port in the rule is this port. Don't re insert */ +- if (fdb.port_mask == port_mask) +- goto exit; +- +- /* Remove port from port mask */ +- fdb.port_mask &= ~port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and VLAN index */ +- reg = QCA8K_VTU_FUNC1_BUSY; +- reg |= cmd; +- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_VLAN_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_VTU_FUNC1_FULL) +- return -ENOMEM; +- } +- +- return 0; +-} +- +-static int +-qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) +-{ +- u32 reg; +- int ret; +- +- /* +- We do the right thing with VLAN 0 and treat it as untagged while +- preserving the tag on egress. +- */ +- if (vid == 0) +- return 0; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- if (untagged) +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); +- else +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); +- +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) +-{ +- u32 reg, mask; +- int ret, i; +- bool del; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); +- +- /* Check if we're the last member to be removed */ +- del = true; +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); +- +- if ((reg & mask) != mask) { +- del = false; +- break; +- } +- } +- +- if (del) { +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); +- } else { +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- } +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_mib_init(struct qca8k_priv *priv) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, +- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, +- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | +- QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); +- if (ret) +- goto exit; +- +- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static void +-qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) +-{ +- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; +- +- /* Port 0 and 6 have no internal PHY */ +- if (port > 0 && port < 6) +- mask |= QCA8K_PORT_STATUS_LINK_AUTO; +- +- if (enable) +- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +- else +- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +-} +- +-static int +-qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, +- struct sk_buff *read_skb, u32 *val) +-{ +- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); +- bool ack; +- int ret; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the copy pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) +- return -ETIMEDOUT; +- +- if (!ack) +- return -EINVAL; +- +- *val = mgmt_eth_data->data[0]; +- +- return 0; +-} +- +-static int +-qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, +- int regnum, u16 data) +-{ +- struct sk_buff *write_skb, *clear_skb, *read_skb; +- struct qca8k_mgmt_eth_data *mgmt_eth_data; +- u32 write_val, clear_val = 0, val; +- struct net_device *mgmt_master; +- int ret, ret1; +- bool ack; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- mgmt_eth_data = &priv->mgmt_eth_data; +- +- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum); +- +- if (read) { +- write_val |= QCA8K_MDIO_MASTER_READ; +- } else { +- write_val |= QCA8K_MDIO_MASTER_WRITE; +- write_val |= QCA8K_MDIO_MASTER_DATA(data); +- } +- +- /* Prealloc all the needed skb before the lock */ +- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); +- if (!write_skb) +- return -ENOMEM; +- +- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); +- if (!clear_skb) { +- ret = -ENOMEM; +- goto err_clear_skb; +- } +- +- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, +- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); +- if (!read_skb) { +- ret = -ENOMEM; +- goto err_read_skb; +- } +- +- /* Actually start the request: +- * 1. Send mdio master packet +- * 2. Busy Wait for mdio master command +- * 3. Get the data if we are reading +- * 4. Reset the mdio master (even with error) +- */ +- mutex_lock(&mgmt_eth_data->mutex); +- +- /* Check if mgmt_master is operational */ +- mgmt_master = priv->mgmt_master; +- if (!mgmt_master) { +- mutex_unlock(&mgmt_eth_data->mutex); +- ret = -EINVAL; +- goto err_mgmt_master; +- } +- +- read_skb->dev = mgmt_master; +- clear_skb->dev = mgmt_master; +- write_skb->dev = mgmt_master; +- +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the write pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(write_skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) { +- ret = -ETIMEDOUT; +- kfree_skb(read_skb); +- goto exit; +- } +- +- if (!ack) { +- ret = -EINVAL; +- kfree_skb(read_skb); +- goto exit; +- } +- +- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, +- !(val & QCA8K_MDIO_MASTER_BUSY), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, +- mgmt_eth_data, read_skb, &val); +- +- if (ret < 0 && ret1 < 0) { +- ret = ret1; +- goto exit; +- } +- +- if (read) { +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the read pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(read_skb); +- +- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- ack = mgmt_eth_data->ack; +- +- if (ret <= 0) { +- ret = -ETIMEDOUT; +- goto exit; +- } +- +- if (!ack) { +- ret = -EINVAL; +- goto exit; +- } +- +- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; +- } else { +- kfree_skb(read_skb); +- } +-exit: +- reinit_completion(&mgmt_eth_data->rw_done); +- +- /* Increment seq_num and set it in the clear pkt */ +- mgmt_eth_data->seq++; +- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); +- mgmt_eth_data->ack = false; +- +- dev_queue_xmit(clear_skb); +- +- wait_for_completion_timeout(&mgmt_eth_data->rw_done, +- QCA8K_ETHERNET_TIMEOUT); +- +- mutex_unlock(&mgmt_eth_data->mutex); +- +- return ret; +- +- /* Error handling before lock */ +-err_mgmt_master: +- kfree_skb(read_skb); +-err_read_skb: +- kfree_skb(clear_skb); +-err_clear_skb: +- kfree_skb(write_skb); +- +- return ret; +-} +- +-static u32 +-qca8k_port_to_phy(int port) +-{ +- /* From Andrew Lunn: +- * Port 0 has no internal phy. +- * Port 1 has an internal PHY at MDIO address 0. +- * Port 2 has an internal PHY at MDIO address 1. +- * ... +- * Port 5 has an internal PHY at MDIO address 4. +- * Port 6 has no internal PHY. +- */ +- +- return port - 1; +-} +- +-static int +-qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) +-{ +- u16 r1, r2, page; +- u32 val; +- int ret, ret1; +- +- qca8k_split_addr(reg, &r1, &r2, &page); +- +- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, +- bus, 0x10 | r2, r1, &val); +- +- /* Check if qca8k_read has failed for a different reason +- * before returnting -ETIMEDOUT +- */ +- if (ret < 0 && ret1 < 0) +- return ret1; +- +- return ret; +-} +- +-static int +-qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) +-{ +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum) | +- QCA8K_MDIO_MASTER_DATA(data); +- +- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_BUSY); +- +-exit: +- /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); +- +- mutex_unlock(&bus->mdio_lock); +- +- return ret; +-} +- +-static int +-qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) +-{ +- struct mii_bus *bus = priv->bus; +- u16 r1, r2, page; +- u32 val; +- int ret; +- +- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) +- return -EINVAL; +- +- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | +- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | +- QCA8K_MDIO_MASTER_REG_ADDR(regnum); +- +- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); +- +- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); +- +- ret = qca8k_set_page(priv, page); +- if (ret) +- goto exit; +- +- qca8k_mii_write32(priv, 0x10 | r2, r1, val); +- +- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_BUSY); +- if (ret) +- goto exit; +- +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); +- +-exit: +- /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); +- +- mutex_unlock(&bus->mdio_lock); +- +- if (ret >= 0) +- ret = val & QCA8K_MDIO_MASTER_DATA_MASK; +- +- return ret; +-} +- +-static int +-qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) +-{ +- struct qca8k_priv *priv = slave_bus->priv; +- int ret; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); +- if (!ret) +- return 0; +- +- return qca8k_mdio_write(priv, phy, regnum, data); +-} +- +-static int +-qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) +-{ +- struct qca8k_priv *priv = slave_bus->priv; +- int ret; +- +- /* Use mdio Ethernet when available, fallback to legacy one on error */ +- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); +- if (ret >= 0) +- return ret; +- +- ret = qca8k_mdio_read(priv, phy, regnum); +- +- if (ret < 0) +- return 0xffff; +- +- return ret; +-} +- +-static int +-qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) +-{ +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- return qca8k_internal_mdio_write(slave_bus, port, regnum, data); +-} +- +-static int +-qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) +-{ +- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; +- +- return qca8k_internal_mdio_read(slave_bus, port, regnum); +-} +- +-static int +-qca8k_mdio_register(struct qca8k_priv *priv) +-{ +- struct dsa_switch *ds = priv->ds; +- struct device_node *mdio; +- struct mii_bus *bus; +- +- bus = devm_mdiobus_alloc(ds->dev); +- if (!bus) +- return -ENOMEM; +- +- bus->priv = (void *)priv; +- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", +- ds->dst->index, ds->index); +- bus->parent = ds->dev; +- bus->phy_mask = ~ds->phys_mii_mask; +- ds->slave_mii_bus = bus; +- +- /* Check if the devicetree declare the port:phy mapping */ +- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); +- if (of_device_is_available(mdio)) { +- bus->name = "qca8k slave mii"; +- bus->read = qca8k_internal_mdio_read; +- bus->write = qca8k_internal_mdio_write; +- return devm_of_mdiobus_register(priv->dev, bus, mdio); +- } +- +- /* If a mapping can't be found the legacy mapping is used, +- * using the qca8k_port_to_phy function +- */ +- bus->name = "qca8k-legacy slave mii"; +- bus->read = qca8k_legacy_mdio_read; +- bus->write = qca8k_legacy_mdio_write; +- return devm_mdiobus_register(priv->dev, bus); +-} +- +-static int +-qca8k_setup_mdio_bus(struct qca8k_priv *priv) +-{ +- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; +- struct device_node *ports, *port; +- phy_interface_t mode; +- int err; +- +- ports = of_get_child_by_name(priv->dev->of_node, "ports"); +- if (!ports) +- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); +- +- if (!ports) +- return -EINVAL; +- +- for_each_available_child_of_node(ports, port) { +- err = of_property_read_u32(port, "reg", ®); +- if (err) { +- of_node_put(port); +- of_node_put(ports); +- return err; +- } +- +- if (!dsa_is_user_port(priv->ds, reg)) +- continue; +- +- of_get_phy_mode(port, &mode); +- +- if (of_property_read_bool(port, "phy-handle") && +- mode != PHY_INTERFACE_MODE_INTERNAL) +- external_mdio_mask |= BIT(reg); +- else +- internal_mdio_mask |= BIT(reg); +- } +- +- of_node_put(ports); +- if (!external_mdio_mask && !internal_mdio_mask) { +- dev_err(priv->dev, "no PHYs are defined.\n"); +- return -EINVAL; +- } +- +- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through +- * the MDIO_MASTER register also _disconnects_ the external MDC +- * passthrough to the internal PHYs. It's not possible to use both +- * configurations at the same time! +- * +- * Because this came up during the review process: +- * If the external mdio-bus driver is capable magically disabling +- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's +- * accessors for the time being, it would be possible to pull this +- * off. +- */ +- if (!!external_mdio_mask && !!internal_mdio_mask) { +- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); +- return -EINVAL; +- } +- +- if (external_mdio_mask) { +- /* Make sure to disable the internal mdio bus in cases +- * a dt-overlay and driver reload changed the configuration +- */ +- +- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, +- QCA8K_MDIO_MASTER_EN); +- } +- +- return qca8k_mdio_register(priv); +-} +- +-static int +-qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) +-{ +- u32 mask = 0; +- int ret = 0; +- +- /* SoC specific settings for ipq8064. +- * If more device require this consider adding +- * a dedicated binding. +- */ +- if (of_machine_is_compatible("qcom,ipq8064")) +- mask |= QCA8K_MAC_PWR_RGMII0_1_8V; +- +- /* SoC specific settings for ipq8065 */ +- if (of_machine_is_compatible("qcom,ipq8065")) +- mask |= QCA8K_MAC_PWR_RGMII1_1_8V; +- +- if (mask) { +- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, +- QCA8K_MAC_PWR_RGMII0_1_8V | +- QCA8K_MAC_PWR_RGMII1_1_8V, +- mask); +- } +- +- return ret; +-} +- +-static int qca8k_find_cpu_port(struct dsa_switch *ds) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- /* Find the connected cpu port. Valid port are 0 or 6 */ +- if (dsa_is_cpu_port(ds, 0)) +- return 0; +- +- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); +- +- if (dsa_is_cpu_port(ds, 6)) +- return 6; +- +- return -EINVAL; +-} +- +-static int +-qca8k_setup_of_pws_reg(struct qca8k_priv *priv) +-{ +- const struct qca8k_match_data *data = priv->info; +- struct device_node *node = priv->dev->of_node; +- u32 val = 0; +- int ret; +- +- /* QCA8327 require to set to the correct mode. +- * His bigger brother QCA8328 have the 172 pin layout. +- * Should be applied by default but we set this just to make sure. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- /* Set the correct package of 148 pin for QCA8327 */ +- if (data->reduced_package) +- val |= QCA8327_PWS_PACKAGE148_EN; +- +- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, +- val); +- if (ret) +- return ret; +- } +- +- if (of_property_read_bool(node, "qca,ignore-power-on-sel")) +- val |= QCA8K_PWS_POWER_ON_SEL; +- +- if (of_property_read_bool(node, "qca,led-open-drain")) { +- if (!(val & QCA8K_PWS_POWER_ON_SEL)) { +- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); +- return -EINVAL; +- } +- +- val |= QCA8K_PWS_LED_OPEN_EN_CSR; +- } +- +- return qca8k_rmw(priv, QCA8K_REG_PWS, +- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, +- val); +-} +- +-static int +-qca8k_parse_port_config(struct qca8k_priv *priv) +-{ +- int port, cpu_port_index = -1, ret; +- struct device_node *port_dn; +- phy_interface_t mode; +- struct dsa_port *dp; +- u32 delay; +- +- /* We have 2 CPU port. Check them */ +- for (port = 0; port < QCA8K_NUM_PORTS; port++) { +- /* Skip every other port */ +- if (port != 0 && port != 6) +- continue; +- +- dp = dsa_to_port(priv->ds, port); +- port_dn = dp->dn; +- cpu_port_index++; +- +- if (!of_device_is_available(port_dn)) +- continue; +- +- ret = of_get_phy_mode(port_dn, &mode); +- if (ret) +- continue; +- +- switch (mode) { +- case PHY_INTERFACE_MODE_RGMII: +- case PHY_INTERFACE_MODE_RGMII_ID: +- case PHY_INTERFACE_MODE_RGMII_TXID: +- case PHY_INTERFACE_MODE_RGMII_RXID: +- case PHY_INTERFACE_MODE_SGMII: +- delay = 0; +- +- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) +- /* Switch regs accept value in ns, convert ps to ns */ +- delay = delay / 1000; +- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_TXID) +- delay = 1; +- +- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { +- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); +- delay = 3; +- } +- +- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; +- +- delay = 0; +- +- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) +- /* Switch regs accept value in ns, convert ps to ns */ +- delay = delay / 1000; +- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_RXID) +- delay = 2; +- +- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { +- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); +- delay = 3; +- } +- +- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; +- +- /* Skip sgmii parsing for rgmii* mode */ +- if (mode == PHY_INTERFACE_MODE_RGMII || +- mode == PHY_INTERFACE_MODE_RGMII_ID || +- mode == PHY_INTERFACE_MODE_RGMII_TXID || +- mode == PHY_INTERFACE_MODE_RGMII_RXID) +- break; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) +- priv->ports_config.sgmii_tx_clk_falling_edge = true; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) +- priv->ports_config.sgmii_rx_clk_falling_edge = true; +- +- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { +- priv->ports_config.sgmii_enable_pll = true; +- +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); +- priv->ports_config.sgmii_enable_pll = false; +- } +- +- if (priv->switch_revision < 2) +- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); +- } +- +- break; +- default: +- continue; +- } +- } +- +- return 0; +-} +- +-static int +-qca8k_setup(struct dsa_switch *ds) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int cpu_port, ret, i; +- u32 mask; +- +- cpu_port = qca8k_find_cpu_port(ds); +- if (cpu_port < 0) { +- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); +- return cpu_port; +- } +- +- /* Parse CPU port config to be later used in phy_link mac_config */ +- ret = qca8k_parse_port_config(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_mdio_bus(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_of_pws_reg(priv); +- if (ret) +- return ret; +- +- ret = qca8k_setup_mac_pwr_sel(priv); +- if (ret) +- return ret; +- +- /* Make sure MAC06 is disabled */ +- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, +- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); +- if (ret) { +- dev_err(priv->dev, "failed disabling MAC06 exchange"); +- return ret; +- } +- +- /* Enable CPU Port */ +- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); +- if (ret) { +- dev_err(priv->dev, "failed enabling CPU port"); +- return ret; +- } +- +- /* Enable MIB counters */ +- ret = qca8k_mib_init(priv); +- if (ret) +- dev_warn(priv->dev, "mib init failed"); +- +- /* Initial setup of all ports */ +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- /* Disable forwarding by default on all ports */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, 0); +- if (ret) +- return ret; +- +- /* Enable QCA header mode on all cpu ports */ +- if (dsa_is_cpu_port(ds, i)) { +- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), +- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | +- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); +- if (ret) { +- dev_err(priv->dev, "failed enabling QCA header mode"); +- return ret; +- } +- } +- +- /* Disable MAC by default on all user ports */ +- if (dsa_is_user_port(ds, i)) +- qca8k_port_set_status(priv, i, 0); +- } +- +- /* Forward all unknown frames to CPU port for Linux processing +- * Notice that in multi-cpu config only one port should be set +- * for igmp, unknown, multicast and broadcast packet +- */ +- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | +- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); +- if (ret) +- return ret; +- +- /* Setup connection between CPU port & user ports +- * Configure specific switch configuration for ports +- */ +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- /* CPU port gets connected to all user ports of the switch */ +- if (dsa_is_cpu_port(ds, i)) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); +- if (ret) +- return ret; +- } +- +- /* Individual user ports get connected to CPU port only */ +- if (dsa_is_user_port(ds, i)) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_MEMBER, +- BIT(cpu_port)); +- if (ret) +- return ret; +- +- /* Enable ARP Auto-learning by default */ +- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), +- QCA8K_PORT_LOOKUP_LEARN); +- if (ret) +- return ret; +- +- /* For port based vlans to work we need to set the +- * default egress vid +- */ +- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), +- QCA8K_EGREES_VLAN_PORT_MASK(i), +- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); +- if (ret) +- return ret; +- +- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), +- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | +- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); +- if (ret) +- return ret; +- } +- +- /* The port 5 of the qca8337 have some problem in flood condition. The +- * original legacy driver had some specific buffer and priority settings +- * for the different port suggested by the QCA switch team. Add this +- * missing settings to improve switch stability under load condition. +- * This problem is limited to qca8337 and other qca8k switch are not affected. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8337) { +- switch (i) { +- /* The 2 CPU port and port 5 requires some different +- * priority than any other ports. +- */ +- case 0: +- case 5: +- case 6: +- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | +- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); +- break; +- default: +- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | +- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | +- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); +- } +- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); +- +- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | +- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_WRED_EN; +- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), +- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | +- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | +- QCA8K_PORT_HOL_CTRL1_WRED_EN, +- mask); +- } +- } +- +- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ +- if (priv->switch_id == QCA8K_ID_QCA8327) { +- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | +- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); +- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, +- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | +- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, +- mask); +- } +- +- /* Setup our port MTUs to match power on defaults */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); +- if (ret) +- dev_warn(priv->dev, "failed setting MTU settings"); +- +- /* Flush the FDB table */ +- qca8k_fdb_flush(priv); +- +- /* We don't have interrupts for link changes, so we need to poll */ +- ds->pcs_poll = true; +- +- /* Set min a max ageing value supported */ +- ds->ageing_time_min = 7000; +- ds->ageing_time_max = 458745000; +- +- /* Set max number of LAGs supported */ +- ds->num_lag_ids = QCA8K_NUM_LAGS; +- +- return 0; +-} +- +-static void +-qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, +- u32 reg) +-{ +- u32 delay, val = 0; +- int ret; +- +- /* Delay can be declared in 3 different way. +- * Mode to rgmii and internal-delay standard binding defined +- * rgmii-id or rgmii-tx/rx phy mode set. +- * The parse logic set a delay different than 0 only when one +- * of the 3 different way is used. In all other case delay is +- * not enabled. With ID or TX/RXID delay is enabled and set +- * to the default and recommended value. +- */ +- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { +- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; +- +- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | +- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; +- } +- +- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { +- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; +- +- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; +- } +- +- /* Set RGMII delay based on the selected values */ +- ret = qca8k_rmw(priv, reg, +- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | +- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, +- val); +- if (ret) +- dev_err(priv->dev, "Failed to set internal delay for CPU port%d", +- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); +-} +- +-static void +-qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, +- const struct phylink_link_state *state) +-{ +- struct qca8k_priv *priv = ds->priv; +- int cpu_port_index, ret; +- u32 reg, val; +- +- switch (port) { +- case 0: /* 1st CPU port */ +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII) +- return; +- +- reg = QCA8K_REG_PORT0_PAD_CTRL; +- cpu_port_index = QCA8K_CPU_PORT0; +- break; +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- /* Internal PHY, nothing to do */ +- return; +- case 6: /* 2nd CPU port / external PHY */ +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII && +- state->interface != PHY_INTERFACE_MODE_1000BASEX) +- return; +- +- reg = QCA8K_REG_PORT6_PAD_CTRL; +- cpu_port_index = QCA8K_CPU_PORT6; +- break; +- default: +- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); +- return; +- } +- +- if (port != 6 && phylink_autoneg_inband(mode)) { +- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", +- __func__); +- return; +- } +- +- switch (state->interface) { +- case PHY_INTERFACE_MODE_RGMII: +- case PHY_INTERFACE_MODE_RGMII_ID: +- case PHY_INTERFACE_MODE_RGMII_TXID: +- case PHY_INTERFACE_MODE_RGMII_RXID: +- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); +- +- /* Configure rgmii delay */ +- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); +- +- /* QCA8337 requires to set rgmii rx delay for all ports. +- * This is enabled through PORT5_PAD_CTRL for all ports, +- * rather than individual port registers. +- */ +- if (priv->switch_id == QCA8K_ID_QCA8337) +- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, +- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); +- break; +- case PHY_INTERFACE_MODE_SGMII: +- case PHY_INTERFACE_MODE_1000BASEX: +- /* Enable SGMII on the port */ +- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); +- +- /* Enable/disable SerDes auto-negotiation as necessary */ +- ret = qca8k_read(priv, QCA8K_REG_PWS, &val); +- if (ret) +- return; +- if (phylink_autoneg_inband(mode)) +- val &= ~QCA8K_PWS_SERDES_AEN_DIS; +- else +- val |= QCA8K_PWS_SERDES_AEN_DIS; +- qca8k_write(priv, QCA8K_REG_PWS, val); +- +- /* Configure the SGMII parameters */ +- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); +- if (ret) +- return; +- +- val |= QCA8K_SGMII_EN_SD; +- +- if (priv->ports_config.sgmii_enable_pll) +- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | +- QCA8K_SGMII_EN_TX; +- +- if (dsa_is_cpu_port(ds, port)) { +- /* CPU port, we're talking to the CPU MAC, be a PHY */ +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_PHY; +- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_MAC; +- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { +- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; +- val |= QCA8K_SGMII_MODE_CTRL_BASEX; +- } +- +- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); +- +- /* From original code is reported port instability as SGMII also +- * require delay set. Apply advised values here or take them from DT. +- */ +- if (state->interface == PHY_INTERFACE_MODE_SGMII) +- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); +- +- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and +- * falling edge is set writing in the PORT0 PAD reg +- */ +- if (priv->switch_id == QCA8K_ID_QCA8327 || +- priv->switch_id == QCA8K_ID_QCA8337) +- reg = QCA8K_REG_PORT0_PAD_CTRL; +- +- val = 0; +- +- /* SGMII Clock phase configuration */ +- if (priv->ports_config.sgmii_rx_clk_falling_edge) +- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; +- +- if (priv->ports_config.sgmii_tx_clk_falling_edge) +- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; +- +- if (val) +- ret = qca8k_rmw(priv, reg, +- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | +- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, +- val); +- +- break; +- default: +- dev_err(ds->dev, "xMII mode %s not supported for port %d\n", +- phy_modes(state->interface), port); +- return; +- } +-} +- +-static void +-qca8k_phylink_validate(struct dsa_switch *ds, int port, +- unsigned long *supported, +- struct phylink_link_state *state) +-{ +- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; +- +- switch (port) { +- case 0: /* 1st CPU port */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII) +- goto unsupported; +- break; +- case 1: +- case 2: +- case 3: +- case 4: +- case 5: +- /* Internal PHY */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_GMII && +- state->interface != PHY_INTERFACE_MODE_INTERNAL) +- goto unsupported; +- break; +- case 6: /* 2nd CPU port / external PHY */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_RGMII_ID && +- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && +- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && +- state->interface != PHY_INTERFACE_MODE_SGMII && +- state->interface != PHY_INTERFACE_MODE_1000BASEX) +- goto unsupported; +- break; +- default: +-unsupported: +- linkmode_zero(supported); +- return; +- } +- +- phylink_set_port_modes(mask); +- phylink_set(mask, Autoneg); +- +- phylink_set(mask, 1000baseT_Full); +- phylink_set(mask, 10baseT_Half); +- phylink_set(mask, 10baseT_Full); +- phylink_set(mask, 100baseT_Half); +- phylink_set(mask, 100baseT_Full); +- +- if (state->interface == PHY_INTERFACE_MODE_1000BASEX) +- phylink_set(mask, 1000baseX_Full); +- +- phylink_set(mask, Pause); +- phylink_set(mask, Asym_Pause); +- +- linkmode_and(supported, supported, mask); +- linkmode_and(state->advertising, state->advertising, mask); +-} +- +-static int +-qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, +- struct phylink_link_state *state) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg; +- int ret; +- +- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); +- if (ret < 0) +- return ret; +- +- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); +- state->an_complete = state->link; +- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); +- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : +- DUPLEX_HALF; +- +- switch (reg & QCA8K_PORT_STATUS_SPEED) { +- case QCA8K_PORT_STATUS_SPEED_10: +- state->speed = SPEED_10; +- break; +- case QCA8K_PORT_STATUS_SPEED_100: +- state->speed = SPEED_100; +- break; +- case QCA8K_PORT_STATUS_SPEED_1000: +- state->speed = SPEED_1000; +- break; +- default: +- state->speed = SPEED_UNKNOWN; +- break; +- } +- +- state->pause = MLO_PAUSE_NONE; +- if (reg & QCA8K_PORT_STATUS_RXFLOW) +- state->pause |= MLO_PAUSE_RX; +- if (reg & QCA8K_PORT_STATUS_TXFLOW) +- state->pause |= MLO_PAUSE_TX; +- +- return 1; +-} +- +-static void +-qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, +- phy_interface_t interface) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- qca8k_port_set_status(priv, port, 0); +-} +- +-static void +-qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, +- phy_interface_t interface, struct phy_device *phydev, +- int speed, int duplex, bool tx_pause, bool rx_pause) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg; +- +- if (phylink_autoneg_inband(mode)) { +- reg = QCA8K_PORT_STATUS_LINK_AUTO; +- } else { +- switch (speed) { +- case SPEED_10: +- reg = QCA8K_PORT_STATUS_SPEED_10; +- break; +- case SPEED_100: +- reg = QCA8K_PORT_STATUS_SPEED_100; +- break; +- case SPEED_1000: +- reg = QCA8K_PORT_STATUS_SPEED_1000; +- break; +- default: +- reg = QCA8K_PORT_STATUS_LINK_AUTO; +- break; +- } +- +- if (duplex == DUPLEX_FULL) +- reg |= QCA8K_PORT_STATUS_DUPLEX; +- +- if (rx_pause || dsa_is_cpu_port(ds, port)) +- reg |= QCA8K_PORT_STATUS_RXFLOW; +- +- if (tx_pause || dsa_is_cpu_port(ds, port)) +- reg |= QCA8K_PORT_STATUS_TXFLOW; +- } +- +- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; +- +- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); +-} +- +-static void +-qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) +-{ +- struct qca8k_priv *priv = ds->priv; +- int i; +- +- if (stringset != ETH_SS_STATS) +- return; +- +- for (i = 0; i < priv->info->mib_count; i++) +- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, +- ETH_GSTRING_LEN); +-} +- +-static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) +-{ +- struct qca8k_mib_eth_data *mib_eth_data; +- struct qca8k_priv *priv = ds->priv; +- const struct qca8k_mib_desc *mib; +- struct mib_ethhdr *mib_ethhdr; +- int i, mib_len, offset = 0; +- u64 *data; +- u8 port; +- +- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); +- mib_eth_data = &priv->mib_eth_data; +- +- /* The switch autocast every port. Ignore other packet and +- * parse only the requested one. +- */ +- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); +- if (port != mib_eth_data->req_port) +- goto exit; +- +- data = mib_eth_data->data; +- +- for (i = 0; i < priv->info->mib_count; i++) { +- mib = &ar8327_mib[i]; +- +- /* First 3 mib are present in the skb head */ +- if (i < 3) { +- data[i] = mib_ethhdr->data[i]; +- continue; +- } +- +- mib_len = sizeof(uint32_t); +- +- /* Some mib are 64 bit wide */ +- if (mib->size == 2) +- mib_len = sizeof(uint64_t); +- +- /* Copy the mib value from packet to the */ +- memcpy(data + i, skb->data + offset, mib_len); +- +- /* Set the offset for the next mib */ +- offset += mib_len; +- } +- +-exit: +- /* Complete on receiving all the mib packet */ +- if (refcount_dec_and_test(&mib_eth_data->port_parsed)) +- complete(&mib_eth_data->rw_done); +-} +- +-static int +-qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) +-{ +- struct dsa_port *dp = dsa_to_port(ds, port); +- struct qca8k_mib_eth_data *mib_eth_data; +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- mib_eth_data = &priv->mib_eth_data; +- +- mutex_lock(&mib_eth_data->mutex); +- +- reinit_completion(&mib_eth_data->rw_done); +- +- mib_eth_data->req_port = dp->index; +- mib_eth_data->data = data; +- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); +- +- mutex_lock(&priv->reg_mutex); +- +- /* Send mib autocast request */ +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, +- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, +- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | +- QCA8K_MIB_BUSY); +- +- mutex_unlock(&priv->reg_mutex); +- +- if (ret) +- goto exit; +- +- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); +- +-exit: +- mutex_unlock(&mib_eth_data->mutex); +- +- return ret; +-} +- +-static void +-qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, +- uint64_t *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- const struct qca8k_mib_desc *mib; +- u32 reg, i, val; +- u32 hi = 0; +- int ret; +- +- if (priv->mgmt_master && priv->info->ops->autocast_mib && +- priv->info->ops->autocast_mib(ds, port, data) > 0) +- return; +- +- for (i = 0; i < priv->info->mib_count; i++) { +- mib = &ar8327_mib[i]; +- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; +- +- ret = qca8k_read(priv, reg, &val); +- if (ret < 0) +- continue; +- +- if (mib->size == 2) { +- ret = qca8k_read(priv, reg + 4, &hi); +- if (ret < 0) +- continue; +- } +- +- data[i] = val; +- if (mib->size == 2) +- data[i] |= (u64)hi << 32; +- } +-} +- +-static int +-qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- if (sset != ETH_SS_STATS) +- return 0; +- +- return priv->info->mib_count; +-} +- +-static int +-qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); +- u32 reg; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); +- if (ret < 0) +- goto exit; +- +- if (eee->eee_enabled) +- reg |= lpi_en; +- else +- reg &= ~lpi_en; +- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +-{ +- /* Nothing to do on the port's MAC */ +- return 0; +-} +- +-static void +-qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 stp_state; +- +- switch (state) { +- case BR_STATE_DISABLED: +- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; +- break; +- case BR_STATE_BLOCKING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; +- break; +- case BR_STATE_LISTENING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; +- break; +- case BR_STATE_LEARNING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; +- break; +- case BR_STATE_FORWARDING: +- default: +- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; +- break; +- } +- +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); +-} +- +-static int +-qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int port_mask, cpu_port; +- int i, ret; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- port_mask = BIT(cpu_port); +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Add this port to the portvlan mask of the other ports +- * in the bridge +- */ +- ret = regmap_set_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- if (ret) +- return ret; +- if (i != port) +- port_mask |= BIT(i); +- } +- +- /* Add all other ports to this ports portvlan mask */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, port_mask); +- +- return ret; +-} +- +-static void +-qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int cpu_port, i; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Remove this port to the portvlan mask of the other ports +- * in the bridge +- */ +- regmap_clear_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- } +- +- /* Set the cpu port to be the only one in the portvlan mask of +- * this port +- */ +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); +-} +- +-static void +-qca8k_port_fast_age(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +-{ +- struct qca8k_priv *priv = ds->priv; +- unsigned int secs = msecs / 1000; +- u32 val; +- +- /* AGE_TIME reg is set in 7s step */ +- val = secs / 7; +- +- /* Handle case with 0 as val to NOT disable +- * learning +- */ +- if (!val) +- val = 1; +- +- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, +- QCA8K_ATU_AGE_TIME(val)); +-} +- +-static int +-qca8k_port_enable(struct dsa_switch *ds, int port, +- struct phy_device *phy) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 1); +- priv->port_enabled_map |= BIT(port); +- +- if (dsa_is_user_port(ds, port)) +- phy_support_asym_pause(phy); +- +- return 0; +-} +- +-static void +-qca8k_port_disable(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 0); +- priv->port_enabled_map &= ~BIT(port); +-} +- +-static int +-qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- /* We have only have a general MTU setting. +- * DSA always set the CPU port's MTU to the largest MTU of the slave +- * ports. +- * Setting MTU just for the CPU port is sufficient to correctly set a +- * value for every port. +- */ +- if (!dsa_is_cpu_port(ds, port)) +- return 0; +- +- /* To change the MAX_FRAME_SIZE the cpu ports must be off or +- * the switch panics. +- * Turn off both cpu ports before applying the new value to prevent +- * this. +- */ +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 0); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 0); +- +- /* Include L2 header / FCS length */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); +- +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 1); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 1); +- +- return ret; +-} +- +-static int +-qca8k_port_max_mtu(struct dsa_switch *ds, int port) +-{ +- return QCA8K_MAX_MTU; +-} +- +-static int +-qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, +- u16 port_mask, u16 vid) +-{ +- /* Set the vid to the port vlan id if no vid is set */ +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_add(priv, addr, port_mask, vid, +- QCA8K_ATU_STATUS_STATIC); +-} +- +-static int +-qca8k_port_fdb_add(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_del(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_del(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_dump(struct dsa_switch *ds, int port, +- dsa_fdb_dump_cb_t *cb, void *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- struct qca8k_fdb _fdb = { 0 }; +- int cnt = QCA8K_NUM_FDB_RECORDS; +- bool is_static; +- int ret = 0; +- +- mutex_lock(&priv->reg_mutex); +- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { +- if (!_fdb.aging) +- break; +- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); +- ret = cb(_fdb.mac, _fdb.vid, is_static, data); +- if (ret) +- break; +- } +- mutex_unlock(&priv->reg_mutex); +- +- return 0; +-} +- +-static int +-qca8k_port_mdb_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); +-} +- +-static int +-qca8k_port_mdb_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); +-} +- +-static int +-qca8k_port_mirror_add(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror, +- bool ingress) +-{ +- struct qca8k_priv *priv = ds->priv; +- int monitor_port, ret; +- u32 reg, val; +- +- /* Check for existent entry */ +- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) +- return -EEXIST; +- +- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); +- if (ret) +- return ret; +- +- /* QCA83xx can have only one port set to mirror mode. +- * Check that the correct port is requested and return error otherwise. +- * When no mirror port is set, the values is set to 0xF +- */ +- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) +- return -EEXIST; +- +- /* Set the monitor port */ +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, +- mirror->to_local_port); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- return ret; +- +- if (ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_update_bits(priv->regmap, reg, val, val); +- if (ret) +- return ret; +- +- /* Track mirror port for tx and rx to decide when the +- * mirror port has to be disabled. +- */ +- if (ingress) +- priv->mirror_rx |= BIT(port); +- else +- priv->mirror_tx |= BIT(port); +- +- return 0; +-} +- +-static void +-qca8k_port_mirror_del(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg, val; +- int ret; +- +- if (mirror->ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_clear_bits(priv->regmap, reg, val); +- if (ret) +- goto err; +- +- if (mirror->ingress) +- priv->mirror_rx &= ~BIT(port); +- else +- priv->mirror_tx &= ~BIT(port); +- +- /* No port set to send packet to mirror port. Disable mirror port */ +- if (!priv->mirror_rx && !priv->mirror_tx) { +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- goto err; +- } +-err: +- dev_err(priv->dev, "Failed to del mirror port from %d", port); +-} +- +-static int +-qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, +- struct netlink_ext_ack *extack) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- if (vlan_filtering) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); +- } else { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan, +- struct netlink_ext_ack *extack) +-{ +- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); +- if (ret) { +- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); +- return ret; +- } +- +- if (pvid) { +- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), +- QCA8K_EGREES_VLAN_PORT_MASK(port), +- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); +- if (ret) +- return ret; +- +- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), +- QCA8K_PORT_VLAN_CVID(vlan->vid) | +- QCA8K_PORT_VLAN_SVID(vlan->vid)); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_del(priv, port, vlan->vid); +- if (ret) +- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); +- +- return ret; +-} +- +-static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- /* Communicate to the phy internal driver the switch revision. +- * Based on the switch revision different values needs to be +- * set to the dbg and mmd reg on the phy. +- * The first 2 bit are used to communicate the switch revision +- * to the phy driver. +- */ +- if (port > 0 && port < 6) +- return priv->switch_revision; +- +- return 0; +-} +- +-static enum dsa_tag_protocol +-qca8k_get_tag_protocol(struct dsa_switch *ds, int port, +- enum dsa_tag_protocol mp) +-{ +- return DSA_TAG_PROTO_QCA; +-} +- +-static bool +-qca8k_lag_can_offload(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct dsa_port *dp; +- int id, members = 0; +- +- id = dsa_lag_id(ds->dst, lag); +- if (id < 0 || id >= ds->num_lag_ids) +- return false; +- +- dsa_lag_foreach_port(dp, ds->dst, lag) +- /* Includes the port joining the LAG */ +- members++; +- +- if (members > QCA8K_NUM_PORTS_FOR_LAG) +- return false; +- +- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) +- return false; +- +- if (info->hash_type != NETDEV_LAG_HASH_L2 && +- info->hash_type != NETDEV_LAG_HASH_L23) +- return false; +- +- return true; +-} +- +-static int +-qca8k_lag_setup_hash(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct qca8k_priv *priv = ds->priv; +- bool unique_lag = true; +- u32 hash = 0; +- int i, id; +- +- id = dsa_lag_id(ds->dst, lag); +- +- switch (info->hash_type) { +- case NETDEV_LAG_HASH_L23: +- hash |= QCA8K_TRUNK_HASH_SIP_EN; +- hash |= QCA8K_TRUNK_HASH_DIP_EN; +- fallthrough; +- case NETDEV_LAG_HASH_L2: +- hash |= QCA8K_TRUNK_HASH_SA_EN; +- hash |= QCA8K_TRUNK_HASH_DA_EN; +- break; +- default: /* We should NEVER reach this */ +- return -EOPNOTSUPP; +- } +- +- /* Check if we are the unique configured LAG */ +- dsa_lags_foreach_id(i, ds->dst) +- if (i != id && dsa_lag_dev(ds->dst, i)) { +- unique_lag = false; +- break; +- } +- +- /* Hash Mode is global. Make sure the same Hash Mode +- * is set to all the 4 possible lag. +- * If we are the unique LAG we can set whatever hash +- * mode we want. +- * To change hash mode it's needed to remove all LAG +- * and change the mode with the latest. +- */ +- if (unique_lag) { +- priv->lag_hash_mode = hash; +- } else if (priv->lag_hash_mode != hash) { +- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); +- return -EOPNOTSUPP; +- } +- +- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, +- QCA8K_TRUNK_HASH_MASK, hash); +-} +- +-static int +-qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, +- struct net_device *lag, bool delete) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret, id, i; +- u32 val; +- +- id = dsa_lag_id(ds->dst, lag); +- +- /* Read current port member */ +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); +- if (ret) +- return ret; +- +- /* Shift val to the correct trunk */ +- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); +- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; +- if (delete) +- val &= ~BIT(port); +- else +- val |= BIT(port); +- +- /* Update port member. With empty portmap disable trunk */ +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, +- QCA8K_REG_GOL_TRUNK_MEMBER(id) | +- QCA8K_REG_GOL_TRUNK_EN(id), +- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | +- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); +- +- /* Search empty member if adding or port on deleting */ +- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); +- if (ret) +- return ret; +- +- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; +- +- if (delete) { +- /* If port flagged to be disabled assume this member is +- * empty +- */ +- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; +- if (val != port) +- continue; +- } else { +- /* If port flagged to be enabled assume this member is +- * already set +- */ +- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- } +- +- /* We have found the member to add/remove */ +- break; +- } +- +- /* Set port in the correct port mask or disable port if in delete mode */ +- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), +- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | +- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); +-} +- +-static int +-qca8k_port_lag_join(struct dsa_switch *ds, int port, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- int ret; +- +- if (!qca8k_lag_can_offload(ds, lag, info)) +- return -EOPNOTSUPP; +- +- ret = qca8k_lag_setup_hash(ds, lag, info); +- if (ret) +- return ret; +- +- return qca8k_lag_refresh_portmap(ds, port, lag, false); +-} +- +-static int +-qca8k_port_lag_leave(struct dsa_switch *ds, int port, +- struct net_device *lag) +-{ +- return qca8k_lag_refresh_portmap(ds, port, lag, true); +-} +- +-static void +-qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, +- bool operational) +-{ +- struct dsa_port *dp = master->dsa_ptr; +- struct qca8k_priv *priv = ds->priv; +- +- /* Ethernet MIB/MDIO is only supported for CPU port 0 */ +- if (dp->index != 0) +- return; +- +- mutex_lock(&priv->mgmt_eth_data.mutex); +- mutex_lock(&priv->mib_eth_data.mutex); +- +- priv->mgmt_master = operational ? (struct net_device *)master : NULL; +- +- mutex_unlock(&priv->mib_eth_data.mutex); +- mutex_unlock(&priv->mgmt_eth_data.mutex); +-} +- +-static int qca8k_connect_tag_protocol(struct dsa_switch *ds, +- enum dsa_tag_protocol proto) +-{ +- struct qca_tagger_data *tagger_data; +- +- switch (proto) { +- case DSA_TAG_PROTO_QCA: +- tagger_data = ds->tagger_data; +- +- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; +- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; +- +- break; +- default: +- return -EOPNOTSUPP; +- } +- +- return 0; +-} +- +-static const struct dsa_switch_ops qca8k_switch_ops = { +- .get_tag_protocol = qca8k_get_tag_protocol, +- .setup = qca8k_setup, +- .get_strings = qca8k_get_strings, +- .get_ethtool_stats = qca8k_get_ethtool_stats, +- .get_sset_count = qca8k_get_sset_count, +- .set_ageing_time = qca8k_set_ageing_time, +- .get_mac_eee = qca8k_get_mac_eee, +- .set_mac_eee = qca8k_set_mac_eee, +- .port_enable = qca8k_port_enable, +- .port_disable = qca8k_port_disable, +- .port_change_mtu = qca8k_port_change_mtu, +- .port_max_mtu = qca8k_port_max_mtu, +- .port_stp_state_set = qca8k_port_stp_state_set, +- .port_bridge_join = qca8k_port_bridge_join, +- .port_bridge_leave = qca8k_port_bridge_leave, +- .port_fast_age = qca8k_port_fast_age, +- .port_fdb_add = qca8k_port_fdb_add, +- .port_fdb_del = qca8k_port_fdb_del, +- .port_fdb_dump = qca8k_port_fdb_dump, +- .port_mdb_add = qca8k_port_mdb_add, +- .port_mdb_del = qca8k_port_mdb_del, +- .port_mirror_add = qca8k_port_mirror_add, +- .port_mirror_del = qca8k_port_mirror_del, +- .port_vlan_filtering = qca8k_port_vlan_filtering, +- .port_vlan_add = qca8k_port_vlan_add, +- .port_vlan_del = qca8k_port_vlan_del, +- .phylink_validate = qca8k_phylink_validate, +- .phylink_mac_link_state = qca8k_phylink_mac_link_state, +- .phylink_mac_config = qca8k_phylink_mac_config, +- .phylink_mac_link_down = qca8k_phylink_mac_link_down, +- .phylink_mac_link_up = qca8k_phylink_mac_link_up, +- .get_phy_flags = qca8k_get_phy_flags, +- .port_lag_join = qca8k_port_lag_join, +- .port_lag_leave = qca8k_port_lag_leave, +- .master_state_change = qca8k_master_change, +- .connect_tag_protocol = qca8k_connect_tag_protocol, +-}; +- +-static int qca8k_read_switch_id(struct qca8k_priv *priv) +-{ +- u32 val; +- u8 id; +- int ret; +- +- if (!priv->info) +- return -ENODEV; +- +- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); +- if (ret < 0) +- return -ENODEV; +- +- id = QCA8K_MASK_CTRL_DEVICE_ID(val); +- if (id != priv->info->id) { +- dev_err(priv->dev, +- "Switch id detected %x but expected %x", +- id, priv->info->id); +- return -ENODEV; +- } +- +- priv->switch_id = id; +- +- /* Save revision to communicate to the internal PHY driver */ +- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); +- +- return 0; +-} +- +-static int +-qca8k_sw_probe(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv; +- int ret; +- +- /* allocate the private data struct so that we can probe the switches +- * ID register +- */ +- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- +- priv->info = of_device_get_match_data(priv->dev); +- priv->bus = mdiodev->bus; +- priv->dev = &mdiodev->dev; +- +- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", +- GPIOD_ASIS); +- if (IS_ERR(priv->reset_gpio)) +- return PTR_ERR(priv->reset_gpio); +- +- if (priv->reset_gpio) { +- gpiod_set_value_cansleep(priv->reset_gpio, 1); +- /* The active low duration must be greater than 10 ms +- * and checkpatch.pl wants 20 ms. +- */ +- msleep(20); +- gpiod_set_value_cansleep(priv->reset_gpio, 0); +- } +- +- /* Start by setting up the register mapping */ +- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, +- &qca8k_regmap_config); +- if (IS_ERR(priv->regmap)) { +- dev_err(priv->dev, "regmap initialization failed"); +- return PTR_ERR(priv->regmap); +- } +- +- priv->mdio_cache.page = 0xffff; +- priv->mdio_cache.lo = 0xffff; +- priv->mdio_cache.hi = 0xffff; +- +- /* Check the detected switch id */ +- ret = qca8k_read_switch_id(priv); +- if (ret) +- return ret; +- +- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); +- if (!priv->ds) +- return -ENOMEM; +- +- mutex_init(&priv->mgmt_eth_data.mutex); +- init_completion(&priv->mgmt_eth_data.rw_done); +- +- mutex_init(&priv->mib_eth_data.mutex); +- init_completion(&priv->mib_eth_data.rw_done); +- +- priv->ds->dev = &mdiodev->dev; +- priv->ds->num_ports = QCA8K_NUM_PORTS; +- priv->ds->priv = priv; +- priv->ds->ops = &qca8k_switch_ops; +- mutex_init(&priv->reg_mutex); +- dev_set_drvdata(&mdiodev->dev, priv); +- +- return dsa_register_switch(priv->ds); +-} +- +-static void +-qca8k_sw_remove(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); +- int i; +- +- if (!priv) +- return; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) +- qca8k_port_set_status(priv, i, 0); +- +- dsa_unregister_switch(priv->ds); +- +- dev_set_drvdata(&mdiodev->dev, NULL); +-} +- +-static void qca8k_sw_shutdown(struct mdio_device *mdiodev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); +- +- if (!priv) +- return; +- +- dsa_switch_shutdown(priv->ds); +- +- dev_set_drvdata(&mdiodev->dev, NULL); +-} +- +-#ifdef CONFIG_PM_SLEEP +-static void +-qca8k_set_pm(struct qca8k_priv *priv, int enable) +-{ +- int port; +- +- for (port = 0; port < QCA8K_NUM_PORTS; port++) { +- /* Do not enable on resume if the port was +- * disabled before. +- */ +- if (!(priv->port_enabled_map & BIT(port))) +- continue; +- +- qca8k_port_set_status(priv, port, enable); +- } +-} +- +-static int qca8k_suspend(struct device *dev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(dev); +- +- qca8k_set_pm(priv, 0); +- +- return dsa_switch_suspend(priv->ds); +-} +- +-static int qca8k_resume(struct device *dev) +-{ +- struct qca8k_priv *priv = dev_get_drvdata(dev); +- +- qca8k_set_pm(priv, 1); +- +- return dsa_switch_resume(priv->ds); +-} +-#endif /* CONFIG_PM_SLEEP */ +- +-static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, +- qca8k_suspend, qca8k_resume); +- +-static const struct qca8k_info_ops qca8xxx_ops = { +- .autocast_mib = qca8k_get_ethtool_stats_eth, +-}; +- +-static const struct qca8k_match_data qca8327 = { +- .id = QCA8K_ID_QCA8327, +- .reduced_package = true, +- .mib_count = QCA8K_QCA832X_MIB_COUNT, +- .ops = &qca8xxx_ops, +-}; +- +-static const struct qca8k_match_data qca8328 = { +- .id = QCA8K_ID_QCA8327, +- .mib_count = QCA8K_QCA832X_MIB_COUNT, +- .ops = &qca8xxx_ops, +-}; +- +-static const struct qca8k_match_data qca833x = { +- .id = QCA8K_ID_QCA8337, +- .mib_count = QCA8K_QCA833X_MIB_COUNT, +- .ops = &qca8xxx_ops, +-}; +- +-static const struct of_device_id qca8k_of_match[] = { +- { .compatible = "qca,qca8327", .data = &qca8327 }, +- { .compatible = "qca,qca8328", .data = &qca8328 }, +- { .compatible = "qca,qca8334", .data = &qca833x }, +- { .compatible = "qca,qca8337", .data = &qca833x }, +- { /* sentinel */ }, +-}; +- +-static struct mdio_driver qca8kmdio_driver = { +- .probe = qca8k_sw_probe, +- .remove = qca8k_sw_remove, +- .shutdown = qca8k_sw_shutdown, +- .mdiodrv.driver = { +- .name = "qca8k", +- .of_match_table = qca8k_of_match, +- .pm = &qca8k_pm_ops, +- }, +-}; +- +-mdio_module_driver(qca8kmdio_driver); +- +-MODULE_AUTHOR("Mathieu Olivari, John Crispin "); +-MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); +-MODULE_LICENSE("GPL v2"); +-MODULE_ALIAS("platform:qca8k"); +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -0,0 +1,3186 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2009 Felix Fietkau ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2016 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qca8k.h" ++ ++static void ++qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) ++{ ++ regaddr >>= 1; ++ *r1 = regaddr & 0x1e; ++ ++ regaddr >>= 5; ++ *r2 = regaddr & 0x7; ++ ++ regaddr >>= 3; ++ *page = regaddr & 0x3ff; ++} ++ ++static int ++qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) ++{ ++ u16 *cached_lo = &priv->mdio_cache.lo; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (lo == *cached_lo) ++ return 0; ++ ++ ret = bus->write(bus, phy_id, regnum, lo); ++ if (ret < 0) ++ dev_err_ratelimited(&bus->dev, ++ "failed to write qca8k 32bit lo register\n"); ++ ++ *cached_lo = lo; ++ return 0; ++} ++ ++static int ++qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) ++{ ++ u16 *cached_hi = &priv->mdio_cache.hi; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (hi == *cached_hi) ++ return 0; ++ ++ ret = bus->write(bus, phy_id, regnum, hi); ++ if (ret < 0) ++ dev_err_ratelimited(&bus->dev, ++ "failed to write qca8k 32bit hi register\n"); ++ ++ *cached_hi = hi; ++ return 0; ++} ++ ++static int ++qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) ++{ ++ int ret; ++ ++ ret = bus->read(bus, phy_id, regnum); ++ if (ret >= 0) { ++ *val = ret; ++ ret = bus->read(bus, phy_id, regnum + 1); ++ *val |= ret << 16; ++ } ++ ++ if (ret < 0) { ++ dev_err_ratelimited(&bus->dev, ++ "failed to read qca8k 32bit register\n"); ++ *val = 0; ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void ++qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) ++{ ++ u16 lo, hi; ++ int ret; ++ ++ lo = val & 0xffff; ++ hi = (u16)(val >> 16); ++ ++ ret = qca8k_set_lo(priv, phy_id, regnum, lo); ++ if (ret >= 0) ++ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); ++} ++ ++static int ++qca8k_set_page(struct qca8k_priv *priv, u16 page) ++{ ++ u16 *cached_page = &priv->mdio_cache.page; ++ struct mii_bus *bus = priv->bus; ++ int ret; ++ ++ if (page == *cached_page) ++ return 0; ++ ++ ret = bus->write(bus, 0x18, 0, page); ++ if (ret < 0) { ++ dev_err_ratelimited(&bus->dev, ++ "failed to set qca8k page\n"); ++ return ret; ++ } ++ ++ *cached_page = page; ++ usleep_range(1000, 2000); ++ return 0; ++} ++ ++static int ++qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) ++{ ++ return regmap_read(priv->regmap, reg, val); ++} ++ ++static int ++qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) ++{ ++ return regmap_write(priv->regmap, reg, val); ++} ++ ++static int ++qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) ++{ ++ return regmap_update_bits(priv->regmap, reg, mask, write_val); ++} ++ ++static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u8 len, cmd; ++ ++ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); ++ mgmt_eth_data = &priv->mgmt_eth_data; ++ ++ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); ++ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); ++ ++ /* Make sure the seq match the requested packet */ ++ if (mgmt_ethhdr->seq == mgmt_eth_data->seq) ++ mgmt_eth_data->ack = true; ++ ++ if (cmd == MDIO_READ) { ++ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; ++ ++ /* Get the rest of the 12 byte of data. ++ * The read/write function will extract the requested data. ++ */ ++ if (len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(mgmt_eth_data->data + 1, skb->data, ++ QCA_HDR_MGMT_DATA2_LEN); ++ } ++ ++ complete(&mgmt_eth_data->rw_done); ++} ++ ++static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, ++ int priority, unsigned int len) ++{ ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ unsigned int real_len; ++ struct sk_buff *skb; ++ u32 *data2; ++ u16 hdr; ++ ++ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); ++ if (!skb) ++ return NULL; ++ ++ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte ++ * Actually for some reason the steps are: ++ * 0: nothing ++ * 1-4: first 4 byte ++ * 5-6: first 12 byte ++ * 7-15: all 16 byte ++ */ ++ if (len == 16) ++ real_len = 15; ++ else ++ real_len = len; ++ ++ skb_reset_mac_header(skb); ++ skb_set_network_header(skb, skb->len); ++ ++ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); ++ ++ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); ++ hdr |= QCA_HDR_XMIT_FROM_CPU; ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); ++ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); ++ ++ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); ++ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, ++ QCA_HDR_MGMT_CHECK_CODE_VAL); ++ ++ if (cmd == MDIO_WRITE) ++ mgmt_ethhdr->mdio_data = *val; ++ ++ mgmt_ethhdr->hdr = htons(hdr); ++ ++ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); ++ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ return skb; ++} ++ ++static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) ++{ ++ struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ ++ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; ++ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); ++} ++ ++static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; ++ struct sk_buff *skb; ++ bool ack; ++ int ret; ++ ++ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, ++ QCA8K_ETHERNET_MDIO_PRIORITY, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check mgmt_master if is operational */ ++ if (!priv->mgmt_master) { ++ kfree_skb(skb); ++ mutex_unlock(&mgmt_eth_data->mutex); ++ return -EINVAL; ++ } ++ ++ skb->dev = priv->mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the mdio pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); ++ ++ *val = mgmt_eth_data->data[0]; ++ if (len > QCA_HDR_MGMT_DATA1_LEN) ++ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ ack = mgmt_eth_data->ack; ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; ++ struct sk_buff *skb; ++ bool ack; ++ int ret; ++ ++ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, ++ QCA8K_ETHERNET_MDIO_PRIORITY, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check mgmt_master if is operational */ ++ if (!priv->mgmt_master) { ++ kfree_skb(skb); ++ mutex_unlock(&mgmt_eth_data->mutex); ++ return -EINVAL; ++ } ++ ++ skb->dev = priv->mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the mdio pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); ++ ++ ack = mgmt_eth_data->ack; ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int ++qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) ++{ ++ u32 val = 0; ++ int ret; ++ ++ ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); ++ if (ret) ++ return ret; ++ ++ val &= ~mask; ++ val |= write_val; ++ ++ return qca8k_write_eth(priv, reg, &val, sizeof(val)); ++} ++ ++static int ++qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ ++ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ u32 tmp; ++ ++ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ tmp = val[i]; ++ ++ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ int ret; ++ ++ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ return ret; ++} ++ ++static int ++qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ int ret; ++ ++ if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ return ret; ++} ++ ++static int ++qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) ++ return 0; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); ++ if (ret < 0) ++ goto exit; ++ ++ val &= ~mask; ++ val |= write_val; ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++exit: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static const struct regmap_range qca8k_readable_ranges[] = { ++ regmap_reg_range(0x0000, 0x00e4), /* Global control */ ++ regmap_reg_range(0x0100, 0x0168), /* EEE control */ ++ regmap_reg_range(0x0200, 0x0270), /* Parser control */ ++ regmap_reg_range(0x0400, 0x0454), /* ACL */ ++ regmap_reg_range(0x0600, 0x0718), /* Lookup */ ++ regmap_reg_range(0x0800, 0x0b70), /* QM */ ++ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ ++ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ ++ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ ++ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ ++ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ ++ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ ++ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ ++ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ ++ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ ++ ++}; ++ ++static const struct regmap_access_table qca8k_readable_table = { ++ .yes_ranges = qca8k_readable_ranges, ++ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), ++}; ++ ++static struct regmap_config qca8k_regmap_config = { ++ .reg_bits = 16, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x16ac, /* end MIB - Port6 range */ ++ .reg_read = qca8k_regmap_read, ++ .reg_write = qca8k_regmap_write, ++ .reg_update_bits = qca8k_regmap_update_bits, ++ .rd_table = &qca8k_readable_table, ++ .disable_locking = true, /* Locking is handled by qca8k read/write */ ++ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ ++}; ++ ++static int ++qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) ++{ ++ u32 val; ++ ++ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); ++} ++ ++static int ++qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) ++{ ++ u32 reg[3]; ++ int ret; ++ ++ /* load the ARL table into an array */ ++ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++ if (ret) ++ return ret; ++ ++ /* vid - 83:72 */ ++ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); ++ /* aging - 67:64 */ ++ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); ++ /* portmask - 54:48 */ ++ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); ++ /* mac - 47:0 */ ++ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); ++ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); ++ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); ++ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); ++ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); ++ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); ++ ++ return 0; ++} ++ ++static void ++qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, ++ u8 aging) ++{ ++ u32 reg[3] = { 0 }; ++ ++ /* vid - 83:72 */ ++ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); ++ /* aging - 67:64 */ ++ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); ++ /* portmask - 54:48 */ ++ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); ++ /* mac - 47:0 */ ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); ++ ++ /* load the array into the ARL table */ ++ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++} ++ ++static int ++qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and FDB index */ ++ reg = QCA8K_ATU_FUNC_BUSY; ++ reg |= cmd; ++ if (port >= 0) { ++ reg |= QCA8K_ATU_FUNC_PORT_EN; ++ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); ++ } ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_FDB_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_ATU_FUNC_FULL) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) ++{ ++ int ret; ++ ++ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); ++ if (ret < 0) ++ return ret; ++ ++ return qca8k_fdb_read(priv, fdb); ++} ++ ++static int ++qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, ++ u16 vid, u8 aging) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static void ++qca8k_fdb_flush(struct qca8k_priv *priv) ++{ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); ++ mutex_unlock(&priv->reg_mutex); ++} ++ ++static int ++qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_fdb_read(priv, &fdb); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule exist. Delete first */ ++ if (!fdb.aging) { ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ } ++ ++ /* Add port to fdb portmask */ ++ fdb.port_mask |= port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule doesn't exist. Why delete? */ ++ if (!fdb.aging) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ ++ /* Only port in the rule is this port. Don't re insert */ ++ if (fdb.port_mask == port_mask) ++ goto exit; ++ ++ /* Remove port from port mask */ ++ fdb.port_mask &= ~port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and VLAN index */ ++ reg = QCA8K_VTU_FUNC1_BUSY; ++ reg |= cmd; ++ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_VLAN_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_VTU_FUNC1_FULL) ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) ++{ ++ u32 reg; ++ int ret; ++ ++ /* ++ We do the right thing with VLAN 0 and treat it as untagged while ++ preserving the tag on egress. ++ */ ++ if (vid == 0) ++ return 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ if (untagged) ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); ++ else ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); ++ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) ++{ ++ u32 reg, mask; ++ int ret, i; ++ bool del; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); ++ ++ /* Check if we're the last member to be removed */ ++ del = true; ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); ++ ++ if ((reg & mask) != mask) { ++ del = false; ++ break; ++ } ++ } ++ ++ if (del) { ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); ++ } else { ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ } ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int ++qca8k_mib_init(struct qca8k_priv *priv) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, ++ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, ++ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | ++ QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static void ++qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) ++{ ++ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; ++ ++ /* Port 0 and 6 have no internal PHY */ ++ if (port > 0 && port < 6) ++ mask |= QCA8K_PORT_STATUS_LINK_AUTO; ++ ++ if (enable) ++ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++ else ++ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++} ++ ++static int ++qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, ++ struct sk_buff *read_skb, u32 *val) ++{ ++ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); ++ bool ack; ++ int ret; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the copy pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) ++ return -ETIMEDOUT; ++ ++ if (!ack) ++ return -EINVAL; ++ ++ *val = mgmt_eth_data->data[0]; ++ ++ return 0; ++} ++ ++static int ++qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, ++ int regnum, u16 data) ++{ ++ struct sk_buff *write_skb, *clear_skb, *read_skb; ++ struct qca8k_mgmt_eth_data *mgmt_eth_data; ++ u32 write_val, clear_val = 0, val; ++ struct net_device *mgmt_master; ++ int ret, ret1; ++ bool ack; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ mgmt_eth_data = &priv->mgmt_eth_data; ++ ++ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum); ++ ++ if (read) { ++ write_val |= QCA8K_MDIO_MASTER_READ; ++ } else { ++ write_val |= QCA8K_MDIO_MASTER_WRITE; ++ write_val |= QCA8K_MDIO_MASTER_DATA(data); ++ } ++ ++ /* Prealloc all the needed skb before the lock */ ++ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); ++ if (!write_skb) ++ return -ENOMEM; ++ ++ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); ++ if (!clear_skb) { ++ ret = -ENOMEM; ++ goto err_clear_skb; ++ } ++ ++ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, ++ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); ++ if (!read_skb) { ++ ret = -ENOMEM; ++ goto err_read_skb; ++ } ++ ++ /* Actually start the request: ++ * 1. Send mdio master packet ++ * 2. Busy Wait for mdio master command ++ * 3. Get the data if we are reading ++ * 4. Reset the mdio master (even with error) ++ */ ++ mutex_lock(&mgmt_eth_data->mutex); ++ ++ /* Check if mgmt_master is operational */ ++ mgmt_master = priv->mgmt_master; ++ if (!mgmt_master) { ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ret = -EINVAL; ++ goto err_mgmt_master; ++ } ++ ++ read_skb->dev = mgmt_master; ++ clear_skb->dev = mgmt_master; ++ write_skb->dev = mgmt_master; ++ ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the write pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(write_skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) { ++ ret = -ETIMEDOUT; ++ kfree_skb(read_skb); ++ goto exit; ++ } ++ ++ if (!ack) { ++ ret = -EINVAL; ++ kfree_skb(read_skb); ++ goto exit; ++ } ++ ++ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, ++ !(val & QCA8K_MDIO_MASTER_BUSY), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, ++ mgmt_eth_data, read_skb, &val); ++ ++ if (ret < 0 && ret1 < 0) { ++ ret = ret1; ++ goto exit; ++ } ++ ++ if (read) { ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the read pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(read_skb); ++ ++ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ ack = mgmt_eth_data->ack; ++ ++ if (ret <= 0) { ++ ret = -ETIMEDOUT; ++ goto exit; ++ } ++ ++ if (!ack) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; ++ } else { ++ kfree_skb(read_skb); ++ } ++exit: ++ reinit_completion(&mgmt_eth_data->rw_done); ++ ++ /* Increment seq_num and set it in the clear pkt */ ++ mgmt_eth_data->seq++; ++ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); ++ mgmt_eth_data->ack = false; ++ ++ dev_queue_xmit(clear_skb); ++ ++ wait_for_completion_timeout(&mgmt_eth_data->rw_done, ++ QCA8K_ETHERNET_TIMEOUT); ++ ++ mutex_unlock(&mgmt_eth_data->mutex); ++ ++ return ret; ++ ++ /* Error handling before lock */ ++err_mgmt_master: ++ kfree_skb(read_skb); ++err_read_skb: ++ kfree_skb(clear_skb); ++err_clear_skb: ++ kfree_skb(write_skb); ++ ++ return ret; ++} ++ ++static u32 ++qca8k_port_to_phy(int port) ++{ ++ /* From Andrew Lunn: ++ * Port 0 has no internal phy. ++ * Port 1 has an internal PHY at MDIO address 0. ++ * Port 2 has an internal PHY at MDIO address 1. ++ * ... ++ * Port 5 has an internal PHY at MDIO address 4. ++ * Port 6 has no internal PHY. ++ */ ++ ++ return port - 1; ++} ++ ++static int ++qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) ++{ ++ u16 r1, r2, page; ++ u32 val; ++ int ret, ret1; ++ ++ qca8k_split_addr(reg, &r1, &r2, &page); ++ ++ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, ++ bus, 0x10 | r2, r1, &val); ++ ++ /* Check if qca8k_read has failed for a different reason ++ * before returnting -ETIMEDOUT ++ */ ++ if (ret < 0 && ret1 < 0) ++ return ret1; ++ ++ return ret; ++} ++ ++static int ++qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) ++{ ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum) | ++ QCA8K_MDIO_MASTER_DATA(data); ++ ++ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_BUSY); ++ ++exit: ++ /* even if the busy_wait timeouts try to clear the MASTER_EN */ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) ++{ ++ struct mii_bus *bus = priv->bus; ++ u16 r1, r2, page; ++ u32 val; ++ int ret; ++ ++ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) ++ return -EINVAL; ++ ++ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | ++ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | ++ QCA8K_MDIO_MASTER_REG_ADDR(regnum); ++ ++ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = qca8k_set_page(priv, page); ++ if (ret) ++ goto exit; ++ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, val); ++ ++ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); ++ ++exit: ++ /* even if the busy_wait timeouts try to clear the MASTER_EN */ ++ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ if (ret >= 0) ++ ret = val & QCA8K_MDIO_MASTER_DATA_MASK; ++ ++ return ret; ++} ++ ++static int ++qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) ++{ ++ struct qca8k_priv *priv = slave_bus->priv; ++ int ret; ++ ++ /* Use mdio Ethernet when available, fallback to legacy one on error */ ++ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); ++ if (!ret) ++ return 0; ++ ++ return qca8k_mdio_write(priv, phy, regnum, data); ++} ++ ++static int ++qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) ++{ ++ struct qca8k_priv *priv = slave_bus->priv; ++ int ret; ++ ++ /* Use mdio Ethernet when available, fallback to legacy one on error */ ++ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); ++ if (ret >= 0) ++ return ret; ++ ++ ret = qca8k_mdio_read(priv, phy, regnum); ++ ++ if (ret < 0) ++ return 0xffff; ++ ++ return ret; ++} ++ ++static int ++qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) ++{ ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; ++ ++ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); ++} ++ ++static int ++qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) ++{ ++ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; ++ ++ return qca8k_internal_mdio_read(slave_bus, port, regnum); ++} ++ ++static int ++qca8k_mdio_register(struct qca8k_priv *priv) ++{ ++ struct dsa_switch *ds = priv->ds; ++ struct device_node *mdio; ++ struct mii_bus *bus; ++ ++ bus = devm_mdiobus_alloc(ds->dev); ++ if (!bus) ++ return -ENOMEM; ++ ++ bus->priv = (void *)priv; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", ++ ds->dst->index, ds->index); ++ bus->parent = ds->dev; ++ bus->phy_mask = ~ds->phys_mii_mask; ++ ds->slave_mii_bus = bus; ++ ++ /* Check if the devicetree declare the port:phy mapping */ ++ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); ++ if (of_device_is_available(mdio)) { ++ bus->name = "qca8k slave mii"; ++ bus->read = qca8k_internal_mdio_read; ++ bus->write = qca8k_internal_mdio_write; ++ return devm_of_mdiobus_register(priv->dev, bus, mdio); ++ } ++ ++ /* If a mapping can't be found the legacy mapping is used, ++ * using the qca8k_port_to_phy function ++ */ ++ bus->name = "qca8k-legacy slave mii"; ++ bus->read = qca8k_legacy_mdio_read; ++ bus->write = qca8k_legacy_mdio_write; ++ return devm_mdiobus_register(priv->dev, bus); ++} ++ ++static int ++qca8k_setup_mdio_bus(struct qca8k_priv *priv) ++{ ++ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; ++ struct device_node *ports, *port; ++ phy_interface_t mode; ++ int err; ++ ++ ports = of_get_child_by_name(priv->dev->of_node, "ports"); ++ if (!ports) ++ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); ++ ++ if (!ports) ++ return -EINVAL; ++ ++ for_each_available_child_of_node(ports, port) { ++ err = of_property_read_u32(port, "reg", ®); ++ if (err) { ++ of_node_put(port); ++ of_node_put(ports); ++ return err; ++ } ++ ++ if (!dsa_is_user_port(priv->ds, reg)) ++ continue; ++ ++ of_get_phy_mode(port, &mode); ++ ++ if (of_property_read_bool(port, "phy-handle") && ++ mode != PHY_INTERFACE_MODE_INTERNAL) ++ external_mdio_mask |= BIT(reg); ++ else ++ internal_mdio_mask |= BIT(reg); ++ } ++ ++ of_node_put(ports); ++ if (!external_mdio_mask && !internal_mdio_mask) { ++ dev_err(priv->dev, "no PHYs are defined.\n"); ++ return -EINVAL; ++ } ++ ++ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through ++ * the MDIO_MASTER register also _disconnects_ the external MDC ++ * passthrough to the internal PHYs. It's not possible to use both ++ * configurations at the same time! ++ * ++ * Because this came up during the review process: ++ * If the external mdio-bus driver is capable magically disabling ++ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's ++ * accessors for the time being, it would be possible to pull this ++ * off. ++ */ ++ if (!!external_mdio_mask && !!internal_mdio_mask) { ++ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); ++ return -EINVAL; ++ } ++ ++ if (external_mdio_mask) { ++ /* Make sure to disable the internal mdio bus in cases ++ * a dt-overlay and driver reload changed the configuration ++ */ ++ ++ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, ++ QCA8K_MDIO_MASTER_EN); ++ } ++ ++ return qca8k_mdio_register(priv); ++} ++ ++static int ++qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) ++{ ++ u32 mask = 0; ++ int ret = 0; ++ ++ /* SoC specific settings for ipq8064. ++ * If more device require this consider adding ++ * a dedicated binding. ++ */ ++ if (of_machine_is_compatible("qcom,ipq8064")) ++ mask |= QCA8K_MAC_PWR_RGMII0_1_8V; ++ ++ /* SoC specific settings for ipq8065 */ ++ if (of_machine_is_compatible("qcom,ipq8065")) ++ mask |= QCA8K_MAC_PWR_RGMII1_1_8V; ++ ++ if (mask) { ++ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, ++ QCA8K_MAC_PWR_RGMII0_1_8V | ++ QCA8K_MAC_PWR_RGMII1_1_8V, ++ mask); ++ } ++ ++ return ret; ++} ++ ++static int qca8k_find_cpu_port(struct dsa_switch *ds) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Find the connected cpu port. Valid port are 0 or 6 */ ++ if (dsa_is_cpu_port(ds, 0)) ++ return 0; ++ ++ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); ++ ++ if (dsa_is_cpu_port(ds, 6)) ++ return 6; ++ ++ return -EINVAL; ++} ++ ++static int ++qca8k_setup_of_pws_reg(struct qca8k_priv *priv) ++{ ++ const struct qca8k_match_data *data = priv->info; ++ struct device_node *node = priv->dev->of_node; ++ u32 val = 0; ++ int ret; ++ ++ /* QCA8327 require to set to the correct mode. ++ * His bigger brother QCA8328 have the 172 pin layout. ++ * Should be applied by default but we set this just to make sure. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ /* Set the correct package of 148 pin for QCA8327 */ ++ if (data->reduced_package) ++ val |= QCA8327_PWS_PACKAGE148_EN; ++ ++ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, ++ val); ++ if (ret) ++ return ret; ++ } ++ ++ if (of_property_read_bool(node, "qca,ignore-power-on-sel")) ++ val |= QCA8K_PWS_POWER_ON_SEL; ++ ++ if (of_property_read_bool(node, "qca,led-open-drain")) { ++ if (!(val & QCA8K_PWS_POWER_ON_SEL)) { ++ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); ++ return -EINVAL; ++ } ++ ++ val |= QCA8K_PWS_LED_OPEN_EN_CSR; ++ } ++ ++ return qca8k_rmw(priv, QCA8K_REG_PWS, ++ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, ++ val); ++} ++ ++static int ++qca8k_parse_port_config(struct qca8k_priv *priv) ++{ ++ int port, cpu_port_index = -1, ret; ++ struct device_node *port_dn; ++ phy_interface_t mode; ++ struct dsa_port *dp; ++ u32 delay; ++ ++ /* We have 2 CPU port. Check them */ ++ for (port = 0; port < QCA8K_NUM_PORTS; port++) { ++ /* Skip every other port */ ++ if (port != 0 && port != 6) ++ continue; ++ ++ dp = dsa_to_port(priv->ds, port); ++ port_dn = dp->dn; ++ cpu_port_index++; ++ ++ if (!of_device_is_available(port_dn)) ++ continue; ++ ++ ret = of_get_phy_mode(port_dn, &mode); ++ if (ret) ++ continue; ++ ++ switch (mode) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_SGMII: ++ delay = 0; ++ ++ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) ++ /* Switch regs accept value in ns, convert ps to ns */ ++ delay = delay / 1000; ++ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_TXID) ++ delay = 1; ++ ++ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { ++ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); ++ delay = 3; ++ } ++ ++ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; ++ ++ delay = 0; ++ ++ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) ++ /* Switch regs accept value in ns, convert ps to ns */ ++ delay = delay / 1000; ++ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_RXID) ++ delay = 2; ++ ++ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { ++ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); ++ delay = 3; ++ } ++ ++ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; ++ ++ /* Skip sgmii parsing for rgmii* mode */ ++ if (mode == PHY_INTERFACE_MODE_RGMII || ++ mode == PHY_INTERFACE_MODE_RGMII_ID || ++ mode == PHY_INTERFACE_MODE_RGMII_TXID || ++ mode == PHY_INTERFACE_MODE_RGMII_RXID) ++ break; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) ++ priv->ports_config.sgmii_tx_clk_falling_edge = true; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) ++ priv->ports_config.sgmii_rx_clk_falling_edge = true; ++ ++ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { ++ priv->ports_config.sgmii_enable_pll = true; ++ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); ++ priv->ports_config.sgmii_enable_pll = false; ++ } ++ ++ if (priv->switch_revision < 2) ++ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); ++ } ++ ++ break; ++ default: ++ continue; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_setup(struct dsa_switch *ds) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int cpu_port, ret, i; ++ u32 mask; ++ ++ cpu_port = qca8k_find_cpu_port(ds); ++ if (cpu_port < 0) { ++ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); ++ return cpu_port; ++ } ++ ++ /* Parse CPU port config to be later used in phy_link mac_config */ ++ ret = qca8k_parse_port_config(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_mdio_bus(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_of_pws_reg(priv); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_setup_mac_pwr_sel(priv); ++ if (ret) ++ return ret; ++ ++ /* Make sure MAC06 is disabled */ ++ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, ++ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); ++ if (ret) { ++ dev_err(priv->dev, "failed disabling MAC06 exchange"); ++ return ret; ++ } ++ ++ /* Enable CPU Port */ ++ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); ++ if (ret) { ++ dev_err(priv->dev, "failed enabling CPU port"); ++ return ret; ++ } ++ ++ /* Enable MIB counters */ ++ ret = qca8k_mib_init(priv); ++ if (ret) ++ dev_warn(priv->dev, "mib init failed"); ++ ++ /* Initial setup of all ports */ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ /* Disable forwarding by default on all ports */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, 0); ++ if (ret) ++ return ret; ++ ++ /* Enable QCA header mode on all cpu ports */ ++ if (dsa_is_cpu_port(ds, i)) { ++ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), ++ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | ++ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); ++ if (ret) { ++ dev_err(priv->dev, "failed enabling QCA header mode"); ++ return ret; ++ } ++ } ++ ++ /* Disable MAC by default on all user ports */ ++ if (dsa_is_user_port(ds, i)) ++ qca8k_port_set_status(priv, i, 0); ++ } ++ ++ /* Forward all unknown frames to CPU port for Linux processing ++ * Notice that in multi-cpu config only one port should be set ++ * for igmp, unknown, multicast and broadcast packet ++ */ ++ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | ++ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); ++ if (ret) ++ return ret; ++ ++ /* Setup connection between CPU port & user ports ++ * Configure specific switch configuration for ports ++ */ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ /* CPU port gets connected to all user ports of the switch */ ++ if (dsa_is_cpu_port(ds, i)) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); ++ if (ret) ++ return ret; ++ } ++ ++ /* Individual user ports get connected to CPU port only */ ++ if (dsa_is_user_port(ds, i)) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_MEMBER, ++ BIT(cpu_port)); ++ if (ret) ++ return ret; ++ ++ /* Enable ARP Auto-learning by default */ ++ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), ++ QCA8K_PORT_LOOKUP_LEARN); ++ if (ret) ++ return ret; ++ ++ /* For port based vlans to work we need to set the ++ * default egress vid ++ */ ++ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), ++ QCA8K_EGREES_VLAN_PORT_MASK(i), ++ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), ++ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | ++ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); ++ if (ret) ++ return ret; ++ } ++ ++ /* The port 5 of the qca8337 have some problem in flood condition. The ++ * original legacy driver had some specific buffer and priority settings ++ * for the different port suggested by the QCA switch team. Add this ++ * missing settings to improve switch stability under load condition. ++ * This problem is limited to qca8337 and other qca8k switch are not affected. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8337) { ++ switch (i) { ++ /* The 2 CPU port and port 5 requires some different ++ * priority than any other ports. ++ */ ++ case 0: ++ case 5: ++ case 6: ++ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | ++ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); ++ break; ++ default: ++ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | ++ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | ++ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); ++ } ++ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); ++ ++ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | ++ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_WRED_EN; ++ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), ++ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | ++ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | ++ QCA8K_PORT_HOL_CTRL1_WRED_EN, ++ mask); ++ } ++ } ++ ++ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ ++ if (priv->switch_id == QCA8K_ID_QCA8327) { ++ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | ++ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); ++ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, ++ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | ++ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, ++ mask); ++ } ++ ++ /* Setup our port MTUs to match power on defaults */ ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); ++ if (ret) ++ dev_warn(priv->dev, "failed setting MTU settings"); ++ ++ /* Flush the FDB table */ ++ qca8k_fdb_flush(priv); ++ ++ /* We don't have interrupts for link changes, so we need to poll */ ++ ds->pcs_poll = true; ++ ++ /* Set min a max ageing value supported */ ++ ds->ageing_time_min = 7000; ++ ds->ageing_time_max = 458745000; ++ ++ /* Set max number of LAGs supported */ ++ ds->num_lag_ids = QCA8K_NUM_LAGS; ++ ++ return 0; ++} ++ ++static void ++qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, ++ u32 reg) ++{ ++ u32 delay, val = 0; ++ int ret; ++ ++ /* Delay can be declared in 3 different way. ++ * Mode to rgmii and internal-delay standard binding defined ++ * rgmii-id or rgmii-tx/rx phy mode set. ++ * The parse logic set a delay different than 0 only when one ++ * of the 3 different way is used. In all other case delay is ++ * not enabled. With ID or TX/RXID delay is enabled and set ++ * to the default and recommended value. ++ */ ++ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { ++ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; ++ ++ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; ++ } ++ ++ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { ++ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; ++ ++ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; ++ } ++ ++ /* Set RGMII delay based on the selected values */ ++ ret = qca8k_rmw(priv, reg, ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | ++ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, ++ val); ++ if (ret) ++ dev_err(priv->dev, "Failed to set internal delay for CPU port%d", ++ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); ++} ++ ++static void ++qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int cpu_port_index, ret; ++ u32 reg, val; ++ ++ switch (port) { ++ case 0: /* 1st CPU port */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII) ++ return; ++ ++ reg = QCA8K_REG_PORT0_PAD_CTRL; ++ cpu_port_index = QCA8K_CPU_PORT0; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ /* Internal PHY, nothing to do */ ++ return; ++ case 6: /* 2nd CPU port / external PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII && ++ state->interface != PHY_INTERFACE_MODE_1000BASEX) ++ return; ++ ++ reg = QCA8K_REG_PORT6_PAD_CTRL; ++ cpu_port_index = QCA8K_CPU_PORT6; ++ break; ++ default: ++ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); ++ return; ++ } ++ ++ if (port != 6 && phylink_autoneg_inband(mode)) { ++ dev_err(ds->dev, "%s: in-band negotiation unsupported\n", ++ __func__); ++ return; ++ } ++ ++ switch (state->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); ++ ++ /* Configure rgmii delay */ ++ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); ++ ++ /* QCA8337 requires to set rgmii rx delay for all ports. ++ * This is enabled through PORT5_PAD_CTRL for all ports, ++ * rather than individual port registers. ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8337) ++ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, ++ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ /* Enable SGMII on the port */ ++ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); ++ ++ /* Enable/disable SerDes auto-negotiation as necessary */ ++ ret = qca8k_read(priv, QCA8K_REG_PWS, &val); ++ if (ret) ++ return; ++ if (phylink_autoneg_inband(mode)) ++ val &= ~QCA8K_PWS_SERDES_AEN_DIS; ++ else ++ val |= QCA8K_PWS_SERDES_AEN_DIS; ++ qca8k_write(priv, QCA8K_REG_PWS, val); ++ ++ /* Configure the SGMII parameters */ ++ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); ++ if (ret) ++ return; ++ ++ val |= QCA8K_SGMII_EN_SD; ++ ++ if (priv->ports_config.sgmii_enable_pll) ++ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | ++ QCA8K_SGMII_EN_TX; ++ ++ if (dsa_is_cpu_port(ds, port)) { ++ /* CPU port, we're talking to the CPU MAC, be a PHY */ ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_PHY; ++ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_MAC; ++ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { ++ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; ++ val |= QCA8K_SGMII_MODE_CTRL_BASEX; ++ } ++ ++ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); ++ ++ /* From original code is reported port instability as SGMII also ++ * require delay set. Apply advised values here or take them from DT. ++ */ ++ if (state->interface == PHY_INTERFACE_MODE_SGMII) ++ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); ++ ++ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and ++ * falling edge is set writing in the PORT0 PAD reg ++ */ ++ if (priv->switch_id == QCA8K_ID_QCA8327 || ++ priv->switch_id == QCA8K_ID_QCA8337) ++ reg = QCA8K_REG_PORT0_PAD_CTRL; ++ ++ val = 0; ++ ++ /* SGMII Clock phase configuration */ ++ if (priv->ports_config.sgmii_rx_clk_falling_edge) ++ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; ++ ++ if (priv->ports_config.sgmii_tx_clk_falling_edge) ++ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; ++ ++ if (val) ++ ret = qca8k_rmw(priv, reg, ++ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | ++ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, ++ val); ++ ++ break; ++ default: ++ dev_err(ds->dev, "xMII mode %s not supported for port %d\n", ++ phy_modes(state->interface), port); ++ return; ++ } ++} ++ ++static void ++qca8k_phylink_validate(struct dsa_switch *ds, int port, ++ unsigned long *supported, ++ struct phylink_link_state *state) ++{ ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; ++ ++ switch (port) { ++ case 0: /* 1st CPU port */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII) ++ goto unsupported; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ /* Internal PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_GMII && ++ state->interface != PHY_INTERFACE_MODE_INTERNAL) ++ goto unsupported; ++ break; ++ case 6: /* 2nd CPU port / external PHY */ ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_RGMII_ID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && ++ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && ++ state->interface != PHY_INTERFACE_MODE_SGMII && ++ state->interface != PHY_INTERFACE_MODE_1000BASEX) ++ goto unsupported; ++ break; ++ default: ++unsupported: ++ linkmode_zero(supported); ++ return; ++ } ++ ++ phylink_set_port_modes(mask); ++ phylink_set(mask, Autoneg); ++ ++ phylink_set(mask, 1000baseT_Full); ++ phylink_set(mask, 10baseT_Half); ++ phylink_set(mask, 10baseT_Full); ++ phylink_set(mask, 100baseT_Half); ++ phylink_set(mask, 100baseT_Full); ++ ++ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) ++ phylink_set(mask, 1000baseX_Full); ++ ++ phylink_set(mask, Pause); ++ phylink_set(mask, Asym_Pause); ++ ++ linkmode_and(supported, supported, mask); ++ linkmode_and(state->advertising, state->advertising, mask); ++} ++ ++static int ++qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, ++ struct phylink_link_state *state) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg; ++ int ret; ++ ++ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); ++ if (ret < 0) ++ return ret; ++ ++ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); ++ state->an_complete = state->link; ++ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); ++ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : ++ DUPLEX_HALF; ++ ++ switch (reg & QCA8K_PORT_STATUS_SPEED) { ++ case QCA8K_PORT_STATUS_SPEED_10: ++ state->speed = SPEED_10; ++ break; ++ case QCA8K_PORT_STATUS_SPEED_100: ++ state->speed = SPEED_100; ++ break; ++ case QCA8K_PORT_STATUS_SPEED_1000: ++ state->speed = SPEED_1000; ++ break; ++ default: ++ state->speed = SPEED_UNKNOWN; ++ break; ++ } ++ ++ state->pause = MLO_PAUSE_NONE; ++ if (reg & QCA8K_PORT_STATUS_RXFLOW) ++ state->pause |= MLO_PAUSE_RX; ++ if (reg & QCA8K_PORT_STATUS_TXFLOW) ++ state->pause |= MLO_PAUSE_TX; ++ ++ return 1; ++} ++ ++static void ++qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ qca8k_port_set_status(priv, port, 0); ++} ++ ++static void ++qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface, struct phy_device *phydev, ++ int speed, int duplex, bool tx_pause, bool rx_pause) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg; ++ ++ if (phylink_autoneg_inband(mode)) { ++ reg = QCA8K_PORT_STATUS_LINK_AUTO; ++ } else { ++ switch (speed) { ++ case SPEED_10: ++ reg = QCA8K_PORT_STATUS_SPEED_10; ++ break; ++ case SPEED_100: ++ reg = QCA8K_PORT_STATUS_SPEED_100; ++ break; ++ case SPEED_1000: ++ reg = QCA8K_PORT_STATUS_SPEED_1000; ++ break; ++ default: ++ reg = QCA8K_PORT_STATUS_LINK_AUTO; ++ break; ++ } ++ ++ if (duplex == DUPLEX_FULL) ++ reg |= QCA8K_PORT_STATUS_DUPLEX; ++ ++ if (rx_pause || dsa_is_cpu_port(ds, port)) ++ reg |= QCA8K_PORT_STATUS_RXFLOW; ++ ++ if (tx_pause || dsa_is_cpu_port(ds, port)) ++ reg |= QCA8K_PORT_STATUS_TXFLOW; ++ } ++ ++ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; ++ ++ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); ++} ++ ++static void ++qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int i; ++ ++ if (stringset != ETH_SS_STATS) ++ return; ++ ++ for (i = 0; i < priv->info->mib_count; i++) ++ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, ++ ETH_GSTRING_LEN); ++} ++ ++static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) ++{ ++ struct qca8k_mib_eth_data *mib_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ const struct qca8k_mib_desc *mib; ++ struct mib_ethhdr *mib_ethhdr; ++ int i, mib_len, offset = 0; ++ u64 *data; ++ u8 port; ++ ++ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); ++ mib_eth_data = &priv->mib_eth_data; ++ ++ /* The switch autocast every port. Ignore other packet and ++ * parse only the requested one. ++ */ ++ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); ++ if (port != mib_eth_data->req_port) ++ goto exit; ++ ++ data = mib_eth_data->data; ++ ++ for (i = 0; i < priv->info->mib_count; i++) { ++ mib = &ar8327_mib[i]; ++ ++ /* First 3 mib are present in the skb head */ ++ if (i < 3) { ++ data[i] = mib_ethhdr->data[i]; ++ continue; ++ } ++ ++ mib_len = sizeof(uint32_t); ++ ++ /* Some mib are 64 bit wide */ ++ if (mib->size == 2) ++ mib_len = sizeof(uint64_t); ++ ++ /* Copy the mib value from packet to the */ ++ memcpy(data + i, skb->data + offset, mib_len); ++ ++ /* Set the offset for the next mib */ ++ offset += mib_len; ++ } ++ ++exit: ++ /* Complete on receiving all the mib packet */ ++ if (refcount_dec_and_test(&mib_eth_data->port_parsed)) ++ complete(&mib_eth_data->rw_done); ++} ++ ++static int ++qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) ++{ ++ struct dsa_port *dp = dsa_to_port(ds, port); ++ struct qca8k_mib_eth_data *mib_eth_data; ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ mib_eth_data = &priv->mib_eth_data; ++ ++ mutex_lock(&mib_eth_data->mutex); ++ ++ reinit_completion(&mib_eth_data->rw_done); ++ ++ mib_eth_data->req_port = dp->index; ++ mib_eth_data->data = data; ++ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ /* Send mib autocast request */ ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, ++ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, ++ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | ++ QCA8K_MIB_BUSY); ++ ++ mutex_unlock(&priv->reg_mutex); ++ ++ if (ret) ++ goto exit; ++ ++ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); ++ ++exit: ++ mutex_unlock(&mib_eth_data->mutex); ++ ++ return ret; ++} ++ ++static void ++qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, ++ uint64_t *data) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ const struct qca8k_mib_desc *mib; ++ u32 reg, i, val; ++ u32 hi = 0; ++ int ret; ++ ++ if (priv->mgmt_master && priv->info->ops->autocast_mib && ++ priv->info->ops->autocast_mib(ds, port, data) > 0) ++ return; ++ ++ for (i = 0; i < priv->info->mib_count; i++) { ++ mib = &ar8327_mib[i]; ++ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; ++ ++ ret = qca8k_read(priv, reg, &val); ++ if (ret < 0) ++ continue; ++ ++ if (mib->size == 2) { ++ ret = qca8k_read(priv, reg + 4, &hi); ++ if (ret < 0) ++ continue; ++ } ++ ++ data[i] = val; ++ if (mib->size == 2) ++ data[i] |= (u64)hi << 32; ++ } ++} ++ ++static int ++qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ if (sset != ETH_SS_STATS) ++ return 0; ++ ++ return priv->info->mib_count; ++} ++ ++static int ++qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); ++ u32 reg; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); ++ if (ret < 0) ++ goto exit; ++ ++ if (eee->eee_enabled) ++ reg |= lpi_en; ++ else ++ reg &= ~lpi_en; ++ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int ++qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) ++{ ++ /* Nothing to do on the port's MAC */ ++ return 0; ++} ++ ++static void ++qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u32 stp_state; ++ ++ switch (state) { ++ case BR_STATE_DISABLED: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; ++ break; ++ case BR_STATE_BLOCKING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; ++ break; ++ case BR_STATE_LISTENING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; ++ break; ++ case BR_STATE_LEARNING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; ++ break; ++ case BR_STATE_FORWARDING: ++ default: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; ++ break; ++ } ++ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); ++} ++ ++static int ++qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int port_mask, cpu_port; ++ int i, ret; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ port_mask = BIT(cpu_port); ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Add this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ ret = regmap_set_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ if (ret) ++ return ret; ++ if (i != port) ++ port_mask |= BIT(i); ++ } ++ ++ /* Add all other ports to this ports portvlan mask */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, port_mask); ++ ++ return ret; ++} ++ ++static void ++qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ int cpu_port, i; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Remove this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ regmap_clear_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ } ++ ++ /* Set the cpu port to be the only one in the portvlan mask of ++ * this port ++ */ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); ++} ++ ++static void ++qca8k_port_fast_age(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); ++ mutex_unlock(&priv->reg_mutex); ++} ++ ++static int ++qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ unsigned int secs = msecs / 1000; ++ u32 val; ++ ++ /* AGE_TIME reg is set in 7s step */ ++ val = secs / 7; ++ ++ /* Handle case with 0 as val to NOT disable ++ * learning ++ */ ++ if (!val) ++ val = 1; ++ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, ++ QCA8K_ATU_AGE_TIME(val)); ++} ++ ++static int ++qca8k_port_enable(struct dsa_switch *ds, int port, ++ struct phy_device *phy) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ ++ qca8k_port_set_status(priv, port, 1); ++ priv->port_enabled_map |= BIT(port); ++ ++ if (dsa_is_user_port(ds, port)) ++ phy_support_asym_pause(phy); ++ ++ return 0; ++} ++ ++static void ++qca8k_port_disable(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ ++ qca8k_port_set_status(priv, port, 0); ++ priv->port_enabled_map &= ~BIT(port); ++} ++ ++static int ++qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ /* We have only have a general MTU setting. ++ * DSA always set the CPU port's MTU to the largest MTU of the slave ++ * ports. ++ * Setting MTU just for the CPU port is sufficient to correctly set a ++ * value for every port. ++ */ ++ if (!dsa_is_cpu_port(ds, port)) ++ return 0; ++ ++ /* To change the MAX_FRAME_SIZE the cpu ports must be off or ++ * the switch panics. ++ * Turn off both cpu ports before applying the new value to prevent ++ * this. ++ */ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 0); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 0); ++ ++ /* Include L2 header / FCS length */ ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); ++ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 1); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 1); ++ ++ return ret; ++} ++ ++static int ++qca8k_port_max_mtu(struct dsa_switch *ds, int port) ++{ ++ return QCA8K_MAX_MTU; ++} ++ ++static int ++qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, ++ u16 port_mask, u16 vid) ++{ ++ /* Set the vid to the port vlan id if no vid is set */ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_add(priv, addr, port_mask, vid, ++ QCA8K_ATU_STATUS_STATIC); ++} ++ ++static int ++qca8k_port_fdb_add(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); ++} ++ ++static int ++qca8k_port_fdb_del(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_del(priv, addr, port_mask, vid); ++} ++ ++static int ++qca8k_port_fdb_dump(struct dsa_switch *ds, int port, ++ dsa_fdb_dump_cb_t *cb, void *data) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ struct qca8k_fdb _fdb = { 0 }; ++ int cnt = QCA8K_NUM_FDB_RECORDS; ++ bool is_static; ++ int ret = 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { ++ if (!_fdb.aging) ++ break; ++ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); ++ ret = cb(_fdb.mac, _fdb.vid, is_static, data); ++ if (ret) ++ break; ++ } ++ mutex_unlock(&priv->reg_mutex); ++ ++ return 0; ++} ++ ++static int ++qca8k_port_mdb_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); ++} ++ ++static int ++qca8k_port_mdb_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); ++} ++ ++static int ++qca8k_port_mirror_add(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror, ++ bool ingress) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int monitor_port, ret; ++ u32 reg, val; ++ ++ /* Check for existent entry */ ++ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) ++ return -EEXIST; ++ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* QCA83xx can have only one port set to mirror mode. ++ * Check that the correct port is requested and return error otherwise. ++ * When no mirror port is set, the values is set to 0xF ++ */ ++ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) ++ return -EEXIST; ++ ++ /* Set the monitor port */ ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, ++ mirror->to_local_port); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ return ret; ++ ++ if (ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_update_bits(priv->regmap, reg, val, val); ++ if (ret) ++ return ret; ++ ++ /* Track mirror port for tx and rx to decide when the ++ * mirror port has to be disabled. ++ */ ++ if (ingress) ++ priv->mirror_rx |= BIT(port); ++ else ++ priv->mirror_tx |= BIT(port); ++ ++ return 0; ++} ++ ++static void ++qca8k_port_mirror_del(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg, val; ++ int ret; ++ ++ if (mirror->ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_clear_bits(priv->regmap, reg, val); ++ if (ret) ++ goto err; ++ ++ if (mirror->ingress) ++ priv->mirror_rx &= ~BIT(port); ++ else ++ priv->mirror_tx &= ~BIT(port); ++ ++ /* No port set to send packet to mirror port. Disable mirror port */ ++ if (!priv->mirror_rx && !priv->mirror_tx) { ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ goto err; ++ } ++err: ++ dev_err(priv->dev, "Failed to del mirror port from %d", port); ++} ++ ++static int ++qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, ++ struct netlink_ext_ack *extack) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ if (vlan_filtering) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); ++ } else { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); ++ } ++ ++ return ret; ++} ++ ++static int ++qca8k_port_vlan_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan, ++ struct netlink_ext_ack *extack) ++{ ++ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; ++ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); ++ if (ret) { ++ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); ++ return ret; ++ } ++ ++ if (pvid) { ++ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), ++ QCA8K_EGREES_VLAN_PORT_MASK(port), ++ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), ++ QCA8K_PORT_VLAN_CVID(vlan->vid) | ++ QCA8K_PORT_VLAN_SVID(vlan->vid)); ++ } ++ ++ return ret; ++} ++ ++static int ++qca8k_port_vlan_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_del(priv, port, vlan->vid); ++ if (ret) ++ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); ++ ++ return ret; ++} ++ ++static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Communicate to the phy internal driver the switch revision. ++ * Based on the switch revision different values needs to be ++ * set to the dbg and mmd reg on the phy. ++ * The first 2 bit are used to communicate the switch revision ++ * to the phy driver. ++ */ ++ if (port > 0 && port < 6) ++ return priv->switch_revision; ++ ++ return 0; ++} ++ ++static enum dsa_tag_protocol ++qca8k_get_tag_protocol(struct dsa_switch *ds, int port, ++ enum dsa_tag_protocol mp) ++{ ++ return DSA_TAG_PROTO_QCA; ++} ++ ++static bool ++qca8k_lag_can_offload(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct dsa_port *dp; ++ int id, members = 0; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ if (id < 0 || id >= ds->num_lag_ids) ++ return false; ++ ++ dsa_lag_foreach_port(dp, ds->dst, lag) ++ /* Includes the port joining the LAG */ ++ members++; ++ ++ if (members > QCA8K_NUM_PORTS_FOR_LAG) ++ return false; ++ ++ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) ++ return false; ++ ++ if (info->hash_type != NETDEV_LAG_HASH_L2 && ++ info->hash_type != NETDEV_LAG_HASH_L23) ++ return false; ++ ++ return true; ++} ++ ++static int ++qca8k_lag_setup_hash(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ bool unique_lag = true; ++ u32 hash = 0; ++ int i, id; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ switch (info->hash_type) { ++ case NETDEV_LAG_HASH_L23: ++ hash |= QCA8K_TRUNK_HASH_SIP_EN; ++ hash |= QCA8K_TRUNK_HASH_DIP_EN; ++ fallthrough; ++ case NETDEV_LAG_HASH_L2: ++ hash |= QCA8K_TRUNK_HASH_SA_EN; ++ hash |= QCA8K_TRUNK_HASH_DA_EN; ++ break; ++ default: /* We should NEVER reach this */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* Check if we are the unique configured LAG */ ++ dsa_lags_foreach_id(i, ds->dst) ++ if (i != id && dsa_lag_dev(ds->dst, i)) { ++ unique_lag = false; ++ break; ++ } ++ ++ /* Hash Mode is global. Make sure the same Hash Mode ++ * is set to all the 4 possible lag. ++ * If we are the unique LAG we can set whatever hash ++ * mode we want. ++ * To change hash mode it's needed to remove all LAG ++ * and change the mode with the latest. ++ */ ++ if (unique_lag) { ++ priv->lag_hash_mode = hash; ++ } else if (priv->lag_hash_mode != hash) { ++ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, ++ QCA8K_TRUNK_HASH_MASK, hash); ++} ++ ++static int ++qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, ++ struct net_device *lag, bool delete) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret, id, i; ++ u32 val; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ /* Read current port member */ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* Shift val to the correct trunk */ ++ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); ++ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; ++ if (delete) ++ val &= ~BIT(port); ++ else ++ val |= BIT(port); ++ ++ /* Update port member. With empty portmap disable trunk */ ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, ++ QCA8K_REG_GOL_TRUNK_MEMBER(id) | ++ QCA8K_REG_GOL_TRUNK_EN(id), ++ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | ++ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); ++ ++ /* Search empty member if adding or port on deleting */ ++ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); ++ if (ret) ++ return ret; ++ ++ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; ++ ++ if (delete) { ++ /* If port flagged to be disabled assume this member is ++ * empty ++ */ ++ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; ++ if (val != port) ++ continue; ++ } else { ++ /* If port flagged to be enabled assume this member is ++ * already set ++ */ ++ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ } ++ ++ /* We have found the member to add/remove */ ++ break; ++ } ++ ++ /* Set port in the correct port mask or disable port if in delete mode */ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), ++ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | ++ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); ++} ++ ++static int ++qca8k_port_lag_join(struct dsa_switch *ds, int port, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ int ret; ++ ++ if (!qca8k_lag_can_offload(ds, lag, info)) ++ return -EOPNOTSUPP; ++ ++ ret = qca8k_lag_setup_hash(ds, lag, info); ++ if (ret) ++ return ret; ++ ++ return qca8k_lag_refresh_portmap(ds, port, lag, false); ++} ++ ++static int ++qca8k_port_lag_leave(struct dsa_switch *ds, int port, ++ struct net_device *lag) ++{ ++ return qca8k_lag_refresh_portmap(ds, port, lag, true); ++} ++ ++static void ++qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, ++ bool operational) ++{ ++ struct dsa_port *dp = master->dsa_ptr; ++ struct qca8k_priv *priv = ds->priv; ++ ++ /* Ethernet MIB/MDIO is only supported for CPU port 0 */ ++ if (dp->index != 0) ++ return; ++ ++ mutex_lock(&priv->mgmt_eth_data.mutex); ++ mutex_lock(&priv->mib_eth_data.mutex); ++ ++ priv->mgmt_master = operational ? (struct net_device *)master : NULL; ++ ++ mutex_unlock(&priv->mib_eth_data.mutex); ++ mutex_unlock(&priv->mgmt_eth_data.mutex); ++} ++ ++static int qca8k_connect_tag_protocol(struct dsa_switch *ds, ++ enum dsa_tag_protocol proto) ++{ ++ struct qca_tagger_data *tagger_data; ++ ++ switch (proto) { ++ case DSA_TAG_PROTO_QCA: ++ tagger_data = ds->tagger_data; ++ ++ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; ++ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; ++ ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static const struct dsa_switch_ops qca8k_switch_ops = { ++ .get_tag_protocol = qca8k_get_tag_protocol, ++ .setup = qca8k_setup, ++ .get_strings = qca8k_get_strings, ++ .get_ethtool_stats = qca8k_get_ethtool_stats, ++ .get_sset_count = qca8k_get_sset_count, ++ .set_ageing_time = qca8k_set_ageing_time, ++ .get_mac_eee = qca8k_get_mac_eee, ++ .set_mac_eee = qca8k_set_mac_eee, ++ .port_enable = qca8k_port_enable, ++ .port_disable = qca8k_port_disable, ++ .port_change_mtu = qca8k_port_change_mtu, ++ .port_max_mtu = qca8k_port_max_mtu, ++ .port_stp_state_set = qca8k_port_stp_state_set, ++ .port_bridge_join = qca8k_port_bridge_join, ++ .port_bridge_leave = qca8k_port_bridge_leave, ++ .port_fast_age = qca8k_port_fast_age, ++ .port_fdb_add = qca8k_port_fdb_add, ++ .port_fdb_del = qca8k_port_fdb_del, ++ .port_fdb_dump = qca8k_port_fdb_dump, ++ .port_mdb_add = qca8k_port_mdb_add, ++ .port_mdb_del = qca8k_port_mdb_del, ++ .port_mirror_add = qca8k_port_mirror_add, ++ .port_mirror_del = qca8k_port_mirror_del, ++ .port_vlan_filtering = qca8k_port_vlan_filtering, ++ .port_vlan_add = qca8k_port_vlan_add, ++ .port_vlan_del = qca8k_port_vlan_del, ++ .phylink_validate = qca8k_phylink_validate, ++ .phylink_mac_link_state = qca8k_phylink_mac_link_state, ++ .phylink_mac_config = qca8k_phylink_mac_config, ++ .phylink_mac_link_down = qca8k_phylink_mac_link_down, ++ .phylink_mac_link_up = qca8k_phylink_mac_link_up, ++ .get_phy_flags = qca8k_get_phy_flags, ++ .port_lag_join = qca8k_port_lag_join, ++ .port_lag_leave = qca8k_port_lag_leave, ++ .master_state_change = qca8k_master_change, ++ .connect_tag_protocol = qca8k_connect_tag_protocol, ++}; ++ ++static int qca8k_read_switch_id(struct qca8k_priv *priv) ++{ ++ u32 val; ++ u8 id; ++ int ret; ++ ++ if (!priv->info) ++ return -ENODEV; ++ ++ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); ++ if (ret < 0) ++ return -ENODEV; ++ ++ id = QCA8K_MASK_CTRL_DEVICE_ID(val); ++ if (id != priv->info->id) { ++ dev_err(priv->dev, ++ "Switch id detected %x but expected %x", ++ id, priv->info->id); ++ return -ENODEV; ++ } ++ ++ priv->switch_id = id; ++ ++ /* Save revision to communicate to the internal PHY driver */ ++ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); ++ ++ return 0; ++} ++ ++static int ++qca8k_sw_probe(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv; ++ int ret; ++ ++ /* allocate the private data struct so that we can probe the switches ++ * ID register ++ */ ++ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->info = of_device_get_match_data(priv->dev); ++ priv->bus = mdiodev->bus; ++ priv->dev = &mdiodev->dev; ++ ++ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", ++ GPIOD_ASIS); ++ if (IS_ERR(priv->reset_gpio)) ++ return PTR_ERR(priv->reset_gpio); ++ ++ if (priv->reset_gpio) { ++ gpiod_set_value_cansleep(priv->reset_gpio, 1); ++ /* The active low duration must be greater than 10 ms ++ * and checkpatch.pl wants 20 ms. ++ */ ++ msleep(20); ++ gpiod_set_value_cansleep(priv->reset_gpio, 0); ++ } ++ ++ /* Start by setting up the register mapping */ ++ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, ++ &qca8k_regmap_config); ++ if (IS_ERR(priv->regmap)) { ++ dev_err(priv->dev, "regmap initialization failed"); ++ return PTR_ERR(priv->regmap); ++ } ++ ++ priv->mdio_cache.page = 0xffff; ++ priv->mdio_cache.lo = 0xffff; ++ priv->mdio_cache.hi = 0xffff; ++ ++ /* Check the detected switch id */ ++ ret = qca8k_read_switch_id(priv); ++ if (ret) ++ return ret; ++ ++ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); ++ if (!priv->ds) ++ return -ENOMEM; ++ ++ mutex_init(&priv->mgmt_eth_data.mutex); ++ init_completion(&priv->mgmt_eth_data.rw_done); ++ ++ mutex_init(&priv->mib_eth_data.mutex); ++ init_completion(&priv->mib_eth_data.rw_done); ++ ++ priv->ds->dev = &mdiodev->dev; ++ priv->ds->num_ports = QCA8K_NUM_PORTS; ++ priv->ds->priv = priv; ++ priv->ds->ops = &qca8k_switch_ops; ++ mutex_init(&priv->reg_mutex); ++ dev_set_drvdata(&mdiodev->dev, priv); ++ ++ return dsa_register_switch(priv->ds); ++} ++ ++static void ++qca8k_sw_remove(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); ++ int i; ++ ++ if (!priv) ++ return; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) ++ qca8k_port_set_status(priv, i, 0); ++ ++ dsa_unregister_switch(priv->ds); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++static void qca8k_sw_shutdown(struct mdio_device *mdiodev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); ++ ++ if (!priv) ++ return; ++ ++ dsa_switch_shutdown(priv->ds); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static void ++qca8k_set_pm(struct qca8k_priv *priv, int enable) ++{ ++ int port; ++ ++ for (port = 0; port < QCA8K_NUM_PORTS; port++) { ++ /* Do not enable on resume if the port was ++ * disabled before. ++ */ ++ if (!(priv->port_enabled_map & BIT(port))) ++ continue; ++ ++ qca8k_port_set_status(priv, port, enable); ++ } ++} ++ ++static int qca8k_suspend(struct device *dev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(dev); ++ ++ qca8k_set_pm(priv, 0); ++ ++ return dsa_switch_suspend(priv->ds); ++} ++ ++static int qca8k_resume(struct device *dev) ++{ ++ struct qca8k_priv *priv = dev_get_drvdata(dev); ++ ++ qca8k_set_pm(priv, 1); ++ ++ return dsa_switch_resume(priv->ds); ++} ++#endif /* CONFIG_PM_SLEEP */ ++ ++static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, ++ qca8k_suspend, qca8k_resume); ++ ++static const struct qca8k_info_ops qca8xxx_ops = { ++ .autocast_mib = qca8k_get_ethtool_stats_eth, ++}; ++ ++static const struct qca8k_match_data qca8327 = { ++ .id = QCA8K_ID_QCA8327, ++ .reduced_package = true, ++ .mib_count = QCA8K_QCA832X_MIB_COUNT, ++ .ops = &qca8xxx_ops, ++}; ++ ++static const struct qca8k_match_data qca8328 = { ++ .id = QCA8K_ID_QCA8327, ++ .mib_count = QCA8K_QCA832X_MIB_COUNT, ++ .ops = &qca8xxx_ops, ++}; ++ ++static const struct qca8k_match_data qca833x = { ++ .id = QCA8K_ID_QCA8337, ++ .mib_count = QCA8K_QCA833X_MIB_COUNT, ++ .ops = &qca8xxx_ops, ++}; ++ ++static const struct of_device_id qca8k_of_match[] = { ++ { .compatible = "qca,qca8327", .data = &qca8327 }, ++ { .compatible = "qca,qca8328", .data = &qca8328 }, ++ { .compatible = "qca,qca8334", .data = &qca833x }, ++ { .compatible = "qca,qca8337", .data = &qca833x }, ++ { /* sentinel */ }, ++}; ++ ++static struct mdio_driver qca8kmdio_driver = { ++ .probe = qca8k_sw_probe, ++ .remove = qca8k_sw_remove, ++ .shutdown = qca8k_sw_shutdown, ++ .mdiodrv.driver = { ++ .name = "qca8k", ++ .of_match_table = qca8k_of_match, ++ .pm = &qca8k_pm_ops, ++ }, ++}; ++ ++mdio_module_driver(qca8kmdio_driver); ++ ++MODULE_AUTHOR("Mathieu Olivari, John Crispin "); ++MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:qca8k"); +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2009 Felix Fietkau ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2016 John Crispin ++ */ ++ ++#include ++#include ++ ++#include "qca8k.h" ++ ++#define MIB_DESC(_s, _o, _n) \ ++ { \ ++ .size = (_s), \ ++ .offset = (_o), \ ++ .name = (_n), \ ++ } ++ ++const struct qca8k_mib_desc ar8327_mib[] = { ++ MIB_DESC(1, 0x00, "RxBroad"), ++ MIB_DESC(1, 0x04, "RxPause"), ++ MIB_DESC(1, 0x08, "RxMulti"), ++ MIB_DESC(1, 0x0c, "RxFcsErr"), ++ MIB_DESC(1, 0x10, "RxAlignErr"), ++ MIB_DESC(1, 0x14, "RxRunt"), ++ MIB_DESC(1, 0x18, "RxFragment"), ++ MIB_DESC(1, 0x1c, "Rx64Byte"), ++ MIB_DESC(1, 0x20, "Rx128Byte"), ++ MIB_DESC(1, 0x24, "Rx256Byte"), ++ MIB_DESC(1, 0x28, "Rx512Byte"), ++ MIB_DESC(1, 0x2c, "Rx1024Byte"), ++ MIB_DESC(1, 0x30, "Rx1518Byte"), ++ MIB_DESC(1, 0x34, "RxMaxByte"), ++ MIB_DESC(1, 0x38, "RxTooLong"), ++ MIB_DESC(2, 0x3c, "RxGoodByte"), ++ MIB_DESC(2, 0x44, "RxBadByte"), ++ MIB_DESC(1, 0x4c, "RxOverFlow"), ++ MIB_DESC(1, 0x50, "Filtered"), ++ MIB_DESC(1, 0x54, "TxBroad"), ++ MIB_DESC(1, 0x58, "TxPause"), ++ MIB_DESC(1, 0x5c, "TxMulti"), ++ MIB_DESC(1, 0x60, "TxUnderRun"), ++ MIB_DESC(1, 0x64, "Tx64Byte"), ++ MIB_DESC(1, 0x68, "Tx128Byte"), ++ MIB_DESC(1, 0x6c, "Tx256Byte"), ++ MIB_DESC(1, 0x70, "Tx512Byte"), ++ MIB_DESC(1, 0x74, "Tx1024Byte"), ++ MIB_DESC(1, 0x78, "Tx1518Byte"), ++ MIB_DESC(1, 0x7c, "TxMaxByte"), ++ MIB_DESC(1, 0x80, "TxOverSize"), ++ MIB_DESC(2, 0x84, "TxByte"), ++ MIB_DESC(1, 0x8c, "TxCollision"), ++ MIB_DESC(1, 0x90, "TxAbortCol"), ++ MIB_DESC(1, 0x94, "TxMultiCol"), ++ MIB_DESC(1, 0x98, "TxSingleCol"), ++ MIB_DESC(1, 0x9c, "TxExcDefer"), ++ MIB_DESC(1, 0xa0, "TxDefer"), ++ MIB_DESC(1, 0xa4, "TxLateCol"), ++ MIB_DESC(1, 0xa8, "RXUnicast"), ++ MIB_DESC(1, 0xac, "TXUnicast"), ++}; +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -414,4 +414,7 @@ struct qca8k_fdb { + u8 mac[6]; + }; + ++/* Common setup function */ ++extern const struct qca8k_mib_desc ar8327_mib[]; ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch b/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch new file mode 100644 index 000000000..012ab8547 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch @@ -0,0 +1,135 @@ +From d5f901eab2e9dfed1095995dfc98f231f4fd2971 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:13 +0200 +Subject: [PATCH 04/14] net: dsa: qca8k: move qca8k read/write/rmw and reg + table to common code + +The same reg table and read/write/rmw function are used by drivers +based on qca8k family switch. +Move them to common code to make it accessible also by other drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 42 ------------------------------ + drivers/net/dsa/qca/qca8k-common.c | 38 +++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 6 +++++ + 3 files changed, 44 insertions(+), 42 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -133,24 +133,6 @@ qca8k_set_page(struct qca8k_priv *priv, + return 0; + } + +-static int +-qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) +-{ +- return regmap_read(priv->regmap, reg, val); +-} +- +-static int +-qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) +-{ +- return regmap_write(priv->regmap, reg, val); +-} +- +-static int +-qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) +-{ +- return regmap_update_bits(priv->regmap, reg, mask, write_val); +-} +- + static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) + { + struct qca8k_mgmt_eth_data *mgmt_eth_data; +@@ -483,30 +465,6 @@ exit: + return ret; + } + +-static const struct regmap_range qca8k_readable_ranges[] = { +- regmap_reg_range(0x0000, 0x00e4), /* Global control */ +- regmap_reg_range(0x0100, 0x0168), /* EEE control */ +- regmap_reg_range(0x0200, 0x0270), /* Parser control */ +- regmap_reg_range(0x0400, 0x0454), /* ACL */ +- regmap_reg_range(0x0600, 0x0718), /* Lookup */ +- regmap_reg_range(0x0800, 0x0b70), /* QM */ +- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ +- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ +- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ +- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ +- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ +- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ +- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ +- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ +- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ +- +-}; +- +-static const struct regmap_access_table qca8k_readable_table = { +- .yes_ranges = qca8k_readable_ranges, +- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), +-}; +- + static struct regmap_config qca8k_regmap_config = { + .reg_bits = 16, + .val_bits = 32, +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -61,3 +61,41 @@ const struct qca8k_mib_desc ar8327_mib[] + MIB_DESC(1, 0xa8, "RXUnicast"), + MIB_DESC(1, 0xac, "TXUnicast"), + }; ++ ++int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) ++{ ++ return regmap_read(priv->regmap, reg, val); ++} ++ ++int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) ++{ ++ return regmap_write(priv->regmap, reg, val); ++} ++ ++int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) ++{ ++ return regmap_update_bits(priv->regmap, reg, mask, write_val); ++} ++ ++static const struct regmap_range qca8k_readable_ranges[] = { ++ regmap_reg_range(0x0000, 0x00e4), /* Global control */ ++ regmap_reg_range(0x0100, 0x0168), /* EEE control */ ++ regmap_reg_range(0x0200, 0x0270), /* Parser control */ ++ regmap_reg_range(0x0400, 0x0454), /* ACL */ ++ regmap_reg_range(0x0600, 0x0718), /* Lookup */ ++ regmap_reg_range(0x0800, 0x0b70), /* QM */ ++ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ ++ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ ++ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ ++ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ ++ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ ++ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ ++ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ ++ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ ++ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ ++}; ++ ++const struct regmap_access_table qca8k_readable_table = { ++ .yes_ranges = qca8k_readable_ranges, ++ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), ++}; +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -416,5 +416,11 @@ struct qca8k_fdb { + + /* Common setup function */ + extern const struct qca8k_mib_desc ar8327_mib[]; ++extern const struct regmap_access_table qca8k_readable_table; ++ ++/* Common read/write/rmw function */ ++int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); ++int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); ++int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); + + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch b/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch new file mode 100644 index 000000000..0ed7ed41f --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch @@ -0,0 +1,145 @@ +From 910746444313dc463396cd63024cdf54ef04ef39 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:14 +0200 +Subject: [PATCH 05/14] net: dsa: qca8k: move qca8k bulk read/write helper to + common code + +The same ATU function are used by drivers based on qca8k family switch. +Move the bulk read/write helper to common code to declare these shared +ATU functions in common code. +These helper will be dropped when regmap correctly support bulk +read/write. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 39 ++---------------------------- + drivers/net/dsa/qca/qca8k-common.c | 39 ++++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 8 ++++++ + 3 files changed, 49 insertions(+), 37 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -343,43 +343,6 @@ qca8k_regmap_update_bits_eth(struct qca8 + } + + static int +-qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- +- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int +-qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +-{ +- int i, count = len / sizeof(u32), ret; +- u32 tmp; +- +- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) +- return 0; +- +- for (i = 0; i < count; i++) { +- tmp = val[i]; +- +- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); +- if (ret < 0) +- return ret; +- } +- +- return 0; +-} +- +-static int + qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) + { + struct qca8k_priv *priv = (struct qca8k_priv *)ctx; +@@ -3096,6 +3059,8 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, + + static const struct qca8k_info_ops qca8xxx_ops = { + .autocast_mib = qca8k_get_ethtool_stats_eth, ++ .read_eth = qca8k_read_eth, ++ .write_eth = qca8k_write_eth, + }; + + static const struct qca8k_match_data qca8327 = { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -99,3 +99,42 @@ const struct regmap_access_table qca8k_r + .yes_ranges = qca8k_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), + }; ++ ++/* TODO: remove these extra ops when we can support regmap bulk read/write */ ++int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ ++ if (priv->mgmt_master && priv->info->ops->read_eth && ++ !priv->info->ops->read_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/* TODO: remove these extra ops when we can support regmap bulk read/write */ ++int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++{ ++ int i, count = len / sizeof(u32), ret; ++ u32 tmp; ++ ++ if (priv->mgmt_master && priv->info->ops->write_eth && ++ !priv->info->ops->write_eth(priv, reg, val, len)) ++ return 0; ++ ++ for (i = 0; i < count; i++) { ++ tmp = val[i]; ++ ++ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -324,8 +324,13 @@ enum qca8k_mid_cmd { + QCA8K_MIB_CAST = 3, + }; + ++struct qca8k_priv; ++ + struct qca8k_info_ops { + int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); ++ /* TODO: remove these extra ops when we can support regmap bulk read/write */ ++ int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); ++ int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); + }; + + struct qca8k_match_data { +@@ -423,4 +428,7 @@ int qca8k_read(struct qca8k_priv *priv, + int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); + int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); + ++int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); ++int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch new file mode 100644 index 000000000..a39a55b89 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch @@ -0,0 +1,137 @@ +From fce1ec0c4e2d03d9c62ffc615a42bdba78eb4c14 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:15 +0200 +Subject: [PATCH 06/14] net: dsa: qca8k: move mib init function to common code + +The same mib function is used by drivers based on qca8k family switch. +Move it to common code to make it accessible also by other drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 37 ------------------------------ + drivers/net/dsa/qca/qca8k-common.c | 35 ++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 4 ++++ + 3 files changed, 39 insertions(+), 37 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -442,15 +442,6 @@ static struct regmap_config qca8k_regmap + }; + + static int +-qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) +-{ +- u32 val; +- +- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, +- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); +-} +- +-static int + qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) + { + u32 reg[3]; +@@ -777,34 +768,6 @@ out: + return ret; + } + +-static int +-qca8k_mib_init(struct qca8k_priv *priv) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, +- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, +- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | +- QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); +- if (ret) +- goto exit; +- +- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); +- if (ret) +- goto exit; +- +- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- + static void + qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) + { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + + #include "qca8k.h" +@@ -138,3 +139,38 @@ int qca8k_bulk_write(struct qca8k_priv * + + return 0; + } ++ ++int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) ++{ ++ u32 val; ++ ++ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, ++ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); ++} ++ ++int qca8k_mib_init(struct qca8k_priv *priv) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, ++ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, ++ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | ++ QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); ++ if (ret) ++ goto exit; ++ ++ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); ++ if (ret) ++ goto exit; ++ ++ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -422,6 +422,7 @@ struct qca8k_fdb { + /* Common setup function */ + extern const struct qca8k_mib_desc ar8327_mib[]; + extern const struct regmap_access_table qca8k_readable_table; ++int qca8k_mib_init(struct qca8k_priv *priv); + + /* Common read/write/rmw function */ + int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); +@@ -431,4 +432,7 @@ int qca8k_rmw(struct qca8k_priv *priv, u + int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); + int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); + ++/* Common ops function */ ++int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch b/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch new file mode 100644 index 000000000..6fd1c66b0 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch @@ -0,0 +1,281 @@ +From 472fcea160f27a5d9b7526093d9d8d89ba0b6137 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:16 +0200 +Subject: [PATCH 07/14] net: dsa: qca8k: move port set status/eee/ethtool stats + function to common code + +The same logic to disable/enable port, set eee and get ethtool stats is +used by drivers based on qca8k family switch. +Move it to common code to make it accessible also by other drivers. +While at it also drop unnecessary qca8k_priv cast for void pointers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 105 ----------------------------- + drivers/net/dsa/qca/qca8k-common.c | 102 ++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 11 +++ + 3 files changed, 113 insertions(+), 105 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -768,21 +768,6 @@ out: + return ret; + } + +-static void +-qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) +-{ +- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; +- +- /* Port 0 and 6 have no internal PHY */ +- if (port > 0 && port < 6) +- mask |= QCA8K_PORT_STATUS_LINK_AUTO; +- +- if (enable) +- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +- else +- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); +-} +- + static int + qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, + struct sk_buff *read_skb, u32 *val) +@@ -1974,20 +1959,6 @@ qca8k_phylink_mac_link_up(struct dsa_swi + qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); + } + +-static void +-qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) +-{ +- struct qca8k_priv *priv = ds->priv; +- int i; +- +- if (stringset != ETH_SS_STATS) +- return; +- +- for (i = 0; i < priv->info->mib_count; i++) +- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, +- ETH_GSTRING_LEN); +-} +- + static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) + { + struct qca8k_mib_eth_data *mib_eth_data; +@@ -2078,82 +2049,6 @@ exit: + } + + static void +-qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, +- uint64_t *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- const struct qca8k_mib_desc *mib; +- u32 reg, i, val; +- u32 hi = 0; +- int ret; +- +- if (priv->mgmt_master && priv->info->ops->autocast_mib && +- priv->info->ops->autocast_mib(ds, port, data) > 0) +- return; +- +- for (i = 0; i < priv->info->mib_count; i++) { +- mib = &ar8327_mib[i]; +- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; +- +- ret = qca8k_read(priv, reg, &val); +- if (ret < 0) +- continue; +- +- if (mib->size == 2) { +- ret = qca8k_read(priv, reg + 4, &hi); +- if (ret < 0) +- continue; +- } +- +- data[i] = val; +- if (mib->size == 2) +- data[i] |= (u64)hi << 32; +- } +-} +- +-static int +-qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- if (sset != ETH_SS_STATS) +- return 0; +- +- return priv->info->mib_count; +-} +- +-static int +-qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); +- u32 reg; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); +- if (ret < 0) +- goto exit; +- +- if (eee->eee_enabled) +- reg |= lpi_en; +- else +- reg &= ~lpi_en; +- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +-{ +- /* Nothing to do on the port's MAC */ +- return 0; +-} +- +-static void + qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) + { + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -174,3 +174,105 @@ exit: + mutex_unlock(&priv->reg_mutex); + return ret; + } ++ ++void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) ++{ ++ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; ++ ++ /* Port 0 and 6 have no internal PHY */ ++ if (port > 0 && port < 6) ++ mask |= QCA8K_PORT_STATUS_LINK_AUTO; ++ ++ if (enable) ++ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++ else ++ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); ++} ++ ++void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, ++ uint8_t *data) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int i; ++ ++ if (stringset != ETH_SS_STATS) ++ return; ++ ++ for (i = 0; i < priv->info->mib_count; i++) ++ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, ++ ETH_GSTRING_LEN); ++} ++ ++void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, ++ uint64_t *data) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const struct qca8k_mib_desc *mib; ++ u32 reg, i, val; ++ u32 hi = 0; ++ int ret; ++ ++ if (priv->mgmt_master && priv->info->ops->autocast_mib && ++ priv->info->ops->autocast_mib(ds, port, data) > 0) ++ return; ++ ++ for (i = 0; i < priv->info->mib_count; i++) { ++ mib = &ar8327_mib[i]; ++ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; ++ ++ ret = qca8k_read(priv, reg, &val); ++ if (ret < 0) ++ continue; ++ ++ if (mib->size == 2) { ++ ret = qca8k_read(priv, reg + 4, &hi); ++ if (ret < 0) ++ continue; ++ } ++ ++ data[i] = val; ++ if (mib->size == 2) ++ data[i] |= (u64)hi << 32; ++ } ++} ++ ++int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ if (sset != ETH_SS_STATS) ++ return 0; ++ ++ return priv->info->mib_count; ++} ++ ++int qca8k_set_mac_eee(struct dsa_switch *ds, int port, ++ struct ethtool_eee *eee) ++{ ++ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); ++ if (ret < 0) ++ goto exit; ++ ++ if (eee->eee_enabled) ++ reg |= lpi_en; ++ else ++ reg &= ~lpi_en; ++ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++int qca8k_get_mac_eee(struct dsa_switch *ds, int port, ++ struct ethtool_eee *e) ++{ ++ /* Nothing to do on the port's MAC */ ++ return 0; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -423,6 +423,7 @@ struct qca8k_fdb { + extern const struct qca8k_mib_desc ar8327_mib[]; + extern const struct regmap_access_table qca8k_readable_table; + int qca8k_mib_init(struct qca8k_priv *priv); ++void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable); + + /* Common read/write/rmw function */ + int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); +@@ -435,4 +436,14 @@ int qca8k_bulk_write(struct qca8k_priv * + /* Common ops function */ + int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); + ++/* Common ethtool stats function */ ++void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data); ++void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, ++ uint64_t *data); ++int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset); ++ ++/* Common eee function */ ++int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee); ++int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch new file mode 100644 index 000000000..3ca682d72 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch @@ -0,0 +1,237 @@ +From fd3cae2f3ac190d06e48f43739237e02f9dc51ff Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:17 +0200 +Subject: [PATCH 08/14] net: dsa: qca8k: move bridge functions to common code + +The same bridge functions are used by drivers based on qca8k family +switch. Move them to common code to make them accessible also by other +drivers. +While at it also drop unnecessary qca8k_priv cast for void pointers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------ + drivers/net/dsa/qca/qca8k-common.c | 93 ++++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 9 +++ + 3 files changed, 102 insertions(+), 93 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -2049,97 +2049,6 @@ exit: + } + + static void +-qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u32 stp_state; +- +- switch (state) { +- case BR_STATE_DISABLED: +- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; +- break; +- case BR_STATE_BLOCKING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; +- break; +- case BR_STATE_LISTENING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; +- break; +- case BR_STATE_LEARNING: +- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; +- break; +- case BR_STATE_FORWARDING: +- default: +- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; +- break; +- } +- +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); +-} +- +-static int +-qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int port_mask, cpu_port; +- int i, ret; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- port_mask = BIT(cpu_port); +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Add this port to the portvlan mask of the other ports +- * in the bridge +- */ +- ret = regmap_set_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- if (ret) +- return ret; +- if (i != port) +- port_mask |= BIT(i); +- } +- +- /* Add all other ports to this ports portvlan mask */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, port_mask); +- +- return ret; +-} +- +-static void +-qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- int cpu_port, i; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (dsa_to_port(ds, i)->bridge_dev != br) +- continue; +- /* Remove this port to the portvlan mask of the other ports +- * in the bridge +- */ +- regmap_clear_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- } +- +- /* Set the cpu port to be the only one in the portvlan mask of +- * this port +- */ +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); +-} +- +-static void + qca8k_port_fast_age(struct dsa_switch *ds, int port) + { + struct qca8k_priv *priv = ds->priv; +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "qca8k.h" + +@@ -276,3 +277,93 @@ int qca8k_get_mac_eee(struct dsa_switch + /* Nothing to do on the port's MAC */ + return 0; + } ++ ++void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 stp_state; ++ ++ switch (state) { ++ case BR_STATE_DISABLED: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; ++ break; ++ case BR_STATE_BLOCKING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; ++ break; ++ case BR_STATE_LISTENING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; ++ break; ++ case BR_STATE_LEARNING: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; ++ break; ++ case BR_STATE_FORWARDING: ++ default: ++ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; ++ break; ++ } ++ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); ++} ++ ++int qca8k_port_bridge_join(struct dsa_switch *ds, int port, ++ struct net_device *br) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int port_mask, cpu_port; ++ int i, ret; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ port_mask = BIT(cpu_port); ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Add this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ ret = regmap_set_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ if (ret) ++ return ret; ++ if (i != port) ++ port_mask |= BIT(i); ++ } ++ ++ /* Add all other ports to this ports portvlan mask */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, port_mask); ++ ++ return ret; ++} ++ ++void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, ++ struct net_device *br) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int cpu_port, i; ++ ++ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i)) ++ continue; ++ if (dsa_to_port(ds, i)->bridge_dev != br) ++ continue; ++ /* Remove this port to the portvlan mask of the other ports ++ * in the bridge ++ */ ++ regmap_clear_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ } ++ ++ /* Set the cpu port to be the only one in the portvlan mask of ++ * this port ++ */ ++ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -446,4 +446,11 @@ int qca8k_get_sset_count(struct dsa_swit + int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee); + int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); + ++/* Common bridge function */ ++void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); ++int qca8k_port_bridge_join(struct dsa_switch *ds, int port, ++ struct net_device *br); ++void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, ++ struct net_device *br); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch b/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch new file mode 100644 index 000000000..e3414408d --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch @@ -0,0 +1,227 @@ +From b3a302b171f73425b41de8d3357fae3fa7057322 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:18 +0200 +Subject: [PATCH 09/14] net: dsa: qca8k: move set age/MTU/port enable/disable + functions to common code + +The same set age, MTU and port enable/disable function are used by +driver based on qca8k family switch. +Move them to common code to make them accessible also by other drivers. +While at it also drop unnecessary qca8k_priv cast for void pointers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 88 ------------------------------ + drivers/net/dsa/qca/qca8k-common.c | 85 +++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 12 ++++ + 3 files changed, 97 insertions(+), 88 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -2059,94 +2059,6 @@ qca8k_port_fast_age(struct dsa_switch *d + } + + static int +-qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) +-{ +- struct qca8k_priv *priv = ds->priv; +- unsigned int secs = msecs / 1000; +- u32 val; +- +- /* AGE_TIME reg is set in 7s step */ +- val = secs / 7; +- +- /* Handle case with 0 as val to NOT disable +- * learning +- */ +- if (!val) +- val = 1; +- +- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, +- QCA8K_ATU_AGE_TIME(val)); +-} +- +-static int +-qca8k_port_enable(struct dsa_switch *ds, int port, +- struct phy_device *phy) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 1); +- priv->port_enabled_map |= BIT(port); +- +- if (dsa_is_user_port(ds, port)) +- phy_support_asym_pause(phy); +- +- return 0; +-} +- +-static void +-qca8k_port_disable(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- +- qca8k_port_set_status(priv, port, 0); +- priv->port_enabled_map &= ~BIT(port); +-} +- +-static int +-qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- /* We have only have a general MTU setting. +- * DSA always set the CPU port's MTU to the largest MTU of the slave +- * ports. +- * Setting MTU just for the CPU port is sufficient to correctly set a +- * value for every port. +- */ +- if (!dsa_is_cpu_port(ds, port)) +- return 0; +- +- /* To change the MAX_FRAME_SIZE the cpu ports must be off or +- * the switch panics. +- * Turn off both cpu ports before applying the new value to prevent +- * this. +- */ +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 0); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 0); +- +- /* Include L2 header / FCS length */ +- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); +- +- if (priv->port_enabled_map & BIT(0)) +- qca8k_port_set_status(priv, 0, 1); +- +- if (priv->port_enabled_map & BIT(6)) +- qca8k_port_set_status(priv, 6, 1); +- +- return ret; +-} +- +-static int +-qca8k_port_max_mtu(struct dsa_switch *ds, int port) +-{ +- return QCA8K_MAX_MTU; +-} +- +-static int + qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, + u16 port_mask, u16 vid) + { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -367,3 +367,88 @@ void qca8k_port_bridge_leave(struct dsa_ + qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), + QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); + } ++ ++int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ unsigned int secs = msecs / 1000; ++ u32 val; ++ ++ /* AGE_TIME reg is set in 7s step */ ++ val = secs / 7; ++ ++ /* Handle case with 0 as val to NOT disable ++ * learning ++ */ ++ if (!val) ++ val = 1; ++ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, ++ QCA8K_ATU_AGE_TIME_MASK, ++ QCA8K_ATU_AGE_TIME(val)); ++} ++ ++int qca8k_port_enable(struct dsa_switch *ds, int port, ++ struct phy_device *phy) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ qca8k_port_set_status(priv, port, 1); ++ priv->port_enabled_map |= BIT(port); ++ ++ if (dsa_is_user_port(ds, port)) ++ phy_support_asym_pause(phy); ++ ++ return 0; ++} ++ ++void qca8k_port_disable(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ qca8k_port_set_status(priv, port, 0); ++ priv->port_enabled_map &= ~BIT(port); ++} ++ ++int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ /* We have only have a general MTU setting. ++ * DSA always set the CPU port's MTU to the largest MTU of the slave ++ * ports. ++ * Setting MTU just for the CPU port is sufficient to correctly set a ++ * value for every port. ++ */ ++ if (!dsa_is_cpu_port(ds, port)) ++ return 0; ++ ++ /* To change the MAX_FRAME_SIZE the cpu ports must be off or ++ * the switch panics. ++ * Turn off both cpu ports before applying the new value to prevent ++ * this. ++ */ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 0); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 0); ++ ++ /* Include L2 header / FCS length */ ++ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ++ ETH_HLEN + ETH_FCS_LEN); ++ ++ if (priv->port_enabled_map & BIT(0)) ++ qca8k_port_set_status(priv, 0, 1); ++ ++ if (priv->port_enabled_map & BIT(6)) ++ qca8k_port_set_status(priv, 6, 1); ++ ++ return ret; ++} ++ ++int qca8k_port_max_mtu(struct dsa_switch *ds, int port) ++{ ++ return QCA8K_MAX_MTU; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -453,4 +453,16 @@ int qca8k_port_bridge_join(struct dsa_sw + void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, + struct net_device *br); + ++/* Common port enable/disable function */ ++int qca8k_port_enable(struct dsa_switch *ds, int port, ++ struct phy_device *phy); ++void qca8k_port_disable(struct dsa_switch *ds, int port); ++ ++/* Common MTU function */ ++int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu); ++int qca8k_port_max_mtu(struct dsa_switch *ds, int port); ++ ++/* Common fast age function */ ++int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch new file mode 100644 index 000000000..96468ae74 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch @@ -0,0 +1,704 @@ +From 2e5bd96eea86a246b4de3bf756f7a11b43e6187d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:19 +0200 +Subject: [PATCH 10/14] net: dsa: qca8k: move port FDB/MDB function to common + code + +The same port FDB/MDB function are used by drivers based on qca8k family +switch. Move them to common code to make them accessible also by other +drivers. +Also drop bulk read/write functions and make them static + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 306 ----------------------------- + drivers/net/dsa/qca/qca8k-common.c | 297 +++++++++++++++++++++++++++- + drivers/net/dsa/qca/qca8k.h | 25 ++- + 3 files changed, 317 insertions(+), 311 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -442,217 +442,6 @@ static struct regmap_config qca8k_regmap + }; + + static int +-qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) +-{ +- u32 reg[3]; +- int ret; +- +- /* load the ARL table into an array */ +- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +- if (ret) +- return ret; +- +- /* vid - 83:72 */ +- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); +- /* aging - 67:64 */ +- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); +- /* portmask - 54:48 */ +- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); +- /* mac - 47:0 */ +- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); +- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); +- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); +- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); +- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); +- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); +- +- return 0; +-} +- +-static void +-qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, +- u8 aging) +-{ +- u32 reg[3] = { 0 }; +- +- /* vid - 83:72 */ +- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); +- /* aging - 67:64 */ +- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); +- /* portmask - 54:48 */ +- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); +- /* mac - 47:0 */ +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); +- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); +- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); +- +- /* load the array into the ARL table */ +- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); +-} +- +-static int +-qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and FDB index */ +- reg = QCA8K_ATU_FUNC_BUSY; +- reg |= cmd; +- if (port >= 0) { +- reg |= QCA8K_ATU_FUNC_PORT_EN; +- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); +- } +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_FDB_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_ATU_FUNC_FULL) +- return -1; +- } +- +- return 0; +-} +- +-static int +-qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) +-{ +- int ret; +- +- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); +- if (ret < 0) +- return ret; +- +- return qca8k_fdb_read(priv, fdb); +-} +- +-static int +-qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, +- u16 vid, u8 aging) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) +-{ +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_write(priv, vid, port_mask, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static void +-qca8k_fdb_flush(struct qca8k_priv *priv) +-{ +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- ret = qca8k_fdb_read(priv, &fdb); +- if (ret < 0) +- goto exit; +- +- /* Rule exist. Delete first */ +- if (!fdb.aging) { +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- } +- +- /* Add port to fdb portmask */ +- fdb.port_mask |= port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int +-qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, +- const u8 *mac, u16 vid) +-{ +- struct qca8k_fdb fdb = { 0 }; +- int ret; +- +- mutex_lock(&priv->reg_mutex); +- +- qca8k_fdb_write(priv, vid, 0, mac, 0); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); +- if (ret < 0) +- goto exit; +- +- /* Rule doesn't exist. Why delete? */ +- if (!fdb.aging) { +- ret = -EINVAL; +- goto exit; +- } +- +- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); +- if (ret) +- goto exit; +- +- /* Only port in the rule is this port. Don't re insert */ +- if (fdb.port_mask == port_mask) +- goto exit; +- +- /* Remove port from port mask */ +- fdb.port_mask &= ~port_mask; +- +- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); +- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); +- +-exit: +- mutex_unlock(&priv->reg_mutex); +- return ret; +-} +- +-static int + qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) + { + u32 reg; +@@ -2048,97 +1837,6 @@ exit: + return ret; + } + +-static void +-qca8k_port_fast_age(struct dsa_switch *ds, int port) +-{ +- struct qca8k_priv *priv = ds->priv; +- +- mutex_lock(&priv->reg_mutex); +- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); +- mutex_unlock(&priv->reg_mutex); +-} +- +-static int +-qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, +- u16 port_mask, u16 vid) +-{ +- /* Set the vid to the port vlan id if no vid is set */ +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_add(priv, addr, port_mask, vid, +- QCA8K_ATU_STATUS_STATIC); +-} +- +-static int +-qca8k_port_fdb_add(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_del(struct dsa_switch *ds, int port, +- const unsigned char *addr, u16 vid) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- u16 port_mask = BIT(port); +- +- if (!vid) +- vid = QCA8K_PORT_VID_DEF; +- +- return qca8k_fdb_del(priv, addr, port_mask, vid); +-} +- +-static int +-qca8k_port_fdb_dump(struct dsa_switch *ds, int port, +- dsa_fdb_dump_cb_t *cb, void *data) +-{ +- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; +- struct qca8k_fdb _fdb = { 0 }; +- int cnt = QCA8K_NUM_FDB_RECORDS; +- bool is_static; +- int ret = 0; +- +- mutex_lock(&priv->reg_mutex); +- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { +- if (!_fdb.aging) +- break; +- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); +- ret = cb(_fdb.mac, _fdb.vid, is_static, data); +- if (ret) +- break; +- } +- mutex_unlock(&priv->reg_mutex); +- +- return 0; +-} +- +-static int +-qca8k_port_mdb_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); +-} +- +-static int +-qca8k_port_mdb_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_mdb *mdb) +-{ +- struct qca8k_priv *priv = ds->priv; +- const u8 *addr = mdb->addr; +- u16 vid = mdb->vid; +- +- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); +-} +- + static int + qca8k_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -103,7 +103,7 @@ const struct regmap_access_table qca8k_r + }; + + /* TODO: remove these extra ops when we can support regmap bulk read/write */ +-int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) + { + int i, count = len / sizeof(u32), ret; + +@@ -121,7 +121,7 @@ int qca8k_bulk_read(struct qca8k_priv *p + } + + /* TODO: remove these extra ops when we can support regmap bulk read/write */ +-int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ++static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) + { + int i, count = len / sizeof(u32), ret; + u32 tmp; +@@ -149,6 +149,211 @@ int qca8k_busy_wait(struct qca8k_priv *p + QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); + } + ++static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) ++{ ++ u32 reg[3]; ++ int ret; ++ ++ /* load the ARL table into an array */ ++ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++ if (ret) ++ return ret; ++ ++ /* vid - 83:72 */ ++ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); ++ /* aging - 67:64 */ ++ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); ++ /* portmask - 54:48 */ ++ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); ++ /* mac - 47:0 */ ++ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); ++ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); ++ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); ++ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); ++ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); ++ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); ++ ++ return 0; ++} ++ ++static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, ++ const u8 *mac, u8 aging) ++{ ++ u32 reg[3] = { 0 }; ++ ++ /* vid - 83:72 */ ++ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); ++ /* aging - 67:64 */ ++ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); ++ /* portmask - 54:48 */ ++ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); ++ /* mac - 47:0 */ ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); ++ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); ++ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); ++ ++ /* load the array into the ARL table */ ++ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); ++} ++ ++static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, ++ int port) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and FDB index */ ++ reg = QCA8K_ATU_FUNC_BUSY; ++ reg |= cmd; ++ if (port >= 0) { ++ reg |= QCA8K_ATU_FUNC_PORT_EN; ++ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); ++ } ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_FDB_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_ATU_FUNC_FULL) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, ++ int port) ++{ ++ int ret; ++ ++ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); ++ if (ret < 0) ++ return ret; ++ ++ return qca8k_fdb_read(priv, fdb); ++} ++ ++static int qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, ++ u16 port_mask, u16 vid, u8 aging) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, ++ u16 port_mask, u16 vid) ++{ ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_write(priv, vid, port_mask, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++void qca8k_fdb_flush(struct qca8k_priv *priv) ++{ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); ++ mutex_unlock(&priv->reg_mutex); ++} ++ ++static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ ret = qca8k_fdb_read(priv, &fdb); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule exist. Delete first */ ++ if (!fdb.aging) { ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ } ++ ++ /* Add port to fdb portmask */ ++ fdb.port_mask |= port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ ++static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, ++ const u8 *mac, u16 vid) ++{ ++ struct qca8k_fdb fdb = { 0 }; ++ int ret; ++ ++ mutex_lock(&priv->reg_mutex); ++ ++ qca8k_fdb_write(priv, vid, 0, mac, 0); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); ++ if (ret < 0) ++ goto exit; ++ ++ /* Rule doesn't exist. Why delete? */ ++ if (!fdb.aging) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); ++ if (ret) ++ goto exit; ++ ++ /* Only port in the rule is this port. Don't re insert */ ++ if (fdb.port_mask == port_mask) ++ goto exit; ++ ++ /* Remove port from port mask */ ++ fdb.port_mask &= ~port_mask; ++ ++ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); ++ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); ++ ++exit: ++ mutex_unlock(&priv->reg_mutex); ++ return ret; ++} ++ + int qca8k_mib_init(struct qca8k_priv *priv) + { + int ret; +@@ -368,6 +573,15 @@ void qca8k_port_bridge_leave(struct dsa_ + QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); + } + ++void qca8k_port_fast_age(struct dsa_switch *ds, int port) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ ++ mutex_lock(&priv->reg_mutex); ++ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); ++ mutex_unlock(&priv->reg_mutex); ++} ++ + int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) + { + struct qca8k_priv *priv = ds->priv; +@@ -452,3 +666,78 @@ int qca8k_port_max_mtu(struct dsa_switch + { + return QCA8K_MAX_MTU; + } ++ ++int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, ++ u16 port_mask, u16 vid) ++{ ++ /* Set the vid to the port vlan id if no vid is set */ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_add(priv, addr, port_mask, vid, ++ QCA8K_ATU_STATUS_STATIC); ++} ++ ++int qca8k_port_fdb_add(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); ++} ++ ++int qca8k_port_fdb_del(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ u16 port_mask = BIT(port); ++ ++ if (!vid) ++ vid = QCA8K_PORT_VID_DEF; ++ ++ return qca8k_fdb_del(priv, addr, port_mask, vid); ++} ++ ++int qca8k_port_fdb_dump(struct dsa_switch *ds, int port, ++ dsa_fdb_dump_cb_t *cb, void *data) ++{ ++ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ++ struct qca8k_fdb _fdb = { 0 }; ++ int cnt = QCA8K_NUM_FDB_RECORDS; ++ bool is_static; ++ int ret = 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { ++ if (!_fdb.aging) ++ break; ++ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); ++ ret = cb(_fdb.mac, _fdb.vid, is_static, data); ++ if (ret) ++ break; ++ } ++ mutex_unlock(&priv->reg_mutex); ++ ++ return 0; ++} ++ ++int qca8k_port_mdb_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); ++} ++ ++int qca8k_port_mdb_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ const u8 *addr = mdb->addr; ++ u16 vid = mdb->vid; ++ ++ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -430,11 +430,9 @@ int qca8k_read(struct qca8k_priv *priv, + int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); + int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); + +-int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); +-int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); +- + /* Common ops function */ + int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); ++void qca8k_fdb_flush(struct qca8k_priv *priv); + + /* Common ethtool stats function */ + void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data); +@@ -463,6 +461,23 @@ int qca8k_port_change_mtu(struct dsa_swi + int qca8k_port_max_mtu(struct dsa_switch *ds, int port); + + /* Common fast age function */ ++void qca8k_port_fast_age(struct dsa_switch *ds, int port); + int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); + ++/* Common FDB function */ ++int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, ++ u16 port_mask, u16 vid); ++int qca8k_port_fdb_add(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid); ++int qca8k_port_fdb_del(struct dsa_switch *ds, int port, ++ const unsigned char *addr, u16 vid); ++int qca8k_port_fdb_dump(struct dsa_switch *ds, int port, ++ dsa_fdb_dump_cb_t *cb, void *data); ++ ++/* Common MDB function */ ++int qca8k_port_mdb_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb); ++int qca8k_port_mdb_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_mdb *mdb); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch new file mode 100644 index 000000000..c1336d4a9 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch @@ -0,0 +1,232 @@ +From 742d37a84d3f7bb60d9b2d9ada9ad4e599f65ebf Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:20 +0200 +Subject: [PATCH 11/14] net: dsa: qca8k: move port mirror functions to common + code + +The same port mirror functions are used by drivers based on qca8k family +switch. Move them to common code to make them accessible also by other +drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------ + drivers/net/dsa/qca/qca8k-common.c | 91 +++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 7 +++ + 3 files changed, 98 insertions(+), 93 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1838,99 +1838,6 @@ exit: + } + + static int +-qca8k_port_mirror_add(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror, +- bool ingress) +-{ +- struct qca8k_priv *priv = ds->priv; +- int monitor_port, ret; +- u32 reg, val; +- +- /* Check for existent entry */ +- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) +- return -EEXIST; +- +- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); +- if (ret) +- return ret; +- +- /* QCA83xx can have only one port set to mirror mode. +- * Check that the correct port is requested and return error otherwise. +- * When no mirror port is set, the values is set to 0xF +- */ +- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) +- return -EEXIST; +- +- /* Set the monitor port */ +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, +- mirror->to_local_port); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- return ret; +- +- if (ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_update_bits(priv->regmap, reg, val, val); +- if (ret) +- return ret; +- +- /* Track mirror port for tx and rx to decide when the +- * mirror port has to be disabled. +- */ +- if (ingress) +- priv->mirror_rx |= BIT(port); +- else +- priv->mirror_tx |= BIT(port); +- +- return 0; +-} +- +-static void +-qca8k_port_mirror_del(struct dsa_switch *ds, int port, +- struct dsa_mall_mirror_tc_entry *mirror) +-{ +- struct qca8k_priv *priv = ds->priv; +- u32 reg, val; +- int ret; +- +- if (mirror->ingress) { +- reg = QCA8K_PORT_LOOKUP_CTRL(port); +- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; +- } else { +- reg = QCA8K_REG_PORT_HOL_CTRL1(port); +- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; +- } +- +- ret = regmap_clear_bits(priv->regmap, reg, val); +- if (ret) +- goto err; +- +- if (mirror->ingress) +- priv->mirror_rx &= ~BIT(port); +- else +- priv->mirror_tx &= ~BIT(port); +- +- /* No port set to send packet to mirror port. Disable mirror port */ +- if (!priv->mirror_rx && !priv->mirror_tx) { +- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, +- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); +- if (ret) +- goto err; +- } +-err: +- dev_err(priv->dev, "Failed to del mirror port from %d", port); +-} +- +-static int + qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, + struct netlink_ext_ack *extack) + { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -741,3 +741,94 @@ int qca8k_port_mdb_del(struct dsa_switch + + return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); + } ++ ++int qca8k_port_mirror_add(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror, ++ bool ingress) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int monitor_port, ret; ++ u32 reg, val; ++ ++ /* Check for existent entry */ ++ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) ++ return -EEXIST; ++ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* QCA83xx can have only one port set to mirror mode. ++ * Check that the correct port is requested and return error otherwise. ++ * When no mirror port is set, the values is set to 0xF ++ */ ++ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) ++ return -EEXIST; ++ ++ /* Set the monitor port */ ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, ++ mirror->to_local_port); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ return ret; ++ ++ if (ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_update_bits(priv->regmap, reg, val, val); ++ if (ret) ++ return ret; ++ ++ /* Track mirror port for tx and rx to decide when the ++ * mirror port has to be disabled. ++ */ ++ if (ingress) ++ priv->mirror_rx |= BIT(port); ++ else ++ priv->mirror_tx |= BIT(port); ++ ++ return 0; ++} ++ ++void qca8k_port_mirror_del(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ u32 reg, val; ++ int ret; ++ ++ if (mirror->ingress) { ++ reg = QCA8K_PORT_LOOKUP_CTRL(port); ++ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; ++ } else { ++ reg = QCA8K_REG_PORT_HOL_CTRL1(port); ++ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; ++ } ++ ++ ret = regmap_clear_bits(priv->regmap, reg, val); ++ if (ret) ++ goto err; ++ ++ if (mirror->ingress) ++ priv->mirror_rx &= ~BIT(port); ++ else ++ priv->mirror_tx &= ~BIT(port); ++ ++ /* No port set to send packet to mirror port. Disable mirror port */ ++ if (!priv->mirror_rx && !priv->mirror_tx) { ++ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, ++ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); ++ if (ret) ++ goto err; ++ } ++err: ++ dev_err(priv->dev, "Failed to del mirror port from %d", port); ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -480,4 +480,11 @@ int qca8k_port_mdb_add(struct dsa_switch + int qca8k_port_mdb_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_mdb *mdb); + ++/* Common port mirror function */ ++int qca8k_port_mirror_add(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror, ++ bool ingress); ++void qca8k_port_mirror_del(struct dsa_switch *ds, int port, ++ struct dsa_mall_mirror_tc_entry *mirror); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch b/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch new file mode 100644 index 000000000..898010f95 --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch @@ -0,0 +1,448 @@ +From c5290f636624b98e76a82bd63ffec0a8a9daa620 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:21 +0200 +Subject: [PATCH 12/14] net: dsa: qca8k: move port VLAN functions to common + code + +The same port VLAN functions are used by drivers based on qca8k family +switch. Move them to common code to make them accessible also by other +drivers. +Also drop exposing busy_wait and make it static. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 182 ----------------------------- + drivers/net/dsa/qca/qca8k-common.c | 179 +++++++++++++++++++++++++++- + drivers/net/dsa/qca/qca8k.h | 10 +- + 3 files changed, 187 insertions(+), 184 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -442,122 +441,6 @@ static struct regmap_config qca8k_regmap + }; + + static int +-qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) +-{ +- u32 reg; +- int ret; +- +- /* Set the command and VLAN index */ +- reg = QCA8K_VTU_FUNC1_BUSY; +- reg |= cmd; +- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); +- +- /* Write the function register triggering the table access */ +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); +- if (ret) +- return ret; +- +- /* wait for completion */ +- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); +- if (ret) +- return ret; +- +- /* Check for table full violation when adding an entry */ +- if (cmd == QCA8K_VLAN_LOAD) { +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); +- if (ret < 0) +- return ret; +- if (reg & QCA8K_VTU_FUNC1_FULL) +- return -ENOMEM; +- } +- +- return 0; +-} +- +-static int +-qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) +-{ +- u32 reg; +- int ret; +- +- /* +- We do the right thing with VLAN 0 and treat it as untagged while +- preserving the tag on egress. +- */ +- if (vid == 0) +- return 0; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- if (untagged) +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); +- else +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); +- +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int +-qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) +-{ +- u32 reg, mask; +- int ret, i; +- bool del; +- +- mutex_lock(&priv->reg_mutex); +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); +- if (ret < 0) +- goto out; +- +- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); +- if (ret < 0) +- goto out; +- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); +- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); +- +- /* Check if we're the last member to be removed */ +- del = true; +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); +- +- if ((reg & mask) != mask) { +- del = false; +- break; +- } +- } +- +- if (del) { +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); +- } else { +- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); +- if (ret) +- goto out; +- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); +- } +- +-out: +- mutex_unlock(&priv->reg_mutex); +- +- return ret; +-} +- +-static int + qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, + struct sk_buff *read_skb, u32 *val) + { +@@ -1836,71 +1719,6 @@ exit: + + return ret; + } +- +-static int +-qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, +- struct netlink_ext_ack *extack) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- if (vlan_filtering) { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); +- } else { +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, +- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_add(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan, +- struct netlink_ext_ack *extack) +-{ +- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); +- if (ret) { +- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); +- return ret; +- } +- +- if (pvid) { +- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), +- QCA8K_EGREES_VLAN_PORT_MASK(port), +- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); +- if (ret) +- return ret; +- +- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), +- QCA8K_PORT_VLAN_CVID(vlan->vid) | +- QCA8K_PORT_VLAN_SVID(vlan->vid)); +- } +- +- return ret; +-} +- +-static int +-qca8k_port_vlan_del(struct dsa_switch *ds, int port, +- const struct switchdev_obj_port_vlan *vlan) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret; +- +- ret = qca8k_vlan_del(priv, port, vlan->vid); +- if (ret) +- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); +- +- return ret; +-} + + static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) + { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -141,7 +141,7 @@ static int qca8k_bulk_write(struct qca8k + return 0; + } + +-int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) ++static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) + { + u32 val; + +@@ -354,6 +354,120 @@ exit: + return ret; + } + ++static int qca8k_vlan_access(struct qca8k_priv *priv, ++ enum qca8k_vlan_cmd cmd, u16 vid) ++{ ++ u32 reg; ++ int ret; ++ ++ /* Set the command and VLAN index */ ++ reg = QCA8K_VTU_FUNC1_BUSY; ++ reg |= cmd; ++ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); ++ ++ /* Write the function register triggering the table access */ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); ++ if (ret) ++ return ret; ++ ++ /* wait for completion */ ++ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); ++ if (ret) ++ return ret; ++ ++ /* Check for table full violation when adding an entry */ ++ if (cmd == QCA8K_VLAN_LOAD) { ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); ++ if (ret < 0) ++ return ret; ++ if (reg & QCA8K_VTU_FUNC1_FULL) ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, ++ bool untagged) ++{ ++ u32 reg; ++ int ret; ++ ++ /* We do the right thing with VLAN 0 and treat it as untagged while ++ * preserving the tag on egress. ++ */ ++ if (vid == 0) ++ return 0; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ if (untagged) ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); ++ else ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); ++ ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ ++static int qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) ++{ ++ u32 reg, mask; ++ int ret, i; ++ bool del; ++ ++ mutex_lock(&priv->reg_mutex); ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); ++ if (ret < 0) ++ goto out; ++ ++ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); ++ if (ret < 0) ++ goto out; ++ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); ++ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); ++ ++ /* Check if we're the last member to be removed */ ++ del = true; ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); ++ ++ if ((reg & mask) != mask) { ++ del = false; ++ break; ++ } ++ } ++ ++ if (del) { ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); ++ } else { ++ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); ++ if (ret) ++ goto out; ++ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); ++ } ++ ++out: ++ mutex_unlock(&priv->reg_mutex); ++ ++ return ret; ++} ++ + int qca8k_mib_init(struct qca8k_priv *priv) + { + int ret; +@@ -832,3 +946,66 @@ void qca8k_port_mirror_del(struct dsa_sw + err: + dev_err(priv->dev, "Failed to del mirror port from %d", port); + } ++ ++int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, ++ bool vlan_filtering, ++ struct netlink_ext_ack *extack) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ if (vlan_filtering) { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); ++ } else { ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, ++ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); ++ } ++ ++ return ret; ++} ++ ++int qca8k_port_vlan_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan, ++ struct netlink_ext_ack *extack) ++{ ++ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; ++ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); ++ if (ret) { ++ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); ++ return ret; ++ } ++ ++ if (pvid) { ++ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), ++ QCA8K_EGREES_VLAN_PORT_MASK(port), ++ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), ++ QCA8K_PORT_VLAN_CVID(vlan->vid) | ++ QCA8K_PORT_VLAN_SVID(vlan->vid)); ++ } ++ ++ return ret; ++} ++ ++int qca8k_port_vlan_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret; ++ ++ ret = qca8k_vlan_del(priv, port, vlan->vid); ++ if (ret) ++ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); ++ ++ return ret; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -431,7 +431,6 @@ int qca8k_write(struct qca8k_priv *priv, + int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); + + /* Common ops function */ +-int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); + void qca8k_fdb_flush(struct qca8k_priv *priv); + + /* Common ethtool stats function */ +@@ -487,4 +486,13 @@ int qca8k_port_mirror_add(struct dsa_swi + void qca8k_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror); + ++/* Common port VLAN function */ ++int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, ++ struct netlink_ext_ack *extack); ++int qca8k_port_vlan_add(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan, ++ struct netlink_ext_ack *extack); ++int qca8k_port_vlan_del(struct dsa_switch *ds, int port, ++ const struct switchdev_obj_port_vlan *vlan); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch new file mode 100644 index 000000000..1802b17ea --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch @@ -0,0 +1,384 @@ +From e9bbf019af44b204b71ef8edf224002550aab641 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:22 +0200 +Subject: [PATCH 13/14] net: dsa: qca8k: move port LAG functions to common code + +The same port LAG functions are used by drivers based on qca8k family +switch. Move them to common code to make them accessible also by other +drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 168 ----------------------------- + drivers/net/dsa/qca/qca8k-common.c | 165 ++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 6 ++ + 3 files changed, 171 insertions(+), 168 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1743,178 +1743,6 @@ qca8k_get_tag_protocol(struct dsa_switch + return DSA_TAG_PROTO_QCA; + } + +-static bool +-qca8k_lag_can_offload(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct dsa_port *dp; +- int id, members = 0; +- +- id = dsa_lag_id(ds->dst, lag); +- if (id < 0 || id >= ds->num_lag_ids) +- return false; +- +- dsa_lag_foreach_port(dp, ds->dst, lag) +- /* Includes the port joining the LAG */ +- members++; +- +- if (members > QCA8K_NUM_PORTS_FOR_LAG) +- return false; +- +- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) +- return false; +- +- if (info->hash_type != NETDEV_LAG_HASH_L2 && +- info->hash_type != NETDEV_LAG_HASH_L23) +- return false; +- +- return true; +-} +- +-static int +-qca8k_lag_setup_hash(struct dsa_switch *ds, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- struct qca8k_priv *priv = ds->priv; +- bool unique_lag = true; +- u32 hash = 0; +- int i, id; +- +- id = dsa_lag_id(ds->dst, lag); +- +- switch (info->hash_type) { +- case NETDEV_LAG_HASH_L23: +- hash |= QCA8K_TRUNK_HASH_SIP_EN; +- hash |= QCA8K_TRUNK_HASH_DIP_EN; +- fallthrough; +- case NETDEV_LAG_HASH_L2: +- hash |= QCA8K_TRUNK_HASH_SA_EN; +- hash |= QCA8K_TRUNK_HASH_DA_EN; +- break; +- default: /* We should NEVER reach this */ +- return -EOPNOTSUPP; +- } +- +- /* Check if we are the unique configured LAG */ +- dsa_lags_foreach_id(i, ds->dst) +- if (i != id && dsa_lag_dev(ds->dst, i)) { +- unique_lag = false; +- break; +- } +- +- /* Hash Mode is global. Make sure the same Hash Mode +- * is set to all the 4 possible lag. +- * If we are the unique LAG we can set whatever hash +- * mode we want. +- * To change hash mode it's needed to remove all LAG +- * and change the mode with the latest. +- */ +- if (unique_lag) { +- priv->lag_hash_mode = hash; +- } else if (priv->lag_hash_mode != hash) { +- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); +- return -EOPNOTSUPP; +- } +- +- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, +- QCA8K_TRUNK_HASH_MASK, hash); +-} +- +-static int +-qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, +- struct net_device *lag, bool delete) +-{ +- struct qca8k_priv *priv = ds->priv; +- int ret, id, i; +- u32 val; +- +- id = dsa_lag_id(ds->dst, lag); +- +- /* Read current port member */ +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); +- if (ret) +- return ret; +- +- /* Shift val to the correct trunk */ +- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); +- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; +- if (delete) +- val &= ~BIT(port); +- else +- val |= BIT(port); +- +- /* Update port member. With empty portmap disable trunk */ +- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, +- QCA8K_REG_GOL_TRUNK_MEMBER(id) | +- QCA8K_REG_GOL_TRUNK_EN(id), +- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | +- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); +- +- /* Search empty member if adding or port on deleting */ +- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { +- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); +- if (ret) +- return ret; +- +- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; +- +- if (delete) { +- /* If port flagged to be disabled assume this member is +- * empty +- */ +- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- +- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; +- if (val != port) +- continue; +- } else { +- /* If port flagged to be enabled assume this member is +- * already set +- */ +- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) +- continue; +- } +- +- /* We have found the member to add/remove */ +- break; +- } +- +- /* Set port in the correct port mask or disable port if in delete mode */ +- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | +- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), +- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | +- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); +-} +- +-static int +-qca8k_port_lag_join(struct dsa_switch *ds, int port, +- struct net_device *lag, +- struct netdev_lag_upper_info *info) +-{ +- int ret; +- +- if (!qca8k_lag_can_offload(ds, lag, info)) +- return -EOPNOTSUPP; +- +- ret = qca8k_lag_setup_hash(ds, lag, info); +- if (ret) +- return ret; +- +- return qca8k_lag_refresh_portmap(ds, port, lag, false); +-} +- +-static int +-qca8k_port_lag_leave(struct dsa_switch *ds, int port, +- struct net_device *lag) +-{ +- return qca8k_lag_refresh_portmap(ds, port, lag, true); +-} +- + static void + qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, + bool operational) +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -1009,3 +1009,169 @@ int qca8k_port_vlan_del(struct dsa_switc + + return ret; + } ++ ++static bool qca8k_lag_can_offload(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct dsa_port *dp; ++ int id, members = 0; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ if (id < 0 || id >= ds->num_lag_ids) ++ return false; ++ ++ dsa_lag_foreach_port(dp, ds->dst, lag) ++ /* Includes the port joining the LAG */ ++ members++; ++ ++ if (members > QCA8K_NUM_PORTS_FOR_LAG) ++ return false; ++ ++ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) ++ return false; ++ ++ if (info->hash_type != NETDEV_LAG_HASH_L2 && ++ info->hash_type != NETDEV_LAG_HASH_L23) ++ return false; ++ ++ return true; ++} ++ ++static int qca8k_lag_setup_hash(struct dsa_switch *ds, ++ struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ bool unique_lag = true; ++ u32 hash = 0; ++ int i, id; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ switch (info->hash_type) { ++ case NETDEV_LAG_HASH_L23: ++ hash |= QCA8K_TRUNK_HASH_SIP_EN; ++ hash |= QCA8K_TRUNK_HASH_DIP_EN; ++ fallthrough; ++ case NETDEV_LAG_HASH_L2: ++ hash |= QCA8K_TRUNK_HASH_SA_EN; ++ hash |= QCA8K_TRUNK_HASH_DA_EN; ++ break; ++ default: /* We should NEVER reach this */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* Check if we are the unique configured LAG */ ++ dsa_lags_foreach_id(i, ds->dst) ++ if (i != id && dsa_lag_dev(ds->dst, i)) { ++ unique_lag = false; ++ break; ++ } ++ ++ /* Hash Mode is global. Make sure the same Hash Mode ++ * is set to all the 4 possible lag. ++ * If we are the unique LAG we can set whatever hash ++ * mode we want. ++ * To change hash mode it's needed to remove all LAG ++ * and change the mode with the latest. ++ */ ++ if (unique_lag) { ++ priv->lag_hash_mode = hash; ++ } else if (priv->lag_hash_mode != hash) { ++ netdev_err(lag, "Error: Mismatched Hash Mode across different lag is not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, ++ QCA8K_TRUNK_HASH_MASK, hash); ++} ++ ++static int qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, ++ struct net_device *lag, bool delete) ++{ ++ struct qca8k_priv *priv = ds->priv; ++ int ret, id, i; ++ u32 val; ++ ++ id = dsa_lag_id(ds->dst, lag); ++ ++ /* Read current port member */ ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); ++ if (ret) ++ return ret; ++ ++ /* Shift val to the correct trunk */ ++ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); ++ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; ++ if (delete) ++ val &= ~BIT(port); ++ else ++ val |= BIT(port); ++ ++ /* Update port member. With empty portmap disable trunk */ ++ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, ++ QCA8K_REG_GOL_TRUNK_MEMBER(id) | ++ QCA8K_REG_GOL_TRUNK_EN(id), ++ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | ++ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); ++ ++ /* Search empty member if adding or port on deleting */ ++ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { ++ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); ++ if (ret) ++ return ret; ++ ++ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; ++ ++ if (delete) { ++ /* If port flagged to be disabled assume this member is ++ * empty ++ */ ++ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ ++ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; ++ if (val != port) ++ continue; ++ } else { ++ /* If port flagged to be enabled assume this member is ++ * already set ++ */ ++ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) ++ continue; ++ } ++ ++ /* We have found the member to add/remove */ ++ break; ++ } ++ ++ /* Set port in the correct port mask or disable port if in delete mode */ ++ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | ++ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), ++ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | ++ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); ++} ++ ++int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag, ++ struct netdev_lag_upper_info *info) ++{ ++ int ret; ++ ++ if (!qca8k_lag_can_offload(ds, lag, info)) ++ return -EOPNOTSUPP; ++ ++ ret = qca8k_lag_setup_hash(ds, lag, info); ++ if (ret) ++ return ret; ++ ++ return qca8k_lag_refresh_portmap(ds, port, lag, false); ++} ++ ++int qca8k_port_lag_leave(struct dsa_switch *ds, int port, ++ struct net_device *lag) ++{ ++ return qca8k_lag_refresh_portmap(ds, port, lag, true); ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -495,4 +495,10 @@ int qca8k_port_vlan_add(struct dsa_switc + int qca8k_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); + ++/* Common port LAG function */ ++int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag, ++ struct netdev_lag_upper_info *info); ++int qca8k_port_lag_leave(struct dsa_switch *ds, int port, ++ struct net_device *lag); ++ + #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch b/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch new file mode 100644 index 000000000..d6ec8b77e --- /dev/null +++ b/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch @@ -0,0 +1,102 @@ +From 9d1bcb1f293f1391302a109c9819c3705c804700 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 27 Jul 2022 13:35:23 +0200 +Subject: [PATCH 14/14] net: dsa: qca8k: move read_switch_id function to common + code + +The same function to read the switch id is used by drivers based on +qca8k family switch. Move them to common code to make them accessible +also by other drivers. + +Signed-off-by: Christian Marangi +Reviewed-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 29 ----------------------------- + drivers/net/dsa/qca/qca8k-common.c | 29 +++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 1 + + 3 files changed, 30 insertions(+), 29 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1822,35 +1822,6 @@ static const struct dsa_switch_ops qca8k + .connect_tag_protocol = qca8k_connect_tag_protocol, + }; + +-static int qca8k_read_switch_id(struct qca8k_priv *priv) +-{ +- u32 val; +- u8 id; +- int ret; +- +- if (!priv->info) +- return -ENODEV; +- +- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); +- if (ret < 0) +- return -ENODEV; +- +- id = QCA8K_MASK_CTRL_DEVICE_ID(val); +- if (id != priv->info->id) { +- dev_err(priv->dev, +- "Switch id detected %x but expected %x", +- id, priv->info->id); +- return -ENODEV; +- } +- +- priv->switch_id = id; +- +- /* Save revision to communicate to the internal PHY driver */ +- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); +- +- return 0; +-} +- + static int + qca8k_sw_probe(struct mdio_device *mdiodev) + { +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -1175,3 +1175,32 @@ int qca8k_port_lag_leave(struct dsa_swit + { + return qca8k_lag_refresh_portmap(ds, port, lag, true); + } ++ ++int qca8k_read_switch_id(struct qca8k_priv *priv) ++{ ++ u32 val; ++ u8 id; ++ int ret; ++ ++ if (!priv->info) ++ return -ENODEV; ++ ++ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); ++ if (ret < 0) ++ return -ENODEV; ++ ++ id = QCA8K_MASK_CTRL_DEVICE_ID(val); ++ if (id != priv->info->id) { ++ dev_err(priv->dev, ++ "Switch id detected %x but expected %x", ++ id, priv->info->id); ++ return -ENODEV; ++ } ++ ++ priv->switch_id = id; ++ ++ /* Save revision to communicate to the internal PHY driver */ ++ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); ++ ++ return 0; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -424,6 +424,7 @@ extern const struct qca8k_mib_desc ar832 + extern const struct regmap_access_table qca8k_readable_table; + int qca8k_mib_init(struct qca8k_priv *priv); + void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable); ++int qca8k_read_switch_id(struct qca8k_priv *priv); + + /* Common read/write/rmw function */ + int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); diff --git a/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch b/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch new file mode 100644 index 000000000..0cca2788f --- /dev/null +++ b/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch @@ -0,0 +1,29 @@ +From 057bcf15db8e625276ddf02b2b7c668a3cb43f81 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 4 Sep 2022 23:46:24 +0200 +Subject: [net PATCH] net: dsa: qca8k: fix NULL pointer dereference for + of_device_get_match_data + +of_device_get_match_data is called on priv->dev before priv->dev is +actually set. Move of_device_get_match_data after priv->dev is correctly +set to fix this kernel panic. + +Fixes: 3bb0844e7bcd ("net: dsa: qca8k: cache match data to speed up access") +Signed-off-by: Christian Marangi +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1835,9 +1835,9 @@ qca8k_sw_probe(struct mdio_device *mdiod + if (!priv) + return -ENOMEM; + +- priv->info = of_device_get_match_data(priv->dev); + priv->bus = mdiodev->bus; + priv->dev = &mdiodev->dev; ++ priv->info = of_device_get_match_data(priv->dev); + + priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", + GPIOD_ASIS); diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch index acb67ab16..7f16b936c 100644 --- a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2952,9 +2952,6 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2979,9 +2979,6 @@ mt7531_mac_config(struct dsa_switch *ds, case PHY_INTERFACE_MODE_NA: case PHY_INTERFACE_MODE_1000BASEX: case PHY_INTERFACE_MODE_2500BASEX: @@ -29,7 +29,7 @@ Signed-off-by: David S. Miller return mt7531_sgmii_setup_mode_force(priv, port, interface); default: return -EINVAL; -@@ -3030,13 +3027,6 @@ unsupported: +@@ -3057,13 +3054,6 @@ unsupported: return; } @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); mcr_new = mcr_cur; mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -3173,6 +3163,9 @@ static void mt753x_phylink_get_caps(stru +@@ -3200,6 +3190,9 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; @@ -53,7 +53,7 @@ Signed-off-by: David S. Miller /* This driver does not make use of the speed, duplex, pause or the * advertisement in its mac_config, so it is safe to mark this driver * as non-legacy. -@@ -3238,6 +3231,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3265,6 +3258,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); state->link = !!(status & MT7531_SGMII_LINK_STATUS); @@ -61,7 +61,7 @@ Signed-off-by: David S. Miller if (state->interface == PHY_INTERFACE_MODE_SGMII && (status & MT7531_SGMII_AN_ENABLE)) { val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -@@ -3268,16 +3262,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3295,16 +3289,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -109,7 +109,7 @@ Signed-off-by: David S. Miller } static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -3318,6 +3340,8 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3345,6 +3367,8 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; @@ -120,7 +120,7 @@ Signed-off-by: David S. Miller ret = priv->info->sw_setup(ds); --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -405,6 +405,7 @@ enum mt7530_vlan_port_acc_frm { +@@ -410,6 +410,7 @@ enum mt7530_vlan_port_acc_frm { #define MT7531_SGMII_LINK_STATUS BIT(18) #define MT7531_SGMII_AN_ENABLE BIT(12) #define MT7531_SGMII_AN_RESTART BIT(9) diff --git a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch index d8386fc3c..8060ad5af 100644 --- a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch +++ b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch @@ -81,7 +81,7 @@ Tested-by: Frank Wunderlich #include #include #include -@@ -2804,128 +2805,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2831,128 +2832,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -210,7 +210,7 @@ Tested-by: Frank Wunderlich static int mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -2948,11 +2832,11 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2975,11 +2859,11 @@ mt7531_mac_config(struct dsa_switch *ds, phydev = dp->slave->phydev; return mt7531_rgmii_setup(priv, port, interface, phydev); case PHY_INTERFACE_MODE_SGMII: @@ -224,7 +224,7 @@ Tested-by: Frank Wunderlich default: return -EINVAL; } -@@ -2977,11 +2861,11 @@ mt753x_phylink_mac_select_pcs(struct dsa +@@ -3004,11 +2888,11 @@ mt753x_phylink_mac_select_pcs(struct dsa switch (interface) { case PHY_INTERFACE_MODE_TRGMII: @@ -238,7 +238,7 @@ Tested-by: Frank Wunderlich default: return NULL; } -@@ -3222,86 +3106,6 @@ static void mt7530_pcs_get_state(struct +@@ -3249,86 +3133,6 @@ static void mt7530_pcs_get_state(struct state->pause |= MLO_PAUSE_TX; } @@ -325,7 +325,7 @@ Tested-by: Frank Wunderlich static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, phy_interface_t interface, const unsigned long *advertising, -@@ -3321,18 +3125,57 @@ static const struct phylink_pcs_ops mt75 +@@ -3348,18 +3152,57 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -389,7 +389,7 @@ Tested-by: Frank Wunderlich int i, ret; /* Initialise the PCS devices */ -@@ -3340,8 +3183,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3367,8 +3210,6 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; @@ -398,7 +398,7 @@ Tested-by: Frank Wunderlich } ret = priv->info->sw_setup(ds); -@@ -3356,6 +3197,16 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3383,6 +3224,16 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -415,7 +415,7 @@ Tested-by: Frank Wunderlich return ret; } -@@ -3447,7 +3298,7 @@ static const struct mt753x_info mt753x_t +@@ -3475,7 +3326,7 @@ static const struct mt753x_info mt753x_t }, [ID_MT7531] = { .id = ID_MT7531, @@ -424,7 +424,7 @@ Tested-by: Frank Wunderlich .sw_setup = mt7531_setup, .phy_read = mt7531_ind_phy_read, .phy_write = mt7531_ind_phy_write, -@@ -3555,7 +3406,7 @@ static void +@@ -3583,7 +3434,7 @@ static void mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); @@ -433,7 +433,7 @@ Tested-by: Frank Wunderlich if (!priv) return; -@@ -3574,6 +3425,10 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3602,6 +3453,10 @@ mt7530_remove(struct mdio_device *mdiode mt7530_free_irq(priv); dsa_unregister_switch(priv->ds); @@ -446,7 +446,7 @@ Tested-by: Frank Wunderlich dev_set_drvdata(&mdiodev->dev, NULL); --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -396,47 +396,8 @@ enum mt7530_vlan_port_acc_frm { +@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm { CCR_TX_OCT_CNT_BAD) /* MT7531 SGMII register group */ @@ -496,7 +496,7 @@ Tested-by: Frank Wunderlich /* Register for system reset */ #define MT7530_SYS_CTRL 0x7000 -@@ -735,13 +696,13 @@ struct mt7530_fdb { +@@ -741,13 +702,13 @@ struct mt7530_fdb { * @pm: The matrix used to show all connections with the port. * @pvid: The VLAN specified is to be considered a PVID at ingress. Any * untagged frames will be assigned to the related VLAN. diff --git a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch index 8311aaa0b..62d9c78cc 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3157,26 +3157,56 @@ static const struct regmap_bus mt7531_re +@@ -3184,26 +3184,56 @@ static const struct regmap_bus mt7531_re .reg_update_bits = mt7530_regmap_update_bits, }; @@ -88,7 +88,7 @@ Signed-off-by: David S. Miller int i, ret; /* Initialise the PCS devices */ -@@ -3198,15 +3228,11 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3225,15 +3255,11 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch index 7271f1023..e9f69a877 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3130,7 +3130,7 @@ static int mt7530_regmap_read(void *cont +@@ -3157,7 +3157,7 @@ static int mt7530_regmap_read(void *cont { struct mt7530_priv *priv = context; @@ -28,7 +28,7 @@ Signed-off-by: David S. Miller return 0; }; -@@ -3138,23 +3138,25 @@ static int mt7530_regmap_write(void *con +@@ -3165,23 +3165,25 @@ static int mt7530_regmap_write(void *con { struct mt7530_priv *priv = context; @@ -62,7 +62,7 @@ Signed-off-by: David S. Miller }; static int -@@ -3180,6 +3182,9 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -3207,6 +3209,9 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->reg_stride = 4; mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); mt7531_pcs_config[i]->max_register = 0x17c; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch index 2f761c2fa..a2dcc08b0 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch @@ -133,7 +133,7 @@ Signed-off-by: David S. Miller } static void -@@ -3126,22 +3147,6 @@ static const struct phylink_pcs_ops mt75 +@@ -3153,22 +3174,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -156,7 +156,7 @@ Signed-off-by: David S. Miller static void mt7530_mdio_regmap_lock(void *mdio_lock) { -@@ -3154,7 +3159,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc +@@ -3181,7 +3186,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc mutex_unlock(mdio_lock); } @@ -165,7 +165,7 @@ Signed-off-by: David S. Miller .reg_write = mt7530_regmap_write, .reg_read = mt7530_regmap_read, }; -@@ -3187,7 +3192,7 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -3214,7 +3219,7 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; regmap = devm_regmap_init(priv->dev, @@ -174,7 +174,7 @@ Signed-off-by: David S. Miller mt7531_pcs_config[i]); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); -@@ -3352,6 +3357,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) +@@ -3380,6 +3385,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) static int mt7530_probe(struct mdio_device *mdiodev) { @@ -182,7 +182,7 @@ Signed-off-by: David S. Miller struct mt7530_priv *priv; struct device_node *dn; -@@ -3431,6 +3437,21 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3459,6 +3465,21 @@ mt7530_probe(struct mdio_device *mdiodev mutex_init(&priv->reg_mutex); dev_set_drvdata(&mdiodev->dev, priv); @@ -206,7 +206,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -779,6 +779,7 @@ struct mt753x_info { +@@ -785,6 +785,7 @@ struct mt753x_info { * @dev: The device pointer * @ds: The pointer to the dsa core structure * @bus: The bus used for the device and built-in PHY @@ -214,7 +214,7 @@ Signed-off-by: David S. Miller * @rstc: The pointer to reset control used by MCM * @core_pwr: The power supplied into the core * @io_pwr: The power supplied into the I/O -@@ -799,6 +800,7 @@ struct mt7530_priv { +@@ -805,6 +806,7 @@ struct mt7530_priv { struct device *dev; struct dsa_switch *ds; struct mii_bus *bus; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch index 16feba1da..abbecd5e4 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3238,12 +3238,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3265,12 +3265,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -31,7 +31,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -3360,6 +3354,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3388,6 +3382,7 @@ mt7530_probe(struct mdio_device *mdiodev static struct regmap_config *regmap_config; struct mt7530_priv *priv; struct device_node *dn; @@ -39,7 +39,7 @@ Signed-off-by: David S. Miller dn = mdiodev->dev.of_node; -@@ -3452,6 +3447,12 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3480,6 +3475,12 @@ mt7530_probe(struct mdio_device *mdiodev if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch index dc4b40b82..ef02d4693 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch @@ -114,7 +114,7 @@ Signed-off-by: David S. Miller } static void -@@ -646,14 +650,13 @@ static int +@@ -660,14 +664,13 @@ static int mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, int regnum) { @@ -130,7 +130,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -686,7 +689,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr +@@ -700,7 +703,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr ret = val & MT7531_MDIO_RW_DATA_MASK; out: @@ -139,7 +139,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -695,14 +698,13 @@ static int +@@ -709,14 +712,13 @@ static int mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, int regnum, u32 data) { @@ -155,7 +155,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -734,7 +736,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p +@@ -748,7 +750,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p } out: @@ -164,7 +164,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -742,14 +744,13 @@ out: +@@ -756,14 +758,13 @@ out: static int mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) { @@ -180,7 +180,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -772,7 +773,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr +@@ -786,7 +787,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr ret = val & MT7531_MDIO_RW_DATA_MASK; out: @@ -189,7 +189,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -781,14 +782,13 @@ static int +@@ -795,14 +796,13 @@ static int mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, u16 data) { @@ -205,7 +205,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, !(reg & MT7531_PHY_ACS_ST), 20, 100000); -@@ -810,7 +810,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p +@@ -824,7 +824,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p } out: @@ -214,7 +214,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -1323,7 +1323,6 @@ static int +@@ -1344,7 +1344,6 @@ static int mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) { struct mt7530_priv *priv = ds->priv; @@ -222,7 +222,7 @@ Signed-off-by: David S. Miller int length; u32 val; -@@ -1334,7 +1333,7 @@ mt7530_port_change_mtu(struct dsa_switch +@@ -1355,7 +1354,7 @@ mt7530_port_change_mtu(struct dsa_switch if (!dsa_is_cpu_port(ds, port)) return 0; @@ -231,7 +231,7 @@ Signed-off-by: David S. Miller val = mt7530_mii_read(priv, MT7530_GMACCR); val &= ~MAX_RX_PKT_LEN_MASK; -@@ -1355,7 +1354,7 @@ mt7530_port_change_mtu(struct dsa_switch +@@ -1376,7 +1375,7 @@ mt7530_port_change_mtu(struct dsa_switch mt7530_mii_write(priv, MT7530_GMACCR, val); @@ -240,7 +240,7 @@ Signed-off-by: David S. Miller return 0; } -@@ -2151,10 +2150,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ +@@ -2172,10 +2171,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ u32 val; int p; @@ -253,7 +253,7 @@ Signed-off-by: David S. Miller for (p = 0; p < MT7530_NUM_PHYS; p++) { if (BIT(p) & val) { -@@ -2190,7 +2189,7 @@ mt7530_irq_bus_lock(struct irq_data *d) +@@ -2211,7 +2210,7 @@ mt7530_irq_bus_lock(struct irq_data *d) { struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); @@ -262,7 +262,7 @@ Signed-off-by: David S. Miller } static void -@@ -2199,7 +2198,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da +@@ -2220,7 +2219,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch index 265cf1fda..2e1ed2e65 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch @@ -21,7 +21,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -951,6 +951,24 @@ mt7530_set_ageing_time(struct dsa_switch +@@ -965,6 +965,24 @@ mt7530_set_ageing_time(struct dsa_switch return 0; } @@ -48,7 +48,7 @@ Signed-off-by: David S. Miller struct mt7530_priv *priv = ds->priv; --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -714,24 +714,6 @@ enum p5_interface_select { +@@ -720,24 +720,6 @@ enum p5_interface_select { P5_INTF_SEL_GMAC5_SGMII, }; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch index 10e2c6a18..c9ff26ff2 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3366,44 +3366,21 @@ static const struct of_device_id mt7530_ +@@ -3394,44 +3394,21 @@ static const struct of_device_id mt7530_ MODULE_DEVICE_TABLE(of, mt7530_of_match); static int @@ -67,7 +67,7 @@ Signed-off-by: David S. Miller if (!priv->info) return -EINVAL; -@@ -3417,23 +3394,53 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3445,23 +3422,53 @@ mt7530_probe(struct mdio_device *mdiodev return -EINVAL; priv->id = priv->info->id; @@ -131,7 +131,7 @@ Signed-off-by: David S. Miller priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(priv->reset)) { -@@ -3442,12 +3449,15 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3470,12 +3477,15 @@ mt7530_probe(struct mdio_device *mdiodev } } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch index 4e754b100..7c1c80e7b 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3484,6 +3484,17 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3512,6 +3512,17 @@ mt7530_probe(struct mdio_device *mdiodev } static void @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -@@ -3502,16 +3513,11 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3530,16 +3541,11 @@ mt7530_remove(struct mdio_device *mdiode dev_err(priv->dev, "Failed to disable io pwr: %d\n", ret); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch index 15e1f1c98..84883147a 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch @@ -68,8 +68,8 @@ Signed-off-by: David S. Miller obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o +obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o + realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o --- /dev/null +++ b/drivers/net/dsa/mt7530-mdio.c @@ -0,0 +1,271 @@ @@ -416,7 +416,7 @@ Signed-off-by: David S. Miller static u32 mt7530_mii_read(struct mt7530_priv *priv, u32 reg) { -@@ -3164,72 +3115,6 @@ static const struct phylink_pcs_ops mt75 +@@ -3191,72 +3142,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -489,7 +489,7 @@ Signed-off-by: David S. Miller static int mt753x_setup(struct dsa_switch *ds) { -@@ -3288,7 +3173,7 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3315,7 +3200,7 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -497,8 +497,8 @@ Signed-off-by: David S. Miller +const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, - .get_strings = mt7530_get_strings, -@@ -3322,8 +3207,9 @@ static const struct dsa_switch_ops mt753 + .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port, +@@ -3350,8 +3235,9 @@ static const struct dsa_switch_ops mt753 .get_mac_eee = mt753x_get_mac_eee, .set_mac_eee = mt753x_set_mac_eee, }; @@ -509,7 +509,7 @@ Signed-off-by: David S. Miller [ID_MT7621] = { .id = ID_MT7621, .pcs_ops = &mt7530_pcs_ops, -@@ -3356,16 +3242,9 @@ static const struct mt753x_info mt753x_t +@@ -3384,16 +3270,9 @@ static const struct mt753x_info mt753x_t .mac_port_config = mt7531_mac_config, }, }; @@ -528,7 +528,7 @@ Signed-off-by: David S. Miller mt7530_probe_common(struct mt7530_priv *priv) { struct device *dev = priv->dev; -@@ -3402,88 +3281,9 @@ mt7530_probe_common(struct mt7530_priv * +@@ -3430,88 +3309,9 @@ mt7530_probe_common(struct mt7530_priv * return 0; } @@ -619,7 +619,7 @@ Signed-off-by: David S. Miller mt7530_remove_common(struct mt7530_priv *priv) { if (priv->irq) -@@ -3494,57 +3294,6 @@ mt7530_remove_common(struct mt7530_priv +@@ -3522,57 +3322,6 @@ mt7530_remove_common(struct mt7530_priv mutex_destroy(&priv->reg_mutex); } @@ -679,7 +679,7 @@ Signed-off-by: David S. Miller MODULE_LICENSE("GPL"); --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -839,4 +839,10 @@ static inline void INIT_MT7530_DUMMY_POL +@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL p->reg = reg; } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch index f5758f7a6..c8417091f 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch @@ -76,8 +76,8 @@ Signed-off-by: David S. Miller obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o +obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o + realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o --- /dev/null +++ b/drivers/net/dsa/mt7530-mmio.c @@ -0,0 +1,101 @@ @@ -184,7 +184,7 @@ Signed-off-by: David S. Miller +MODULE_LICENSE("GPL"); --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2198,6 +2198,47 @@ static const struct irq_domain_ops mt753 +@@ -2219,6 +2219,47 @@ static const struct irq_domain_ops mt753 }; static void @@ -232,7 +232,7 @@ Signed-off-by: David S. Miller mt7530_setup_mdio_irq(struct mt7530_priv *priv) { struct dsa_switch *ds = priv->ds; -@@ -2231,8 +2272,15 @@ mt7530_setup_irq(struct mt7530_priv *pri +@@ -2252,8 +2293,15 @@ mt7530_setup_irq(struct mt7530_priv *pri return priv->irq ? : -EINVAL; } @@ -250,7 +250,7 @@ Signed-off-by: David S. Miller if (!priv->irq_domain) { dev_err(dev, "failed to create IRQ domain\n"); return -ENOMEM; -@@ -2727,6 +2775,25 @@ static void mt7531_mac_port_get_caps(str +@@ -2754,6 +2802,25 @@ static void mt7531_mac_port_get_caps(str } } @@ -276,7 +276,7 @@ Signed-off-by: David S. Miller static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -2803,6 +2870,17 @@ static bool mt753x_is_mac_port(u32 port) +@@ -2830,6 +2897,17 @@ static bool mt753x_is_mac_port(u32 port) } static int @@ -294,7 +294,7 @@ Signed-off-by: David S. Miller mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) { -@@ -2872,7 +2950,8 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2899,7 +2977,8 @@ mt753x_phylink_mac_config(struct dsa_swi switch (port) { case 0 ... 4: /* Internal phy */ @@ -304,7 +304,7 @@ Signed-off-by: David S. Miller goto unsupported; break; case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -@@ -2950,7 +3029,8 @@ static void mt753x_phylink_mac_link_up(s +@@ -2977,7 +3056,8 @@ static void mt753x_phylink_mac_link_up(s /* MT753x MAC works in 1G full duplex mode for all up-clocked * variants. */ @@ -314,7 +314,7 @@ Signed-off-by: David S. Miller (phy_interface_mode_is_8023z(interface))) { speed = SPEED_1000; duplex = DUPLEX_FULL; -@@ -3030,6 +3110,21 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -3057,6 +3137,21 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -336,7 +336,7 @@ Signed-off-by: David S. Miller static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { -@@ -3175,6 +3270,27 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3202,6 +3297,27 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -364,7 +364,7 @@ Signed-off-by: David S. Miller const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, -@@ -3243,6 +3359,17 @@ const struct mt753x_info mt753x_table[] +@@ -3271,6 +3387,17 @@ const struct mt753x_info mt753x_table[] .mac_port_get_caps = mt7531_mac_port_get_caps, .mac_port_config = mt7531_mac_config, }, @@ -392,9 +392,9 @@ Signed-off-by: David S. Miller }; #define NUM_TRGMII_CTRL 5 -@@ -54,11 +55,11 @@ enum mt753x_id { - #define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16) +@@ -59,11 +60,11 @@ enum mt753x_id { #define MT7531_CPU_PMAP_MASK GENMASK(7, 0) + #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x) -#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \ +#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ @@ -407,7 +407,7 @@ Signed-off-by: David S. Miller MT7531_MIRROR_MASK : MIRROR_MASK) /* Registers for BPDU and PAE frame control*/ -@@ -327,9 +328,8 @@ enum mt7530_vlan_port_acc_frm { +@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm { MT7531_FORCE_DPX | \ MT7531_FORCE_RX_FC | \ MT7531_FORCE_TX_FC) diff --git a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch index 49ac8d978..268964731 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch @@ -73,7 +73,7 @@ Signed-off-by: Jakub Kicinski } --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3237,6 +3237,12 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3264,6 +3264,12 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -88,7 +88,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -773,10 +773,10 @@ struct mt753x_info { +@@ -779,10 +779,10 @@ struct mt753x_info { * registers * @p6_interface Holding the current port 6 interface * @p5_intf_sel: Holding the current port 5 interface select @@ -100,7 +100,7 @@ Signed-off-by: Jakub Kicinski */ struct mt7530_priv { struct device *dev; -@@ -795,7 +795,6 @@ struct mt7530_priv { +@@ -801,7 +801,6 @@ struct mt7530_priv { unsigned int p5_intf_sel; u8 mirror_rx; u8 mirror_tx; @@ -108,7 +108,7 @@ Signed-off-by: Jakub Kicinski struct mt7530_port ports[MT7530_NUM_PORTS]; struct mt753x_pcs pcs[MT7530_NUM_PORTS]; /* protect among processes for registers access*/ -@@ -803,6 +802,7 @@ struct mt7530_priv { +@@ -809,6 +808,7 @@ struct mt7530_priv { int irq; struct irq_domain *irq_domain; u32 irq_enable; diff --git a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch b/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch new file mode 100644 index 000000000..f6ecf4b97 --- /dev/null +++ b/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch @@ -0,0 +1,81 @@ +From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Mon, 27 Jun 2022 12:44:43 +0100 +Subject: [PATCH] net: phylink: disable PCS polling over major configuration + +While we are performing a major configuration, there is no point having +the PCS polling timer running. Stop it before we begin preparing for +the configuration change, and restart it only once we've successfully +completed the change. + +Reviewed-by: Andrew Lunn +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/phylink.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -767,6 +767,18 @@ static void phylink_resolve_flow(struct + } + } + ++static void phylink_pcs_poll_stop(struct phylink *pl) ++{ ++ if (pl->cfg_link_an_mode == MLO_AN_INBAND) ++ del_timer(&pl->link_poll); ++} ++ ++static void phylink_pcs_poll_start(struct phylink *pl) ++{ ++ if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) ++ mod_timer(&pl->link_poll, jiffies + HZ); ++} ++ + static void phylink_mac_config(struct phylink *pl, + const struct phylink_link_state *state) + { +@@ -798,6 +810,7 @@ static void phylink_major_config(struct + const struct phylink_link_state *state) + { + struct phylink_pcs *pcs = NULL; ++ bool pcs_changed = false; + int err; + + phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); +@@ -810,8 +823,12 @@ static void phylink_major_config(struct + pcs); + return; + } ++ ++ pcs_changed = pcs && pl->pcs != pcs; + } + ++ phylink_pcs_poll_stop(pl); ++ + if (pl->mac_ops->mac_prepare) { + err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, + state->interface); +@@ -825,8 +842,10 @@ static void phylink_major_config(struct + /* If we have a new PCS, switch to the new PCS after preparing the MAC + * for the change. + */ +- if (pcs) +- phylink_set_pcs(pl, pcs); ++ if (pcs_changed) { ++ pl->pcs = pcs; ++ pl->pcs_ops = pcs->ops; ++ } + + phylink_mac_config(pl, state); + +@@ -852,6 +871,8 @@ static void phylink_major_config(struct + phylink_err(pl, "mac_finish failed: %pe\n", + ERR_PTR(err)); + } ++ ++ phylink_pcs_poll_start(pl); + } + + /* diff --git a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch b/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch new file mode 100644 index 000000000..e5f282c5c --- /dev/null +++ b/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch @@ -0,0 +1,38 @@ +From b7d78b46d5e8dc77c656c13885d31e931923b915 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Wed, 29 Jun 2022 22:33:58 +0300 +Subject: [PATCH] net: phylink: fix NULL pl->pcs dereference during + phylink_pcs_poll_start + +The current link mode of the phylink instance may not require an +attached PCS. However, phylink_major_config() unconditionally +dereferences this potentially NULL pointer when restarting the link poll +timer, which will panic the kernel. + +Fix the problem by checking whether a PCS exists in phylink_pcs_poll_start(), +otherwise do nothing. The code prior to the blamed patch also only +looked at pcs->poll within an "if (pcs)" block. + +Fixes: bfac8c490d60 ("net: phylink: disable PCS polling over major configuration") +Signed-off-by: Vladimir Oltean +Reviewed-by: Russell King (Oracle) +Tested-by: Gerhard Engleder +Tested-by: Michael Walle # on kontron-kbox-a-230-ls +Tested-by: Nicolas Ferre # on sam9x60ek +Link: https://lore.kernel.org/r/20220629193358.4007923-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/phylink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -775,7 +775,7 @@ static void phylink_pcs_poll_stop(struct + + static void phylink_pcs_poll_start(struct phylink *pl) + { +- if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) ++ if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) + mod_timer(&pl->link_poll, jiffies + HZ); + } + diff --git a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch new file mode 100644 index 000000000..1c936767d --- /dev/null +++ b/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch @@ -0,0 +1,172 @@ +From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 13 Jul 2023 09:42:07 +0100 +Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods + +Add phylink PCS enable/disable callbacks that will allow us to place +IEEE 802.3 register compliant PCS in power-down mode while not being +used. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: David S. Miller +--- + drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++-------- + include/linux/phylink.h | 16 +++++++++++++ + 2 files changed, 55 insertions(+), 9 deletions(-) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -34,6 +34,10 @@ enum { + PHYLINK_DISABLE_STOPPED, + PHYLINK_DISABLE_LINK, + PHYLINK_DISABLE_MAC_WOL, ++ ++ PCS_STATE_DOWN = 0, ++ PCS_STATE_STARTING, ++ PCS_STATE_STARTED, + }; + + /** +@@ -72,6 +76,7 @@ struct phylink { + struct mutex state_mutex; + struct phylink_link_state phy_state; + struct work_struct resolve; ++ unsigned int pcs_state; + + bool mac_link_dropped; + bool using_mac_select_pcs; +@@ -806,6 +811,22 @@ static void phylink_mac_pcs_an_restart(s + } + } + ++static void phylink_pcs_disable(struct phylink_pcs *pcs) ++{ ++ if (pcs && pcs->ops->pcs_disable) ++ pcs->ops->pcs_disable(pcs); ++} ++ ++static int phylink_pcs_enable(struct phylink_pcs *pcs) ++{ ++ int err = 0; ++ ++ if (pcs && pcs->ops->pcs_enable) ++ err = pcs->ops->pcs_enable(pcs); ++ ++ return err; ++} ++ + static void phylink_major_config(struct phylink *pl, bool restart, + const struct phylink_link_state *state) + { +@@ -843,12 +864,16 @@ static void phylink_major_config(struct + * for the change. + */ + if (pcs_changed) { ++ phylink_pcs_disable(pl->pcs); + pl->pcs = pcs; + pl->pcs_ops = pcs->ops; + } + + phylink_mac_config(pl, state); + ++ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) ++ phylink_pcs_enable(pl->pcs); ++ + if (pl->pcs_ops) { + err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, + state->interface, +@@ -1272,6 +1297,7 @@ struct phylink *phylink_create(struct ph + pl->link_config.speed = SPEED_UNKNOWN; + pl->link_config.duplex = DUPLEX_UNKNOWN; + pl->link_config.an_enabled = true; ++ pl->pcs_state = PCS_STATE_DOWN; + pl->mac_ops = mac_ops; + __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); + timer_setup(&pl->link_poll, phylink_fixed_poll, 0); +@@ -1663,6 +1689,8 @@ void phylink_start(struct phylink *pl) + if (pl->netdev) + netif_carrier_off(pl->netdev); + ++ pl->pcs_state = PCS_STATE_STARTING; ++ + /* Apply the link configuration to the MAC when starting. This allows + * a fixed-link to start with the correct parameters, and also + * ensures that we set the appropriate advertisement for Serdes links. +@@ -1673,6 +1701,8 @@ void phylink_start(struct phylink *pl) + */ + phylink_mac_initial_config(pl, true); + ++ pl->pcs_state = PCS_STATE_STARTED; ++ + clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); + phylink_run_resolve(pl); + +@@ -1692,16 +1722,9 @@ void phylink_start(struct phylink *pl) + poll = true; + } + +- switch (pl->cfg_link_an_mode) { +- case MLO_AN_FIXED: ++ if (pl->cfg_link_an_mode == MLO_AN_FIXED) + poll |= pl->config->poll_fixed_state; +- break; +- case MLO_AN_INBAND: +- poll |= pl->config->pcs_poll; +- if (pl->pcs) +- poll |= pl->pcs->poll; +- break; +- } ++ + if (poll) + mod_timer(&pl->link_poll, jiffies + HZ); + if (pl->phydev) +@@ -1738,6 +1761,10 @@ void phylink_stop(struct phylink *pl) + } + + phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); ++ ++ pl->pcs_state = PCS_STATE_DOWN; ++ ++ phylink_pcs_disable(pl->pcs); + } + EXPORT_SYMBOL_GPL(phylink_stop); + +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -419,6 +419,8 @@ struct phylink_pcs { + /** + * struct phylink_pcs_ops - MAC PCS operations structure. + * @pcs_validate: validate the link configuration. ++ * @pcs_enable: enable the PCS. ++ * @pcs_disable: disable the PCS. + * @pcs_get_state: read the current MAC PCS link state from the hardware. + * @pcs_config: configure the MAC PCS for the selected mode and state. + * @pcs_an_restart: restart 802.3z BaseX autonegotiation. +@@ -428,6 +430,8 @@ struct phylink_pcs { + struct phylink_pcs_ops { + int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, + const struct phylink_link_state *state); ++ int (*pcs_enable)(struct phylink_pcs *pcs); ++ void (*pcs_disable)(struct phylink_pcs *pcs); + void (*pcs_get_state)(struct phylink_pcs *pcs, + struct phylink_link_state *state); + int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, +@@ -458,6 +462,18 @@ int pcs_validate(struct phylink_pcs *pcs + const struct phylink_link_state *state); + + /** ++ * pcs_enable() - enable the PCS. ++ * @pcs: a pointer to a &struct phylink_pcs. ++ */ ++int pcs_enable(struct phylink_pcs *pcs); ++ ++/** ++ * pcs_disable() - disable the PCS. ++ * @pcs: a pointer to a &struct phylink_pcs. ++ */ ++void pcs_disable(struct phylink_pcs *pcs); ++ ++/** + * pcs_get_state() - Read the current inband link state from the hardware + * @pcs: a pointer to a &struct phylink_pcs. + * @state: a pointer to a &struct phylink_link_state. diff --git a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch new file mode 100644 index 000000000..eb9b4b7c0 --- /dev/null +++ b/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch @@ -0,0 +1,44 @@ +From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 18 Aug 2023 04:07:46 +0100 +Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op + +When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface +modes provided by mtk-pcs-lynxi we need to make sure to always perform +a full configuration of the PHYA. + +Implement pcs_disable op which resets the stored interface mode to +PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI +PCS driver had previously been deselected in favor of another PCS +driver such as the to-be-added driver for the USXGMII PCS found in +MT7988. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/pcs/pcs-mtk-lynxi.c ++++ b/drivers/net/pcs/pcs-mtk-lynxi.c +@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct + } + } + ++static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ ++ mpcs->interface = PHY_INTERFACE_MODE_NA; ++} ++ + static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { + .pcs_get_state = mtk_pcs_lynxi_get_state, + .pcs_config = mtk_pcs_lynxi_config, + .pcs_an_restart = mtk_pcs_lynxi_restart_an, + .pcs_link_up = mtk_pcs_lynxi_link_up, ++ .pcs_disable = mtk_pcs_lynxi_disable, + }; + + struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, diff --git a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch b/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch index 698e524c3..b2af169b9 100644 --- a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch +++ b/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller ax88179_reset(dev); -@@ -1507,17 +1508,19 @@ ax88179_tx_fixup(struct usbnet *dev, str +@@ -1502,17 +1503,19 @@ ax88179_tx_fixup(struct usbnet *dev, str { u32 tx_hdr1, tx_hdr2; int frame_size = dev->maxpacket; @@ -57,7 +57,7 @@ Signed-off-by: David S. Miller if ((skb_header_cloned(skb) || headroom < 0) && pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) { dev_kfree_skb_any(skb); -@@ -1528,6 +1531,8 @@ ax88179_tx_fixup(struct usbnet *dev, str +@@ -1523,6 +1526,8 @@ ax88179_tx_fixup(struct usbnet *dev, str put_unaligned_le32(tx_hdr1, ptr); put_unaligned_le32(tx_hdr2, ptr + 4); diff --git a/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch new file mode 100644 index 000000000..592111fb9 --- /dev/null +++ b/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch @@ -0,0 +1,39 @@ +From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 3 Jan 2023 15:12:47 +0200 +Subject: [PATCH] leds: Move led_init_default_state_get() to the global header + +There are users inside and outside LED framework that have implemented +a local copy of led_init_default_state_get(). In order to deduplicate +that, as the first step move the declaration from LED header to the +global one. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com +--- + drivers/leds/leds.h | 1 - + include/linux/leds.h | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/leds/leds.h ++++ b/drivers/leds/leds.h +@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi + ssize_t led_trigger_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t pos, size_t count); +-enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); + + extern struct rw_semaphore leds_list_lock; + extern struct list_head leds_list; +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -63,6 +63,8 @@ struct led_init_data { + bool devname_mandatory; + }; + ++enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); ++ + struct led_hw_trigger_type { + int dummy; + }; diff --git a/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch new file mode 100644 index 000000000..9fadade05 --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch @@ -0,0 +1,67 @@ +From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:23 +0200 +Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header + +Move qca8k_port_to_phy() to qca8k header as it's useful for future +reference in Switch LEDs module since the same logic is applied to get +the right index of the switch port. +Make it inline as it's simple function that just decrease the port. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Reviewed-by: Michal Kubiak +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 15 --------------- + drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++ + 2 files changed, 14 insertions(+), 15 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -633,21 +633,6 @@ err_clear_skb: + return ret; + } + +-static u32 +-qca8k_port_to_phy(int port) +-{ +- /* From Andrew Lunn: +- * Port 0 has no internal phy. +- * Port 1 has an internal PHY at MDIO address 0. +- * Port 2 has an internal PHY at MDIO address 1. +- * ... +- * Port 5 has an internal PHY at MDIO address 4. +- * Port 6 has no internal PHY. +- */ +- +- return port - 1; +-} +- + static int + qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) + { +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -419,6 +419,20 @@ struct qca8k_fdb { + u8 mac[6]; + }; + ++static inline u32 qca8k_port_to_phy(int port) ++{ ++ /* From Andrew Lunn: ++ * Port 0 has no internal phy. ++ * Port 1 has an internal PHY at MDIO address 0. ++ * Port 2 has an internal PHY at MDIO address 1. ++ * ... ++ * Port 5 has an internal PHY at MDIO address 4. ++ * Port 6 has no internal PHY. ++ */ ++ ++ return port - 1; ++} ++ + /* Common setup function */ + extern const struct qca8k_mib_desc ar8327_mib[]; + extern const struct regmap_access_table qca8k_readable_table; diff --git a/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch new file mode 100644 index 000000000..cf57ad016 --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch @@ -0,0 +1,435 @@ +From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:24 +0200 +Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support + +Add LEDs basic support for qca8k Switch Family by adding basic +brightness_set() support. + +Since these LEDs refelect port status, the default label is set to +":port". DT binding should describe the color and function of the +LEDs using standard LEDs api. +Each LED always have the device name as prefix. The device name is +composed from the mii bus id and the PHY addr resulting in example +names like: +- qca8k-0.0:00:amber:lan +- qca8k-0.0:00:white:lan +- qca8k-0.0:01:amber:lan +- qca8k-0.0:01:white:lan + +These LEDs supports only blocking variant of the brightness_set() +function since they can sleep during access of the switch leds to set +the brightness. + +While at it add to the qca8k header file each mode defined by the Switch +Documentation for future use. + +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/Kconfig | 8 ++ + drivers/net/dsa/qca/Makefile | 3 + + drivers/net/dsa/qca/qca8k-8xxx.c | 5 + + drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 60 ++++++++ + drivers/net/dsa/qca/qca8k_leds.h | 16 +++ + 6 files changed, 331 insertions(+) + create mode 100644 drivers/net/dsa/qca/qca8k-leds.c + create mode 100644 drivers/net/dsa/qca/qca8k_leds.h + +--- a/drivers/net/dsa/qca/Kconfig ++++ b/drivers/net/dsa/qca/Kconfig +@@ -15,3 +15,11 @@ config NET_DSA_QCA8K + help + This enables support for the Qualcomm Atheros QCA8K Ethernet + switch chips. ++ ++config NET_DSA_QCA8K_LEDS_SUPPORT ++ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support" ++ depends on NET_DSA_QCA8K ++ depends on LEDS_CLASS ++ help ++ This enabled support for LEDs present on the Qualcomm Atheros ++ QCA8K Ethernet switch chips. +--- a/drivers/net/dsa/qca/Makefile ++++ b/drivers/net/dsa/qca/Makefile +@@ -2,3 +2,6 @@ + obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o + obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o + qca8k-y += qca8k-common.o qca8k-8xxx.o ++ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT ++qca8k-y += qca8k-leds.o ++endif +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -22,6 +22,7 @@ + #include + + #include "qca8k.h" ++#include "qca8k_leds.h" + + static void + qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) +@@ -1102,6 +1103,10 @@ qca8k_setup(struct dsa_switch *ds) + if (ret) + return ret; + ++ ret = qca8k_setup_led_ctrl(priv); ++ if (ret) ++ return ret; ++ + /* Make sure MAC06 is disabled */ + ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, + QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -0,0 +1,239 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++#include ++ ++#include "qca8k.h" ++#include "qca8k_leds.h" ++ ++static int ++qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) ++{ ++ switch (port_num) { ++ case 0: ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ /* Port 123 are controlled on a different reg */ ++ reg_info->reg = QCA8K_LED_CTRL3_REG; ++ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num); ++ break; ++ case 4: ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_led_brightness_set(struct qca8k_led *led, ++ enum led_brightness brightness) ++{ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 mask, val; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ val = QCA8K_LED_ALWAYS_OFF; ++ if (brightness) ++ val = QCA8K_LED_ALWAYS_ON; ++ ++ /* HW regs to control brightness is special and port 1-2-3 ++ * are placed in a different reg. ++ * ++ * To control port 0 brightness: ++ * - the 2 bit (15, 14) of: ++ * - QCA8K_LED_CTRL0_REG for led1 ++ * - QCA8K_LED_CTRL1_REG for led2 ++ * - QCA8K_LED_CTRL2_REG for led3 ++ * ++ * To control port 4: ++ * - the 2 bit (31, 30) of: ++ * - QCA8K_LED_CTRL0_REG for led1 ++ * - QCA8K_LED_CTRL1_REG for led2 ++ * - QCA8K_LED_CTRL2_REG for led3 ++ * ++ * To control port 1: ++ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To control port 2: ++ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To control port 3: ++ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To abstract this and have less code, we use the port and led numm ++ * to calculate the shift and the correct reg due to this problem of ++ * not having a 1:1 map of LED with the regs. ++ */ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, ++ mask << reg_info.shift, ++ val << reg_info.shift); ++} ++ ++static int ++qca8k_cled_brightness_set_blocking(struct led_classdev *ldev, ++ enum led_brightness brightness) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ return qca8k_led_brightness_set(led, brightness); ++} ++ ++static enum led_brightness ++qca8k_led_brightness_get(struct qca8k_led *led) ++{ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ int ret; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ ret = regmap_read(priv->regmap, reg_info.reg, &val); ++ if (ret) ++ return 0; ++ ++ val >>= reg_info.shift; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ val &= QCA8K_LED_PATTERN_EN_MASK; ++ val >>= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ /* Assume brightness ON only when the LED is set to always ON */ ++ return val == QCA8K_LED_ALWAYS_ON; ++} ++ ++static int ++qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) ++{ ++ struct fwnode_handle *led = NULL, *leds = NULL; ++ struct led_init_data init_data = { }; ++ struct dsa_switch *ds = priv->ds; ++ enum led_default_state state; ++ struct qca8k_led *port_led; ++ int led_num, led_index; ++ int ret; ++ ++ leds = fwnode_get_named_child_node(port, "leds"); ++ if (!leds) { ++ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n", ++ port_num); ++ return 0; ++ } ++ ++ fwnode_for_each_child_node(leds, led) { ++ /* Reg represent the led number of the port. ++ * Each port can have at most 3 leds attached ++ * Commonly: ++ * 1. is gigabit led ++ * 2. is mbit led ++ * 3. additional status led ++ */ ++ if (fwnode_property_read_u32(led, "reg", &led_num)) ++ continue; ++ ++ if (led_num >= QCA8K_LED_PORT_COUNT) { ++ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", ++ led_num, port_num); ++ continue; ++ } ++ ++ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num); ++ ++ port_led = &priv->ports_led[led_index]; ++ port_led->port_num = port_num; ++ port_led->led_num = led_num; ++ port_led->priv = priv; ++ ++ state = led_init_default_state_get(led); ++ switch (state) { ++ case LEDS_DEFSTATE_ON: ++ port_led->cdev.brightness = 1; ++ qca8k_led_brightness_set(port_led, 1); ++ break; ++ case LEDS_DEFSTATE_KEEP: ++ port_led->cdev.brightness = ++ qca8k_led_brightness_get(port_led); ++ break; ++ default: ++ port_led->cdev.brightness = 0; ++ qca8k_led_brightness_set(port_led, 0); ++ } ++ ++ port_led->cdev.max_brightness = 1; ++ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; ++ init_data.default_label = ":port"; ++ init_data.fwnode = led; ++ init_data.devname_mandatory = true; ++ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id, ++ port_num); ++ if (!init_data.devicename) ++ return -ENOMEM; ++ ++ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); ++ if (ret) ++ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num); ++ ++ kfree(init_data.devicename); ++ } ++ ++ return 0; ++} ++ ++int ++qca8k_setup_led_ctrl(struct qca8k_priv *priv) ++{ ++ struct fwnode_handle *ports, *port; ++ int port_num; ++ int ret; ++ ++ ports = device_get_named_child_node(priv->dev, "ports"); ++ if (!ports) { ++ dev_info(priv->dev, "No ports node specified in device tree!"); ++ return 0; ++ } ++ ++ fwnode_for_each_child_node(ports, port) { ++ if (fwnode_property_read_u32(port, "reg", &port_num)) ++ continue; ++ ++ /* Skip checking for CPU port 0 and CPU port 6 as not supported */ ++ if (port_num == 0 || port_num == 6) ++ continue; ++ ++ /* Each port can have at most 3 different leds attached. ++ * Switch port starts from 0 to 6, but port 0 and 6 are CPU ++ * port. The port index needs to be decreased by one to identify ++ * the correct port for LED setup. ++ */ ++ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num)); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + + #define QCA8K_ETHERNET_MDIO_PRIORITY 7 +@@ -85,6 +86,51 @@ + #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) + #define QCA8K_MDIO_MASTER_MAX_PORTS 5 + #define QCA8K_MDIO_MASTER_MAX_REG 32 ++ ++/* LED control register */ ++#define QCA8K_LED_PORT_COUNT 3 ++#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT) ++#define QCA8K_LED_RULE_COUNT 6 ++#define QCA8K_LED_RULE_MAX 11 ++#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led)) ++ ++#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led))) ++#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0) ++ ++#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0 ++#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16 ++ ++#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4) ++#define QCA8K_LED_CTRL0_REG 0x50 ++#define QCA8K_LED_CTRL1_REG 0x54 ++#define QCA8K_LED_CTRL2_REG 0x58 ++#define QCA8K_LED_CTRL3_REG 0x5C ++#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16) ++#define QCA8K_LED_CTRL_MASK GENMASK(15, 0) ++#define QCA8K_LED_RULE_MASK GENMASK(13, 0) ++#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0) ++#define QCA8K_LED_BLINK_FREQ_SHITF 0 ++#define QCA8K_LED_BLINK_2HZ 0 ++#define QCA8K_LED_BLINK_4HZ 1 ++#define QCA8K_LED_BLINK_8HZ 2 ++#define QCA8K_LED_BLINK_AUTO 3 ++#define QCA8K_LED_LINKUP_OVER_MASK BIT(2) ++#define QCA8K_LED_TX_BLINK_MASK BIT(4) ++#define QCA8K_LED_RX_BLINK_MASK BIT(5) ++#define QCA8K_LED_COL_BLINK_MASK BIT(7) ++#define QCA8K_LED_LINK_10M_EN_MASK BIT(8) ++#define QCA8K_LED_LINK_100M_EN_MASK BIT(9) ++#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10) ++#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11) ++#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12) ++#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13) ++#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14) ++#define QCA8K_LED_PATTERN_EN_SHIFT 14 ++#define QCA8K_LED_ALWAYS_OFF 0 ++#define QCA8K_LED_ALWAYS_BLINK_4HZ 1 ++#define QCA8K_LED_ALWAYS_ON 2 ++#define QCA8K_LED_RULE_CONTROLLED 3 ++ + #define QCA8K_GOL_MAC_ADDR0 0x60 + #define QCA8K_GOL_MAC_ADDR1 0x64 + #define QCA8K_MAX_FRAME_SIZE 0x78 +@@ -382,6 +428,19 @@ struct qca8k_mdio_cache { + u16 hi; + }; + ++struct qca8k_led_pattern_en { ++ u32 reg; ++ u8 shift; ++}; ++ ++struct qca8k_led { ++ u8 port_num; ++ u8 led_num; ++ u16 old_rule; ++ struct qca8k_priv *priv; ++ struct led_classdev cdev; ++}; ++ + struct qca8k_priv { + u8 switch_id; + u8 switch_revision; +@@ -404,6 +463,7 @@ struct qca8k_priv { + struct qca8k_mib_eth_data mib_eth_data; + struct qca8k_mdio_cache mdio_cache; + const struct qca8k_match_data *info; ++ struct qca8k_led ports_led[QCA8K_LED_COUNT]; + }; + + struct qca8k_mib_desc { +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k_leds.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef __QCA8K_LEDS_H ++#define __QCA8K_LEDS_H ++ ++/* Leds Support function */ ++#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT ++int qca8k_setup_led_ctrl(struct qca8k_priv *priv); ++#else ++static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv) ++{ ++ return 0; ++} ++#endif ++ ++#endif /* __QCA8K_LEDS_H */ diff --git a/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch new file mode 100644 index 000000000..231c4156d --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch @@ -0,0 +1,74 @@ +From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:25 +0200 +Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support + +Add LEDs blink_set() support to qca8k Switch Family. +These LEDs support hw accellerated blinking at a fixed rate +of 4Hz. + +Reject any other value since not supported by the LEDs switch. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Acked-by: Pavel Machek +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le + } + + static int ++qca8k_cled_blink_set(struct led_classdev *ldev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ; ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ ++ if (*delay_on == 0 && *delay_off == 0) { ++ *delay_on = 125; ++ *delay_off = 125; ++ } ++ ++ if (*delay_on != 125 || *delay_off != 125) { ++ /* The hardware only supports blinking at 4Hz. Fall back ++ * to software implementation in other cases. ++ */ ++ return -EINVAL; ++ } ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, ++ val << reg_info.shift); ++ ++ return 0; ++} ++ ++static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { + struct fwnode_handle *led = NULL, *leds = NULL; +@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv + + port_led->cdev.max_brightness = 1; + port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; ++ port_led->cdev.blink_set = qca8k_cled_blink_set; + init_data.default_label = ":port"; + init_data.fwnode = led; + init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch new file mode 100644 index 000000000..bc905b446 --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch @@ -0,0 +1,59 @@ +From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:26 +0200 +Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are + disabled + +Provide stubs for devm_led_classdev_register_ext() and +led_init_default_state_get() so that LED drivers embedded within other +drivers such as PHYs and Ethernet switches still build when LEDS_CLASS +or NEW_LEDS are disabled. This also helps with Kconfig dependencies, +which are somewhat hairy for phylib and mdio and only get worse when +adding a dependency on LED_CLASS. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -63,7 +63,15 @@ struct led_init_data { + bool devname_mandatory; + }; + ++#if IS_ENABLED(CONFIG_NEW_LEDS) + enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); ++#else ++static inline enum led_default_state ++led_init_default_state_get(struct fwnode_handle *fwnode) ++{ ++ return LEDS_DEFSTATE_OFF; ++} ++#endif + + struct led_hw_trigger_type { + int dummy; +@@ -198,9 +206,19 @@ static inline int led_classdev_register( + return led_classdev_register_ext(parent, led_cdev, NULL); + } + ++#if IS_ENABLED(CONFIG_LEDS_CLASS) + int devm_led_classdev_register_ext(struct device *parent, + struct led_classdev *led_cdev, + struct led_init_data *init_data); ++#else ++static inline int ++devm_led_classdev_register_ext(struct device *parent, ++ struct led_classdev *led_cdev, ++ struct led_init_data *init_data) ++{ ++ return 0; ++} ++#endif + + static inline int devm_led_classdev_register(struct device *parent, + struct led_classdev *led_cdev) diff --git a/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch new file mode 100644 index 000000000..3e60f91a2 --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch @@ -0,0 +1,191 @@ +From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:27 +0200 +Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs + +Define common binding parsing for all PHY drivers with LEDs using +phylib. Parse the DT as part of the phy_probe and add LEDs to the +linux LED class infrastructure. For the moment, provide a dummy +brightness function, which will later be replaced with a call into the +PHY driver. This allows testing since the LED core might otherwise +reject an LED whose brightness cannot be set. + +Add a dependency on LED_CLASS. It either needs to be built in, or not +enabled, since a modular build can result in linker errors. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/Kconfig | 1 + + drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 16 ++++++++ + 3 files changed, 93 insertions(+) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -18,6 +18,7 @@ menuconfig PHYLIB + depends on NETDEVICES + select MDIO_DEVICE + select MDIO_DEVRES ++ depends on LEDS_CLASS || LEDS_CLASS=n + help + Ethernet controllers are usually attached to PHY + devices. This option provides infrastructure for +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -19,10 +19,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -641,6 +643,7 @@ struct phy_device *phy_device_create(str + device_initialize(&mdiodev->dev); + + dev->state = PHY_DOWN; ++ INIT_LIST_HEAD(&dev->leds); + + mutex_init(&dev->lock); + INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); +@@ -2942,6 +2945,74 @@ static bool phy_drv_supports_irq(struct + return phydrv->config_intr && phydrv->handle_interrupt; + } + ++/* Dummy implementation until calls into PHY driver are added */ ++static int phy_led_set_brightness(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ return 0; ++} ++ ++static int of_phy_led(struct phy_device *phydev, ++ struct device_node *led) ++{ ++ struct device *dev = &phydev->mdio.dev; ++ struct led_init_data init_data = {}; ++ struct led_classdev *cdev; ++ struct phy_led *phyled; ++ int err; ++ ++ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); ++ if (!phyled) ++ return -ENOMEM; ++ ++ cdev = &phyled->led_cdev; ++ ++ err = of_property_read_u8(led, "reg", &phyled->index); ++ if (err) ++ return err; ++ ++ cdev->brightness_set_blocking = phy_led_set_brightness; ++ cdev->max_brightness = 1; ++ init_data.devicename = dev_name(&phydev->mdio.dev); ++ init_data.fwnode = of_fwnode_handle(led); ++ init_data.devname_mandatory = true; ++ ++ err = devm_led_classdev_register_ext(dev, cdev, &init_data); ++ if (err) ++ return err; ++ ++ list_add(&phyled->list, &phydev->leds); ++ ++ return 0; ++} ++ ++static int of_phy_leds(struct phy_device *phydev) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ struct device_node *leds, *led; ++ int err; ++ ++ if (!IS_ENABLED(CONFIG_OF_MDIO)) ++ return 0; ++ ++ if (!node) ++ return 0; ++ ++ leds = of_get_child_by_name(node, "leds"); ++ if (!leds) ++ return 0; ++ ++ for_each_available_child_of_node(leds, led) { ++ err = of_phy_led(phydev, led); ++ if (err) { ++ of_node_put(led); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ + /** + * fwnode_mdio_find_device - Given a fwnode, find the mdio_device + * @fwnode: pointer to the mdio_device's fwnode +@@ -3120,6 +3191,11 @@ static int phy_probe(struct device *dev) + /* Set the state to READY by default */ + phydev->state = PHY_READY; + ++ /* Get the LEDs from the device tree, and instantiate standard ++ * LEDs for them. ++ */ ++ err = of_phy_leds(phydev); ++ + out: + /* Re-assert the reset signal on error */ + if (err) +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -582,6 +583,7 @@ struct macsec_ops; + * @phy_num_led_triggers: Number of triggers in @phy_led_triggers + * @led_link_trigger: LED trigger for link up/down + * @last_triggered: last LED trigger for link speed ++ * @leds: list of PHY LED structures + * @master_slave_set: User requested master/slave configuration + * @master_slave_get: Current master/slave advertisement + * @master_slave_state: Current master/slave configuration +@@ -668,6 +670,7 @@ struct phy_device { + + struct phy_led_trigger *led_link_trigger; + #endif ++ struct list_head leds; + + /* + * Interrupt number for this PHY +@@ -739,6 +742,19 @@ struct phy_tdr_config { + #define PHY_PAIR_ALL -1 + + /** ++ * struct phy_led: An LED driven by the PHY ++ * ++ * @list: List of LEDs ++ * @led_cdev: Standard LED class structure ++ * @index: Number of the LED ++ */ ++struct phy_led { ++ struct list_head list; ++ struct led_classdev led_cdev; ++ u8 index; ++}; ++ ++/** + * struct phy_driver - Driver structure for a particular PHY type + * + * @mdiodrv: Data common to all MDIO devices diff --git a/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch new file mode 100644 index 000000000..f990557cc --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -0,0 +1,97 @@ +From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:28 +0200 +Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED + brightness + +Linux LEDs can be software controlled via the brightness file in /sys. +LED drivers need to implement a brightness_set function which the core +will call. Implement an intermediary in phy_device, which will call +into the phy driver if it implements the necessary function. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 15 ++++++++++++--- + include/linux/phy.h | 13 +++++++++++++ + 2 files changed, 25 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2945,11 +2945,18 @@ static bool phy_drv_supports_irq(struct + return phydrv->config_intr && phydrv->handle_interrupt; + } + +-/* Dummy implementation until calls into PHY driver are added */ + static int phy_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness value) + { +- return 0; ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_brightness_set(phydev, phyled->index, value); ++ mutex_unlock(&phydev->lock); ++ ++ return err; + } + + static int of_phy_led(struct phy_device *phydev, +@@ -2966,12 +2973,14 @@ static int of_phy_led(struct phy_device + return -ENOMEM; + + cdev = &phyled->led_cdev; ++ phyled->phydev = phydev; + + err = of_property_read_u8(led, "reg", &phyled->index); + if (err) + return err; + +- cdev->brightness_set_blocking = phy_led_set_brightness; ++ if (phydev->drv->led_brightness_set) ++ cdev->brightness_set_blocking = phy_led_set_brightness; + cdev->max_brightness = 1; + init_data.devicename = dev_name(&phydev->mdio.dev); + init_data.fwnode = of_fwnode_handle(led); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -745,15 +745,19 @@ struct phy_tdr_config { + * struct phy_led: An LED driven by the PHY + * + * @list: List of LEDs ++ * @phydev: PHY this LED is attached to + * @led_cdev: Standard LED class structure + * @index: Number of the LED + */ + struct phy_led { + struct list_head list; ++ struct phy_device *phydev; + struct led_classdev led_cdev; + u8 index; + }; + ++#define to_phy_led(d) container_of(d, struct phy_led, led_cdev) ++ + /** + * struct phy_driver - Driver structure for a particular PHY type + * +@@ -953,6 +957,15 @@ struct phy_driver { + int (*get_sqi)(struct phy_device *dev); + /** @get_sqi_max: Get the maximum signal quality indication */ + int (*get_sqi_max)(struct phy_device *dev); ++ ++ /** ++ * @led_brightness_set: Set a PHY LED brightness. Index ++ * indicates which of the PHYs led should be set. Value ++ * follows the standard LED class meaning, e.g. LED_OFF, ++ * LED_HALF, LED_FULL. ++ */ ++ int (*led_brightness_set)(struct phy_device *dev, ++ u8 index, enum led_brightness value); + }; + #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ + struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch new file mode 100644 index 000000000..053288cec --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch @@ -0,0 +1,112 @@ +From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:29 +0200 +Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs + +Add a brightness function, so the LEDs can be controlled from +software using the standard Linux LED infrastructure. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 40 insertions(+), 5 deletions(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -144,11 +144,13 @@ + /* WOL Event Interrupt Enable */ + #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) + +-/* LED Timer Control Register */ +-#define MII_88E1318S_PHY_LED_TCR 0x12 +-#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) +-#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) +-#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) ++#define MII_88E1318S_PHY_LED_FUNC 0x10 ++#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) ++#define MII_88E1318S_PHY_LED_FUNC_ON (0x9) ++#define MII_88E1318S_PHY_LED_TCR 0x12 ++#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) ++#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) ++#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) + + /* Magic Packet MAC address registers */ + #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 +@@ -2793,6 +2795,34 @@ static int marvell_hwmon_probe(struct ph + } + #endif + ++static int m88e1318_led_brightness_set(struct phy_device *phydev, ++ u8 index, enum led_brightness value) ++{ ++ int reg; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ reg &= ~(0xf << (4 * index)); ++ if (value == LED_OFF) ++ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index); ++ else ++ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC, reg); ++} ++ + static int marvell_probe(struct phy_device *phydev) + { + struct marvell_priv *priv; +@@ -3041,6 +3071,7 @@ static struct phy_driver marvell_drivers + .get_sset_count = marvell_get_sset_count, + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1145, +@@ -3147,6 +3178,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1540, +@@ -3173,6 +3205,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1545, +@@ -3199,6 +3232,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E3016, +@@ -3340,6 +3374,7 @@ static struct phy_driver marvell_drivers + .get_stats = marvell_get_stats, + .get_tunable = m88e1540_get_tunable, + .set_tunable = m88e1540_set_tunable, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + }; + diff --git a/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch new file mode 100644 index 000000000..4814688de --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -0,0 +1,73 @@ +From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:30 +0200 +Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED + blinking + +Linux LEDs can be requested to perform hardware accelerated +blinking. Pass this to the PHY driver, if it implements the op. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 18 ++++++++++++++++++ + include/linux/phy.h | 12 ++++++++++++ + 2 files changed, 30 insertions(+) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2959,6 +2959,22 @@ static int phy_led_set_brightness(struct + return err; + } + ++static int phy_led_blink_set(struct led_classdev *led_cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_blink_set(phydev, phyled->index, ++ delay_on, delay_off); ++ mutex_unlock(&phydev->lock); ++ ++ return err; ++} ++ + static int of_phy_led(struct phy_device *phydev, + struct device_node *led) + { +@@ -2981,6 +2997,8 @@ static int of_phy_led(struct phy_device + + if (phydev->drv->led_brightness_set) + cdev->brightness_set_blocking = phy_led_set_brightness; ++ if (phydev->drv->led_blink_set) ++ cdev->blink_set = phy_led_blink_set; + cdev->max_brightness = 1; + init_data.devicename = dev_name(&phydev->mdio.dev); + init_data.fwnode = of_fwnode_handle(led); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -966,6 +966,18 @@ struct phy_driver { + */ + int (*led_brightness_set)(struct phy_device *dev, + u8 index, enum led_brightness value); ++ ++ /** ++ * @led_blink_set: Set a PHY LED brightness. Index indicates ++ * which of the PHYs led should be configured to blink. Delays ++ * are in milliseconds and if both are zero then a sensible ++ * default should be chosen. The call should adjust the ++ * timings in that case and if it can't match the values ++ * specified exactly. ++ */ ++ int (*led_blink_set)(struct phy_device *dev, u8 index, ++ unsigned long *delay_on, ++ unsigned long *delay_off); + }; + #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ + struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch new file mode 100644 index 000000000..0f258c6b9 --- /dev/null +++ b/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch @@ -0,0 +1,104 @@ +From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:31 +0200 +Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set() + +The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at +the same rate, and the reset default is 84ms per blink, which is +around 12Hz. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -147,6 +147,8 @@ + #define MII_88E1318S_PHY_LED_FUNC 0x10 + #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) + #define MII_88E1318S_PHY_LED_FUNC_ON (0x9) ++#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa) ++#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb) + #define MII_88E1318S_PHY_LED_TCR 0x12 + #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) + #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) +@@ -2823,6 +2825,35 @@ static int m88e1318_led_brightness_set(s + MII_88E1318S_PHY_LED_FUNC, reg); + } + ++static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ int reg; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ reg &= ~(0xf << (4 * index)); ++ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); ++ /* Reset default is 84ms */ ++ *delay_on = 84 / 2; ++ *delay_off = 84 / 2; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC, reg); ++} ++ + static int marvell_probe(struct phy_device *phydev) + { + struct marvell_priv *priv; +@@ -3072,6 +3103,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1145, +@@ -3179,6 +3211,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1540, +@@ -3206,6 +3239,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1545, +@@ -3233,6 +3267,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E3016, +@@ -3375,6 +3410,7 @@ static struct phy_driver marvell_drivers + .get_tunable = m88e1540_get_tunable, + .set_tunable = m88e1540_set_tunable, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + }; + diff --git a/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch new file mode 100644 index 000000000..c5b611a12 --- /dev/null +++ b/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch @@ -0,0 +1,38 @@ +From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 23 Apr 2023 19:28:00 +0200 +Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in + led_blink_set + +Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel +test robot, probably done by the presence of an if condition dropped in +later revision of the same code. + +Reported-by: kernel test robot +Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/ +Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()") +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/marvell.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -2841,10 +2841,10 @@ static int m88e1318_led_blink_set(struct + case 1: + case 2: + reg &= ~(0xf << (4 * index)); +- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); +- /* Reset default is 84ms */ +- *delay_on = 84 / 2; +- *delay_off = 84 / 2; ++ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); ++ /* Reset default is 84ms */ ++ *delay_on = 84 / 2; ++ *delay_off = 84 / 2; + break; + default: + return -EINVAL; diff --git a/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch new file mode 100644 index 000000000..3170c2605 --- /dev/null +++ b/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch @@ -0,0 +1,87 @@ +From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:40 +0200 +Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from + mode + +Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger +modes is wrong as it's used to set the link state of the device and not +to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and +NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the +netdev trigger mode and should be external to it. + +Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool +that will be true or false based on the carrier link. No functional +change intended. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -50,10 +50,10 @@ struct led_netdev_data { + unsigned int last_activity; + + unsigned long mode; ++ bool carrier_link_up; + #define NETDEV_LED_LINK 0 + #define NETDEV_LED_TX 1 + #define NETDEV_LED_RX 2 +-#define NETDEV_LED_MODE_LINKUP 3 + }; + + enum netdev_led_attr { +@@ -73,9 +73,9 @@ static void set_baseline_state(struct le + if (!led_cdev->blink_brightness) + led_cdev->blink_brightness = led_cdev->max_brightness; + +- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) ++ if (!trigger_data->carrier_link_up) { + led_set_brightness(led_cdev, LED_OFF); +- else { ++ } else { + if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); +@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct + trigger_data->net_dev = + dev_get_by_name(&init_net, trigger_data->device_name); + +- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = false; + if (trigger_data->net_dev != NULL) +- if (netif_carrier_ok(trigger_data->net_dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); + + trigger_data->last_activity = 0; + +@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not + + spin_lock_bh(&trigger_data->lock); + +- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = false; + switch (evt) { + case NETDEV_CHANGENAME: +- if (netif_carrier_ok(dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(dev); + fallthrough; + case NETDEV_REGISTER: + if (trigger_data->net_dev) +@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not + break; + case NETDEV_UP: + case NETDEV_CHANGE: +- if (netif_carrier_ok(dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(dev); + break; + } + diff --git a/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch new file mode 100644 index 000000000..19cc1d7c9 --- /dev/null +++ b/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch @@ -0,0 +1,149 @@ +From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:41 +0200 +Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev + trigger enum modes + +Rename NETDEV trigger enum modes to a more symbolic name and add a +namespace to them. + +Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev +trigger. + +This is a cleanup to drop the define and no behaviour change are +intended. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++--------------- + 1 file changed, 25 insertions(+), 33 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -51,15 +51,15 @@ struct led_netdev_data { + + unsigned long mode; + bool carrier_link_up; +-#define NETDEV_LED_LINK 0 +-#define NETDEV_LED_TX 1 +-#define NETDEV_LED_RX 2 + }; + +-enum netdev_led_attr { +- NETDEV_ATTR_LINK, +- NETDEV_ATTR_TX, +- NETDEV_ATTR_RX ++enum led_trigger_netdev_modes { ++ TRIGGER_NETDEV_LINK = 0, ++ TRIGGER_NETDEV_TX, ++ TRIGGER_NETDEV_RX, ++ ++ /* Keep last */ ++ __TRIGGER_NETDEV_MAX, + }; + + static void set_baseline_state(struct led_netdev_data *trigger_data) +@@ -76,7 +76,7 @@ static void set_baseline_state(struct le + if (!trigger_data->carrier_link_up) { + led_set_brightness(led_cdev, LED_OFF); + } else { +- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) ++ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); + else +@@ -85,8 +85,8 @@ static void set_baseline_state(struct le + /* If we are looking for RX/TX start periodically + * checking stats + */ +- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || +- test_bit(NETDEV_LED_RX, &trigger_data->mode)) ++ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) + schedule_delayed_work(&trigger_data->work, 0); + } + } +@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct + static DEVICE_ATTR_RW(device_name); + + static ssize_t netdev_led_attr_show(struct device *dev, char *buf, +- enum netdev_led_attr attr) ++ enum led_trigger_netdev_modes attr) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + int bit; + + switch (attr) { +- case NETDEV_ATTR_LINK: +- bit = NETDEV_LED_LINK; +- break; +- case NETDEV_ATTR_TX: +- bit = NETDEV_LED_TX; +- break; +- case NETDEV_ATTR_RX: +- bit = NETDEV_LED_RX; ++ case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_TX: ++ case TRIGGER_NETDEV_RX: ++ bit = attr; + break; + default: + return -EINVAL; +@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru + } + + static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, +- size_t size, enum netdev_led_attr attr) ++ size_t size, enum led_trigger_netdev_modes attr) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + unsigned long state; +@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str + return ret; + + switch (attr) { +- case NETDEV_ATTR_LINK: +- bit = NETDEV_LED_LINK; +- break; +- case NETDEV_ATTR_TX: +- bit = NETDEV_LED_TX; +- break; +- case NETDEV_ATTR_RX: +- bit = NETDEV_LED_RX; ++ case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_TX: ++ case TRIGGER_NETDEV_RX: ++ bit = attr; + break; + default: + return -EINVAL; +@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work + } + + /* If we are not looking for RX/TX then return */ +- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && +- !test_bit(NETDEV_LED_RX, &trigger_data->mode)) ++ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && ++ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) + return; + + dev_stats = dev_get_stats(trigger_data->net_dev, &temp); + new_activity = +- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? ++ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? + dev_stats->tx_packets : 0) + +- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? ++ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? + dev_stats->rx_packets : 0); + + if (trigger_data->last_activity != new_activity) { + led_stop_software_blink(trigger_data->led_cdev); + +- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); ++ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); + interval = jiffies_to_msecs( + atomic_read(&trigger_data->interval)); + /* base state is ON (link present) */ diff --git a/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch new file mode 100644 index 000000000..3b45951f5 --- /dev/null +++ b/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch @@ -0,0 +1,82 @@ +From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:42 +0200 +Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro + +Convert link tx and rx device attr to a common macro to reduce common +code and in preparation for additional attr. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++------------------- + 1 file changed, 16 insertions(+), 41 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str + return size; + } + +-static ssize_t link_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); +-} +- +-static ssize_t link_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); +-} +- +-static DEVICE_ATTR_RW(link); +- +-static ssize_t tx_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); +-} +- +-static ssize_t tx_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); +-} +- +-static DEVICE_ATTR_RW(tx); +- +-static ssize_t rx_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); +-} +- +-static ssize_t rx_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); +-} +- +-static DEVICE_ATTR_RW(rx); ++#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \ ++ static ssize_t trigger_name##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ ++ { \ ++ return netdev_led_attr_show(dev, buf, trigger); \ ++ } \ ++ static ssize_t trigger_name##_store(struct device *dev, \ ++ struct device_attribute *attr, const char *buf, size_t size) \ ++ { \ ++ return netdev_led_attr_store(dev, buf, size, trigger); \ ++ } \ ++ static DEVICE_ATTR_RW(trigger_name) ++ ++DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); ++DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); ++DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); + + static ssize_t interval_show(struct device *dev, + struct device_attribute *attr, char *buf) diff --git a/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch new file mode 100644 index 000000000..180bee961 --- /dev/null +++ b/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch @@ -0,0 +1,106 @@ +From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:43 +0200 +Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks + +Some LEDs may require to sleep while doing some operation like setting +brightness and other cleanup. + +For this reason, using a spinlock will cause a sleep under spinlock +warning. + +It should be safe to convert this to a sleepable lock since: +- sysfs read/write can sleep +- netdev_trig_work is a work queue and can sleep +- netdev _trig_notify can sleep + +The spinlock was used when brightness didn't support sleeping, but this +changed and now it supported with brightness_set_blocking(). + +Convert to mutex lock to permit sleeping using brightness_set_blocking(). + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + #include + #include "../leds.h" + +@@ -37,7 +37,7 @@ + */ + + struct led_netdev_data { +- spinlock_t lock; ++ struct mutex lock; + + struct delayed_work work; + struct notifier_block notifier; +@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + ssize_t len; + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + len = sprintf(buf, "%s\n", trigger_data->device_name); +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return len; + } +@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct + + cancel_delayed_work_sync(&trigger_data->work); + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + + if (trigger_data->net_dev) { + dev_put(trigger_data->net_dev); +@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct + trigger_data->last_activity = 0; + + set_baseline_state(trigger_data); +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return size; + } +@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not + + cancel_delayed_work_sync(&trigger_data->work); + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + + trigger_data->carrier_link_up = false; + switch (evt) { +@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not + + set_baseline_state(trigger_data); + +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return NOTIFY_DONE; + } +@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l + if (!trigger_data) + return -ENOMEM; + +- spin_lock_init(&trigger_data->lock); ++ mutex_init(&trigger_data->lock); + + trigger_data->notifier.notifier_call = netdev_trig_notify; + trigger_data->notifier.priority = 10; diff --git a/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch new file mode 100644 index 000000000..ac1861173 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch @@ -0,0 +1,74 @@ +From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:31 +0200 +Subject: [PATCH 01/13] leds: add APIs for LEDs hw control + +Add an option to permit LED driver to declare support for a specific +trigger to use hw control and setup the LED to blink based on specific +provided modes. + +Add APIs for LEDs hw control. These functions will be used to activate +hardware control where a LED will use the provided flags, from an +unique defined supported trigger, to setup the LED to be driven by +hardware. + +Add hw_control_is_supported() to ask the LED driver if the requested +mode by the trigger are supported and the LED can be setup to follow +the requested modes. + +Deactivate hardware blink control by setting brightness to LED_OFF via +the brightness_set() callback. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -164,6 +164,43 @@ struct led_classdev { + + /* LEDs that have private triggers have this set */ + struct led_hw_trigger_type *trigger_type; ++ ++ /* Unique trigger name supported by LED set in hw control mode */ ++ const char *hw_control_trigger; ++ /* ++ * Check if the LED driver supports the requested mode provided by the ++ * defined supported trigger to setup the LED to hw control mode. ++ * ++ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not ++ * supported and software fallback needs to be used. ++ * Return a negative error number on any other case for check fail due ++ * to various reason like device not ready or timeouts. ++ */ ++ int (*hw_control_is_supported)(struct led_classdev *led_cdev, ++ unsigned long flags); ++ /* ++ * Activate hardware control, LED driver will use the provided flags ++ * from the supported trigger and setup the LED to be driven by hardware ++ * following the requested mode from the trigger flags. ++ * Deactivate hardware blink control by setting brightness to LED_OFF via ++ * the brightness_set() callback. ++ * ++ * Return 0 on success, a negative error number on flags apply fail. ++ */ ++ int (*hw_control_set)(struct led_classdev *led_cdev, ++ unsigned long flags); ++ /* ++ * Get from the LED driver the current mode that the LED is set in hw ++ * control mode and put them in flags. ++ * Trigger can use this to get the initial state of a LED already set in ++ * hardware blink control. ++ * ++ * Return 0 on success, a negative error number on failing parsing the ++ * initial mode. Error from this function is NOT FATAL as the device ++ * may be in a not supported initial state by the attached LED trigger. ++ */ ++ int (*hw_control_get)(struct led_classdev *led_cdev, ++ unsigned long *flags); + #endif + + #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch new file mode 100644 index 000000000..1a221727a --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch @@ -0,0 +1,37 @@ +From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:32 +0200 +Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control + +Some specific LED triggers blink the LED based on events from a device +or subsystem. +For example, an LED could be blinked to indicate a network device is +receiving packets, or a disk is reading blocks. To correctly enable and +request the hw control of the LED, the trigger has to check if the +network interface or block device configured via a /sys/class/led file +match the one the LED driver provide for hw control for. + +Provide an API call to get the device which the LED blinks for. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -201,6 +201,12 @@ struct led_classdev { + */ + int (*hw_control_get)(struct led_classdev *led_cdev, + unsigned long *flags); ++ /* ++ * Get the device this LED blinks in response to. ++ * e.g. for a PHY LED, it is the network device. If the LED is ++ * not yet associated to a device, return NULL. ++ */ ++ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); + #endif + + #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch new file mode 100644 index 000000000..af9fb7fdc --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch @@ -0,0 +1,113 @@ +From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:33 +0200 +Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware + driven LEDs APIs + +Document new Hardware driven LEDs APIs. + +Some LEDs can be programmed to be driven by hardware. This is not +limited to blink but also to turn off or on autonomously. +To support this feature, a LED needs to implement various additional +ops and needs to declare specific support for the supported triggers. + +Add documentation for each required value and API to make hw control +possible and implementable by both LEDs and triggers. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++ + 1 file changed, 81 insertions(+) + +--- a/Documentation/leds/leds-class.rst ++++ b/Documentation/leds/leds-class.rst +@@ -169,6 +169,87 @@ Setting the brightness to zero with brig + should completely turn off the LED and cancel the previously programmed + hardware blinking function, if any. + ++Hardware driven LEDs ++==================== ++ ++Some LEDs can be programmed to be driven by hardware. This is not ++limited to blink but also to turn off or on autonomously. ++To support this feature, a LED needs to implement various additional ++ops and needs to declare specific support for the supported triggers. ++ ++With hw control we refer to the LED driven by hardware. ++ ++LED driver must define the following value to support hw control: ++ ++ - hw_control_trigger: ++ unique trigger name supported by the LED in hw control ++ mode. ++ ++LED driver must implement the following API to support hw control: ++ - hw_control_is_supported: ++ check if the flags passed by the supported trigger can ++ be parsed and activate hw control on the LED. ++ ++ Return 0 if the passed flags mask is supported and ++ can be set with hw_control_set(). ++ ++ If the passed flags mask is not supported -EOPNOTSUPP ++ must be returned, the LED trigger will use software ++ fallback in this case. ++ ++ Return a negative error in case of any other error like ++ device not ready or timeouts. ++ ++ - hw_control_set: ++ activate hw control. LED driver will use the provided ++ flags passed from the supported trigger, parse them to ++ a set of mode and setup the LED to be driven by hardware ++ following the requested modes. ++ ++ Set LED_OFF via the brightness_set to deactivate hw control. ++ ++ Return 0 on success, a negative error number on failing to ++ apply flags. ++ ++ - hw_control_get: ++ get active modes from a LED already in hw control, parse ++ them and set in flags the current active flags for the ++ supported trigger. ++ ++ Return 0 on success, a negative error number on failing ++ parsing the initial mode. ++ Error from this function is NOT FATAL as the device may ++ be in a not supported initial state by the attached LED ++ trigger. ++ ++ - hw_control_get_device: ++ return the device associated with the LED driver in ++ hw control. A trigger might use this to match the ++ returned device from this function with a configured ++ device for the trigger as the source for blinking ++ events and correctly enable hw control. ++ (example a netdev trigger configured to blink for a ++ particular dev match the returned dev from get_device ++ to set hw control) ++ ++ Returns a pointer to a struct device or NULL if nothing ++ is currently attached. ++ ++LED driver can activate additional modes by default to workaround the ++impossibility of supporting each different mode on the supported trigger. ++Examples are hardcoding the blink speed to a set interval, enable special ++feature like bypassing blink if some requirements are not met. ++ ++A trigger should first check if the hw control API are supported by the LED ++driver and check if the trigger is supported to verify if hw control is possible, ++use hw_control_is_supported to check if the flags are supported and only at ++the end use hw_control_set to activate hw control. ++ ++A trigger can use hw_control_get to check if a LED is already in hw control ++and init their flags. ++ ++When the LED is in hw control, no software blink is possible and doing so ++will effectively disable hw control. + + Known Issues + ============ diff --git a/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch new file mode 100644 index 000000000..3c804c0b4 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch @@ -0,0 +1,69 @@ +From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:34 +0200 +Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device + name + +Move the code into a helper, ready for it to be called at +other times. No intended behaviour change. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d + return len; + } + +-static ssize_t device_name_store(struct device *dev, +- struct device_attribute *attr, const char *buf, +- size_t size) ++static int set_device_name(struct led_netdev_data *trigger_data, ++ const char *name, size_t size) + { +- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); +- +- if (size >= IFNAMSIZ) +- return -EINVAL; +- + cancel_delayed_work_sync(&trigger_data->work); + + mutex_lock(&trigger_data->lock); +@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct + trigger_data->net_dev = NULL; + } + +- memcpy(trigger_data->device_name, buf, size); ++ memcpy(trigger_data->device_name, name, size); + trigger_data->device_name[size] = 0; + if (size > 0 && trigger_data->device_name[size - 1] == '\n') + trigger_data->device_name[size - 1] = 0; +@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct + set_baseline_state(trigger_data); + mutex_unlock(&trigger_data->lock); + ++ return 0; ++} ++ ++static ssize_t device_name_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t size) ++{ ++ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ++ int ret; ++ ++ if (size >= IFNAMSIZ) ++ return -EINVAL; ++ ++ ret = set_device_name(trigger_data, buf, size); ++ ++ if (ret < 0) ++ return ret; + return size; + } + diff --git a/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch new file mode 100644 index 000000000..284b51948 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch @@ -0,0 +1,54 @@ +From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:35 +0200 +Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw + control + +Introduce function to check if the requested mode can use hw control in +preparation for hw control support. Currently everything is handled in +software so can_hw_control will always return false. + +Add knob with the new value hw_control in trigger_data struct to +set hw control possible. Useful for future implementation to implement +in set_baseline_state() the required function to set the requested mode +using LEDs hw control ops and in other function to reject set if hw +control is currently active. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -51,6 +51,7 @@ struct led_netdev_data { + + unsigned long mode; + bool carrier_link_up; ++ bool hw_control; + }; + + enum led_trigger_netdev_modes { +@@ -91,6 +92,11 @@ static void set_baseline_state(struct le + } + } + ++static bool can_hw_control(struct led_netdev_data *trigger_data) ++{ ++ return false; ++} ++ + static ssize_t device_name_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str + else + clear_bit(bit, &trigger_data->mode); + ++ trigger_data->hw_control = can_hw_control(trigger_data); ++ + set_baseline_state(trigger_data); + + return size; diff --git a/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch new file mode 100644 index 000000000..09759bc62 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch @@ -0,0 +1,42 @@ +From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:36 +0200 +Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control + support + +Add basic check for hw control support. Check if the required API are +defined and check if the defined trigger supported in hw control for the +LED driver match netdev. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -92,8 +92,22 @@ static void set_baseline_state(struct le + } + } + ++static bool supports_hw_control(struct led_classdev *led_cdev) ++{ ++ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set || ++ !led_cdev->hw_control_is_supported) ++ return false; ++ ++ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); ++} ++ + static bool can_hw_control(struct led_netdev_data *trigger_data) + { ++ struct led_classdev *led_cdev = trigger_data->led_cdev; ++ ++ if (!supports_hw_control(led_cdev)) ++ return false; ++ + return false; + } + diff --git a/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch new file mode 100644 index 000000000..663490680 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch @@ -0,0 +1,28 @@ +From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:37 +0200 +Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for + hw_control + +Reject interval store with hw_control enabled. It's are currently not +supported and MUST be set to the default value with hw control enabled. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev + unsigned long value; + int ret; + ++ if (trigger_data->hw_control) ++ return -EINVAL; ++ + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; diff --git a/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch new file mode 100644 index 000000000..52faa4809 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch @@ -0,0 +1,107 @@ +From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:38 +0200 +Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control + +Add support for LED hw control for the netdev trigger. + +The trigger on calling set_baseline_state to configure a new mode, will +do various check to verify if hw control can be used for the requested +mode in can_hw_control() function. + +It will first check if the LED driver supports hw control for the netdev +trigger, then will use hw_control_is_supported() and finally will call +hw_control_set() to apply the requested mode. + +To use such mode, interval MUST be set to the default value and net_dev +MUST be set. If one of these 2 value are not valid, hw control will +never be used and normal software fallback is used. + +The default interval value is moved to a define to make sure they are +always synced. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -24,6 +24,8 @@ + #include + #include "../leds.h" + ++#define NETDEV_LED_DEFAULT_INTERVAL 50 ++ + /* + * Configurable sysfs attributes: + * +@@ -68,6 +70,13 @@ static void set_baseline_state(struct le + int current_brightness; + struct led_classdev *led_cdev = trigger_data->led_cdev; + ++ /* Already validated, hw control is possible with the requested mode */ ++ if (trigger_data->hw_control) { ++ led_cdev->hw_control_set(led_cdev, trigger_data->mode); ++ ++ return; ++ } ++ + current_brightness = led_cdev->brightness; + if (current_brightness) + led_cdev->blink_brightness = current_brightness; +@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l + + static bool can_hw_control(struct led_netdev_data *trigger_data) + { ++ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); ++ unsigned int interval = atomic_read(&trigger_data->interval); + struct led_classdev *led_cdev = trigger_data->led_cdev; ++ int ret; + + if (!supports_hw_control(led_cdev)) + return false; + +- return false; ++ /* ++ * Interval must be set to the default ++ * value. Any different value is rejected if in hw ++ * control. ++ */ ++ if (interval != default_interval) ++ return false; ++ ++ /* ++ * net_dev must be set with hw control, otherwise no ++ * blinking can be happening and there is nothing to ++ * offloaded. ++ */ ++ if (!trigger_data->net_dev) ++ return false; ++ ++ /* Check if the requested mode is supported */ ++ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode); ++ /* Fall back to software blinking if not supported */ ++ if (ret == -EOPNOTSUPP) ++ return false; ++ if (ret) { ++ dev_warn(led_cdev->dev, ++ "Current mode check failed with error %d\n", ret); ++ return false; ++ } ++ ++ return true; + } + + static ssize_t device_name_show(struct device *dev, +@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l + trigger_data->device_name[0] = 0; + + trigger_data->mode = 0; +- atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); ++ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); + trigger_data->last_activity = 0; + + led_set_trigger_data(led_cdev, trigger_data); diff --git a/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch new file mode 100644 index 000000000..c129ffa4f --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch @@ -0,0 +1,58 @@ +From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:39 +0200 +Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev + +The netdev which the LED should blink for is configurable in +/sys/class/led/foo/device_name. Ensure when offloading that the +configured netdev is the same as the netdev the LED is associated +with. If it is not, only perform software blinking. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l + return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); + } + ++/* ++ * Validate the configured netdev is the same as the one associated with ++ * the LED driver in hw control. ++ */ ++static bool validate_net_dev(struct led_classdev *led_cdev, ++ struct net_device *net_dev) ++{ ++ struct device *dev = led_cdev->hw_control_get_device(led_cdev); ++ struct net_device *ndev; ++ ++ if (!dev) ++ return false; ++ ++ ndev = to_net_dev(dev); ++ ++ return ndev == net_dev; ++} ++ + static bool can_hw_control(struct led_netdev_data *trigger_data) + { + unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); +@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne + /* + * net_dev must be set with hw control, otherwise no + * blinking can be happening and there is nothing to +- * offloaded. ++ * offloaded. Additionally, for hw control to be ++ * valid, the configured netdev must be the same as ++ * netdev associated to the LED. + */ +- if (!trigger_data->net_dev) ++ if (!validate_net_dev(led_cdev, trigger_data->net_dev)) + return false; + + /* Check if the requested mode is supported */ diff --git a/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch new file mode 100644 index 000000000..e20594c99 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch @@ -0,0 +1,53 @@ +From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:40 +0200 +Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already + active + +On netdev trigger activation, hw control may be already active by +default. If this is the case and a device is actually provided by +hw_control_get_device(), init the already active mode and set the +bool to hw_control bool to true to reflect the already set mode in the +trigger_data. + +Co-developed-by: Andrew Lunn +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work + static int netdev_trig_activate(struct led_classdev *led_cdev) + { + struct led_netdev_data *trigger_data; ++ unsigned long mode; ++ struct device *dev; + int rc; + + trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); +@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l + atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); + trigger_data->last_activity = 0; + ++ /* Check if hw control is active by default on the LED. ++ * Init already enabled mode in hw control. ++ */ ++ if (supports_hw_control(led_cdev) && ++ !led_cdev->hw_control_get(led_cdev, &mode)) { ++ dev = led_cdev->hw_control_get_device(led_cdev); ++ if (dev) { ++ const char *name = dev_name(dev); ++ ++ set_device_name(trigger_data, name, strlen(name)); ++ trigger_data->hw_control = true; ++ trigger_data->mode = mode; ++ } ++ } ++ + led_set_trigger_data(led_cdev, trigger_data); + + rc = register_netdevice_notifier(&trigger_data->notifier); diff --git a/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch new file mode 100644 index 000000000..70aed850d --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch @@ -0,0 +1,54 @@ +From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:41 +0200 +Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in + linux include + +Expose netdev trigger modes to make them accessible by LED driver that +will support netdev trigger for hw control. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 9 --------- + include/linux/leds.h | 10 ++++++++++ + 2 files changed, 10 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -56,15 +56,6 @@ struct led_netdev_data { + bool hw_control; + }; + +-enum led_trigger_netdev_modes { +- TRIGGER_NETDEV_LINK = 0, +- TRIGGER_NETDEV_TX, +- TRIGGER_NETDEV_RX, +- +- /* Keep last */ +- __TRIGGER_NETDEV_MAX, +-}; +- + static void set_baseline_state(struct led_netdev_data *trigger_data) + { + int current_brightness; +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data + + #endif /* CONFIG_LEDS_TRIGGERS */ + ++/* Trigger specific enum */ ++enum led_trigger_netdev_modes { ++ TRIGGER_NETDEV_LINK = 0, ++ TRIGGER_NETDEV_TX, ++ TRIGGER_NETDEV_RX, ++ ++ /* Keep last */ ++ __TRIGGER_NETDEV_MAX, ++}; ++ + /* Trigger specific functions */ + #ifdef CONFIG_LEDS_TRIGGER_DISK + void ledtrig_disk_activity(bool write); diff --git a/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch new file mode 100644 index 000000000..ad76d89b7 --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch @@ -0,0 +1,200 @@ +From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:42 +0200 +Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops + +Implement hw_control ops to drive Switch LEDs based on hardware events. + +Netdev trigger is the declared supported trigger for hw control +operation and supports the following mode: +- tx +- rx + +When hw_control_set is called, LEDs are set to follow the requested +mode. +Each LEDs will blink at 4Hz by default. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++ + 1 file changed, 154 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i + } + + static int ++qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) ++{ ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ ++ /* 6 total control rule: ++ * 3 control rules for phy0-3 that applies to all their leds ++ * 3 control rules for phy4 ++ */ ++ if (port_num == 4) ++ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; ++ else ++ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; ++ ++ return 0; ++} ++ ++static int ++qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger) ++{ ++ /* Parsing specific to netdev trigger */ ++ if (test_bit(TRIGGER_NETDEV_TX, &rules)) ++ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK; ++ if (test_bit(TRIGGER_NETDEV_RX, &rules)) ++ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK; ++ ++ if (rules && !*offload_trigger) ++ return -EOPNOTSUPP; ++ ++ /* Enable some default rule by default to the requested mode: ++ * - Blink at 4Hz by default ++ */ ++ *offload_trigger |= QCA8K_LED_BLINK_4HZ; ++ ++ return 0; ++} ++ ++static int + qca8k_led_brightness_set(struct qca8k_led *led, + enum led_brightness brightness) + { +@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev + } + + static int ++qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 mask, val = QCA8K_LED_ALWAYS_OFF; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ if (enable) ++ val = QCA8K_LED_RULE_CONTROLLED; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, ++ val << reg_info.shift); ++} ++ ++static bool ++qca8k_cled_hw_control_status(struct led_classdev *ldev) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ regmap_read(priv->regmap, reg_info.reg, &val); ++ ++ val >>= reg_info.shift; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ val &= QCA8K_LED_PATTERN_EN_MASK; ++ val >>= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return val == QCA8K_LED_RULE_CONTROLLED; ++} ++ ++static int ++qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) ++{ ++ u32 offload_trigger = 0; ++ ++ return qca8k_parse_netdev(rules, &offload_trigger); ++} ++ ++static int ++qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 offload_trigger = 0; ++ int ret; ++ ++ ret = qca8k_parse_netdev(rules, &offload_trigger); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_cled_trigger_offload(ldev, true); ++ if (ret) ++ return ret; ++ ++ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, ++ QCA8K_LED_RULE_MASK << reg_info.shift, ++ offload_trigger << reg_info.shift); ++} ++ ++static int ++qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ int ret; ++ ++ /* With hw control not active return err */ ++ if (!qca8k_cled_hw_control_status(ldev)) ++ return -EINVAL; ++ ++ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); ++ ++ ret = regmap_read(priv->regmap, reg_info.reg, &val); ++ if (ret) ++ return ret; ++ ++ val >>= reg_info.shift; ++ val &= QCA8K_LED_RULE_MASK; ++ ++ /* Parsing specific to netdev trigger */ ++ if (val & QCA8K_LED_TX_BLINK_MASK) ++ set_bit(TRIGGER_NETDEV_TX, rules); ++ if (val & QCA8K_LED_RX_BLINK_MASK) ++ set_bit(TRIGGER_NETDEV_RX, rules); ++ ++ return 0; ++} ++ ++static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { + struct fwnode_handle *led = NULL, *leds = NULL; +@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv + port_led->cdev.max_brightness = 1; + port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; + port_led->cdev.blink_set = qca8k_cled_blink_set; ++ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; ++ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; ++ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; ++ port_led->cdev.hw_control_trigger = "netdev"; + init_data.default_label = ":port"; + init_data.fwnode = led; + init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch new file mode 100644 index 000000000..feb6b9e1e --- /dev/null +++ b/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch @@ -0,0 +1,70 @@ +From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:43 +0200 +Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev + +In order that the LED trigger can blink the switch MAC ports LED, it +needs to know the netdev associated to the port. Add the callback to +return the struct device of the netdev. + +Add an helper function qca8k_phy_to_port() to convert the phy back to +dsa_port index, as we reference LED port based on the internal PHY +index and needs to be converted back. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -5,6 +5,18 @@ + #include "qca8k.h" + #include "qca8k_leds.h" + ++static u32 qca8k_phy_to_port(int phy) ++{ ++ /* Internal PHY 0 has port at index 1. ++ * Internal PHY 1 has port at index 2. ++ * Internal PHY 2 has port at index 3. ++ * Internal PHY 3 has port at index 4. ++ * Internal PHY 4 has port at index 5. ++ */ ++ ++ return phy + 1; ++} ++ + static int + qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) + { +@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla + return 0; + } + ++static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_priv *priv = led->priv; ++ struct dsa_port *dp; ++ ++ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num)); ++ if (!dp) ++ return NULL; ++ if (dp->slave) ++ return &dp->slave->dev; ++ return NULL; ++} ++ + static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { +@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv + port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; + port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; + port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; ++ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device; + port_led->cdev.hw_control_trigger = "netdev"; + init_data.default_label = ":port"; + init_data.fwnode = led; diff --git a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch b/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch index 725af4b52..4a63b89f5 100644 --- a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch +++ b/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch @@ -17,7 +17,7 @@ Signed-off-by: Marcel Holtmann --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -2287,6 +2287,23 @@ struct btmtk_section_map { +@@ -2289,6 +2289,23 @@ struct btmtk_section_map { }; } __packed; @@ -41,7 +41,7 @@ Signed-off-by: Marcel Holtmann static void btusb_mtk_wmt_recv(struct urb *urb) { struct hci_dev *hdev = urb->context; -@@ -3941,6 +3958,7 @@ static int btusb_probe(struct usb_interf +@@ -3943,6 +3960,7 @@ static int btusb_probe(struct usb_interf hdev->shutdown = btusb_mtk_shutdown; hdev->manufacturer = 70; hdev->cmd_timeout = btusb_mtk_cmd_timeout; diff --git a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch b/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch index d72866eab..d21adada9 100644 --- a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch +++ b/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch @@ -18,7 +18,7 @@ Signed-off-by: Marcel Holtmann --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -2292,7 +2292,7 @@ static int btusb_set_bdaddr_mtk(struct h +@@ -2294,7 +2294,7 @@ static int btusb_set_bdaddr_mtk(struct h struct sk_buff *skb; long ret; diff --git a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch b/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch index ebb6cc471..30492ac48 100644 --- a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch +++ b/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch @@ -58,7 +58,7 @@ Signed-off-by: Marcel Holtmann --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -476,6 +476,9 @@ static const struct usb_device_id blackl +@@ -478,6 +478,9 @@ static const struct usb_device_id blackl { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, diff --git a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch b/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch index a8c7ca003..6bcd81c3b 100644 --- a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch +++ b/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch @@ -56,7 +56,7 @@ Signed-off-by: Marcel Holtmann --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -467,6 +467,9 @@ static const struct usb_device_id blackl +@@ -469,6 +469,9 @@ static const struct usb_device_id blackl BTUSB_VALID_LE_STATES }, /* Additional MediaTek MT7921 Bluetooth devices */ diff --git a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch b/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch index b46e6926d..b6b76f64f 100644 --- a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch +++ b/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch @@ -54,7 +54,7 @@ Signed-off-by: Luiz Augusto von Dentz --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c -@@ -485,6 +485,9 @@ static const struct usb_device_id blackl +@@ -487,6 +487,9 @@ static const struct usb_device_id blackl { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, diff --git a/target/linux/generic/backport-5.15/890-v6.1-mtd-spinand-winbond-fix-flash-detection.patch b/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch similarity index 100% rename from target/linux/generic/backport-5.15/890-v6.1-mtd-spinand-winbond-fix-flash-detection.patch rename to target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch diff --git a/target/linux/generic/backport-5.15/891-v6.1-mtd-spinand-winbond-add-W25N02KV.patch b/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch similarity index 100% rename from target/linux/generic/backport-5.15/891-v6.1-mtd-spinand-winbond-add-W25N02KV.patch rename to target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch diff --git a/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch b/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch index 86885c2b2..b5c0ac505 100644 --- a/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch +++ b/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch @@ -49,7 +49,7 @@ Signed-off-by: David S. Miller enum mv88e6xxx_frame_mode { MV88E6XXX_FRAME_MODE_NORMAL, MV88E6XXX_FRAME_MODE_DSA, -@@ -464,7 +469,9 @@ struct mv88e6xxx_ops { +@@ -465,7 +470,9 @@ struct mv88e6xxx_ops { int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, uint64_t *data); int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port); diff --git a/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch b/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch index 0e69fb292..3ac7a4f0f 100644 --- a/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch +++ b/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch @@ -25,7 +25,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -4944,6 +4944,80 @@ static int mv88e6xxx_port_mdb_del(struct +@@ -4969,6 +4969,80 @@ static int mv88e6xxx_port_mdb_del(struct return err; } @@ -106,7 +106,7 @@ Signed-off-by: David S. Miller static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port, bool unicast, bool multicast) { -@@ -4998,6 +5072,8 @@ static const struct dsa_switch_ops mv88e +@@ -5023,6 +5097,8 @@ static const struct dsa_switch_ops mv88e .port_mdb_prepare = mv88e6xxx_port_mdb_prepare, .port_mdb_add = mv88e6xxx_port_mdb_add, .port_mdb_del = mv88e6xxx_port_mdb_del, @@ -117,7 +117,7 @@ Signed-off-by: David S. Miller .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set, --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -232,6 +232,8 @@ struct mv88e6xxx_port { +@@ -233,6 +233,8 @@ struct mv88e6xxx_port { u64 vtu_member_violation; u64 vtu_miss_violation; u8 cmode; @@ -126,7 +126,7 @@ Signed-off-by: David S. Miller unsigned int serdes_irq; }; -@@ -315,6 +317,10 @@ struct mv88e6xxx_chip { +@@ -316,6 +318,10 @@ struct mv88e6xxx_chip { u16 evcap_config; u16 enable_count; diff --git a/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch b/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch index 017a68958..5d68ba579 100644 --- a/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch +++ b/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -5011,7 +5011,7 @@ static void mv88e6xxx_port_mirror_del(st +@@ -5036,7 +5036,7 @@ static void mv88e6xxx_port_mirror_del(st if (chip->info->ops->set_egress_port(chip, direction, dsa_upstream_port(ds, diff --git a/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch index 0cb3696b2..4aa71d6a3 100644 --- a/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch +++ b/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch @@ -1000,7 +1000,7 @@ Signed-off-by: David S. Miller u32 mahr = ravb_read(ndev, MAHR); u32 malr = ravb_read(ndev, MALR); -@@ -2165,7 +2167,7 @@ static int ravb_probe(struct platform_de +@@ -2168,7 +2170,7 @@ static int ravb_probe(struct platform_de priv->msg_enable = RAVB_DEF_MSG_ENABLE; /* Read and set MAC address */ @@ -1775,7 +1775,7 @@ Signed-off-by: David S. Miller eth_hw_addr_inherit(slave_dev, master); --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c -@@ -550,13 +550,14 @@ unsigned char * __weak arch_get_platform +@@ -540,13 +540,14 @@ unsigned char * __weak arch_get_platform int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr) { @@ -1815,7 +1815,7 @@ Signed-off-by: David S. Miller } --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -901,11 +901,12 @@ static int smsc95xx_ioctl(struct net_dev +@@ -903,11 +903,12 @@ static int smsc95xx_ioctl(struct net_dev static void smsc95xx_init_mac_address(struct usbnet *dev) { @@ -1833,7 +1833,7 @@ Signed-off-by: David S. Miller } --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -3459,10 +3459,11 @@ static int bcmgenet_probe(struct platfor +@@ -3478,10 +3478,11 @@ static int bcmgenet_probe(struct platfor const struct of_device_id *of_id = NULL; struct bcmgenet_priv *priv; struct net_device *dev; @@ -1846,7 +1846,7 @@ Signed-off-by: David S. Miller /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */ dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, -@@ -3489,14 +3490,15 @@ static int bcmgenet_probe(struct platfor +@@ -3508,14 +3509,15 @@ static int bcmgenet_probe(struct platfor } if (dn) { @@ -1865,7 +1865,7 @@ Signed-off-by: David S. Miller } priv->base = devm_platform_ioremap_resource(pdev, 0); -@@ -3509,7 +3511,6 @@ static int bcmgenet_probe(struct platfor +@@ -3529,7 +3531,6 @@ static int bcmgenet_probe(struct platfor SET_NETDEV_DEV(dev, &pdev->dev); dev_set_drvdata(&pdev->dev, dev); diff --git a/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch deleted file mode 100644 index 31a8ca3ea..000000000 --- a/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code - on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -921,7 +921,13 @@ enum mkt_eth_capabilities { - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - --#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) -+#ifdef CONFIG_SOC_MT7621 -+#define MTK_CAP_MASK MTK_NETSYS_V2 -+#else -+#define MTK_CAP_MASK 0 -+#endif -+ -+#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x)) - - #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ - MTK_GMAC2_RGMII | MTK_SHARED_INT | \ diff --git a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch index 293c95031..b8e3452f3 100644 --- a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ b/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch @@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau /* CDMP Ingress Control Register */ #define MTK_CDMP_IG_CTRL 0x400 #define MTK_CDMP_STAG_EN BIT(0) -@@ -1170,6 +1176,8 @@ struct mtk_eth { +@@ -1164,6 +1170,8 @@ struct mtk_eth { int ip_align; diff --git a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch index 7db59ad87..a02c583de 100644 --- a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch +++ b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch @@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1073,11 +1073,13 @@ struct mtk_soc_data { +@@ -1067,11 +1067,13 @@ struct mtk_soc_data { * @regmap: The register map pointing at the range used to setup * SGMII modes * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap diff --git a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch index e67eec3f2..a1247218b 100644 --- a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch +++ b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch @@ -14,6 +14,12 @@ new device-tree attribute 'mediatek,pn_swap' to support them. Signed-off-by: Daniel Golle Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 31 ++++++++++++++++++++ + drivers/net/ethernet/mediatek/mtk_sgmii.c | 10 +++++++ + 4 files changed, 73 insertions(+), 3 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_path.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c @@ -145,7 +151,7 @@ Signed-off-by: Jakub Kicinski #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -966,6 +990,11 @@ enum mkt_eth_capabilities { +@@ -960,6 +984,11 @@ enum mkt_eth_capabilities { MTK_MUX_U3_GMAC2_TO_QPHY | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) @@ -157,7 +163,7 @@ Signed-off-by: Jakub Kicinski #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -@@ -1079,12 +1108,14 @@ struct mtk_soc_data { +@@ -1073,12 +1102,14 @@ struct mtk_soc_data { * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap * @interface: Currently configured interface mode * @pcs: Phylink PCS structure diff --git a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch index c415a1a29..110944658 100644 --- a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch +++ b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch @@ -228,7 +228,7 @@ Signed-off-by: Jakub Kicinski /* Infrasys subsystem config registers */ #define INFRA_MISC2 0x70c #define CO_QPHY_SEL BIT(0) -@@ -1108,31 +1049,6 @@ struct mtk_soc_data { +@@ -1102,31 +1043,6 @@ struct mtk_soc_data { /* currently no SoC has more than 2 macs */ #define MTK_MAX_DEVS 2 @@ -260,7 +260,7 @@ Signed-off-by: Jakub Kicinski /* struct mtk_eth - This is the main datasructure for holding the state * of the driver * @dev: The device pointer -@@ -1152,6 +1068,7 @@ struct mtk_sgmii { +@@ -1146,6 +1062,7 @@ struct mtk_sgmii { * MII modes * @infra: The register map pointing at the range used to setup * SGMII and GePHY path @@ -268,7 +268,7 @@ Signed-off-by: Jakub Kicinski * @pctl: The register map pointing at the range used to setup * GMAC port drive/slew values * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1192,8 +1109,8 @@ struct mtk_eth { +@@ -1186,8 +1103,8 @@ struct mtk_eth { u32 msg_enable; unsigned long sysclk; struct regmap *ethsys; @@ -279,7 +279,7 @@ Signed-off-by: Jakub Kicinski struct regmap *pctl; bool hwlro; refcount_t dma_refcnt; -@@ -1355,10 +1272,6 @@ void mtk_stats_update_mac(struct mtk_mac +@@ -1349,10 +1266,6 @@ void mtk_stats_update_mac(struct mtk_mac void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); u32 mtk_r32(struct mtk_eth *eth, unsigned reg); diff --git a/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch similarity index 78% rename from target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch rename to target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch index 7eae25188..93eaffa19 100644 --- a/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch +++ b/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch @@ -1,59 +1,33 @@ -From patchwork Wed Nov 2 00:58:01 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13027653 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -Date: Wed, 2 Nov 2022 00:58:01 +0000 +From f601293f37c4be618c5efaef85d2ee21f97e82e0 Mon Sep 17 00:00:00 2001 From: Daniel Golle -To: Felix Fietkau , John Crispin , - Sean Wang , - Mark Lee , - "David S. Miller" , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org -Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow +Date: Sun, 19 Mar 2023 12:57:35 +0000 +Subject: [PATCH 092/250] net: ethernet: mtk_eth_soc: ppe: add support for flow accounting -Message-ID: MIME-Version: 1.0 -Content-Disposition: inline -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit The PPE units found in MT7622 and newer support packet and byte -accounting of hw-offloaded flows. Add support for reading those -counters as found in MediaTek's SDK[1]. +accounting of hw-offloaded flows. Add support for reading those counters +as found in MediaTek's SDK[1]. [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92 +Tested-by: Bjørn Mork Signed-off-by: Daniel Golle +Signed-off-by: Jakub Kicinski --- -v4: declare function mtk_mib_entry_read as static -v3: don't bother to set 'false' values in any zero-initialized struct - use mtk_foe_entry_ib2 - both changes were requested by Felix Fietkau - -v2: fix wrong variable name in return value check spotted by Denis Kirjanov - - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - drivers/net/ethernet/mediatek/mtk_ppe.c | 110 +++++++++++++++++- - drivers/net/ethernet/mediatek/mtk_ppe.h | 23 +++- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 + + drivers/net/ethernet/mediatek/mtk_ppe.c | 114 +++++++++++++++++- + drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +++- .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 7 ++ + .../net/ethernet/mediatek/mtk_ppe_offload.c | 8 ++ drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++ - 7 files changed, 166 insertions(+), 5 deletions(-) + 7 files changed, 172 insertions(+), 9 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4637,8 +4637,8 @@ static int mtk_probe(struct platform_dev +@@ -4691,8 +4691,8 @@ static int mtk_probe(struct platform_dev for (i = 0; i < num_ppe; i++) { u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; @@ -63,8 +37,8 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov + if (!eth->ppe[i]) { err = -ENOMEM; - goto err_free_dev; -@@ -4765,6 +4765,7 @@ static const struct mtk_soc_data mt7622_ + goto err_deinit_ppe; +@@ -4816,6 +4816,7 @@ static const struct mtk_soc_data mt7622_ .required_pctl = false, .offload_version = 2, .hash_offset = 2, @@ -72,7 +46,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), -@@ -4802,6 +4803,7 @@ static const struct mtk_soc_data mt7629_ +@@ -4853,6 +4854,7 @@ static const struct mtk_soc_data mt7629_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7629_CLKS_BITMAP, .required_pctl = false, @@ -80,7 +54,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4822,6 +4824,7 @@ static const struct mtk_soc_data mt7981_ +@@ -4873,6 +4875,7 @@ static const struct mtk_soc_data mt7981_ .offload_version = 2, .hash_offset = 4, .foe_entry_size = sizeof(struct mtk_foe_entry), @@ -88,7 +62,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .txrx = { .txd_size = sizeof(struct mtk_tx_dma_v2), .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4842,6 +4845,7 @@ static const struct mtk_soc_data mt7986_ +@@ -4893,6 +4896,7 @@ static const struct mtk_soc_data mt7986_ .offload_version = 2, .hash_offset = 4, .foe_entry_size = sizeof(struct mtk_foe_entry), @@ -98,7 +72,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .rxd_size = sizeof(struct mtk_rx_dma_v2), --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1014,6 +1014,8 @@ struct mtk_reg_map { +@@ -1011,6 +1011,8 @@ struct mtk_reg_map { * the extra setup for those pins used by GMAC. * @hash_offset Flow table hash offset. * @foe_entry_size Foe table entry size. @@ -107,7 +81,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov * @txd_size Tx DMA descriptor size. * @rxd_size Rx DMA descriptor size. * @rx_irq_done_mask Rx irq done register mask. -@@ -1031,6 +1033,7 @@ struct mtk_soc_data { +@@ -1028,6 +1030,7 @@ struct mtk_soc_data { u8 hash_offset; u16 foe_entry_size; netdev_features_t hw_features; @@ -166,10 +140,10 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) { ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); -@@ -464,6 +506,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 &= ~MTK_FOE_IB1_STATE; +@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); dma_wmb(); + mtk_ppe_cache_clear(ppe); + if (ppe->accounting) { + struct mtk_foe_accounting *acct; + @@ -180,7 +154,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov } entry->hash = 0xffff; -@@ -571,6 +620,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p wmb(); hwe->ib1 = entry->ib1; @@ -190,7 +164,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov dma_wmb(); mtk_ppe_cache_clear(ppe); -@@ -762,11 +814,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe +@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe return mtk_ppe_wait_busy(ppe); } @@ -232,7 +206,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov struct mtk_ppe *ppe; u32 foe_flow_size; void *foe; -@@ -783,7 +863,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ ppe->base = base; ppe->eth = eth; ppe->dev = dev; @@ -242,9 +216,9 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * soc->foe_entry_size, -@@ -799,6 +880,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ if (!ppe->foe_flow) - return NULL; + goto err_free_l2_flows; + if (accounting) { + mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib), @@ -266,7 +240,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov mtk_ppe_debugfs_init(ppe, index); return ppe; -@@ -913,6 +1011,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) +@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); } @@ -328,17 +302,18 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov u16 foe_check_time[MTK_PPE_ENTRIES]; struct hlist_head *foe_flow; -@@ -303,8 +322,7 @@ struct mtk_ppe { +@@ -303,8 +322,8 @@ struct mtk_ppe { void *acct_table; }; -struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version, int index); +struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index); ++ + void mtk_ppe_deinit(struct mtk_eth *eth); void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); -@@ -358,5 +376,7 @@ int mtk_foe_entry_commit(struct mtk_ppe +@@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); @@ -381,7 +356,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov return 0; --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -500,6 +500,7 @@ static int +@@ -497,6 +497,7 @@ static int mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) { struct mtk_flow_entry *entry; @@ -389,7 +364,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov u32 idle; entry = rhashtable_lookup(ð->flow_table, &f->cookie, -@@ -510,6 +511,13 @@ mtk_flow_offload_stats(struct mtk_eth *e +@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); f->stats.lastused = jiffies - idle * HZ; diff --git a/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch similarity index 63% rename from target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch rename to target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch index 33c983832..64352426a 100644 --- a/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch +++ b/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch @@ -1,17 +1,24 @@ +From 88a0fd5927b7c2c7aecd6dc747d898eb38043d2b Mon Sep 17 00:00:00 2001 From: Felix Fietkau -Date: Thu, 23 Mar 2023 21:45:43 +0100 -Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1 - hardware +Date: Thu, 20 Apr 2023 22:06:42 +0100 +Subject: [PATCH 093/250] net: mtk_eth_soc: mediatek: fix ppe flow accounting + for v1 hardware Older chips (like MT7622) use a different bit in ib2 to enable hardware -counter support. +counter support. Add macros for both and select the appropriate bit. +Fixes: 3fbe4d8c0e53 ("net: ethernet: mtk_eth_soc: ppe: add support for flow accounting") Signed-off-by: Felix Fietkau +Signed-off-by: Daniel Golle +Signed-off-by: David S. Miller --- + drivers/net/ethernet/mediatek/mtk_ppe.c | 10 ++++++++-- + drivers/net/ethernet/mediatek/mtk_ppe.h | 3 ++- + 2 files changed, 10 insertions(+), 3 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -640,6 +640,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -599,6 +599,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p struct mtk_eth *eth = ppe->eth; u16 timestamp = mtk_eth_timestamp(eth); struct mtk_foe_entry *hwe; @@ -19,7 +26,7 @@ Signed-off-by: Felix Fietkau if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -@@ -656,8 +657,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -615,8 +616,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p wmb(); hwe->ib1 = entry->ib1; diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch similarity index 100% rename from target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch rename to target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch diff --git a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch new file mode 100644 index 000000000..2704faec1 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch @@ -0,0 +1,31 @@ +From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 19 Jul 2023 01:39:36 +0100 +Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always + mtk_get_ib1_pkt_type + +entries and bind debugfs files would display wrong data on NETSYS_V2 and +later because instead of using mtk_get_ib1_pkt_type the driver would use +MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs. +Use mtk_get_ib1_pkt_type so entries and bind records display correctly. + +Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986") +Signed-off-by: Daniel Golle +Acked-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file + + acct = mtk_foe_entry_get_mib(ppe, i, NULL); + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); + seq_printf(m, "%05x %s %7s", i, + mtk_foe_entry_state_str(state), + mtk_foe_pkt_type_str(type)); diff --git a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch new file mode 100644 index 000000000..d7d1c08fc --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch @@ -0,0 +1,78 @@ +From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 19 Jul 2023 12:29:49 +0200 +Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE + macros + +Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more +explicit foe_entry size for different chipset revisions. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++----- + drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4765,7 +4765,7 @@ static const struct mtk_soc_data mt7621_ + .required_pctl = false, + .offload_version = 1, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4786,7 +4786,7 @@ static const struct mtk_soc_data mt7622_ + .offload_version = 2, + .hash_offset = 2, + .has_accounting = true, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4805,7 +4805,7 @@ static const struct mtk_soc_data mt7623_ + .required_pctl = true, + .offload_version = 1, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, ++ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4843,8 +4843,8 @@ static const struct mtk_soc_data mt7981_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 4, +- .foe_entry_size = sizeof(struct mtk_foe_entry), + .has_accounting = true, ++ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +@@ -4864,8 +4864,8 @@ static const struct mtk_soc_data mt7986_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 4, +- .foe_entry_size = sizeof(struct mtk_foe_entry), + .has_accounting = true, ++ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd { + struct mtk_foe_mac_info l2; + }; + ++#define MTK_FOE_ENTRY_V1_SIZE 80 ++#define MTK_FOE_ENTRY_V2_SIZE 96 ++ + struct mtk_foe_entry { + u32 ib1; + diff --git a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch new file mode 100644 index 000000000..fb54f404b --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch @@ -0,0 +1,141 @@ +From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Sat, 22 Jul 2023 21:32:49 +0100 +Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL + configuration + +MT7623 GMAC0 attempts to configure the system clocking according to the +required speed in the .mac_config callback for non-SGMII, non-baseX and +non-TRGMII modes. + +state->speed setting has never been reliable in the .mac_config +callback - there are cases where this is not the link speed, +particularly via ethtool paths, so this has always been unreliable (as +detailed in phylink's documentation.) + +There is the additional issue that mtk_gmac0_rgmii_adjust() will only +be called if state->interface changes, which means it only configures +the system clocking on the very first .mac_config call, which will be +made when the network device is first brought up before any link is +established. + +Essentially, this code is incredibly buggy, and probably never worked. + +Moreover, checking the in-kernel DT files, it seems no platform makes +use of this code path. + +Therefore, let's remove it, and disable interface modes for port 0 that +are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623. + +Reviewed-by: Daniel Golle +Tested-by: Daniel Golle +Tested-by: Frank Wunderlich +Signed-off-by: Russell King (Oracle) +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++--------------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + + 2 files changed, 17 insertions(+), 38 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -352,7 +352,7 @@ static int mt7621_gmac0_rgmii_adjust(str + } + + static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, +- phy_interface_t interface, int speed) ++ phy_interface_t interface) + { + u32 val; + int ret; +@@ -366,26 +366,7 @@ static void mtk_gmac0_rgmii_adjust(struc + return; + } + +- val = (speed == SPEED_1000) ? +- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100; +- mtk_w32(eth, val, INTF_MODE); +- +- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0, +- ETHSYS_TRGMII_CLK_SEL362_5, +- ETHSYS_TRGMII_CLK_SEL362_5); +- +- val = (speed == SPEED_1000) ? 250000000 : 500000000; +- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val); +- if (ret) +- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret); +- +- val = (speed == SPEED_1000) ? +- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100; +- mtk_w32(eth, val, TRGMII_RCK_CTRL); +- +- val = (speed == SPEED_1000) ? +- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100; +- mtk_w32(eth, val, TRGMII_TCK_CTRL); ++ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); + } + + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, +@@ -471,17 +452,8 @@ static void mtk_mac_config(struct phylin + state->interface)) + goto err_phy; + } else { +- /* FIXME: this is incorrect. Not only does it +- * use state->speed (which is not guaranteed +- * to be correct) but it also makes use of it +- * in a code path that will only be reachable +- * when the PHY interface mode changes, not +- * when the speed changes. Consequently, RGMII +- * is probably broken. +- */ + mtk_gmac0_rgmii_adjust(mac->hw, +- state->interface, +- state->speed); ++ state->interface); + + /* mt7623_pad_clk_setup */ + for (i = 0 ; i < NUM_TRGMII_CTRL; i++) +@@ -4342,13 +4314,19 @@ static int mtk_add_mac(struct mtk_eth *e + mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; + +- __set_bit(PHY_INTERFACE_MODE_MII, +- mac->phylink_config.supported_interfaces); +- __set_bit(PHY_INTERFACE_MODE_GMII, +- mac->phylink_config.supported_interfaces); ++ /* MT7623 gmac0 is now missing its speed-specific PLL configuration ++ * in its .mac_config method (since state->speed is not valid there. ++ * Disable support for MII, GMII and RGMII. ++ */ ++ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) { ++ __set_bit(PHY_INTERFACE_MODE_MII, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_GMII, ++ mac->phylink_config.supported_interfaces); + +- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) +- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); ++ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) ++ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); ++ } + + if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id) + __set_bit(PHY_INTERFACE_MODE_TRGMII, +@@ -4806,6 +4784,7 @@ static const struct mtk_soc_data mt7623_ + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, ++ .disable_pll_modes = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1030,6 +1030,7 @@ struct mtk_soc_data { + u16 foe_entry_size; + netdev_features_t hw_features; + bool has_accounting; ++ bool disable_pll_modes; + struct { + u32 txd_size; + u32 rxd_size; diff --git a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch new file mode 100644 index 000000000..500fad3b8 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch @@ -0,0 +1,81 @@ +From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Sat, 22 Jul 2023 21:32:54 +0100 +Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state + and modernise + +Remove the .mac_pcs_get_state function, since as far as I can tell is +never called - no DT appears to specify an in-band-status management +nor SFP support for this driver. + +Removal of this, along with the previous patch to remove the incorrect +clocking configuration, means that the driver becomes non-legacy, so +we can remove the "legacy_pre_march2020" status from this driver. + +Reviewed-by: Daniel Golle +Tested-by: Daniel Golle +Tested-by: Frank Wunderlich +Signed-off-by: Russell King (Oracle) +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 --------------------- + 1 file changed, 35 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -554,38 +554,6 @@ static int mtk_mac_finish(struct phylink + return 0; + } + +-static void mtk_mac_pcs_get_state(struct phylink_config *config, +- struct phylink_link_state *state) +-{ +- struct mtk_mac *mac = container_of(config, struct mtk_mac, +- phylink_config); +- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); +- +- state->link = (pmsr & MAC_MSR_LINK); +- state->duplex = (pmsr & MAC_MSR_DPX) >> 1; +- +- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) { +- case 0: +- state->speed = SPEED_10; +- break; +- case MAC_MSR_SPEED_100: +- state->speed = SPEED_100; +- break; +- case MAC_MSR_SPEED_1000: +- state->speed = SPEED_1000; +- break; +- default: +- state->speed = SPEED_UNKNOWN; +- break; +- } +- +- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); +- if (pmsr & MAC_MSR_RX_FC) +- state->pause |= MLO_PAUSE_RX; +- if (pmsr & MAC_MSR_TX_FC) +- state->pause |= MLO_PAUSE_TX; +-} +- + static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, + phy_interface_t interface) + { +@@ -708,7 +676,6 @@ static void mtk_mac_link_up(struct phyli + static const struct phylink_mac_ops mtk_phylink_ops = { + .validate = phylink_generic_validate, + .mac_select_pcs = mtk_mac_select_pcs, +- .mac_pcs_get_state = mtk_mac_pcs_get_state, + .mac_config = mtk_mac_config, + .mac_finish = mtk_mac_finish, + .mac_link_down = mtk_mac_link_down, +@@ -4309,8 +4276,6 @@ static int mtk_add_mac(struct mtk_eth *e + + mac->phylink_config.dev = ð->netdev[id]->dev; + mac->phylink_config.type = PHYLINK_NETDEV; +- /* This driver makes use of state->speed in mac_config */ +- mac->phylink_config.legacy_pre_march2020 = true; + mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; + diff --git a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch new file mode 100644 index 000000000..3b1225e94 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch @@ -0,0 +1,550 @@ +From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:52:02 +0100 +Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in + mtk_soc_data + +Introduce version field in mtk_soc_data data structure in order to +make mtk_eth driver easier to maintain for chipset configuration +codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities. +This is a preliminary patch to introduce support for MT7988 SoC. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++-------- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++----- + drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++--- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +- + drivers/net/ethernet/mediatek/mtk_wed.c | 4 +- + 5 files changed, 66 insertions(+), 49 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -579,7 +579,7 @@ static void mtk_set_queue_speed(struct m + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v1(eth)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + + if (IS_ENABLED(CONFIG_SOC_MT7621)) { +@@ -955,7 +955,7 @@ static bool mtk_rx_get_desc(struct mtk_e + rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); + rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); + rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); + rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); + } +@@ -1013,7 +1013,7 @@ static int mtk_init_fq_dma(struct mtk_et + + txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); + txd->txd4 = 0; +- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + txd->txd5 = 0; + txd->txd6 = 0; + txd->txd7 = 0; +@@ -1204,7 +1204,7 @@ static void mtk_tx_set_dma_desc(struct n + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mtk_tx_set_dma_desc_v2(dev, txd, info); + else + mtk_tx_set_dma_desc_v1(dev, txd, info); +@@ -1511,7 +1511,7 @@ static void mtk_update_rx_cpu_idx(struct + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) + { +- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); ++ return eth->soc->version == 2; + } + + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, +@@ -1853,7 +1853,7 @@ static int mtk_poll_rx(struct napi_struc + break; + + /* find out which mac the packet come from. values start at 1 */ +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; + else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && + !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) +@@ -1949,7 +1949,7 @@ static int mtk_poll_rx(struct napi_struc + skb->dev = netdev; + bytes += skb->len; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); + hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; + if (hash != MTK_RXD5_FOE_ENTRY) +@@ -1974,8 +1974,8 @@ static int mtk_poll_rx(struct napi_struc + /* When using VLAN untagging in combination with DSA, the + * hardware treats the MTK special tag as a VLAN and untags it. + */ +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && +- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { ++ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) && ++ netdev_uses_dsa(netdev)) { + unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); + + if (port < ARRAY_SIZE(eth->dsa_meta) && +@@ -2285,7 +2285,7 @@ static int mtk_tx_alloc(struct mtk_eth * + txd->txd2 = next_ptr; + txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; + txd->txd4 = 0; +- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + txd->txd5 = 0; + txd->txd6 = 0; + txd->txd7 = 0; +@@ -2338,14 +2338,14 @@ static int mtk_tx_alloc(struct mtk_eth * + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v1(eth)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); + ofs += MTK_QTX_OFFSET; + } + val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); + } else { + mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); +@@ -2474,7 +2474,7 @@ static int mtk_rx_alloc(struct mtk_eth * + + rxd->rxd3 = 0; + rxd->rxd4 = 0; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + rxd->rxd5 = 0; + rxd->rxd6 = 0; + rxd->rxd7 = 0; +@@ -3025,7 +3025,7 @@ static int mtk_start_dma(struct mtk_eth + MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | + MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + val |= MTK_MUTLI_CNT | MTK_RESV_BUF | + MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | + MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; +@@ -3167,7 +3167,7 @@ static int mtk_open(struct net_device *d + phylink_start(mac->phylink); + netif_tx_start_all_queues(dev); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return 0; + + if (mtk_uses_dsa(dev) && !eth->prog) { +@@ -3432,7 +3432,7 @@ static void mtk_hw_reset(struct mtk_eth + { + u32 val; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); + val = RSTCTRL_PPE0_V2; + } else { +@@ -3444,7 +3444,7 @@ static void mtk_hw_reset(struct mtk_eth + + ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, + 0x3ffffff); + } +@@ -3470,7 +3470,7 @@ static void mtk_hw_warm_reset(struct mtk + return; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; + else + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; +@@ -3640,7 +3640,7 @@ static int mtk_hw_init(struct mtk_eth *e + else + mtk_hw_reset(eth); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + /* Set FE to PDMAv2 if necessary */ + val = mtk_r32(eth, MTK_FE_GLO_MISC); + mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); +@@ -3677,7 +3677,7 @@ static int mtk_hw_init(struct mtk_eth *e + */ + val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); + mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v1(eth)) { + val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); + +@@ -3699,7 +3699,7 @@ static int mtk_hw_init(struct mtk_eth *e + mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); + mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + /* PSE should not drop port8 and port9 packets from WDMA Tx */ + mtk_w32(eth, 0x00000300, PSE_DROP_CFG); + +@@ -4488,7 +4488,7 @@ static int mtk_probe(struct platform_dev + } + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; +@@ -4596,9 +4596,8 @@ static int mtk_probe(struct platform_dev + } + + if (eth->soc->offload_version) { +- u32 num_ppe; ++ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1; + +- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; + num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); + for (i = 0; i < num_ppe; i++) { + u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; +@@ -4690,6 +4689,7 @@ static const struct mtk_soc_data mt2701_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4706,6 +4706,7 @@ static const struct mtk_soc_data mt7621_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7621_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, +@@ -4726,6 +4727,7 @@ static const struct mtk_soc_data mt7622_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7622_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .offload_version = 2, + .hash_offset = 2, + .has_accounting = true, +@@ -4746,6 +4748,7 @@ static const struct mtk_soc_data mt7623_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, ++ .version = 1, + .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, +@@ -4768,6 +4771,7 @@ static const struct mtk_soc_data mt7629_ + .required_clks = MT7629_CLKS_BITMAP, + .required_pctl = false, + .has_accounting = true, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4785,6 +4789,7 @@ static const struct mtk_soc_data mt7981_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7981_CLKS_BITMAP, + .required_pctl = false, ++ .version = 2, + .offload_version = 2, + .hash_offset = 4, + .has_accounting = true, +@@ -4806,6 +4811,7 @@ static const struct mtk_soc_data mt7986_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, ++ .version = 2, + .offload_version = 2, + .hash_offset = 4, + .has_accounting = true, +@@ -4826,6 +4832,7 @@ static const struct mtk_soc_data rt5350_ + .hw_features = MTK_HW_FEATURES_MT7628, + .required_clks = MT7628_CLKS_BITMAP, + .required_pctl = false, ++ .version = 1, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -820,7 +820,6 @@ enum mkt_eth_capabilities { + MTK_SHARED_INT_BIT, + MTK_TRGMII_MT7621_CLK_BIT, + MTK_QDMA_BIT, +- MTK_NETSYS_V2_BIT, + MTK_SOC_MT7628_BIT, + MTK_RSTCTRL_PPE1_BIT, + MTK_U3_COPHY_V2_BIT, +@@ -855,7 +854,6 @@ enum mkt_eth_capabilities { + #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) + #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) + #define MTK_QDMA BIT(MTK_QDMA_BIT) +-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) + #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) + #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) + #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) +@@ -934,11 +932,11 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1009,6 +1007,7 @@ struct mtk_reg_map { + * @required_pctl A bool value to show whether the SoC requires + * the extra setup for those pins used by GMAC. + * @hash_offset Flow table hash offset. ++ * @version SoC version. + * @foe_entry_size Foe table entry size. + * @has_accounting Bool indicating support for accounting of + * offloaded flows. +@@ -1027,6 +1026,7 @@ struct mtk_soc_data { + bool required_pctl; + u8 offload_version; + u8 hash_offset; ++ u8 version; + u16 foe_entry_size; + netdev_features_t hw_features; + bool has_accounting; +@@ -1183,6 +1183,16 @@ struct mtk_mac { + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; + ++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) ++{ ++ return eth->soc->version == 1; ++} ++ ++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) ++{ ++ return eth->soc->version > 1; ++} ++ + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) + { +@@ -1193,7 +1203,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u + + static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_TIMESTAMP_V2; + + return MTK_FOE_IB1_BIND_TIMESTAMP; +@@ -1201,7 +1211,7 @@ static inline u32 mtk_get_ib1_ts_mask(st + + static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_PPPOE_V2; + + return MTK_FOE_IB1_BIND_PPPOE; +@@ -1209,7 +1219,7 @@ static inline u32 mtk_get_ib1_ppoe_mask( + + static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_VLAN_TAG_V2; + + return MTK_FOE_IB1_BIND_VLAN_TAG; +@@ -1217,7 +1227,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m + + static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; + + return MTK_FOE_IB1_BIND_VLAN_LAYER; +@@ -1225,7 +1235,7 @@ static inline u32 mtk_get_ib1_vlan_layer + + static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); + + return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); +@@ -1233,7 +1243,7 @@ static inline u32 mtk_prep_ib1_vlan_laye + + static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); + + return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); +@@ -1241,7 +1251,7 @@ static inline u32 mtk_get_ib1_vlan_layer + + static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB1_PACKET_TYPE_V2; + + return MTK_FOE_IB1_PACKET_TYPE; +@@ -1249,7 +1259,7 @@ static inline u32 mtk_get_ib1_pkt_type_m + + static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); + + return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); +@@ -1257,7 +1267,7 @@ static inline u32 mtk_get_ib1_pkt_type(s + + static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) + { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + return MTK_FOE_IB2_MULTICAST_V2; + + return MTK_FOE_IB2_MULTICAST; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth + + memset(entry, 0, sizeof(*entry)); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | + FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | + FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + u32 val = *ib2; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + val &= ~MTK_FOE_IB2_DEST_PORT_V2; + val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); + } else { +@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et + struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | + MTK_FOE_IB2_WDMA_WINFO_V2; +@@ -446,7 +446,7 @@ int mtk_foe_entry_set_queue(struct mtk_e + { + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + *ib2 &= ~MTK_FOE_IB2_QID_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); + *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; +@@ -601,7 +601,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + struct mtk_foe_entry *hwe; + u32 val; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; + entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, + timestamp); +@@ -617,7 +617,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + hwe->ib1 = entry->ib1; + + if (ppe->accounting) { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + val = MTK_FOE_IB2_MIB_CNT_V2; + else + val = MTK_FOE_IB2_MIB_CNT; +@@ -965,7 +965,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_SCAN_MODE_CHECK_AGE) | + FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, + MTK_PPE_ENTRIES_SHIFT); +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_TB_CFG_INFO_SEL; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + +@@ -981,7 +981,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_FLOW_CFG_IP4_NAPT | + MTK_PPE_FLOW_CFG_IP4_DSLITE | + MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | + MTK_PPE_MD_TOAP_BYP_CRSN1 | + MTK_PPE_MD_TOAP_BYP_CRSN2 | +@@ -1023,7 +1023,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); + +- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(ppe->eth)) { + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); + ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); + } +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et + if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { + mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, + info.bss, info.wcid); +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + switch (info.wdma_idx) { + case 0: + pse_port = 8; +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * + } else { + struct mtk_eth *eth = dev->hw->eth; + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ if (mtk_is_netsys_v2_or_greater(eth)) + wed_set(dev, MTK_WED_RESET_IDX, + MTK_WED_RESET_IDX_RX_V2); + else +@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node * + hw->wdma = wdma; + hw->index = index; + hw->irq = irq; +- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; ++ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; + + if (hw->version == 1) { + hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, diff --git a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch new file mode 100644 index 000000000..7b945bb86 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch @@ -0,0 +1,29 @@ +From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:52:27 +0100 +Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3 + +This is a preliminary patch to add MT7988 SoC support since it runs 3 +macs instead of 2. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1043,8 +1043,8 @@ struct mtk_soc_data { + + #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) + +-/* currently no SoC has more than 2 macs */ +-#define MTK_MAX_DEVS 2 ++/* currently no SoC has more than 3 macs */ ++#define MTK_MAX_DEVS 3 + + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver diff --git a/target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch b/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch similarity index 50% rename from target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch rename to target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch index 5033887f0..807165831 100644 --- a/target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch +++ b/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch @@ -1,143 +1,176 @@ -From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001 +From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:35 +0000 -Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove - MTK_MAC_COUNT +Date: Tue, 25 Jul 2023 01:52:44 +0100 +Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and + remove MTK_MAC_COUNT -Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs. +Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++----------- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++--------- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 15 insertions(+), 16 deletions(-) + 2 files changed, 27 insertions(+), 23 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -899,7 +899,7 @@ static void mtk_stats_update(struct mtk_ +@@ -881,7 +881,7 @@ static void mtk_stats_update(struct mtk_ { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->mac[i] || !eth->mac[i]->hw_stats) continue; if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) { -@@ -1402,7 +1402,7 @@ static int mtk_queue_stopped(struct mtk_ +@@ -1386,7 +1386,7 @@ static int mtk_queue_stopped(struct mtk_ { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; if (netif_queue_stopped(eth->netdev[i])) -@@ -1416,7 +1416,7 @@ static void mtk_wake_queue(struct mtk_et +@@ -1400,7 +1400,7 @@ static void mtk_wake_queue(struct mtk_et { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; netif_tx_wake_all_queues(eth->netdev[i]); -@@ -1907,7 +1907,7 @@ static int mtk_poll_rx(struct napi_struc +@@ -1859,7 +1859,7 @@ static int mtk_poll_rx(struct napi_struc !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; - if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || -+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs || ++ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || !eth->netdev[mac])) goto release_desc; -@@ -2939,7 +2939,7 @@ static void mtk_dma_free(struct mtk_eth +@@ -2899,7 +2899,7 @@ static void mtk_dma_free(struct mtk_eth const struct mtk_soc_data *soc = eth->soc; int i; - for (i = 0; i < MTK_MAC_COUNT; i++) -+ for (i = 0; i < soc->num_devs; i++) ++ for (i = 0; i < MTK_MAX_DEVS; i++) if (eth->netdev[i]) netdev_reset_queue(eth->netdev[i]); if (eth->scratch_ring) { -@@ -3093,7 +3093,7 @@ static void mtk_gdm_config(struct mtk_et +@@ -3053,8 +3053,13 @@ static void mtk_gdm_config(struct mtk_et if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) return; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); +- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ u32 val; ++ ++ if (!eth->netdev[i]) ++ continue; ++ ++ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); /* default setup the forward port to send frame to PDMA */ -@@ -3706,7 +3706,7 @@ static int mtk_hw_init(struct mtk_eth *e + val &= ~0xffff; +@@ -3064,7 +3069,7 @@ static void mtk_gdm_config(struct mtk_et + + val |= config; + +- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) ++ if (netdev_uses_dsa(eth->netdev[i])) + val |= MTK_GDMA_SPECIAL_TAG; + + mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); +@@ -3661,15 +3666,15 @@ static int mtk_hw_init(struct mtk_eth *e * up with the more appropriate value when mtk_mac_config call is being * invoked. */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { struct net_device *dev = eth->netdev[i]; - mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -@@ -3894,7 +3894,7 @@ static void mtk_pending_work(struct work +- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); +- if (dev) { +- struct mtk_mac *mac = netdev_priv(dev); ++ if (!dev) ++ continue; + +- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); +- } ++ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); ++ mtk_set_mcr_max_rx(netdev_priv(dev), ++ dev->mtu + MTK_RX_ETH_HLEN); + } + + /* Indicates CDM to parse the MTK special tag from CPU +@@ -3849,7 +3854,7 @@ static void mtk_pending_work(struct work mtk_prepare_for_reset(eth); /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i] || !netif_running(eth->netdev[i])) continue; -@@ -3910,7 +3910,7 @@ static void mtk_pending_work(struct work +@@ -3865,8 +3870,8 @@ static void mtk_pending_work(struct work mtk_hw_init(eth, true); /* restart DMA and enable IRQs */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - if (!test_bit(i, &restart)) +- if (!test_bit(i, &restart)) ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->netdev[i] || !test_bit(i, &restart)) continue; -@@ -3938,7 +3938,7 @@ static int mtk_free_dev(struct mtk_eth * + if (mtk_open(eth->netdev[i])) { +@@ -3893,7 +3898,7 @@ static int mtk_free_dev(struct mtk_eth * { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; free_netdev(eth->netdev[i]); -@@ -3957,7 +3957,7 @@ static int mtk_unreg_dev(struct mtk_eth +@@ -3912,7 +3917,7 @@ static int mtk_unreg_dev(struct mtk_eth { int i; - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { struct mtk_mac *mac; if (!eth->netdev[i]) continue; -@@ -4261,7 +4261,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4213,7 +4218,7 @@ static int mtk_add_mac(struct mtk_eth *e } id = be32_to_cpup(_id); - if (id >= MTK_MAC_COUNT) { -+ if (id >= eth->soc->num_devs) { ++ if (id >= MTK_MAX_DEVS) { dev_err(eth->dev, "%d is not a valid mac id\n", id); return -EINVAL; } -@@ -4402,7 +4402,7 @@ void mtk_eth_set_dma_device(struct mtk_e +@@ -4358,7 +4363,7 @@ void mtk_eth_set_dma_device(struct mtk_e rtnl_lock(); - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { dev = eth->netdev[i]; if (!dev || !(dev->flags & IFF_UP)) -@@ -4729,7 +4729,7 @@ static int mtk_remove(struct platform_de +@@ -4664,7 +4669,7 @@ static int mtk_remove(struct platform_de int i; /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { ++ for (i = 0; i < MTK_MAX_DEVS; i++) { if (!eth->netdev[i]) continue; mtk_stop(eth->netdev[i]); diff --git a/target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch b/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch similarity index 63% rename from target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch rename to target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch index ccf9e0d65..1a9b31f52 100644 --- a/target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch +++ b/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch @@ -1,22 +1,24 @@ -From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001 +From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:47 +0000 -Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability - bit +Date: Tue, 25 Jul 2023 01:52:59 +0100 +Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version + support -Introduce MTK_NETSYS_V3 bit in the device capabilities. +Introduce NETSYS_V3 chipset version support. This is a preliminary patch to introduce support for MT7988 SoC. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++- - 2 files changed, 134 insertions(+), 25 deletions(-) + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++-- + 2 files changed, 116 insertions(+), 37 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -923,17 +923,32 @@ void mtk_stats_update_mac(struct mtk_mac +@@ -861,17 +861,32 @@ void mtk_stats_update_mac(struct mtk_mac mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); hw_stats->rx_flow_control_packets += mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); @@ -32,7 +34,7 @@ Signed-off-by: Daniel Golle - hw_stats->tx_packets += - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); + -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { + hw_stats->tx_skip += + mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs); + hw_stats->tx_collisions += @@ -60,7 +62,7 @@ Signed-off-by: Daniel Golle } u64_stats_update_end(&hw_stats->syncp); -@@ -1237,7 +1252,10 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1175,7 +1190,10 @@ static void mtk_tx_set_dma_desc_v2(struc data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); @@ -72,57 +74,53 @@ Signed-off-by: Daniel Golle data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); WRITE_ONCE(desc->txd4, data); -@@ -1248,6 +1266,9 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1186,6 +1204,8 @@ static void mtk_tx_set_dma_desc_v2(struc /* tx checksum offload */ if (info->csum) data |= TX_DMA_CHKSUM_V2; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ netdev_uses_dsa(dev)) ++ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev)) + data |= TX_DMA_SPTAG_V3; } WRITE_ONCE(desc->txd5, data); -@@ -1313,8 +1334,13 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1251,8 +1271,7 @@ static int mtk_tx_map(struct sk_buff *sk mtk_tx_set_dma_desc(dev, itxd, &txd_info); itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -+ if (mac->id == MTK_GMAC1_ID) -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0; -+ else if (mac->id == MTK_GMAC2_ID) -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1; -+ else -+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2; -+ ++ itx_buf->mac_id = mac->id; setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, k++); -@@ -1362,8 +1388,13 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1300,8 +1319,7 @@ static int mtk_tx_map(struct sk_buff *sk memset(tx_buf, 0, sizeof(*tx_buf)); tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; tx_buf->flags |= MTK_TX_FLAGS_PAGE0; - tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0; -+ else if (mac->id == MTK_GMAC2_ID) -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1; -+ else -+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2; ++ tx_buf->mac_id = mac->id; setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, k++); -@@ -1949,11 +1980,24 @@ static int mtk_poll_rx(struct napi_struc +@@ -1603,7 +1621,7 @@ static int mtk_xdp_frame_map(struct mtk_ + } + mtk_tx_set_dma_desc(dev, txd, txd_info); + +- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; ++ tx_buf->mac_id = mac->id; + tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; + tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; + +@@ -1853,11 +1871,24 @@ static int mtk_poll_rx(struct napi_struc break; /* find out which mac the packet come from. values start at 1 */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) +- if (mtk_is_netsys_v2_or_greater(eth)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) { + u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); + + switch (val) { @@ -137,29 +135,44 @@ Signed-off-by: Daniel Golle + break; + } + } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { ++ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; + } - if (unlikely(mac < 0 || mac >= eth->soc->num_devs || + if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || !eth->netdev[mac])) -@@ -2184,7 +2228,9 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -2079,7 +2110,6 @@ static int mtk_poll_tx_qdma(struct mtk_e + + while ((cpu != dma) && budget) { + u32 next_cpu = desc->txd2; +- int mac = 0; + + desc = mtk_qdma_phys_to_virt(ring, desc->txd2); + if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) +@@ -2087,15 +2117,13 @@ static int mtk_poll_tx_qdma(struct mtk_e + tx_buf = mtk_desc_to_tx_buf(ring, desc, eth->soc->txrx.txd_size); - if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) +- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) - mac = 1; -+ mac = MTK_GMAC2_ID; -+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2) -+ mac = MTK_GMAC3_ID; - +- if (!tx_buf->data) break; -@@ -3798,7 +3844,26 @@ static int mtk_hw_init(struct mtk_eth *e + + if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { + if (tx_buf->type == MTK_TYPE_SKB) +- mtk_poll_tx_done(eth, state, mac, tx_buf->data); ++ mtk_poll_tx_done(eth, state, tx_buf->mac_id, ++ tx_buf->data); + + budget--; + } +@@ -3704,7 +3732,24 @@ static int mtk_hw_init(struct mtk_eth *e mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { + /* PSE should not drop port1, port8 and port9 packets */ + mtk_w32(eth, 0x00000302, PSE_DROP_CFG); + @@ -168,9 +181,7 @@ Signed-off-by: Daniel Golle + mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES); + + /* Disable GDM1 RX CRC stripping */ -+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0)); -+ val &= ~MTK_GDMA_STRP_CRC; -+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0)); ++ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0)); + + /* PSE GDM3 MIB counter has incorrect hw default values, + * so the driver ought to read clear the values beforehand @@ -178,17 +189,17 @@ Signed-off-by: Daniel Golle + */ + for (i = 0; i < 0x80; i += 0x4) + mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i); -+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ } else if (!mtk_is_netsys_v1(eth)) { /* PSE should not drop port8 and port9 packets from WDMA Tx */ mtk_w32(eth, 0x00000300, PSE_DROP_CFG); -@@ -4363,7 +4428,11 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4266,7 +4311,11 @@ static int mtk_add_mac(struct mtk_eth *e } spin_lock_init(&mac->hw_stats->stats_lock); u64_stats_init(&mac->hw_stats->syncp); - mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; + -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) ++ if (mtk_is_netsys_v3_or_greater(eth)) + mac->hw_stats->reg_offset = id * 0x80; + else + mac->hw_stats->reg_offset = id * 0x40; @@ -197,7 +208,7 @@ Signed-off-by: Daniel Golle err = of_get_phy_mode(np, &phy_mode); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -121,6 +121,7 @@ +@@ -122,6 +122,7 @@ #define MTK_GDMA_ICS_EN BIT(22) #define MTK_GDMA_TCS_EN BIT(21) #define MTK_GDMA_UCS_EN BIT(20) @@ -205,7 +216,7 @@ Signed-off-by: Daniel Golle #define MTK_GDMA_TO_PDMA 0x0 #define MTK_GDMA_DROP_ALL 0x7777 -@@ -286,8 +287,6 @@ +@@ -287,8 +288,6 @@ /* QDMA Interrupt grouping registers */ #define MTK_RLS_DONE_INT BIT(0) @@ -214,7 +225,7 @@ Signed-off-by: Daniel Golle /* QDMA TX NUM */ #define QID_BITS_V2(x) (((x) & 0x3f) << 16) #define MTK_QDMA_GMAC2_QID 8 -@@ -300,6 +299,8 @@ +@@ -301,6 +300,8 @@ #define TX_DMA_CHKSUM_V2 (0x7 << 28) #define TX_DMA_TSO_V2 BIT(31) @@ -223,15 +234,20 @@ Signed-off-by: Daniel Golle /* QDMA V2 descriptor txd4 */ #define TX_DMA_FPORT_SHIFT_V2 8 #define TX_DMA_FPORT_MASK_V2 0xf -@@ -639,6 +640,7 @@ enum mtk_tx_flags { +@@ -634,12 +635,6 @@ enum mtk_tx_flags { */ - MTK_TX_FLAGS_FPORT0 = 0x04, - MTK_TX_FLAGS_FPORT1 = 0x08, -+ MTK_TX_FLAGS_FPORT2 = 0x10, + MTK_TX_FLAGS_SINGLE0 = 0x01, + MTK_TX_FLAGS_PAGE0 = 0x02, +- +- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted +- * SKB out instead of looking up through hardware TX descriptor. +- */ +- MTK_TX_FLAGS_FPORT0 = 0x04, +- MTK_TX_FLAGS_FPORT1 = 0x08, }; /* This enum allows us to identify how the clock is defined on the array of the -@@ -724,6 +726,42 @@ enum mtk_dev_state { +@@ -725,6 +720,35 @@ enum mtk_dev_state { MTK_RESETTING }; @@ -263,30 +279,29 @@ Signed-off-by: Daniel Golle + MTK_GMAC3_ID, + MTK_GMAC_ID_MAX +}; -+ -+/* GDM Type */ -+enum mtk_gdm_type { -+ MTK_GDM_TYPE = 0, -+ MTK_XGDM_TYPE, -+ MTK_GDM_TYPE_MAX -+}; + enum mtk_tx_buf_type { MTK_TYPE_SKB, MTK_TYPE_XDP_TX, -@@ -820,6 +858,7 @@ enum mkt_eth_capabilities { - MTK_QDMA_BIT, - MTK_NETSYS_V1_BIT, - MTK_NETSYS_V2_BIT, -+ MTK_NETSYS_V3_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, - MTK_U3_COPHY_V2_BIT, -@@ -856,6 +895,7 @@ enum mkt_eth_capabilities { - #define MTK_QDMA BIT(MTK_QDMA_BIT) - #define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) -+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) - #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) +@@ -743,7 +767,8 @@ struct mtk_tx_buf { + enum mtk_tx_buf_type type; + void *data; + +- u32 flags; ++ u16 mac_id; ++ u16 flags; + DEFINE_DMA_UNMAP_ADDR(dma_addr0); + DEFINE_DMA_UNMAP_LEN(dma_len0); + DEFINE_DMA_UNMAP_ADDR(dma_addr1); +@@ -1192,6 +1217,11 @@ static inline bool mtk_is_netsys_v2_or_g + return eth->soc->version > 1; + } + ++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) ++{ ++ return eth->soc->version > 2; ++} ++ + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) + { diff --git a/target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch similarity index 89% rename from target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch rename to target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch index bd26cca30..7a0b285f2 100644 --- a/target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch +++ b/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch @@ -1,17 +1,19 @@ -From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001 +From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:56:00 +0000 -Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data - struct to u64 +Date: Tue, 25 Jul 2023 01:53:13 +0100 +Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in + mtk_soc_data struct to u64 This is a preliminary patch to introduce support for MT7988 SoC. Signed-off-by: Lorenzo Bianconi Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski --- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++---------- - 2 files changed, 42 insertions(+), 42 deletions(-) + drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++---- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++---------- + 2 files changed, 39 insertions(+), 39 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_path.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c @@ -111,7 +113,7 @@ Signed-off-by: Daniel Golle MTK_ETH_PATH_GMAC2_RGMII; --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -878,44 +878,44 @@ enum mkt_eth_capabilities { +@@ -866,41 +866,41 @@ enum mkt_eth_capabilities { }; /* Supported hardware group on SoCs */ @@ -127,9 +129,6 @@ Signed-off-by: Daniel Golle -#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) -#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) -#define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) --#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) --#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT) -#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) -#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) @@ -145,9 +144,6 @@ Signed-off-by: Daniel Golle +#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT) +#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT) +#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) -+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT) -+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT) -+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT) +#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) +#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) +#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) @@ -186,7 +182,7 @@ Signed-off-by: Daniel Golle #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1071,7 +1071,7 @@ struct mtk_reg_map { +@@ -1045,7 +1045,7 @@ struct mtk_reg_map { struct mtk_soc_data { const struct mtk_reg_map *reg_map; u32 ana_rgc3; diff --git a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch new file mode 100644 index 000000000..5947d385f --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch @@ -0,0 +1,132 @@ +From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 25 Jul 2023 01:53:28 +0100 +Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to + u64 + +The to-be-added MT7988 SoC adds many new clocks which need to be +controlled by the Ethernet driver, which will result in their total +number exceeding 32. +Prepare by converting clock bitmaps into 64-bit types. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++---------- + 1 file changed, 49 insertions(+), 47 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -666,54 +666,56 @@ enum mtk_clks_map { + MTK_CLK_MAX + }; + +-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ +- BIT(MTK_CLK_TRGPLL)) +-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_GP2) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK) | \ +- BIT(MTK_CLK_ETH2PLL)) ++#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_TRGPLL)) ++#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK) | \ ++ BIT_ULL(MTK_CLK_ETH2PLL)) + #define MT7621_CLKS_BITMAP (0) + #define MT7628_CLKS_BITMAP (0) +-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ +- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK) | \ +- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) +-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_WOCPU0) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB) | \ +- BIT(MTK_CLK_SGMII_CK)) +-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ +- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ +- BIT(MTK_CLK_SGMII_TX_250M) | \ +- BIT(MTK_CLK_SGMII_RX_250M) | \ +- BIT(MTK_CLK_SGMII_CDR_REF) | \ +- BIT(MTK_CLK_SGMII_CDR_FB) | \ +- BIT(MTK_CLK_SGMII2_TX_250M) | \ +- BIT(MTK_CLK_SGMII2_RX_250M) | \ +- BIT(MTK_CLK_SGMII2_CDR_REF) | \ +- BIT(MTK_CLK_SGMII2_CDR_FB)) ++#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK) | \ ++ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) ++#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII_CK)) ++#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP1) | \ ++ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) + + enum mtk_dev_state { + MTK_HW_INIT, +@@ -1046,7 +1048,7 @@ struct mtk_soc_data { + const struct mtk_reg_map *reg_map; + u32 ana_rgc3; + u64 caps; +- u32 required_clks; ++ u64 required_clks; + bool required_pctl; + u8 offload_version; + u8 hash_offset; diff --git a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch new file mode 100644 index 000000000..8c24321dd --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch @@ -0,0 +1,477 @@ +From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Jul 2023 01:57:42 +0100 +Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for + MT7988 SoC + +Introduce support for ethernet chip available in MT7988 SoC to +mtk_eth_soc driver. As a first step support only the first GMAC which +is hard-wired to the internal DSA switch having 4 built-in gigabit +Ethernet PHYs. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++- + 3 files changed, 273 insertions(+), 28 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64 + static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) + { + bool updated = true; +- u32 val, mask, set; ++ u32 mask, set, reg; + + switch (path) { + case MTK_ETH_PATH_GMAC1_SGMII: +@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str + break; + } + +- if (updated) { +- val = mtk_r32(eth, MTK_MAC_MISC); +- val = (val & mask) | set; +- mtk_w32(eth, val, MTK_MAC_MISC); +- } ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ reg = MTK_MAC_MISC_V3; ++ else ++ reg = MTK_MAC_MISC; ++ ++ if (updated) ++ mtk_m32(eth, mask, set, reg); + + dev_dbg(eth->dev, "path %s in %s updated = %d\n", + mtk_eth_path_name(path), __func__, updated); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r + .pse_oq_sta = 0x01a0, + }; + ++static const struct mtk_reg_map mt7988_reg_map = { ++ .tx_irq_mask = 0x461c, ++ .tx_irq_status = 0x4618, ++ .pdma = { ++ .rx_ptr = 0x6900, ++ .rx_cnt_cfg = 0x6904, ++ .pcrx_ptr = 0x6908, ++ .glo_cfg = 0x6a04, ++ .rst_idx = 0x6a08, ++ .delay_irq = 0x6a0c, ++ .irq_status = 0x6a20, ++ .irq_mask = 0x6a28, ++ .adma_rx_dbg0 = 0x6a38, ++ .int_grp = 0x6a50, ++ }, ++ .qdma = { ++ .qtx_cfg = 0x4400, ++ .qtx_sch = 0x4404, ++ .rx_ptr = 0x4500, ++ .rx_cnt_cfg = 0x4504, ++ .qcrx_ptr = 0x4508, ++ .glo_cfg = 0x4604, ++ .rst_idx = 0x4608, ++ .delay_irq = 0x460c, ++ .fc_th = 0x4610, ++ .int_grp = 0x4620, ++ .hred = 0x4644, ++ .ctx_ptr = 0x4700, ++ .dtx_ptr = 0x4704, ++ .crx_ptr = 0x4710, ++ .drx_ptr = 0x4714, ++ .fq_head = 0x4720, ++ .fq_tail = 0x4724, ++ .fq_count = 0x4728, ++ .fq_blen = 0x472c, ++ .tx_sch_rate = 0x4798, ++ }, ++ .gdm1_cnt = 0x1c00, ++ .gdma_to_ppe = 0x3333, ++ .ppe_base = 0x2000, ++ .wdma_base = { ++ [0] = 0x4800, ++ [1] = 0x4c00, ++ }, ++ .pse_iq_sta = 0x0180, ++ .pse_oq_sta = 0x01a0, ++}; ++ + /* strings used by ethtool */ + static const struct mtk_ethtool_stats { + char str[ETH_GSTRING_LEN]; +@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { + }; + + static const char * const mtk_clks_source_name[] = { +- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", +- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", +- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", +- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" ++ "ethif", ++ "sgmiitop", ++ "esw", ++ "gp0", ++ "gp1", ++ "gp2", ++ "gp3", ++ "xgp1", ++ "xgp2", ++ "xgp3", ++ "crypto", ++ "fe", ++ "trgpll", ++ "sgmii_tx250m", ++ "sgmii_rx250m", ++ "sgmii_cdr_ref", ++ "sgmii_cdr_fb", ++ "sgmii2_tx250m", ++ "sgmii2_rx250m", ++ "sgmii2_cdr_ref", ++ "sgmii2_cdr_fb", ++ "sgmii_ck", ++ "eth2pll", ++ "wocpu0", ++ "wocpu1", ++ "netsys0", ++ "netsys1", ++ "ethwarp_wocpu2", ++ "ethwarp_wocpu1", ++ "ethwarp_wocpu0", ++ "top_usxgmii0_sel", ++ "top_usxgmii1_sel", ++ "top_sgm0_sel", ++ "top_sgm1_sel", ++ "top_xfi_phy0_xtal_sel", ++ "top_xfi_phy1_xtal_sel", ++ "top_eth_gmii_sel", ++ "top_eth_refck_50m_sel", ++ "top_eth_sys_200m_sel", ++ "top_eth_sys_sel", ++ "top_eth_xgmii_sel", ++ "top_eth_mii_sel", ++ "top_netsys_sel", ++ "top_netsys_500m_sel", ++ "top_netsys_pao_2x_sel", ++ "top_netsys_sync_250m_sel", ++ "top_netsys_ppefb_250m_sel", ++ "top_netsys_warp_sel", + }; + + void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) +@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne + return __raw_readl(eth->base + reg); + } + +-static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg) ++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg) + { + u32 val; + +@@ -369,6 +461,19 @@ static void mtk_gmac0_rgmii_adjust(struc + dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); + } + ++static void mtk_setup_bridge_switch(struct mtk_eth *eth) ++{ ++ /* Force Port1 XGMAC Link Up */ ++ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), ++ MTK_XGMAC_STS(MTK_GMAC1_ID)); ++ ++ /* Adjust GSW bridge IPG to 11 */ ++ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK, ++ (GSW_IPG_11 << GSWTX_IPG_SHIFT) | ++ (GSW_IPG_11 << GSWRX_IPG_SHIFT), ++ MTK_GSW_CFG); ++} ++ + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) + { +@@ -438,6 +543,8 @@ static void mtk_mac_config(struct phylin + goto init_err; + } + break; ++ case PHY_INTERFACE_MODE_INTERNAL: ++ break; + default: + goto err_phy; + } +@@ -515,6 +622,15 @@ static void mtk_mac_config(struct phylin + return; + } + ++ /* Setup gmac */ ++ if (mtk_is_netsys_v3_or_greater(eth) && ++ mac->interface == PHY_INTERFACE_MODE_INTERNAL) { ++ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); ++ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ ++ mtk_setup_bridge_switch(eth); ++ } ++ + return; + + err_phy: +@@ -725,11 +841,15 @@ static int mtk_mdio_init(struct mtk_eth + } + divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); + ++ /* Configure MDC Turbo Mode */ ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3); ++ + /* Configure MDC Divider */ +- val = mtk_r32(eth, MTK_PPSC); +- val &= ~PPSC_MDC_CFG; +- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; +- mtk_w32(eth, val, MTK_PPSC); ++ val = FIELD_PREP(PPSC_MDC_CFG, divider); ++ if (!mtk_is_netsys_v3_or_greater(eth)) ++ val |= PPSC_MDC_TURBO; ++ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC); + + dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); + +@@ -1190,10 +1310,19 @@ static void mtk_tx_set_dma_desc_v2(struc + data |= TX_DMA_LS0; + WRITE_ONCE(desc->txd3, data); + +- if (mac->id == MTK_GMAC3_ID) +- data = PSE_GDM3_PORT; +- else +- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ ++ /* set forward port */ ++ switch (mac->id) { ++ case MTK_GMAC1_ID: ++ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ case MTK_GMAC2_ID: ++ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ case MTK_GMAC3_ID: ++ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; ++ break; ++ } ++ + data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); + WRITE_ONCE(desc->txd4, data); + +@@ -4360,6 +4489,17 @@ static int mtk_add_mac(struct mtk_eth *e + mac->phylink_config.supported_interfaces); + } + ++ if (mtk_is_netsys_v3_or_greater(mac->hw) && ++ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) && ++ id == MTK_GMAC1_ID) { ++ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | ++ MAC_SYM_PAUSE | ++ MAC_10000FD; ++ phy_interface_zero(mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_INTERNAL, ++ mac->phylink_config.supported_interfaces); ++ } ++ + phylink = phylink_create(&mac->phylink_config, + of_fwnode_handle(mac->of_node), + phy_mode, &mtk_phylink_ops); +@@ -4880,6 +5020,24 @@ static const struct mtk_soc_data mt7986_ + }, + }; + ++static const struct mtk_soc_data mt7988_data = { ++ .reg_map = &mt7988_reg_map, ++ .ana_rgc3 = 0x128, ++ .caps = MT7988_CAPS, ++ .hw_features = MTK_HW_FEATURES, ++ .required_clks = MT7988_CLKS_BITMAP, ++ .required_pctl = false, ++ .version = 3, ++ .txrx = { ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, ++ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, ++ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, ++ .dma_len_offset = 8, ++ }, ++}; ++ + static const struct mtk_soc_data rt5350_data = { + .reg_map = &mt7628_reg_map, + .caps = MT7628_CAPS, +@@ -4898,14 +5056,15 @@ static const struct mtk_soc_data rt5350_ + }; + + const struct of_device_id of_mtk_match[] = { +- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, +- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, +- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, +- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, +- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, +- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, +- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, +- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, ++ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, ++ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, ++ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, ++ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, ++ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, ++ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, ++ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, ++ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, ++ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, of_mtk_match); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -117,7 +117,8 @@ + #define MTK_CDMP_EG_CTRL 0x404 + + /* GDM Exgress Control Register */ +-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) ++#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x540 : 0x500 + (_x * 0x1000); }) + #define MTK_GDMA_SPECIAL_TAG BIT(24) + #define MTK_GDMA_ICS_EN BIT(22) + #define MTK_GDMA_TCS_EN BIT(21) +@@ -126,6 +127,11 @@ + #define MTK_GDMA_TO_PDMA 0x0 + #define MTK_GDMA_DROP_ALL 0x7777 + ++/* GDM Egress Control Register */ ++#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x544 : 0x504 + (_x * 0x1000); }) ++#define MTK_GDMA_XGDM_SEL BIT(31) ++ + /* Unicast Filter MAC Address Register - Low */ + #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) + +@@ -389,7 +395,26 @@ + #define PHY_IAC_TIMEOUT HZ + + #define MTK_MAC_MISC 0x1000c ++#define MTK_MAC_MISC_V3 0x10010 + #define MTK_MUX_TO_ESW BIT(0) ++#define MISC_MDC_TURBO BIT(4) ++ ++/* XMAC status registers */ ++#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) ++#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) ++#define MTK_USXGMII_PCS_LINK BIT(8) ++#define MTK_XGMAC_RX_FC BIT(5) ++#define MTK_XGMAC_TX_FC BIT(4) ++#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) ++#define MTK_XGMAC_LINK_STS BIT(0) ++ ++/* GSW bridge registers */ ++#define MTK_GSW_CFG (0x10080) ++#define GSWTX_IPG_MASK GENMASK(19, 16) ++#define GSWTX_IPG_SHIFT 16 ++#define GSWRX_IPG_MASK GENMASK(3, 0) ++#define GSWRX_IPG_SHIFT 0 ++#define GSW_IPG_11 11 + + /* Mac control registers */ + #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) +@@ -647,6 +672,11 @@ enum mtk_clks_map { + MTK_CLK_GP0, + MTK_CLK_GP1, + MTK_CLK_GP2, ++ MTK_CLK_GP3, ++ MTK_CLK_XGP1, ++ MTK_CLK_XGP2, ++ MTK_CLK_XGP3, ++ MTK_CLK_CRYPTO, + MTK_CLK_FE, + MTK_CLK_TRGPLL, + MTK_CLK_SGMII_TX_250M, +@@ -663,6 +693,27 @@ enum mtk_clks_map { + MTK_CLK_WOCPU1, + MTK_CLK_NETSYS0, + MTK_CLK_NETSYS1, ++ MTK_CLK_ETHWARP_WOCPU2, ++ MTK_CLK_ETHWARP_WOCPU1, ++ MTK_CLK_ETHWARP_WOCPU0, ++ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, ++ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, ++ MTK_CLK_TOP_SGM_0_SEL, ++ MTK_CLK_TOP_SGM_1_SEL, ++ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, ++ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, ++ MTK_CLK_TOP_ETH_GMII_SEL, ++ MTK_CLK_TOP_ETH_REFCK_50M_SEL, ++ MTK_CLK_TOP_ETH_SYS_200M_SEL, ++ MTK_CLK_TOP_ETH_SYS_SEL, ++ MTK_CLK_TOP_ETH_XGMII_SEL, ++ MTK_CLK_TOP_ETH_MII_SEL, ++ MTK_CLK_TOP_NETSYS_SEL, ++ MTK_CLK_TOP_NETSYS_500M_SEL, ++ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, ++ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, ++ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, ++ MTK_CLK_TOP_NETSYS_WARP_SEL, + MTK_CLK_MAX + }; + +@@ -716,6 +767,36 @@ enum mtk_clks_map { + BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ + BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ + BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) ++#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ ++ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ ++ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ ++ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ ++ BIT_ULL(MTK_CLK_CRYPTO) | \ ++ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ ++ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ ++ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ ++ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) + + enum mtk_dev_state { + MTK_HW_INIT, +@@ -964,6 +1045,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1) + ++#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) ++ + struct mtk_tx_dma_desc_info { + dma_addr_t addr; + u32 size; +@@ -1309,6 +1392,7 @@ void mtk_stats_update_mac(struct mtk_mac + + void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); + u32 mtk_r32(struct mtk_eth *eth, unsigned reg); ++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); + + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); diff --git a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch new file mode 100644 index 000000000..3dc4662d1 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch @@ -0,0 +1,27 @@ +From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 27 Jul 2023 09:02:26 +0200 +Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support + for MT7988 SoC + +In order to recycle pages, enable page_pool allocator for MT7988 SoC. + +Tested-by: Daniel Golle +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1658,7 +1658,7 @@ static void mtk_update_rx_cpu_idx(struct + + static bool mtk_page_pool_enabled(struct mtk_eth *eth) + { +- return eth->soc->version == 2; ++ return mtk_is_netsys_v2_or_greater(eth); + } + + static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch new file mode 100644 index 000000000..32f26d7d2 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch @@ -0,0 +1,135 @@ +From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 27 Jul 2023 09:07:28 +0200 +Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw + flowtable_offload for MT7988 SoC + +Enable hw Packet Process Engine (PPE) for MT7988 SoC. + +Tested-by: Daniel Golle +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++---- + drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++- + 3 files changed, 36 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -5028,6 +5028,9 @@ static const struct mtk_soc_data mt7988_ + .required_clks = MT7988_CLKS_BITMAP, + .required_pctl = false, + .version = 3, ++ .offload_version = 2, ++ .hash_offset = 4, ++ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et + struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ switch (eth->soc->version) { ++ case 3: ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | ++ MTK_FOE_IB2_WDMA_WINFO_V2; ++ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | ++ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); ++ break; ++ case 2: + *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; + *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | + MTK_FOE_IB2_WDMA_WINFO_V2; + l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | + FIELD_PREP(MTK_FOE_WINFO_BSS, bss); +- } else { ++ break; ++ default: + *ib2 &= ~MTK_FOE_IB2_PORT_MG; + *ib2 |= MTK_FOE_IB2_WDMA_WINFO; + if (wdma_idx) +@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et + l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | + FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | + FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ break; + } + + return 0; +@@ -950,8 +960,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + mtk_ppe_init_foe_table(ppe); + ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); + +- val = MTK_PPE_TB_CFG_ENTRY_80B | +- MTK_PPE_TB_CFG_AGE_NON_L4 | ++ val = MTK_PPE_TB_CFG_AGE_NON_L4 | + MTK_PPE_TB_CFG_AGE_UNBIND | + MTK_PPE_TB_CFG_AGE_TCP | + MTK_PPE_TB_CFG_AGE_UDP | +@@ -967,6 +976,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_ENTRIES_SHIFT); + if (mtk_is_netsys_v2_or_greater(ppe->eth)) + val |= MTK_PPE_TB_CFG_INFO_SEL; ++ if (!mtk_is_netsys_v3_or_greater(ppe->eth)) ++ val |= MTK_PPE_TB_CFG_ENTRY_80B; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + + ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -85,6 +85,17 @@ enum { + #define MTK_FOE_WINFO_BSS GENMASK(5, 0) + #define MTK_FOE_WINFO_WCID GENMASK(15, 6) + ++#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) ++#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) ++ ++#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) ++#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) ++#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) ++#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) ++#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) ++#define MTK_FOE_WINFO_PAO_HF BIT(23) ++#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) ++ + enum { + MTK_FOE_STATE_INVALID, + MTK_FOE_STATE_UNBIND, +@@ -106,8 +117,13 @@ struct mtk_foe_mac_info { + u16 pppoe_id; + u16 src_mac_lo; + ++ /* netsys_v2 */ + u16 minfo; + u16 winfo; ++ ++ /* netsys_v3 */ ++ u32 w3info; ++ u32 wpao; + }; + + /* software-only entry type */ +@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd { + + #define MTK_FOE_ENTRY_V1_SIZE 80 + #define MTK_FOE_ENTRY_V2_SIZE 96 ++#define MTK_FOE_ENTRY_V3_SIZE 128 + + struct mtk_foe_entry { + u32 ib1; +@@ -228,7 +245,7 @@ struct mtk_foe_entry { + struct mtk_foe_ipv4_dslite dslite; + struct mtk_foe_ipv6 ipv6; + struct mtk_foe_ipv6_6rd ipv6_6rd; +- u32 data[23]; ++ u32 data[31]; + }; + }; + diff --git a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch new file mode 100644 index 000000000..876bdd5dd --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch @@ -0,0 +1,78 @@ +From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 2 Aug 2023 04:31:09 +0100 +Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow + accounting on MT7988 + +NETSYS_V3 uses 64 bits for each counters while older SoCs are using +48/40 bits for each counter. +Support reading per-flow byte and package counters on NETSYS_V3. + +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + + drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++------- + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++ + 3 files changed, 17 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -5030,6 +5030,7 @@ static const struct mtk_soc_data mt7988_ + .version = 3, + .offload_version = 2, + .hash_offset = 4, ++ .has_accounting = true, + .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct + + static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) + { +- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; + u32 val, cnt_r0, cnt_r1, cnt_r2; + int ret; + +@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk + cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); + cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); + +- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); +- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); +- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); +- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); +- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; +- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ if (mtk_is_netsys_v3_or_greater(ppe->eth)) { ++ /* 64 bit for each counter */ ++ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); ++ *bytes = ((u64)cnt_r1 << 32) | cnt_r0; ++ *packets = ((u64)cnt_r3 << 32) | cnt_r2; ++ } else { ++ /* 48 bit byte counter, 40 bit packet counter */ ++ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); ++ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); ++ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); ++ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); ++ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ } + + return 0; + } +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -163,6 +163,8 @@ enum { + #define MTK_PPE_MIB_SER_R2 0x348 + #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) + ++#define MTK_PPE_MIB_SER_R3 0x34c ++ + #define MTK_PPE_MIB_CACHE_CTL 0x350 + #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) + #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch new file mode 100644 index 000000000..6f1639a57 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch @@ -0,0 +1,52 @@ +From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 21 Aug 2023 17:12:44 +0100 +Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw + reset + +When a hardware reset is triggered on devices not initializing WED the +calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a +pointer on uninitialized stack memory. +Break out of both functions in case a hw_list entry is 0. + +Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Acked-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void) + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; +- struct mtk_wed_device *dev = hw->wed_dev; ++ struct mtk_wed_device *dev; + int err; + ++ if (!hw) ++ break; ++ ++ dev = hw->wed_dev; + if (!dev || !dev->wlan.reset) + continue; + +@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void) + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { + struct mtk_wed_hw *hw = hw_list[i]; +- struct mtk_wed_device *dev = hw->wed_dev; ++ struct mtk_wed_device *dev; ++ ++ if (!hw) ++ break; + ++ dev = hw->wed_dev; + if (!dev || !dev->wlan.reset_complete) + continue; + diff --git a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch new file mode 100644 index 000000000..2190761fd --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch @@ -0,0 +1,44 @@ +From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:31:24 +0100 +Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions + for MT7988 + +More register macros need to be adjusted for the 3rd GMAC on MT7988. +Account for added bit in SYSCFG0_SGMII_MASK. + +Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -133,10 +133,12 @@ + #define MTK_GDMA_XGDM_SEL BIT(31) + + /* Unicast Filter MAC Address Register - Low */ +-#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) ++#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x548 : 0x508 + (_x * 0x1000); }) + + /* Unicast Filter MAC Address Register - High */ +-#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) ++#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ ++ 0x54C : 0x50C + (_x * 0x1000); }) + + /* FE global misc reg*/ + #define MTK_FE_GLO_MISC 0x124 +@@ -503,7 +505,7 @@ + #define ETHSYS_SYSCFG0 0x14 + #define SYSCFG0_GE_MASK 0x3 + #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2))) +-#define SYSCFG0_SGMII_MASK GENMASK(9, 8) ++#define SYSCFG0_SGMII_MASK GENMASK(9, 7) + #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) diff --git a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch new file mode 100644 index 000000000..05a18364d --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch @@ -0,0 +1,188 @@ +From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:32:03 +0100 +Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988 + +Add bits needed to reset the frame engine on MT7988. + +Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++-- + 2 files changed, 68 insertions(+), 24 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3594,19 +3594,34 @@ static void mtk_hw_reset(struct mtk_eth + { + u32 val; + +- if (mtk_is_netsys_v2_or_greater(eth)) { ++ if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ val = RSTCTRL_PPE0_V3; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1_V3; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val |= RSTCTRL_PPE2; ++ ++ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; ++ } else if (mtk_is_netsys_v2_or_greater(eth)) { + val = RSTCTRL_PPE0_V2; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1; + } else { + val = RSTCTRL_PPE0; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= RSTCTRL_PPE1; +- + ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + +- if (mtk_is_netsys_v2_or_greater(eth)) ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, ++ 0x6f8ff); ++ else if (mtk_is_netsys_v2_or_greater(eth)) + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, + 0x3ffffff); + } +@@ -3632,13 +3647,21 @@ static void mtk_hw_warm_reset(struct mtk + return; + } + +- if (mtk_is_netsys_v2_or_greater(eth)) ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1_V3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ rst_mask |= RSTCTRL_PPE2; ++ ++ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; ++ } else if (mtk_is_netsys_v2_or_greater(eth)) { + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; +- else ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1; ++ } else { + rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- rst_mask |= RSTCTRL_PPE1; ++ } + + regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); + +@@ -3990,11 +4013,17 @@ static void mtk_prepare_for_reset(struct + u32 val; + int i; + +- /* disabe FE P3 and P4 */ +- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= MTK_FE_LINK_DOWN_P4; +- mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ /* set FE PPE ports link down */ ++ for (i = MTK_GMAC1_ID; ++ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); ++ i += 2) { ++ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); ++ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); ++ } + + /* adjust PPE configurations to prepare for reset */ + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) +@@ -4055,11 +4084,18 @@ static void mtk_pending_work(struct work + } + } + +- /* enabe FE P3 and P4 */ +- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val &= ~MTK_FE_LINK_DOWN_P4; +- mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ /* set FE PPE ports link up */ ++ for (i = MTK_GMAC1_ID; ++ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); ++ i += 2) { ++ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) ++ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); ++ ++ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); ++ } + + clear_bit(MTK_RESETTING, ð->state); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -76,9 +76,8 @@ + #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 + + /* Frame Engine Global Configuration */ +-#define MTK_FE_GLO_CFG 0x00 +-#define MTK_FE_LINK_DOWN_P3 BIT(11) +-#define MTK_FE_LINK_DOWN_P4 BIT(12) ++#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00) ++#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16) + + /* Frame Engine Global Reset Register */ + #define MTK_RST_GL 0x04 +@@ -522,9 +521,15 @@ + /* ethernet reset control register */ + #define ETHSYS_RSTCTRL 0x34 + #define RSTCTRL_FE BIT(6) ++#define RSTCTRL_WDMA0 BIT(24) ++#define RSTCTRL_WDMA1 BIT(25) ++#define RSTCTRL_WDMA2 BIT(26) + #define RSTCTRL_PPE0 BIT(31) + #define RSTCTRL_PPE0_V2 BIT(30) + #define RSTCTRL_PPE1 BIT(31) ++#define RSTCTRL_PPE0_V3 BIT(29) ++#define RSTCTRL_PPE1_V3 BIT(30) ++#define RSTCTRL_PPE2 BIT(31) + #define RSTCTRL_ETH BIT(23) + + /* ethernet reset check idle register */ +@@ -931,6 +936,7 @@ enum mkt_eth_capabilities { + MTK_QDMA_BIT, + MTK_SOC_MT7628_BIT, + MTK_RSTCTRL_PPE1_BIT, ++ MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, + + /* MUX BITS*/ +@@ -965,6 +971,7 @@ enum mkt_eth_capabilities { + #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) + #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) + #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) ++#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ +@@ -1047,7 +1054,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1) + +-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) ++#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ ++ MTK_RSTCTRL_PPE2) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; diff --git a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch new file mode 100644 index 000000000..74ac8dc89 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch @@ -0,0 +1,254 @@ +From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:32:54 +0100 +Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC + SRAM + +MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet +DMA rings. Support using the SRAM without breaking existing device tree +bindings, ie. only new SoC starting from MT7988 will have the SRAM +declared as additional resource in device tree. For MT7981 and MT7986 +an offset on top of the main I/O base is used. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++----- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++- + 2 files changed, 78 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1118,10 +1118,13 @@ static int mtk_init_fq_dma(struct mtk_et + dma_addr_t dma_addr; + int i; + +- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, +- cnt * soc->txrx.txd_size, +- ð->phy_scratch_ring, +- GFP_KERNEL); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) ++ eth->scratch_ring = eth->sram_base; ++ else ++ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, ++ cnt * soc->txrx.txd_size, ++ ð->phy_scratch_ring, ++ GFP_KERNEL); + if (unlikely(!eth->scratch_ring)) + return -ENOMEM; + +@@ -2429,8 +2432,14 @@ static int mtk_tx_alloc(struct mtk_eth * + if (!ring->buf) + goto no_tx_mem; + +- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, +- &ring->phys, GFP_KERNEL); ++ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) { ++ ring->dma = eth->sram_base + ring_size * sz; ++ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz; ++ } else { ++ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, ++ &ring->phys, GFP_KERNEL); ++ } ++ + if (!ring->dma) + goto no_tx_mem; + +@@ -2529,8 +2538,7 @@ static void mtk_tx_clean(struct mtk_eth + kfree(ring->buf); + ring->buf = NULL; + } +- +- if (ring->dma) { ++ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { + dma_free_coherent(eth->dma_dev, + ring->dma_size * soc->txrx.txd_size, + ring->dma, ring->phys); +@@ -2549,9 +2557,14 @@ static int mtk_rx_alloc(struct mtk_eth * + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + struct mtk_rx_ring *ring; +- int rx_data_len, rx_dma_size; ++ int rx_data_len, rx_dma_size, tx_ring_size; + int i; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ tx_ring_size = MTK_QDMA_RING_SIZE; ++ else ++ tx_ring_size = MTK_DMA_SIZE; ++ + if (rx_flag == MTK_RX_FLAGS_QDMA) { + if (ring_no) + return -EINVAL; +@@ -2586,9 +2599,20 @@ static int mtk_rx_alloc(struct mtk_eth * + ring->page_pool = pp; + } + +- ring->dma = dma_alloc_coherent(eth->dma_dev, +- rx_dma_size * eth->soc->txrx.rxd_size, +- &ring->phys, GFP_KERNEL); ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || ++ rx_flag != MTK_RX_FLAGS_NORMAL) { ++ ring->dma = dma_alloc_coherent(eth->dma_dev, ++ rx_dma_size * eth->soc->txrx.rxd_size, ++ &ring->phys, GFP_KERNEL); ++ } else { ++ struct mtk_tx_ring *tx_ring = ð->tx_ring; ++ ++ ring->dma = tx_ring->dma + tx_ring_size * ++ eth->soc->txrx.txd_size * (ring_no + 1); ++ ring->phys = tx_ring->phys + tx_ring_size * ++ eth->soc->txrx.txd_size * (ring_no + 1); ++ } ++ + if (!ring->dma) + return -ENOMEM; + +@@ -2673,7 +2697,7 @@ static int mtk_rx_alloc(struct mtk_eth * + return 0; + } + +-static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) ++static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) + { + int i; + +@@ -2696,7 +2720,7 @@ static void mtk_rx_clean(struct mtk_eth + ring->data = NULL; + } + +- if (ring->dma) { ++ if (!in_sram && ring->dma) { + dma_free_coherent(eth->dma_dev, + ring->dma_size * eth->soc->txrx.rxd_size, + ring->dma, ring->phys); +@@ -3059,7 +3083,7 @@ static void mtk_dma_free(struct mtk_eth + for (i = 0; i < MTK_MAX_DEVS; i++) + if (eth->netdev[i]) + netdev_reset_queue(eth->netdev[i]); +- if (eth->scratch_ring) { ++ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { + dma_free_coherent(eth->dma_dev, + MTK_QDMA_RING_SIZE * soc->txrx.txd_size, + eth->scratch_ring, eth->phy_scratch_ring); +@@ -3067,13 +3091,13 @@ static void mtk_dma_free(struct mtk_eth + eth->phy_scratch_ring = 0; + } + mtk_tx_clean(eth); +- mtk_rx_clean(eth, ð->rx_ring[0]); +- mtk_rx_clean(eth, ð->rx_ring_qdma); ++ mtk_rx_clean(eth, ð->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM)); ++ mtk_rx_clean(eth, ð->rx_ring_qdma, false); + + if (eth->hwlro) { + mtk_hwlro_rx_uninit(eth); + for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) +- mtk_rx_clean(eth, ð->rx_ring[i]); ++ mtk_rx_clean(eth, ð->rx_ring[i], false); + } + + kfree(eth->scratch_head); +@@ -4641,7 +4665,7 @@ static int mtk_sgmii_init(struct mtk_eth + + static int mtk_probe(struct platform_device *pdev) + { +- struct resource *res = NULL; ++ struct resource *res = NULL, *res_sram; + struct device_node *mac_np; + struct mtk_eth *eth; + int err, i; +@@ -4661,6 +4685,20 @@ static int mtk_probe(struct platform_dev + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) + eth->ip_align = NET_IP_ALIGN; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { ++ /* SRAM is actual memory and supports transparent access just like DRAM. ++ * Hence we don't require __iomem being set and don't need to use accessor ++ * functions to read from or write to SRAM. ++ */ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1); ++ if (IS_ERR(eth->sram_base)) ++ return PTR_ERR(eth->sram_base); ++ } else { ++ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET; ++ } ++ } ++ + spin_lock_init(ð->page_lock); + spin_lock_init(ð->tx_irq_lock); + spin_lock_init(ð->rx_irq_lock); +@@ -4724,6 +4762,18 @@ static int mtk_probe(struct platform_dev + err = -EINVAL; + goto err_destroy_sgmii; + } ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res_sram) { ++ err = -EINVAL; ++ goto err_destroy_sgmii; ++ } ++ eth->phy_scratch_ring = res_sram->start; ++ } else { ++ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET; ++ } ++ } + } + + if (eth->soc->offload_version) { +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -139,6 +139,9 @@ + #define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ + 0x54C : 0x50C + (_x * 0x1000); }) + ++/* Internal SRAM offset */ ++#define MTK_ETH_SRAM_OFFSET 0x40000 ++ + /* FE global misc reg*/ + #define MTK_FE_GLO_MISC 0x124 + +@@ -938,6 +941,7 @@ enum mkt_eth_capabilities { + MTK_RSTCTRL_PPE1_BIT, + MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, ++ MTK_SRAM_BIT, + + /* MUX BITS*/ + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, +@@ -973,6 +977,7 @@ enum mkt_eth_capabilities { + #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) + #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) ++#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ + BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) +@@ -1048,14 +1053,14 @@ enum mkt_eth_capabilities { + #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ +- MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM) + + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1) ++ MTK_RSTCTRL_PPE1 | MTK_SRAM) + + #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ +- MTK_RSTCTRL_PPE2) ++ MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1215,6 +1220,7 @@ struct mtk_eth { + struct device *dev; + struct device *dma_dev; + void __iomem *base; ++ void *sram_base; + spinlock_t page_lock; + spinlock_t tx_irq_lock; + spinlock_t rx_irq_lock; diff --git a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch new file mode 100644 index 000000000..1584dfd07 --- /dev/null +++ b/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch @@ -0,0 +1,166 @@ +From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 17:33:12 +0100 +Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA + addressing on MT7988 + +Systems having 4 GiB of RAM and more require DMA addressing beyond the +current 32-bit limit. Starting from MT7988 the hardware now supports +36-bit DMA addressing, let's use that new capability in the driver to +avoid running into swiotlb on systems with 4 GiB of RAM or more. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++-- + 2 files changed, 48 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1311,6 +1311,10 @@ static void mtk_tx_set_dma_desc_v2(struc + data = TX_DMA_PLEN0(info->size); + if (info->last) + data |= TX_DMA_LS0; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ data |= TX_DMA_PREP_ADDR64(info->addr); ++ + WRITE_ONCE(desc->txd3, data); + + /* set forward port */ +@@ -1980,6 +1984,7 @@ static int mtk_poll_rx(struct napi_struc + bool xdp_flush = false; + int idx; + struct sk_buff *skb; ++ u64 addr64 = 0; + u8 *data, *new_data; + struct mtk_rx_dma_v2 *rxd, trxd; + int done = 0, bytes = 0; +@@ -2095,7 +2100,10 @@ static int mtk_poll_rx(struct napi_struc + goto release_desc; + } + +- dma_unmap_single(eth->dma_dev, trxd.rxd1, ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2); ++ ++ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64), + ring->buf_size, DMA_FROM_DEVICE); + + skb = build_skb(data, ring->frag_size); +@@ -2161,6 +2169,9 @@ release_desc: + else + rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ + ring->calc_idx = idx; + done++; + } +@@ -2653,6 +2664,9 @@ static int mtk_rx_alloc(struct mtk_eth * + else + rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); ++ + rxd->rxd3 = 0; + rxd->rxd4 = 0; + if (mtk_is_netsys_v2_or_greater(eth)) { +@@ -2699,6 +2713,7 @@ static int mtk_rx_alloc(struct mtk_eth * + + static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) + { ++ u64 addr64 = 0; + int i; + + if (ring->data && ring->dma) { +@@ -2712,7 +2727,10 @@ static void mtk_rx_clean(struct mtk_eth + if (!rxd->rxd1) + continue; + +- dma_unmap_single(eth->dma_dev, rxd->rxd1, ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) ++ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2); ++ ++ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64), + ring->buf_size, DMA_FROM_DEVICE); + mtk_rx_put_buff(ring, ring->data[i], false); + } +@@ -4699,6 +4717,14 @@ static int mtk_probe(struct platform_dev + } + } + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); ++ if (err) { ++ dev_err(&pdev->dev, "Wrong DMA config\n"); ++ return -EINVAL; ++ } ++ } ++ + spin_lock_init(ð->page_lock); + spin_lock_init(ð->tx_irq_lock); + spin_lock_init(ð->rx_irq_lock); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -331,6 +331,14 @@ + #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) + #define TX_DMA_SWC BIT(14) + #define TX_DMA_PQID GENMASK(3, 0) ++#define TX_DMA_ADDR64_MASK GENMASK(3, 0) ++#if IS_ENABLED(CONFIG_64BIT) ++# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32) ++# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32)) ++#else ++# define TX_DMA_GET_ADDR64(x) (0) ++# define TX_DMA_PREP_ADDR64(x) (0) ++#endif + + /* PDMA on MT7628 */ + #define TX_DMA_DONE BIT(31) +@@ -343,6 +351,14 @@ + #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) + #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) + #define RX_DMA_VTAG BIT(15) ++#define RX_DMA_ADDR64_MASK GENMASK(3, 0) ++#if IS_ENABLED(CONFIG_64BIT) ++# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32) ++# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32)) ++#else ++# define RX_DMA_GET_ADDR64(x) (0) ++# define RX_DMA_PREP_ADDR64(x) (0) ++#endif + + /* QDMA descriptor rxd3 */ + #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK) +@@ -942,6 +958,7 @@ enum mkt_eth_capabilities { + MTK_RSTCTRL_PPE2_BIT, + MTK_U3_COPHY_V2_BIT, + MTK_SRAM_BIT, ++ MTK_36BIT_DMA_BIT, + + /* MUX BITS*/ + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, +@@ -978,6 +995,7 @@ enum mkt_eth_capabilities { + #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) + #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) + #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) ++#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ + BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) +@@ -1059,8 +1077,8 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1 | MTK_SRAM) + +-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ +- MTK_RSTCTRL_PPE2 | MTK_SRAM) ++#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ ++ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; diff --git a/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch index 1819b78ae..b158a8946 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch @@ -21,9 +21,9 @@ Signed-off-by: David S. Miller drivers/net/dsa/Kconfig | 12 +++ drivers/net/dsa/Makefile | 1 + drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++ - drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++- + drivers/net/dsa/mt7530.c | 135 +++++++++++++++++++++++++++++++++- drivers/net/dsa/mt7530.h | 12 +-- - 6 files changed, 255 insertions(+), 10 deletions(-) + 6 files changed, 253 insertions(+), 10 deletions(-) create mode 100644 drivers/net/dsa/mt7530-mmio.c --- a/MAINTAINERS diff --git a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch new file mode 100644 index 000000000..eac8966a4 --- /dev/null +++ b/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch @@ -0,0 +1,172 @@ +From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 13 Jul 2023 09:42:07 +0100 +Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods + +Add phylink PCS enable/disable callbacks that will allow us to place +IEEE 802.3 register compliant PCS in power-down mode while not being +used. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: David S. Miller +--- + drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++-------- + include/linux/phylink.h | 16 +++++++++++++ + 2 files changed, 55 insertions(+), 9 deletions(-) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -34,6 +34,10 @@ enum { + PHYLINK_DISABLE_STOPPED, + PHYLINK_DISABLE_LINK, + PHYLINK_DISABLE_MAC_WOL, ++ ++ PCS_STATE_DOWN = 0, ++ PCS_STATE_STARTING, ++ PCS_STATE_STARTED, + }; + + /** +@@ -71,6 +75,7 @@ struct phylink { + struct mutex state_mutex; + struct phylink_link_state phy_state; + struct work_struct resolve; ++ unsigned int pcs_state; + + bool mac_link_dropped; + bool using_mac_select_pcs; +@@ -987,6 +992,22 @@ static void phylink_mac_pcs_an_restart(s + } + } + ++static void phylink_pcs_disable(struct phylink_pcs *pcs) ++{ ++ if (pcs && pcs->ops->pcs_disable) ++ pcs->ops->pcs_disable(pcs); ++} ++ ++static int phylink_pcs_enable(struct phylink_pcs *pcs) ++{ ++ int err = 0; ++ ++ if (pcs && pcs->ops->pcs_enable) ++ err = pcs->ops->pcs_enable(pcs); ++ ++ return err; ++} ++ + static void phylink_major_config(struct phylink *pl, bool restart, + const struct phylink_link_state *state) + { +@@ -1023,11 +1044,16 @@ static void phylink_major_config(struct + /* If we have a new PCS, switch to the new PCS after preparing the MAC + * for the change. + */ +- if (pcs_changed) ++ if (pcs_changed) { ++ phylink_pcs_disable(pl->pcs); + pl->pcs = pcs; ++ } + + phylink_mac_config(pl, state); + ++ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) ++ phylink_pcs_enable(pl->pcs); ++ + if (pl->pcs) { + err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode, + state->interface, +@@ -1499,6 +1525,7 @@ struct phylink *phylink_create(struct ph + pl->link_config.speed = SPEED_UNKNOWN; + pl->link_config.duplex = DUPLEX_UNKNOWN; + pl->link_config.an_enabled = true; ++ pl->pcs_state = PCS_STATE_DOWN; + pl->mac_ops = mac_ops; + __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); + timer_setup(&pl->link_poll, phylink_fixed_poll, 0); +@@ -1900,6 +1927,8 @@ void phylink_start(struct phylink *pl) + if (pl->netdev) + netif_carrier_off(pl->netdev); + ++ pl->pcs_state = PCS_STATE_STARTING; ++ + /* Apply the link configuration to the MAC when starting. This allows + * a fixed-link to start with the correct parameters, and also + * ensures that we set the appropriate advertisement for Serdes links. +@@ -1910,6 +1939,8 @@ void phylink_start(struct phylink *pl) + */ + phylink_mac_initial_config(pl, true); + ++ pl->pcs_state = PCS_STATE_STARTED; ++ + phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED); + + if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { +@@ -1928,15 +1959,9 @@ void phylink_start(struct phylink *pl) + poll = true; + } + +- switch (pl->cfg_link_an_mode) { +- case MLO_AN_FIXED: ++ if (pl->cfg_link_an_mode == MLO_AN_FIXED) + poll |= pl->config->poll_fixed_state; +- break; +- case MLO_AN_INBAND: +- if (pl->pcs) +- poll |= pl->pcs->poll; +- break; +- } ++ + if (poll) + mod_timer(&pl->link_poll, jiffies + HZ); + if (pl->phydev) +@@ -1973,6 +1998,10 @@ void phylink_stop(struct phylink *pl) + } + + phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); ++ ++ pl->pcs_state = PCS_STATE_DOWN; ++ ++ phylink_pcs_disable(pl->pcs); + } + EXPORT_SYMBOL_GPL(phylink_stop); + +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -446,6 +446,8 @@ struct phylink_pcs { + /** + * struct phylink_pcs_ops - MAC PCS operations structure. + * @pcs_validate: validate the link configuration. ++ * @pcs_enable: enable the PCS. ++ * @pcs_disable: disable the PCS. + * @pcs_get_state: read the current MAC PCS link state from the hardware. + * @pcs_config: configure the MAC PCS for the selected mode and state. + * @pcs_an_restart: restart 802.3z BaseX autonegotiation. +@@ -455,6 +457,8 @@ struct phylink_pcs { + struct phylink_pcs_ops { + int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, + const struct phylink_link_state *state); ++ int (*pcs_enable)(struct phylink_pcs *pcs); ++ void (*pcs_disable)(struct phylink_pcs *pcs); + void (*pcs_get_state)(struct phylink_pcs *pcs, + struct phylink_link_state *state); + int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, +@@ -485,6 +489,18 @@ int pcs_validate(struct phylink_pcs *pcs + const struct phylink_link_state *state); + + /** ++ * pcs_enable() - enable the PCS. ++ * @pcs: a pointer to a &struct phylink_pcs. ++ */ ++int pcs_enable(struct phylink_pcs *pcs); ++ ++/** ++ * pcs_disable() - disable the PCS. ++ * @pcs: a pointer to a &struct phylink_pcs. ++ */ ++void pcs_disable(struct phylink_pcs *pcs); ++ ++/** + * pcs_get_state() - Read the current inband link state from the hardware + * @pcs: a pointer to a &struct phylink_pcs. + * @state: a pointer to a &struct phylink_link_state. diff --git a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch new file mode 100644 index 000000000..eb9b4b7c0 --- /dev/null +++ b/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch @@ -0,0 +1,44 @@ +From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 18 Aug 2023 04:07:46 +0100 +Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op + +When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface +modes provided by mtk-pcs-lynxi we need to make sure to always perform +a full configuration of the PHYA. + +Implement pcs_disable op which resets the stored interface mode to +PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI +PCS driver had previously been deselected in favor of another PCS +driver such as the to-be-added driver for the USXGMII PCS found in +MT7988. + +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/pcs/pcs-mtk-lynxi.c ++++ b/drivers/net/pcs/pcs-mtk-lynxi.c +@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct + } + } + ++static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ ++ mpcs->interface = PHY_INTERFACE_MODE_NA; ++} ++ + static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { + .pcs_get_state = mtk_pcs_lynxi_get_state, + .pcs_config = mtk_pcs_lynxi_config, + .pcs_an_restart = mtk_pcs_lynxi_restart_an, + .pcs_link_up = mtk_pcs_lynxi_link_up, ++ .pcs_disable = mtk_pcs_lynxi_disable, + }; + + struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, diff --git a/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch new file mode 100644 index 000000000..592111fb9 --- /dev/null +++ b/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch @@ -0,0 +1,39 @@ +From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Tue, 3 Jan 2023 15:12:47 +0200 +Subject: [PATCH] leds: Move led_init_default_state_get() to the global header + +There are users inside and outside LED framework that have implemented +a local copy of led_init_default_state_get(). In order to deduplicate +that, as the first step move the declaration from LED header to the +global one. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com +--- + drivers/leds/leds.h | 1 - + include/linux/leds.h | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/leds/leds.h ++++ b/drivers/leds/leds.h +@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi + ssize_t led_trigger_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t pos, size_t count); +-enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); + + extern struct rw_semaphore leds_list_lock; + extern struct list_head leds_list; +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -63,6 +63,8 @@ struct led_init_data { + bool devname_mandatory; + }; + ++enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); ++ + struct led_hw_trigger_type { + int dummy; + }; diff --git a/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch new file mode 100644 index 000000000..07becafbe --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch @@ -0,0 +1,67 @@ +From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:23 +0200 +Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header + +Move qca8k_port_to_phy() to qca8k header as it's useful for future +reference in Switch LEDs module since the same logic is applied to get +the right index of the switch port. +Make it inline as it's simple function that just decrease the port. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Reviewed-by: Michal Kubiak +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 15 --------------- + drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++ + 2 files changed, 14 insertions(+), 15 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -730,21 +730,6 @@ err_clear_skb: + return ret; + } + +-static u32 +-qca8k_port_to_phy(int port) +-{ +- /* From Andrew Lunn: +- * Port 0 has no internal phy. +- * Port 1 has an internal PHY at MDIO address 0. +- * Port 2 has an internal PHY at MDIO address 1. +- * ... +- * Port 5 has an internal PHY at MDIO address 4. +- * Port 6 has no internal PHY. +- */ +- +- return port - 1; +-} +- + static int + qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) + { +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -422,6 +422,20 @@ struct qca8k_fdb { + u8 mac[6]; + }; + ++static inline u32 qca8k_port_to_phy(int port) ++{ ++ /* From Andrew Lunn: ++ * Port 0 has no internal phy. ++ * Port 1 has an internal PHY at MDIO address 0. ++ * Port 2 has an internal PHY at MDIO address 1. ++ * ... ++ * Port 5 has an internal PHY at MDIO address 4. ++ * Port 6 has no internal PHY. ++ */ ++ ++ return port - 1; ++} ++ + /* Common setup function */ + extern const struct qca8k_mib_desc ar8327_mib[]; + extern const struct regmap_access_table qca8k_readable_table; diff --git a/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch new file mode 100644 index 000000000..414ba97e9 --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch @@ -0,0 +1,435 @@ +From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:24 +0200 +Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support + +Add LEDs basic support for qca8k Switch Family by adding basic +brightness_set() support. + +Since these LEDs refelect port status, the default label is set to +":port". DT binding should describe the color and function of the +LEDs using standard LEDs api. +Each LED always have the device name as prefix. The device name is +composed from the mii bus id and the PHY addr resulting in example +names like: +- qca8k-0.0:00:amber:lan +- qca8k-0.0:00:white:lan +- qca8k-0.0:01:amber:lan +- qca8k-0.0:01:white:lan + +These LEDs supports only blocking variant of the brightness_set() +function since they can sleep during access of the switch leds to set +the brightness. + +While at it add to the qca8k header file each mode defined by the Switch +Documentation for future use. + +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/Kconfig | 8 ++ + drivers/net/dsa/qca/Makefile | 3 + + drivers/net/dsa/qca/qca8k-8xxx.c | 5 + + drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++ + drivers/net/dsa/qca/qca8k.h | 60 ++++++++ + drivers/net/dsa/qca/qca8k_leds.h | 16 +++ + 6 files changed, 331 insertions(+) + create mode 100644 drivers/net/dsa/qca/qca8k-leds.c + create mode 100644 drivers/net/dsa/qca/qca8k_leds.h + +--- a/drivers/net/dsa/qca/Kconfig ++++ b/drivers/net/dsa/qca/Kconfig +@@ -15,3 +15,11 @@ config NET_DSA_QCA8K + help + This enables support for the Qualcomm Atheros QCA8K Ethernet + switch chips. ++ ++config NET_DSA_QCA8K_LEDS_SUPPORT ++ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support" ++ depends on NET_DSA_QCA8K ++ depends on LEDS_CLASS ++ help ++ This enabled support for LEDs present on the Qualcomm Atheros ++ QCA8K Ethernet switch chips. +--- a/drivers/net/dsa/qca/Makefile ++++ b/drivers/net/dsa/qca/Makefile +@@ -2,3 +2,6 @@ + obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o + obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o + qca8k-y += qca8k-common.o qca8k-8xxx.o ++ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT ++qca8k-y += qca8k-leds.o ++endif +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -22,6 +22,7 @@ + #include + + #include "qca8k.h" ++#include "qca8k_leds.h" + + static void + qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) +@@ -1751,6 +1752,10 @@ qca8k_setup(struct dsa_switch *ds) + if (ret) + return ret; + ++ ret = qca8k_setup_led_ctrl(priv); ++ if (ret) ++ return ret; ++ + qca8k_setup_pcs(priv, &priv->pcs_port_0, 0); + qca8k_setup_pcs(priv, &priv->pcs_port_6, 6); + +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -0,0 +1,239 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++#include ++ ++#include "qca8k.h" ++#include "qca8k_leds.h" ++ ++static int ++qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) ++{ ++ switch (port_num) { ++ case 0: ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; ++ break; ++ case 1: ++ case 2: ++ case 3: ++ /* Port 123 are controlled on a different reg */ ++ reg_info->reg = QCA8K_LED_CTRL3_REG; ++ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num); ++ break; ++ case 4: ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++qca8k_led_brightness_set(struct qca8k_led *led, ++ enum led_brightness brightness) ++{ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 mask, val; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ val = QCA8K_LED_ALWAYS_OFF; ++ if (brightness) ++ val = QCA8K_LED_ALWAYS_ON; ++ ++ /* HW regs to control brightness is special and port 1-2-3 ++ * are placed in a different reg. ++ * ++ * To control port 0 brightness: ++ * - the 2 bit (15, 14) of: ++ * - QCA8K_LED_CTRL0_REG for led1 ++ * - QCA8K_LED_CTRL1_REG for led2 ++ * - QCA8K_LED_CTRL2_REG for led3 ++ * ++ * To control port 4: ++ * - the 2 bit (31, 30) of: ++ * - QCA8K_LED_CTRL0_REG for led1 ++ * - QCA8K_LED_CTRL1_REG for led2 ++ * - QCA8K_LED_CTRL2_REG for led3 ++ * ++ * To control port 1: ++ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To control port 2: ++ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To control port 3: ++ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1 ++ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2 ++ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3 ++ * ++ * To abstract this and have less code, we use the port and led numm ++ * to calculate the shift and the correct reg due to this problem of ++ * not having a 1:1 map of LED with the regs. ++ */ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, ++ mask << reg_info.shift, ++ val << reg_info.shift); ++} ++ ++static int ++qca8k_cled_brightness_set_blocking(struct led_classdev *ldev, ++ enum led_brightness brightness) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ return qca8k_led_brightness_set(led, brightness); ++} ++ ++static enum led_brightness ++qca8k_led_brightness_get(struct qca8k_led *led) ++{ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ int ret; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ ret = regmap_read(priv->regmap, reg_info.reg, &val); ++ if (ret) ++ return 0; ++ ++ val >>= reg_info.shift; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ val &= QCA8K_LED_PATTERN_EN_MASK; ++ val >>= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ /* Assume brightness ON only when the LED is set to always ON */ ++ return val == QCA8K_LED_ALWAYS_ON; ++} ++ ++static int ++qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) ++{ ++ struct fwnode_handle *led = NULL, *leds = NULL; ++ struct led_init_data init_data = { }; ++ struct dsa_switch *ds = priv->ds; ++ enum led_default_state state; ++ struct qca8k_led *port_led; ++ int led_num, led_index; ++ int ret; ++ ++ leds = fwnode_get_named_child_node(port, "leds"); ++ if (!leds) { ++ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n", ++ port_num); ++ return 0; ++ } ++ ++ fwnode_for_each_child_node(leds, led) { ++ /* Reg represent the led number of the port. ++ * Each port can have at most 3 leds attached ++ * Commonly: ++ * 1. is gigabit led ++ * 2. is mbit led ++ * 3. additional status led ++ */ ++ if (fwnode_property_read_u32(led, "reg", &led_num)) ++ continue; ++ ++ if (led_num >= QCA8K_LED_PORT_COUNT) { ++ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", ++ led_num, port_num); ++ continue; ++ } ++ ++ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num); ++ ++ port_led = &priv->ports_led[led_index]; ++ port_led->port_num = port_num; ++ port_led->led_num = led_num; ++ port_led->priv = priv; ++ ++ state = led_init_default_state_get(led); ++ switch (state) { ++ case LEDS_DEFSTATE_ON: ++ port_led->cdev.brightness = 1; ++ qca8k_led_brightness_set(port_led, 1); ++ break; ++ case LEDS_DEFSTATE_KEEP: ++ port_led->cdev.brightness = ++ qca8k_led_brightness_get(port_led); ++ break; ++ default: ++ port_led->cdev.brightness = 0; ++ qca8k_led_brightness_set(port_led, 0); ++ } ++ ++ port_led->cdev.max_brightness = 1; ++ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; ++ init_data.default_label = ":port"; ++ init_data.fwnode = led; ++ init_data.devname_mandatory = true; ++ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id, ++ port_num); ++ if (!init_data.devicename) ++ return -ENOMEM; ++ ++ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); ++ if (ret) ++ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num); ++ ++ kfree(init_data.devicename); ++ } ++ ++ return 0; ++} ++ ++int ++qca8k_setup_led_ctrl(struct qca8k_priv *priv) ++{ ++ struct fwnode_handle *ports, *port; ++ int port_num; ++ int ret; ++ ++ ports = device_get_named_child_node(priv->dev, "ports"); ++ if (!ports) { ++ dev_info(priv->dev, "No ports node specified in device tree!"); ++ return 0; ++ } ++ ++ fwnode_for_each_child_node(ports, port) { ++ if (fwnode_property_read_u32(port, "reg", &port_num)) ++ continue; ++ ++ /* Skip checking for CPU port 0 and CPU port 6 as not supported */ ++ if (port_num == 0 || port_num == 6) ++ continue; ++ ++ /* Each port can have at most 3 different leds attached. ++ * Switch port starts from 0 to 6, but port 0 and 6 are CPU ++ * port. The port index needs to be decreased by one to identify ++ * the correct port for LED setup. ++ */ ++ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num)); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + + #define QCA8K_ETHERNET_MDIO_PRIORITY 7 +@@ -85,6 +86,51 @@ + #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) + #define QCA8K_MDIO_MASTER_MAX_PORTS 5 + #define QCA8K_MDIO_MASTER_MAX_REG 32 ++ ++/* LED control register */ ++#define QCA8K_LED_PORT_COUNT 3 ++#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT) ++#define QCA8K_LED_RULE_COUNT 6 ++#define QCA8K_LED_RULE_MAX 11 ++#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led)) ++ ++#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led))) ++#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0) ++ ++#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0 ++#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16 ++ ++#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4) ++#define QCA8K_LED_CTRL0_REG 0x50 ++#define QCA8K_LED_CTRL1_REG 0x54 ++#define QCA8K_LED_CTRL2_REG 0x58 ++#define QCA8K_LED_CTRL3_REG 0x5C ++#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16) ++#define QCA8K_LED_CTRL_MASK GENMASK(15, 0) ++#define QCA8K_LED_RULE_MASK GENMASK(13, 0) ++#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0) ++#define QCA8K_LED_BLINK_FREQ_SHITF 0 ++#define QCA8K_LED_BLINK_2HZ 0 ++#define QCA8K_LED_BLINK_4HZ 1 ++#define QCA8K_LED_BLINK_8HZ 2 ++#define QCA8K_LED_BLINK_AUTO 3 ++#define QCA8K_LED_LINKUP_OVER_MASK BIT(2) ++#define QCA8K_LED_TX_BLINK_MASK BIT(4) ++#define QCA8K_LED_RX_BLINK_MASK BIT(5) ++#define QCA8K_LED_COL_BLINK_MASK BIT(7) ++#define QCA8K_LED_LINK_10M_EN_MASK BIT(8) ++#define QCA8K_LED_LINK_100M_EN_MASK BIT(9) ++#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10) ++#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11) ++#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12) ++#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13) ++#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14) ++#define QCA8K_LED_PATTERN_EN_SHIFT 14 ++#define QCA8K_LED_ALWAYS_OFF 0 ++#define QCA8K_LED_ALWAYS_BLINK_4HZ 1 ++#define QCA8K_LED_ALWAYS_ON 2 ++#define QCA8K_LED_RULE_CONTROLLED 3 ++ + #define QCA8K_GOL_MAC_ADDR0 0x60 + #define QCA8K_GOL_MAC_ADDR1 0x64 + #define QCA8K_MAX_FRAME_SIZE 0x78 +@@ -383,6 +429,19 @@ struct qca8k_pcs { + int port; + }; + ++struct qca8k_led_pattern_en { ++ u32 reg; ++ u8 shift; ++}; ++ ++struct qca8k_led { ++ u8 port_num; ++ u8 led_num; ++ u16 old_rule; ++ struct qca8k_priv *priv; ++ struct led_classdev cdev; ++}; ++ + struct qca8k_priv { + u8 switch_id; + u8 switch_revision; +@@ -407,6 +466,7 @@ struct qca8k_priv { + struct qca8k_pcs pcs_port_0; + struct qca8k_pcs pcs_port_6; + const struct qca8k_match_data *info; ++ struct qca8k_led ports_led[QCA8K_LED_COUNT]; + }; + + struct qca8k_mib_desc { +--- /dev/null ++++ b/drivers/net/dsa/qca/qca8k_leds.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef __QCA8K_LEDS_H ++#define __QCA8K_LEDS_H ++ ++/* Leds Support function */ ++#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT ++int qca8k_setup_led_ctrl(struct qca8k_priv *priv); ++#else ++static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv) ++{ ++ return 0; ++} ++#endif ++ ++#endif /* __QCA8K_LEDS_H */ diff --git a/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch new file mode 100644 index 000000000..231c4156d --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch @@ -0,0 +1,74 @@ +From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 17:17:25 +0200 +Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support + +Add LEDs blink_set() support to qca8k Switch Family. +These LEDs support hw accellerated blinking at a fixed rate +of 4Hz. + +Reject any other value since not supported by the LEDs switch. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Acked-by: Pavel Machek +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le + } + + static int ++qca8k_cled_blink_set(struct led_classdev *ldev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ; ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ ++ if (*delay_on == 0 && *delay_off == 0) { ++ *delay_on = 125; ++ *delay_off = 125; ++ } ++ ++ if (*delay_on != 125 || *delay_off != 125) { ++ /* The hardware only supports blinking at 4Hz. Fall back ++ * to software implementation in other cases. ++ */ ++ return -EINVAL; ++ } ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, ++ val << reg_info.shift); ++ ++ return 0; ++} ++ ++static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { + struct fwnode_handle *led = NULL, *leds = NULL; +@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv + + port_led->cdev.max_brightness = 1; + port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; ++ port_led->cdev.blink_set = qca8k_cled_blink_set; + init_data.default_label = ":port"; + init_data.fwnode = led; + init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch new file mode 100644 index 000000000..bc905b446 --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch @@ -0,0 +1,59 @@ +From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:26 +0200 +Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are + disabled + +Provide stubs for devm_led_classdev_register_ext() and +led_init_default_state_get() so that LED drivers embedded within other +drivers such as PHYs and Ethernet switches still build when LEDS_CLASS +or NEW_LEDS are disabled. This also helps with Kconfig dependencies, +which are somewhat hairy for phylib and mdio and only get worse when +adding a dependency on LED_CLASS. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -63,7 +63,15 @@ struct led_init_data { + bool devname_mandatory; + }; + ++#if IS_ENABLED(CONFIG_NEW_LEDS) + enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); ++#else ++static inline enum led_default_state ++led_init_default_state_get(struct fwnode_handle *fwnode) ++{ ++ return LEDS_DEFSTATE_OFF; ++} ++#endif + + struct led_hw_trigger_type { + int dummy; +@@ -198,9 +206,19 @@ static inline int led_classdev_register( + return led_classdev_register_ext(parent, led_cdev, NULL); + } + ++#if IS_ENABLED(CONFIG_LEDS_CLASS) + int devm_led_classdev_register_ext(struct device *parent, + struct led_classdev *led_cdev, + struct led_init_data *init_data); ++#else ++static inline int ++devm_led_classdev_register_ext(struct device *parent, ++ struct led_classdev *led_cdev, ++ struct led_init_data *init_data) ++{ ++ return 0; ++} ++#endif + + static inline int devm_led_classdev_register(struct device *parent, + struct led_classdev *led_cdev) diff --git a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch new file mode 100644 index 000000000..a3184513e --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch @@ -0,0 +1,191 @@ +From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:27 +0200 +Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs + +Define common binding parsing for all PHY drivers with LEDs using +phylib. Parse the DT as part of the phy_probe and add LEDs to the +linux LED class infrastructure. For the moment, provide a dummy +brightness function, which will later be replaced with a call into the +PHY driver. This allows testing since the LED core might otherwise +reject an LED whose brightness cannot be set. + +Add a dependency on LED_CLASS. It either needs to be built in, or not +enabled, since a modular build can result in linker errors. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/Kconfig | 1 + + drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 16 ++++++++ + 3 files changed, 93 insertions(+) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -18,6 +18,7 @@ menuconfig PHYLIB + depends on NETDEVICES + select MDIO_DEVICE + select MDIO_DEVRES ++ depends on LEDS_CLASS || LEDS_CLASS=n + help + Ethernet controllers are usually attached to PHY + devices. This option provides infrastructure for +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -19,10 +19,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -644,6 +646,7 @@ struct phy_device *phy_device_create(str + device_initialize(&mdiodev->dev); + + dev->state = PHY_DOWN; ++ INIT_LIST_HEAD(&dev->leds); + + mutex_init(&dev->lock); + INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); +@@ -2931,6 +2934,74 @@ static bool phy_drv_supports_irq(struct + return phydrv->config_intr && phydrv->handle_interrupt; + } + ++/* Dummy implementation until calls into PHY driver are added */ ++static int phy_led_set_brightness(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ return 0; ++} ++ ++static int of_phy_led(struct phy_device *phydev, ++ struct device_node *led) ++{ ++ struct device *dev = &phydev->mdio.dev; ++ struct led_init_data init_data = {}; ++ struct led_classdev *cdev; ++ struct phy_led *phyled; ++ int err; ++ ++ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); ++ if (!phyled) ++ return -ENOMEM; ++ ++ cdev = &phyled->led_cdev; ++ ++ err = of_property_read_u8(led, "reg", &phyled->index); ++ if (err) ++ return err; ++ ++ cdev->brightness_set_blocking = phy_led_set_brightness; ++ cdev->max_brightness = 1; ++ init_data.devicename = dev_name(&phydev->mdio.dev); ++ init_data.fwnode = of_fwnode_handle(led); ++ init_data.devname_mandatory = true; ++ ++ err = devm_led_classdev_register_ext(dev, cdev, &init_data); ++ if (err) ++ return err; ++ ++ list_add(&phyled->list, &phydev->leds); ++ ++ return 0; ++} ++ ++static int of_phy_leds(struct phy_device *phydev) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ struct device_node *leds, *led; ++ int err; ++ ++ if (!IS_ENABLED(CONFIG_OF_MDIO)) ++ return 0; ++ ++ if (!node) ++ return 0; ++ ++ leds = of_get_child_by_name(node, "leds"); ++ if (!leds) ++ return 0; ++ ++ for_each_available_child_of_node(leds, led) { ++ err = of_phy_led(phydev, led); ++ if (err) { ++ of_node_put(led); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ + /** + * fwnode_mdio_find_device - Given a fwnode, find the mdio_device + * @fwnode: pointer to the mdio_device's fwnode +@@ -3109,6 +3180,11 @@ static int phy_probe(struct device *dev) + /* Set the state to READY by default */ + phydev->state = PHY_READY; + ++ /* Get the LEDs from the device tree, and instantiate standard ++ * LEDs for them. ++ */ ++ err = of_phy_leds(phydev); ++ + out: + /* Re-assert the reset signal on error */ + if (err) +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -593,6 +594,7 @@ struct macsec_ops; + * @phy_num_led_triggers: Number of triggers in @phy_led_triggers + * @led_link_trigger: LED trigger for link up/down + * @last_triggered: last LED trigger for link speed ++ * @leds: list of PHY LED structures + * @master_slave_set: User requested master/slave configuration + * @master_slave_get: Current master/slave advertisement + * @master_slave_state: Current master/slave configuration +@@ -685,6 +687,7 @@ struct phy_device { + + struct phy_led_trigger *led_link_trigger; + #endif ++ struct list_head leds; + + /* + * Interrupt number for this PHY +@@ -759,6 +762,19 @@ struct phy_tdr_config { + #define PHY_PAIR_ALL -1 + + /** ++ * struct phy_led: An LED driven by the PHY ++ * ++ * @list: List of LEDs ++ * @led_cdev: Standard LED class structure ++ * @index: Number of the LED ++ */ ++struct phy_led { ++ struct list_head list; ++ struct led_classdev led_cdev; ++ u8 index; ++}; ++ ++/** + * struct phy_driver - Driver structure for a particular PHY type + * + * @mdiodrv: Data common to all MDIO devices diff --git a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch new file mode 100644 index 000000000..57db12ed4 --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -0,0 +1,97 @@ +From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:28 +0200 +Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED + brightness + +Linux LEDs can be software controlled via the brightness file in /sys. +LED drivers need to implement a brightness_set function which the core +will call. Implement an intermediary in phy_device, which will call +into the phy driver if it implements the necessary function. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 15 ++++++++++++--- + include/linux/phy.h | 13 +++++++++++++ + 2 files changed, 25 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2934,11 +2934,18 @@ static bool phy_drv_supports_irq(struct + return phydrv->config_intr && phydrv->handle_interrupt; + } + +-/* Dummy implementation until calls into PHY driver are added */ + static int phy_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness value) + { +- return 0; ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_brightness_set(phydev, phyled->index, value); ++ mutex_unlock(&phydev->lock); ++ ++ return err; + } + + static int of_phy_led(struct phy_device *phydev, +@@ -2955,12 +2962,14 @@ static int of_phy_led(struct phy_device + return -ENOMEM; + + cdev = &phyled->led_cdev; ++ phyled->phydev = phydev; + + err = of_property_read_u8(led, "reg", &phyled->index); + if (err) + return err; + +- cdev->brightness_set_blocking = phy_led_set_brightness; ++ if (phydev->drv->led_brightness_set) ++ cdev->brightness_set_blocking = phy_led_set_brightness; + cdev->max_brightness = 1; + init_data.devicename = dev_name(&phydev->mdio.dev); + init_data.fwnode = of_fwnode_handle(led); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -765,15 +765,19 @@ struct phy_tdr_config { + * struct phy_led: An LED driven by the PHY + * + * @list: List of LEDs ++ * @phydev: PHY this LED is attached to + * @led_cdev: Standard LED class structure + * @index: Number of the LED + */ + struct phy_led { + struct list_head list; ++ struct phy_device *phydev; + struct led_classdev led_cdev; + u8 index; + }; + ++#define to_phy_led(d) container_of(d, struct phy_led, led_cdev) ++ + /** + * struct phy_driver - Driver structure for a particular PHY type + * +@@ -988,6 +992,15 @@ struct phy_driver { + int (*get_sqi)(struct phy_device *dev); + /** @get_sqi_max: Get the maximum signal quality indication */ + int (*get_sqi_max)(struct phy_device *dev); ++ ++ /** ++ * @led_brightness_set: Set a PHY LED brightness. Index ++ * indicates which of the PHYs led should be set. Value ++ * follows the standard LED class meaning, e.g. LED_OFF, ++ * LED_HALF, LED_FULL. ++ */ ++ int (*led_brightness_set)(struct phy_device *dev, ++ u8 index, enum led_brightness value); + }; + #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ + struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch new file mode 100644 index 000000000..5114c0e6d --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch @@ -0,0 +1,112 @@ +From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:29 +0200 +Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs + +Add a brightness function, so the LEDs can be controlled from +software using the standard Linux LED infrastructure. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 40 insertions(+), 5 deletions(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -144,11 +144,13 @@ + /* WOL Event Interrupt Enable */ + #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) + +-/* LED Timer Control Register */ +-#define MII_88E1318S_PHY_LED_TCR 0x12 +-#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) +-#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) +-#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) ++#define MII_88E1318S_PHY_LED_FUNC 0x10 ++#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) ++#define MII_88E1318S_PHY_LED_FUNC_ON (0x9) ++#define MII_88E1318S_PHY_LED_TCR 0x12 ++#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) ++#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) ++#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) + + /* Magic Packet MAC address registers */ + #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 +@@ -2832,6 +2834,34 @@ static int marvell_hwmon_probe(struct ph + } + #endif + ++static int m88e1318_led_brightness_set(struct phy_device *phydev, ++ u8 index, enum led_brightness value) ++{ ++ int reg; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ reg &= ~(0xf << (4 * index)); ++ if (value == LED_OFF) ++ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index); ++ else ++ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC, reg); ++} ++ + static int marvell_probe(struct phy_device *phydev) + { + struct marvell_priv *priv; +@@ -3081,6 +3111,7 @@ static struct phy_driver marvell_drivers + .get_sset_count = marvell_get_sset_count, + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1145, +@@ -3187,6 +3218,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1540, +@@ -3213,6 +3245,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1545, +@@ -3239,6 +3272,7 @@ static struct phy_driver marvell_drivers + .cable_test_start = marvell_vct7_cable_test_start, + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E3016, +@@ -3380,6 +3414,7 @@ static struct phy_driver marvell_drivers + .get_stats = marvell_get_stats, + .get_tunable = m88e1540_get_tunable, + .set_tunable = m88e1540_set_tunable, ++ .led_brightness_set = m88e1318_led_brightness_set, + }, + }; + diff --git a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch new file mode 100644 index 000000000..e868722af --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -0,0 +1,73 @@ +From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:30 +0200 +Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED + blinking + +Linux LEDs can be requested to perform hardware accelerated +blinking. Pass this to the PHY driver, if it implements the op. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 18 ++++++++++++++++++ + include/linux/phy.h | 12 ++++++++++++ + 2 files changed, 30 insertions(+) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2948,6 +2948,22 @@ static int phy_led_set_brightness(struct + return err; + } + ++static int phy_led_blink_set(struct led_classdev *led_cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_blink_set(phydev, phyled->index, ++ delay_on, delay_off); ++ mutex_unlock(&phydev->lock); ++ ++ return err; ++} ++ + static int of_phy_led(struct phy_device *phydev, + struct device_node *led) + { +@@ -2970,6 +2986,8 @@ static int of_phy_led(struct phy_device + + if (phydev->drv->led_brightness_set) + cdev->brightness_set_blocking = phy_led_set_brightness; ++ if (phydev->drv->led_blink_set) ++ cdev->blink_set = phy_led_blink_set; + cdev->max_brightness = 1; + init_data.devicename = dev_name(&phydev->mdio.dev); + init_data.fwnode = of_fwnode_handle(led); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -1001,6 +1001,18 @@ struct phy_driver { + */ + int (*led_brightness_set)(struct phy_device *dev, + u8 index, enum led_brightness value); ++ ++ /** ++ * @led_blink_set: Set a PHY LED brightness. Index indicates ++ * which of the PHYs led should be configured to blink. Delays ++ * are in milliseconds and if both are zero then a sensible ++ * default should be chosen. The call should adjust the ++ * timings in that case and if it can't match the values ++ * specified exactly. ++ */ ++ int (*led_blink_set)(struct phy_device *dev, u8 index, ++ unsigned long *delay_on, ++ unsigned long *delay_off); + }; + #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ + struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch new file mode 100644 index 000000000..8d5081a43 --- /dev/null +++ b/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch @@ -0,0 +1,104 @@ +From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 17 Apr 2023 17:17:31 +0200 +Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set() + +The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at +the same rate, and the reset default is 84ms per blink, which is +around 12Hz. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -147,6 +147,8 @@ + #define MII_88E1318S_PHY_LED_FUNC 0x10 + #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) + #define MII_88E1318S_PHY_LED_FUNC_ON (0x9) ++#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa) ++#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb) + #define MII_88E1318S_PHY_LED_TCR 0x12 + #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) + #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) +@@ -2862,6 +2864,35 @@ static int m88e1318_led_brightness_set(s + MII_88E1318S_PHY_LED_FUNC, reg); + } + ++static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ int reg; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ reg &= ~(0xf << (4 * index)); ++ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); ++ /* Reset default is 84ms */ ++ *delay_on = 84 / 2; ++ *delay_off = 84 / 2; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC, reg); ++} ++ + static int marvell_probe(struct phy_device *phydev) + { + struct marvell_priv *priv; +@@ -3112,6 +3143,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1145, +@@ -3219,6 +3251,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1540, +@@ -3246,6 +3279,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E1545, +@@ -3273,6 +3307,7 @@ static struct phy_driver marvell_drivers + .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + { + .phy_id = MARVELL_PHY_ID_88E3016, +@@ -3415,6 +3450,7 @@ static struct phy_driver marvell_drivers + .get_tunable = m88e1540_get_tunable, + .set_tunable = m88e1540_set_tunable, + .led_brightness_set = m88e1318_led_brightness_set, ++ .led_blink_set = m88e1318_led_blink_set, + }, + }; + diff --git a/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch new file mode 100644 index 000000000..56df3f095 --- /dev/null +++ b/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch @@ -0,0 +1,38 @@ +From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 23 Apr 2023 19:28:00 +0200 +Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in + led_blink_set + +Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel +test robot, probably done by the presence of an if condition dropped in +later revision of the same code. + +Reported-by: kernel test robot +Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/ +Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()") +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/marvell.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -2880,10 +2880,10 @@ static int m88e1318_led_blink_set(struct + case 1: + case 2: + reg &= ~(0xf << (4 * index)); +- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); +- /* Reset default is 84ms */ +- *delay_on = 84 / 2; +- *delay_off = 84 / 2; ++ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); ++ /* Reset default is 84ms */ ++ *delay_on = 84 / 2; ++ *delay_off = 84 / 2; + break; + default: + return -EINVAL; diff --git a/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch new file mode 100644 index 000000000..3170c2605 --- /dev/null +++ b/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch @@ -0,0 +1,87 @@ +From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:40 +0200 +Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from + mode + +Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger +modes is wrong as it's used to set the link state of the device and not +to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and +NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the +netdev trigger mode and should be external to it. + +Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool +that will be true or false based on the carrier link. No functional +change intended. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -50,10 +50,10 @@ struct led_netdev_data { + unsigned int last_activity; + + unsigned long mode; ++ bool carrier_link_up; + #define NETDEV_LED_LINK 0 + #define NETDEV_LED_TX 1 + #define NETDEV_LED_RX 2 +-#define NETDEV_LED_MODE_LINKUP 3 + }; + + enum netdev_led_attr { +@@ -73,9 +73,9 @@ static void set_baseline_state(struct le + if (!led_cdev->blink_brightness) + led_cdev->blink_brightness = led_cdev->max_brightness; + +- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) ++ if (!trigger_data->carrier_link_up) { + led_set_brightness(led_cdev, LED_OFF); +- else { ++ } else { + if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); +@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct + trigger_data->net_dev = + dev_get_by_name(&init_net, trigger_data->device_name); + +- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = false; + if (trigger_data->net_dev != NULL) +- if (netif_carrier_ok(trigger_data->net_dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); + + trigger_data->last_activity = 0; + +@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not + + spin_lock_bh(&trigger_data->lock); + +- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = false; + switch (evt) { + case NETDEV_CHANGENAME: +- if (netif_carrier_ok(dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(dev); + fallthrough; + case NETDEV_REGISTER: + if (trigger_data->net_dev) +@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not + break; + case NETDEV_UP: + case NETDEV_CHANGE: +- if (netif_carrier_ok(dev)) +- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); ++ trigger_data->carrier_link_up = netif_carrier_ok(dev); + break; + } + diff --git a/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch new file mode 100644 index 000000000..19cc1d7c9 --- /dev/null +++ b/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch @@ -0,0 +1,149 @@ +From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:41 +0200 +Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev + trigger enum modes + +Rename NETDEV trigger enum modes to a more symbolic name and add a +namespace to them. + +Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev +trigger. + +This is a cleanup to drop the define and no behaviour change are +intended. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++--------------- + 1 file changed, 25 insertions(+), 33 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -51,15 +51,15 @@ struct led_netdev_data { + + unsigned long mode; + bool carrier_link_up; +-#define NETDEV_LED_LINK 0 +-#define NETDEV_LED_TX 1 +-#define NETDEV_LED_RX 2 + }; + +-enum netdev_led_attr { +- NETDEV_ATTR_LINK, +- NETDEV_ATTR_TX, +- NETDEV_ATTR_RX ++enum led_trigger_netdev_modes { ++ TRIGGER_NETDEV_LINK = 0, ++ TRIGGER_NETDEV_TX, ++ TRIGGER_NETDEV_RX, ++ ++ /* Keep last */ ++ __TRIGGER_NETDEV_MAX, + }; + + static void set_baseline_state(struct led_netdev_data *trigger_data) +@@ -76,7 +76,7 @@ static void set_baseline_state(struct le + if (!trigger_data->carrier_link_up) { + led_set_brightness(led_cdev, LED_OFF); + } else { +- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) ++ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); + else +@@ -85,8 +85,8 @@ static void set_baseline_state(struct le + /* If we are looking for RX/TX start periodically + * checking stats + */ +- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || +- test_bit(NETDEV_LED_RX, &trigger_data->mode)) ++ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) + schedule_delayed_work(&trigger_data->work, 0); + } + } +@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct + static DEVICE_ATTR_RW(device_name); + + static ssize_t netdev_led_attr_show(struct device *dev, char *buf, +- enum netdev_led_attr attr) ++ enum led_trigger_netdev_modes attr) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + int bit; + + switch (attr) { +- case NETDEV_ATTR_LINK: +- bit = NETDEV_LED_LINK; +- break; +- case NETDEV_ATTR_TX: +- bit = NETDEV_LED_TX; +- break; +- case NETDEV_ATTR_RX: +- bit = NETDEV_LED_RX; ++ case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_TX: ++ case TRIGGER_NETDEV_RX: ++ bit = attr; + break; + default: + return -EINVAL; +@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru + } + + static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, +- size_t size, enum netdev_led_attr attr) ++ size_t size, enum led_trigger_netdev_modes attr) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + unsigned long state; +@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str + return ret; + + switch (attr) { +- case NETDEV_ATTR_LINK: +- bit = NETDEV_LED_LINK; +- break; +- case NETDEV_ATTR_TX: +- bit = NETDEV_LED_TX; +- break; +- case NETDEV_ATTR_RX: +- bit = NETDEV_LED_RX; ++ case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_TX: ++ case TRIGGER_NETDEV_RX: ++ bit = attr; + break; + default: + return -EINVAL; +@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work + } + + /* If we are not looking for RX/TX then return */ +- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && +- !test_bit(NETDEV_LED_RX, &trigger_data->mode)) ++ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && ++ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) + return; + + dev_stats = dev_get_stats(trigger_data->net_dev, &temp); + new_activity = +- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? ++ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? + dev_stats->tx_packets : 0) + +- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? ++ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? + dev_stats->rx_packets : 0); + + if (trigger_data->last_activity != new_activity) { + led_stop_software_blink(trigger_data->led_cdev); + +- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); ++ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); + interval = jiffies_to_msecs( + atomic_read(&trigger_data->interval)); + /* base state is ON (link present) */ diff --git a/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch new file mode 100644 index 000000000..3b45951f5 --- /dev/null +++ b/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch @@ -0,0 +1,82 @@ +From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:42 +0200 +Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro + +Convert link tx and rx device attr to a common macro to reduce common +code and in preparation for additional attr. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++------------------- + 1 file changed, 16 insertions(+), 41 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str + return size; + } + +-static ssize_t link_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); +-} +- +-static ssize_t link_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); +-} +- +-static DEVICE_ATTR_RW(link); +- +-static ssize_t tx_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); +-} +- +-static ssize_t tx_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); +-} +- +-static DEVICE_ATTR_RW(tx); +- +-static ssize_t rx_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); +-} +- +-static ssize_t rx_store(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t size) +-{ +- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); +-} +- +-static DEVICE_ATTR_RW(rx); ++#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \ ++ static ssize_t trigger_name##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ ++ { \ ++ return netdev_led_attr_show(dev, buf, trigger); \ ++ } \ ++ static ssize_t trigger_name##_store(struct device *dev, \ ++ struct device_attribute *attr, const char *buf, size_t size) \ ++ { \ ++ return netdev_led_attr_store(dev, buf, size, trigger); \ ++ } \ ++ static DEVICE_ATTR_RW(trigger_name) ++ ++DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); ++DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); ++DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); + + static ssize_t interval_show(struct device *dev, + struct device_attribute *attr, char *buf) diff --git a/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch new file mode 100644 index 000000000..180bee961 --- /dev/null +++ b/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch @@ -0,0 +1,106 @@ +From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 19 Apr 2023 23:07:43 +0200 +Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks + +Some LEDs may require to sleep while doing some operation like setting +brightness and other cleanup. + +For this reason, using a spinlock will cause a sleep under spinlock +warning. + +It should be safe to convert this to a sleepable lock since: +- sysfs read/write can sleep +- netdev_trig_work is a work queue and can sleep +- netdev _trig_notify can sleep + +The spinlock was used when brightness didn't support sleeping, but this +changed and now it supported with brightness_set_blocking(). + +Convert to mutex lock to permit sleeping using brightness_set_blocking(). + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com +--- + drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + #include + #include "../leds.h" + +@@ -37,7 +37,7 @@ + */ + + struct led_netdev_data { +- spinlock_t lock; ++ struct mutex lock; + + struct delayed_work work; + struct notifier_block notifier; +@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + ssize_t len; + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + len = sprintf(buf, "%s\n", trigger_data->device_name); +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return len; + } +@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct + + cancel_delayed_work_sync(&trigger_data->work); + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + + if (trigger_data->net_dev) { + dev_put(trigger_data->net_dev); +@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct + trigger_data->last_activity = 0; + + set_baseline_state(trigger_data); +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return size; + } +@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not + + cancel_delayed_work_sync(&trigger_data->work); + +- spin_lock_bh(&trigger_data->lock); ++ mutex_lock(&trigger_data->lock); + + trigger_data->carrier_link_up = false; + switch (evt) { +@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not + + set_baseline_state(trigger_data); + +- spin_unlock_bh(&trigger_data->lock); ++ mutex_unlock(&trigger_data->lock); + + return NOTIFY_DONE; + } +@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l + if (!trigger_data) + return -ENOMEM; + +- spin_lock_init(&trigger_data->lock); ++ mutex_init(&trigger_data->lock); + + trigger_data->notifier.notifier_call = netdev_trig_notify; + trigger_data->notifier.priority = 10; diff --git a/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch new file mode 100644 index 000000000..ac1861173 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch @@ -0,0 +1,74 @@ +From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:31 +0200 +Subject: [PATCH 01/13] leds: add APIs for LEDs hw control + +Add an option to permit LED driver to declare support for a specific +trigger to use hw control and setup the LED to blink based on specific +provided modes. + +Add APIs for LEDs hw control. These functions will be used to activate +hardware control where a LED will use the provided flags, from an +unique defined supported trigger, to setup the LED to be driven by +hardware. + +Add hw_control_is_supported() to ask the LED driver if the requested +mode by the trigger are supported and the LED can be setup to follow +the requested modes. + +Deactivate hardware blink control by setting brightness to LED_OFF via +the brightness_set() callback. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -164,6 +164,43 @@ struct led_classdev { + + /* LEDs that have private triggers have this set */ + struct led_hw_trigger_type *trigger_type; ++ ++ /* Unique trigger name supported by LED set in hw control mode */ ++ const char *hw_control_trigger; ++ /* ++ * Check if the LED driver supports the requested mode provided by the ++ * defined supported trigger to setup the LED to hw control mode. ++ * ++ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not ++ * supported and software fallback needs to be used. ++ * Return a negative error number on any other case for check fail due ++ * to various reason like device not ready or timeouts. ++ */ ++ int (*hw_control_is_supported)(struct led_classdev *led_cdev, ++ unsigned long flags); ++ /* ++ * Activate hardware control, LED driver will use the provided flags ++ * from the supported trigger and setup the LED to be driven by hardware ++ * following the requested mode from the trigger flags. ++ * Deactivate hardware blink control by setting brightness to LED_OFF via ++ * the brightness_set() callback. ++ * ++ * Return 0 on success, a negative error number on flags apply fail. ++ */ ++ int (*hw_control_set)(struct led_classdev *led_cdev, ++ unsigned long flags); ++ /* ++ * Get from the LED driver the current mode that the LED is set in hw ++ * control mode and put them in flags. ++ * Trigger can use this to get the initial state of a LED already set in ++ * hardware blink control. ++ * ++ * Return 0 on success, a negative error number on failing parsing the ++ * initial mode. Error from this function is NOT FATAL as the device ++ * may be in a not supported initial state by the attached LED trigger. ++ */ ++ int (*hw_control_get)(struct led_classdev *led_cdev, ++ unsigned long *flags); + #endif + + #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch new file mode 100644 index 000000000..1a221727a --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch @@ -0,0 +1,37 @@ +From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:32 +0200 +Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control + +Some specific LED triggers blink the LED based on events from a device +or subsystem. +For example, an LED could be blinked to indicate a network device is +receiving packets, or a disk is reading blocks. To correctly enable and +request the hw control of the LED, the trigger has to check if the +network interface or block device configured via a /sys/class/led file +match the one the LED driver provide for hw control for. + +Provide an API call to get the device which the LED blinks for. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + include/linux/leds.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -201,6 +201,12 @@ struct led_classdev { + */ + int (*hw_control_get)(struct led_classdev *led_cdev, + unsigned long *flags); ++ /* ++ * Get the device this LED blinks in response to. ++ * e.g. for a PHY LED, it is the network device. If the LED is ++ * not yet associated to a device, return NULL. ++ */ ++ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); + #endif + + #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch new file mode 100644 index 000000000..af9fb7fdc --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch @@ -0,0 +1,113 @@ +From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:33 +0200 +Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware + driven LEDs APIs + +Document new Hardware driven LEDs APIs. + +Some LEDs can be programmed to be driven by hardware. This is not +limited to blink but also to turn off or on autonomously. +To support this feature, a LED needs to implement various additional +ops and needs to declare specific support for the supported triggers. + +Add documentation for each required value and API to make hw control +possible and implementable by both LEDs and triggers. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++ + 1 file changed, 81 insertions(+) + +--- a/Documentation/leds/leds-class.rst ++++ b/Documentation/leds/leds-class.rst +@@ -169,6 +169,87 @@ Setting the brightness to zero with brig + should completely turn off the LED and cancel the previously programmed + hardware blinking function, if any. + ++Hardware driven LEDs ++==================== ++ ++Some LEDs can be programmed to be driven by hardware. This is not ++limited to blink but also to turn off or on autonomously. ++To support this feature, a LED needs to implement various additional ++ops and needs to declare specific support for the supported triggers. ++ ++With hw control we refer to the LED driven by hardware. ++ ++LED driver must define the following value to support hw control: ++ ++ - hw_control_trigger: ++ unique trigger name supported by the LED in hw control ++ mode. ++ ++LED driver must implement the following API to support hw control: ++ - hw_control_is_supported: ++ check if the flags passed by the supported trigger can ++ be parsed and activate hw control on the LED. ++ ++ Return 0 if the passed flags mask is supported and ++ can be set with hw_control_set(). ++ ++ If the passed flags mask is not supported -EOPNOTSUPP ++ must be returned, the LED trigger will use software ++ fallback in this case. ++ ++ Return a negative error in case of any other error like ++ device not ready or timeouts. ++ ++ - hw_control_set: ++ activate hw control. LED driver will use the provided ++ flags passed from the supported trigger, parse them to ++ a set of mode and setup the LED to be driven by hardware ++ following the requested modes. ++ ++ Set LED_OFF via the brightness_set to deactivate hw control. ++ ++ Return 0 on success, a negative error number on failing to ++ apply flags. ++ ++ - hw_control_get: ++ get active modes from a LED already in hw control, parse ++ them and set in flags the current active flags for the ++ supported trigger. ++ ++ Return 0 on success, a negative error number on failing ++ parsing the initial mode. ++ Error from this function is NOT FATAL as the device may ++ be in a not supported initial state by the attached LED ++ trigger. ++ ++ - hw_control_get_device: ++ return the device associated with the LED driver in ++ hw control. A trigger might use this to match the ++ returned device from this function with a configured ++ device for the trigger as the source for blinking ++ events and correctly enable hw control. ++ (example a netdev trigger configured to blink for a ++ particular dev match the returned dev from get_device ++ to set hw control) ++ ++ Returns a pointer to a struct device or NULL if nothing ++ is currently attached. ++ ++LED driver can activate additional modes by default to workaround the ++impossibility of supporting each different mode on the supported trigger. ++Examples are hardcoding the blink speed to a set interval, enable special ++feature like bypassing blink if some requirements are not met. ++ ++A trigger should first check if the hw control API are supported by the LED ++driver and check if the trigger is supported to verify if hw control is possible, ++use hw_control_is_supported to check if the flags are supported and only at ++the end use hw_control_set to activate hw control. ++ ++A trigger can use hw_control_get to check if a LED is already in hw control ++and init their flags. ++ ++When the LED is in hw control, no software blink is possible and doing so ++will effectively disable hw control. + + Known Issues + ============ diff --git a/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch new file mode 100644 index 000000000..3c804c0b4 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch @@ -0,0 +1,69 @@ +From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:34 +0200 +Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device + name + +Move the code into a helper, ready for it to be called at +other times. No intended behaviour change. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d + return len; + } + +-static ssize_t device_name_store(struct device *dev, +- struct device_attribute *attr, const char *buf, +- size_t size) ++static int set_device_name(struct led_netdev_data *trigger_data, ++ const char *name, size_t size) + { +- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); +- +- if (size >= IFNAMSIZ) +- return -EINVAL; +- + cancel_delayed_work_sync(&trigger_data->work); + + mutex_lock(&trigger_data->lock); +@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct + trigger_data->net_dev = NULL; + } + +- memcpy(trigger_data->device_name, buf, size); ++ memcpy(trigger_data->device_name, name, size); + trigger_data->device_name[size] = 0; + if (size > 0 && trigger_data->device_name[size - 1] == '\n') + trigger_data->device_name[size - 1] = 0; +@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct + set_baseline_state(trigger_data); + mutex_unlock(&trigger_data->lock); + ++ return 0; ++} ++ ++static ssize_t device_name_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t size) ++{ ++ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ++ int ret; ++ ++ if (size >= IFNAMSIZ) ++ return -EINVAL; ++ ++ ret = set_device_name(trigger_data, buf, size); ++ ++ if (ret < 0) ++ return ret; + return size; + } + diff --git a/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch new file mode 100644 index 000000000..284b51948 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch @@ -0,0 +1,54 @@ +From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:35 +0200 +Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw + control + +Introduce function to check if the requested mode can use hw control in +preparation for hw control support. Currently everything is handled in +software so can_hw_control will always return false. + +Add knob with the new value hw_control in trigger_data struct to +set hw control possible. Useful for future implementation to implement +in set_baseline_state() the required function to set the requested mode +using LEDs hw control ops and in other function to reject set if hw +control is currently active. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -51,6 +51,7 @@ struct led_netdev_data { + + unsigned long mode; + bool carrier_link_up; ++ bool hw_control; + }; + + enum led_trigger_netdev_modes { +@@ -91,6 +92,11 @@ static void set_baseline_state(struct le + } + } + ++static bool can_hw_control(struct led_netdev_data *trigger_data) ++{ ++ return false; ++} ++ + static ssize_t device_name_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str + else + clear_bit(bit, &trigger_data->mode); + ++ trigger_data->hw_control = can_hw_control(trigger_data); ++ + set_baseline_state(trigger_data); + + return size; diff --git a/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch new file mode 100644 index 000000000..09759bc62 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch @@ -0,0 +1,42 @@ +From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:36 +0200 +Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control + support + +Add basic check for hw control support. Check if the required API are +defined and check if the defined trigger supported in hw control for the +LED driver match netdev. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -92,8 +92,22 @@ static void set_baseline_state(struct le + } + } + ++static bool supports_hw_control(struct led_classdev *led_cdev) ++{ ++ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set || ++ !led_cdev->hw_control_is_supported) ++ return false; ++ ++ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); ++} ++ + static bool can_hw_control(struct led_netdev_data *trigger_data) + { ++ struct led_classdev *led_cdev = trigger_data->led_cdev; ++ ++ if (!supports_hw_control(led_cdev)) ++ return false; ++ + return false; + } + diff --git a/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch new file mode 100644 index 000000000..663490680 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch @@ -0,0 +1,28 @@ +From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:37 +0200 +Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for + hw_control + +Reject interval store with hw_control enabled. It's are currently not +supported and MUST be set to the default value with hw control enabled. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev + unsigned long value; + int ret; + ++ if (trigger_data->hw_control) ++ return -EINVAL; ++ + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; diff --git a/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch new file mode 100644 index 000000000..52faa4809 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch @@ -0,0 +1,107 @@ +From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:38 +0200 +Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control + +Add support for LED hw control for the netdev trigger. + +The trigger on calling set_baseline_state to configure a new mode, will +do various check to verify if hw control can be used for the requested +mode in can_hw_control() function. + +It will first check if the LED driver supports hw control for the netdev +trigger, then will use hw_control_is_supported() and finally will call +hw_control_set() to apply the requested mode. + +To use such mode, interval MUST be set to the default value and net_dev +MUST be set. If one of these 2 value are not valid, hw control will +never be used and normal software fallback is used. + +The default interval value is moved to a define to make sure they are +always synced. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -24,6 +24,8 @@ + #include + #include "../leds.h" + ++#define NETDEV_LED_DEFAULT_INTERVAL 50 ++ + /* + * Configurable sysfs attributes: + * +@@ -68,6 +70,13 @@ static void set_baseline_state(struct le + int current_brightness; + struct led_classdev *led_cdev = trigger_data->led_cdev; + ++ /* Already validated, hw control is possible with the requested mode */ ++ if (trigger_data->hw_control) { ++ led_cdev->hw_control_set(led_cdev, trigger_data->mode); ++ ++ return; ++ } ++ + current_brightness = led_cdev->brightness; + if (current_brightness) + led_cdev->blink_brightness = current_brightness; +@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l + + static bool can_hw_control(struct led_netdev_data *trigger_data) + { ++ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); ++ unsigned int interval = atomic_read(&trigger_data->interval); + struct led_classdev *led_cdev = trigger_data->led_cdev; ++ int ret; + + if (!supports_hw_control(led_cdev)) + return false; + +- return false; ++ /* ++ * Interval must be set to the default ++ * value. Any different value is rejected if in hw ++ * control. ++ */ ++ if (interval != default_interval) ++ return false; ++ ++ /* ++ * net_dev must be set with hw control, otherwise no ++ * blinking can be happening and there is nothing to ++ * offloaded. ++ */ ++ if (!trigger_data->net_dev) ++ return false; ++ ++ /* Check if the requested mode is supported */ ++ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode); ++ /* Fall back to software blinking if not supported */ ++ if (ret == -EOPNOTSUPP) ++ return false; ++ if (ret) { ++ dev_warn(led_cdev->dev, ++ "Current mode check failed with error %d\n", ret); ++ return false; ++ } ++ ++ return true; + } + + static ssize_t device_name_show(struct device *dev, +@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l + trigger_data->device_name[0] = 0; + + trigger_data->mode = 0; +- atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); ++ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); + trigger_data->last_activity = 0; + + led_set_trigger_data(led_cdev, trigger_data); diff --git a/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch new file mode 100644 index 000000000..c129ffa4f --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch @@ -0,0 +1,58 @@ +From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:39 +0200 +Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev + +The netdev which the LED should blink for is configurable in +/sys/class/led/foo/device_name. Ensure when offloading that the +configured netdev is the same as the netdev the LED is associated +with. If it is not, only perform software blinking. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l + return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); + } + ++/* ++ * Validate the configured netdev is the same as the one associated with ++ * the LED driver in hw control. ++ */ ++static bool validate_net_dev(struct led_classdev *led_cdev, ++ struct net_device *net_dev) ++{ ++ struct device *dev = led_cdev->hw_control_get_device(led_cdev); ++ struct net_device *ndev; ++ ++ if (!dev) ++ return false; ++ ++ ndev = to_net_dev(dev); ++ ++ return ndev == net_dev; ++} ++ + static bool can_hw_control(struct led_netdev_data *trigger_data) + { + unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); +@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne + /* + * net_dev must be set with hw control, otherwise no + * blinking can be happening and there is nothing to +- * offloaded. ++ * offloaded. Additionally, for hw control to be ++ * valid, the configured netdev must be the same as ++ * netdev associated to the LED. + */ +- if (!trigger_data->net_dev) ++ if (!validate_net_dev(led_cdev, trigger_data->net_dev)) + return false; + + /* Check if the requested mode is supported */ diff --git a/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch new file mode 100644 index 000000000..e20594c99 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch @@ -0,0 +1,53 @@ +From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:40 +0200 +Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already + active + +On netdev trigger activation, hw control may be already active by +default. If this is the case and a device is actually provided by +hw_control_get_device(), init the already active mode and set the +bool to hw_control bool to true to reflect the already set mode in the +trigger_data. + +Co-developed-by: Andrew Lunn +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work + static int netdev_trig_activate(struct led_classdev *led_cdev) + { + struct led_netdev_data *trigger_data; ++ unsigned long mode; ++ struct device *dev; + int rc; + + trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); +@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l + atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); + trigger_data->last_activity = 0; + ++ /* Check if hw control is active by default on the LED. ++ * Init already enabled mode in hw control. ++ */ ++ if (supports_hw_control(led_cdev) && ++ !led_cdev->hw_control_get(led_cdev, &mode)) { ++ dev = led_cdev->hw_control_get_device(led_cdev); ++ if (dev) { ++ const char *name = dev_name(dev); ++ ++ set_device_name(trigger_data, name, strlen(name)); ++ trigger_data->hw_control = true; ++ trigger_data->mode = mode; ++ } ++ } ++ + led_set_trigger_data(led_cdev, trigger_data); + + rc = register_netdevice_notifier(&trigger_data->notifier); diff --git a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch new file mode 100644 index 000000000..70aed850d --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch @@ -0,0 +1,54 @@ +From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:41 +0200 +Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in + linux include + +Expose netdev trigger modes to make them accessible by LED driver that +will support netdev trigger for hw control. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 9 --------- + include/linux/leds.h | 10 ++++++++++ + 2 files changed, 10 insertions(+), 9 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -56,15 +56,6 @@ struct led_netdev_data { + bool hw_control; + }; + +-enum led_trigger_netdev_modes { +- TRIGGER_NETDEV_LINK = 0, +- TRIGGER_NETDEV_TX, +- TRIGGER_NETDEV_RX, +- +- /* Keep last */ +- __TRIGGER_NETDEV_MAX, +-}; +- + static void set_baseline_state(struct led_netdev_data *trigger_data) + { + int current_brightness; +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data + + #endif /* CONFIG_LEDS_TRIGGERS */ + ++/* Trigger specific enum */ ++enum led_trigger_netdev_modes { ++ TRIGGER_NETDEV_LINK = 0, ++ TRIGGER_NETDEV_TX, ++ TRIGGER_NETDEV_RX, ++ ++ /* Keep last */ ++ __TRIGGER_NETDEV_MAX, ++}; ++ + /* Trigger specific functions */ + #ifdef CONFIG_LEDS_TRIGGER_DISK + void ledtrig_disk_activity(bool write); diff --git a/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch new file mode 100644 index 000000000..ad76d89b7 --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch @@ -0,0 +1,200 @@ +From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 29 May 2023 18:32:42 +0200 +Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops + +Implement hw_control ops to drive Switch LEDs based on hardware events. + +Netdev trigger is the declared supported trigger for hw control +operation and supports the following mode: +- tx +- rx + +When hw_control_set is called, LEDs are set to follow the requested +mode. +Each LEDs will blink at 4Hz by default. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++ + 1 file changed, 154 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i + } + + static int ++qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) ++{ ++ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); ++ ++ /* 6 total control rule: ++ * 3 control rules for phy0-3 that applies to all their leds ++ * 3 control rules for phy4 ++ */ ++ if (port_num == 4) ++ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; ++ else ++ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; ++ ++ return 0; ++} ++ ++static int ++qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger) ++{ ++ /* Parsing specific to netdev trigger */ ++ if (test_bit(TRIGGER_NETDEV_TX, &rules)) ++ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK; ++ if (test_bit(TRIGGER_NETDEV_RX, &rules)) ++ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK; ++ ++ if (rules && !*offload_trigger) ++ return -EOPNOTSUPP; ++ ++ /* Enable some default rule by default to the requested mode: ++ * - Blink at 4Hz by default ++ */ ++ *offload_trigger |= QCA8K_LED_BLINK_4HZ; ++ ++ return 0; ++} ++ ++static int + qca8k_led_brightness_set(struct qca8k_led *led, + enum led_brightness brightness) + { +@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev + } + + static int ++qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 mask, val = QCA8K_LED_ALWAYS_OFF; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ if (enable) ++ val = QCA8K_LED_RULE_CONTROLLED; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ mask = QCA8K_LED_PATTERN_EN_MASK; ++ val <<= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, ++ val << reg_info.shift); ++} ++ ++static bool ++qca8k_cled_hw_control_status(struct led_classdev *ldev) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ ++ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); ++ ++ regmap_read(priv->regmap, reg_info.reg, &val); ++ ++ val >>= reg_info.shift; ++ ++ if (led->port_num == 0 || led->port_num == 4) { ++ val &= QCA8K_LED_PATTERN_EN_MASK; ++ val >>= QCA8K_LED_PATTERN_EN_SHIFT; ++ } else { ++ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; ++ } ++ ++ return val == QCA8K_LED_RULE_CONTROLLED; ++} ++ ++static int ++qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) ++{ ++ u32 offload_trigger = 0; ++ ++ return qca8k_parse_netdev(rules, &offload_trigger); ++} ++ ++static int ++qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 offload_trigger = 0; ++ int ret; ++ ++ ret = qca8k_parse_netdev(rules, &offload_trigger); ++ if (ret) ++ return ret; ++ ++ ret = qca8k_cled_trigger_offload(ldev, true); ++ if (ret) ++ return ret; ++ ++ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); ++ ++ return regmap_update_bits(priv->regmap, reg_info.reg, ++ QCA8K_LED_RULE_MASK << reg_info.shift, ++ offload_trigger << reg_info.shift); ++} ++ ++static int ++qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_led_pattern_en reg_info; ++ struct qca8k_priv *priv = led->priv; ++ u32 val; ++ int ret; ++ ++ /* With hw control not active return err */ ++ if (!qca8k_cled_hw_control_status(ldev)) ++ return -EINVAL; ++ ++ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); ++ ++ ret = regmap_read(priv->regmap, reg_info.reg, &val); ++ if (ret) ++ return ret; ++ ++ val >>= reg_info.shift; ++ val &= QCA8K_LED_RULE_MASK; ++ ++ /* Parsing specific to netdev trigger */ ++ if (val & QCA8K_LED_TX_BLINK_MASK) ++ set_bit(TRIGGER_NETDEV_TX, rules); ++ if (val & QCA8K_LED_RX_BLINK_MASK) ++ set_bit(TRIGGER_NETDEV_RX, rules); ++ ++ return 0; ++} ++ ++static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { + struct fwnode_handle *led = NULL, *leds = NULL; +@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv + port_led->cdev.max_brightness = 1; + port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; + port_led->cdev.blink_set = qca8k_cled_blink_set; ++ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; ++ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; ++ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; ++ port_led->cdev.hw_control_trigger = "netdev"; + init_data.default_label = ":port"; + init_data.fwnode = led; + init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch new file mode 100644 index 000000000..feb6b9e1e --- /dev/null +++ b/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch @@ -0,0 +1,70 @@ +From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Mon, 29 May 2023 18:32:43 +0200 +Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev + +In order that the LED trigger can blink the switch MAC ports LED, it +needs to know the netdev associated to the port. Add the callback to +return the struct device of the netdev. + +Add an helper function qca8k_phy_to_port() to convert the phy back to +dsa_port index, as we reference LED port based on the internal PHY +index and needs to be converted back. + +Signed-off-by: Andrew Lunn +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/drivers/net/dsa/qca/qca8k-leds.c ++++ b/drivers/net/dsa/qca/qca8k-leds.c +@@ -5,6 +5,18 @@ + #include "qca8k.h" + #include "qca8k_leds.h" + ++static u32 qca8k_phy_to_port(int phy) ++{ ++ /* Internal PHY 0 has port at index 1. ++ * Internal PHY 1 has port at index 2. ++ * Internal PHY 2 has port at index 3. ++ * Internal PHY 3 has port at index 4. ++ * Internal PHY 4 has port at index 5. ++ */ ++ ++ return phy + 1; ++} ++ + static int + qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) + { +@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla + return 0; + } + ++static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev) ++{ ++ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); ++ struct qca8k_priv *priv = led->priv; ++ struct dsa_port *dp; ++ ++ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num)); ++ if (!dp) ++ return NULL; ++ if (dp->slave) ++ return &dp->slave->dev; ++ return NULL; ++} ++ + static int + qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) + { +@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv + port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; + port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; + port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; ++ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device; + port_led->cdev.hw_control_trigger = "netdev"; + init_data.default_label = ":port"; + init_data.fwnode = led; diff --git a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch new file mode 100644 index 000000000..1c564b389 --- /dev/null +++ b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch @@ -0,0 +1,242 @@ +From d5e01266e7f5fa12400d4c8aa4e86fe89dcc61e9 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 Jun 2023 22:46:58 +0200 +Subject: [PATCH 1/3] leds: trigger: netdev: add additional specific link speed + mode + +Add additional modes for specific link speed. Use ethtool APIs to get the +current link speed and enable the LED accordingly. Under netdev event +handler the rtnl lock is already held and is not needed to be set to +access ethtool APIs. + +This is especially useful for PHY and Switch that supports LEDs hw +control for specific link speed. (example scenario a PHY that have 2 LED +connected one green and one orange where the green is turned on with +1000mbps speed and orange is turned on with 10mpbs speed) + +On mode set from sysfs we check if we have enabled split link speed mode +and reject enabling generic link mode to prevent wrong and redundant +configuration. + +Rework logic on the set baseline state to support these new modes to +select if we need to turn on or off the LED. + +Add additional modes: +- link_10: Turn on LED when link speed is 10mbps +- link_100: Turn on LED when link speed is 100mbps +- link_1000: Turn on LED when link speed is 1000mbps + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Acked-by: Lee Jones +Signed-off-by: Jakub Kicinski +--- + drivers/leds/trigger/ledtrig-netdev.c | 80 +++++++++++++++++++++++---- + include/linux/leds.h | 3 + + 2 files changed, 73 insertions(+), 10 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -21,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include "../leds.h" + +@@ -52,6 +54,8 @@ struct led_netdev_data { + unsigned int last_activity; + + unsigned long mode; ++ int link_speed; ++ + bool carrier_link_up; + bool hw_control; + }; +@@ -77,7 +81,24 @@ static void set_baseline_state(struct le + if (!trigger_data->carrier_link_up) { + led_set_brightness(led_cdev, LED_OFF); + } else { ++ bool blink_on = false; ++ + if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) ++ blink_on = true; ++ ++ if (test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) && ++ trigger_data->link_speed == SPEED_10) ++ blink_on = true; ++ ++ if (test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) && ++ trigger_data->link_speed == SPEED_100) ++ blink_on = true; ++ ++ if (test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) && ++ trigger_data->link_speed == SPEED_1000) ++ blink_on = true; ++ ++ if (blink_on) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); + else +@@ -161,6 +182,18 @@ static bool can_hw_control(struct led_ne + return true; + } + ++static void get_device_state(struct led_netdev_data *trigger_data) ++{ ++ struct ethtool_link_ksettings cmd; ++ ++ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); ++ if (!trigger_data->carrier_link_up) ++ return; ++ ++ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) ++ trigger_data->link_speed = cmd.base.speed; ++} ++ + static ssize_t device_name_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -196,8 +229,12 @@ static int set_device_name(struct led_ne + dev_get_by_name(&init_net, trigger_data->device_name); + + trigger_data->carrier_link_up = false; +- if (trigger_data->net_dev != NULL) +- trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); ++ trigger_data->link_speed = SPEED_UNKNOWN; ++ if (trigger_data->net_dev != NULL) { ++ rtnl_lock(); ++ get_device_state(trigger_data); ++ rtnl_unlock(); ++ } + + trigger_data->last_activity = 0; + +@@ -234,6 +271,9 @@ static ssize_t netdev_led_attr_show(stru + + switch (attr) { + case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_LINK_10: ++ case TRIGGER_NETDEV_LINK_100: ++ case TRIGGER_NETDEV_LINK_1000: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; +@@ -249,7 +289,7 @@ static ssize_t netdev_led_attr_store(str + size_t size, enum led_trigger_netdev_modes attr) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); +- unsigned long state; ++ unsigned long state, mode = trigger_data->mode; + int ret; + int bit; + +@@ -259,6 +299,9 @@ static ssize_t netdev_led_attr_store(str + + switch (attr) { + case TRIGGER_NETDEV_LINK: ++ case TRIGGER_NETDEV_LINK_10: ++ case TRIGGER_NETDEV_LINK_100: ++ case TRIGGER_NETDEV_LINK_1000: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; +@@ -267,13 +310,20 @@ static ssize_t netdev_led_attr_store(str + return -EINVAL; + } + +- cancel_delayed_work_sync(&trigger_data->work); +- + if (state) +- set_bit(bit, &trigger_data->mode); ++ set_bit(bit, &mode); + else +- clear_bit(bit, &trigger_data->mode); ++ clear_bit(bit, &mode); ++ ++ if (test_bit(TRIGGER_NETDEV_LINK, &mode) && ++ (test_bit(TRIGGER_NETDEV_LINK_10, &mode) || ++ test_bit(TRIGGER_NETDEV_LINK_100, &mode) || ++ test_bit(TRIGGER_NETDEV_LINK_1000, &mode))) ++ return -EINVAL; ++ ++ cancel_delayed_work_sync(&trigger_data->work); + ++ trigger_data->mode = mode; + trigger_data->hw_control = can_hw_control(trigger_data); + + set_baseline_state(trigger_data); +@@ -295,6 +345,9 @@ static ssize_t netdev_led_attr_store(str + static DEVICE_ATTR_RW(trigger_name) + + DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); ++DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); ++DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); ++DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); + DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); + DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); + +@@ -338,6 +391,9 @@ static DEVICE_ATTR_RW(interval); + static struct attribute *netdev_trig_attrs[] = { + &dev_attr_device_name.attr, + &dev_attr_link.attr, ++ &dev_attr_link_10.attr, ++ &dev_attr_link_100.attr, ++ &dev_attr_link_1000.attr, + &dev_attr_rx.attr, + &dev_attr_tx.attr, + &dev_attr_interval.attr, +@@ -368,9 +424,10 @@ static int netdev_trig_notify(struct not + mutex_lock(&trigger_data->lock); + + trigger_data->carrier_link_up = false; ++ trigger_data->link_speed = SPEED_UNKNOWN; + switch (evt) { + case NETDEV_CHANGENAME: +- trigger_data->carrier_link_up = netif_carrier_ok(dev); ++ get_device_state(trigger_data); + fallthrough; + case NETDEV_REGISTER: + if (trigger_data->net_dev) +@@ -384,7 +441,7 @@ static int netdev_trig_notify(struct not + break; + case NETDEV_UP: + case NETDEV_CHANGE: +- trigger_data->carrier_link_up = netif_carrier_ok(dev); ++ get_device_state(trigger_data); + break; + } + +@@ -427,7 +484,10 @@ static void netdev_trig_work(struct work + if (trigger_data->last_activity != new_activity) { + led_stop_software_blink(trigger_data->led_cdev); + +- invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); ++ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode); + interval = jiffies_to_msecs( + atomic_read(&trigger_data->interval)); + /* base state is ON (link present) */ +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -530,6 +530,9 @@ static inline void *led_get_trigger_data + /* Trigger specific enum */ + enum led_trigger_netdev_modes { + TRIGGER_NETDEV_LINK = 0, ++ TRIGGER_NETDEV_LINK_10, ++ TRIGGER_NETDEV_LINK_100, ++ TRIGGER_NETDEV_LINK_1000, + TRIGGER_NETDEV_TX, + TRIGGER_NETDEV_RX, + diff --git a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch new file mode 100644 index 000000000..a5ab46182 --- /dev/null +++ b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch @@ -0,0 +1,138 @@ +From f22f95b9ff1551c9bab13104131929f33d51f23f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 Jun 2023 22:46:59 +0200 +Subject: [PATCH 2/3] leds: trigger: netdev: add additional specific link + duplex mode + +Add additional modes for specific link duplex. Use ethtool APIs to get the +current link duplex and enable the LED accordingly. Under netdev event +handler the rtnl lock is already held and is not needed to be set to +access ethtool APIs. + +This is especially useful for PHY and Switch that supports LEDs hw +control for specific link duplex. + +Add additional modes: +- half_duplex: Turn on LED when link is half duplex +- full_duplex: Turn on LED when link is full duplex + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Acked-by: Lee Jones +Signed-off-by: Jakub Kicinski +--- + drivers/leds/trigger/ledtrig-netdev.c | 27 +++++++++++++++++++++++++-- + include/linux/leds.h | 2 ++ + 2 files changed, 27 insertions(+), 2 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -55,6 +55,7 @@ struct led_netdev_data { + + unsigned long mode; + int link_speed; ++ u8 duplex; + + bool carrier_link_up; + bool hw_control; +@@ -98,6 +99,14 @@ static void set_baseline_state(struct le + trigger_data->link_speed == SPEED_1000) + blink_on = true; + ++ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) && ++ trigger_data->duplex == DUPLEX_HALF) ++ blink_on = true; ++ ++ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode) && ++ trigger_data->duplex == DUPLEX_FULL) ++ blink_on = true; ++ + if (blink_on) + led_set_brightness(led_cdev, + led_cdev->blink_brightness); +@@ -190,8 +199,10 @@ static void get_device_state(struct led_ + if (!trigger_data->carrier_link_up) + return; + +- if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) ++ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) { + trigger_data->link_speed = cmd.base.speed; ++ trigger_data->duplex = cmd.base.duplex; ++ } + } + + static ssize_t device_name_show(struct device *dev, +@@ -230,6 +241,7 @@ static int set_device_name(struct led_ne + + trigger_data->carrier_link_up = false; + trigger_data->link_speed = SPEED_UNKNOWN; ++ trigger_data->duplex = DUPLEX_UNKNOWN; + if (trigger_data->net_dev != NULL) { + rtnl_lock(); + get_device_state(trigger_data); +@@ -274,6 +286,8 @@ static ssize_t netdev_led_attr_show(stru + case TRIGGER_NETDEV_LINK_10: + case TRIGGER_NETDEV_LINK_100: + case TRIGGER_NETDEV_LINK_1000: ++ case TRIGGER_NETDEV_HALF_DUPLEX: ++ case TRIGGER_NETDEV_FULL_DUPLEX: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; +@@ -302,6 +316,8 @@ static ssize_t netdev_led_attr_store(str + case TRIGGER_NETDEV_LINK_10: + case TRIGGER_NETDEV_LINK_100: + case TRIGGER_NETDEV_LINK_1000: ++ case TRIGGER_NETDEV_HALF_DUPLEX: ++ case TRIGGER_NETDEV_FULL_DUPLEX: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; +@@ -348,6 +364,8 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETD + DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); + DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); + DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); ++DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX); ++DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX); + DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); + DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); + +@@ -394,6 +412,8 @@ static struct attribute *netdev_trig_att + &dev_attr_link_10.attr, + &dev_attr_link_100.attr, + &dev_attr_link_1000.attr, ++ &dev_attr_full_duplex.attr, ++ &dev_attr_half_duplex.attr, + &dev_attr_rx.attr, + &dev_attr_tx.attr, + &dev_attr_interval.attr, +@@ -425,6 +445,7 @@ static int netdev_trig_notify(struct not + + trigger_data->carrier_link_up = false; + trigger_data->link_speed = SPEED_UNKNOWN; ++ trigger_data->duplex = DUPLEX_UNKNOWN; + switch (evt) { + case NETDEV_CHANGENAME: + get_device_state(trigger_data); +@@ -487,7 +508,9 @@ static void netdev_trig_work(struct work + invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) || + test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) || + test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) || +- test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode); ++ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) || ++ test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode); + interval = jiffies_to_msecs( + atomic_read(&trigger_data->interval)); + /* base state is ON (link present) */ +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -533,6 +533,8 @@ enum led_trigger_netdev_modes { + TRIGGER_NETDEV_LINK_10, + TRIGGER_NETDEV_LINK_100, + TRIGGER_NETDEV_LINK_1000, ++ TRIGGER_NETDEV_HALF_DUPLEX, ++ TRIGGER_NETDEV_FULL_DUPLEX, + TRIGGER_NETDEV_TX, + TRIGGER_NETDEV_RX, + diff --git a/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch b/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch new file mode 100644 index 000000000..67528cafe --- /dev/null +++ b/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch @@ -0,0 +1,45 @@ +From b655892ffd6d89b0c7407e099c40dbde82ee3f03 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 Jun 2023 22:47:00 +0200 +Subject: [PATCH 3/3] leds: trigger: netdev: expose hw_control status via sysfs + +Expose hw_control status via sysfs for the netdev trigger to give +userspace better understanding of the current state of the trigger and +the LED. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Reviewed-by: Kalesh AP +Acked-by: Lee Jones +Signed-off-by: Jakub Kicinski +--- + drivers/leds/trigger/ledtrig-netdev.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -406,6 +406,16 @@ static ssize_t interval_store(struct dev + + static DEVICE_ATTR_RW(interval); + ++static ssize_t hw_control_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", trigger_data->hw_control); ++} ++ ++static DEVICE_ATTR_RO(hw_control); ++ + static struct attribute *netdev_trig_attrs[] = { + &dev_attr_device_name.attr, + &dev_attr_link.attr, +@@ -417,6 +427,7 @@ static struct attribute *netdev_trig_att + &dev_attr_rx.attr, + &dev_attr_tx.attr, + &dev_attr_interval.attr, ++ &dev_attr_hw_control.attr, + NULL + }; + ATTRIBUTE_GROUPS(netdev_trig); diff --git a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch new file mode 100644 index 000000000..1de086417 --- /dev/null +++ b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch @@ -0,0 +1,65 @@ +From 4bb7aac70b5d8a4bddf4ee0791b834f9f56883d2 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 20 Apr 2023 10:45:51 +0200 +Subject: [PATCH] net: phy: fix circular LEDS_CLASS dependencies + +The CONFIG_PHYLIB symbol is selected by a number of device drivers that +need PHY support, but it now has a dependency on CONFIG_LEDS_CLASS, +which may not be enabled, causing build failures. + +Avoid the risk of missing and circular dependencies by guarding the +phylib LED support itself in another Kconfig symbol that can only be +enabled if the dependency is met. + +This could be made a hidden symbol and always enabled when both CONFIG_OF +and CONFIG_LEDS_CLASS are reachable from the phylib, but there may be an +advantage in having users see this option when they have a misconfigured +kernel without built-in LED support. + +Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") +Signed-off-by: Arnd Bergmann +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20230420084624.3005701-1-arnd@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/Kconfig | 9 ++++++++- + drivers/net/phy/phy_device.c | 3 ++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -18,7 +18,6 @@ menuconfig PHYLIB + depends on NETDEVICES + select MDIO_DEVICE + select MDIO_DEVRES +- depends on LEDS_CLASS || LEDS_CLASS=n + help + Ethernet controllers are usually attached to PHY + devices. This option provides infrastructure for +@@ -45,6 +44,14 @@ config LED_TRIGGER_PHY + Mbps OR Gbps OR link + for any speed known to the PHY. + ++config PHYLIB_LEDS ++ bool "Support probing LEDs from device tree" ++ depends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB ++ depends on OF ++ default y ++ help ++ When LED class support is enabled, phylib can automatically ++ probe LED setting from device tree. + + config FIXED_PHY + tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs" +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -3210,7 +3210,8 @@ static int phy_probe(struct device *dev) + /* Get the LEDs from the device tree, and instantiate standard + * LEDs for them. + */ +- err = of_phy_leds(phydev); ++ if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) ++ err = of_phy_leds(phydev); + + out: + /* Re-assert the reset signal on error */ diff --git a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch new file mode 100644 index 000000000..d6081d0e6 --- /dev/null +++ b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch @@ -0,0 +1,43 @@ +From aed8fdad2152d946add50bec00a6b07c457bdcdf Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Mon, 24 Apr 2023 16:16:48 +0200 +Subject: [PATCH] net: phy: Fix reading LED reg property + +'reg' is always encoded in 32 bits, thus it has to be read using the +function with the corresponding bit width. + +Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") +Signed-off-by: Alexander Stein +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20230424141648.317944-1-alexander.stein@ew.tq-group.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/phy_device.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2971,6 +2971,7 @@ static int of_phy_led(struct phy_device + struct led_init_data init_data = {}; + struct led_classdev *cdev; + struct phy_led *phyled; ++ u32 index; + int err; + + phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); +@@ -2980,10 +2981,13 @@ static int of_phy_led(struct phy_device + cdev = &phyled->led_cdev; + phyled->phydev = phydev; + +- err = of_property_read_u8(led, "reg", &phyled->index); ++ err = of_property_read_u32(led, "reg", &index); + if (err) + return err; ++ if (index > U8_MAX) ++ return -EINVAL; + ++ phyled->index = index; + if (phydev->drv->led_brightness_set) + cdev->brightness_set_blocking = phy_led_set_brightness; + if (phydev->drv->led_blink_set) diff --git a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch new file mode 100644 index 000000000..8f076be64 --- /dev/null +++ b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch @@ -0,0 +1,67 @@ +From c938ab4da0eb1620ae3243b0b24c572ddfc318fc Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Sat, 17 Jun 2023 17:55:00 +0200 +Subject: [PATCH] net: phy: Manual remove LEDs to ensure correct ordering + +If the core is left to remove the LEDs via devm_, it is performed too +late, after the PHY driver is removed from the PHY. This results in +dereferencing a NULL pointer when the LED core tries to turn the LED +off before destroying the LED. + +Manually unregister the LEDs at a safe point in phy_remove. + +Cc: stable@vger.kernel.org +Reported-by: Florian Fainelli +Suggested-by: Florian Fainelli +Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") +Signed-off-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2964,6 +2964,15 @@ static int phy_led_blink_set(struct led_ + return err; + } + ++static void phy_leds_unregister(struct phy_device *phydev) ++{ ++ struct phy_led *phyled; ++ ++ list_for_each_entry(phyled, &phydev->leds, list) { ++ led_classdev_unregister(&phyled->led_cdev); ++ } ++} ++ + static int of_phy_led(struct phy_device *phydev, + struct device_node *led) + { +@@ -2997,7 +3006,7 @@ static int of_phy_led(struct phy_device + init_data.fwnode = of_fwnode_handle(led); + init_data.devname_mandatory = true; + +- err = devm_led_classdev_register_ext(dev, cdev, &init_data); ++ err = led_classdev_register_ext(dev, cdev, &init_data); + if (err) + return err; + +@@ -3026,6 +3035,7 @@ static int of_phy_leds(struct phy_device + err = of_phy_led(phydev, led); + if (err) { + of_node_put(led); ++ phy_leds_unregister(phydev); + return err; + } + } +@@ -3231,6 +3241,9 @@ static int phy_remove(struct device *dev + + cancel_delayed_work_sync(&phydev->state_queue); + ++ if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) ++ phy_leds_unregister(phydev); ++ + phydev->state = PHY_DOWN; + + sfp_bus_del_upstream(phydev->sfp_bus); diff --git a/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch b/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch new file mode 100644 index 000000000..609115b04 --- /dev/null +++ b/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch @@ -0,0 +1,44 @@ +From af7320ecae0ce646fd2c4a88341a3fbc243553da Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Thu, 11 May 2023 15:08:20 +0800 +Subject: [PATCH] leds: trigger: netdev: Remove NULL check before dev_{put, + hold} + +The call netdev_{put, hold} of dev_{put, hold} will check NULL, +so there is no need to check before using dev_{put, hold}, +remove it to silence the warnings: + +./drivers/leds/trigger/ledtrig-netdev.c:291:3-10: WARNING: NULL check before dev_{put, hold} functions is not needed. +./drivers/leds/trigger/ledtrig-netdev.c:401:2-9: WARNING: NULL check before dev_{put, hold} functions is not needed. + +Reported-by: Abaci Robot +Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=4929 +Signed-off-by: Yang Li +Link: https://lore.kernel.org/r/20230511070820.52731-1-yang.lee@linux.alibaba.com +Signed-off-by: Lee Jones +--- + drivers/leds/trigger/ledtrig-netdev.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -462,8 +462,7 @@ static int netdev_trig_notify(struct not + get_device_state(trigger_data); + fallthrough; + case NETDEV_REGISTER: +- if (trigger_data->net_dev) +- dev_put(trigger_data->net_dev); ++ dev_put(trigger_data->net_dev); + dev_hold(dev); + trigger_data->net_dev = dev; + break; +@@ -594,8 +593,7 @@ static void netdev_trig_deactivate(struc + + cancel_delayed_work_sync(&trigger_data->work); + +- if (trigger_data->net_dev) +- dev_put(trigger_data->net_dev); ++ dev_put(trigger_data->net_dev); + + kfree(trigger_data); + } diff --git a/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch b/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch new file mode 100644 index 000000000..2f7a6ced9 --- /dev/null +++ b/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch @@ -0,0 +1,31 @@ +From 97c5209b3d374a25ebdb4c2ea9e9c1b121768da0 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 14 Jun 2023 10:03:59 +0300 +Subject: [PATCH] leds: trigger: netdev: uninitialized variable in + netdev_trig_activate() + +The qca8k_cled_hw_control_get() function which implements ->hw_control_get +sets the appropriate bits but does not clear them. This leads to an +uninitialized variable bug. Fix this by setting mode to zero at the +start. + +Fixes: e0256648c831 ("net: dsa: qca8k: implement hw_control ops") +Signed-off-by: Dan Carpenter +Reviewed-by: Andrew Lunn +Acked-by: Lee Jones +Signed-off-by: David S. Miller +--- + drivers/leds/trigger/ledtrig-netdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -538,7 +538,7 @@ static void netdev_trig_work(struct work + static int netdev_trig_activate(struct led_classdev *led_cdev) + { + struct led_netdev_data *trigger_data; +- unsigned long mode; ++ unsigned long mode = 0; + struct device *dev; + int rc; + diff --git a/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch b/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch new file mode 100644 index 000000000..dedf84c64 --- /dev/null +++ b/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch @@ -0,0 +1,57 @@ +From 7df1f14c04cbb1950e79c19793420f87227c3e80 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Tue, 8 Aug 2023 23:04:33 +0200 +Subject: [PATCH 1/4] led: trig: netdev: Fix requesting offload device + +When the netdev trigger is activates, it tries to determine what +device the LED blinks for, and what the current blink mode is. + +The documentation for hw_control_get() says: + + * Return 0 on success, a negative error number on failing parsing the + * initial mode. Error from this function is NOT FATAL as the device + * may be in a not supported initial state by the attached LED trigger. + */ + +For the Marvell PHY and the Armada 370-rd board, the initial LED blink +mode is not supported by the trigger, so it returns an error. This +resulted in not getting the device the LED is blinking for. As a +result, the device is unknown and offloaded is never performed. + +Change to condition to always get the device if offloading is +supported, and reduce the scope of testing for an error from +hw_control_get() to skip setting trigger internal state if there is an +error. + +Reviewed-by: Simon Horman +Signed-off-by: Andrew Lunn +Tested-by: Daniel Golle +Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch +Signed-off-by: Jakub Kicinski +--- + drivers/leds/trigger/ledtrig-netdev.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct l + /* Check if hw control is active by default on the LED. + * Init already enabled mode in hw control. + */ +- if (supports_hw_control(led_cdev) && +- !led_cdev->hw_control_get(led_cdev, &mode)) { ++ if (supports_hw_control(led_cdev)) { + dev = led_cdev->hw_control_get_device(led_cdev); + if (dev) { + const char *name = dev_name(dev); + + set_device_name(trigger_data, name, strlen(name)); + trigger_data->hw_control = true; +- trigger_data->mode = mode; ++ ++ rc = led_cdev->hw_control_get(led_cdev, &mode); ++ if (!rc) ++ trigger_data->mode = mode; + } + } + diff --git a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch new file mode 100644 index 000000000..6cd798fc5 --- /dev/null +++ b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -0,0 +1,149 @@ +From 1dcc03c9a7a824a31eaaecdfaa03542fb25feb6c Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Tue, 8 Aug 2023 23:04:34 +0200 +Subject: [PATCH 2/4] net: phy: phy_device: Call into the PHY driver to set LED + offload + +Linux LEDs can be requested to perform hardware accelerated blinking +to indicate link, RX, TX etc. Pass the rules for blinking to the PHY +driver, if it implements the ops needed to determine if a given +pattern can be offloaded, to offload it, and what the current offload +is. Additionally implement the op needed to get what device the LED is +for. + +Reviewed-by: Simon Horman +Signed-off-by: Andrew Lunn +Tested-by: Daniel Golle +Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 33 +++++++++++++++++ + 2 files changed, 101 insertions(+) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2964,6 +2964,61 @@ static int phy_led_blink_set(struct led_ + return err; + } + ++static __maybe_unused struct device * ++phy_led_hw_control_get_device(struct led_classdev *led_cdev) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ ++ if (phydev->attached_dev) ++ return &phydev->attached_dev->dev; ++ return NULL; ++} ++ ++static int __maybe_unused ++phy_led_hw_control_get(struct led_classdev *led_cdev, ++ unsigned long *rules) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules); ++ mutex_unlock(&phydev->lock); ++ ++ return err; ++} ++ ++static int __maybe_unused ++phy_led_hw_control_set(struct led_classdev *led_cdev, ++ unsigned long rules) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules); ++ mutex_unlock(&phydev->lock); ++ ++ return err; ++} ++ ++static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, ++ unsigned long rules) ++{ ++ struct phy_led *phyled = to_phy_led(led_cdev); ++ struct phy_device *phydev = phyled->phydev; ++ int err; ++ ++ mutex_lock(&phydev->lock); ++ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules); ++ mutex_unlock(&phydev->lock); ++ ++ return err; ++} ++ + static void phy_leds_unregister(struct phy_device *phydev) + { + struct phy_led *phyled; +@@ -3001,6 +3056,19 @@ static int of_phy_led(struct phy_device + cdev->brightness_set_blocking = phy_led_set_brightness; + if (phydev->drv->led_blink_set) + cdev->blink_set = phy_led_blink_set; ++ ++#ifdef CONFIG_LEDS_TRIGGERS ++ if (phydev->drv->led_hw_is_supported && ++ phydev->drv->led_hw_control_set && ++ phydev->drv->led_hw_control_get) { ++ cdev->hw_control_is_supported = phy_led_hw_is_supported; ++ cdev->hw_control_set = phy_led_hw_control_set; ++ cdev->hw_control_get = phy_led_hw_control_get; ++ cdev->hw_control_trigger = "netdev"; ++ } ++ ++ cdev->hw_control_get_device = phy_led_hw_control_get_device; ++#endif + cdev->max_brightness = 1; + init_data.devicename = dev_name(&phydev->mdio.dev); + init_data.fwnode = of_fwnode_handle(led); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -1013,6 +1013,39 @@ struct phy_driver { + int (*led_blink_set)(struct phy_device *dev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off); ++ /** ++ * @led_hw_is_supported: Can the HW support the given rules. ++ * @dev: PHY device which has the LED ++ * @index: Which LED of the PHY device ++ * @rules The core is interested in these rules ++ * ++ * Return 0 if yes, -EOPNOTSUPP if not, or an error code. ++ */ ++ int (*led_hw_is_supported)(struct phy_device *dev, u8 index, ++ unsigned long rules); ++ /** ++ * @led_hw_control_set: Set the HW to control the LED ++ * @dev: PHY device which has the LED ++ * @index: Which LED of the PHY device ++ * @rules The rules used to control the LED ++ * ++ * Returns 0, or a an error code. ++ */ ++ int (*led_hw_control_set)(struct phy_device *dev, u8 index, ++ unsigned long rules); ++ /** ++ * @led_hw_control_get: Get how the HW is controlling the LED ++ * @dev: PHY device which has the LED ++ * @index: Which LED of the PHY device ++ * @rules Pointer to the rules used to control the LED ++ * ++ * Set *@rules to how the HW is currently blinking. Returns 0 ++ * on success, or a error code if the current blinking cannot ++ * be represented in rules, or some other error happens. ++ */ ++ int (*led_hw_control_get)(struct phy_device *dev, u8 index, ++ unsigned long *rules); ++ + }; + #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ + struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch b/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch new file mode 100644 index 000000000..1300583b6 --- /dev/null +++ b/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch @@ -0,0 +1,344 @@ +From 460b0b648fab24f576c481424e0de5479ffb9786 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Tue, 8 Aug 2023 23:04:35 +0200 +Subject: [PATCH 3/4] net: phy: marvell: Add support for offloading LED + blinking + +Add the code needed to indicate if a given blinking pattern can be +offloaded, to offload a pattern and to try to return the current +pattern. + +Reviewed-by: Simon Horman +Signed-off-by: Andrew Lunn +Tested-by: Daniel Golle +Link: https://lore.kernel.org/r/20230808210436.838995-4-andrew@lunn.ch +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/marvell.c | 281 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 281 insertions(+) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -2893,6 +2893,272 @@ static int m88e1318_led_blink_set(struct + MII_88E1318S_PHY_LED_FUNC, reg); + } + ++struct marvell_led_rules { ++ int mode; ++ unsigned long rules; ++}; ++ ++static const struct marvell_led_rules marvell_led0[] = { ++ { ++ .mode = 0, ++ .rules = BIT(TRIGGER_NETDEV_LINK), ++ }, ++ { ++ .mode = 1, ++ .rules = (BIT(TRIGGER_NETDEV_LINK) | ++ BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 3, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 4, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 5, ++ .rules = BIT(TRIGGER_NETDEV_TX), ++ }, ++ { ++ .mode = 6, ++ .rules = BIT(TRIGGER_NETDEV_LINK), ++ }, ++ { ++ .mode = 7, ++ .rules = BIT(TRIGGER_NETDEV_LINK_1000), ++ }, ++ { ++ .mode = 8, ++ .rules = 0, ++ }, ++}; ++ ++static const struct marvell_led_rules marvell_led1[] = { ++ { ++ .mode = 1, ++ .rules = (BIT(TRIGGER_NETDEV_LINK) | ++ BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 2, ++ .rules = (BIT(TRIGGER_NETDEV_LINK) | ++ BIT(TRIGGER_NETDEV_RX)), ++ }, ++ { ++ .mode = 3, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 4, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 6, ++ .rules = (BIT(TRIGGER_NETDEV_LINK_100) | ++ BIT(TRIGGER_NETDEV_LINK_1000)), ++ }, ++ { ++ .mode = 7, ++ .rules = BIT(TRIGGER_NETDEV_LINK_100), ++ }, ++ { ++ .mode = 8, ++ .rules = 0, ++ }, ++}; ++ ++static const struct marvell_led_rules marvell_led2[] = { ++ { ++ .mode = 0, ++ .rules = BIT(TRIGGER_NETDEV_LINK), ++ }, ++ { ++ .mode = 1, ++ .rules = (BIT(TRIGGER_NETDEV_LINK) | ++ BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 3, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 4, ++ .rules = (BIT(TRIGGER_NETDEV_RX) | ++ BIT(TRIGGER_NETDEV_TX)), ++ }, ++ { ++ .mode = 5, ++ .rules = BIT(TRIGGER_NETDEV_TX), ++ }, ++ { ++ .mode = 6, ++ .rules = (BIT(TRIGGER_NETDEV_LINK_10) | ++ BIT(TRIGGER_NETDEV_LINK_1000)), ++ }, ++ { ++ .mode = 7, ++ .rules = BIT(TRIGGER_NETDEV_LINK_10), ++ }, ++ { ++ .mode = 8, ++ .rules = 0, ++ }, ++}; ++ ++static int marvell_find_led_mode(unsigned long rules, ++ const struct marvell_led_rules *marvell_rules, ++ int count, ++ int *mode) ++{ ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ if (marvell_rules[i].rules == rules) { ++ *mode = marvell_rules[i].mode; ++ return 0; ++ } ++ } ++ return -EOPNOTSUPP; ++} ++ ++static int marvell_get_led_mode(u8 index, unsigned long rules, int *mode) ++{ ++ int ret; ++ ++ switch (index) { ++ case 0: ++ ret = marvell_find_led_mode(rules, marvell_led0, ++ ARRAY_SIZE(marvell_led0), mode); ++ break; ++ case 1: ++ ret = marvell_find_led_mode(rules, marvell_led1, ++ ARRAY_SIZE(marvell_led1), mode); ++ break; ++ case 2: ++ ret = marvell_find_led_mode(rules, marvell_led2, ++ ARRAY_SIZE(marvell_led2), mode); ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int marvell_find_led_rules(unsigned long *rules, ++ const struct marvell_led_rules *marvell_rules, ++ int count, ++ int mode) ++{ ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ if (marvell_rules[i].mode == mode) { ++ *rules = marvell_rules[i].rules; ++ return 0; ++ } ++ } ++ return -EOPNOTSUPP; ++} ++ ++static int marvell_get_led_rules(u8 index, unsigned long *rules, int mode) ++{ ++ int ret; ++ ++ switch (index) { ++ case 0: ++ ret = marvell_find_led_rules(rules, marvell_led0, ++ ARRAY_SIZE(marvell_led0), mode); ++ break; ++ case 1: ++ ret = marvell_find_led_rules(rules, marvell_led1, ++ ARRAY_SIZE(marvell_led1), mode); ++ break; ++ case 2: ++ ret = marvell_find_led_rules(rules, marvell_led2, ++ ARRAY_SIZE(marvell_led2), mode); ++ break; ++ default: ++ ret = -EOPNOTSUPP; ++ } ++ ++ return ret; ++} ++ ++static int m88e1318_led_hw_is_supported(struct phy_device *phydev, u8 index, ++ unsigned long rules) ++{ ++ int mode, ret; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ ret = marvell_get_led_mode(index, rules, &mode); ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int m88e1318_led_hw_control_set(struct phy_device *phydev, u8 index, ++ unsigned long rules) ++{ ++ int mode, ret, reg; ++ ++ switch (index) { ++ case 0: ++ case 1: ++ case 2: ++ ret = marvell_get_led_mode(index, rules, &mode); ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ if (ret < 0) ++ return ret; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ reg &= ~(0xf << (4 * index)); ++ reg |= mode << (4 * index); ++ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC, reg); ++} ++ ++static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index, ++ unsigned long *rules) ++{ ++ int mode, reg; ++ ++ if (index > 2) ++ return -EINVAL; ++ ++ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, ++ MII_88E1318S_PHY_LED_FUNC); ++ if (reg < 0) ++ return reg; ++ ++ mode = (reg >> (4 * index)) & 0xf; ++ ++ return marvell_get_led_rules(index, rules, mode); ++} ++ + static int marvell_probe(struct phy_device *phydev) + { + struct marvell_priv *priv; +@@ -3144,6 +3410,9 @@ static struct phy_driver marvell_drivers + .get_stats = marvell_get_stats, + .led_brightness_set = m88e1318_led_brightness_set, + .led_blink_set = m88e1318_led_blink_set, ++ .led_hw_is_supported = m88e1318_led_hw_is_supported, ++ .led_hw_control_set = m88e1318_led_hw_control_set, ++ .led_hw_control_get = m88e1318_led_hw_control_get, + }, + { + .phy_id = MARVELL_PHY_ID_88E1145, +@@ -3252,6 +3521,9 @@ static struct phy_driver marvell_drivers + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, + .led_blink_set = m88e1318_led_blink_set, ++ .led_hw_is_supported = m88e1318_led_hw_is_supported, ++ .led_hw_control_set = m88e1318_led_hw_control_set, ++ .led_hw_control_get = m88e1318_led_hw_control_get, + }, + { + .phy_id = MARVELL_PHY_ID_88E1540, +@@ -3280,6 +3552,9 @@ static struct phy_driver marvell_drivers + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, + .led_blink_set = m88e1318_led_blink_set, ++ .led_hw_is_supported = m88e1318_led_hw_is_supported, ++ .led_hw_control_set = m88e1318_led_hw_control_set, ++ .led_hw_control_get = m88e1318_led_hw_control_get, + }, + { + .phy_id = MARVELL_PHY_ID_88E1545, +@@ -3308,6 +3583,9 @@ static struct phy_driver marvell_drivers + .cable_test_get_status = marvell_vct7_cable_test_get_status, + .led_brightness_set = m88e1318_led_brightness_set, + .led_blink_set = m88e1318_led_blink_set, ++ .led_hw_is_supported = m88e1318_led_hw_is_supported, ++ .led_hw_control_set = m88e1318_led_hw_control_set, ++ .led_hw_control_get = m88e1318_led_hw_control_get, + }, + { + .phy_id = MARVELL_PHY_ID_88E3016, +@@ -3451,6 +3729,9 @@ static struct phy_driver marvell_drivers + .set_tunable = m88e1540_set_tunable, + .led_brightness_set = m88e1318_led_brightness_set, + .led_blink_set = m88e1318_led_blink_set, ++ .led_hw_is_supported = m88e1318_led_hw_is_supported, ++ .led_hw_control_set = m88e1318_led_hw_control_set, ++ .led_hw_control_get = m88e1318_led_hw_control_get, + }, + }; + diff --git a/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch b/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch new file mode 100644 index 000000000..d6a69aa9c --- /dev/null +++ b/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch @@ -0,0 +1,31 @@ +From e8fbcc47a8e935f36f044d85f21a99acecbd7bfb Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Tue, 8 Aug 2023 23:04:36 +0200 +Subject: [PATCH 4/4] leds: trig-netdev: Disable offload on deactivation of + trigger + +Ensure that the offloading of blinking is stopped when the trigger is +deactivated. Calling led_set_brightness() is documented as stopping +offload and setting the LED to a constant brightness. + +Suggested-by: Daniel Golle +Signed-off-by: Andrew Lunn +Reviewed-by: Simon Horman +Tested-by: Daniel Golle +Link: https://lore.kernel.org/r/20230808210436.838995-5-andrew@lunn.ch +Signed-off-by: Jakub Kicinski +--- + drivers/leds/trigger/ledtrig-netdev.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -595,6 +595,8 @@ static void netdev_trig_deactivate(struc + + cancel_delayed_work_sync(&trigger_data->work); + ++ led_set_brightness(led_cdev, LED_OFF); ++ + dev_put(trigger_data->net_dev); + + kfree(trigger_data); diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 index 4ae77b8c7..726d40a5f 100644 --- a/target/linux/generic/config-5.10 +++ b/target/linux/generic/config-5.10 @@ -2120,6 +2120,7 @@ CONFIG_GPIO_SYSFS=y CONFIG_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY_FALLBACK is not set # CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_HARDEN_BRANCH_HISTORY=y CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_ARM_ARCH_TIMER is not set @@ -3340,8 +3341,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MICROCHIP_T1_PHY is not set # CONFIG_MICROSEMI_PHY is not set # CONFIG_MIGRATION is not set -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y CONFIG_MII=y # CONFIG_MIKROTIK is not set # CONFIG_MIKROTIK_RB532 is not set @@ -3372,6 +3371,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MISDN_NETJET is not set # CONFIG_MISDN_SPEEDFAX is not set # CONFIG_MISDN_W6692 is not set +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y # CONFIG_MKISS is not set # CONFIG_MLX4_CORE is not set # CONFIG_MLX4_EN is not set diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 8e9d9469a..7daac70a4 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -4018,6 +4018,7 @@ CONFIG_NET_CORE=y # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set # CONFIG_NET_DSA_MV88E6XXX_PTP is not set # CONFIG_NET_DSA_QCA8K is not set +# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set # CONFIG_NET_DSA_REALTEK_SMI is not set # CONFIG_NET_DSA_SJA1105 is not set # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set diff --git a/target/linux/generic/config-5.4 b/target/linux/generic/config-5.4 index eb83bd117..fa19816db 100644 --- a/target/linux/generic/config-5.4 +++ b/target/linux/generic/config-5.4 @@ -959,14 +959,14 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_AES_586 is not set # CONFIG_CRYPTO_AES_ARM is not set -# CONFIG_CRYPTO_AES_ARM_BS is not set -# CONFIG_CRYPTO_AES_ARM64_BS is not set -# CONFIG_CRYPTO_AES_ARM_CE is not set # CONFIG_CRYPTO_AES_ARM64 is not set +# CONFIG_CRYPTO_AES_ARM64_BS is not set # CONFIG_CRYPTO_AES_ARM64_CE is not set # CONFIG_CRYPTO_AES_ARM64_CE_BLK is not set # CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set # CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set +# CONFIG_CRYPTO_AES_ARM_BS is not set +# CONFIG_CRYPTO_AES_ARM_CE is not set # CONFIG_CRYPTO_AES_NI_INTEL is not set # CONFIG_CRYPTO_AES_TI is not set CONFIG_CRYPTO_ALGAPI=y @@ -996,8 +996,8 @@ CONFIG_CRYPTO_BLKCIPHER2=y # CONFIG_CRYPTO_CRC32C_INTEL is not set # CONFIG_CRYPTO_CRC32_ARM_CE is not set # CONFIG_CRYPTO_CRCT10DIF is not set -# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set # CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set +# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_CTR is not set # CONFIG_CRYPTO_CTS is not set @@ -1054,8 +1054,8 @@ CONFIG_CRYPTO_BLKCIPHER2=y # CONFIG_CRYPTO_GCM is not set # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_GHASH_ARM_CE is not set # CONFIG_CRYPTO_GHASH_ARM64_CE is not set +# CONFIG_CRYPTO_GHASH_ARM_CE is not set # CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set # CONFIG_CRYPTO_HASH is not set # CONFIG_CRYPTO_HMAC is not set @@ -1116,8 +1116,8 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA256_ARM is not set # CONFIG_CRYPTO_SHA256_ARM64 is not set -# CONFIG_CRYPTO_SHA2_ARM_CE is not set # CONFIG_CRYPTO_SHA2_ARM64_CE is not set +# CONFIG_CRYPTO_SHA2_ARM_CE is not set # CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_SHA3_ARM64 is not set # CONFIG_CRYPTO_SHA512 is not set @@ -2241,7 +2241,6 @@ CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_INA2XX_ADC is not set # CONFIG_INDIRECT_PIO is not set CONFIG_INET=y -CONFIG_INET_TABLE_PERTURB_ORDER=16 # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -2256,6 +2255,7 @@ CONFIG_INET_TABLE_PERTURB_ORDER=16 # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_LRO is not set +CONFIG_INET_TABLE_PERTURB_ORDER=16 # CONFIG_INET_TCP_DIAG is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_UDP_DIAG is not set diff --git a/target/linux/generic/hack-5.10/204-module_strip.patch b/target/linux/generic/hack-5.10/204-module_strip.patch index 17e34524c..1db015f68 100644 --- a/target/linux/generic/hack-5.10/204-module_strip.patch +++ b/target/linux/generic/hack-5.10/204-module_strip.patch @@ -104,7 +104,7 @@ Signed-off-by: Felix Fietkau config MODULES_TREE_LOOKUP --- a/kernel/module.c +++ b/kernel/module.c -@@ -3262,9 +3262,11 @@ static int setup_load_info(struct load_i +@@ -3254,9 +3254,11 @@ static int setup_load_info(struct load_i static int check_modinfo(struct module *mod, struct load_info *info, int flags) { @@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau if (flags & MODULE_INIT_IGNORE_VERMAGIC) modmagic = NULL; -@@ -3285,6 +3287,7 @@ static int check_modinfo(struct module * +@@ -3277,6 +3279,7 @@ static int check_modinfo(struct module * mod->name); add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); } diff --git a/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch index 8f6702e43..cea9bb000 100644 --- a/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch +++ b/target/linux/generic/hack-5.10/721-net-add-packet-mangeling.patch @@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau */ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2728,6 +2728,10 @@ static inline int pskb_trim(struct sk_bu +@@ -2743,6 +2743,10 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } @@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau /** * pskb_trim_unique - remove end from a paged unique (not cloned) buffer * @skb: buffer to alter -@@ -2859,16 +2863,6 @@ static inline struct sk_buff *dev_alloc_ +@@ -2874,16 +2878,6 @@ static inline struct sk_buff *dev_alloc_ } @@ -119,15 +119,15 @@ Signed-off-by: Felix Fietkau trace_net_dev_start_xmit(skb, dev); --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -60,6 +60,7 @@ - #include +@@ -61,6 +61,7 @@ #include #include + #include +#include #include #include -@@ -553,6 +554,22 @@ skb_fail: +@@ -554,6 +555,22 @@ skb_fail: } EXPORT_SYMBOL(__napi_alloc_skb); diff --git a/target/linux/generic/hack-5.10/902-debloat_proc.patch b/target/linux/generic/hack-5.10/902-debloat_proc.patch index 6dc608f2f..8bb572e42 100644 --- a/target/linux/generic/hack-5.10/902-debloat_proc.patch +++ b/target/linux/generic/hack-5.10/902-debloat_proc.patch @@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau --- a/fs/locks.c +++ b/fs/locks.c -@@ -3016,6 +3016,8 @@ static const struct seq_operations locks +@@ -3076,6 +3076,8 @@ static const struct seq_operations locks static int __init proc_locks_init(void) { @@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau } --- a/net/ipv4/route.c +++ b/net/ipv4/route.c -@@ -410,6 +410,9 @@ static struct pernet_operations ip_rt_pr +@@ -411,6 +411,9 @@ static struct pernet_operations ip_rt_pr static int __init ip_rt_proc_init(void) { diff --git a/target/linux/generic/hack-5.10/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-5.10/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index 11a15a6fe..2a76af106 100644 --- a/target/linux/generic/hack-5.10/953-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-5.10/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -12,9 +12,9 @@ struct list_head *br_ip_list); --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -866,6 +866,10 @@ struct sk_buff { +@@ -865,6 +865,10 @@ struct sk_buff { + #endif __u8 scm_io_uring:1; - __u8 gro_skip:1; +#ifdef CONFIG_SHORTCUT_FE + __u8 fast_forwarded:1; diff --git a/target/linux/generic/hack-5.15/250-netfilter_depends.patch b/target/linux/generic/hack-5.15/250-netfilter_depends.patch index d9a2b81d7..1f8af6dbe 100644 --- a/target/linux/generic/hack-5.15/250-netfilter_depends.patch +++ b/target/linux/generic/hack-5.15/250-netfilter_depends.patch @@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau depends on NETFILTER_ADVANCED help H.323 is a VoIP signalling protocol from ITU-T. As one of the most -@@ -1105,7 +1104,6 @@ config NETFILTER_XT_TARGET_SECMARK +@@ -1114,7 +1113,6 @@ config NETFILTER_XT_TARGET_SECMARK config NETFILTER_XT_TARGET_TCPMSS tristate '"TCPMSS" target support' diff --git a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch index 8225ae14f..9d569f0f4 100644 --- a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch +++ b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch @@ -77,7 +77,7 @@ Signed-off-by: Daniel Golle #include "mtdcore.h" -@@ -1006,6 +1007,8 @@ int mtd_device_parse_register(struct mtd +@@ -1008,6 +1009,8 @@ int mtd_device_parse_register(struct mtd register_reboot_notifier(&mtd->reboot_notifier); } diff --git a/target/linux/generic/hack-5.15/600-bridge_offload.patch b/target/linux/generic/hack-5.15/600-bridge_offload.patch index de02c5de2..61a8efdac 100644 --- a/target/linux/generic/hack-5.15/600-bridge_offload.patch +++ b/target/linux/generic/hack-5.15/600-bridge_offload.patch @@ -154,7 +154,7 @@ static int br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -171,6 +172,7 @@ int br_handle_frame_finish(struct net *n +@@ -176,6 +177,7 @@ int br_handle_frame_finish(struct net *n dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { @@ -162,7 +162,7 @@ if (!mcast_hit) br_flood(br, skb, pkt_type, local_rcv, false); else -@@ -304,6 +306,9 @@ static rx_handler_result_t br_handle_fra +@@ -309,6 +311,9 @@ static rx_handler_result_t br_handle_fra memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); p = br_port_get_rcu(skb->dev); @@ -661,7 +661,7 @@ #ifdef CONFIG_NET_SWITCHDEV /* Counter used to make sure that hardware domains get unique * identifiers in case a bridge spans multiple switchdev instances. -@@ -553,6 +569,10 @@ struct br_input_skb_cb { +@@ -554,6 +570,10 @@ struct br_input_skb_cb { #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE u8 br_netfilter_broute:1; #endif diff --git a/target/linux/generic/hack-5.15/601-of_net-add-mac-address-ascii-support.patch b/target/linux/generic/hack-5.15/601-of_net-add-mac-address-ascii-support.patch index 4ab05b4ea..6f61cde0d 100644 --- a/target/linux/generic/hack-5.15/601-of_net-add-mac-address-ascii-support.patch +++ b/target/linux/generic/hack-5.15/601-of_net-add-mac-address-ascii-support.patch @@ -11,7 +11,7 @@ Submitted-by: Yousong Zhou --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c -@@ -538,6 +538,63 @@ int eth_platform_get_mac_address(struct +@@ -527,6 +527,63 @@ int eth_platform_get_mac_address(struct } EXPORT_SYMBOL(eth_platform_get_mac_address); @@ -75,7 +75,7 @@ Submitted-by: Yousong Zhou /** * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named * 'mac-address' associated with given device. -@@ -551,19 +608,23 @@ int nvmem_get_mac_address(struct device +@@ -540,19 +597,23 @@ int nvmem_get_mac_address(struct device { struct nvmem_cell *cell; const void *mac; diff --git a/target/linux/generic/hack-5.15/640-bridge-only-accept-EAP-locally.patch b/target/linux/generic/hack-5.15/640-bridge-only-accept-EAP-locally.patch index 7ae96b43d..875657883 100644 --- a/target/linux/generic/hack-5.15/640-bridge-only-accept-EAP-locally.patch +++ b/target/linux/generic/hack-5.15/640-bridge-only-accept-EAP-locally.patch @@ -12,14 +12,14 @@ Signed-off-by: Etienne Champetier --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -116,10 +116,14 @@ int br_handle_frame_finish(struct net *n +@@ -121,10 +121,14 @@ int br_handle_frame_finish(struct net *n } } + BR_INPUT_SKB_CB(skb)->brdev = br->dev; + + if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack) -+ return br_pass_frame_up(skb); ++ return br_pass_frame_up(skb,false); + if (state == BR_STATE_LEARNING) goto drop; diff --git a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch index 49f339bdd..d22b9f909 100644 --- a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch +++ b/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch @@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau help This option adds the flow table core infrastructure. -@@ -1010,6 +1009,15 @@ config NETFILTER_XT_TARGET_NOTRACK +@@ -1019,6 +1018,15 @@ config NETFILTER_XT_TARGET_NOTRACK depends on NETFILTER_ADVANCED select NETFILTER_XT_TARGET_CT @@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau depends on NETFILTER_ADVANCED --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile -@@ -143,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF +@@ -144,6 +144,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o diff --git a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch index 48be44002..9d77efaca 100644 --- a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch +++ b/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -61,6 +61,80 @@ config SFP +@@ -62,6 +62,80 @@ config SFP depends on HWMON || HWMON=n select MDIO_I2C diff --git a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch index 328814c6a..ee26704f1 100644 --- a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch +++ b/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch @@ -1,6 +1,6 @@ --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -2997,6 +2997,9 @@ static int mv88e6xxx_setup_port(struct m +@@ -3007,6 +3007,9 @@ static int mv88e6xxx_setup_port(struct m else reg = 1 << port; diff --git a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch index 3f971d654..550e45b42 100644 --- a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch +++ b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch @@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau */ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2855,6 +2855,10 @@ static inline int pskb_trim(struct sk_bu +@@ -2870,6 +2870,10 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } @@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau /** * pskb_trim_unique - remove end from a paged unique (not cloned) buffer * @skb: buffer to alter -@@ -3005,16 +3009,6 @@ static inline struct sk_buff *dev_alloc_ +@@ -3020,16 +3024,6 @@ static inline struct sk_buff *dev_alloc_ } diff --git a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch index 75c2e41fb..b4ed6c991 100644 --- a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch @@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support #define QUECTEL_VENDOR_ID 0x2c7c /* These Quectel products use Quectel's vendor ID */ -@@ -1152,6 +1157,11 @@ static const struct usb_device_id option +@@ -1156,6 +1161,11 @@ static const struct usb_device_id option { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, @@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support /* Quectel products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1193,6 +1203,11 @@ static const struct usb_device_id option +@@ -1197,6 +1207,11 @@ static const struct usb_device_id option .driver_info = ZLP }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = RSVD(4) }, diff --git a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch b/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch index 3e05241cd..2d1992edb 100644 --- a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch +++ b/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch @@ -1,6 +1,6 @@ --- a/include/linux/phylink.h +++ b/include/linux/phylink.h -@@ -585,10 +585,37 @@ int phylink_speed_up(struct phylink *pl) +@@ -601,10 +601,37 @@ int phylink_speed_up(struct phylink *pl) void phylink_set_port_modes(unsigned long *bits); void phylink_set_10g_modes(unsigned long *mask); @@ -40,7 +40,7 @@ const unsigned long *advertising); --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -896,7 +896,6 @@ static int phylink_change_inband_advert( +@@ -942,7 +942,6 @@ static int phylink_change_inband_advert( return 0; } @@ -48,7 +48,7 @@ static void phylink_mac_pcs_get_state(struct phylink *pl, struct phylink_link_state *state) { -@@ -2978,6 +2977,52 @@ void phylink_mii_c22_pcs_get_state(struc +@@ -3026,6 +3025,52 @@ void phylink_mii_c22_pcs_get_state(struc EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state); /** @@ -101,7 +101,7 @@ * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS * advertisement * @pcs: a pointer to a &struct mdio_device. -@@ -3049,6 +3094,46 @@ int phylink_mii_c22_pcs_set_advertisemen +@@ -3097,6 +3142,46 @@ int phylink_mii_c22_pcs_set_advertisemen EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement); /** diff --git a/target/linux/generic/hack-5.15/902-debloat_proc.patch b/target/linux/generic/hack-5.15/902-debloat_proc.patch index c7e40dfc6..4404d3456 100644 --- a/target/linux/generic/hack-5.15/902-debloat_proc.patch +++ b/target/linux/generic/hack-5.15/902-debloat_proc.patch @@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau } --- a/net/ipv4/route.c +++ b/net/ipv4/route.c -@@ -387,6 +387,9 @@ static struct pernet_operations ip_rt_pr +@@ -388,6 +388,9 @@ static struct pernet_operations ip_rt_pr static int __init ip_rt_proc_init(void) { diff --git a/target/linux/generic/hack-5.15/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-5.15/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index a185f603f..99567b52a 100644 --- a/target/linux/generic/hack-5.15/953-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-5.15/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -12,7 +12,7 @@ struct list_head *br_ip_list); --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -916,6 +916,10 @@ struct sk_buff { +@@ -915,6 +915,10 @@ struct sk_buff { __u8 slow_gro:1; __u8 scm_io_uring:1; diff --git a/target/linux/generic/hack-5.4/550-loop-Report-EOPNOTSUPP-properly.patch b/target/linux/generic/hack-5.4/550-loop-Report-EOPNOTSUPP-properly.patch index 29a8d84e4..16a7bcd68 100644 --- a/target/linux/generic/hack-5.4/550-loop-Report-EOPNOTSUPP-properly.patch +++ b/target/linux/generic/hack-5.4/550-loop-Report-EOPNOTSUPP-properly.patch @@ -18,7 +18,7 @@ Reviewed-by: Bart Van Assche --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -462,7 +462,7 @@ static void lo_complete_rq(struct reques +@@ -468,7 +468,7 @@ static void lo_complete_rq(struct reques if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) || req_op(rq) != REQ_OP_READ) { if (cmd->ret < 0) @@ -27,7 +27,7 @@ Reviewed-by: Bart Van Assche goto end_io; } -@@ -1978,7 +1978,10 @@ static void loop_handle_cmd(struct loop_ +@@ -2001,7 +2001,10 @@ static void loop_handle_cmd(struct loop_ failed: /* complete non-aio request */ if (!cmd->use_aio || ret) { diff --git a/target/linux/generic/hack-5.4/721-phy_packets.patch b/target/linux/generic/hack-5.4/721-phy_packets.patch index 89d5b965a..2336bcdee 100644 --- a/target/linux/generic/hack-5.4/721-phy_packets.patch +++ b/target/linux/generic/hack-5.4/721-phy_packets.patch @@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau */ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2695,6 +2695,10 @@ static inline int pskb_trim(struct sk_bu +@@ -2710,6 +2710,10 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } @@ -67,7 +67,7 @@ Signed-off-by: Felix Fietkau /** * pskb_trim_unique - remove end from a paged unique (not cloned) buffer * @skb: buffer to alter -@@ -2826,16 +2830,6 @@ static inline struct sk_buff *dev_alloc_ +@@ -2841,16 +2845,6 @@ static inline struct sk_buff *dev_alloc_ } diff --git a/target/linux/generic/hack-5.4/902-debloat_proc.patch b/target/linux/generic/hack-5.4/902-debloat_proc.patch index c980dfe41..8cbedc629 100644 --- a/target/linux/generic/hack-5.4/902-debloat_proc.patch +++ b/target/linux/generic/hack-5.4/902-debloat_proc.patch @@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau } --- a/net/ipv4/route.c +++ b/net/ipv4/route.c -@@ -410,6 +410,9 @@ static struct pernet_operations ip_rt_pr +@@ -411,6 +411,9 @@ static struct pernet_operations ip_rt_pr static int __init ip_rt_proc_init(void) { diff --git a/target/linux/generic/hack-5.4/995-usb-serial-option-add-ec200a.patch b/target/linux/generic/hack-5.4/995-usb-serial-option-add-ec200a.patch index 684e85e21..71b05f073 100644 --- a/target/linux/generic/hack-5.4/995-usb-serial-option-add-ec200a.patch +++ b/target/linux/generic/hack-5.4/995-usb-serial-option-add-ec200a.patch @@ -1,6 +1,6 @@ --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c -@@ -278,6 +278,7 @@ static void option_instat_callback(struc +@@ -282,6 +282,7 @@ static void option_instat_callback(struc #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 #define QUECTEL_PRODUCT_EC200T 0x6026 @@ -8,7 +8,7 @@ #define QUECTEL_PRODUCT_RM500K 0x7001 #define CMOTECH_VENDOR_ID 0x16d8 -@@ -1246,6 +1247,7 @@ static const struct usb_device_id option +@@ -1267,6 +1268,7 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, diff --git a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch index 48be44002..5f49678a3 100644 --- a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch +++ b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -61,6 +61,80 @@ config SFP +@@ -69,6 +69,80 @@ config SFP depends on HWMON || HWMON=n select MDIO_I2C diff --git a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch index 94b7d7f75..6a46b4c9a 100644 --- a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch @@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -7123,7 +7123,7 @@ static void __ref alloc_node_mem_map(str +@@ -7125,7 +7125,7 @@ static void __ref alloc_node_mem_map(str if (pgdat == NODE_DATA(0)) { mem_map = NODE_DATA(0)->node_mem_map; if (page_to_pfn(mem_map) != pgdat->node_start_pfn) diff --git a/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch index c1e050e93..8b1e70bd0 100644 --- a/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch +++ b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch @@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau for (i = sizeof(struct ipt_entry); i < e->target_offset; i += m->u.match_size) { -@@ -1222,12 +1259,15 @@ compat_copy_entry_to_user(struct ipt_ent +@@ -1226,12 +1263,15 @@ compat_copy_entry_to_user(struct ipt_ent compat_uint_t origsize; const struct xt_entry_match *ematch; int ret = 0; diff --git a/target/linux/generic/pending-5.10/630-packet_socket_type.patch b/target/linux/generic/pending-5.10/630-packet_socket_type.patch index 1f21ced0a..3f5f461e7 100644 --- a/target/linux/generic/pending-5.10/630-packet_socket_type.patch +++ b/target/linux/generic/pending-5.10/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3346,6 +3348,7 @@ static int packet_create(struct net *net +@@ -3345,6 +3347,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3986,6 +3989,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3985,6 +3988,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4042,6 +4055,13 @@ static int packet_getsockopt(struct sock +@@ -4041,6 +4054,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-5.10/655-increase_skb_pad.patch b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch index dafafad58..c94563a6a 100644 --- a/target/linux/generic/pending-5.10/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2694,7 +2694,7 @@ static inline int pskb_network_may_pull( +@@ -2709,7 +2709,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD diff --git a/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch index 7beabef9a..ef22be2b6 100644 --- a/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -110,7 +110,7 @@ Signed-off-by: Jonas Gorski return -EINVAL; --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -95,6 +95,8 @@ static int ip6_pkt_discard(struct sk_bu +@@ -96,6 +96,8 @@ static int ip6_pkt_discard(struct sk_bu static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); static int ip6_pkt_prohibit(struct sk_buff *skb); static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); @@ -119,7 +119,7 @@ Signed-off-by: Jonas Gorski static void ip6_link_failure(struct sk_buff *skb); static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, -@@ -310,6 +312,18 @@ static const struct rt6_info ip6_prohibi +@@ -311,6 +313,18 @@ static const struct rt6_info ip6_prohibi .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), }; @@ -138,7 +138,7 @@ Signed-off-by: Jonas Gorski static const struct rt6_info ip6_blk_hole_entry_template = { .dst = { .__refcnt = ATOMIC_INIT(1), -@@ -1031,6 +1045,7 @@ static const int fib6_prop[RTN_MAX + 1] +@@ -1032,6 +1046,7 @@ static const int fib6_prop[RTN_MAX + 1] [RTN_BLACKHOLE] = -EINVAL, [RTN_UNREACHABLE] = -EHOSTUNREACH, [RTN_PROHIBIT] = -EACCES, @@ -146,7 +146,7 @@ Signed-off-by: Jonas Gorski [RTN_THROW] = -EAGAIN, [RTN_NAT] = -EINVAL, [RTN_XRESOLVE] = -EINVAL, -@@ -1066,6 +1081,10 @@ static void ip6_rt_init_dst_reject(struc +@@ -1067,6 +1082,10 @@ static void ip6_rt_init_dst_reject(struc rt->dst.output = ip6_pkt_prohibit_out; rt->dst.input = ip6_pkt_prohibit; break; @@ -157,7 +157,7 @@ Signed-off-by: Jonas Gorski case RTN_THROW: case RTN_UNREACHABLE: default: -@@ -4446,6 +4465,17 @@ static int ip6_pkt_prohibit_out(struct n +@@ -4450,6 +4469,17 @@ static int ip6_pkt_prohibit_out(struct n return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); } @@ -175,7 +175,7 @@ Signed-off-by: Jonas Gorski /* * Allocate a dst for local (unicast / anycast) address. */ -@@ -4933,7 +4963,8 @@ static int rtm_to_fib6_config(struct sk_ +@@ -4937,7 +4967,8 @@ static int rtm_to_fib6_config(struct sk_ if (rtm->rtm_type == RTN_UNREACHABLE || rtm->rtm_type == RTN_BLACKHOLE || rtm->rtm_type == RTN_PROHIBIT || @@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski cfg->fc_flags |= RTF_REJECT; if (rtm->rtm_type == RTN_LOCAL) -@@ -6126,6 +6157,8 @@ static int ip6_route_dev_notify(struct n +@@ -6130,6 +6161,8 @@ static int ip6_route_dev_notify(struct n #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry->dst.dev = dev; net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); @@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.dev = dev; net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); #endif -@@ -6137,6 +6170,7 @@ static int ip6_route_dev_notify(struct n +@@ -6141,6 +6174,7 @@ static int ip6_route_dev_notify(struct n in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); @@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); #endif } -@@ -6328,6 +6362,8 @@ static int __net_init ip6_route_net_init +@@ -6332,6 +6366,8 @@ static int __net_init ip6_route_net_init #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.fib6_has_custom_rules = false; @@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, sizeof(*net->ipv6.ip6_prohibit_entry), GFP_KERNEL); -@@ -6338,11 +6374,21 @@ static int __net_init ip6_route_net_init +@@ -6342,11 +6378,21 @@ static int __net_init ip6_route_net_init ip6_template_metrics, true); INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); @@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, ip6_template_metrics, true); -@@ -6369,6 +6415,8 @@ out: +@@ -6373,6 +6419,8 @@ out: return ret; #ifdef CONFIG_IPV6_MULTIPLE_TABLES @@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski out_ip6_prohibit_entry: kfree(net->ipv6.ip6_prohibit_entry); out_ip6_null_entry: -@@ -6388,6 +6436,7 @@ static void __net_exit ip6_route_net_exi +@@ -6392,6 +6440,7 @@ static void __net_exit ip6_route_net_exi kfree(net->ipv6.ip6_null_entry); #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); @@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski kfree(net->ipv6.ip6_blk_hole_entry); #endif dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -6471,6 +6520,9 @@ void __init ip6_route_init_special_entri +@@ -6475,6 +6524,9 @@ void __init ip6_route_init_special_entri init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); diff --git a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index ceaf1e99f..8b06c2ca2 100644 --- a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -22,14 +22,14 @@ Signed-off-by: Felix Fietkau #endif --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -864,6 +864,7 @@ struct sk_buff { - __u8 decrypted:1; - #endif - __u8 scm_io_uring:1; -+ __u8 gro_skip:1; - +@@ -868,6 +868,7 @@ struct sk_buff { #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ + #endif ++ __u8 gro_skip:1; + + union { + __wsum csum; --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6081,6 +6081,9 @@ static enum gro_result dev_gro_receive(s @@ -136,14 +136,13 @@ Signed-off-by: Felix Fietkau /** * eth_type_trans - determine the packet's protocol ID. * @skb: received socket data -@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk - } else { - skb->pkt_type = PACKET_OTHERHOST; - } -+ -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; - } +@@ -166,6 +178,9 @@ __be16 eth_type_trans(struct sk_buff *sk + eth_skb_pkt_type(skb, dev); + ++ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, ++ dev->local_addr_mask)) ++ skb->gro_skip = 1; /* + * Some variants of DSA tagging don't have an ethertype field + * at all, so we check here whether one of those tagging diff --git a/target/linux/generic/pending-5.10/701-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch b/target/linux/generic/pending-5.10/701-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch deleted file mode 100644 index d9015d480..000000000 --- a/target/linux/generic/pending-5.10/701-01-arm64-dts-mediatek-mt7622-add-support-for-coherent-D.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Mon, 7 Feb 2022 10:27:22 +0100 -Subject: [PATCH] arm64: dts: mediatek: mt7622: add support for coherent - DMA - -It improves performance by eliminating the need for a cache flush on rx and tx - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -357,7 +357,7 @@ - }; - - cci_control2: slave-if@5000 { -- compatible = "arm,cci-400-ctrl-if"; -+ compatible = "arm,cci-400-ctrl-if", "syscon"; - interface-type = "ace"; - reg = <0x5000 0x1000>; - }; -@@ -937,6 +937,8 @@ - power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; - mediatek,ethsys = <ðsys>; - mediatek,sgmiisys = <&sgmiisys>; -+ mediatek,cci-control = <&cci_control2>; -+ dma-coherent; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; diff --git a/target/linux/generic/pending-5.10/701-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch b/target/linux/generic/pending-5.10/701-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch deleted file mode 100644 index f59a364a7..000000000 --- a/target/linux/generic/pending-5.10/701-04-arm64-dts-mediatek-mt7622-introduce-nodes-for-Wirele.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Felix Fietkau -Date: Sat, 5 Feb 2022 18:36:36 +0100 -Subject: [PATCH] arm64: dts: mediatek: mt7622: introduce nodes for - Wireless Ethernet Dispatch - -Introduce wed0 and wed1 nodes in order to enable offloading forwarding -between ethernet and wireless devices on the mt7622 chipset. - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -893,6 +893,11 @@ - }; - }; - -+ hifsys: syscon@1af00000 { -+ compatible = "mediatek,mt7622-hifsys", "syscon"; -+ reg = <0 0x1af00000 0 0x70>; -+ }; -+ - ethsys: syscon@1b000000 { - compatible = "mediatek,mt7622-ethsys", - "syscon"; -@@ -911,6 +916,26 @@ - #dma-cells = <1>; - }; - -+ pcie_mirror: pcie-mirror@10000400 { -+ compatible = "mediatek,mt7622-pcie-mirror", -+ "syscon"; -+ reg = <0 0x10000400 0 0x10>; -+ }; -+ -+ wed0: wed@1020a000 { -+ compatible = "mediatek,mt7622-wed", -+ "syscon"; -+ reg = <0 0x1020a000 0 0x1000>; -+ interrupts = ; -+ }; -+ -+ wed1: wed@1020b000 { -+ compatible = "mediatek,mt7622-wed", -+ "syscon"; -+ reg = <0 0x1020b000 0 0x1000>; -+ interrupts = ; -+ }; -+ - eth: ethernet@1b100000 { - compatible = "mediatek,mt7622-eth", - "mediatek,mt2701-eth", -@@ -938,6 +963,9 @@ - mediatek,ethsys = <ðsys>; - mediatek,sgmiisys = <&sgmiisys>; - mediatek,cci-control = <&cci_control2>; -+ mediatek,wed = <&wed0>, <&wed1>; -+ mediatek,pcie-mirror = <&pcie_mirror>; -+ mediatek,hifsys = <&hifsys>; - dma-coherent; - #address-cells = <1>; - #size-cells = <0>; diff --git a/target/linux/generic/pending-5.10/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch b/target/linux/generic/pending-5.10/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch index 278a0b7e8..d64e334af 100644 --- a/target/linux/generic/pending-5.10/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch +++ b/target/linux/generic/pending-5.10/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch @@ -17,7 +17,7 @@ Signed-off-by: Alexander Duyck --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -4176,6 +4176,15 @@ int skb_gro_receive(struct sk_buff *p, s +@@ -4188,6 +4188,15 @@ int skb_gro_receive(struct sk_buff *p, s if (unlikely(p->len + len >= 65536 || NAPI_GRO_CB(skb)->flush)) return -E2BIG; diff --git a/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch index 2a70e4cba..195968eee 100644 --- a/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch +++ b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch @@ -25,7 +25,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c -@@ -206,6 +206,7 @@ static void quirk_mmio_always_on(struct +@@ -207,6 +207,7 @@ static void quirk_mmio_always_on(struct DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); @@ -33,7 +33,7 @@ Signed-off-by: Gabor Juhos /* * The Mellanox Tavor device gives false positive parity errors. Mark this * device with a broken_parity_status to allow PCI scanning code to "skip" -@@ -3340,6 +3341,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I +@@ -3341,6 +3342,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); @@ -42,7 +42,7 @@ Signed-off-by: Gabor Juhos /* * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. * To work around this, query the size it should be configured to by the -@@ -3365,6 +3368,8 @@ static void quirk_intel_ntb(struct pci_d +@@ -3366,6 +3369,8 @@ static void quirk_intel_ntb(struct pci_d DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); @@ -51,7 +51,7 @@ Signed-off-by: Gabor Juhos /* * Some BIOS implementations leave the Intel GPU interrupts enabled, even * though no one is handling them (e.g., if the i915 driver is never -@@ -3403,6 +3408,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN +@@ -3404,6 +3409,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); diff --git a/target/linux/generic/pending-5.10/920-mangle_bootargs.patch b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch index 72a5ca4d2..79db26c27 100644 --- a/target/linux/generic/pending-5.10/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -866,6 +889,7 @@ asmlinkage __visible void __init __no_sa +@@ -868,6 +891,7 @@ asmlinkage __visible void __init __no_sa pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch index 9968a7969..a64d3021d 100644 --- a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch +++ b/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch @@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -204,6 +204,9 @@ static void __br_handle_local_finish(str +@@ -209,6 +209,9 @@ static void __br_handle_local_finish(str /* note: already called with rcu_read_lock */ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau __br_handle_local_finish(skb); /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -369,6 +372,17 @@ static rx_handler_result_t br_handle_fra +@@ -376,6 +379,17 @@ static rx_handler_result_t br_handle_fra forward: switch (p->state) { diff --git a/target/linux/generic/pending-5.15/495-mtd-core-add-get_mtd_device_by_node.patch b/target/linux/generic/pending-5.15/495-mtd-core-add-get_mtd_device_by_node.patch index 4c9bdccb1..ec35f4716 100644 --- a/target/linux/generic/pending-5.15/495-mtd-core-add-get_mtd_device_by_node.patch +++ b/target/linux/generic/pending-5.15/495-mtd-core-add-get_mtd_device_by_node.patch @@ -17,7 +17,7 @@ Reviewed-by: Miquel Raynal --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c -@@ -1240,6 +1240,44 @@ out_unlock: +@@ -1242,6 +1242,44 @@ out_unlock: } EXPORT_SYMBOL_GPL(get_mtd_device_nm); diff --git a/target/linux/generic/pending-5.15/630-packet_socket_type.patch b/target/linux/generic/pending-5.15/630-packet_socket_type.patch index c36e9e9fb..486ba9dee 100644 --- a/target/linux/generic/pending-5.15/630-packet_socket_type.patch +++ b/target/linux/generic/pending-5.15/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3346,6 +3348,7 @@ static int packet_create(struct net *net +@@ -3345,6 +3347,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3983,6 +3986,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3982,6 +3985,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4039,6 +4052,13 @@ static int packet_getsockopt(struct sock +@@ -4038,6 +4051,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch index 5d100270a..e9075f43c 100644 --- a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2821,7 +2821,7 @@ static inline int pskb_network_may_pull( +@@ -2836,7 +2836,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD diff --git a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch index 4c97d8b9e..d4e274e9a 100644 --- a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ b/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -110,7 +110,7 @@ Signed-off-by: Jonas Gorski return -EINVAL; --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -97,6 +97,8 @@ static int ip6_pkt_discard(struct sk_bu +@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_bu static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); static int ip6_pkt_prohibit(struct sk_buff *skb); static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); @@ -119,7 +119,7 @@ Signed-off-by: Jonas Gorski static void ip6_link_failure(struct sk_buff *skb); static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, -@@ -312,6 +314,18 @@ static const struct rt6_info ip6_prohibi +@@ -313,6 +315,18 @@ static const struct rt6_info ip6_prohibi .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), }; @@ -138,7 +138,7 @@ Signed-off-by: Jonas Gorski static const struct rt6_info ip6_blk_hole_entry_template = { .dst = { .__refcnt = ATOMIC_INIT(1), -@@ -1033,6 +1047,7 @@ static const int fib6_prop[RTN_MAX + 1] +@@ -1034,6 +1048,7 @@ static const int fib6_prop[RTN_MAX + 1] [RTN_BLACKHOLE] = -EINVAL, [RTN_UNREACHABLE] = -EHOSTUNREACH, [RTN_PROHIBIT] = -EACCES, @@ -146,7 +146,7 @@ Signed-off-by: Jonas Gorski [RTN_THROW] = -EAGAIN, [RTN_NAT] = -EINVAL, [RTN_XRESOLVE] = -EINVAL, -@@ -1068,6 +1083,10 @@ static void ip6_rt_init_dst_reject(struc +@@ -1069,6 +1084,10 @@ static void ip6_rt_init_dst_reject(struc rt->dst.output = ip6_pkt_prohibit_out; rt->dst.input = ip6_pkt_prohibit; break; @@ -157,7 +157,7 @@ Signed-off-by: Jonas Gorski case RTN_THROW: case RTN_UNREACHABLE: default: -@@ -4557,6 +4576,17 @@ static int ip6_pkt_prohibit_out(struct n +@@ -4561,6 +4580,17 @@ static int ip6_pkt_prohibit_out(struct n return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); } @@ -175,7 +175,7 @@ Signed-off-by: Jonas Gorski /* * Allocate a dst for local (unicast / anycast) address. */ -@@ -5044,7 +5074,8 @@ static int rtm_to_fib6_config(struct sk_ +@@ -5048,7 +5078,8 @@ static int rtm_to_fib6_config(struct sk_ if (rtm->rtm_type == RTN_UNREACHABLE || rtm->rtm_type == RTN_BLACKHOLE || rtm->rtm_type == RTN_PROHIBIT || @@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski cfg->fc_flags |= RTF_REJECT; if (rtm->rtm_type == RTN_LOCAL) -@@ -6291,6 +6322,8 @@ static int ip6_route_dev_notify(struct n +@@ -6295,6 +6326,8 @@ static int ip6_route_dev_notify(struct n #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry->dst.dev = dev; net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); @@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.dev = dev; net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); #endif -@@ -6302,6 +6335,7 @@ static int ip6_route_dev_notify(struct n +@@ -6306,6 +6339,7 @@ static int ip6_route_dev_notify(struct n in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); @@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); #endif } -@@ -6493,6 +6527,8 @@ static int __net_init ip6_route_net_init +@@ -6497,6 +6531,8 @@ static int __net_init ip6_route_net_init #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.fib6_has_custom_rules = false; @@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, sizeof(*net->ipv6.ip6_prohibit_entry), GFP_KERNEL); -@@ -6503,11 +6539,21 @@ static int __net_init ip6_route_net_init +@@ -6507,11 +6543,21 @@ static int __net_init ip6_route_net_init ip6_template_metrics, true); INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); @@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, ip6_template_metrics, true); -@@ -6534,6 +6580,8 @@ out: +@@ -6538,6 +6584,8 @@ out: return ret; #ifdef CONFIG_IPV6_MULTIPLE_TABLES @@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski out_ip6_prohibit_entry: kfree(net->ipv6.ip6_prohibit_entry); out_ip6_null_entry: -@@ -6553,6 +6601,7 @@ static void __net_exit ip6_route_net_exi +@@ -6557,6 +6605,7 @@ static void __net_exit ip6_route_net_exi kfree(net->ipv6.ip6_null_entry); #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); @@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski kfree(net->ipv6.ip6_blk_hole_entry); #endif dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -6636,6 +6685,9 @@ void __init ip6_route_init_special_entri +@@ -6640,6 +6689,9 @@ void __init ip6_route_init_special_entri init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); diff --git a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index 8cb8eeb3c..d2f0168a1 100644 --- a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -22,14 +22,14 @@ Signed-off-by: Felix Fietkau #endif --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -893,6 +893,7 @@ struct sk_buff { - #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2; +@@ -918,6 +918,7 @@ struct sk_buff { + #ifdef CONFIG_NET_SCHED + __u16 tc_index; /* traffic control index */ #endif + __u8 gro_skip:1; - __u8 ipvs_property:1; - __u8 inner_protocol_type:1; + union { + __wsum csum; --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6092,6 +6092,9 @@ static enum gro_result dev_gro_receive(s @@ -136,14 +136,13 @@ Signed-off-by: Felix Fietkau /** * eth_type_trans - determine the packet's protocol ID. * @skb: received socket data -@@ -173,6 +185,10 @@ __be16 eth_type_trans(struct sk_buff *sk - } else { - skb->pkt_type = PACKET_OTHERHOST; - } -+ -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; - } +@@ -165,6 +177,9 @@ __be16 eth_type_trans(struct sk_buff *sk + eth_skb_pkt_type(skb, dev); + ++ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, ++ dev->local_addr_mask)) ++ skb->gro_skip = 1; /* + * Some variants of DSA tagging don't have an ethertype field + * at all, so we check here whether one of those tagging diff --git a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch index 8c7555403..ba75e4a0f 100644 --- a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +++ b/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch @@ -10,9 +10,9 @@ Signed-off-by: Pablo Neira Ayuso --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c -@@ -606,13 +606,41 @@ void nf_flow_table_free(struct nf_flowta - } - EXPORT_SYMBOL_GPL(nf_flow_table_free); +@@ -651,6 +651,23 @@ static struct pernet_operations nf_flow_ + .exit_batch = nf_flow_table_pernet_exit, + }; +static int nf_flow_table_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) @@ -33,26 +33,30 @@ Signed-off-by: Pablo Neira Ayuso + static int __init nf_flow_table_module_init(void) { -- return nf_flow_table_offload_init(); -+ int ret; -+ -+ ret = nf_flow_table_offload_init(); -+ if (ret) -+ return ret; -+ + int ret; +@@ -663,8 +680,14 @@ static int __init nf_flow_table_module_i + if (ret) + goto out_offload; + + ret = register_netdevice_notifier(&flow_offload_netdev_notifier); + if (ret) -+ nf_flow_table_offload_exit(); ++ goto out_offload_init; + -+ return ret; - } + return 0; + ++out_offload_init: ++ nf_flow_table_offload_exit(); + out_offload: + unregister_pernet_subsys(&nf_flow_table_net_ops); + return ret; +@@ -672,6 +695,7 @@ out_offload: static void __exit nf_flow_table_module_exit(void) { + unregister_netdevice_notifier(&flow_offload_netdev_notifier); nf_flow_table_offload_exit(); + unregister_pernet_subsys(&nf_flow_table_net_ops); } - --- a/net/netfilter/nft_flow_offload.c +++ b/net/netfilter/nft_flow_offload.c @@ -455,47 +455,14 @@ static struct nft_expr_type nft_flow_off diff --git a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch index fefe5fedc..9b5d9798a 100644 --- a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2994,8 +2994,8 @@ static irqreturn_t mtk_handle_irq_rx(int +@@ -3097,8 +3097,8 @@ static irqreturn_t mtk_handle_irq_rx(int eth->rx_events++; if (likely(napi_schedule_prep(ð->rx_napi))) { @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -3007,8 +3007,8 @@ static irqreturn_t mtk_handle_irq_tx(int +@@ -3110,8 +3110,8 @@ static irqreturn_t mtk_handle_irq_tx(int eth->tx_events++; if (likely(napi_schedule_prep(ð->tx_napi))) { @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -4668,6 +4668,8 @@ static int mtk_probe(struct platform_dev +@@ -4885,6 +4885,8 @@ static int mtk_probe(struct platform_dev * for NAPI to work */ init_dummy_netdev(ð->dummy_dev); diff --git a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch index 5baccf73c..83587b5c9 100644 --- a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1748,6 +1748,9 @@ void phy_detach(struct phy_device *phyde +@@ -1751,6 +1751,9 @@ void phy_detach(struct phy_device *phyde struct module *ndev_owner = NULL; struct mii_bus *bus; @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos sysfs_remove_link(&dev->dev.kobj, "phydev"); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -823,6 +823,12 @@ struct phy_driver { +@@ -843,6 +843,12 @@ struct phy_driver { /** @handle_interrupt: Override default interrupt handling */ irqreturn_t (*handle_interrupt)(struct phy_device *phydev); diff --git a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index bbbebefdd..fd1b79cdf 100644 --- a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -326,6 +326,8 @@ static rx_handler_result_t br_handle_fra +@@ -331,6 +331,8 @@ static rx_handler_result_t br_handle_fra fwd_mask |= p->group_fwd_mask; switch (dest[5]) { case 0x00: /* Bridge Group Address */ diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch index 9ae65b871..792135b0d 100644 --- a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -15,16 +15,7 @@ Signed-off-by: Alexander Couzens --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2628,7 +2628,7 @@ mt7531_setup(struct dsa_switch *ds) - struct mt7530_priv *priv = ds->priv; - struct mt7530_dummy_poll p; - u32 val, id; -- int ret; -+ int ret, i; - - /* Reset whole chip through gpio pin or memory-mapped registers for - * different type of hardware -@@ -2660,6 +2660,10 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2680,6 +2680,10 @@ mt7531_setup(struct dsa_switch *ds) return -ENODEV; } diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch new file mode 100644 index 000000000..1d84ea9ce --- /dev/null +++ b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch @@ -0,0 +1,44 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 23:39:52 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code + on mt7621 + +Avoid some branches in the hot path on low-end devices with limited CPU power, +and reduce code size + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1323,6 +1323,22 @@ struct mtk_mac { + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; + ++#ifdef CONFIG_SOC_MT7621 ++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) ++{ ++ return true; ++} ++ ++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) ++{ ++ return false; ++} ++ ++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) ++{ ++ return false; ++} ++#else + static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) + { + return eth->soc->version == 1; +@@ -1337,6 +1353,7 @@ static inline bool mtk_is_netsys_v3_or_g + { + return eth->soc->version > 2; + } ++#endif + + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) diff --git a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch index 57162ffe0..9df011fbe 100644 --- a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ b/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1422,12 +1422,28 @@ static void mtk_wake_queue(struct mtk_et +@@ -1515,12 +1515,28 @@ static void mtk_wake_queue(struct mtk_et } } @@ -45,11 +45,11 @@ Signed-off-by: Felix Fietkau bool gso = false; int tx_num; -@@ -1449,6 +1465,18 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1542,6 +1558,18 @@ static netdev_tx_t mtk_start_xmit(struct return NETDEV_TX_BUSY; } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ if (mtk_is_netsys_v1(eth) && + skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { + segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); + if (IS_ERR(segs)) @@ -64,14 +64,14 @@ Signed-off-by: Felix Fietkau /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { -@@ -1464,8 +1492,14 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1557,8 +1585,14 @@ static netdev_tx_t mtk_start_xmit(struct } } - if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) - goto drop; + skb_list_walk_safe(skb, skb, next) { -+ if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ if ((mtk_is_netsys_v1(eth) && + mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || + mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { + stats->tx_dropped++; @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau netif_tx_stop_all_queues(dev); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -258,7 +258,7 @@ +@@ -268,7 +268,7 @@ #define MTK_CHK_DDONE_EN BIT(28) #define MTK_DMAD_WR_WDONE BIT(26) #define MTK_WCOMP_EN BIT(24) diff --git a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch index 3c6359ee4..11a81dd0b 100644 --- a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -48,8 +48,7 @@ +@@ -47,8 +47,7 @@ #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ NETIF_F_RXCSUM | \ NETIF_F_HW_VLAN_CTAG_TX | \ diff --git a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch index 07ed67ce6..243e2f9d0 100644 --- a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch +++ b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -666,6 +666,7 @@ static void mtk_mac_link_up(struct phyli +@@ -722,6 +722,7 @@ static void mtk_mac_link_up(struct phyli MAC_MCR_FORCE_RX_FC); /* Configure speed */ @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau switch (speed) { case SPEED_2500: case SPEED_1000: -@@ -3147,6 +3148,9 @@ found: +@@ -3290,6 +3291,9 @@ found: if (dp->index >= MTK_QDMA_NUM_QUEUES) return NOTIFY_DONE; diff --git a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch index 9ef65ec16..104ce00b7 100644 --- a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch +++ b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau #include #include "mtk_eth_soc.h" #include "mtk_ppe.h" -@@ -757,7 +758,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -781,7 +782,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) goto out; diff --git a/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch index 1340d64ce..ba2db7c72 100644 --- a/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch +++ b/target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1277,6 +1277,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk +@@ -1448,6 +1448,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk int mtk_eth_offload_init(struct mtk_eth *eth); int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data); @@ -120,7 +120,7 @@ Signed-off-by: Felix Fietkau static void wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) { -@@ -1752,6 +1759,99 @@ out: +@@ -1760,6 +1767,99 @@ out: mutex_unlock(&hw_lock); } @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, void __iomem *wdma, phys_addr_t wdma_phy, int index) -@@ -1771,6 +1871,7 @@ void mtk_wed_add_hw(struct device_node * +@@ -1779,6 +1879,7 @@ void mtk_wed_add_hw(struct device_node * .irq_set_mask = mtk_wed_irq_set_mask, .detach = mtk_wed_detach, .ppe_check = mtk_wed_ppe_check, diff --git a/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch index 6e17e4dc5..e89d4cd97 100644 --- a/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch +++ b/target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -639,10 +639,20 @@ void mtk_foe_entry_clear(struct mtk_ppe +@@ -663,10 +663,20 @@ void mtk_foe_entry_clear(struct mtk_ppe static int mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { diff --git a/target/linux/generic/pending-5.15/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/pending-5.15/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch index 29d6e0b09..c8be7a9e2 100644 --- a/target/linux/generic/pending-5.15/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch +++ b/target/linux/generic/pending-5.15/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -466,42 +466,43 @@ int mtk_foe_entry_set_queue(struct mtk_e +@@ -483,42 +483,43 @@ int mtk_foe_entry_set_queue(struct mtk_e return 0; } @@ -72,7 +72,7 @@ Signed-off-by: Felix Fietkau struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -520,7 +521,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp +@@ -538,7 +539,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) return; @@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau kfree(entry); } -@@ -536,66 +538,55 @@ static int __mtk_foe_entry_idle_time(str +@@ -554,66 +556,55 @@ static int __mtk_foe_entry_idle_time(str return now - timestamp; } @@ -178,7 +178,7 @@ Signed-off-by: Felix Fietkau } static void -@@ -632,7 +623,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -656,7 +647,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { spin_lock_bh(&ppe_lock); @@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau spin_unlock_bh(&ppe_lock); } -@@ -679,8 +671,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ +@@ -703,8 +695,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ { const struct mtk_soc_data *soc = ppe->eth->soc; struct mtk_flow_entry *flow_info; @@ -198,7 +198,7 @@ Signed-off-by: Felix Fietkau u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; int type; -@@ -688,30 +680,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ +@@ -712,30 +704,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ if (!flow_info) return; @@ -239,7 +239,7 @@ Signed-off-by: Felix Fietkau } void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -721,9 +713,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -745,9 +737,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); struct mtk_flow_entry *entry; struct mtk_foe_bridge key = {}; @@ -251,7 +251,7 @@ Signed-off-by: Felix Fietkau u8 *tag; spin_lock_bh(&ppe_lock); -@@ -731,20 +725,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -755,20 +749,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) goto out; @@ -278,7 +278,7 @@ Signed-off-by: Felix Fietkau continue; } -@@ -795,9 +783,17 @@ out: +@@ -819,9 +807,17 @@ out: int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { @@ -300,7 +300,7 @@ Signed-off-by: Felix Fietkau int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -265,7 +265,12 @@ enum { +@@ -286,7 +286,12 @@ enum { struct mtk_flow_entry { union { @@ -314,7 +314,7 @@ Signed-off-by: Felix Fietkau struct { struct rhash_head l2_node; struct hlist_head l2_flows; -@@ -275,13 +280,7 @@ struct mtk_flow_entry { +@@ -296,13 +301,7 @@ struct mtk_flow_entry { s8 wed_index; u8 ppe_index; u16 hash; diff --git a/target/linux/generic/pending-5.15/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/pending-5.15/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch index dcc39ae42..bf543464c 100644 --- a/target/linux/generic/pending-5.15/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch +++ b/target/linux/generic/pending-5.15/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch @@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau if (ret) dev_err(ppe->dev, "MIB table busy"); -@@ -90,18 +90,32 @@ static int mtk_ppe_mib_wait_busy(struct +@@ -90,17 +90,31 @@ static int mtk_ppe_mib_wait_busy(struct return ret; } @@ -43,7 +43,6 @@ Signed-off-by: Felix Fietkau + +struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) { - u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; u32 val, cnt_r0, cnt_r1, cnt_r2; + struct mtk_foe_accounting *acct; int ret; @@ -62,25 +61,35 @@ Signed-off-by: Felix Fietkau cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -111,10 +125,11 @@ static int mtk_mib_entry_read(struct mtk - byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; +@@ -109,19 +123,19 @@ static int mtk_mib_entry_read(struct mtk + if (mtk_is_netsys_v3_or_greater(ppe->eth)) { + /* 64 bit for each counter */ + u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); +- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; +- *packets = ((u64)cnt_r3 << 32) | cnt_r2; ++ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; ++ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; + } else { + /* 48 bit byte counter, 40 bit packet counter */ + u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); + u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); + u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); + u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); +- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; +- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; + } - return 0; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; -+ + return acct; } static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -508,13 +523,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 &= ~MTK_FOE_IB1_STATE; +@@ -526,13 +540,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); dma_wmb(); + mtk_ppe_cache_clear(ppe); - if (ppe->accounting) { - struct mtk_foe_accounting *acct; - @@ -91,7 +100,7 @@ Signed-off-by: Felix Fietkau } entry->hash = 0xffff; -@@ -539,11 +547,14 @@ static int __mtk_foe_entry_idle_time(str +@@ -557,11 +564,14 @@ static int __mtk_foe_entry_idle_time(str } static bool @@ -107,7 +116,7 @@ Signed-off-by: Felix Fietkau int len; if (hash == 0xffff) -@@ -554,18 +565,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp +@@ -572,18 +582,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp memcpy(&foe, hwe, len); if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || @@ -146,7 +155,7 @@ Signed-off-by: Felix Fietkau struct mtk_flow_entry *cur; struct hlist_node *tmp; int idle; -@@ -574,7 +602,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe +@@ -592,7 +619,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { int cur_idle; @@ -157,7 +166,7 @@ Signed-off-by: Felix Fietkau __mtk_foe_entry_clear(ppe, entry, false); continue; } -@@ -589,10 +619,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe +@@ -607,10 +636,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe } } @@ -187,7 +196,7 @@ Signed-off-by: Felix Fietkau struct mtk_eth *eth = ppe->eth; u16 timestamp = mtk_eth_timestamp(eth); struct mtk_foe_entry *hwe; -@@ -617,6 +666,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -641,6 +689,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p dma_wmb(); @@ -200,7 +209,7 @@ Signed-off-by: Felix Fietkau mtk_ppe_cache_clear(ppe); } -@@ -781,21 +836,6 @@ out: +@@ -805,21 +859,6 @@ out: spin_unlock_bh(&ppe_lock); } @@ -222,7 +231,7 @@ Signed-off-by: Felix Fietkau int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) { if (!ppe) -@@ -823,32 +863,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe +@@ -847,32 +886,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe return mtk_ppe_wait_busy(ppe); } @@ -257,7 +266,7 @@ Signed-off-by: Felix Fietkau bool accounting = eth->soc->has_accounting; --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -283,6 +283,8 @@ struct mtk_flow_entry { +@@ -304,6 +304,8 @@ struct mtk_flow_entry { struct mtk_foe_entry data; struct rhash_head node; unsigned long cookie; @@ -266,7 +275,7 @@ Signed-off-by: Felix Fietkau }; struct mtk_mib_entry { -@@ -325,6 +327,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -347,6 +349,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); @@ -274,7 +283,7 @@ Signed-off-by: Felix Fietkau void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); -@@ -373,9 +376,8 @@ int mtk_foe_entry_set_queue(struct mtk_e +@@ -395,9 +398,8 @@ int mtk_foe_entry_set_queue(struct mtk_e unsigned int queue); int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); @@ -295,7 +304,7 @@ Signed-off-by: Felix Fietkau - acct = mtk_foe_entry_get_mib(ppe, i, NULL); + acct = mtk_ppe_mib_entry_read(ppe, i); - type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); + type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); seq_printf(m, "%05x %s %7s", i, --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c diff --git a/target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch b/target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch deleted file mode 100644 index 6e77ea7e0..000000000 --- a/target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:13 +0000 -Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability - bit - -Introduce MTK_NETSYS_V1 bit in the device capabilities for -MT7621/MT7622/MT7623/MT7628/MT7629 SoCs. -Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++--------- - 2 files changed, 41 insertions(+), 34 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -596,7 +596,7 @@ static void mtk_set_queue_speed(struct m - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - - if (IS_ENABLED(CONFIG_SOC_MT7621)) { -@@ -973,7 +973,7 @@ static bool mtk_rx_get_desc(struct mtk_e - rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); - rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); - rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); - rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); - } -@@ -1031,7 +1031,7 @@ static int mtk_init_fq_dma(struct mtk_et - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -1220,7 +1220,7 @@ static void mtk_tx_set_dma_desc(struct n - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - mtk_tx_set_dma_desc_v2(dev, txd, info); - else - mtk_tx_set_dma_desc_v1(dev, txd, info); -@@ -1901,7 +1901,7 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -@@ -1997,7 +1997,7 @@ static int mtk_poll_rx(struct napi_struc - skb->dev = netdev; - bytes += skb->len; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) -@@ -2022,7 +2022,7 @@ static int mtk_poll_rx(struct napi_struc - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) && - (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { - unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - -@@ -2327,7 +2327,7 @@ static int mtk_tx_alloc(struct mtk_eth * - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -2380,7 +2380,7 @@ static int mtk_tx_alloc(struct mtk_eth * - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - ofs += MTK_QTX_OFFSET; -@@ -2514,7 +2514,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - rxd->rxd3 = 0; - rxd->rxd4 = 0; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - rxd->rxd5 = 0; - rxd->rxd6 = 0; - rxd->rxd7 = 0; -@@ -3065,7 +3065,7 @@ static int mtk_start_dma(struct mtk_eth - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; -@@ -3477,7 +3477,7 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); - val = RSTCTRL_PPE0_V2; - } else { -@@ -3489,7 +3489,7 @@ static void mtk_hw_reset(struct mtk_eth - - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3685,7 +3685,7 @@ static int mtk_hw_init(struct mtk_eth *e - else - mtk_hw_reset(eth); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); -@@ -3722,7 +3722,7 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -816,6 +816,7 @@ enum mkt_eth_capabilities { - MTK_SHARED_INT_BIT, - MTK_TRGMII_MT7621_CLK_BIT, - MTK_QDMA_BIT, -+ MTK_NETSYS_V1_BIT, - MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -@@ -851,6 +852,7 @@ enum mkt_eth_capabilities { - #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) - #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) - #define MTK_QDMA BIT(MTK_QDMA_BIT) -+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -@@ -913,25 +915,30 @@ enum mkt_eth_capabilities { - - #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x)) - --#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -- MTK_GMAC2_RGMII | MTK_SHARED_INT | \ -- MTK_TRGMII_MT7621_CLK | MTK_QDMA) -- --#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \ -- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \ -- MTK_MUX_GDM1_TO_GMAC1_ESW | \ -- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA) -- --#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \ -- MTK_QDMA) -- --#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628) -- --#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ -- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \ -- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \ -- MTK_MUX_U3_GMAC2_TO_QPHY | \ -- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) -+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \ -+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \ -+ MTK_NETSYS_V1) -+ -+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \ -+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \ -+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\ -+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \ -+ MTK_QDMA | MTK_NETSYS_V1) -+ -+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -+ MTK_GMAC2_RGMII | MTK_QDMA | \ -+ MTK_NETSYS_V1) -+ -+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \ -+ MTK_NETSYS_V1) -+ -+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \ -+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \ -+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\ -+ MTK_MUX_GDM1_TO_GMAC1_ESW | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII) - - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ diff --git a/target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch b/target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch deleted file mode 100644 index 53d957dff..000000000 --- a/target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:24 +0000 -Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data - -This is a preliminary patch to add MT7988 SoC support since it runs 3 -macs instead of 2. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++---- - 2 files changed, 36 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3974,7 +3974,10 @@ static void mtk_sgmii_destroy(struct mtk - { - int i; - -- for (i = 0; i < MTK_MAX_DEVS; i++) -+ if (!eth->sgmii_pcs) -+ return; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) - mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]); - } - -@@ -4427,7 +4430,12 @@ static int mtk_sgmii_init(struct mtk_eth - u32 flags; - int i; - -- for (i = 0; i < MTK_MAX_DEVS; i++) { -+ eth->sgmii_pcs = devm_kzalloc(eth->dev, -+ sizeof(*eth->sgmii_pcs) * -+ eth->soc->num_devs, -+ GFP_KERNEL); -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { - np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i); - if (!np) - break; -@@ -4472,6 +4480,18 @@ static int mtk_probe(struct platform_dev - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - eth->ip_align = NET_IP_ALIGN; - -+ eth->netdev = devm_kzalloc(eth->dev, -+ sizeof(*eth->netdev) * eth->soc->num_devs, -+ GFP_KERNEL); -+ if (!eth->netdev) -+ return -ENOMEM; -+ -+ eth->mac = devm_kzalloc(eth->dev, -+ sizeof(*eth->mac) * eth->soc->num_devs, -+ GFP_KERNEL); -+ if (!eth->mac) -+ return -ENOMEM; -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); -@@ -4657,7 +4677,7 @@ static int mtk_probe(struct platform_dev - goto err_free_dev; - } - -- for (i = 0; i < MTK_MAX_DEVS; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - if (!eth->netdev[i]) - continue; - -@@ -4734,6 +4754,7 @@ static const struct mtk_soc_data mt2701_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4752,6 +4773,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 1, - .hash_offset = 2, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4773,6 +4795,7 @@ static const struct mtk_soc_data mt7622_ - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4792,6 +4815,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 1, - .hash_offset = 2, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4811,6 +4835,7 @@ static const struct mtk_soc_data mt7629_ - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, - .has_accounting = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4832,6 +4857,7 @@ static const struct mtk_soc_data mt7981_ - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4851,6 +4877,7 @@ static const struct mtk_soc_data mt7986_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, - .txrx = { -@@ -4869,6 +4896,7 @@ static const struct mtk_soc_data rt5350_ - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, - .required_pctl = false, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1018,6 +1018,7 @@ struct mtk_reg_map { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. -+ * @num_devs SoC number of macs. - * @foe_entry_size Foe table entry size. - * @has_accounting Bool indicating support for accounting of - * offloaded flows. -@@ -1036,6 +1037,7 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - u8 hash_offset; -+ u8 num_devs; - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -@@ -1051,9 +1053,6 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - --/* currently no SoC has more than 2 macs */ --#define MTK_MAX_DEVS 2 -- - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1108,14 +1107,14 @@ struct mtk_eth { - spinlock_t tx_irq_lock; - spinlock_t rx_irq_lock; - struct net_device dummy_dev; -- struct net_device *netdev[MTK_MAX_DEVS]; -- struct mtk_mac *mac[MTK_MAX_DEVS]; -+ struct net_device **netdev; -+ struct mtk_mac **mac; - int irq[3]; - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; - struct regmap *infra; -- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; -+ struct phylink_pcs **sgmii_pcs; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; diff --git a/target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch b/target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch deleted file mode 100644 index 2e547cbe9..000000000 --- a/target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch +++ /dev/null @@ -1,495 +0,0 @@ -From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 25 Feb 2023 00:08:24 +0100 -Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC - -Introduce support for ethernet chip available in MT7988 SoC to -mtk_eth_soc driver. ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------ - 2 files changed, 279 insertions(+), 67 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r - .pse_oq_sta = 0x01a0, - }; - -+static const struct mtk_reg_map mt7988_reg_map = { -+ .tx_irq_mask = 0x461c, -+ .tx_irq_status = 0x4618, -+ .pdma = { -+ .rx_ptr = 0x6900, -+ .rx_cnt_cfg = 0x6904, -+ .pcrx_ptr = 0x6908, -+ .glo_cfg = 0x6a04, -+ .rst_idx = 0x6a08, -+ .delay_irq = 0x6a0c, -+ .irq_status = 0x6a20, -+ .irq_mask = 0x6a28, -+ .adma_rx_dbg0 = 0x6a38, -+ .int_grp = 0x6a50, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, -+ .rx_ptr = 0x4500, -+ .rx_cnt_cfg = 0x4504, -+ .qcrx_ptr = 0x4508, -+ .glo_cfg = 0x4604, -+ .rst_idx = 0x4608, -+ .delay_irq = 0x460c, -+ .fc_th = 0x4610, -+ .int_grp = 0x4620, -+ .hred = 0x4644, -+ .ctx_ptr = 0x4700, -+ .dtx_ptr = 0x4704, -+ .crx_ptr = 0x4710, -+ .drx_ptr = 0x4714, -+ .fq_head = 0x4720, -+ .fq_tail = 0x4724, -+ .fq_count = 0x4728, -+ .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, -+ }, -+ .gdm1_cnt = 0x1c00, -+ .gdma_to_ppe0 = 0x3333, -+ .ppe_base = 0x2200, -+ .wdma_base = { -+ [0] = 0x4800, -+ [1] = 0x4c00, -+ }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { - }; - - static const char * const mtk_clks_source_name[] = { -- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", -- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", -- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", -- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" -+ "ethif", -+ "sgmiitop", -+ "esw", -+ "gp0", -+ "gp1", -+ "gp2", -+ "gp3", -+ "xgp1", -+ "xgp2", -+ "xgp3", -+ "crypto", -+ "fe", -+ "trgpll", -+ "sgmii_tx250m", -+ "sgmii_rx250m", -+ "sgmii_cdr_ref", -+ "sgmii_cdr_fb", -+ "sgmii2_tx250m", -+ "sgmii2_rx250m", -+ "sgmii2_cdr_ref", -+ "sgmii2_cdr_fb", -+ "sgmii_ck", -+ "eth2pll", -+ "wocpu0", -+ "wocpu1", -+ "netsys0", -+ "netsys1", -+ "ethwarp_wocpu2", -+ "ethwarp_wocpu1", -+ "ethwarp_wocpu0", -+ "top_usxgmii0_sel", -+ "top_usxgmii1_sel", -+ "top_sgm0_sel", -+ "top_sgm1_sel", -+ "top_xfi_phy0_xtal_sel", -+ "top_xfi_phy1_xtal_sel", -+ "top_eth_gmii_sel", -+ "top_eth_refck_50m_sel", -+ "top_eth_sys_200m_sel", -+ "top_eth_sys_sel", -+ "top_eth_xgmii_sel", -+ "top_eth_mii_sel", -+ "top_netsys_sel", -+ "top_netsys_500m_sel", -+ "top_netsys_pao_2x_sel", -+ "top_netsys_sync_250m_sel", -+ "top_netsys_ppefb_250m_sel", -+ "top_netsys_warp_sel", - }; - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -@@ -1206,10 +1298,19 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (mac->id == MTK_GMAC3_ID) -- data = PSE_GDM3_PORT; -- else -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ /* set forward port */ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC2_ID: -+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC3_ID: -+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ } -+ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -4959,6 +5060,25 @@ static const struct mtk_soc_data mt7986_ - }, - }; - -+static const struct mtk_soc_data mt7988_data = { -+ .reg_map = &mt7988_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7988_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7988_CLKS_BITMAP, -+ .required_pctl = false, -+ .num_devs = 3, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ -+ - static const struct mtk_soc_data rt5350_data = { - .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, -@@ -4977,14 +5097,15 @@ static const struct mtk_soc_data rt5350_ - }; - - const struct of_device_id of_mtk_match[] = { -- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, -- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, -- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, -- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, -- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, -- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, -- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, -+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, -+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, -+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, -+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, -+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, -+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, -+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, -+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, of_mtk_match); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -116,7 +116,8 @@ - #define MTK_CDMP_EG_CTRL 0x404 - - /* GDM Exgress Control Register */ --#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) -+#define MTK_GDMA_FWD_CFG(x) ((x == MTK_GMAC3_ID) ? \ -+ 0x540 : 0x500 + (x * 0x1000)) - #define MTK_GDMA_SPECIAL_TAG BIT(24) - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) -@@ -650,6 +651,11 @@ enum mtk_clks_map { - MTK_CLK_GP0, - MTK_CLK_GP1, - MTK_CLK_GP2, -+ MTK_CLK_GP3, -+ MTK_CLK_XGP1, -+ MTK_CLK_XGP2, -+ MTK_CLK_XGP3, -+ MTK_CLK_CRYPTO, - MTK_CLK_FE, - MTK_CLK_TRGPLL, - MTK_CLK_SGMII_TX_250M, -@@ -666,57 +672,108 @@ enum mtk_clks_map { - MTK_CLK_WOCPU1, - MTK_CLK_NETSYS0, - MTK_CLK_NETSYS1, -+ MTK_CLK_ETHWARP_WOCPU2, -+ MTK_CLK_ETHWARP_WOCPU1, -+ MTK_CLK_ETHWARP_WOCPU0, -+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, -+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, -+ MTK_CLK_TOP_SGM_0_SEL, -+ MTK_CLK_TOP_SGM_1_SEL, -+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, -+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, -+ MTK_CLK_TOP_ETH_GMII_SEL, -+ MTK_CLK_TOP_ETH_REFCK_50M_SEL, -+ MTK_CLK_TOP_ETH_SYS_200M_SEL, -+ MTK_CLK_TOP_ETH_SYS_SEL, -+ MTK_CLK_TOP_ETH_XGMII_SEL, -+ MTK_CLK_TOP_ETH_MII_SEL, -+ MTK_CLK_TOP_NETSYS_SEL, -+ MTK_CLK_TOP_NETSYS_500M_SEL, -+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, -+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, -+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, -+ MTK_CLK_TOP_NETSYS_WARP_SEL, - MTK_CLK_MAX - }; - --#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_TRGPLL)) --#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL)) -+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_TRGPLL)) -+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL)) - #define MT7621_CLKS_BITMAP (0) - #define MT7628_CLKS_BITMAP (0) --#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) --#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK)) --#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK)) -+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ -+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ -+ BIT_ULL(MTK_CLK_CRYPTO) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -844,6 +901,7 @@ enum mkt_eth_capabilities { - MTK_RGMII_BIT = 0, - MTK_TRGMII_BIT, - MTK_SGMII_BIT, -+ MTK_USXGMII_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -866,6 +924,8 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, - - /* PATH BITS */ - MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -874,13 +934,18 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, -+ MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -+ MTK_ETH_PATH_GMAC1_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC2_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC3_USXGMII_BIT, - }; - - /* Supported hardware group on SoCs */ - #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -907,6 +972,10 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) - - /* Supported path present on SoCs */ - #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -915,7 +984,11 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -923,7 +996,11 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) -+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) -+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) - - /* MUXes present on SoCs */ - /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -946,6 +1023,12 @@ enum mkt_eth_capabilities { - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - -+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) -+ -+#define MTK_MUX_GMAC123_TO_USXGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) -+ - #ifdef CONFIG_SOC_MT7621 - #define MTK_CAP_MASK MTK_NETSYS_V2 - #else -@@ -984,9 +1067,17 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ - MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) - --#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | \ -+ MTK_QDMA | MTK_NETSYS_V2 | \ -+ MTK_RSTCTRL_PPE1) -+ -+#define MT7988_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_GMAC3_SGMII | MTK_QDMA | \ -+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ -+ MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \ -+ MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \ -+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1072,7 +1163,7 @@ struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; - u64 caps; -- u32 required_clks; -+ u64 required_clks; - bool required_pctl; - u8 offload_version; - u8 hash_offset; diff --git a/target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch deleted file mode 100644 index fa8260aa7..000000000 --- a/target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ /dev/null @@ -1,1867 +0,0 @@ -From 3d833ad2cfc1ab503d9aae2967b7f10811bb3c9c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 1 Mar 2023 11:56:04 +0000 -Subject: [PATCH 7/7] net: ethernet: mtk_eth_soc: add paths and SerDes modes - for MT7988 - -MT7988 comes with a built-in 2.5G PHY as well as -USXGMII/10GBase-KR/5GBase-KR compatible SerDes lanes for external PHYs. -Add support for configuring the MAC and SerDes parts for the new paths. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/Kconfig | 7 + - drivers/net/ethernet/mediatek/Makefile | 1 + - drivers/net/ethernet/mediatek/mtk_eth_path.c | 154 +++- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 270 +++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 194 ++++- - drivers/net/ethernet/mediatek/mtk_usxgmii.c | 835 +++++++++++++++++++ - 6 files changed, 1428 insertions(+), 33 deletions(-) - create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -24,6 +24,13 @@ config NET_MEDIATEK_SOC - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. - -+config NET_MEDIATEK_SOC_USXGMII -+ bool "Support USXGMII SerDes on MT7988" -+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST -+ def_bool NET_MEDIATEK_SOC != n -+ help -+ Include support for 10G SerDes which can be found on MT7988. -+ - config NET_MEDIATEK_STAR_EMAC - tristate "MediaTek STAR Ethernet MAC support" - select PHYLIB ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,6 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 - return "gmac2_rgmii"; - case MTK_ETH_PATH_GMAC2_SGMII: - return "gmac2_sgmii"; -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ return "gmac2_2p5gphy"; - case MTK_ETH_PATH_GMAC2_GEPHY: - return "gmac2_gephy"; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ return "gmac3_sgmii"; - case MTK_ETH_PATH_GDM1_ESW: - return "gdm1_esw"; -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ return "gmac1_usxgmii"; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ return "gmac2_usxgmii"; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ return "gmac3_usxgmii"; - default: - return "unknown path"; - } -@@ -42,8 +52,8 @@ static const char *mtk_eth_path_name(u64 - - static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { -+ u32 val, mask, set, reg; - bool updated = true; -- u32 val, mask, set; - - switch (path) { - case MTK_ETH_PATH_GMAC1_SGMII: -@@ -59,10 +69,15 @@ static int set_mux_gdm1_to_gmac1_esw(str - break; - } - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) -+ reg = MTK_MAC_MISC_V3; -+ else -+ reg = MTK_MAC_MISC; -+ - if (updated) { -- val = mtk_r32(eth, MTK_MAC_MISC); -+ val = mtk_r32(eth, reg); - val = (val & mask) | set; -- mtk_w32(eth, val, MTK_MAC_MISC); -+ mtk_w32(eth, val, reg); - } - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", -@@ -125,6 +140,31 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - -+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ default: -+ updated = false; -+ break; -+ }; -+ -+ if (updated) -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ return 0; -+} -+ - static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; -@@ -163,7 +203,61 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) -+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ /* Disable SYSCFG1 SGMII */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; -+ mac_id = MTK_GMAC1_ID; -+ break; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; -+ mac_id = MTK_GMAC3_ID; -+ break; -+ default: -+ updated = false; -+ }; -+ -+ if (updated) { -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ mac_id == MTK_GMAC2_ID) { -+ regmap_update_bits(eth->infra, -+ TOP_MISC_NETSYS_PCS_MUX, -+ NETSYS_PCS_MUX_MASK, -+ MUX_G2_USXGMII_SEL); -+ } -+ } -+ -+ /* Enable XGDM Path */ -+ val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac_id)); -+ val |= MTK_GDMA_XGDM_SEL; -+ mtk_w32(eth, val, MTK_GDMA_EG_CTRL(mac_id)); -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ -+ return 0; -+} -+ -+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -180,6 +274,9 @@ static int set_mux_gmac12_to_gephy_sgmii - case MTK_ETH_PATH_GMAC2_SGMII: - val |= SYSCFG0_SGMII_GMAC2_V2; - break; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ val |= SYSCFG0_SGMII_GMAC3_V2; -+ break; - default: - updated = false; - } -@@ -208,13 +305,25 @@ static const struct mtk_eth_muxc mtk_eth - .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, - .set_path = set_mux_u3_gmac2_to_qphy, - }, { -+ .name = "mux_gmac2_to_2p5gphy", -+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, -+ .set_path = set_mux_gmac2_to_2p5gphy, -+ }, { - .name = "mux_gmac1_gmac2_to_sgmii_rgmii", - .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, - .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, - }, { - .name = "mux_gmac12_to_gephy_sgmii", - .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, -- .set_path = set_mux_gmac12_to_gephy_sgmii, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_gephy_sgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_usxgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, -+ .set_path = set_mux_gmac123_to_usxgmii, - }, - }; - -@@ -243,16 +352,46 @@ static int mtk_eth_mux_setup(struct mtk_ - } - } - -+ dev_dbg(eth->dev, "leaving mux_setup %s\n", -+ mtk_eth_path_name(path)); -+ - out: - return err; - } - -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path; -+ -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : -+ MTK_ETH_PATH_GMAC3_USXGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { - u64 path; - -- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : -- MTK_ETH_PATH_GMAC2_SGMII; -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : -+ MTK_ETH_PATH_GMAC3_SGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path = 0; -+ -+ if (mac_id == MTK_GMAC2_ID) -+ path = MTK_ETH_PATH_GMAC2_2P5GPHY; -+ -+ if (!path) -+ return -EINVAL; - - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); -@@ -282,4 +421,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); - } -- ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -437,6 +437,23 @@ static void mtk_gmac0_rgmii_adjust(struc - mtk_w32(eth, val, TRGMII_TCK_CTRL); - } - -+static void mtk_setup_bridge_switch(struct mtk_eth *eth) -+{ -+ int val; -+ -+ /* Force Port1 XGMAC Link Up */ -+ val = mtk_r32(eth, MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), -+ MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ -+ /* Adjust GSW bridge IPG to 11*/ -+ val = mtk_r32(eth, MTK_GSW_CFG); -+ val &= ~(GSWTX_IPG_MASK | GSWRX_IPG_MASK); -+ val |= (GSW_IPG_11 << GSWTX_IPG_SHIFT) | -+ (GSW_IPG_11 << GSWRX_IPG_SHIFT); -+ mtk_w32(eth, val, MTK_GSW_CFG); -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -451,6 +468,12 @@ static struct phylink_pcs *mtk_mac_selec - 0 : mac->id; - - return eth->sgmii_pcs[sid]; -+ } else if ((interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GKR || -+ interface == PHY_INTERFACE_MODE_5GBASER) && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ mac->id != MTK_GMAC1_ID) { -+ return mtk_usxgmii_select_pcs(eth, mac->id); - } - - return NULL; -@@ -462,7 +485,7 @@ static void mtk_mac_config(struct phylin - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); - struct mtk_eth *eth = mac->hw; -- int val, ge_mode, err = 0; -+ int val, ge_mode, force_link, err = 0; - u32 i; - - /* MT76x8 has no hardware settings between for the MAC */ -@@ -506,6 +529,23 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_5GBASER: -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; -+ case PHY_INTERFACE_MODE_INTERNAL: -+ if (mac->id == MTK_GMAC2_ID && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { -+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; - default: - goto err_phy; - } -@@ -584,14 +624,78 @@ static void mtk_mac_config(struct phylin - SYSCFG0_SGMII_MASK, - ~(u32)SYSCFG0_SGMII_MASK); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ mtk_xfi_pll_enable(eth); -+ mtk_sgmii_reset(eth, mac->id); -+ if (phylink_autoneg_inband(mode)) -+ mtk_sgmii_setup_phya_gen1(eth, mac->id); -+ else -+ mtk_sgmii_setup_phya_gen2(eth, mac->id); -+ } - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; -- } else if (phylink_autoneg_inband(mode)) { -+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && -+ state->interface != PHY_INTERFACE_MODE_10GKR && -+ state->interface != PHY_INTERFACE_MODE_5GBASER && -+ phylink_autoneg_inband(mode)) { - dev_err(eth->dev, -- "In-band mode not supported in non SGMII mode!\n"); -+ "In-band mode not supported in non-SerDes modes!\n"); - return; - } - -+ /* Setup gmac */ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ (mtk_interface_mode_is_xgmii(state->interface) || -+ mac->interface == PHY_INTERFACE_MODE_INTERNAL)) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ mtk_setup_bridge_switch(eth); -+ break; -+ case MTK_GMAC2_ID: -+ force_link = (mac->interface == -+ PHY_INTERFACE_MODE_INTERNAL) ? -+ MTK_XGMAC_FORCE_LINK(mac->id) : 0; -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, val | force_link, -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ case MTK_GMAC3_ID: -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(mac->id), -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ } -+ } else { -+ val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(eth, val & ~MTK_GDMA_XGDM_SEL, -+ MTK_GDMA_EG_CTRL(mac->id)); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (mac->id) { -+ case MTK_GMAC2_ID: -+ case MTK_GMAC3_ID: -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, -+ val & ~MTK_XGMAC_FORCE_LINK(mac->id), -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ } -+ } -+ -+/* -+ if (mac->type != mac_type) { -+ if (atomic_read(&reset_pending) == 0) { -+ atomic_inc(&force); -+ schedule_work(ð->pending_work); -+ atomic_inc(&reset_pending); -+ } else -+ atomic_dec(&reset_pending); -+ } -+*/ -+ } - return; - - err_phy: -@@ -631,11 +735,40 @@ static int mtk_mac_finish(struct phylink - return 0; - } - --static void mtk_mac_pcs_get_state(struct phylink_config *config, -+static void mtk_xgdm_pcs_get_state(struct mtk_mac *mac, -+ struct phylink_link_state *state) -+{ -+ u32 sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); -+ -+ if (mac->id == MTK_GMAC2_ID) -+ sts = sts >> 16; -+ -+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, sts); -+ if (!state->link) -+ return; -+ -+ state->duplex = DUPLEX_FULL; -+ state->interface = mac->interface; -+ -+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, sts)) { -+ case 0: -+ state->speed = SPEED_10000; -+ break; -+ case 1: -+ state->speed = SPEED_5000; -+ break; -+ case 2: -+ state->speed = SPEED_2500; -+ break; -+ case 3: -+ state->speed = SPEED_1000; -+ break; -+ } -+} -+ -+static void mtk_gdm_pcs_get_state(struct mtk_mac *mac, - struct phylink_link_state *state) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); - - state->link = (pmsr & MAC_MSR_LINK); -@@ -663,15 +796,35 @@ static void mtk_mac_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - -+static void mtk_mac_pcs_get_state(struct phylink_config *config, -+ struct phylink_link_state *state) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_interface_mode_is_xgmii(state->interface)) -+ mtk_xgdm_pcs_get_state(mac, state); -+ else -+ mtk_gdm_pcs_get_state(mac, state); -+} -+ - static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ u32 mcr; - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); -- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ if (!mtk_interface_mode_is_xgmii(interface)) { -+ mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN); -+ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ } else if (mac->id != MTK_GMAC1_ID) { -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ mcr &= 0xfffffff0; -+ mcr |= XMAC_MCR_TRX_DISABLE; -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+ } - } - - static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -@@ -743,13 +896,11 @@ static void mtk_set_queue_speed(struct m - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - } - --static void mtk_mac_link_up(struct phylink_config *config, -- struct phy_device *phy, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex, bool tx_pause, bool rx_pause) -+static void mtk_gdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 mcr; - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -@@ -783,6 +934,47 @@ static void mtk_mac_link_up(struct phyli - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ u32 mcr; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ return; -+ -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ -+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC); -+ /* Configure pause modes - -+ * phylink will avoid these for half duplex -+ */ -+ if (tx_pause) -+ mcr |= XMAC_MCR_FORCE_TX_FC; -+ if (rx_pause) -+ mcr |= XMAC_MCR_FORCE_RX_FC; -+ -+ mcr &= ~(XMAC_MCR_TRX_DISABLE); -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+} -+ -+static void mtk_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 mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ else -+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+} -+ - static const struct phylink_mac_ops mtk_phylink_ops = { - .validate = phylink_generic_validate, - .mac_select_pcs = mtk_mac_select_pcs, -@@ -835,10 +1027,21 @@ static int mtk_mdio_init(struct mtk_eth - } - divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); - -+ /* Configure MDC Turbo Mode */ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ val = mtk_r32(eth, MTK_MAC_MISC_V3); -+ val |= MISC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_MAC_MISC_V3); -+ } else { -+ val = mtk_r32(eth, MTK_PPSC); -+ val |= PPSC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_PPSC); -+ } -+ - /* Configure MDC Divider */ - val = mtk_r32(eth, MTK_PPSC); - val &= ~PPSC_MDC_CFG; -- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -+ val |= FIELD_PREP(PPSC_MDC_CFG, divider); - mtk_w32(eth, val, MTK_PPSC); - - dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); -@@ -4417,8 +4620,8 @@ static int mtk_add_mac(struct mtk_eth *e - const __be32 *_id = of_get_property(np, "reg", NULL); - phy_interface_t phy_mode; - struct phylink *phylink; -- struct mtk_mac *mac; - int id, err; -+ struct mtk_mac *mac; - int txqs = 1; - - if (!_id) { -@@ -4520,6 +4723,32 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.supported_interfaces); - } - -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { -+ if (id == MTK_GMAC1_ID) { -+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | -+ MAC_SYM_PAUSE | -+ MAC_10000FD; -+ phy_interface_zero( -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } else { -+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GKR, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ mac->phylink_config.supported_interfaces); -+ } -+ } -+ -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY)) { -+ if (id == MTK_GMAC2_ID) -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4707,6 +4936,13 @@ static int mtk_probe(struct platform_dev - - if (err) - return err; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_usxgmii_init(eth); -+ -+ if (err) -+ return err; - } - - if (eth->soc->required_pctl) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -126,6 +126,11 @@ - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -+/* GDM Egress Control Register */ -+#define MTK_GDMA_EG_CTRL(x) ((x == MTK_GMAC3_ID) ? \ -+ 0x544 : 0x504 + (x * 0x1000)) -+#define MTK_GDMA_XGDM_SEL BIT(31) -+ - /* Unicast Filter MAC Address Register - Low */ - #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) - -@@ -386,7 +391,26 @@ - #define PHY_IAC_TIMEOUT HZ - - #define MTK_MAC_MISC 0x1000c -+#define MTK_MAC_MISC_V3 0x10010 - #define MTK_MUX_TO_ESW BIT(0) -+#define MISC_MDC_TURBO BIT(4) -+ -+/* XMAC status registers */ -+#define MTK_XGMAC_STS(x) ((x == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) -+#define MTK_XGMAC_FORCE_LINK(x) ((x == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) -+#define MTK_USXGMII_PCS_LINK BIT(8) -+#define MTK_XGMAC_RX_FC BIT(5) -+#define MTK_XGMAC_TX_FC BIT(4) -+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) -+#define MTK_XGMAC_LINK_STS BIT(0) -+ -+/* GSW bridge registers */ -+#define MTK_GSW_CFG (0x10080) -+#define GSWTX_IPG_MASK GENMASK(19, 16) -+#define GSWTX_IPG_SHIFT 16 -+#define GSWRX_IPG_MASK GENMASK(3, 0) -+#define GSWRX_IPG_SHIFT 0 -+#define GSW_IPG_11 11 - - /* Mac control registers */ - #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) -@@ -411,6 +435,17 @@ - #define MAC_MCR_FORCE_LINK BIT(0) - #define MAC_MCR_FORCE_LINK_DOWN (MAC_MCR_FORCE_MODE) - -+/* Mac EEE control registers */ -+#define MTK_MAC_EEE(x) (0x10104 + (x * 0x100)) -+#define MAC_EEE_WAKEUP_TIME_1000 GENMASK(31, 24) -+#define MAC_EEE_WAKEUP_TIME_100 GENMASK(23, 16) -+#define MAC_EEE_LPI_TXIDLE_THD GENMASK(15, 8) -+#define MAC_EEE_RESV0 GENMASK(7, 4) -+#define MAC_EEE_CKG_TXILDE BIT(3) -+#define MAC_EEE_CKG_RXLPI BIT(2) -+#define MAC_EEE_TX_DOWN_REQ BIT(1) -+#define MAC_EEE_LPI_MODE BIT(0) -+ - /* Mac status registers */ - #define MTK_MAC_MSR(x) (0x10108 + (x * 0x100)) - #define MAC_MSR_EEE1G BIT(7) -@@ -455,6 +490,12 @@ - #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) - #define INTF_MODE_RGMII_10_100 0 - -+/* XFI Mac control registers */ -+#define MTK_XMAC_MCR(x) (0x12000 + ((x - 1) * 0x1000)) -+#define XMAC_MCR_TRX_DISABLE 0xf -+#define XMAC_MCR_FORCE_TX_FC BIT(5) -+#define XMAC_MCR_FORCE_RX_FC BIT(4) -+ - /* GPIO port control registers for GMAC 2*/ - #define GPIO_OD33_CTRL8 0x4c0 - #define GPIO_BIAS_CTRL 0xed0 -@@ -480,6 +521,7 @@ - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) - #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) -+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) - - - /* ethernet subsystem clock register */ -@@ -506,16 +548,91 @@ - #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - -+/* USXGMII subsystem config registers */ -+/* Register to control speed */ -+#define RG_PHY_TOP_SPEED_CTRL1 0x80C -+#define USXGMII_RATE_UPDATE_MODE BIT(31) -+#define USXGMII_MAC_CK_GATED BIT(29) -+#define USXGMII_IF_FORCE_EN BIT(28) -+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) -+#define USXGMII_RATE_ADAPT_MODE_X1 0 -+#define USXGMII_RATE_ADAPT_MODE_X2 1 -+#define USXGMII_RATE_ADAPT_MODE_X4 2 -+#define USXGMII_RATE_ADAPT_MODE_X10 3 -+#define USXGMII_RATE_ADAPT_MODE_X100 4 -+#define USXGMII_RATE_ADAPT_MODE_X5 5 -+#define USXGMII_RATE_ADAPT_MODE_X50 6 -+#define USXGMII_XFI_RX_MODE GENMASK(6, 4) -+#define USXGMII_XFI_RX_MODE_10G 0 -+#define USXGMII_XFI_RX_MODE_5G 1 -+#define USXGMII_XFI_TX_MODE GENMASK(2, 0) -+#define USXGMII_XFI_TX_MODE_10G 0 -+#define USXGMII_XFI_TX_MODE_5G 1 -+ -+/* Register to control PCS AN */ -+#define RG_PCS_AN_CTRL0 0x810 -+#define USXGMII_AN_RESTART BIT(31) -+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) -+#define USXGMII_AN_ENABLE BIT(0) -+ -+#define RG_PCS_AN_CTRL2 0x818 -+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) -+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) -+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) -+ -+/* Register to read PCS AN status */ -+#define RG_PCS_AN_STS0 0x81c -+#define USXGMII_LPA_SPEED_MASK GENMASK(11, 9) -+#define USXGMII_LPA_SPEED_10 0 -+#define USXGMII_LPA_SPEED_100 1 -+#define USXGMII_LPA_SPEED_1000 2 -+#define USXGMII_LPA_SPEED_10000 3 -+#define USXGMII_LPA_SPEED_2500 4 -+#define USXGMII_LPA_SPEED_5000 5 -+#define USXGMII_LPA_DUPLEX BIT(12) -+#define USXGMII_LPA_LINK BIT(15) -+#define USXGMII_LPA_LATCH BIT(31) -+ -+/* Register to control USXGMII XFI PLL digital */ -+#define XFI_PLL_DIG_GLB8 0x08 -+#define RG_XFI_PLL_EN BIT(31) -+ -+/* Register to control USXGMII XFI PLL analog */ -+#define XFI_PLL_ANA_GLB8 0x108 -+#define RG_XFI_PLL_ANA_SWWA 0x02283248 -+ - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) - #define GEPHY_MAC_SEL BIT(1) - -+/* Toprgu subsystem config registers */ -+#define TOPRGU_SWSYSRST 0x18 -+#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24) -+#define SWSYSRST_XFI_PLL_GRST BIT(16) -+#define SWSYSRST_XFI_PEXPT1_GRST BIT(15) -+#define SWSYSRST_XFI_PEXPT0_GRST BIT(14) -+#define SWSYSRST_XFI1_GRST BIT(13) -+#define SWSYSRST_XFI0_GRST BIT(12) -+#define SWSYSRST_SGMII1_GRST BIT(2) -+#define SWSYSRST_SGMII0_GRST BIT(1) -+#define TOPRGU_SWSYSRST_EN 0xFC -+ - /* Top misc registers */ -+#define TOP_MISC_NETSYS_PCS_MUX 0x84 -+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) -+#define MUX_G2_USXGMII_SEL BIT(1) -+#define MUX_HSGMII1_G1_SEL BIT(0) -+ - #define USB_PHY_SWITCH_REG 0x218 - #define QPHY_SEL_MASK GENMASK(1, 0) - #define SGMII_QPHY_SEL 0x2 - -+/* MDIO control */ -+#define MII_MMD_ACC_CTL_REG 0x0d -+#define MII_MMD_ADDR_DATA_REG 0x0e -+#define MMD_OP_MODE_DATA BIT(14) -+ - /* MT7628/88 specific stuff */ - #define MT7628_PDMA_OFFSET 0x0800 - #define MT7628_SDM_OFFSET 0x0c00 -@@ -809,13 +926,6 @@ enum mtk_gmac_id { - MTK_GMAC_ID_MAX - }; - --/* GDM Type */ --enum mtk_gdm_type { -- MTK_GDM_TYPE = 0, -- MTK_XGDM_TYPE, -- MTK_GDM_TYPE_MAX --}; -- - enum mtk_tx_buf_type { - MTK_TYPE_SKB, - MTK_TYPE_XDP_TX, -@@ -902,6 +1012,7 @@ enum mkt_eth_capabilities { - MTK_TRGMII_BIT, - MTK_SGMII_BIT, - MTK_USXGMII_BIT, -+ MTK_2P5GPHY_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -922,6 +1033,7 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, - MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, -+ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, - MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -@@ -933,6 +1045,7 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC1_SGMII_BIT, - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, -+ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, - MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -@@ -946,6 +1059,7 @@ enum mkt_eth_capabilities { - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) - #define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) -+#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -968,6 +1082,8 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ - BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ -+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ -@@ -983,6 +1099,7 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) - #define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -@@ -996,6 +1113,7 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) - #define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) - #define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -@@ -1019,6 +1137,10 @@ enum mkt_eth_capabilities { - (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ - MTK_SHARED_SGMII) - -+/* 2: GMAC2 -> XGMII */ -+#define MTK_MUX_GMAC2_TO_2P5GPHY \ -+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) -+ - /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) -@@ -1077,7 +1199,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ - MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \ - MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \ -- MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII) -+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \ -+ MTK_GMAC2_2P5GPHY | MTK_MUX_GMAC2_TO_2P5GPHY) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1183,6 +1306,22 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - -+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and -+ * associated data -+ * @regmap: The register map pointing at the range used to setup -+ * USXGMII modes -+ * @interface: Currently selected interface mode -+ * @id: The element is used to record the index of PCS -+ * @pcs: Phylink PCS structure -+ */ -+struct mtk_usxgmii_pcs { -+ struct mtk_eth *eth; -+ struct regmap *regmap; -+ phy_interface_t interface; -+ u8 id; -+ struct phylink_pcs pcs; -+}; -+ - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1203,6 +1342,11 @@ struct mtk_soc_data { - * @infra: The register map pointing at the range used to setup - * SGMII and GePHY path - * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances -+ * @usxgmii_pll: The register map pointing at the range used to control -+ * the USXGMII SerDes PLL -+ * @regmap_pextp: The register map pointing at the range used to setup -+ * PHYA -+ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1244,7 +1388,11 @@ struct mtk_eth { - unsigned long sysclk; - struct regmap *ethsys; - struct regmap *infra; -+ struct regmap *toprgu; - struct phylink_pcs **sgmii_pcs; -+ struct regmap *usxgmii_pll; -+ struct regmap **regmap_pextp; -+ struct mtk_usxgmii_pcs **usxgmii_pcs; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; -@@ -1400,6 +1548,19 @@ static inline u32 mtk_get_ib2_multicast_ - return MTK_FOE_IB2_MULTICAST; - } - -+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_5GBASER: -+ return true; -+ break; -+ default: -+ return false; -+ } -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - -@@ -1407,8 +1568,10 @@ void mtk_w32(struct mtk_eth *eth, u32 va - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); - - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, -@@ -1418,5 +1581,20 @@ int mtk_flow_offload_cmd(struct mtk_eth - void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - -+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id); -+int mtk_usxgmii_init(struct mtk_eth *eth); -+int mtk_xfi_pll_enable(struct mtk_eth *eth); -+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id); -+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id); -+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id); -+#else -+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) { return NULL; } -+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; } -+static inline int mtk_xfi_pll_enable(struct mtk_eth *eth) { return 0; } -+static inline void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) { } -+static inline void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) { } -+static inline void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) { } -+#endif /* NET_MEDIATEK_SOC_USXGMII */ - - #endif /* MTK_ETH_H */ ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c -@@ -0,0 +1,835 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (c) 2022 MediaTek Inc. -+ * Author: Henry Yen -+ * Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include "mtk_eth_soc.h" -+ -+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); -+} -+ -+static int mtk_xfi_pextp_init(struct mtk_eth *eth) -+{ -+ struct device *dev = eth->dev; -+ struct device_node *r = dev->of_node; -+ struct device_node *np; -+ int i; -+ -+ eth->regmap_pextp = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->regmap_pextp), GFP_KERNEL); -+ if (!eth->regmap_pextp) -+ return -ENOMEM; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { -+ np = of_parse_phandle(r, "mediatek,xfi_pextp", i); -+ if (!np) -+ break; -+ -+ eth->regmap_pextp[i] = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->regmap_pextp[i])) -+ return PTR_ERR(eth->regmap_pextp[i]); -+ } -+ -+ return 0; -+} -+ -+static int mtk_xfi_pll_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,xfi_pll", 0); -+ if (!np) -+ return -1; -+ -+ eth->usxgmii_pll = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pll)) -+ return PTR_ERR(eth->usxgmii_pll); -+ -+ return 0; -+} -+ -+static int mtk_toprgu_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,toprgu", 0); -+ if (!np) -+ return -1; -+ -+ eth->toprgu = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->toprgu)) -+ return PTR_ERR(eth->toprgu); -+ -+ return 0; -+} -+ -+int mtk_xfi_pll_enable(struct mtk_eth *eth) -+{ -+ u32 val = 0; -+ -+ if (!eth->usxgmii_pll) -+ return -EINVAL; -+ -+ /* Add software workaround for USXGMII PLL TCL issue */ -+ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA); -+ -+ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val); -+ val |= RG_XFI_PLL_EN; -+ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val); -+ -+ return 0; -+} -+ -+static int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id) -+{ -+ int xgmii_id = mac_id; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (mac_id) { -+ case MTK_GMAC1_ID: -+ case MTK_GMAC2_ID: -+ xgmii_id = 1; -+ break; -+ case MTK_GMAC3_ID: -+ xgmii_id = 0; -+ break; -+ default: -+ xgmii_id = -1; -+ } -+ } -+ -+ return xgmii_id; -+} -+ -+static int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id) -+{ -+ int mac_id = xgmii_id; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (xgmii_id) { -+ case 0: -+ mac_id = 2; -+ break; -+ case 1: -+ mac_id = 1; -+ break; -+ default: -+ mac_id = -1; -+ } -+ } -+ -+ return mac_id; -+} -+ -+ -+static void mtk_usxgmii_setup_phya_usxgmii(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00C9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x01423342); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000001); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_setup_phya_5gbaser(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAAA5A5AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C018AA); -+ regmap_write(pextp, 0x50E0, 0x3777812B); -+ regmap_write(pextp, 0x506C, 0x005C9CFF); -+ regmap_write(pextp, 0x5070, 0x9DFAFAFA); -+ regmap_write(pextp, 0x5074, 0x273F3F3F); -+ regmap_write(pextp, 0x5078, 0xA8883868); -+ regmap_write(pextp, 0x507C, 0x14661466); -+ regmap_write(pextp, 0x5080, 0x0E001ABF); -+ regmap_write(pextp, 0x5084, 0x080B0D0D); -+ regmap_write(pextp, 0x5088, 0x02050909); -+ regmap_write(pextp, 0x50E4, 0x0C000000); -+ regmap_write(pextp, 0x50E8, 0x04000000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x50808C8C); -+ regmap_write(pextp, 0x6004, 0x18000000); -+ regmap_write(pextp, 0x00F8, 0x00A132A1); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000003); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_setup_phya_10gbaser(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00C9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x01423342); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x47684100); -+ regmap_write(pextp, 0x3050, 0x00000000); -+ regmap_write(pextp, 0x3054, 0x00000000); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ if (mpcs->id == 0) -+ regmap_write(pextp, 0xA008, 0x0007B400); -+ -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000001); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) -+{ -+ u32 id = mtk_mac2xgmii_id(eth, mac_id); -+ struct regmap *pextp; -+ -+ if (id >= eth->soc->num_devs) -+ return; -+ -+ pextp = eth->regmap_pextp[id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020207); -+ regmap_write(pextp, 0x2034, 0x0E05050F); -+ regmap_write(pextp, 0x2040, 0x00200032); -+ regmap_write(pextp, 0x50F0, 0x00C014BA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000EAF); -+ regmap_write(pextp, 0x5084, 0x08080E0D); -+ regmap_write(pextp, 0x5088, 0x02030B09); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0606); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x00FA32FA); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F21); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00011110); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3064, 0x0000C000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x20200F00); -+ regmap_write(pextp, 0xA060, 0x00050000); -+ regmap_write(pextp, 0x90D0, 0x00000007); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen2 */ -+ regmap_write(pextp, 0x0070, 0x0201C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0201C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F01); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) -+{ -+ u32 id = mtk_mac2xgmii_id(eth, mac_id); -+ struct regmap *pextp; -+ -+ if (id >= eth->soc->num_devs) -+ return; -+ -+ pextp = eth->regmap_pextp[id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x009C329C); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F21); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00011110); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x22000F00); -+ regmap_write(pextp, 0xA060, 0x00050000); -+ regmap_write(pextp, 0x90D0, 0x00000005); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen2 */ -+ regmap_write(pextp, 0x0070, 0x0201C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0201C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F01); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id) -+{ -+ u32 val = 0; -+ -+ if (id >= eth->soc->num_devs || !eth->toprgu) -+ return; -+ -+ switch (id) { -+ case 0: -+ /* Enable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val |= SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ -+ /* Assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | -+ SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ udelay(100); -+ -+ /* De-assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); -+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ /* Disable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ break; -+ case 1: -+ /* Enable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val |= SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ -+ /* Assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | -+ SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ udelay(100); -+ -+ /* De-assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); -+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ /* Disable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ break; -+ } -+ -+ mdelay(10); -+} -+ -+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ mtk_usxgmii_reset(eth, xgmii_id); -+} -+ -+ -+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; -+ bool mode_changed = false; -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | -+ USXGMII_AN_ENABLE; -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ } else if (interface == PHY_INTERFACE_MODE_10GKR) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else -+ return -EINVAL; -+ -+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); -+ -+ if (mpcs->interface != interface) { -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ mtk_xfi_pll_enable(eth); -+ mtk_usxgmii_reset(eth, mpcs->id); -+ -+ /* Setup USXGMII AN ctrl */ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0, -+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -+ an_ctrl); -+ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2, -+ USXGMII_LINK_TIMER_IDLE_DETECT | -+ USXGMII_LINK_TIMER_COMP_ACK_DETECT | -+ USXGMII_LINK_TIMER_AN_RESTART, -+ link_timer); -+ -+ /* Gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); -+ -+ /* Enable interface force mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); -+ -+ /* Setup USXGMII adapt mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, -+ adapt_mode); -+ -+ /* Setup USXGMII speed */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, -+ xfi_mode); -+ -+ udelay(1); -+ -+ /* Un-gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, 0); -+ -+ udelay(1); -+ -+ /* Disable interface force mode for the AN mode */ -+ if (an_ctrl & USXGMII_AN_ENABLE) -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, 0); -+ -+ /* Setup USXGMIISYS with the determined property */ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) -+ mtk_usxgmii_setup_phya_usxgmii(mpcs); -+ else if (interface == PHY_INTERFACE_MODE_10GKR) -+ mtk_usxgmii_setup_phya_10gbaser(mpcs); -+ else if (interface == PHY_INTERFACE_MODE_5GBASER) -+ mtk_usxgmii_setup_phya_5gbaser(mpcs); -+ -+ return mode_changed; -+} -+ -+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)]; -+ u32 val = 0; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ if (FIELD_GET(USXGMII_AN_ENABLE, val)) { -+ /* Refresh LPA by inverting LPA_LATCH */ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0, -+ USXGMII_LPA_LATCH, -+ !(val & USXGMII_LPA_LATCH)); -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ -+ state->interface = mpcs->interface; -+ state->link = FIELD_GET(USXGMII_LPA_LINK, val); -+ state->duplex = FIELD_GET(USXGMII_LPA_DUPLEX, val); -+ -+ switch (FIELD_GET(USXGMII_LPA_SPEED_MASK, val)) { -+ case USXGMII_LPA_SPEED_10: -+ state->speed = SPEED_10; -+ break; -+ case USXGMII_LPA_SPEED_100: -+ state->speed = SPEED_100; -+ break; -+ case USXGMII_LPA_SPEED_1000: -+ state->speed = SPEED_1000; -+ break; -+ case USXGMII_LPA_SPEED_2500: -+ state->speed = SPEED_2500; -+ break; -+ case USXGMII_LPA_SPEED_5000: -+ state->speed = SPEED_5000; -+ break; -+ case USXGMII_LPA_SPEED_10000: -+ state->speed = SPEED_10000; -+ break; -+ } -+ } else { -+ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); -+ -+ if (mac->id == MTK_GMAC2_ID) -+ val = val >> 16; -+ -+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) { -+ case 0: -+ state->speed = SPEED_10000; -+ break; -+ case 1: -+ state->speed = SPEED_5000; -+ break; -+ case 2: -+ state->speed = SPEED_2500; -+ break; -+ case 3: -+ state->speed = SPEED_1000; -+ break; -+ } -+ -+ state->interface = mpcs->interface; -+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val); -+ state->duplex = DUPLEX_FULL; -+ } -+ -+ if (state->link == 0) -+ mtk_usxgmii_pcs_config(pcs, MLO_AN_INBAND, -+ state->interface, NULL, false); -+} -+ -+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ unsigned int val = 0; -+ -+ if (!mpcs->regmap) -+ return; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ val |= USXGMII_AN_RESTART; -+ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val); -+} -+ -+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ int speed, int duplex) -+{ -+ /* Reconfiguring USXGMII to ensure the quality of the RX signal -+ * after the line side link up. -+ */ -+ mtk_usxgmii_pcs_config(pcs, mode, -+ interface, NULL, false); -+} -+ -+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { -+ .pcs_config = mtk_usxgmii_pcs_config, -+ .pcs_get_state = mtk_usxgmii_pcs_get_state, -+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, -+ .pcs_link_up = mtk_usxgmii_pcs_link_up, -+}; -+ -+int mtk_usxgmii_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device *dev = eth->dev; -+ struct device_node *np; -+ int i, ret; -+ -+ eth->usxgmii_pcs = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->usxgmii_pcs), GFP_KERNEL); -+ if (!eth->usxgmii_pcs) -+ return -ENOMEM; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { -+ np = of_parse_phandle(r, "mediatek,usxgmiisys", i); -+ if (!np) -+ break; -+ -+ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs), GFP_KERNEL); -+ if (!eth->usxgmii_pcs[i]) -+ return -ENOMEM; -+ -+ eth->usxgmii_pcs[i]->id = i; -+ eth->usxgmii_pcs[i]->eth = eth; -+ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pcs[i]->regmap)) -+ return PTR_ERR(eth->usxgmii_pcs[i]->regmap); -+ -+ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops; -+ eth->usxgmii_pcs[i]->pcs.poll = true; -+ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA; -+ -+ of_node_put(np); -+ } -+ -+ ret = mtk_xfi_pextp_init(eth); -+ if (ret) -+ return ret; -+ -+ ret = mtk_xfi_pll_init(eth); -+ if (ret) -+ return ret; -+ -+ return mtk_toprgu_init(eth); -+} -+ -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ if (!eth->usxgmii_pcs[xgmii_id]->regmap) -+ return NULL; -+ -+ return ð->usxgmii_pcs[xgmii_id]->pcs; -+} diff --git a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch new file mode 100644 index 000000000..78263feeb --- /dev/null +++ b/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -0,0 +1,1604 @@ +From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 19:04:42 +0100 +Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes + modes for MT7988 + +MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to +connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R, +2500Base-X, 1000Base-X and Cisco SGMII interface modes. + +Implement support for configuring for the new paths to SerDes interfaces +and the internal 2.5G PHY. + +Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and +setup the new PHYA on MT7988 to access the also still existing old +LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface +modes. + +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/Kconfig | 16 + + drivers/net/ethernet/mediatek/Makefile | 1 + + drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 182 ++++- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 232 ++++++- + drivers/net/ethernet/mediatek/mtk_usxgmii.c | 692 +++++++++++++++++++ + 6 files changed, 1215 insertions(+), 31 deletions(-) + create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c + +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -24,6 +24,22 @@ config NET_MEDIATEK_SOC + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. + ++config NET_MEDIATEK_SOC_USXGMII ++ bool "Support USXGMII SerDes on MT7988" ++ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST ++ def_bool NET_MEDIATEK_SOC != n ++ help ++ Include support for 10GE SerDes which can be found on MT7988. ++ If this kernel should run on SoCs with 10 GBit/s Ethernet you ++ will need to select this option to use GMAC2 and GMAC3 with ++ external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII ++ interface modes. ++ ++ Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS ++ unit (MediaTek LynxI) in MT7988 is connected via the new 10GE ++ SerDes, you will also need to select this option in case you ++ want to use any of those SerDes modes. ++ + config NET_MEDIATEK_STAR_EMAC + tristate "MediaTek STAR Ethernet MAC support" + select PHYLIB +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o + mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o ++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 + return "gmac2_rgmii"; + case MTK_ETH_PATH_GMAC2_SGMII: + return "gmac2_sgmii"; ++ case MTK_ETH_PATH_GMAC2_2P5GPHY: ++ return "gmac2_2p5gphy"; + case MTK_ETH_PATH_GMAC2_GEPHY: + return "gmac2_gephy"; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ return "gmac3_sgmii"; + case MTK_ETH_PATH_GDM1_ESW: + return "gdm1_esw"; ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ return "gmac1_usxgmii"; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ return "gmac2_usxgmii"; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ return "gmac3_usxgmii"; + default: + return "unknown path"; + } +@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru + return 0; + } + ++static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) ++{ ++ int ret; ++ ++ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) { ++ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2); ++ if (ret) ++ return ret; ++ ++ /* Setup mux to 2p5g PHY */ ++ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL); ++ if (ret) ++ return ret; ++ ++ dev_dbg(eth->dev, "path %s in %s updated\n", ++ mtk_eth_path_name(path), __func__); ++ } ++ ++ return 0; ++} ++ + static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) + { + unsigned int val = 0; +@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_ + return 0; + } + +-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) ++static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) ++{ ++ unsigned int val = 0; ++ bool updated = true; ++ int mac_id = 0; ++ ++ /* Disable SYSCFG1 SGMII */ ++ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); ++ ++ switch (path) { ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; ++ mac_id = MTK_GMAC1_ID; ++ break; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; ++ mac_id = MTK_GMAC2_ID; ++ break; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; ++ mac_id = MTK_GMAC3_ID; ++ break; ++ default: ++ updated = false; ++ }; ++ ++ if (updated) { ++ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, ++ SYSCFG0_SGMII_MASK, val); ++ ++ if (mac_id == MTK_GMAC2_ID) ++ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, ++ MUX_G2_USXGMII_SEL); ++ } ++ ++ dev_dbg(eth->dev, "path %s in %s updated = %d\n", ++ mtk_eth_path_name(path), __func__, updated); ++ ++ return 0; ++} ++ ++static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) + { + unsigned int val = 0; + bool updated = true; +@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii + case MTK_ETH_PATH_GMAC2_SGMII: + val |= SYSCFG0_SGMII_GMAC2_V2; + break; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ val |= SYSCFG0_SGMII_GMAC3_V2; ++ break; + default: + updated = false; + } +@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth + .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, + .set_path = set_mux_u3_gmac2_to_qphy, + }, { ++ .name = "mux_gmac2_to_2p5gphy", ++ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, ++ .set_path = set_mux_gmac2_to_2p5gphy, ++ }, { + .name = "mux_gmac1_gmac2_to_sgmii_rgmii", + .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, + .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, + }, { + .name = "mux_gmac12_to_gephy_sgmii", + .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, +- .set_path = set_mux_gmac12_to_gephy_sgmii, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_gephy_sgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_usxgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, ++ .set_path = set_mux_gmac123_to_usxgmii, + }, + }; + +@@ -249,12 +336,39 @@ out: + return err; + } + ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) ++{ ++ u64 path; ++ ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : ++ MTK_ETH_PATH_GMAC3_USXGMII; ++ ++ /* Setup proper MUXes along the path */ ++ return mtk_eth_mux_setup(eth, path); ++} ++ + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) + { + u64 path; + +- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : +- MTK_ETH_PATH_GMAC2_SGMII; ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : ++ MTK_ETH_PATH_GMAC3_SGMII; ++ ++ /* Setup proper MUXes along the path */ ++ return mtk_eth_mux_setup(eth, path); ++} ++ ++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) ++{ ++ u64 path = 0; ++ ++ if (mac_id == MTK_GMAC2_ID) ++ path = MTK_ETH_PATH_GMAC2_2P5GPHY; ++ ++ if (!path) ++ return -EINVAL; + + /* Setup proper MUXes along the path */ + return mtk_eth_mux_setup(eth, path); +@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk + /* Setup proper MUXes along the path */ + return mtk_eth_mux_setup(eth, path); + } +- +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -431,6 +431,30 @@ static void mtk_setup_bridge_switch(stru + MTK_GSW_CFG); + } + ++static bool mtk_check_gmac23_idle(struct mtk_mac *mac) ++{ ++ u32 mac_fsm, gdm_fsm; ++ ++ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); ++ ++ switch (mac->id) { ++ case MTK_GMAC2_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); ++ break; ++ case MTK_GMAC3_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); ++ break; ++ default: ++ return true; ++ }; ++ ++ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && ++ (gdm_fsm & 0xFFFF0000) == 0x00000000) ++ return true; ++ ++ return false; ++} ++ + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) + { +@@ -439,12 +463,20 @@ static struct phylink_pcs *mtk_mac_selec + struct mtk_eth *eth = mac->hw; + unsigned int sid; + +- if (interface == PHY_INTERFACE_MODE_SGMII || +- phy_interface_mode_is_8023z(interface)) { +- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? +- 0 : mac->id; +- +- return eth->sgmii_pcs[sid]; ++ if ((interface == PHY_INTERFACE_MODE_SGMII || ++ phy_interface_mode_is_8023z(interface)) && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { ++ sid = mtk_mac2xgmii_id(eth, mac->id); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) ++ return mtk_sgmii_wrapper_select_pcs(eth, mac->id); ++ else ++ return eth->sgmii_pcs[sid]; ++ } else if ((interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_5GBASER) && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) && ++ mac->id != MTK_GMAC1_ID) { ++ return mtk_usxgmii_select_pcs(eth, mac->id); + } + + return NULL; +@@ -500,7 +532,22 @@ static void mtk_mac_config(struct phylin + goto init_err; + } + break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_5GBASER: ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { ++ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); ++ if (err) ++ goto init_err; ++ } ++ break; + case PHY_INTERFACE_MODE_INTERNAL: ++ if (mac->id == MTK_GMAC2_ID && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { ++ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); ++ if (err) ++ goto init_err; ++ } + break; + default: + goto err_phy; +@@ -555,8 +602,6 @@ static void mtk_mac_config(struct phylin + val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); + val |= SYSCFG0_GE_MODE(ge_mode, mac->id); + regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); +- +- mac->interface = state->interface; + } + + /* SGMII */ +@@ -573,21 +618,40 @@ static void mtk_mac_config(struct phylin + + /* Save the syscfg0 value for mac_finish */ + mac->syscfg0 = val; +- } else if (phylink_autoneg_inband(mode)) { ++ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && ++ state->interface != PHY_INTERFACE_MODE_10GBASER && ++ state->interface != PHY_INTERFACE_MODE_5GBASER && ++ phylink_autoneg_inband(mode)) { + dev_err(eth->dev, +- "In-band mode not supported in non SGMII mode!\n"); ++ "In-band mode not supported in non-SerDes modes!\n"); + return; + } + + /* Setup gmac */ +- if (mtk_is_netsys_v3_or_greater(eth) && +- mac->interface == PHY_INTERFACE_MODE_INTERNAL) { +- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); +- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ if (mtk_interface_mode_is_xgmii(state->interface)) { ++ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); ++ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ ++ if (mac->id == MTK_GMAC1_ID) ++ mtk_setup_bridge_switch(eth); ++ } else { ++ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); + +- mtk_setup_bridge_switch(eth); ++ /* FIXME: In current hardware design, we have to reset FE ++ * when swtiching XGDM to GDM. Therefore, here trigger an SER ++ * to let GDM go back to the initial state. ++ */ ++ if ((mtk_interface_mode_is_xgmii(mac->interface) || ++ mac->interface == PHY_INTERFACE_MODE_NA) && ++ !mtk_check_gmac23_idle(mac) && ++ !test_bit(MTK_RESETTING, ð->state)) ++ schedule_work(ð->pending_work); ++ } + } + ++ mac->interface = state->interface; ++ + return; + + err_phy: +@@ -632,10 +696,13 @@ static void mtk_mac_link_down(struct phy + { + struct mtk_mac *mac = container_of(config, struct mtk_mac, + phylink_config); +- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); + +- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); +- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); ++ if (!mtk_interface_mode_is_xgmii(interface)) { ++ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id)); ++ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id)); ++ } else if (mac->id != MTK_GMAC1_ID) { ++ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id)); ++ } + } + + static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, +@@ -707,13 +774,11 @@ static void mtk_set_queue_speed(struct m + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); + } + +-static void mtk_mac_link_up(struct phylink_config *config, +- struct phy_device *phy, +- unsigned int mode, phy_interface_t interface, +- int speed, int duplex, bool tx_pause, bool rx_pause) ++static void mtk_gdm_mac_link_up(struct mtk_mac *mac, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) + { +- struct mtk_mac *mac = container_of(config, struct mtk_mac, +- phylink_config); + u32 mcr; + + mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); +@@ -747,6 +812,55 @@ static void mtk_mac_link_up(struct phyli + mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) ++{ ++ u32 mcr, force_link = 0; ++ ++ if (mac->id == MTK_GMAC1_ID) ++ return; ++ ++ /* Eliminate the interference(before link-up) caused by PHY noise */ ++ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id)); ++ mdelay(20); ++ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id)); ++ ++ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID) ++ force_link = MTK_XGMAC_FORCE_LINK(mac->id); ++ ++ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id)); ++ ++ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); ++ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE); ++ /* Configure pause modes - ++ * phylink will avoid these for half duplex ++ */ ++ if (tx_pause) ++ mcr |= XMAC_MCR_FORCE_TX_FC; ++ if (rx_pause) ++ mcr |= XMAC_MCR_FORCE_RX_FC; ++ ++ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); ++} ++ ++static void mtk_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 mtk_mac *mac = container_of(config, struct mtk_mac, ++ phylink_config); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, ++ tx_pause, rx_pause); ++ else ++ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, ++ tx_pause, rx_pause); ++} ++ + static const struct phylink_mac_ops mtk_phylink_ops = { + .validate = phylink_generic_validate, + .mac_select_pcs = mtk_mac_select_pcs, +@@ -4560,8 +4674,21 @@ static int mtk_add_mac(struct mtk_eth *e + phy_interface_zero(mac->phylink_config.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + mac->phylink_config.supported_interfaces); ++ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { ++ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; ++ __set_bit(PHY_INTERFACE_MODE_5GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, ++ mac->phylink_config.supported_interfaces); + } + ++ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && ++ id == MTK_GMAC2_ID) ++ __set_bit(PHY_INTERFACE_MODE_INTERNAL, ++ mac->phylink_config.supported_interfaces); ++ + phylink = phylink_create(&mac->phylink_config, + of_fwnode_handle(mac->of_node), + phy_mode, &mtk_phylink_ops); +@@ -4754,6 +4881,13 @@ static int mtk_probe(struct platform_dev + + if (err) + return err; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { ++ err = mtk_usxgmii_init(eth); ++ ++ if (err) ++ return err; + } + + if (eth->soc->required_pctl) { +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -499,6 +499,21 @@ + #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) + #define INTF_MODE_RGMII_10_100 0 + ++/* XFI Mac control registers */ ++#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000)) ++#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x)) ++#define XMAC_MCR_TRX_DISABLE 0xf ++#define XMAC_MCR_FORCE_TX_FC BIT(5) ++#define XMAC_MCR_FORCE_RX_FC BIT(4) ++ ++/* XFI Mac logic reset registers */ ++#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10) ++#define XMAC_LOGIC_RST BIT(0) ++ ++/* XFI Mac count global control */ ++#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100) ++#define XMAC_GLB_CNTCLR BIT(0) ++ + /* GPIO port control registers for GMAC 2*/ + #define GPIO_OD33_CTRL8 0x4c0 + #define GPIO_BIAS_CTRL 0xed0 +@@ -524,6 +539,7 @@ + #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) + #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) ++#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) + + + /* ethernet subsystem clock register */ +@@ -556,12 +572,74 @@ + #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) + #define ETHSYS_DMA_AG_MAP_PPE BIT(2) + ++/* USXGMII subsystem config registers */ ++/* Register to control speed */ ++#define RG_PHY_TOP_SPEED_CTRL1 0x80C ++#define USXGMII_RATE_UPDATE_MODE BIT(31) ++#define USXGMII_MAC_CK_GATED BIT(29) ++#define USXGMII_IF_FORCE_EN BIT(28) ++#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) ++#define USXGMII_RATE_ADAPT_MODE_X1 0 ++#define USXGMII_RATE_ADAPT_MODE_X2 1 ++#define USXGMII_RATE_ADAPT_MODE_X4 2 ++#define USXGMII_RATE_ADAPT_MODE_X10 3 ++#define USXGMII_RATE_ADAPT_MODE_X100 4 ++#define USXGMII_RATE_ADAPT_MODE_X5 5 ++#define USXGMII_RATE_ADAPT_MODE_X50 6 ++#define USXGMII_XFI_RX_MODE GENMASK(6, 4) ++#define USXGMII_XFI_RX_MODE_10G 0 ++#define USXGMII_XFI_RX_MODE_5G 1 ++#define USXGMII_XFI_TX_MODE GENMASK(2, 0) ++#define USXGMII_XFI_TX_MODE_10G 0 ++#define USXGMII_XFI_TX_MODE_5G 1 ++ ++/* Register to control PCS AN */ ++#define RG_PCS_AN_CTRL0 0x810 ++#define USXGMII_AN_RESTART BIT(31) ++#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) ++#define USXGMII_AN_ENABLE BIT(0) ++ ++#define RG_PCS_AN_CTRL2 0x818 ++#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) ++#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) ++#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) ++ ++/* Register to read PCS AN status */ ++#define RG_PCS_AN_STS0 0x81c ++#define USXGMII_PCS_AN_WORD GENMASK(15, 0) ++#define USXGMII_LPA_LATCH BIT(31) ++ ++/* Register to control USXGMII XFI PLL digital */ ++#define XFI_PLL_DIG_GLB8 0x08 ++#define RG_XFI_PLL_EN BIT(31) ++ ++/* Register to control USXGMII XFI PLL analog */ ++#define XFI_PLL_ANA_GLB8 0x108 ++#define RG_XFI_PLL_ANA_SWWA 0x02283248 ++ + /* Infrasys subsystem config registers */ + #define INFRA_MISC2 0x70c + #define CO_QPHY_SEL BIT(0) + #define GEPHY_MAC_SEL BIT(1) + ++/* Toprgu subsystem config registers */ ++#define TOPRGU_SWSYSRST 0x18 ++#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24) ++#define SWSYSRST_XFI_PLL_GRST BIT(16) ++#define SWSYSRST_XFI_PEXPT1_GRST BIT(15) ++#define SWSYSRST_XFI_PEXPT0_GRST BIT(14) ++#define SWSYSRST_XFI1_GRST BIT(13) ++#define SWSYSRST_XFI0_GRST BIT(12) ++#define SWSYSRST_SGMII1_GRST BIT(2) ++#define SWSYSRST_SGMII0_GRST BIT(1) ++#define TOPRGU_SWSYSRST_EN 0xFC ++ + /* Top misc registers */ ++#define TOP_MISC_NETSYS_PCS_MUX 0x84 ++#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) ++#define MUX_G2_USXGMII_SEL BIT(1) ++#define MUX_HSGMII1_G1_SEL BIT(0) ++ + #define USB_PHY_SWITCH_REG 0x218 + #define QPHY_SEL_MASK GENMASK(1, 0) + #define SGMII_QPHY_SEL 0x2 +@@ -586,6 +664,8 @@ + #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) + #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + ++/* Debug Purpose Register */ ++#define MTK_PSE_FQFC_CFG 0x100 + #define MTK_FE_CDM1_FSM 0x220 + #define MTK_FE_CDM2_FSM 0x224 + #define MTK_FE_CDM3_FSM 0x238 +@@ -594,6 +674,11 @@ + #define MTK_FE_CDM6_FSM 0x328 + #define MTK_FE_GDM1_FSM 0x228 + #define MTK_FE_GDM2_FSM 0x22C ++#define MTK_FE_GDM3_FSM 0x23C ++#define MTK_FE_PSE_FREE 0x240 ++#define MTK_FE_DROP_FQ 0x244 ++#define MTK_FE_DROP_FC 0x248 ++#define MTK_FE_DROP_PPE 0x24C + + #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + +@@ -940,6 +1025,8 @@ enum mkt_eth_capabilities { + MTK_RGMII_BIT = 0, + MTK_TRGMII_BIT, + MTK_SGMII_BIT, ++ MTK_USXGMII_BIT, ++ MTK_2P5GPHY_BIT, + MTK_ESW_BIT, + MTK_GEPHY_BIT, + MTK_MUX_BIT, +@@ -960,8 +1047,11 @@ enum mkt_eth_capabilities { + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, + MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, + MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, ++ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, + MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, + MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_RGMII_BIT, +@@ -969,14 +1059,21 @@ enum mkt_eth_capabilities { + MTK_ETH_PATH_GMAC1_SGMII_BIT, + MTK_ETH_PATH_GMAC2_RGMII_BIT, + MTK_ETH_PATH_GMAC2_SGMII_BIT, ++ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, + MTK_ETH_PATH_GMAC2_GEPHY_BIT, ++ MTK_ETH_PATH_GMAC3_SGMII_BIT, + MTK_ETH_PATH_GDM1_ESW_BIT, ++ MTK_ETH_PATH_GMAC1_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC2_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC3_USXGMII_BIT, + }; + + /* Supported hardware group on SoCs */ + #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) + #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) + #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) ++#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) ++#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) + #define MTK_ESW BIT_ULL(MTK_ESW_BIT) + #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) + #define MTK_MUX BIT_ULL(MTK_MUX_BIT) +@@ -999,10 +1096,16 @@ enum mkt_eth_capabilities { + BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) + #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ + BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) ++#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ ++ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) + #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ + BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) + #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ + BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) + + /* Supported path present on SoCs */ + #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) +@@ -1010,8 +1113,13 @@ enum mkt_eth_capabilities { + #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) + #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) + #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) ++#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) + #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) ++#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) + #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) ++#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) + + #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) + #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) +@@ -1019,7 +1127,12 @@ enum mkt_eth_capabilities { + #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) + #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) + #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) ++#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) ++#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) + #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) ++#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) ++#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) ++#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) + + /* MUXes present on SoCs */ + /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ +@@ -1038,10 +1151,20 @@ enum mkt_eth_capabilities { + (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ + MTK_SHARED_SGMII) + ++/* 2: GMAC2 -> XGMII */ ++#define MTK_MUX_GMAC2_TO_2P5GPHY \ ++ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) ++ + /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ + #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ + (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) + ++#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) ++ ++#define MTK_MUX_GMAC123_TO_USXGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) ++ + #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) + + #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ +@@ -1073,8 +1196,12 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1 | MTK_SRAM) + +-#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) ++#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ ++ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ ++ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ ++ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ ++ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ ++ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1184,6 +1311,24 @@ struct mtk_soc_data { + /* currently no SoC has more than 3 macs */ + #define MTK_MAX_DEVS 3 + ++/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and ++ * associated data ++ * @regmap: The register map pointing at the range used to setup ++ * USXGMII modes ++ * @interface: Currently selected interface mode ++ * @id: The element is used to record the index of PCS ++ * @pcs: Phylink PCS structure ++ */ ++struct mtk_usxgmii_pcs { ++ struct mtk_eth *eth; ++ struct regmap *regmap; ++ struct phylink_pcs *wrapped_sgmii_pcs; ++ phy_interface_t interface; ++ u8 id; ++ unsigned int mode; ++ struct phylink_pcs pcs; ++}; ++ + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver + * @dev: The device pointer +@@ -1204,6 +1349,12 @@ struct mtk_soc_data { + * @infra: The register map pointing at the range used to setup + * SGMII and GePHY path + * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances ++ * @sgmii_wrapped_pcs: Pointers to NETSYSv3 wrapper PCS instances ++ * @usxgmii_pll: The register map pointing at the range used to control ++ * the USXGMII SerDes PLL ++ * @regmap_pextp: The register map pointing at the range used to setup ++ * PHYA ++ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS + * @pctl: The register map pointing at the range used to setup + * GMAC port drive/slew values + * @dma_refcnt: track how many netdevs are using the DMA engine +@@ -1247,6 +1398,10 @@ struct mtk_eth { + struct regmap *ethsys; + struct regmap *infra; + struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; ++ struct regmap *toprgu; ++ struct regmap *usxgmii_pll; ++ struct regmap *regmap_pextp[MTK_MAX_DEVS]; ++ struct mtk_usxgmii_pcs *usxgmii_pcs[MTK_MAX_DEVS]; + struct regmap *pctl; + bool hwlro; + refcount_t dma_refcnt; +@@ -1434,6 +1589,19 @@ static inline u32 mtk_get_ib2_multicast_ + return MTK_FOE_IB2_MULTICAST; + } + ++static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_INTERNAL: ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_5GBASER: ++ return true; ++ default: ++ return false; ++ } ++} ++ + /* read the hardware status register */ + void mtk_stats_update_mac(struct mtk_mac *mac); + +@@ -1442,8 +1610,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne + u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); + + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); ++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); + + int mtk_eth_offload_init(struct mtk_eth *eth); + int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, +@@ -1453,5 +1623,63 @@ int mtk_flow_offload_cmd(struct mtk_eth + void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); + void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); + ++static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id) ++{ ++ int xgmii_id = mac_id; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ switch (mac_id) { ++ case MTK_GMAC1_ID: ++ case MTK_GMAC2_ID: ++ xgmii_id = 1; ++ break; ++ case MTK_GMAC3_ID: ++ xgmii_id = 0; ++ break; ++ default: ++ xgmii_id = -1; ++ } ++ } ++ ++ return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id; ++} ++ ++static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id) ++{ ++ int mac_id = xgmii_id; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ switch (xgmii_id) { ++ case 0: ++ mac_id = 2; ++ break; ++ case 1: ++ mac_id = 1; ++ break; ++ default: ++ mac_id = -1; ++ } ++ } ++ ++ return mac_id; ++} ++ ++#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII ++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id); ++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id); ++int mtk_usxgmii_init(struct mtk_eth *eth); ++#else ++static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id) ++{ ++ return NULL; ++} ++ ++static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) ++{ ++ return NULL; ++} ++ ++static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; } ++#endif /* NET_MEDIATEK_SOC_USXGMII */ + + #endif /* MTK_ETH_H */ +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c +@@ -0,0 +1,690 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2023 MediaTek Inc. ++ * Author: Henry Yen ++ * Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include "mtk_eth_soc.h" ++ ++static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) ++{ ++ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); ++} ++ ++static int mtk_xfi_pextp_init(struct mtk_eth *eth) ++{ ++ struct device *dev = eth->dev; ++ struct device_node *r = dev->of_node; ++ struct device_node *np; ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ np = of_parse_phandle(r, "mediatek,xfi-pextp", i); ++ if (!np) ++ break; ++ ++ eth->regmap_pextp[i] = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->regmap_pextp[i])) ++ return PTR_ERR(eth->regmap_pextp[i]); ++ } ++ ++ return 0; ++} ++ ++static int mtk_xfi_pll_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device_node *np; ++ ++ np = of_parse_phandle(r, "mediatek,xfi-pll", 0); ++ if (!np) ++ return -1; ++ ++ eth->usxgmii_pll = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->usxgmii_pll)) ++ return PTR_ERR(eth->usxgmii_pll); ++ ++ return 0; ++} ++ ++static int mtk_toprgu_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device_node *np; ++ ++ np = of_parse_phandle(r, "mediatek,toprgu", 0); ++ if (!np) ++ return -1; ++ ++ eth->toprgu = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->toprgu)) ++ return PTR_ERR(eth->toprgu); ++ ++ return 0; ++} ++ ++static int mtk_xfi_pll_enable(struct mtk_eth *eth) ++{ ++ u32 val = 0; ++ ++ if (!eth->usxgmii_pll) ++ return -EINVAL; ++ ++ /* Add software workaround for USXGMII PLL TCL issue */ ++ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA); ++ ++ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val); ++ val |= RG_XFI_PLL_EN; ++ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val); ++ ++ return 0; ++} ++ ++static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id) ++{ ++ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_USXGMII); ++ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX); ++ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER); ++ ++ /* Setup operation mode */ ++ if (is_10g) ++ regmap_write(pextp, 0x9024, 0x00C9071C); ++ else ++ regmap_write(pextp, 0x9024, 0x00D9071C); ++ ++ if (is_5g) ++ regmap_write(pextp, 0x2020, 0xAAA5A5AA); ++ else ++ regmap_write(pextp, 0x2020, 0xAA8585AA); ++ ++ if (is_2p5g || is_5g || is_10g) { ++ regmap_write(pextp, 0x2030, 0x0C020707); ++ regmap_write(pextp, 0x2034, 0x0E050F0F); ++ regmap_write(pextp, 0x2040, 0x00140032); ++ } else { ++ regmap_write(pextp, 0x2030, 0x0C020207); ++ regmap_write(pextp, 0x2034, 0x0E05050F); ++ regmap_write(pextp, 0x2040, 0x00200032); ++ } ++ ++ if (is_2p5g || is_10g) ++ regmap_write(pextp, 0x50F0, 0x00C014AA); ++ else if (is_5g) ++ regmap_write(pextp, 0x50F0, 0x00C018AA); ++ else ++ regmap_write(pextp, 0x50F0, 0x00C014BA); ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50E0, 0x3777812B); ++ regmap_write(pextp, 0x506C, 0x005C9CFF); ++ regmap_write(pextp, 0x5070, 0x9DFAFAFA); ++ regmap_write(pextp, 0x5074, 0x273F3F3F); ++ regmap_write(pextp, 0x5078, 0xA8883868); ++ regmap_write(pextp, 0x507C, 0x14661466); ++ } else { ++ regmap_write(pextp, 0x50E0, 0x3777C12B); ++ regmap_write(pextp, 0x506C, 0x005F9CFF); ++ regmap_write(pextp, 0x5070, 0x9D9DFAFA); ++ regmap_write(pextp, 0x5074, 0x27273F3F); ++ regmap_write(pextp, 0x5078, 0xA7883C68); ++ regmap_write(pextp, 0x507C, 0x11661166); ++ } ++ ++ if (is_2p5g || is_10g) { ++ regmap_write(pextp, 0x5080, 0x0E000AAF); ++ regmap_write(pextp, 0x5084, 0x08080D0D); ++ regmap_write(pextp, 0x5088, 0x02030909); ++ } else if (is_5g) { ++ regmap_write(pextp, 0x5080, 0x0E001ABF); ++ regmap_write(pextp, 0x5084, 0x080B0D0D); ++ regmap_write(pextp, 0x5088, 0x02050909); ++ } else { ++ regmap_write(pextp, 0x5080, 0x0E000EAF); ++ regmap_write(pextp, 0x5084, 0x08080E0D); ++ regmap_write(pextp, 0x5088, 0x02030B09); ++ } ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50E4, 0x0C000000); ++ regmap_write(pextp, 0x50E8, 0x04000000); ++ } else { ++ regmap_write(pextp, 0x50E4, 0x0C0C0000); ++ regmap_write(pextp, 0x50E8, 0x04040000); ++ } ++ ++ if (is_2p5g || mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x50EC, 0x0F0F0C06); ++ else ++ regmap_write(pextp, 0x50EC, 0x0F0F0606); ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50A8, 0x50808C8C); ++ regmap_write(pextp, 0x6004, 0x18000000); ++ } else { ++ regmap_write(pextp, 0x50A8, 0x506E8C8C); ++ regmap_write(pextp, 0x6004, 0x18190000); ++ } ++ ++ if (is_10g) ++ regmap_write(pextp, 0x00F8, 0x01423342); ++ else if (is_5g) ++ regmap_write(pextp, 0x00F8, 0x00A132A1); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x00F8, 0x009C329C); ++ else ++ regmap_write(pextp, 0x00F8, 0x00FA32FA); ++ ++ /* Force SGDT_OUT off and select PCS */ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x00F4, 0x80201F20); ++ else ++ regmap_write(pextp, 0x00F4, 0x80201F21); ++ ++ /* Force GLB_CKDET_OUT */ ++ regmap_write(pextp, 0x0030, 0x00050C00); ++ ++ /* Force AEQ on */ ++ regmap_write(pextp, 0x0070, 0x02002800); ++ ndelay(1020); ++ ++ /* Setup DA default value */ ++ regmap_write(pextp, 0x30B0, 0x00000020); ++ regmap_write(pextp, 0x3028, 0x00008A01); ++ regmap_write(pextp, 0x302C, 0x0000A884); ++ regmap_write(pextp, 0x3024, 0x00083002); ++ if (mtk_interface_mode_is_xgmii(interface)) { ++ regmap_write(pextp, 0x3010, 0x00022220); ++ regmap_write(pextp, 0x5064, 0x0F020A01); ++ regmap_write(pextp, 0x50B4, 0x06100600); ++ if (interface == PHY_INTERFACE_MODE_USXGMII) ++ regmap_write(pextp, 0x3048, 0x40704000); ++ else ++ regmap_write(pextp, 0x3048, 0x47684100); ++ } else { ++ regmap_write(pextp, 0x3010, 0x00011110); ++ regmap_write(pextp, 0x3048, 0x40704000); ++ } ++ ++ if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g) ++ regmap_write(pextp, 0x3064, 0x0000C000); ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII) { ++ regmap_write(pextp, 0x3050, 0xA8000000); ++ regmap_write(pextp, 0x3054, 0x000000AA); ++ } else if (mtk_interface_mode_is_xgmii(interface)) { ++ regmap_write(pextp, 0x3050, 0x00000000); ++ regmap_write(pextp, 0x3054, 0x00000000); ++ } else { ++ regmap_write(pextp, 0x3050, 0xA8000000); ++ regmap_write(pextp, 0x3054, 0x000000AA); ++ } ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x306C, 0x00000F00); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x306C, 0x22000F00); ++ else ++ regmap_write(pextp, 0x306C, 0x20200F00); ++ ++ if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0) ++ regmap_write(pextp, 0xA008, 0x0007B400); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0xA060, 0x00040000); ++ else ++ regmap_write(pextp, 0xA060, 0x00050000); ++ ++ if (is_10g) ++ regmap_write(pextp, 0x90D0, 0x00000001); ++ else if (is_5g) ++ regmap_write(pextp, 0x90D0, 0x00000003); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x90D0, 0x00000005); ++ else ++ regmap_write(pextp, 0x90D0, 0x00000007); ++ ++ /* Release reset */ ++ regmap_write(pextp, 0x0070, 0x0200E800); ++ usleep_range(150, 500); ++ ++ /* Switch to P0 */ ++ regmap_write(pextp, 0x0070, 0x0200C111); ++ ndelay(1020); ++ regmap_write(pextp, 0x0070, 0x0200C101); ++ usleep_range(15, 50); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) { ++ /* Switch to Gen3 */ ++ regmap_write(pextp, 0x0070, 0x0202C111); ++ } else { ++ /* Switch to Gen2 */ ++ regmap_write(pextp, 0x0070, 0x0201C111); ++ } ++ ndelay(1020); ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x0070, 0x0202C101); ++ else ++ regmap_write(pextp, 0x0070, 0x0201C101); ++ usleep_range(100, 500); ++ regmap_write(pextp, 0x30B0, 0x00000030); ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x00F4, 0x80201F00); ++ else ++ regmap_write(pextp, 0x00F4, 0x80201F01); ++ ++ regmap_write(pextp, 0x3040, 0x30000000); ++ usleep_range(400, 1000); ++} ++ ++static void mtk_usxgmii_reset(struct mtk_eth *eth, int id) ++{ ++ u32 toggle, val; ++ ++ if (id >= MTK_MAX_DEVS || !eth->toprgu) ++ return; ++ ++ switch (id) { ++ case 0: ++ toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST | ++ SWSYSRST_SGMII0_GRST; ++ break; ++ case 1: ++ toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST | ++ SWSYSRST_SGMII1_GRST; ++ break; ++ default: ++ return; ++ } ++ ++ /* Enable software reset */ ++ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); ++ ++ /* Assert USXGMII reset */ ++ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST, ++ FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle); ++ ++ usleep_range(100, 500); ++ ++ /* De-assert USXGMII reset */ ++ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); ++ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); ++ val &= ~toggle; ++ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); ++ ++ /* Disable software reset */ ++ regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); ++ ++ mdelay(10); ++} ++ ++/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit ++ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config ++ * also trigger an initial reset and subsequent configuration of the PHYA. ++ */ ++struct mtk_sgmii_wrapper_pcs { ++ struct mtk_eth *eth; ++ struct phylink_pcs *wrapped_pcs; ++ u8 id; ++ struct phylink_pcs pcs; ++}; ++ ++static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs, ++ unsigned int mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ bool full_reconf; ++ int ret; ++ ++ full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface; ++ if (full_reconf) { ++ mtk_xfi_pll_enable(wp->eth); ++ mtk_usxgmii_reset(wp->eth, wp->id); ++ } ++ ++ ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface, ++ advertising, permit_pause_to_mac); ++ ++ if (full_reconf) ++ mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id); ++ ++ wp->eth->usxgmii_pcs[wp->id]->interface = interface; ++ ++ return ret; ++} ++ ++static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state); ++} ++ ++static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs); ++} ++ ++static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs, ++ unsigned int mode, ++ phy_interface_t interface, int speed, ++ int duplex) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex); ++} ++ ++static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs); ++ ++ wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA; ++} ++ ++static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = { ++ .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state, ++ .pcs_config = mtk_sgmii_wrapped_pcs_config, ++ .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart, ++ .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up, ++ .pcs_disable = mtk_sgmii_wrapped_pcs_disable, ++}; ++ ++static int mtk_sgmii_wrapper_init(struct mtk_eth *eth) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp; ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->sgmii_pcs[i]) ++ continue; ++ ++ if (!eth->usxgmii_pcs[i]) ++ continue; ++ ++ /* Make sure all PCS ops are supported by wrapped PCS */ ++ if (!eth->sgmii_pcs[i]->ops->pcs_get_state || ++ !eth->sgmii_pcs[i]->ops->pcs_config || ++ !eth->sgmii_pcs[i]->ops->pcs_an_restart || ++ !eth->sgmii_pcs[i]->ops->pcs_link_up || ++ !eth->sgmii_pcs[i]->ops->pcs_disable) ++ return -EOPNOTSUPP; ++ ++ wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL); ++ if (!wp) ++ return -ENOMEM; ++ ++ wp->wrapped_pcs = eth->sgmii_pcs[i]; ++ wp->id = i; ++ wp->pcs.poll = true; ++ wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops; ++ wp->eth = eth; ++ ++ eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs; ++ } ++ ++ return 0; ++} ++ ++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id) ++{ ++ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); ++ ++ if (!eth->usxgmii_pcs[xgmii_id]) ++ return NULL; ++ ++ return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs; ++} ++ ++static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ struct mtk_eth *eth = mpcs->eth; ++ struct regmap *pextp = eth->regmap_pextp[mpcs->id]; ++ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; ++ bool mode_changed = false; ++ ++ if (!pextp) ++ return -ENODEV; ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); ++ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else { ++ return -EINVAL; ++ } ++ ++ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); ++ ++ if (mpcs->interface != interface) { ++ mpcs->interface = interface; ++ mode_changed = true; ++ } ++ ++ mtk_xfi_pll_enable(eth); ++ mtk_usxgmii_reset(eth, mpcs->id); ++ ++ /* Setup USXGMII AN ctrl */ ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0, ++ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, ++ an_ctrl); ++ ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2, ++ USXGMII_LINK_TIMER_IDLE_DETECT | ++ USXGMII_LINK_TIMER_COMP_ACK_DETECT | ++ USXGMII_LINK_TIMER_AN_RESTART, ++ link_timer); ++ ++ mpcs->mode = mode; ++ ++ /* Gated MAC CK */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); ++ ++ /* Enable interface force mode */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); ++ ++ /* Setup USXGMII adapt mode */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, ++ adapt_mode); ++ ++ /* Setup USXGMII speed */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, ++ xfi_mode); ++ ++ usleep_range(1, 10); ++ ++ /* Un-gated MAC CK */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_MAC_CK_GATED, 0); ++ ++ usleep_range(1, 10); ++ ++ /* Disable interface force mode for the AN mode */ ++ if (an_ctrl & USXGMII_AN_ENABLE) ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_IF_FORCE_EN, 0); ++ ++ /* Setup USXGMIISYS with the determined property */ ++ mtk_usxgmii_setup_phya(pextp, interface, mpcs->id); ++ ++ return mode_changed; ++} ++ ++static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ struct mtk_eth *eth = mpcs->eth; ++ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)]; ++ u32 val = 0; ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); ++ if (FIELD_GET(USXGMII_AN_ENABLE, val)) { ++ /* Refresh LPA by inverting LPA_LATCH */ ++ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0, ++ USXGMII_LPA_LATCH, ++ !(val & USXGMII_LPA_LATCH)); ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); ++ ++ phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD, ++ val)); ++ ++ state->interface = mpcs->interface; ++ } else { ++ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); ++ ++ if (mac->id == MTK_GMAC2_ID) ++ val >>= 16; ++ ++ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) { ++ case 0: ++ state->speed = SPEED_10000; ++ break; ++ case 1: ++ state->speed = SPEED_5000; ++ break; ++ case 2: ++ state->speed = SPEED_2500; ++ break; ++ case 3: ++ state->speed = SPEED_1000; ++ break; ++ } ++ ++ state->interface = mpcs->interface; ++ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val); ++ state->duplex = DUPLEX_FULL; ++ } ++ ++ /* Continuously repeat re-configuration sequence until link comes up */ ++ if (state->link == 0) ++ mtk_usxgmii_pcs_config(pcs, mpcs->mode, ++ state->interface, NULL, false); ++} ++ ++static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ unsigned int val = 0; ++ ++ if (!mpcs->regmap) ++ return; ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); ++ val |= USXGMII_AN_RESTART; ++ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val); ++} ++ ++static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, ++ int speed, int duplex) ++{ ++ /* Reconfiguring USXGMII to ensure the quality of the RX signal ++ * after the line side link up. ++ */ ++ mtk_usxgmii_pcs_config(pcs, mode, ++ interface, NULL, false); ++} ++ ++static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { ++ .pcs_config = mtk_usxgmii_pcs_config, ++ .pcs_get_state = mtk_usxgmii_pcs_get_state, ++ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, ++ .pcs_link_up = mtk_usxgmii_pcs_link_up, ++}; ++ ++int mtk_usxgmii_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device *dev = eth->dev; ++ struct device_node *np; ++ int i, ret; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ np = of_parse_phandle(r, "mediatek,usxgmiisys", i); ++ if (!np) ++ break; ++ ++ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL); ++ if (!eth->usxgmii_pcs[i]) ++ return -ENOMEM; ++ ++ eth->usxgmii_pcs[i]->id = i; ++ eth->usxgmii_pcs[i]->eth = eth; ++ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->usxgmii_pcs[i]->regmap)) ++ return PTR_ERR(eth->usxgmii_pcs[i]->regmap); ++ ++ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops; ++ eth->usxgmii_pcs[i]->pcs.poll = true; ++ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA; ++ eth->usxgmii_pcs[i]->mode = -1; ++ ++ of_node_put(np); ++ } ++ ++ ret = mtk_xfi_pextp_init(eth); ++ if (ret) ++ return ret; ++ ++ ret = mtk_xfi_pll_init(eth); ++ if (ret) ++ return ret; ++ ++ ret = mtk_toprgu_init(eth); ++ if (ret) ++ return ret; ++ ++ return mtk_sgmii_wrapper_init(eth); ++} ++ ++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id) ++{ ++ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); ++ ++ if (!eth->usxgmii_pcs[xgmii_id]->regmap) ++ return NULL; ++ ++ return ð->usxgmii_pcs[xgmii_id]->pcs; ++} diff --git a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch b/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch index 54c07f002..ec3e57031 100644 --- a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch +++ b/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch @@ -17,7 +17,7 @@ Signed-off-by: Alexander Duyck --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -4360,6 +4360,15 @@ int skb_gro_receive(struct sk_buff *p, s +@@ -4371,6 +4371,15 @@ int skb_gro_receive(struct sk_buff *p, s if (unlikely(p->len + len >= 65536 || NAPI_GRO_CB(skb)->flush)) return -E2BIG; diff --git a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch index 1fde953e4..2e9f81263 100644 --- a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch +++ b/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch @@ -162,7 +162,7 @@ Signed-off-by: Felix Fietkau void netif_napi_add(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight) { -@@ -11399,6 +11474,9 @@ static int dev_cpu_dead(unsigned int old +@@ -11400,6 +11475,9 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); @@ -172,7 +172,7 @@ Signed-off-by: Felix Fietkau #ifdef CONFIG_RPS remsd = oldsd->rps_ipi_list; oldsd->rps_ipi_list = NULL; -@@ -11738,6 +11816,7 @@ static int __init net_dev_init(void) +@@ -11739,6 +11817,7 @@ static int __init net_dev_init(void) sd->cpu = i; #endif diff --git a/target/linux/generic/pending-5.15/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch b/target/linux/generic/pending-5.15/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch index 9e97a75ec..66db25022 100644 --- a/target/linux/generic/pending-5.15/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +++ b/target/linux/generic/pending-5.15/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch @@ -17,7 +17,7 @@ Signed-off-by: DENG Qingfang --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3215,6 +3215,7 @@ static int mv88e6xxx_setup(struct dsa_sw +@@ -3225,6 +3225,7 @@ static int mv88e6xxx_setup(struct dsa_sw chip->ds = ds; ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip); diff --git a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch index c9494db90..c73f894ad 100644 --- a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ b/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch @@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -6344,6 +6344,7 @@ static int mv88e6xxx_register_switch(str +@@ -6386,6 +6386,7 @@ static int mv88e6xxx_register_switch(str ds->ops = &mv88e6xxx_switch_ops; ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; diff --git a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch index 06546b79e..609e03d96 100644 --- a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch +++ b/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch @@ -16,7 +16,7 @@ Signed-off-by: David Bauer --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2335,10 +2335,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2356,10 +2356,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr { struct dsa_switch *ds = priv->ds; struct device *dev = priv->dev; @@ -30,7 +30,7 @@ Signed-off-by: David Bauer bus = devm_mdiobus_alloc(dev); if (!bus) return -ENOMEM; -@@ -2355,7 +2358,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2376,7 +2379,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr if (priv->irq) mt7530_setup_mdio_irq(priv); diff --git a/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch new file mode 100644 index 000000000..c5db5d949 --- /dev/null +++ b/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch @@ -0,0 +1,61 @@ +From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001 +Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org> +From: Daniel Golle +Date: Mon, 11 Sep 2023 21:27:44 +0100 +Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error +To: Greg Kroah-Hartman , + Jiri Slaby , + Matthias Brugger , + AngeloGioacchino Del Regno , + Daniel Golle , + John Ogness , + Chen-Yu Tsai , + Changqi Hu , + linux-kernel@vger.kernel.org, + linux-serial@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, + linux-mediatek@lists.infradead.org + +Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and +clock management") introduced polling a debug register to make sure +the UART is idle before disabling the bus clock. However, at least on +some MediaTek SoCs access to that very debug register requires the bus +clock being enabled. Hence calling the suspend function while already +in suspended state results in that register access triggering a bus +error. In order to avoid that, track the state of the bus clock and +only poll the debug register if not already in suspended state. + +Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management") +Signed-off-by: Daniel Golle +--- + drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/8250/8250_mtk.c ++++ b/drivers/tty/serial/8250/8250_mtk.c +@@ -32,7 +32,7 @@ + #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ + #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ + #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ +-#define MTK_UART_DEBUG0 0x18 ++#define MTK_UART_DEBUG0 0x18 + #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ + #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ + #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ +@@ -418,13 +418,12 @@ static int __maybe_unused mtk8250_runtim + struct mtk8250_data *data = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(data->line); + +- /* wait until UART in idle status */ +- while +- (serial_in(up, MTK_UART_DEBUG0)); +- + if (data->clk_count == 0U) { + dev_dbg(dev, "%s clock count is 0\n", __func__); + } else { ++ /* wait until UART in idle status */ ++ while ++ (serial_in(up, MTK_UART_DEBUG0)); + clk_disable_unprepare(data->bus_clk); + data->clk_count--; + } diff --git a/target/linux/generic/pending-5.15/901-usb-add-more-modem-support.patch b/target/linux/generic/pending-5.15/901-usb-add-more-modem-support.patch index 53d3feeaf..91f621126 100644 --- a/target/linux/generic/pending-5.15/901-usb-add-more-modem-support.patch +++ b/target/linux/generic/pending-5.15/901-usb-add-more-modem-support.patch @@ -1,9 +1,9 @@ --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c -@@ -1420,6 +1420,9 @@ static const struct usb_device_id produc - {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ +@@ -1424,6 +1424,9 @@ static const struct usb_device_id produc {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ + {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ + {QMI_FIXED_INTF(0x2077, 0x2002, 4)}, /* T&W TW04C */ + {QMI_FIXED_INTF(0x2077, 0x2003, 4)}, /* T&W TW12G */ + {QMI_FIXED_INTF(0x2077, 0x2004, 4)}, /* T&W TW510M */ @@ -12,16 +12,17 @@ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c -@@ -2277,6 +2277,12 @@ static const struct usb_device_id option - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */ - .driver_info = RSVD(4) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a04, 0xff), /* Fibocom FM650 ECM */ -+ .driver_info = RSVD(5) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff), /* Fibocom FM650 NCM */ -+ .driver_info = RSVD(6) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff), /* Fibocom FM650 RNDIS */ -+ .driver_info = RSVD(6) }, +@@ -2310,9 +2310,13 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1402, 0xff) }, /* GosunCn GM800 (Download mode) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1403, 0xff) }, /* GosunCn GM800 (rmnet, old) */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1421, 0xff) }, /* GosunCn GM800 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1422, 0xff) }, /* GosunCn GM800 (EAP) */ + { USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ diff --git a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch b/target/linux/generic/pending-5.15/920-mangle_bootargs.patch index a8c084b98..b127d76e0 100644 --- a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-5.15/920-mangle_bootargs.patch @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -958,6 +981,7 @@ asmlinkage __visible void __init __no_sa +@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch index fcf3aa035..0e26ccb39 100644 --- a/target/linux/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ b/target/linux/generic/pending-5.4/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch @@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -6947,7 +6947,7 @@ static void __ref alloc_node_mem_map(str +@@ -6949,7 +6949,7 @@ static void __ref alloc_node_mem_map(str mem_map = NODE_DATA(0)->node_mem_map; #if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM) if (page_to_pfn(mem_map) != pgdat->node_start_pfn) diff --git a/target/linux/generic/pending-5.4/630-packet_socket_type.patch b/target/linux/generic/pending-5.4/630-packet_socket_type.patch index 7370f5eda..9b218614e 100644 --- a/target/linux/generic/pending-5.4/630-packet_socket_type.patch +++ b/target/linux/generic/pending-5.4/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3317,6 +3319,7 @@ static int packet_create(struct net *net +@@ -3316,6 +3318,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3956,6 +3959,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3955,6 +3958,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4012,6 +4025,13 @@ static int packet_getsockopt(struct sock +@@ -4011,6 +4024,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch b/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch index 2d71dddf3..386a81945 100644 --- a/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch +++ b/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch @@ -506,7 +506,7 @@ Signed-off-by: Pablo Neira Ayuso +MODULE_ALIAS("nf-flow-table-hw"); --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c -@@ -6006,6 +6006,13 @@ static int nf_tables_flowtable_parse_hoo +@@ -6045,6 +6045,13 @@ static int nf_tables_flowtable_parse_hoo if (err < 0) return err; @@ -520,7 +520,7 @@ Signed-off-by: Pablo Neira Ayuso ops = kcalloc(n, sizeof(struct nf_hook_ops), GFP_KERNEL); if (!ops) return -ENOMEM; -@@ -6150,10 +6157,19 @@ static int nf_tables_newflowtable(struct +@@ -6194,10 +6201,19 @@ static int nf_tables_newflowtable(struct } flowtable->data.type = type; @@ -540,7 +540,7 @@ Signed-off-by: Pablo Neira Ayuso err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], flowtable); if (err < 0) -@@ -6279,7 +6295,8 @@ static int nf_tables_fill_flowtable_info +@@ -6323,7 +6339,8 @@ static int nf_tables_fill_flowtable_info nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) || nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle), diff --git a/target/linux/generic/pending-5.4/655-increase_skb_pad.patch b/target/linux/generic/pending-5.4/655-increase_skb_pad.patch index 3ca190f0a..ff39ddb8b 100644 --- a/target/linux/generic/pending-5.4/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-5.4/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2661,7 +2661,7 @@ static inline int pskb_network_may_pull( +@@ -2676,7 +2676,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD diff --git a/target/linux/generic/pending-5.4/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.4/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch index abb27cb33..e848e0072 100644 --- a/target/linux/generic/pending-5.4/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ b/target/linux/generic/pending-5.4/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -110,7 +110,7 @@ Signed-off-by: Jonas Gorski return -EINVAL; --- a/net/ipv6/route.c +++ b/net/ipv6/route.c -@@ -94,6 +94,8 @@ static int ip6_pkt_discard(struct sk_bu +@@ -95,6 +95,8 @@ static int ip6_pkt_discard(struct sk_bu static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); static int ip6_pkt_prohibit(struct sk_buff *skb); static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); @@ -119,7 +119,7 @@ Signed-off-by: Jonas Gorski static void ip6_link_failure(struct sk_buff *skb); static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, -@@ -327,6 +329,18 @@ static const struct rt6_info ip6_prohibi +@@ -328,6 +330,18 @@ static const struct rt6_info ip6_prohibi .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), }; @@ -138,7 +138,7 @@ Signed-off-by: Jonas Gorski static const struct rt6_info ip6_blk_hole_entry_template = { .dst = { .__refcnt = ATOMIC_INIT(1), -@@ -1048,6 +1062,7 @@ static const int fib6_prop[RTN_MAX + 1] +@@ -1049,6 +1063,7 @@ static const int fib6_prop[RTN_MAX + 1] [RTN_BLACKHOLE] = -EINVAL, [RTN_UNREACHABLE] = -EHOSTUNREACH, [RTN_PROHIBIT] = -EACCES, @@ -146,7 +146,7 @@ Signed-off-by: Jonas Gorski [RTN_THROW] = -EAGAIN, [RTN_NAT] = -EINVAL, [RTN_XRESOLVE] = -EINVAL, -@@ -1085,6 +1100,10 @@ static void ip6_rt_init_dst_reject(struc +@@ -1086,6 +1101,10 @@ static void ip6_rt_init_dst_reject(struc rt->dst.output = ip6_pkt_prohibit_out; rt->dst.input = ip6_pkt_prohibit; break; @@ -157,7 +157,7 @@ Signed-off-by: Jonas Gorski case RTN_THROW: case RTN_UNREACHABLE: default: -@@ -4454,6 +4473,17 @@ static int ip6_pkt_prohibit_out(struct n +@@ -4458,6 +4477,17 @@ static int ip6_pkt_prohibit_out(struct n return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); } @@ -175,7 +175,7 @@ Signed-off-by: Jonas Gorski /* * Allocate a dst for local (unicast / anycast) address. */ -@@ -4941,7 +4971,8 @@ static int rtm_to_fib6_config(struct sk_ +@@ -4945,7 +4975,8 @@ static int rtm_to_fib6_config(struct sk_ if (rtm->rtm_type == RTN_UNREACHABLE || rtm->rtm_type == RTN_BLACKHOLE || rtm->rtm_type == RTN_PROHIBIT || @@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski cfg->fc_flags |= RTF_REJECT; if (rtm->rtm_type == RTN_LOCAL) -@@ -6086,6 +6117,8 @@ static int ip6_route_dev_notify(struct n +@@ -6090,6 +6121,8 @@ static int ip6_route_dev_notify(struct n #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry->dst.dev = dev; net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); @@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.dev = dev; net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); #endif -@@ -6097,6 +6130,7 @@ static int ip6_route_dev_notify(struct n +@@ -6101,6 +6134,7 @@ static int ip6_route_dev_notify(struct n in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); @@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); #endif } -@@ -6289,6 +6323,8 @@ static int __net_init ip6_route_net_init +@@ -6293,6 +6327,8 @@ static int __net_init ip6_route_net_init #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.fib6_has_custom_rules = false; @@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, sizeof(*net->ipv6.ip6_prohibit_entry), GFP_KERNEL); -@@ -6299,11 +6335,21 @@ static int __net_init ip6_route_net_init +@@ -6303,11 +6339,21 @@ static int __net_init ip6_route_net_init ip6_template_metrics, true); INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); @@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, ip6_template_metrics, true); -@@ -6327,6 +6373,8 @@ out: +@@ -6331,6 +6377,8 @@ out: return ret; #ifdef CONFIG_IPV6_MULTIPLE_TABLES @@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski out_ip6_prohibit_entry: kfree(net->ipv6.ip6_prohibit_entry); out_ip6_null_entry: -@@ -6346,6 +6394,7 @@ static void __net_exit ip6_route_net_exi +@@ -6350,6 +6398,7 @@ static void __net_exit ip6_route_net_exi kfree(net->ipv6.ip6_null_entry); #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); @@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski kfree(net->ipv6.ip6_blk_hole_entry); #endif dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -6429,6 +6478,9 @@ void __init ip6_route_init_special_entri +@@ -6433,6 +6482,9 @@ void __init ip6_route_init_special_entri init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); diff --git a/target/linux/generic/pending-5.4/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.4/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index 6f7edc161..6fe3df256 100644 --- a/target/linux/generic/pending-5.4/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-5.4/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -136,14 +136,13 @@ Signed-off-by: Felix Fietkau /** * eth_type_trans - determine the packet's protocol ID. * @skb: received socket data -@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk - } else { - skb->pkt_type = PACKET_OTHERHOST; - } -+ -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; - } +@@ -166,6 +178,9 @@ __be16 eth_type_trans(struct sk_buff *sk + eth_skb_pkt_type(skb, dev); + ++ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, ++ dev->local_addr_mask)) ++ skb->gro_skip = 1; /* + * Some variants of DSA tagging don't have an ethertype field + * at all, so we check here whether one of those tagging diff --git a/target/linux/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch index 4d6e0f99d..93c414b63 100644 --- a/target/linux/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ b/target/linux/generic/pending-5.4/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch @@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -5098,6 +5098,7 @@ static int mv88e6xxx_register_switch(str +@@ -5123,6 +5123,7 @@ static int mv88e6xxx_register_switch(str ds->ops = &mv88e6xxx_switch_ops; ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; diff --git a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch index 0ebfa4bbd..77a94dae8 100644 --- a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4722,6 +4722,8 @@ static int mtk_probe(struct platform_dev +@@ -4939,6 +4939,8 @@ static int mtk_probe(struct platform_dev * for NAPI to work */ init_dummy_netdev(ð->dummy_dev); diff --git a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch index 48b1afe3f..8d2803158 100644 --- a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1750,6 +1750,9 @@ void phy_detach(struct phy_device *phyde +@@ -1753,6 +1753,9 @@ void phy_detach(struct phy_device *phyde struct module *ndev_owner = NULL; struct mii_bus *bus; @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos sysfs_remove_link(&dev->dev.kobj, "phydev"); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -858,6 +858,12 @@ struct phy_driver { +@@ -878,6 +878,12 @@ struct phy_driver { /** @handle_interrupt: Override default interrupt handling */ irqreturn_t (*handle_interrupt)(struct phy_device *phydev); diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch new file mode 100644 index 000000000..decf647bc --- /dev/null +++ b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch @@ -0,0 +1,44 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 23:39:52 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code + on mt7621 + +Avoid some branches in the hot path on low-end devices with limited CPU power, +and reduce code size + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1326,6 +1326,22 @@ struct mtk_mac { + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ + extern const struct of_device_id of_mtk_match[]; + ++#ifdef CONFIG_SOC_MT7621 ++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) ++{ ++ return true; ++} ++ ++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) ++{ ++ return false; ++} ++ ++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) ++{ ++ return false; ++} ++#else + static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) + { + return eth->soc->version == 1; +@@ -1340,6 +1356,7 @@ static inline bool mtk_is_netsys_v3_or_g + { + return eth->soc->version > 2; + } ++#endif + + static inline struct mtk_foe_entry * + mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) diff --git a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch index 9c162aab5..600109a95 100644 --- a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1468,12 +1468,28 @@ static void mtk_wake_queue(struct mtk_et +@@ -1561,12 +1561,28 @@ static void mtk_wake_queue(struct mtk_et } } @@ -45,11 +45,11 @@ Signed-off-by: Felix Fietkau bool gso = false; int tx_num; -@@ -1495,6 +1511,18 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1588,6 +1604,18 @@ static netdev_tx_t mtk_start_xmit(struct return NETDEV_TX_BUSY; } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ if (mtk_is_netsys_v1(eth) && + skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { + segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); + if (IS_ERR(segs)) @@ -64,14 +64,14 @@ Signed-off-by: Felix Fietkau /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { -@@ -1510,8 +1538,14 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1603,8 +1631,14 @@ static netdev_tx_t mtk_start_xmit(struct } } - if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) - goto drop; + skb_list_walk_safe(skb, skb, next) { -+ if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ if ((mtk_is_netsys_v1(eth) && + mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || + mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { + stats->tx_dropped++; @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau netif_tx_stop_all_queues(dev); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -258,7 +258,7 @@ +@@ -268,7 +268,7 @@ #define MTK_CHK_DDONE_EN BIT(28) #define MTK_DMAD_WR_WDONE BIT(26) #define MTK_WCOMP_EN BIT(24) diff --git a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch index 3c6359ee4..11a81dd0b 100644 --- a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -48,8 +48,7 @@ +@@ -47,8 +47,7 @@ #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ NETIF_F_RXCSUM | \ NETIF_F_HW_VLAN_CTAG_TX | \ diff --git a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch index 3d11da2be..1a3f56e94 100644 --- a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch +++ b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -709,6 +709,7 @@ static void mtk_mac_link_up(struct phyli +@@ -765,6 +765,7 @@ static void mtk_mac_link_up(struct phyli MAC_MCR_FORCE_RX_FC); /* Configure speed */ @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau switch (speed) { case SPEED_2500: case SPEED_1000: -@@ -3203,6 +3204,9 @@ found: +@@ -3346,6 +3347,9 @@ found: if (dp->index >= MTK_QDMA_NUM_QUEUES) return NOTIFY_DONE; diff --git a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch index dc2163959..72d574340 100644 --- a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch +++ b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau #include #include "mtk_eth_soc.h" #include "mtk_ppe.h" -@@ -752,7 +753,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -775,7 +776,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) goto out; diff --git a/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch index c5654a606..c29c63bb1 100644 --- a/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch +++ b/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch @@ -11,10 +11,15 @@ PPE device. Signed-off-by: Felix Fietkau --- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 + + .../net/ethernet/mediatek/mtk_ppe_offload.c | 37 ++++--- + drivers/net/ethernet/mediatek/mtk_wed.c | 101 ++++++++++++++++++ + include/linux/soc/mediatek/mtk_wed.h | 6 ++ + 4 files changed, 133 insertions(+), 14 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1280,6 +1280,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk +@@ -1451,6 +1451,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk int mtk_eth_offload_init(struct mtk_eth *eth); int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data); @@ -120,7 +125,7 @@ Signed-off-by: Felix Fietkau static void wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) { -@@ -1745,6 +1752,99 @@ out: +@@ -1753,6 +1760,99 @@ out: mutex_unlock(&hw_lock); } @@ -220,7 +225,7 @@ Signed-off-by: Felix Fietkau void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, void __iomem *wdma, phys_addr_t wdma_phy, int index) -@@ -1764,6 +1864,7 @@ void mtk_wed_add_hw(struct device_node * +@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node * .irq_set_mask = mtk_wed_irq_set_mask, .detach = mtk_wed_detach, .ppe_check = mtk_wed_ppe_check, diff --git a/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch index 08036e0b1..74cb562a5 100644 --- a/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch +++ b/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -634,10 +634,20 @@ void mtk_foe_entry_clear(struct mtk_ppe +@@ -657,10 +657,20 @@ void mtk_foe_entry_clear(struct mtk_ppe static int mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { diff --git a/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch index ec04fb354..ecdb345d6 100644 --- a/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch +++ b/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch @@ -9,10 +9,13 @@ flow accounting support. Signed-off-by: Felix Fietkau --- + drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------ + drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +-- + 2 files changed, 86 insertions(+), 91 deletions(-) --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -460,42 +460,43 @@ int mtk_foe_entry_set_queue(struct mtk_e +@@ -477,42 +477,43 @@ int mtk_foe_entry_set_queue(struct mtk_e return 0; } @@ -72,7 +75,7 @@ Signed-off-by: Felix Fietkau struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -515,7 +516,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp +@@ -532,7 +533,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) return; @@ -82,7 +85,7 @@ Signed-off-by: Felix Fietkau kfree(entry); } -@@ -531,66 +533,55 @@ static int __mtk_foe_entry_idle_time(str +@@ -548,66 +550,55 @@ static int __mtk_foe_entry_idle_time(str return now - timestamp; } @@ -178,7 +181,7 @@ Signed-off-by: Felix Fietkau } static void -@@ -627,7 +618,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -650,7 +641,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { spin_lock_bh(&ppe_lock); @@ -188,7 +191,7 @@ Signed-off-by: Felix Fietkau spin_unlock_bh(&ppe_lock); } -@@ -674,8 +666,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ +@@ -697,8 +689,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ { const struct mtk_soc_data *soc = ppe->eth->soc; struct mtk_flow_entry *flow_info; @@ -198,7 +201,7 @@ Signed-off-by: Felix Fietkau u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; int type; -@@ -683,30 +675,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ +@@ -706,30 +698,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ if (!flow_info) return; @@ -239,7 +242,7 @@ Signed-off-by: Felix Fietkau } void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -716,9 +708,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -739,9 +731,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); struct mtk_flow_entry *entry; struct mtk_foe_bridge key = {}; @@ -251,7 +254,7 @@ Signed-off-by: Felix Fietkau u8 *tag; spin_lock_bh(&ppe_lock); -@@ -726,20 +720,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe +@@ -749,20 +743,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) goto out; @@ -278,7 +281,7 @@ Signed-off-by: Felix Fietkau continue; } -@@ -790,9 +778,17 @@ out: +@@ -813,9 +801,17 @@ out: int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) { @@ -300,7 +303,7 @@ Signed-off-by: Felix Fietkau int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -265,7 +265,12 @@ enum { +@@ -286,7 +286,12 @@ enum { struct mtk_flow_entry { union { @@ -314,7 +317,7 @@ Signed-off-by: Felix Fietkau struct { struct rhash_head l2_node; struct hlist_head l2_flows; -@@ -275,13 +280,7 @@ struct mtk_flow_entry { +@@ -296,13 +301,7 @@ struct mtk_flow_entry { s8 wed_index; u8 ppe_index; u16 hash; diff --git a/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch index 79386d6cf..e323baeb1 100644 --- a/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch +++ b/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch @@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau if (ret) dev_err(ppe->dev, "MIB table busy"); -@@ -90,18 +90,32 @@ static int mtk_ppe_mib_wait_busy(struct +@@ -90,17 +90,31 @@ static int mtk_ppe_mib_wait_busy(struct return ret; } @@ -43,7 +43,6 @@ Signed-off-by: Felix Fietkau + +struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) { - u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; u32 val, cnt_r0, cnt_r1, cnt_r2; + struct mtk_foe_accounting *acct; int ret; @@ -62,22 +61,32 @@ Signed-off-by: Felix Fietkau cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -111,10 +125,11 @@ static int mtk_mib_entry_read(struct mtk - byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; +@@ -109,19 +123,19 @@ static int mtk_mib_entry_read(struct mtk + if (mtk_is_netsys_v3_or_greater(ppe->eth)) { + /* 64 bit for each counter */ + u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); +- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; +- *packets = ((u64)cnt_r3 << 32) | cnt_r2; ++ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; ++ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; + } else { + /* 48 bit byte counter, 40 bit packet counter */ + u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); + u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); + u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); + u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); +- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; +- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; + } - return 0; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; -+ + return acct; } static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -503,13 +518,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp +@@ -520,13 +534,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); dma_wmb(); mtk_ppe_cache_clear(ppe); @@ -91,7 +100,7 @@ Signed-off-by: Felix Fietkau } entry->hash = 0xffff; -@@ -534,11 +542,14 @@ static int __mtk_foe_entry_idle_time(str +@@ -551,11 +558,14 @@ static int __mtk_foe_entry_idle_time(str } static bool @@ -107,7 +116,7 @@ Signed-off-by: Felix Fietkau int len; if (hash == 0xffff) -@@ -549,18 +560,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp +@@ -566,18 +576,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp memcpy(&foe, hwe, len); if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || @@ -146,7 +155,7 @@ Signed-off-by: Felix Fietkau struct mtk_flow_entry *cur; struct hlist_node *tmp; int idle; -@@ -569,7 +597,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe +@@ -586,7 +613,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { int cur_idle; @@ -157,7 +166,7 @@ Signed-off-by: Felix Fietkau __mtk_foe_entry_clear(ppe, entry, false); continue; } -@@ -584,10 +614,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe +@@ -601,10 +630,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe } } @@ -187,7 +196,7 @@ Signed-off-by: Felix Fietkau struct mtk_eth *eth = ppe->eth; u16 timestamp = mtk_eth_timestamp(eth); struct mtk_foe_entry *hwe; -@@ -612,6 +661,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p +@@ -635,6 +683,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p dma_wmb(); @@ -200,7 +209,7 @@ Signed-off-by: Felix Fietkau mtk_ppe_cache_clear(ppe); } -@@ -776,21 +831,6 @@ out: +@@ -799,21 +853,6 @@ out: spin_unlock_bh(&ppe_lock); } @@ -222,7 +231,7 @@ Signed-off-by: Felix Fietkau int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) { if (!ppe) -@@ -818,32 +858,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe +@@ -841,32 +880,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe return mtk_ppe_wait_busy(ppe); } @@ -257,7 +266,7 @@ Signed-off-by: Felix Fietkau bool accounting = eth->soc->has_accounting; --- a/drivers/net/ethernet/mediatek/mtk_ppe.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -283,6 +283,8 @@ struct mtk_flow_entry { +@@ -304,6 +304,8 @@ struct mtk_flow_entry { struct mtk_foe_entry data; struct rhash_head node; unsigned long cookie; @@ -266,7 +275,7 @@ Signed-off-by: Felix Fietkau }; struct mtk_mib_entry { -@@ -326,6 +328,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) +@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); @@ -274,7 +283,7 @@ Signed-off-by: Felix Fietkau void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); -@@ -374,9 +377,8 @@ int mtk_foe_entry_set_queue(struct mtk_e +@@ -396,9 +399,8 @@ int mtk_foe_entry_set_queue(struct mtk_e unsigned int queue); int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); @@ -295,7 +304,7 @@ Signed-off-by: Felix Fietkau - acct = mtk_foe_entry_get_mib(ppe, i, NULL); + acct = mtk_ppe_mib_entry_read(ppe, i); - type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); + type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); seq_printf(m, "%05x %s %7s", i, --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c diff --git a/target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch b/target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch deleted file mode 100644 index 4eee1b367..000000000 --- a/target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:13 +0000 -Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability - bit - -Introduce MTK_NETSYS_V1 bit in the device capabilities for -MT7621/MT7622/MT7623/MT7628/MT7629 SoCs. -Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++--------- - 2 files changed, 41 insertions(+), 34 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -639,7 +639,7 @@ static void mtk_set_queue_speed(struct m - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - - if (IS_ENABLED(CONFIG_SOC_MT7621)) { -@@ -1017,7 +1017,7 @@ static bool mtk_rx_get_desc(struct mtk_e - rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); - rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); - rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); - rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); - } -@@ -1075,7 +1075,7 @@ static int mtk_init_fq_dma(struct mtk_et - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -1266,7 +1266,7 @@ static void mtk_tx_set_dma_desc(struct n - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - mtk_tx_set_dma_desc_v2(dev, txd, info); - else - mtk_tx_set_dma_desc_v1(dev, txd, info); -@@ -1949,7 +1949,7 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -@@ -2045,7 +2045,7 @@ static int mtk_poll_rx(struct napi_struc - skb->dev = netdev; - bytes += skb->len; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) -@@ -2070,7 +2070,7 @@ static int mtk_poll_rx(struct napi_struc - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) && - (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { - unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - -@@ -2381,7 +2381,7 @@ static int mtk_tx_alloc(struct mtk_eth * - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -2434,7 +2434,7 @@ static int mtk_tx_alloc(struct mtk_eth * - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - ofs += MTK_QTX_OFFSET; -@@ -2570,7 +2570,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - rxd->rxd3 = 0; - rxd->rxd4 = 0; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - rxd->rxd5 = 0; - rxd->rxd6 = 0; - rxd->rxd7 = 0; -@@ -3121,7 +3121,7 @@ static int mtk_start_dma(struct mtk_eth - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; -@@ -3531,7 +3531,7 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); - val = RSTCTRL_PPE0_V2; - } else { -@@ -3543,7 +3543,7 @@ static void mtk_hw_reset(struct mtk_eth - - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3739,7 +3739,7 @@ static int mtk_hw_init(struct mtk_eth *e - else - mtk_hw_reset(eth); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); -@@ -3776,7 +3776,7 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -819,6 +819,7 @@ enum mkt_eth_capabilities { - MTK_SHARED_INT_BIT, - MTK_TRGMII_MT7621_CLK_BIT, - MTK_QDMA_BIT, -+ MTK_NETSYS_V1_BIT, - MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -@@ -854,6 +855,7 @@ enum mkt_eth_capabilities { - #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) - #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) - #define MTK_QDMA BIT(MTK_QDMA_BIT) -+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT) - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -@@ -916,25 +918,30 @@ enum mkt_eth_capabilities { - - #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x)) - --#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -- MTK_GMAC2_RGMII | MTK_SHARED_INT | \ -- MTK_TRGMII_MT7621_CLK | MTK_QDMA) -- --#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \ -- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \ -- MTK_MUX_GDM1_TO_GMAC1_ESW | \ -- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA) -- --#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \ -- MTK_QDMA) -- --#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628) -- --#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ -- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \ -- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \ -- MTK_MUX_U3_GMAC2_TO_QPHY | \ -- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) -+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \ -+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \ -+ MTK_NETSYS_V1) -+ -+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \ -+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \ -+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\ -+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \ -+ MTK_QDMA | MTK_NETSYS_V1) -+ -+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -+ MTK_GMAC2_RGMII | MTK_QDMA | \ -+ MTK_NETSYS_V1) -+ -+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \ -+ MTK_NETSYS_V1) -+ -+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \ -+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \ -+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\ -+ MTK_MUX_GDM1_TO_GMAC1_ESW | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII) - - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ diff --git a/target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch b/target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch deleted file mode 100644 index 9d30e7b5e..000000000 --- a/target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Mar 2023 15:55:24 +0000 -Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data - -This is a preliminary patch to add MT7988 SoC support since it runs 3 -macs instead of 2. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++---- - 2 files changed, 36 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4028,7 +4028,10 @@ static void mtk_sgmii_destroy(struct mtk - { - int i; - -- for (i = 0; i < MTK_MAX_DEVS; i++) -+ if (!eth->sgmii_pcs) -+ return; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) - mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]); - } - -@@ -4481,7 +4484,12 @@ static int mtk_sgmii_init(struct mtk_eth - u32 flags; - int i; - -- for (i = 0; i < MTK_MAX_DEVS; i++) { -+ eth->sgmii_pcs = devm_kzalloc(eth->dev, -+ sizeof(*eth->sgmii_pcs) * -+ eth->soc->num_devs, -+ GFP_KERNEL); -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { - np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i); - if (!np) - break; -@@ -4526,6 +4534,18 @@ static int mtk_probe(struct platform_dev - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - eth->ip_align = NET_IP_ALIGN; - -+ eth->netdev = devm_kzalloc(eth->dev, -+ sizeof(*eth->netdev) * eth->soc->num_devs, -+ GFP_KERNEL); -+ if (!eth->netdev) -+ return -ENOMEM; -+ -+ eth->mac = devm_kzalloc(eth->dev, -+ sizeof(*eth->mac) * eth->soc->num_devs, -+ GFP_KERNEL); -+ if (!eth->mac) -+ return -ENOMEM; -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); -@@ -4711,7 +4731,7 @@ static int mtk_probe(struct platform_dev - goto err_deinit_ppe; - } - -- for (i = 0; i < MTK_MAX_DEVS; i++) { -+ for (i = 0; i < eth->soc->num_devs; i++) { - if (!eth->netdev[i]) - continue; - -@@ -4787,6 +4807,7 @@ static const struct mtk_soc_data mt2701_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4805,6 +4826,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 1, - .hash_offset = 2, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4826,6 +4848,7 @@ static const struct mtk_soc_data mt7622_ - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4845,6 +4868,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 1, - .hash_offset = 2, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4864,6 +4888,7 @@ static const struct mtk_soc_data mt7629_ - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, - .has_accounting = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4885,6 +4910,7 @@ static const struct mtk_soc_data mt7981_ - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4904,6 +4930,7 @@ static const struct mtk_soc_data mt7986_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -+ .num_devs = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, - .txrx = { -@@ -4922,6 +4949,7 @@ static const struct mtk_soc_data rt5350_ - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, - .required_pctl = false, -+ .num_devs = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1021,6 +1021,7 @@ struct mtk_reg_map { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. -+ * @num_devs SoC number of macs. - * @foe_entry_size Foe table entry size. - * @has_accounting Bool indicating support for accounting of - * offloaded flows. -@@ -1039,6 +1040,7 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - u8 hash_offset; -+ u8 num_devs; - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -@@ -1054,9 +1056,6 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - --/* currently no SoC has more than 2 macs */ --#define MTK_MAX_DEVS 2 -- - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1111,14 +1110,14 @@ struct mtk_eth { - spinlock_t tx_irq_lock; - spinlock_t rx_irq_lock; - struct net_device dummy_dev; -- struct net_device *netdev[MTK_MAX_DEVS]; -- struct mtk_mac *mac[MTK_MAX_DEVS]; -+ struct net_device **netdev; -+ struct mtk_mac **mac; - int irq[3]; - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; - struct regmap *infra; -- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; -+ struct phylink_pcs **sgmii_pcs; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; diff --git a/target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch b/target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch deleted file mode 100644 index 06e281aec..000000000 --- a/target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch +++ /dev/null @@ -1,495 +0,0 @@ -From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 25 Feb 2023 00:08:24 +0100 -Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC - -Introduce support for ethernet chip available in MT7988 SoC to -mtk_eth_soc driver. ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------ - 2 files changed, 279 insertions(+), 67 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r - .pse_oq_sta = 0x01a0, - }; - -+static const struct mtk_reg_map mt7988_reg_map = { -+ .tx_irq_mask = 0x461c, -+ .tx_irq_status = 0x4618, -+ .pdma = { -+ .rx_ptr = 0x6900, -+ .rx_cnt_cfg = 0x6904, -+ .pcrx_ptr = 0x6908, -+ .glo_cfg = 0x6a04, -+ .rst_idx = 0x6a08, -+ .delay_irq = 0x6a0c, -+ .irq_status = 0x6a20, -+ .irq_mask = 0x6a28, -+ .adma_rx_dbg0 = 0x6a38, -+ .int_grp = 0x6a50, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, -+ .rx_ptr = 0x4500, -+ .rx_cnt_cfg = 0x4504, -+ .qcrx_ptr = 0x4508, -+ .glo_cfg = 0x4604, -+ .rst_idx = 0x4608, -+ .delay_irq = 0x460c, -+ .fc_th = 0x4610, -+ .int_grp = 0x4620, -+ .hred = 0x4644, -+ .ctx_ptr = 0x4700, -+ .dtx_ptr = 0x4704, -+ .crx_ptr = 0x4710, -+ .drx_ptr = 0x4714, -+ .fq_head = 0x4720, -+ .fq_tail = 0x4724, -+ .fq_count = 0x4728, -+ .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, -+ }, -+ .gdm1_cnt = 0x1c00, -+ .gdma_to_ppe = 0x3333, -+ .ppe_base = 0x2200, -+ .wdma_base = { -+ [0] = 0x4800, -+ [1] = 0x4c00, -+ }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { - }; - - static const char * const mtk_clks_source_name[] = { -- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", -- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", -- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", -- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" -+ "ethif", -+ "sgmiitop", -+ "esw", -+ "gp0", -+ "gp1", -+ "gp2", -+ "gp3", -+ "xgp1", -+ "xgp2", -+ "xgp3", -+ "crypto", -+ "fe", -+ "trgpll", -+ "sgmii_tx250m", -+ "sgmii_rx250m", -+ "sgmii_cdr_ref", -+ "sgmii_cdr_fb", -+ "sgmii2_tx250m", -+ "sgmii2_rx250m", -+ "sgmii2_cdr_ref", -+ "sgmii2_cdr_fb", -+ "sgmii_ck", -+ "eth2pll", -+ "wocpu0", -+ "wocpu1", -+ "netsys0", -+ "netsys1", -+ "ethwarp_wocpu2", -+ "ethwarp_wocpu1", -+ "ethwarp_wocpu0", -+ "top_usxgmii0_sel", -+ "top_usxgmii1_sel", -+ "top_sgm0_sel", -+ "top_sgm1_sel", -+ "top_xfi_phy0_xtal_sel", -+ "top_xfi_phy1_xtal_sel", -+ "top_eth_gmii_sel", -+ "top_eth_refck_50m_sel", -+ "top_eth_sys_200m_sel", -+ "top_eth_sys_sel", -+ "top_eth_xgmii_sel", -+ "top_eth_mii_sel", -+ "top_netsys_sel", -+ "top_netsys_500m_sel", -+ "top_netsys_pao_2x_sel", -+ "top_netsys_sync_250m_sel", -+ "top_netsys_ppefb_250m_sel", -+ "top_netsys_warp_sel", - }; - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -@@ -1252,10 +1344,19 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (mac->id == MTK_GMAC3_ID) -- data = PSE_GDM3_PORT; -- else -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ /* set forward port */ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC2_ID: -+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC3_ID: -+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ } -+ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -5012,6 +5113,25 @@ static const struct mtk_soc_data mt7986_ - }, - }; - -+static const struct mtk_soc_data mt7988_data = { -+ .reg_map = &mt7988_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7988_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7988_CLKS_BITMAP, -+ .required_pctl = false, -+ .num_devs = 3, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ -+ - static const struct mtk_soc_data rt5350_data = { - .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, -@@ -5030,14 +5150,15 @@ static const struct mtk_soc_data rt5350_ - }; - - const struct of_device_id of_mtk_match[] = { -- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, -- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, -- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, -- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, -- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, -- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, -- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, -+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, -+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, -+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, -+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, -+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, -+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, -+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, -+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, of_mtk_match); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -116,7 +116,8 @@ - #define MTK_CDMP_EG_CTRL 0x404 - - /* GDM Exgress Control Register */ --#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) -+#define MTK_GDMA_FWD_CFG(x) ((x == MTK_GMAC3_ID) ? \ -+ 0x540 : 0x500 + (x * 0x1000)) - #define MTK_GDMA_SPECIAL_TAG BIT(24) - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) -@@ -653,6 +654,11 @@ enum mtk_clks_map { - MTK_CLK_GP0, - MTK_CLK_GP1, - MTK_CLK_GP2, -+ MTK_CLK_GP3, -+ MTK_CLK_XGP1, -+ MTK_CLK_XGP2, -+ MTK_CLK_XGP3, -+ MTK_CLK_CRYPTO, - MTK_CLK_FE, - MTK_CLK_TRGPLL, - MTK_CLK_SGMII_TX_250M, -@@ -669,57 +675,108 @@ enum mtk_clks_map { - MTK_CLK_WOCPU1, - MTK_CLK_NETSYS0, - MTK_CLK_NETSYS1, -+ MTK_CLK_ETHWARP_WOCPU2, -+ MTK_CLK_ETHWARP_WOCPU1, -+ MTK_CLK_ETHWARP_WOCPU0, -+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, -+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, -+ MTK_CLK_TOP_SGM_0_SEL, -+ MTK_CLK_TOP_SGM_1_SEL, -+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, -+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, -+ MTK_CLK_TOP_ETH_GMII_SEL, -+ MTK_CLK_TOP_ETH_REFCK_50M_SEL, -+ MTK_CLK_TOP_ETH_SYS_200M_SEL, -+ MTK_CLK_TOP_ETH_SYS_SEL, -+ MTK_CLK_TOP_ETH_XGMII_SEL, -+ MTK_CLK_TOP_ETH_MII_SEL, -+ MTK_CLK_TOP_NETSYS_SEL, -+ MTK_CLK_TOP_NETSYS_500M_SEL, -+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, -+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, -+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, -+ MTK_CLK_TOP_NETSYS_WARP_SEL, - MTK_CLK_MAX - }; - --#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_TRGPLL)) --#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL)) -+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_TRGPLL)) -+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL)) - #define MT7621_CLKS_BITMAP (0) - #define MT7628_CLKS_BITMAP (0) --#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) --#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK)) --#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK)) -+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ -+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ -+ BIT_ULL(MTK_CLK_CRYPTO) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -847,6 +904,7 @@ enum mkt_eth_capabilities { - MTK_RGMII_BIT = 0, - MTK_TRGMII_BIT, - MTK_SGMII_BIT, -+ MTK_USXGMII_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -869,6 +927,8 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, - - /* PATH BITS */ - MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -877,13 +937,18 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, -+ MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -+ MTK_ETH_PATH_GMAC1_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC2_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC3_USXGMII_BIT, - }; - - /* Supported hardware group on SoCs */ - #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -910,6 +975,10 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) - - /* Supported path present on SoCs */ - #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -918,7 +987,11 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -926,7 +999,11 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) -+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) -+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) - - /* MUXes present on SoCs */ - /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -949,6 +1026,12 @@ enum mkt_eth_capabilities { - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - -+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) -+ -+#define MTK_MUX_GMAC123_TO_USXGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) -+ - #ifdef CONFIG_SOC_MT7621 - #define MTK_CAP_MASK MTK_NETSYS_V2 - #else -@@ -987,9 +1070,17 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ - MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) - --#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | \ -+ MTK_QDMA | MTK_NETSYS_V2 | \ -+ MTK_RSTCTRL_PPE1) -+ -+#define MT7988_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_GMAC3_SGMII | MTK_QDMA | \ -+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ -+ MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \ -+ MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \ -+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1075,7 +1166,7 @@ struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; - u64 caps; -- u32 required_clks; -+ u64 required_clks; - bool required_pctl; - u8 offload_version; - u8 hash_offset; diff --git a/target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch deleted file mode 100644 index f1a8dc685..000000000 --- a/target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ /dev/null @@ -1,1867 +0,0 @@ -From 3d833ad2cfc1ab503d9aae2967b7f10811bb3c9c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 1 Mar 2023 11:56:04 +0000 -Subject: [PATCH 7/7] net: ethernet: mtk_eth_soc: add paths and SerDes modes - for MT7988 - -MT7988 comes with a built-in 2.5G PHY as well as -USXGMII/10GBase-KR/5GBase-KR compatible SerDes lanes for external PHYs. -Add support for configuring the MAC and SerDes parts for the new paths. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/Kconfig | 7 + - drivers/net/ethernet/mediatek/Makefile | 1 + - drivers/net/ethernet/mediatek/mtk_eth_path.c | 154 +++- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 270 +++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 194 ++++- - drivers/net/ethernet/mediatek/mtk_usxgmii.c | 835 +++++++++++++++++++ - 6 files changed, 1428 insertions(+), 33 deletions(-) - create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -25,6 +25,13 @@ config NET_MEDIATEK_SOC - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. - -+config NET_MEDIATEK_SOC_USXGMII -+ bool "Support USXGMII SerDes on MT7988" -+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST -+ def_bool NET_MEDIATEK_SOC != n -+ help -+ Include support for 10G SerDes which can be found on MT7988. -+ - config NET_MEDIATEK_STAR_EMAC - tristate "MediaTek STAR Ethernet MAC support" - select PHYLIB ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,6 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 - return "gmac2_rgmii"; - case MTK_ETH_PATH_GMAC2_SGMII: - return "gmac2_sgmii"; -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ return "gmac2_2p5gphy"; - case MTK_ETH_PATH_GMAC2_GEPHY: - return "gmac2_gephy"; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ return "gmac3_sgmii"; - case MTK_ETH_PATH_GDM1_ESW: - return "gdm1_esw"; -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ return "gmac1_usxgmii"; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ return "gmac2_usxgmii"; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ return "gmac3_usxgmii"; - default: - return "unknown path"; - } -@@ -42,8 +52,8 @@ static const char *mtk_eth_path_name(u64 - - static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { -+ u32 val, mask, set, reg; - bool updated = true; -- u32 val, mask, set; - - switch (path) { - case MTK_ETH_PATH_GMAC1_SGMII: -@@ -59,10 +69,15 @@ static int set_mux_gdm1_to_gmac1_esw(str - break; - } - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) -+ reg = MTK_MAC_MISC_V3; -+ else -+ reg = MTK_MAC_MISC; -+ - if (updated) { -- val = mtk_r32(eth, MTK_MAC_MISC); -+ val = mtk_r32(eth, reg); - val = (val & mask) | set; -- mtk_w32(eth, val, MTK_MAC_MISC); -+ mtk_w32(eth, val, reg); - } - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", -@@ -125,6 +140,31 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - -+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ default: -+ updated = false; -+ break; -+ }; -+ -+ if (updated) -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ return 0; -+} -+ - static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; -@@ -163,7 +203,61 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) -+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ /* Disable SYSCFG1 SGMII */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; -+ mac_id = MTK_GMAC1_ID; -+ break; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; -+ mac_id = MTK_GMAC3_ID; -+ break; -+ default: -+ updated = false; -+ }; -+ -+ if (updated) { -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ mac_id == MTK_GMAC2_ID) { -+ regmap_update_bits(eth->infra, -+ TOP_MISC_NETSYS_PCS_MUX, -+ NETSYS_PCS_MUX_MASK, -+ MUX_G2_USXGMII_SEL); -+ } -+ } -+ -+ /* Enable XGDM Path */ -+ val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac_id)); -+ val |= MTK_GDMA_XGDM_SEL; -+ mtk_w32(eth, val, MTK_GDMA_EG_CTRL(mac_id)); -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ -+ return 0; -+} -+ -+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -180,6 +274,9 @@ static int set_mux_gmac12_to_gephy_sgmii - case MTK_ETH_PATH_GMAC2_SGMII: - val |= SYSCFG0_SGMII_GMAC2_V2; - break; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ val |= SYSCFG0_SGMII_GMAC3_V2; -+ break; - default: - updated = false; - } -@@ -208,13 +305,25 @@ static const struct mtk_eth_muxc mtk_eth - .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, - .set_path = set_mux_u3_gmac2_to_qphy, - }, { -+ .name = "mux_gmac2_to_2p5gphy", -+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, -+ .set_path = set_mux_gmac2_to_2p5gphy, -+ }, { - .name = "mux_gmac1_gmac2_to_sgmii_rgmii", - .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, - .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, - }, { - .name = "mux_gmac12_to_gephy_sgmii", - .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, -- .set_path = set_mux_gmac12_to_gephy_sgmii, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_gephy_sgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_usxgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, -+ .set_path = set_mux_gmac123_to_usxgmii, - }, - }; - -@@ -243,16 +352,46 @@ static int mtk_eth_mux_setup(struct mtk_ - } - } - -+ dev_dbg(eth->dev, "leaving mux_setup %s\n", -+ mtk_eth_path_name(path)); -+ - out: - return err; - } - -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path; -+ -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : -+ MTK_ETH_PATH_GMAC3_USXGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { - u64 path; - -- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : -- MTK_ETH_PATH_GMAC2_SGMII; -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : -+ MTK_ETH_PATH_GMAC3_SGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path = 0; -+ -+ if (mac_id == MTK_GMAC2_ID) -+ path = MTK_ETH_PATH_GMAC2_2P5GPHY; -+ -+ if (!path) -+ return -EINVAL; - - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); -@@ -282,4 +421,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); - } -- ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -480,6 +480,23 @@ static void mtk_gmac0_rgmii_adjust(struc - mtk_w32(eth, val, TRGMII_TCK_CTRL); - } - -+static void mtk_setup_bridge_switch(struct mtk_eth *eth) -+{ -+ int val; -+ -+ /* Force Port1 XGMAC Link Up */ -+ val = mtk_r32(eth, MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), -+ MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ -+ /* Adjust GSW bridge IPG to 11*/ -+ val = mtk_r32(eth, MTK_GSW_CFG); -+ val &= ~(GSWTX_IPG_MASK | GSWRX_IPG_MASK); -+ val |= (GSW_IPG_11 << GSWTX_IPG_SHIFT) | -+ (GSW_IPG_11 << GSWRX_IPG_SHIFT); -+ mtk_w32(eth, val, MTK_GSW_CFG); -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -494,6 +511,12 @@ static struct phylink_pcs *mtk_mac_selec - 0 : mac->id; - - return eth->sgmii_pcs[sid]; -+ } else if ((interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GKR || -+ interface == PHY_INTERFACE_MODE_5GBASER) && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ mac->id != MTK_GMAC1_ID) { -+ return mtk_usxgmii_select_pcs(eth, mac->id); - } - - return NULL; -@@ -505,7 +528,7 @@ static void mtk_mac_config(struct phylin - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); - struct mtk_eth *eth = mac->hw; -- int val, ge_mode, err = 0; -+ int val, ge_mode, force_link, err = 0; - u32 i; - - /* MT76x8 has no hardware settings between for the MAC */ -@@ -549,6 +572,23 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_5GBASER: -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; -+ case PHY_INTERFACE_MODE_INTERNAL: -+ if (mac->id == MTK_GMAC2_ID && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { -+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; - default: - goto err_phy; - } -@@ -627,14 +667,78 @@ static void mtk_mac_config(struct phylin - SYSCFG0_SGMII_MASK, - ~(u32)SYSCFG0_SGMII_MASK); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ mtk_xfi_pll_enable(eth); -+ mtk_sgmii_reset(eth, mac->id); -+ if (phylink_autoneg_inband(mode)) -+ mtk_sgmii_setup_phya_gen1(eth, mac->id); -+ else -+ mtk_sgmii_setup_phya_gen2(eth, mac->id); -+ } - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; -- } else if (phylink_autoneg_inband(mode)) { -+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && -+ state->interface != PHY_INTERFACE_MODE_10GKR && -+ state->interface != PHY_INTERFACE_MODE_5GBASER && -+ phylink_autoneg_inband(mode)) { - dev_err(eth->dev, -- "In-band mode not supported in non SGMII mode!\n"); -+ "In-band mode not supported in non-SerDes modes!\n"); - return; - } - -+ /* Setup gmac */ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) && -+ (mtk_interface_mode_is_xgmii(state->interface) || -+ mac->interface == PHY_INTERFACE_MODE_INTERNAL)) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ mtk_setup_bridge_switch(eth); -+ break; -+ case MTK_GMAC2_ID: -+ force_link = (mac->interface == -+ PHY_INTERFACE_MODE_INTERNAL) ? -+ MTK_XGMAC_FORCE_LINK(mac->id) : 0; -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, val | force_link, -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ case MTK_GMAC3_ID: -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(mac->id), -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ } -+ } else { -+ val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(eth, val & ~MTK_GDMA_XGDM_SEL, -+ MTK_GDMA_EG_CTRL(mac->id)); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (mac->id) { -+ case MTK_GMAC2_ID: -+ case MTK_GMAC3_ID: -+ val = mtk_r32(eth, MTK_XGMAC_STS(mac->id)); -+ mtk_w32(eth, -+ val & ~MTK_XGMAC_FORCE_LINK(mac->id), -+ MTK_XGMAC_STS(mac->id)); -+ break; -+ } -+ } -+ -+/* -+ if (mac->type != mac_type) { -+ if (atomic_read(&reset_pending) == 0) { -+ atomic_inc(&force); -+ schedule_work(ð->pending_work); -+ atomic_inc(&reset_pending); -+ } else -+ atomic_dec(&reset_pending); -+ } -+*/ -+ } - return; - - err_phy: -@@ -674,11 +778,40 @@ static int mtk_mac_finish(struct phylink - return 0; - } - --static void mtk_mac_pcs_get_state(struct phylink_config *config, -+static void mtk_xgdm_pcs_get_state(struct mtk_mac *mac, -+ struct phylink_link_state *state) -+{ -+ u32 sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); -+ -+ if (mac->id == MTK_GMAC2_ID) -+ sts = sts >> 16; -+ -+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, sts); -+ if (!state->link) -+ return; -+ -+ state->duplex = DUPLEX_FULL; -+ state->interface = mac->interface; -+ -+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, sts)) { -+ case 0: -+ state->speed = SPEED_10000; -+ break; -+ case 1: -+ state->speed = SPEED_5000; -+ break; -+ case 2: -+ state->speed = SPEED_2500; -+ break; -+ case 3: -+ state->speed = SPEED_1000; -+ break; -+ } -+} -+ -+static void mtk_gdm_pcs_get_state(struct mtk_mac *mac, - struct phylink_link_state *state) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); - - state->link = (pmsr & MAC_MSR_LINK); -@@ -706,15 +839,35 @@ static void mtk_mac_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - -+static void mtk_mac_pcs_get_state(struct phylink_config *config, -+ struct phylink_link_state *state) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_interface_mode_is_xgmii(state->interface)) -+ mtk_xgdm_pcs_get_state(mac, state); -+ else -+ mtk_gdm_pcs_get_state(mac, state); -+} -+ - static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ u32 mcr; - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); -- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ if (!mtk_interface_mode_is_xgmii(interface)) { -+ mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN); -+ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ } else if (mac->id != MTK_GMAC1_ID) { -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ mcr &= 0xfffffff0; -+ mcr |= XMAC_MCR_TRX_DISABLE; -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+ } - } - - static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -@@ -786,13 +939,11 @@ static void mtk_set_queue_speed(struct m - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - } - --static void mtk_mac_link_up(struct phylink_config *config, -- struct phy_device *phy, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex, bool tx_pause, bool rx_pause) -+static void mtk_gdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 mcr; - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -@@ -826,6 +977,47 @@ static void mtk_mac_link_up(struct phyli - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ u32 mcr; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ return; -+ -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ -+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC); -+ /* Configure pause modes - -+ * phylink will avoid these for half duplex -+ */ -+ if (tx_pause) -+ mcr |= XMAC_MCR_FORCE_TX_FC; -+ if (rx_pause) -+ mcr |= XMAC_MCR_FORCE_RX_FC; -+ -+ mcr &= ~(XMAC_MCR_TRX_DISABLE); -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+} -+ -+static void mtk_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 mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ else -+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+} -+ - static const struct phylink_mac_ops mtk_phylink_ops = { - .validate = phylink_generic_validate, - .mac_select_pcs = mtk_mac_select_pcs, -@@ -879,10 +1071,21 @@ static int mtk_mdio_init(struct mtk_eth - } - divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); - -+ /* Configure MDC Turbo Mode */ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ val = mtk_r32(eth, MTK_MAC_MISC_V3); -+ val |= MISC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_MAC_MISC_V3); -+ } else { -+ val = mtk_r32(eth, MTK_PPSC); -+ val |= PPSC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_PPSC); -+ } -+ - /* Configure MDC Divider */ - val = mtk_r32(eth, MTK_PPSC); - val &= ~PPSC_MDC_CFG; -- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -+ val |= FIELD_PREP(PPSC_MDC_CFG, divider); - mtk_w32(eth, val, MTK_PPSC); - - dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); -@@ -4471,8 +4674,8 @@ static int mtk_add_mac(struct mtk_eth *e - const __be32 *_id = of_get_property(np, "reg", NULL); - phy_interface_t phy_mode; - struct phylink *phylink; -- struct mtk_mac *mac; - int id, err; -+ struct mtk_mac *mac; - int txqs = 1; - - if (!_id) { -@@ -4574,6 +4777,32 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.supported_interfaces); - } - -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { -+ if (id == MTK_GMAC1_ID) { -+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | -+ MAC_SYM_PAUSE | -+ MAC_10000FD; -+ phy_interface_zero( -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } else { -+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GKR, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ mac->phylink_config.supported_interfaces); -+ } -+ } -+ -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY)) { -+ if (id == MTK_GMAC2_ID) -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4761,6 +4990,13 @@ static int mtk_probe(struct platform_dev - - if (err) - return err; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_usxgmii_init(eth); -+ -+ if (err) -+ return err; - } - - if (eth->soc->required_pctl) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -126,6 +126,11 @@ - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -+/* GDM Egress Control Register */ -+#define MTK_GDMA_EG_CTRL(x) ((x == MTK_GMAC3_ID) ? \ -+ 0x544 : 0x504 + (x * 0x1000)) -+#define MTK_GDMA_XGDM_SEL BIT(31) -+ - /* Unicast Filter MAC Address Register - Low */ - #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) - -@@ -389,7 +394,26 @@ - #define PHY_IAC_TIMEOUT HZ - - #define MTK_MAC_MISC 0x1000c -+#define MTK_MAC_MISC_V3 0x10010 - #define MTK_MUX_TO_ESW BIT(0) -+#define MISC_MDC_TURBO BIT(4) -+ -+/* XMAC status registers */ -+#define MTK_XGMAC_STS(x) ((x == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) -+#define MTK_XGMAC_FORCE_LINK(x) ((x == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) -+#define MTK_USXGMII_PCS_LINK BIT(8) -+#define MTK_XGMAC_RX_FC BIT(5) -+#define MTK_XGMAC_TX_FC BIT(4) -+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) -+#define MTK_XGMAC_LINK_STS BIT(0) -+ -+/* GSW bridge registers */ -+#define MTK_GSW_CFG (0x10080) -+#define GSWTX_IPG_MASK GENMASK(19, 16) -+#define GSWTX_IPG_SHIFT 16 -+#define GSWRX_IPG_MASK GENMASK(3, 0) -+#define GSWRX_IPG_SHIFT 0 -+#define GSW_IPG_11 11 - - /* Mac control registers */ - #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) -@@ -414,6 +438,17 @@ - #define MAC_MCR_FORCE_LINK BIT(0) - #define MAC_MCR_FORCE_LINK_DOWN (MAC_MCR_FORCE_MODE) - -+/* Mac EEE control registers */ -+#define MTK_MAC_EEE(x) (0x10104 + (x * 0x100)) -+#define MAC_EEE_WAKEUP_TIME_1000 GENMASK(31, 24) -+#define MAC_EEE_WAKEUP_TIME_100 GENMASK(23, 16) -+#define MAC_EEE_LPI_TXIDLE_THD GENMASK(15, 8) -+#define MAC_EEE_RESV0 GENMASK(7, 4) -+#define MAC_EEE_CKG_TXILDE BIT(3) -+#define MAC_EEE_CKG_RXLPI BIT(2) -+#define MAC_EEE_TX_DOWN_REQ BIT(1) -+#define MAC_EEE_LPI_MODE BIT(0) -+ - /* Mac status registers */ - #define MTK_MAC_MSR(x) (0x10108 + (x * 0x100)) - #define MAC_MSR_EEE1G BIT(7) -@@ -458,6 +493,12 @@ - #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) - #define INTF_MODE_RGMII_10_100 0 - -+/* XFI Mac control registers */ -+#define MTK_XMAC_MCR(x) (0x12000 + ((x - 1) * 0x1000)) -+#define XMAC_MCR_TRX_DISABLE 0xf -+#define XMAC_MCR_FORCE_TX_FC BIT(5) -+#define XMAC_MCR_FORCE_RX_FC BIT(4) -+ - /* GPIO port control registers for GMAC 2*/ - #define GPIO_OD33_CTRL8 0x4c0 - #define GPIO_BIAS_CTRL 0xed0 -@@ -483,6 +524,7 @@ - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) - #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) -+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) - - - /* ethernet subsystem clock register */ -@@ -509,16 +551,91 @@ - #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - -+/* USXGMII subsystem config registers */ -+/* Register to control speed */ -+#define RG_PHY_TOP_SPEED_CTRL1 0x80C -+#define USXGMII_RATE_UPDATE_MODE BIT(31) -+#define USXGMII_MAC_CK_GATED BIT(29) -+#define USXGMII_IF_FORCE_EN BIT(28) -+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) -+#define USXGMII_RATE_ADAPT_MODE_X1 0 -+#define USXGMII_RATE_ADAPT_MODE_X2 1 -+#define USXGMII_RATE_ADAPT_MODE_X4 2 -+#define USXGMII_RATE_ADAPT_MODE_X10 3 -+#define USXGMII_RATE_ADAPT_MODE_X100 4 -+#define USXGMII_RATE_ADAPT_MODE_X5 5 -+#define USXGMII_RATE_ADAPT_MODE_X50 6 -+#define USXGMII_XFI_RX_MODE GENMASK(6, 4) -+#define USXGMII_XFI_RX_MODE_10G 0 -+#define USXGMII_XFI_RX_MODE_5G 1 -+#define USXGMII_XFI_TX_MODE GENMASK(2, 0) -+#define USXGMII_XFI_TX_MODE_10G 0 -+#define USXGMII_XFI_TX_MODE_5G 1 -+ -+/* Register to control PCS AN */ -+#define RG_PCS_AN_CTRL0 0x810 -+#define USXGMII_AN_RESTART BIT(31) -+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) -+#define USXGMII_AN_ENABLE BIT(0) -+ -+#define RG_PCS_AN_CTRL2 0x818 -+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) -+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) -+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) -+ -+/* Register to read PCS AN status */ -+#define RG_PCS_AN_STS0 0x81c -+#define USXGMII_LPA_SPEED_MASK GENMASK(11, 9) -+#define USXGMII_LPA_SPEED_10 0 -+#define USXGMII_LPA_SPEED_100 1 -+#define USXGMII_LPA_SPEED_1000 2 -+#define USXGMII_LPA_SPEED_10000 3 -+#define USXGMII_LPA_SPEED_2500 4 -+#define USXGMII_LPA_SPEED_5000 5 -+#define USXGMII_LPA_DUPLEX BIT(12) -+#define USXGMII_LPA_LINK BIT(15) -+#define USXGMII_LPA_LATCH BIT(31) -+ -+/* Register to control USXGMII XFI PLL digital */ -+#define XFI_PLL_DIG_GLB8 0x08 -+#define RG_XFI_PLL_EN BIT(31) -+ -+/* Register to control USXGMII XFI PLL analog */ -+#define XFI_PLL_ANA_GLB8 0x108 -+#define RG_XFI_PLL_ANA_SWWA 0x02283248 -+ - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) - #define GEPHY_MAC_SEL BIT(1) - -+/* Toprgu subsystem config registers */ -+#define TOPRGU_SWSYSRST 0x18 -+#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24) -+#define SWSYSRST_XFI_PLL_GRST BIT(16) -+#define SWSYSRST_XFI_PEXPT1_GRST BIT(15) -+#define SWSYSRST_XFI_PEXPT0_GRST BIT(14) -+#define SWSYSRST_XFI1_GRST BIT(13) -+#define SWSYSRST_XFI0_GRST BIT(12) -+#define SWSYSRST_SGMII1_GRST BIT(2) -+#define SWSYSRST_SGMII0_GRST BIT(1) -+#define TOPRGU_SWSYSRST_EN 0xFC -+ - /* Top misc registers */ -+#define TOP_MISC_NETSYS_PCS_MUX 0x84 -+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) -+#define MUX_G2_USXGMII_SEL BIT(1) -+#define MUX_HSGMII1_G1_SEL BIT(0) -+ - #define USB_PHY_SWITCH_REG 0x218 - #define QPHY_SEL_MASK GENMASK(1, 0) - #define SGMII_QPHY_SEL 0x2 - -+/* MDIO control */ -+#define MII_MMD_ACC_CTL_REG 0x0d -+#define MII_MMD_ADDR_DATA_REG 0x0e -+#define MMD_OP_MODE_DATA BIT(14) -+ - /* MT7628/88 specific stuff */ - #define MT7628_PDMA_OFFSET 0x0800 - #define MT7628_SDM_OFFSET 0x0c00 -@@ -812,13 +929,6 @@ enum mtk_gmac_id { - MTK_GMAC_ID_MAX - }; - --/* GDM Type */ --enum mtk_gdm_type { -- MTK_GDM_TYPE = 0, -- MTK_XGDM_TYPE, -- MTK_GDM_TYPE_MAX --}; -- - enum mtk_tx_buf_type { - MTK_TYPE_SKB, - MTK_TYPE_XDP_TX, -@@ -905,6 +1015,7 @@ enum mkt_eth_capabilities { - MTK_TRGMII_BIT, - MTK_SGMII_BIT, - MTK_USXGMII_BIT, -+ MTK_2P5GPHY_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -925,6 +1036,7 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, - MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, -+ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, - MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -@@ -936,6 +1048,7 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC1_SGMII_BIT, - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, -+ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, - MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -@@ -949,6 +1062,7 @@ enum mkt_eth_capabilities { - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) - #define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) -+#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -971,6 +1085,8 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ - BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ -+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ -@@ -986,6 +1102,7 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) - #define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -@@ -999,6 +1116,7 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) - #define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) - #define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -@@ -1022,6 +1140,10 @@ enum mkt_eth_capabilities { - (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ - MTK_SHARED_SGMII) - -+/* 2: GMAC2 -> XGMII */ -+#define MTK_MUX_GMAC2_TO_2P5GPHY \ -+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) -+ - /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) -@@ -1080,7 +1202,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ - MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \ - MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \ -- MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII) -+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \ -+ MTK_GMAC2_2P5GPHY | MTK_MUX_GMAC2_TO_2P5GPHY) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1186,6 +1309,22 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - -+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and -+ * associated data -+ * @regmap: The register map pointing at the range used to setup -+ * USXGMII modes -+ * @interface: Currently selected interface mode -+ * @id: The element is used to record the index of PCS -+ * @pcs: Phylink PCS structure -+ */ -+struct mtk_usxgmii_pcs { -+ struct mtk_eth *eth; -+ struct regmap *regmap; -+ phy_interface_t interface; -+ u8 id; -+ struct phylink_pcs pcs; -+}; -+ - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1206,6 +1345,11 @@ struct mtk_soc_data { - * @infra: The register map pointing at the range used to setup - * SGMII and GePHY path - * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances -+ * @usxgmii_pll: The register map pointing at the range used to control -+ * the USXGMII SerDes PLL -+ * @regmap_pextp: The register map pointing at the range used to setup -+ * PHYA -+ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1247,7 +1391,11 @@ struct mtk_eth { - unsigned long sysclk; - struct regmap *ethsys; - struct regmap *infra; -+ struct regmap *toprgu; - struct phylink_pcs **sgmii_pcs; -+ struct regmap *usxgmii_pll; -+ struct regmap **regmap_pextp; -+ struct mtk_usxgmii_pcs **usxgmii_pcs; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; -@@ -1403,6 +1551,19 @@ static inline u32 mtk_get_ib2_multicast_ - return MTK_FOE_IB2_MULTICAST; - } - -+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_5GBASER: -+ return true; -+ break; -+ default: -+ return false; -+ } -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - -@@ -1410,8 +1571,10 @@ void mtk_w32(struct mtk_eth *eth, u32 va - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); - - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, -@@ -1421,5 +1584,20 @@ int mtk_flow_offload_cmd(struct mtk_eth - void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - -+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id); -+int mtk_usxgmii_init(struct mtk_eth *eth); -+int mtk_xfi_pll_enable(struct mtk_eth *eth); -+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id); -+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id); -+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id); -+#else -+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) { return NULL; } -+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; } -+static inline int mtk_xfi_pll_enable(struct mtk_eth *eth) { return 0; } -+static inline void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) { } -+static inline void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) { } -+static inline void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) { } -+#endif /* NET_MEDIATEK_SOC_USXGMII */ - - #endif /* MTK_ETH_H */ ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c -@@ -0,0 +1,835 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (c) 2022 MediaTek Inc. -+ * Author: Henry Yen -+ * Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include "mtk_eth_soc.h" -+ -+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); -+} -+ -+static int mtk_xfi_pextp_init(struct mtk_eth *eth) -+{ -+ struct device *dev = eth->dev; -+ struct device_node *r = dev->of_node; -+ struct device_node *np; -+ int i; -+ -+ eth->regmap_pextp = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->regmap_pextp), GFP_KERNEL); -+ if (!eth->regmap_pextp) -+ return -ENOMEM; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { -+ np = of_parse_phandle(r, "mediatek,xfi_pextp", i); -+ if (!np) -+ break; -+ -+ eth->regmap_pextp[i] = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->regmap_pextp[i])) -+ return PTR_ERR(eth->regmap_pextp[i]); -+ } -+ -+ return 0; -+} -+ -+static int mtk_xfi_pll_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,xfi_pll", 0); -+ if (!np) -+ return -1; -+ -+ eth->usxgmii_pll = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pll)) -+ return PTR_ERR(eth->usxgmii_pll); -+ -+ return 0; -+} -+ -+static int mtk_toprgu_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,toprgu", 0); -+ if (!np) -+ return -1; -+ -+ eth->toprgu = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->toprgu)) -+ return PTR_ERR(eth->toprgu); -+ -+ return 0; -+} -+ -+int mtk_xfi_pll_enable(struct mtk_eth *eth) -+{ -+ u32 val = 0; -+ -+ if (!eth->usxgmii_pll) -+ return -EINVAL; -+ -+ /* Add software workaround for USXGMII PLL TCL issue */ -+ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA); -+ -+ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val); -+ val |= RG_XFI_PLL_EN; -+ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val); -+ -+ return 0; -+} -+ -+static int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id) -+{ -+ int xgmii_id = mac_id; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (mac_id) { -+ case MTK_GMAC1_ID: -+ case MTK_GMAC2_ID: -+ xgmii_id = 1; -+ break; -+ case MTK_GMAC3_ID: -+ xgmii_id = 0; -+ break; -+ default: -+ xgmii_id = -1; -+ } -+ } -+ -+ return xgmii_id; -+} -+ -+static int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id) -+{ -+ int mac_id = xgmii_id; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) { -+ switch (xgmii_id) { -+ case 0: -+ mac_id = 2; -+ break; -+ case 1: -+ mac_id = 1; -+ break; -+ default: -+ mac_id = -1; -+ } -+ } -+ -+ return mac_id; -+} -+ -+ -+static void mtk_usxgmii_setup_phya_usxgmii(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00C9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x01423342); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000001); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_setup_phya_5gbaser(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAAA5A5AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C018AA); -+ regmap_write(pextp, 0x50E0, 0x3777812B); -+ regmap_write(pextp, 0x506C, 0x005C9CFF); -+ regmap_write(pextp, 0x5070, 0x9DFAFAFA); -+ regmap_write(pextp, 0x5074, 0x273F3F3F); -+ regmap_write(pextp, 0x5078, 0xA8883868); -+ regmap_write(pextp, 0x507C, 0x14661466); -+ regmap_write(pextp, 0x5080, 0x0E001ABF); -+ regmap_write(pextp, 0x5084, 0x080B0D0D); -+ regmap_write(pextp, 0x5088, 0x02050909); -+ regmap_write(pextp, 0x50E4, 0x0C000000); -+ regmap_write(pextp, 0x50E8, 0x04000000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x50808C8C); -+ regmap_write(pextp, 0x6004, 0x18000000); -+ regmap_write(pextp, 0x00F8, 0x00A132A1); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000003); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_setup_phya_10gbaser(struct mtk_usxgmii_pcs *mpcs) -+{ -+ struct regmap *pextp; -+ -+ if (!mpcs->eth) -+ return; -+ -+ pextp = mpcs->eth->regmap_pextp[mpcs->id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00C9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x01423342); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ regmap_write(pextp, 0x3048, 0x47684100); -+ regmap_write(pextp, 0x3050, 0x00000000); -+ regmap_write(pextp, 0x3054, 0x00000000); -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ if (mpcs->id == 0) -+ regmap_write(pextp, 0xA008, 0x0007B400); -+ -+ regmap_write(pextp, 0xA060, 0x00040000); -+ regmap_write(pextp, 0x90D0, 0x00000001); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) -+{ -+ u32 id = mtk_mac2xgmii_id(eth, mac_id); -+ struct regmap *pextp; -+ -+ if (id >= eth->soc->num_devs) -+ return; -+ -+ pextp = eth->regmap_pextp[id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020207); -+ regmap_write(pextp, 0x2034, 0x0E05050F); -+ regmap_write(pextp, 0x2040, 0x00200032); -+ regmap_write(pextp, 0x50F0, 0x00C014BA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000EAF); -+ regmap_write(pextp, 0x5084, 0x08080E0D); -+ regmap_write(pextp, 0x5088, 0x02030B09); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0606); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x00FA32FA); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F21); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00011110); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3064, 0x0000C000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x20200F00); -+ regmap_write(pextp, 0xA060, 0x00050000); -+ regmap_write(pextp, 0x90D0, 0x00000007); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen2 */ -+ regmap_write(pextp, 0x0070, 0x0201C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0201C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F01); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) -+{ -+ u32 id = mtk_mac2xgmii_id(eth, mac_id); -+ struct regmap *pextp; -+ -+ if (id >= eth->soc->num_devs) -+ return; -+ -+ pextp = eth->regmap_pextp[id]; -+ if (!pextp) -+ return; -+ -+ /* Setup operation mode */ -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ regmap_write(pextp, 0x00F8, 0x009C329C); -+ /* Force SGDT_OUT off and select PCS */ -+ regmap_write(pextp, 0x00F4, 0x80201F21); -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ regmap_write(pextp, 0x3010, 0x00011110); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ regmap_write(pextp, 0x306C, 0x22000F00); -+ regmap_write(pextp, 0xA060, 0x00050000); -+ regmap_write(pextp, 0x90D0, 0x00000005); -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ udelay(150); -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ udelay(15); -+ /* Switch to Gen2 */ -+ regmap_write(pextp, 0x0070, 0x0201C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0201C101); -+ udelay(100); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ regmap_write(pextp, 0x00F4, 0x80201F01); -+ regmap_write(pextp, 0x3040, 0x30000000); -+ udelay(400); -+} -+ -+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id) -+{ -+ u32 val = 0; -+ -+ if (id >= eth->soc->num_devs || !eth->toprgu) -+ return; -+ -+ switch (id) { -+ case 0: -+ /* Enable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val |= SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ -+ /* Assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | -+ SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ udelay(100); -+ -+ /* De-assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); -+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ /* Disable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST | -+ SWSYSRST_XFI0_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ break; -+ case 1: -+ /* Enable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val |= SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ -+ /* Assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | -+ SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ udelay(100); -+ -+ /* De-assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); -+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ /* Disable software reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val); -+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST | -+ SWSYSRST_XFI1_GRST); -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val); -+ break; -+ } -+ -+ mdelay(10); -+} -+ -+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ mtk_usxgmii_reset(eth, xgmii_id); -+} -+ -+ -+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; -+ bool mode_changed = false; -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | -+ USXGMII_AN_ENABLE; -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ } else if (interface == PHY_INTERFACE_MODE_10GKR) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else -+ return -EINVAL; -+ -+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); -+ -+ if (mpcs->interface != interface) { -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ mtk_xfi_pll_enable(eth); -+ mtk_usxgmii_reset(eth, mpcs->id); -+ -+ /* Setup USXGMII AN ctrl */ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0, -+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -+ an_ctrl); -+ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2, -+ USXGMII_LINK_TIMER_IDLE_DETECT | -+ USXGMII_LINK_TIMER_COMP_ACK_DETECT | -+ USXGMII_LINK_TIMER_AN_RESTART, -+ link_timer); -+ -+ /* Gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); -+ -+ /* Enable interface force mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); -+ -+ /* Setup USXGMII adapt mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, -+ adapt_mode); -+ -+ /* Setup USXGMII speed */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, -+ xfi_mode); -+ -+ udelay(1); -+ -+ /* Un-gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, 0); -+ -+ udelay(1); -+ -+ /* Disable interface force mode for the AN mode */ -+ if (an_ctrl & USXGMII_AN_ENABLE) -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, 0); -+ -+ /* Setup USXGMIISYS with the determined property */ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) -+ mtk_usxgmii_setup_phya_usxgmii(mpcs); -+ else if (interface == PHY_INTERFACE_MODE_10GKR) -+ mtk_usxgmii_setup_phya_10gbaser(mpcs); -+ else if (interface == PHY_INTERFACE_MODE_5GBASER) -+ mtk_usxgmii_setup_phya_5gbaser(mpcs); -+ -+ return mode_changed; -+} -+ -+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)]; -+ u32 val = 0; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ if (FIELD_GET(USXGMII_AN_ENABLE, val)) { -+ /* Refresh LPA by inverting LPA_LATCH */ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0, -+ USXGMII_LPA_LATCH, -+ !(val & USXGMII_LPA_LATCH)); -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ -+ state->interface = mpcs->interface; -+ state->link = FIELD_GET(USXGMII_LPA_LINK, val); -+ state->duplex = FIELD_GET(USXGMII_LPA_DUPLEX, val); -+ -+ switch (FIELD_GET(USXGMII_LPA_SPEED_MASK, val)) { -+ case USXGMII_LPA_SPEED_10: -+ state->speed = SPEED_10; -+ break; -+ case USXGMII_LPA_SPEED_100: -+ state->speed = SPEED_100; -+ break; -+ case USXGMII_LPA_SPEED_1000: -+ state->speed = SPEED_1000; -+ break; -+ case USXGMII_LPA_SPEED_2500: -+ state->speed = SPEED_2500; -+ break; -+ case USXGMII_LPA_SPEED_5000: -+ state->speed = SPEED_5000; -+ break; -+ case USXGMII_LPA_SPEED_10000: -+ state->speed = SPEED_10000; -+ break; -+ } -+ } else { -+ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); -+ -+ if (mac->id == MTK_GMAC2_ID) -+ val = val >> 16; -+ -+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) { -+ case 0: -+ state->speed = SPEED_10000; -+ break; -+ case 1: -+ state->speed = SPEED_5000; -+ break; -+ case 2: -+ state->speed = SPEED_2500; -+ break; -+ case 3: -+ state->speed = SPEED_1000; -+ break; -+ } -+ -+ state->interface = mpcs->interface; -+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val); -+ state->duplex = DUPLEX_FULL; -+ } -+ -+ if (state->link == 0) -+ mtk_usxgmii_pcs_config(pcs, MLO_AN_INBAND, -+ state->interface, NULL, false); -+} -+ -+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ unsigned int val = 0; -+ -+ if (!mpcs->regmap) -+ return; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ val |= USXGMII_AN_RESTART; -+ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val); -+} -+ -+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ int speed, int duplex) -+{ -+ /* Reconfiguring USXGMII to ensure the quality of the RX signal -+ * after the line side link up. -+ */ -+ mtk_usxgmii_pcs_config(pcs, mode, -+ interface, NULL, false); -+} -+ -+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { -+ .pcs_config = mtk_usxgmii_pcs_config, -+ .pcs_get_state = mtk_usxgmii_pcs_get_state, -+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, -+ .pcs_link_up = mtk_usxgmii_pcs_link_up, -+}; -+ -+int mtk_usxgmii_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device *dev = eth->dev; -+ struct device_node *np; -+ int i, ret; -+ -+ eth->usxgmii_pcs = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->usxgmii_pcs), GFP_KERNEL); -+ if (!eth->usxgmii_pcs) -+ return -ENOMEM; -+ -+ for (i = 0; i < eth->soc->num_devs; i++) { -+ np = of_parse_phandle(r, "mediatek,usxgmiisys", i); -+ if (!np) -+ break; -+ -+ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs), GFP_KERNEL); -+ if (!eth->usxgmii_pcs[i]) -+ return -ENOMEM; -+ -+ eth->usxgmii_pcs[i]->id = i; -+ eth->usxgmii_pcs[i]->eth = eth; -+ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pcs[i]->regmap)) -+ return PTR_ERR(eth->usxgmii_pcs[i]->regmap); -+ -+ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops; -+ eth->usxgmii_pcs[i]->pcs.poll = true; -+ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA; -+ -+ of_node_put(np); -+ } -+ -+ ret = mtk_xfi_pextp_init(eth); -+ if (ret) -+ return ret; -+ -+ ret = mtk_xfi_pll_init(eth); -+ if (ret) -+ return ret; -+ -+ return mtk_toprgu_init(eth); -+} -+ -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ if (!eth->usxgmii_pcs[xgmii_id]->regmap) -+ return NULL; -+ -+ return ð->usxgmii_pcs[xgmii_id]->pcs; -+} diff --git a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch new file mode 100644 index 000000000..519ece669 --- /dev/null +++ b/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -0,0 +1,1604 @@ +From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 22 Aug 2023 19:04:42 +0100 +Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes + modes for MT7988 + +MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to +connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R, +2500Base-X, 1000Base-X and Cisco SGMII interface modes. + +Implement support for configuring for the new paths to SerDes interfaces +and the internal 2.5G PHY. + +Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and +setup the new PHYA on MT7988 to access the also still existing old +LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface +modes. + +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/Kconfig | 16 + + drivers/net/ethernet/mediatek/Makefile | 1 + + drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 182 ++++- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 232 ++++++- + drivers/net/ethernet/mediatek/mtk_usxgmii.c | 692 +++++++++++++++++++ + 6 files changed, 1215 insertions(+), 31 deletions(-) + create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c + +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -25,6 +25,22 @@ config NET_MEDIATEK_SOC + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. + ++config NET_MEDIATEK_SOC_USXGMII ++ bool "Support USXGMII SerDes on MT7988" ++ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST ++ def_bool NET_MEDIATEK_SOC != n ++ help ++ Include support for 10GE SerDes which can be found on MT7988. ++ If this kernel should run on SoCs with 10 GBit/s Ethernet you ++ will need to select this option to use GMAC2 and GMAC3 with ++ external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII ++ interface modes. ++ ++ Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS ++ unit (MediaTek LynxI) in MT7988 is connected via the new 10GE ++ SerDes, you will also need to select this option in case you ++ want to use any of those SerDes modes. ++ + config NET_MEDIATEK_STAR_EMAC + tristate "MediaTek STAR Ethernet MAC support" + select PHYLIB +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o + mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o ++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 + return "gmac2_rgmii"; + case MTK_ETH_PATH_GMAC2_SGMII: + return "gmac2_sgmii"; ++ case MTK_ETH_PATH_GMAC2_2P5GPHY: ++ return "gmac2_2p5gphy"; + case MTK_ETH_PATH_GMAC2_GEPHY: + return "gmac2_gephy"; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ return "gmac3_sgmii"; + case MTK_ETH_PATH_GDM1_ESW: + return "gdm1_esw"; ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ return "gmac1_usxgmii"; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ return "gmac2_usxgmii"; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ return "gmac3_usxgmii"; + default: + return "unknown path"; + } +@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru + return 0; + } + ++static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) ++{ ++ int ret; ++ ++ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) { ++ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2); ++ if (ret) ++ return ret; ++ ++ /* Setup mux to 2p5g PHY */ ++ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL); ++ if (ret) ++ return ret; ++ ++ dev_dbg(eth->dev, "path %s in %s updated\n", ++ mtk_eth_path_name(path), __func__); ++ } ++ ++ return 0; ++} ++ + static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) + { + unsigned int val = 0; +@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_ + return 0; + } + +-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) ++static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) ++{ ++ unsigned int val = 0; ++ bool updated = true; ++ int mac_id = 0; ++ ++ /* Disable SYSCFG1 SGMII */ ++ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); ++ ++ switch (path) { ++ case MTK_ETH_PATH_GMAC1_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; ++ mac_id = MTK_GMAC1_ID; ++ break; ++ case MTK_ETH_PATH_GMAC2_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; ++ mac_id = MTK_GMAC2_ID; ++ break; ++ case MTK_ETH_PATH_GMAC3_USXGMII: ++ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; ++ mac_id = MTK_GMAC3_ID; ++ break; ++ default: ++ updated = false; ++ }; ++ ++ if (updated) { ++ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, ++ SYSCFG0_SGMII_MASK, val); ++ ++ if (mac_id == MTK_GMAC2_ID) ++ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, ++ MUX_G2_USXGMII_SEL); ++ } ++ ++ dev_dbg(eth->dev, "path %s in %s updated = %d\n", ++ mtk_eth_path_name(path), __func__, updated); ++ ++ return 0; ++} ++ ++static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) + { + unsigned int val = 0; + bool updated = true; +@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii + case MTK_ETH_PATH_GMAC2_SGMII: + val |= SYSCFG0_SGMII_GMAC2_V2; + break; ++ case MTK_ETH_PATH_GMAC3_SGMII: ++ val |= SYSCFG0_SGMII_GMAC3_V2; ++ break; + default: + updated = false; + } +@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth + .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, + .set_path = set_mux_u3_gmac2_to_qphy, + }, { ++ .name = "mux_gmac2_to_2p5gphy", ++ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, ++ .set_path = set_mux_gmac2_to_2p5gphy, ++ }, { + .name = "mux_gmac1_gmac2_to_sgmii_rgmii", + .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, + .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, + }, { + .name = "mux_gmac12_to_gephy_sgmii", + .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, +- .set_path = set_mux_gmac12_to_gephy_sgmii, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_gephy_sgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, ++ .set_path = set_mux_gmac123_to_gephy_sgmii, ++ }, { ++ .name = "mux_gmac123_to_usxgmii", ++ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, ++ .set_path = set_mux_gmac123_to_usxgmii, + }, + }; + +@@ -249,12 +336,39 @@ out: + return err; + } + ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) ++{ ++ u64 path; ++ ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : ++ MTK_ETH_PATH_GMAC3_USXGMII; ++ ++ /* Setup proper MUXes along the path */ ++ return mtk_eth_mux_setup(eth, path); ++} ++ + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) + { + u64 path; + +- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : +- MTK_ETH_PATH_GMAC2_SGMII; ++ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : ++ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : ++ MTK_ETH_PATH_GMAC3_SGMII; ++ ++ /* Setup proper MUXes along the path */ ++ return mtk_eth_mux_setup(eth, path); ++} ++ ++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) ++{ ++ u64 path = 0; ++ ++ if (mac_id == MTK_GMAC2_ID) ++ path = MTK_ETH_PATH_GMAC2_2P5GPHY; ++ ++ if (!path) ++ return -EINVAL; + + /* Setup proper MUXes along the path */ + return mtk_eth_mux_setup(eth, path); +@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk + /* Setup proper MUXes along the path */ + return mtk_eth_mux_setup(eth, path); + } +- +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -474,6 +474,30 @@ static void mtk_setup_bridge_switch(stru + MTK_GSW_CFG); + } + ++static bool mtk_check_gmac23_idle(struct mtk_mac *mac) ++{ ++ u32 mac_fsm, gdm_fsm; ++ ++ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); ++ ++ switch (mac->id) { ++ case MTK_GMAC2_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); ++ break; ++ case MTK_GMAC3_ID: ++ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); ++ break; ++ default: ++ return true; ++ }; ++ ++ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && ++ (gdm_fsm & 0xFFFF0000) == 0x00000000) ++ return true; ++ ++ return false; ++} ++ + static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, + phy_interface_t interface) + { +@@ -482,12 +506,20 @@ static struct phylink_pcs *mtk_mac_selec + struct mtk_eth *eth = mac->hw; + unsigned int sid; + +- if (interface == PHY_INTERFACE_MODE_SGMII || +- phy_interface_mode_is_8023z(interface)) { +- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? +- 0 : mac->id; +- +- return eth->sgmii_pcs[sid]; ++ if ((interface == PHY_INTERFACE_MODE_SGMII || ++ phy_interface_mode_is_8023z(interface)) && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { ++ sid = mtk_mac2xgmii_id(eth, mac->id); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) ++ return mtk_sgmii_wrapper_select_pcs(eth, mac->id); ++ else ++ return eth->sgmii_pcs[sid]; ++ } else if ((interface == PHY_INTERFACE_MODE_USXGMII || ++ interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_5GBASER) && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) && ++ mac->id != MTK_GMAC1_ID) { ++ return mtk_usxgmii_select_pcs(eth, mac->id); + } + + return NULL; +@@ -543,7 +575,22 @@ static void mtk_mac_config(struct phylin + goto init_err; + } + break; ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_5GBASER: ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { ++ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); ++ if (err) ++ goto init_err; ++ } ++ break; + case PHY_INTERFACE_MODE_INTERNAL: ++ if (mac->id == MTK_GMAC2_ID && ++ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { ++ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); ++ if (err) ++ goto init_err; ++ } + break; + default: + goto err_phy; +@@ -598,8 +645,6 @@ static void mtk_mac_config(struct phylin + val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); + val |= SYSCFG0_GE_MODE(ge_mode, mac->id); + regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); +- +- mac->interface = state->interface; + } + + /* SGMII */ +@@ -616,21 +661,40 @@ static void mtk_mac_config(struct phylin + + /* Save the syscfg0 value for mac_finish */ + mac->syscfg0 = val; +- } else if (phylink_autoneg_inband(mode)) { ++ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && ++ state->interface != PHY_INTERFACE_MODE_10GBASER && ++ state->interface != PHY_INTERFACE_MODE_5GBASER && ++ phylink_autoneg_inband(mode)) { + dev_err(eth->dev, +- "In-band mode not supported in non SGMII mode!\n"); ++ "In-band mode not supported in non-SerDes modes!\n"); + return; + } + + /* Setup gmac */ +- if (mtk_is_netsys_v3_or_greater(eth) && +- mac->interface == PHY_INTERFACE_MODE_INTERNAL) { +- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); +- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ if (mtk_interface_mode_is_xgmii(state->interface)) { ++ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); ++ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); ++ ++ if (mac->id == MTK_GMAC1_ID) ++ mtk_setup_bridge_switch(eth); ++ } else { ++ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); + +- mtk_setup_bridge_switch(eth); ++ /* FIXME: In current hardware design, we have to reset FE ++ * when swtiching XGDM to GDM. Therefore, here trigger an SER ++ * to let GDM go back to the initial state. ++ */ ++ if ((mtk_interface_mode_is_xgmii(mac->interface) || ++ mac->interface == PHY_INTERFACE_MODE_NA) && ++ !mtk_check_gmac23_idle(mac) && ++ !test_bit(MTK_RESETTING, ð->state)) ++ schedule_work(ð->pending_work); ++ } + } + ++ mac->interface = state->interface; ++ + return; + + err_phy: +@@ -675,10 +739,13 @@ static void mtk_mac_link_down(struct phy + { + struct mtk_mac *mac = container_of(config, struct mtk_mac, + phylink_config); +- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); + +- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); +- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); ++ if (!mtk_interface_mode_is_xgmii(interface)) { ++ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id)); ++ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id)); ++ } else if (mac->id != MTK_GMAC1_ID) { ++ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id)); ++ } + } + + static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, +@@ -750,13 +817,11 @@ static void mtk_set_queue_speed(struct m + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); + } + +-static void mtk_mac_link_up(struct phylink_config *config, +- struct phy_device *phy, +- unsigned int mode, phy_interface_t interface, +- int speed, int duplex, bool tx_pause, bool rx_pause) ++static void mtk_gdm_mac_link_up(struct mtk_mac *mac, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) + { +- struct mtk_mac *mac = container_of(config, struct mtk_mac, +- phylink_config); + u32 mcr; + + mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); +@@ -790,6 +855,55 @@ static void mtk_mac_link_up(struct phyli + mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) ++{ ++ u32 mcr, force_link = 0; ++ ++ if (mac->id == MTK_GMAC1_ID) ++ return; ++ ++ /* Eliminate the interference(before link-up) caused by PHY noise */ ++ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id)); ++ mdelay(20); ++ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id)); ++ ++ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID) ++ force_link = MTK_XGMAC_FORCE_LINK(mac->id); ++ ++ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id)); ++ ++ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); ++ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE); ++ /* Configure pause modes - ++ * phylink will avoid these for half duplex ++ */ ++ if (tx_pause) ++ mcr |= XMAC_MCR_FORCE_TX_FC; ++ if (rx_pause) ++ mcr |= XMAC_MCR_FORCE_RX_FC; ++ ++ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); ++} ++ ++static void mtk_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 mtk_mac *mac = container_of(config, struct mtk_mac, ++ phylink_config); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, ++ tx_pause, rx_pause); ++ else ++ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, ++ tx_pause, rx_pause); ++} ++ + static const struct phylink_mac_ops mtk_phylink_ops = { + .validate = phylink_generic_validate, + .mac_select_pcs = mtk_mac_select_pcs, +@@ -4614,8 +4728,21 @@ static int mtk_add_mac(struct mtk_eth *e + phy_interface_zero(mac->phylink_config.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + mac->phylink_config.supported_interfaces); ++ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { ++ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; ++ __set_bit(PHY_INTERFACE_MODE_5GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_10GBASER, ++ mac->phylink_config.supported_interfaces); ++ __set_bit(PHY_INTERFACE_MODE_USXGMII, ++ mac->phylink_config.supported_interfaces); + } + ++ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && ++ id == MTK_GMAC2_ID) ++ __set_bit(PHY_INTERFACE_MODE_INTERNAL, ++ mac->phylink_config.supported_interfaces); ++ + phylink = phylink_create(&mac->phylink_config, + of_fwnode_handle(mac->of_node), + phy_mode, &mtk_phylink_ops); +@@ -4808,6 +4935,13 @@ static int mtk_probe(struct platform_dev + + if (err) + return err; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { ++ err = mtk_usxgmii_init(eth); ++ ++ if (err) ++ return err; + } + + if (eth->soc->required_pctl) { +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -502,6 +502,21 @@ + #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) + #define INTF_MODE_RGMII_10_100 0 + ++/* XFI Mac control registers */ ++#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000)) ++#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x)) ++#define XMAC_MCR_TRX_DISABLE 0xf ++#define XMAC_MCR_FORCE_TX_FC BIT(5) ++#define XMAC_MCR_FORCE_RX_FC BIT(4) ++ ++/* XFI Mac logic reset registers */ ++#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10) ++#define XMAC_LOGIC_RST BIT(0) ++ ++/* XFI Mac count global control */ ++#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100) ++#define XMAC_GLB_CNTCLR BIT(0) ++ + /* GPIO port control registers for GMAC 2*/ + #define GPIO_OD33_CTRL8 0x4c0 + #define GPIO_BIAS_CTRL 0xed0 +@@ -527,6 +542,7 @@ + #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) + #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) + #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) ++#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) + + + /* ethernet subsystem clock register */ +@@ -559,12 +575,74 @@ + #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) + #define ETHSYS_DMA_AG_MAP_PPE BIT(2) + ++/* USXGMII subsystem config registers */ ++/* Register to control speed */ ++#define RG_PHY_TOP_SPEED_CTRL1 0x80C ++#define USXGMII_RATE_UPDATE_MODE BIT(31) ++#define USXGMII_MAC_CK_GATED BIT(29) ++#define USXGMII_IF_FORCE_EN BIT(28) ++#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) ++#define USXGMII_RATE_ADAPT_MODE_X1 0 ++#define USXGMII_RATE_ADAPT_MODE_X2 1 ++#define USXGMII_RATE_ADAPT_MODE_X4 2 ++#define USXGMII_RATE_ADAPT_MODE_X10 3 ++#define USXGMII_RATE_ADAPT_MODE_X100 4 ++#define USXGMII_RATE_ADAPT_MODE_X5 5 ++#define USXGMII_RATE_ADAPT_MODE_X50 6 ++#define USXGMII_XFI_RX_MODE GENMASK(6, 4) ++#define USXGMII_XFI_RX_MODE_10G 0 ++#define USXGMII_XFI_RX_MODE_5G 1 ++#define USXGMII_XFI_TX_MODE GENMASK(2, 0) ++#define USXGMII_XFI_TX_MODE_10G 0 ++#define USXGMII_XFI_TX_MODE_5G 1 ++ ++/* Register to control PCS AN */ ++#define RG_PCS_AN_CTRL0 0x810 ++#define USXGMII_AN_RESTART BIT(31) ++#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) ++#define USXGMII_AN_ENABLE BIT(0) ++ ++#define RG_PCS_AN_CTRL2 0x818 ++#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) ++#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) ++#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) ++ ++/* Register to read PCS AN status */ ++#define RG_PCS_AN_STS0 0x81c ++#define USXGMII_PCS_AN_WORD GENMASK(15, 0) ++#define USXGMII_LPA_LATCH BIT(31) ++ ++/* Register to control USXGMII XFI PLL digital */ ++#define XFI_PLL_DIG_GLB8 0x08 ++#define RG_XFI_PLL_EN BIT(31) ++ ++/* Register to control USXGMII XFI PLL analog */ ++#define XFI_PLL_ANA_GLB8 0x108 ++#define RG_XFI_PLL_ANA_SWWA 0x02283248 ++ + /* Infrasys subsystem config registers */ + #define INFRA_MISC2 0x70c + #define CO_QPHY_SEL BIT(0) + #define GEPHY_MAC_SEL BIT(1) + ++/* Toprgu subsystem config registers */ ++#define TOPRGU_SWSYSRST 0x18 ++#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24) ++#define SWSYSRST_XFI_PLL_GRST BIT(16) ++#define SWSYSRST_XFI_PEXPT1_GRST BIT(15) ++#define SWSYSRST_XFI_PEXPT0_GRST BIT(14) ++#define SWSYSRST_XFI1_GRST BIT(13) ++#define SWSYSRST_XFI0_GRST BIT(12) ++#define SWSYSRST_SGMII1_GRST BIT(2) ++#define SWSYSRST_SGMII0_GRST BIT(1) ++#define TOPRGU_SWSYSRST_EN 0xFC ++ + /* Top misc registers */ ++#define TOP_MISC_NETSYS_PCS_MUX 0x84 ++#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) ++#define MUX_G2_USXGMII_SEL BIT(1) ++#define MUX_HSGMII1_G1_SEL BIT(0) ++ + #define USB_PHY_SWITCH_REG 0x218 + #define QPHY_SEL_MASK GENMASK(1, 0) + #define SGMII_QPHY_SEL 0x2 +@@ -589,6 +667,8 @@ + #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) + #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + ++/* Debug Purpose Register */ ++#define MTK_PSE_FQFC_CFG 0x100 + #define MTK_FE_CDM1_FSM 0x220 + #define MTK_FE_CDM2_FSM 0x224 + #define MTK_FE_CDM3_FSM 0x238 +@@ -597,6 +677,11 @@ + #define MTK_FE_CDM6_FSM 0x328 + #define MTK_FE_GDM1_FSM 0x228 + #define MTK_FE_GDM2_FSM 0x22C ++#define MTK_FE_GDM3_FSM 0x23C ++#define MTK_FE_PSE_FREE 0x240 ++#define MTK_FE_DROP_FQ 0x244 ++#define MTK_FE_DROP_FC 0x248 ++#define MTK_FE_DROP_PPE 0x24C + + #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) + +@@ -943,6 +1028,8 @@ enum mkt_eth_capabilities { + MTK_RGMII_BIT = 0, + MTK_TRGMII_BIT, + MTK_SGMII_BIT, ++ MTK_USXGMII_BIT, ++ MTK_2P5GPHY_BIT, + MTK_ESW_BIT, + MTK_GEPHY_BIT, + MTK_MUX_BIT, +@@ -963,8 +1050,11 @@ enum mkt_eth_capabilities { + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, + MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, + MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, ++ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, + MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, + MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, ++ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_RGMII_BIT, +@@ -972,14 +1062,21 @@ enum mkt_eth_capabilities { + MTK_ETH_PATH_GMAC1_SGMII_BIT, + MTK_ETH_PATH_GMAC2_RGMII_BIT, + MTK_ETH_PATH_GMAC2_SGMII_BIT, ++ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, + MTK_ETH_PATH_GMAC2_GEPHY_BIT, ++ MTK_ETH_PATH_GMAC3_SGMII_BIT, + MTK_ETH_PATH_GDM1_ESW_BIT, ++ MTK_ETH_PATH_GMAC1_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC2_USXGMII_BIT, ++ MTK_ETH_PATH_GMAC3_USXGMII_BIT, + }; + + /* Supported hardware group on SoCs */ + #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) + #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) + #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) ++#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) ++#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) + #define MTK_ESW BIT_ULL(MTK_ESW_BIT) + #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) + #define MTK_MUX BIT_ULL(MTK_MUX_BIT) +@@ -1002,10 +1099,16 @@ enum mkt_eth_capabilities { + BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) + #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ + BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) ++#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ ++ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) + #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ + BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) + #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ + BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) ++#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ ++ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) + + /* Supported path present on SoCs */ + #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) +@@ -1013,8 +1116,13 @@ enum mkt_eth_capabilities { + #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) + #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) + #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) ++#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) + #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) ++#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) + #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) ++#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) ++#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) + + #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) + #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) +@@ -1022,7 +1130,12 @@ enum mkt_eth_capabilities { + #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) + #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) + #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) ++#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) ++#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) + #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) ++#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) ++#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) ++#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) + + /* MUXes present on SoCs */ + /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ +@@ -1041,10 +1154,20 @@ enum mkt_eth_capabilities { + (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ + MTK_SHARED_SGMII) + ++/* 2: GMAC2 -> XGMII */ ++#define MTK_MUX_GMAC2_TO_2P5GPHY \ ++ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) ++ + /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ + #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ + (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) + ++#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) ++ ++#define MTK_MUX_GMAC123_TO_USXGMII \ ++ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) ++ + #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) + + #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ +@@ -1076,8 +1199,12 @@ enum mkt_eth_capabilities { + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_RSTCTRL_PPE1 | MTK_SRAM) + +-#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ +- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) ++#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ ++ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ ++ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ ++ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ ++ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ ++ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) + + struct mtk_tx_dma_desc_info { + dma_addr_t addr; +@@ -1187,6 +1314,24 @@ struct mtk_soc_data { + /* currently no SoC has more than 3 macs */ + #define MTK_MAX_DEVS 3 + ++/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and ++ * associated data ++ * @regmap: The register map pointing at the range used to setup ++ * USXGMII modes ++ * @interface: Currently selected interface mode ++ * @id: The element is used to record the index of PCS ++ * @pcs: Phylink PCS structure ++ */ ++struct mtk_usxgmii_pcs { ++ struct mtk_eth *eth; ++ struct regmap *regmap; ++ struct phylink_pcs *wrapped_sgmii_pcs; ++ phy_interface_t interface; ++ u8 id; ++ unsigned int mode; ++ struct phylink_pcs pcs; ++}; ++ + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver + * @dev: The device pointer +@@ -1207,6 +1352,12 @@ struct mtk_soc_data { + * @infra: The register map pointing at the range used to setup + * SGMII and GePHY path + * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances ++ * @sgmii_wrapped_pcs: Pointers to NETSYSv3 wrapper PCS instances ++ * @usxgmii_pll: The register map pointing at the range used to control ++ * the USXGMII SerDes PLL ++ * @regmap_pextp: The register map pointing at the range used to setup ++ * PHYA ++ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS + * @pctl: The register map pointing at the range used to setup + * GMAC port drive/slew values + * @dma_refcnt: track how many netdevs are using the DMA engine +@@ -1250,6 +1401,10 @@ struct mtk_eth { + struct regmap *ethsys; + struct regmap *infra; + struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; ++ struct regmap *toprgu; ++ struct regmap *usxgmii_pll; ++ struct regmap *regmap_pextp[MTK_MAX_DEVS]; ++ struct mtk_usxgmii_pcs *usxgmii_pcs[MTK_MAX_DEVS]; + struct regmap *pctl; + bool hwlro; + refcount_t dma_refcnt; +@@ -1437,6 +1592,19 @@ static inline u32 mtk_get_ib2_multicast_ + return MTK_FOE_IB2_MULTICAST; + } + ++static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_INTERNAL: ++ case PHY_INTERFACE_MODE_USXGMII: ++ case PHY_INTERFACE_MODE_10GBASER: ++ case PHY_INTERFACE_MODE_5GBASER: ++ return true; ++ default: ++ return false; ++ } ++} ++ + /* read the hardware status register */ + void mtk_stats_update_mac(struct mtk_mac *mac); + +@@ -1445,8 +1613,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne + u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); + + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); ++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); + + int mtk_eth_offload_init(struct mtk_eth *eth); + int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, +@@ -1456,5 +1626,63 @@ int mtk_flow_offload_cmd(struct mtk_eth + void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); + void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); + ++static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id) ++{ ++ int xgmii_id = mac_id; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ switch (mac_id) { ++ case MTK_GMAC1_ID: ++ case MTK_GMAC2_ID: ++ xgmii_id = 1; ++ break; ++ case MTK_GMAC3_ID: ++ xgmii_id = 0; ++ break; ++ default: ++ xgmii_id = -1; ++ } ++ } ++ ++ return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id; ++} ++ ++static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id) ++{ ++ int mac_id = xgmii_id; ++ ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ switch (xgmii_id) { ++ case 0: ++ mac_id = 2; ++ break; ++ case 1: ++ mac_id = 1; ++ break; ++ default: ++ mac_id = -1; ++ } ++ } ++ ++ return mac_id; ++} ++ ++#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII ++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id); ++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id); ++int mtk_usxgmii_init(struct mtk_eth *eth); ++#else ++static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id) ++{ ++ return NULL; ++} ++ ++static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) ++{ ++ return NULL; ++} ++ ++static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; } ++#endif /* NET_MEDIATEK_SOC_USXGMII */ + + #endif /* MTK_ETH_H */ +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c +@@ -0,0 +1,690 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2023 MediaTek Inc. ++ * Author: Henry Yen ++ * Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include "mtk_eth_soc.h" ++ ++static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) ++{ ++ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); ++} ++ ++static int mtk_xfi_pextp_init(struct mtk_eth *eth) ++{ ++ struct device *dev = eth->dev; ++ struct device_node *r = dev->of_node; ++ struct device_node *np; ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ np = of_parse_phandle(r, "mediatek,xfi-pextp", i); ++ if (!np) ++ break; ++ ++ eth->regmap_pextp[i] = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->regmap_pextp[i])) ++ return PTR_ERR(eth->regmap_pextp[i]); ++ } ++ ++ return 0; ++} ++ ++static int mtk_xfi_pll_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device_node *np; ++ ++ np = of_parse_phandle(r, "mediatek,xfi-pll", 0); ++ if (!np) ++ return -1; ++ ++ eth->usxgmii_pll = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->usxgmii_pll)) ++ return PTR_ERR(eth->usxgmii_pll); ++ ++ return 0; ++} ++ ++static int mtk_toprgu_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device_node *np; ++ ++ np = of_parse_phandle(r, "mediatek,toprgu", 0); ++ if (!np) ++ return -1; ++ ++ eth->toprgu = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->toprgu)) ++ return PTR_ERR(eth->toprgu); ++ ++ return 0; ++} ++ ++static int mtk_xfi_pll_enable(struct mtk_eth *eth) ++{ ++ u32 val = 0; ++ ++ if (!eth->usxgmii_pll) ++ return -EINVAL; ++ ++ /* Add software workaround for USXGMII PLL TCL issue */ ++ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA); ++ ++ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val); ++ val |= RG_XFI_PLL_EN; ++ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val); ++ ++ return 0; ++} ++ ++static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id) ++{ ++ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER || ++ interface == PHY_INTERFACE_MODE_USXGMII); ++ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX); ++ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER); ++ ++ /* Setup operation mode */ ++ if (is_10g) ++ regmap_write(pextp, 0x9024, 0x00C9071C); ++ else ++ regmap_write(pextp, 0x9024, 0x00D9071C); ++ ++ if (is_5g) ++ regmap_write(pextp, 0x2020, 0xAAA5A5AA); ++ else ++ regmap_write(pextp, 0x2020, 0xAA8585AA); ++ ++ if (is_2p5g || is_5g || is_10g) { ++ regmap_write(pextp, 0x2030, 0x0C020707); ++ regmap_write(pextp, 0x2034, 0x0E050F0F); ++ regmap_write(pextp, 0x2040, 0x00140032); ++ } else { ++ regmap_write(pextp, 0x2030, 0x0C020207); ++ regmap_write(pextp, 0x2034, 0x0E05050F); ++ regmap_write(pextp, 0x2040, 0x00200032); ++ } ++ ++ if (is_2p5g || is_10g) ++ regmap_write(pextp, 0x50F0, 0x00C014AA); ++ else if (is_5g) ++ regmap_write(pextp, 0x50F0, 0x00C018AA); ++ else ++ regmap_write(pextp, 0x50F0, 0x00C014BA); ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50E0, 0x3777812B); ++ regmap_write(pextp, 0x506C, 0x005C9CFF); ++ regmap_write(pextp, 0x5070, 0x9DFAFAFA); ++ regmap_write(pextp, 0x5074, 0x273F3F3F); ++ regmap_write(pextp, 0x5078, 0xA8883868); ++ regmap_write(pextp, 0x507C, 0x14661466); ++ } else { ++ regmap_write(pextp, 0x50E0, 0x3777C12B); ++ regmap_write(pextp, 0x506C, 0x005F9CFF); ++ regmap_write(pextp, 0x5070, 0x9D9DFAFA); ++ regmap_write(pextp, 0x5074, 0x27273F3F); ++ regmap_write(pextp, 0x5078, 0xA7883C68); ++ regmap_write(pextp, 0x507C, 0x11661166); ++ } ++ ++ if (is_2p5g || is_10g) { ++ regmap_write(pextp, 0x5080, 0x0E000AAF); ++ regmap_write(pextp, 0x5084, 0x08080D0D); ++ regmap_write(pextp, 0x5088, 0x02030909); ++ } else if (is_5g) { ++ regmap_write(pextp, 0x5080, 0x0E001ABF); ++ regmap_write(pextp, 0x5084, 0x080B0D0D); ++ regmap_write(pextp, 0x5088, 0x02050909); ++ } else { ++ regmap_write(pextp, 0x5080, 0x0E000EAF); ++ regmap_write(pextp, 0x5084, 0x08080E0D); ++ regmap_write(pextp, 0x5088, 0x02030B09); ++ } ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50E4, 0x0C000000); ++ regmap_write(pextp, 0x50E8, 0x04000000); ++ } else { ++ regmap_write(pextp, 0x50E4, 0x0C0C0000); ++ regmap_write(pextp, 0x50E8, 0x04040000); ++ } ++ ++ if (is_2p5g || mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x50EC, 0x0F0F0C06); ++ else ++ regmap_write(pextp, 0x50EC, 0x0F0F0606); ++ ++ if (is_5g) { ++ regmap_write(pextp, 0x50A8, 0x50808C8C); ++ regmap_write(pextp, 0x6004, 0x18000000); ++ } else { ++ regmap_write(pextp, 0x50A8, 0x506E8C8C); ++ regmap_write(pextp, 0x6004, 0x18190000); ++ } ++ ++ if (is_10g) ++ regmap_write(pextp, 0x00F8, 0x01423342); ++ else if (is_5g) ++ regmap_write(pextp, 0x00F8, 0x00A132A1); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x00F8, 0x009C329C); ++ else ++ regmap_write(pextp, 0x00F8, 0x00FA32FA); ++ ++ /* Force SGDT_OUT off and select PCS */ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x00F4, 0x80201F20); ++ else ++ regmap_write(pextp, 0x00F4, 0x80201F21); ++ ++ /* Force GLB_CKDET_OUT */ ++ regmap_write(pextp, 0x0030, 0x00050C00); ++ ++ /* Force AEQ on */ ++ regmap_write(pextp, 0x0070, 0x02002800); ++ ndelay(1020); ++ ++ /* Setup DA default value */ ++ regmap_write(pextp, 0x30B0, 0x00000020); ++ regmap_write(pextp, 0x3028, 0x00008A01); ++ regmap_write(pextp, 0x302C, 0x0000A884); ++ regmap_write(pextp, 0x3024, 0x00083002); ++ if (mtk_interface_mode_is_xgmii(interface)) { ++ regmap_write(pextp, 0x3010, 0x00022220); ++ regmap_write(pextp, 0x5064, 0x0F020A01); ++ regmap_write(pextp, 0x50B4, 0x06100600); ++ if (interface == PHY_INTERFACE_MODE_USXGMII) ++ regmap_write(pextp, 0x3048, 0x40704000); ++ else ++ regmap_write(pextp, 0x3048, 0x47684100); ++ } else { ++ regmap_write(pextp, 0x3010, 0x00011110); ++ regmap_write(pextp, 0x3048, 0x40704000); ++ } ++ ++ if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g) ++ regmap_write(pextp, 0x3064, 0x0000C000); ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII) { ++ regmap_write(pextp, 0x3050, 0xA8000000); ++ regmap_write(pextp, 0x3054, 0x000000AA); ++ } else if (mtk_interface_mode_is_xgmii(interface)) { ++ regmap_write(pextp, 0x3050, 0x00000000); ++ regmap_write(pextp, 0x3054, 0x00000000); ++ } else { ++ regmap_write(pextp, 0x3050, 0xA8000000); ++ regmap_write(pextp, 0x3054, 0x000000AA); ++ } ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x306C, 0x00000F00); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x306C, 0x22000F00); ++ else ++ regmap_write(pextp, 0x306C, 0x20200F00); ++ ++ if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0) ++ regmap_write(pextp, 0xA008, 0x0007B400); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0xA060, 0x00040000); ++ else ++ regmap_write(pextp, 0xA060, 0x00050000); ++ ++ if (is_10g) ++ regmap_write(pextp, 0x90D0, 0x00000001); ++ else if (is_5g) ++ regmap_write(pextp, 0x90D0, 0x00000003); ++ else if (is_2p5g) ++ regmap_write(pextp, 0x90D0, 0x00000005); ++ else ++ regmap_write(pextp, 0x90D0, 0x00000007); ++ ++ /* Release reset */ ++ regmap_write(pextp, 0x0070, 0x0200E800); ++ usleep_range(150, 500); ++ ++ /* Switch to P0 */ ++ regmap_write(pextp, 0x0070, 0x0200C111); ++ ndelay(1020); ++ regmap_write(pextp, 0x0070, 0x0200C101); ++ usleep_range(15, 50); ++ ++ if (mtk_interface_mode_is_xgmii(interface)) { ++ /* Switch to Gen3 */ ++ regmap_write(pextp, 0x0070, 0x0202C111); ++ } else { ++ /* Switch to Gen2 */ ++ regmap_write(pextp, 0x0070, 0x0201C111); ++ } ++ ndelay(1020); ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x0070, 0x0202C101); ++ else ++ regmap_write(pextp, 0x0070, 0x0201C101); ++ usleep_range(100, 500); ++ regmap_write(pextp, 0x30B0, 0x00000030); ++ if (mtk_interface_mode_is_xgmii(interface)) ++ regmap_write(pextp, 0x00F4, 0x80201F00); ++ else ++ regmap_write(pextp, 0x00F4, 0x80201F01); ++ ++ regmap_write(pextp, 0x3040, 0x30000000); ++ usleep_range(400, 1000); ++} ++ ++static void mtk_usxgmii_reset(struct mtk_eth *eth, int id) ++{ ++ u32 toggle, val; ++ ++ if (id >= MTK_MAX_DEVS || !eth->toprgu) ++ return; ++ ++ switch (id) { ++ case 0: ++ toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST | ++ SWSYSRST_SGMII0_GRST; ++ break; ++ case 1: ++ toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST | ++ SWSYSRST_SGMII1_GRST; ++ break; ++ default: ++ return; ++ } ++ ++ /* Enable software reset */ ++ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); ++ ++ /* Assert USXGMII reset */ ++ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST, ++ FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle); ++ ++ usleep_range(100, 500); ++ ++ /* De-assert USXGMII reset */ ++ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); ++ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); ++ val &= ~toggle; ++ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); ++ ++ /* Disable software reset */ ++ regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); ++ ++ mdelay(10); ++} ++ ++/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit ++ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config ++ * also trigger an initial reset and subsequent configuration of the PHYA. ++ */ ++struct mtk_sgmii_wrapper_pcs { ++ struct mtk_eth *eth; ++ struct phylink_pcs *wrapped_pcs; ++ u8 id; ++ struct phylink_pcs pcs; ++}; ++ ++static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs, ++ unsigned int mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ bool full_reconf; ++ int ret; ++ ++ full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface; ++ if (full_reconf) { ++ mtk_xfi_pll_enable(wp->eth); ++ mtk_usxgmii_reset(wp->eth, wp->id); ++ } ++ ++ ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface, ++ advertising, permit_pause_to_mac); ++ ++ if (full_reconf) ++ mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id); ++ ++ wp->eth->usxgmii_pcs[wp->id]->interface = interface; ++ ++ return ret; ++} ++ ++static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state); ++} ++ ++static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs); ++} ++ ++static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs, ++ unsigned int mode, ++ phy_interface_t interface, int speed, ++ int duplex) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex); ++} ++ ++static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); ++ ++ wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs); ++ ++ wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA; ++} ++ ++static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = { ++ .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state, ++ .pcs_config = mtk_sgmii_wrapped_pcs_config, ++ .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart, ++ .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up, ++ .pcs_disable = mtk_sgmii_wrapped_pcs_disable, ++}; ++ ++static int mtk_sgmii_wrapper_init(struct mtk_eth *eth) ++{ ++ struct mtk_sgmii_wrapper_pcs *wp; ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->sgmii_pcs[i]) ++ continue; ++ ++ if (!eth->usxgmii_pcs[i]) ++ continue; ++ ++ /* Make sure all PCS ops are supported by wrapped PCS */ ++ if (!eth->sgmii_pcs[i]->ops->pcs_get_state || ++ !eth->sgmii_pcs[i]->ops->pcs_config || ++ !eth->sgmii_pcs[i]->ops->pcs_an_restart || ++ !eth->sgmii_pcs[i]->ops->pcs_link_up || ++ !eth->sgmii_pcs[i]->ops->pcs_disable) ++ return -EOPNOTSUPP; ++ ++ wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL); ++ if (!wp) ++ return -ENOMEM; ++ ++ wp->wrapped_pcs = eth->sgmii_pcs[i]; ++ wp->id = i; ++ wp->pcs.poll = true; ++ wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops; ++ wp->eth = eth; ++ ++ eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs; ++ } ++ ++ return 0; ++} ++ ++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id) ++{ ++ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); ++ ++ if (!eth->usxgmii_pcs[xgmii_id]) ++ return NULL; ++ ++ return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs; ++} ++ ++static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ struct mtk_eth *eth = mpcs->eth; ++ struct regmap *pextp = eth->regmap_pextp[mpcs->id]; ++ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; ++ bool mode_changed = false; ++ ++ if (!pextp) ++ return -ENODEV; ++ ++ if (interface == PHY_INTERFACE_MODE_USXGMII) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); ++ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { ++ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); ++ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | ++ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); ++ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) | ++ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G); ++ adapt_mode = USXGMII_RATE_UPDATE_MODE; ++ } else { ++ return -EINVAL; ++ } ++ ++ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); ++ ++ if (mpcs->interface != interface) { ++ mpcs->interface = interface; ++ mode_changed = true; ++ } ++ ++ mtk_xfi_pll_enable(eth); ++ mtk_usxgmii_reset(eth, mpcs->id); ++ ++ /* Setup USXGMII AN ctrl */ ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0, ++ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, ++ an_ctrl); ++ ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2, ++ USXGMII_LINK_TIMER_IDLE_DETECT | ++ USXGMII_LINK_TIMER_COMP_ACK_DETECT | ++ USXGMII_LINK_TIMER_AN_RESTART, ++ link_timer); ++ ++ mpcs->mode = mode; ++ ++ /* Gated MAC CK */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); ++ ++ /* Enable interface force mode */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); ++ ++ /* Setup USXGMII adapt mode */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, ++ adapt_mode); ++ ++ /* Setup USXGMII speed */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, ++ xfi_mode); ++ ++ usleep_range(1, 10); ++ ++ /* Un-gated MAC CK */ ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_MAC_CK_GATED, 0); ++ ++ usleep_range(1, 10); ++ ++ /* Disable interface force mode for the AN mode */ ++ if (an_ctrl & USXGMII_AN_ENABLE) ++ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, ++ USXGMII_IF_FORCE_EN, 0); ++ ++ /* Setup USXGMIISYS with the determined property */ ++ mtk_usxgmii_setup_phya(pextp, interface, mpcs->id); ++ ++ return mode_changed; ++} ++ ++static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ struct mtk_eth *eth = mpcs->eth; ++ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)]; ++ u32 val = 0; ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); ++ if (FIELD_GET(USXGMII_AN_ENABLE, val)) { ++ /* Refresh LPA by inverting LPA_LATCH */ ++ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); ++ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0, ++ USXGMII_LPA_LATCH, ++ !(val & USXGMII_LPA_LATCH)); ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); ++ ++ phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD, ++ val)); ++ ++ state->interface = mpcs->interface; ++ } else { ++ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); ++ ++ if (mac->id == MTK_GMAC2_ID) ++ val >>= 16; ++ ++ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) { ++ case 0: ++ state->speed = SPEED_10000; ++ break; ++ case 1: ++ state->speed = SPEED_5000; ++ break; ++ case 2: ++ state->speed = SPEED_2500; ++ break; ++ case 3: ++ state->speed = SPEED_1000; ++ break; ++ } ++ ++ state->interface = mpcs->interface; ++ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val); ++ state->duplex = DUPLEX_FULL; ++ } ++ ++ /* Continuously repeat re-configuration sequence until link comes up */ ++ if (state->link == 0) ++ mtk_usxgmii_pcs_config(pcs, mpcs->mode, ++ state->interface, NULL, false); ++} ++ ++static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) ++{ ++ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); ++ unsigned int val = 0; ++ ++ if (!mpcs->regmap) ++ return; ++ ++ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); ++ val |= USXGMII_AN_RESTART; ++ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val); ++} ++ ++static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, ++ int speed, int duplex) ++{ ++ /* Reconfiguring USXGMII to ensure the quality of the RX signal ++ * after the line side link up. ++ */ ++ mtk_usxgmii_pcs_config(pcs, mode, ++ interface, NULL, false); ++} ++ ++static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { ++ .pcs_config = mtk_usxgmii_pcs_config, ++ .pcs_get_state = mtk_usxgmii_pcs_get_state, ++ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, ++ .pcs_link_up = mtk_usxgmii_pcs_link_up, ++}; ++ ++int mtk_usxgmii_init(struct mtk_eth *eth) ++{ ++ struct device_node *r = eth->dev->of_node; ++ struct device *dev = eth->dev; ++ struct device_node *np; ++ int i, ret; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ np = of_parse_phandle(r, "mediatek,usxgmiisys", i); ++ if (!np) ++ break; ++ ++ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL); ++ if (!eth->usxgmii_pcs[i]) ++ return -ENOMEM; ++ ++ eth->usxgmii_pcs[i]->id = i; ++ eth->usxgmii_pcs[i]->eth = eth; ++ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np); ++ if (IS_ERR(eth->usxgmii_pcs[i]->regmap)) ++ return PTR_ERR(eth->usxgmii_pcs[i]->regmap); ++ ++ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops; ++ eth->usxgmii_pcs[i]->pcs.poll = true; ++ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA; ++ eth->usxgmii_pcs[i]->mode = -1; ++ ++ of_node_put(np); ++ } ++ ++ ret = mtk_xfi_pextp_init(eth); ++ if (ret) ++ return ret; ++ ++ ret = mtk_xfi_pll_init(eth); ++ if (ret) ++ return ret; ++ ++ ret = mtk_toprgu_init(eth); ++ if (ret) ++ return ret; ++ ++ return mtk_sgmii_wrapper_init(eth); ++} ++ ++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id) ++{ ++ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); ++ ++ if (!eth->usxgmii_pcs[xgmii_id]->regmap) ++ return NULL; ++ ++ return ð->usxgmii_pcs[xgmii_id]->pcs; ++} diff --git a/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch new file mode 100644 index 000000000..013261cb8 --- /dev/null +++ b/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch @@ -0,0 +1,61 @@ +From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001 +Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org> +From: Daniel Golle +Date: Mon, 11 Sep 2023 21:27:44 +0100 +Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error +To: Greg Kroah-Hartman , + Jiri Slaby , + Matthias Brugger , + AngeloGioacchino Del Regno , + Daniel Golle , + John Ogness , + Chen-Yu Tsai , + Changqi Hu , + linux-kernel@vger.kernel.org, + linux-serial@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, + linux-mediatek@lists.infradead.org + +Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and +clock management") introduced polling a debug register to make sure +the UART is idle before disabling the bus clock. However, at least on +some MediaTek SoCs access to that very debug register requires the bus +clock being enabled. Hence calling the suspend function while already +in suspended state results in that register access triggering a bus +error. In order to avoid that, track the state of the bus clock and +only poll the debug register if not already in suspended state. + +Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management") +Signed-off-by: Daniel Golle +--- + drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/8250/8250_mtk.c ++++ b/drivers/tty/serial/8250/8250_mtk.c +@@ -32,7 +32,7 @@ + #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ + #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ + #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ +-#define MTK_UART_DEBUG0 0x18 ++#define MTK_UART_DEBUG0 0x18 + #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ + #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ + #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ +@@ -422,13 +422,12 @@ static int __maybe_unused mtk8250_runtim + struct mtk8250_data *data = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(data->line); + +- /* wait until UART in idle status */ +- while +- (serial_in(up, MTK_UART_DEBUG0)); +- + if (data->clk_count == 0U) { + dev_dbg(dev, "%s clock count is 0\n", __func__); + } else { ++ /* wait until UART in idle status */ ++ while ++ (serial_in(up, MTK_UART_DEBUG0)); + clk_disable_unprepare(data->bus_clk); + data->clk_count--; + } diff --git a/target/linux/ipq806x/patches-5.10/0067-generic-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/ipq806x/patches-5.10/0067-generic-Mangle-bootloader-s-kernel-arguments.patch index 5bfc3edde..4aa8c5659 100644 --- a/target/linux/ipq806x/patches-5.10/0067-generic-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/ipq806x/patches-5.10/0067-generic-Mangle-bootloader-s-kernel-arguments.patch @@ -189,7 +189,7 @@ Signed-off-by: Adrian Panella static int kernel_init(void *); extern void init_IRQ(void); -@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa +@@ -905,6 +909,18 @@ asmlinkage __visible void __init __no_sa pr_notice("Kernel command line: %s\n", saved_command_line); /* parameters may set static keys */ jump_label_init(); diff --git a/target/linux/ipq95xx/patches-6.1/0037-cpufreq-qcom-nvmem-Introduce-cpufreq-for-ipq95xx.patch b/target/linux/ipq95xx/patches-6.1/0037-cpufreq-qcom-nvmem-Introduce-cpufreq-for-ipq95xx.patch index e07815592..e1785ae47 100644 --- a/target/linux/ipq95xx/patches-6.1/0037-cpufreq-qcom-nvmem-Introduce-cpufreq-for-ipq95xx.patch +++ b/target/linux/ipq95xx/patches-6.1/0037-cpufreq-qcom-nvmem-Introduce-cpufreq-for-ipq95xx.patch @@ -36,7 +36,7 @@ Signed-off-by: Viresh Kumar { .compatible = "qcom,msm8960", }, --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -149,6 +149,11 @@ static int qcom_cpufreq_kryo_name_versio +@@ -148,6 +148,11 @@ static int qcom_cpufreq_kryo_name_versio switch (msm_id) { case QCOM_ID_MSM8996: case QCOM_ID_APQ8096: diff --git a/target/linux/lantiq/patches-5.10/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-5.10/0001-MIPS-lantiq-add-pcie-driver.patch index ba07ddb16..f453023f1 100644 --- a/target/linux/lantiq/patches-5.10/0001-MIPS-lantiq-add-pcie-driver.patch +++ b/target/linux/lantiq/patches-5.10/0001-MIPS-lantiq-add-pcie-driver.patch @@ -5481,7 +5481,7 @@ Signed-off-by: John Crispin (transaction layer end-to-end CRC checking). --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -1421,6 +1421,8 @@ void pci_walk_bus(struct pci_bus *top, i +@@ -1427,6 +1427,8 @@ void pci_walk_bus(struct pci_bus *top, i void *userdata); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); diff --git a/target/linux/layerscape/patches-5.15/702-phy-Add-2.5G-SGMII-interface-mode.patch b/target/linux/layerscape/patches-5.15/702-phy-Add-2.5G-SGMII-interface-mode.patch index 35c11d3ef..4bbb545d8 100644 --- a/target/linux/layerscape/patches-5.15/702-phy-Add-2.5G-SGMII-interface-mode.patch +++ b/target/linux/layerscape/patches-5.15/702-phy-Add-2.5G-SGMII-interface-mode.patch @@ -13,7 +13,7 @@ Signed-off-by: Bhaskar Upadhaya --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -152,6 +152,7 @@ typedef enum { +@@ -153,6 +153,7 @@ typedef enum { PHY_INTERFACE_MODE_USXGMII, /* 10GBASE-KR - with Clause 73 AN */ PHY_INTERFACE_MODE_10GKR, @@ -21,7 +21,7 @@ Signed-off-by: Bhaskar Upadhaya PHY_INTERFACE_MODE_MAX, } phy_interface_t; -@@ -267,6 +268,8 @@ static inline const char *phy_modes(phy_ +@@ -268,6 +269,8 @@ static inline const char *phy_modes(phy_ return "10gbase-kr"; case PHY_INTERFACE_MODE_100BASEX: return "100base-x"; diff --git a/target/linux/meson/image/Makefile b/target/linux/meson/image/Makefile deleted file mode 100644 index 2aac6a2fa..000000000 --- a/target/linux/meson/image/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/image.mk - -FAT32_BLOCK_SIZE=1024 -FAT32_BLOCKS=$(shell echo $$(($(CONFIG_TARGET_KERNEL_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) - -define Build/boot-script - # Make an U-boot image and copy it to the boot partition - mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "boot.scr" -d boot.txt $(KDIR)/boot.scr -endef - -define Build/emmc-common - $(RM) -f $@.boot - mkfs.fat -C $@.boot $(FAT32_BLOCKS) - - mkdir -p $(KDIR)/boot.fat - - $(CP) $(KDIR)/boot.scr $(KDIR)/boot.fat/boot.scr - mcopy -i $@.boot $(KDIR)/boot.scr :: - $(CP) $(IMAGE_KERNEL) $(KDIR)/boot.fat/uImage - mcopy -i $@.boot $(KDIR)/boot.fat/uImage :: - - $(foreach dts,$(shell echo $(DEVICE_DTS)),$(CP) $(DTS_DIR)/$(dts).dtb $(KDIR)/boot.fat/dtb;) - mcopy -i $@.boot $(KDIR)/boot.fat/dtb :: - - $(RM) -rf $(KDIR)/boot.fat - - ./gen_aml_emmc_img.sh $@ $@.boot $(IMAGE_ROOTFS) \ - $(CONFIG_TARGET_KERNEL_PARTSIZE) $(CONFIG_TARGET_ROOTFS_PARTSIZE) -endef - -### Devices ### -define Device/Default - FILESYSTEMS := ext4 - IMAGES := emmc.img - KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) - KERNEL_LOADADDR := 0x01080000 - KERNEL_NAME := Image - KERNEL := kernel-bin | uImage none - PROFILES = Default $$(DEVICE_NAME) -endef - -define Device/thunder-onecloud - DEVICE_DTS := meson8b-onecloud - DEVICE_TITLE := Thunder OneCloud - KERNEL_LOADADDR := 0x00208000 - IMAGE/emmc.img := boot-script onecloud | emmc-common $$(DEVICE_NAME) -endef -ifeq ($(SUBTARGET),meson8b) - TARGET_DEVICES += thunder-onecloud -endif - -$(eval $(call BuildImage)) diff --git a/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds b/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds index 809a64a60..d8cca08ca 100644 --- a/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds +++ b/target/linux/mvebu/cortexa72/base-files/etc/board.d/01_leds @@ -7,9 +7,11 @@ board_config_update board=$(board_name) case "$board" in +qnap,qhora-321|\ iei,puzzle-m901) ucidef_set_led_netdev "wan" "WAN" "white:network" "eth0" "link" ;; +qnap,qhora-322|\ iei,puzzle-m902) ucidef_set_led_netdev "wan" "WAN" "white:network" "eth2" "link" ;; diff --git a/target/linux/mvebu/cortexa72/base-files/etc/board.d/02_network b/target/linux/mvebu/cortexa72/base-files/etc/board.d/02_network index 6a5861084..c5704c5a3 100644 --- a/target/linux/mvebu/cortexa72/base-files/etc/board.d/02_network +++ b/target/linux/mvebu/cortexa72/base-files/etc/board.d/02_network @@ -13,9 +13,11 @@ case "$board" in globalscale,mochabin) ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" "eth0 eth2" ;; +qnap,qhora-321|\ iei,puzzle-m901) ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4 eth5" "eth0" ;; +qnap,qhora-322|\ iei,puzzle-m902) ucidef_set_interfaces_lan_wan "eth0 eth1 eth3 eth4 eth5 eth6 eth7 eth8" "eth2" ;; diff --git a/target/linux/mvebu/cortexa72/base-files/lib/upgrade/emmc-puzzle.sh b/target/linux/mvebu/cortexa72/base-files/lib/upgrade/emmc-puzzle.sh index 5e5c356ed..5c184e529 100755 --- a/target/linux/mvebu/cortexa72/base-files/lib/upgrade/emmc-puzzle.sh +++ b/target/linux/mvebu/cortexa72/base-files/lib/upgrade/emmc-puzzle.sh @@ -31,6 +31,8 @@ platform_do_upgrade_emmc() { v "Writing new UUID to /dev/$diskdev..." get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync + + mkfs.ext4 -F -L rootfs_data $(find_mmc_part rootfs_data) sleep 1 } diff --git a/target/linux/mvebu/cortexa72/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa72/base-files/lib/upgrade/platform.sh index dc964a311..527584f69 100755 --- a/target/linux/mvebu/cortexa72/base-files/lib/upgrade/platform.sh +++ b/target/linux/mvebu/cortexa72/base-files/lib/upgrade/platform.sh @@ -10,6 +10,8 @@ REQUIRE_IMAGE_METADATA=1 platform_check_image() { case "$(board_name)" in globalscale,mochabin|\ + qnap,qhora-321|\ + qnap,qhora-322|\ iei,puzzle-m901|\ iei,puzzle-m902|\ marvell,armada8040-mcbin-doubleshot|\ @@ -25,6 +27,8 @@ platform_check_image() { platform_do_upgrade() { case "$(board_name)" in + qnap,qhora-321|\ + qnap,qhora-322|\ iei,puzzle-m901|\ iei,puzzle-m902) platform_do_upgrade_emmc "$1" @@ -43,6 +47,8 @@ platform_do_upgrade() { platform_copy_config() { case "$(board_name)" in globalscale,mochabin|\ + qnap,qhora-321|\ + qnap,qhora-322|\ iei,puzzle-m901|\ iei,puzzle-m902|\ marvell,armada8040-mcbin-doubleshot|\ diff --git a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-db-A.dts b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-db-A.dts new file mode 100644 index 000000000..4f84d036f --- /dev/null +++ b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-db-A.dts @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * Device tree for the CN9131-DB board. + */ + +#include "cn9130.dtsi" + +#include +#include + +/ { + model = "QNAP QHora-321"; + compatible = "qnap,qhora-321", + "marvell,armada-ap807-quad", "marvell,armada-ap807"; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-append = " root=/dev/mmcblk0p3"; + }; + + aliases { + i2c0 = &cp1_i2c0; + i2c1 = &cp0_i2c0; + ethernet0 = &cp0_eth0; + ethernet1 = &cp0_eth1; + ethernet2 = &cp0_eth2; + ethernet3 = &cp1_eth0; + ethernet4 = &cp1_eth1; + ethernet5 = &cp1_eth2; + gpio1 = &cp0_gpio1; + gpio2 = &cp0_gpio2; + gpio3 = &cp1_gpio1; + gpio4 = &cp1_gpio2; + led-boot = &led_power; + led-failsafe = &led_info; + led-running = &led_power; + led-upgrade = &led_info; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + gpio_keys { + compatible = "gpio-keys"; + + reset { + label = "Reset"; + linux,code = ; + gpios = <&cp0_gpio2 4 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&cp0_uart0 { + status = "okay"; + + puzzle-mcu { + compatible = "iei,wt61p803-puzzle"; + #address-cells = <1>; + #size-cells = <1>; + current-speed = <115200>; + enable-beep; + status = "okay"; + + leds { + compatible = "iei,wt61p803-puzzle-leds"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + led@0 { + reg = <0>; + label = "white:network"; + active-low; + }; + + led@1 { + reg = <1>; + label = "green:cloud"; + active-low; + }; + + led_info: led@2 { + reg = <2>; + label = "orange:info"; + active-low; + }; + + led_power: led@3 { + reg = <3>; + label = "yellow:power"; + active-low; + default-state = "on"; + }; + }; + + hwmon { + compatible = "iei,wt61p803-puzzle-hwmon"; + #address-cells = <1>; + #size-cells = <0>; + + chassis_fan_group0: fan-group@0 { + #cooling-cells = <2>; + reg = <0x00>; + cooling-levels = <64 102 170 230 250>; + }; + }; + }; +}; + +&ap_thermal_cpu1 { + trips { + cpu_active: cpu-active { + temperature = <44000>; + hysteresis = <2000>; + type = "active"; + }; + }; + cooling-maps { + fan-map { + trip = <&cpu_active>; + cooling-device = <&chassis_fan_group0 64 THERMAL_NO_LIMIT>; + }; + }; +}; + +/* on-board eMMC - U9 */ +&ap_sdhci0 { + pinctrl-names = "default"; + bus-width = <8>; + status = "okay"; + mmc-ddr-1_8v; + mmc-hs400-1_8v; +}; + +&cp0_crypto { + status = "okay"; +}; + +&cp0_xmdio { + status = "okay"; + cp0_nbaset_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + cp0_nbaset_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + cp0_nbaset_phy2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cp0_ethernet { + status = "okay"; +}; + +/* SLM-1521-V2, CON9 */ +&cp0_eth0 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp0_comphy2 0>; + phy = <&cp0_nbaset_phy0>; +}; + +&cp0_eth1 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp0_comphy4 1>; + phy = <&cp0_nbaset_phy1>; +}; + +&cp0_eth2 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp0_comphy5 2>; + phy = <&cp0_nbaset_phy2>; +}; + +&cp0_gpio1 { + status = "okay"; +}; + +&cp0_gpio2 { + status = "okay"; +}; + +&cp0_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + wakeup-source; + }; +}; + +/* SLM-1521-V2, CON6 */ +&cp0_pcie0 { + status = "okay"; + num-lanes = <2>; + num-viewport = <8>; + phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>; +}; + +/* U55 */ +&cp0_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_spi0_pins>; + reg = <0x700680 0x50>, /* control */ + <0x2000000 0x1000000>; /* CS0 */ + status = "okay"; + spi-flash@0 { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <40000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "U-Boot"; + reg = <0x0 0x1f0000>; + }; + partition@1f0000 { + label = "U-Boot ENV Factory"; + reg = <0x1f0000 0x10000>; + }; + partition@200000 { + label = "Reserved"; + reg = <0x200000 0x1f0000>; + }; + partition@3f0000 { + label = "U-Boot ENV"; + reg = <0x3f0000 0x10000>; + }; + }; + }; +}; + +&cp0_syscon0 { + cp0_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + cp0_i2c0_pins: cp0-i2c-pins-0 { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cp0_i2c1_pins: cp0-i2c-pins-1 { + marvell,pins = "mpp35", "mpp36"; + marvell,function = "i2c1"; + }; + cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { + marvell,pins = "mpp0", "mpp1", "mpp2", + "mpp3", "mpp4", "mpp5", + "mpp6", "mpp7", "mpp8", + "mpp9", "mpp10", "mpp11"; + marvell,function = "ge0"; + }; + cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { + marvell,pins = "mpp44", "mpp45", "mpp46", + "mpp47", "mpp48", "mpp49", + "mpp50", "mpp51", "mpp52", + "mpp53", "mpp54", "mpp55"; + marvell,function = "ge1"; + }; + cp0_spi0_pins: cp0-spi-pins-0 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; + }; +}; + +/* + * Instantiate the first connected CP115 + */ + +#define CP11X_NAME cp1 +#define CP11X_BASE f6000000 +#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000)) +#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000 +#define CP11X_PCIE0_BASE f6600000 +#define CP11X_PCIE1_BASE f6620000 +#define CP11X_PCIE2_BASE f6640000 + +#include "armada-cp115.dtsi" + +#undef CP11X_NAME +#undef CP11X_BASE +#undef CP11X_PCIEx_MEM_BASE +#undef CP11X_PCIEx_MEM_SIZE +#undef CP11X_PCIE0_BASE +#undef CP11X_PCIE1_BASE +#undef CP11X_PCIE2_BASE + +&cp1_crypto { + status = "okay"; +}; + +&cp1_xmdio { + status = "okay"; + cp1_nbaset_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + cp1_nbaset_phy1: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + cp1_nbaset_phy2: ethernet-phy@5 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cp1_ethernet { + status = "okay"; +}; + +/* CON50 */ +&cp1_eth0 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp1_comphy2 0>; + phy = <&cp1_nbaset_phy0>; +}; + +&cp1_eth1 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp1_comphy4 1>; + phy = <&cp1_nbaset_phy1>; +}; + +&cp1_eth2 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp1_comphy5 2>; + phy = <&cp1_nbaset_phy2>; +}; + +&cp1_sata0 { + status = "okay"; + sata-port@1 { + status = "okay"; + phys = <&cp1_comphy0 1>; + }; +}; + +&cp1_gpio1 { + status = "okay"; +}; + +&cp1_gpio2 { + status = "okay"; +}; + +&cp1_i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&cp1_i2c0_pins>; + clock-frequency = <100000>; +}; + +&cp1_syscon0 { + cp1_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + cp1_i2c0_pins: cp1-i2c-pins-0 { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cp1_spi0_pins: cp1-spi-pins-0 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; + cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins { + marvell,pins = "mpp3"; + marvell,function = "gpio"; + }; + cp1_sfp_pins: sfp-pins { + marvell,pins = "mpp8", "mpp9", "mpp10", "mpp11"; + marvell,function = "gpio"; + }; + }; +}; + +&cp1_usb3_1 { + status = "okay"; + phys = <&cp1_comphy3 1>; + phy-names = "usb"; +}; diff --git a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-puzzle-m901.dts b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-puzzle-m901.dts index 80d876b4a..4c1ca8c10 100644 --- a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-puzzle-m901.dts +++ b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9131-puzzle-m901.dts @@ -17,6 +17,7 @@ chosen { stdout-path = "serial0:115200n8"; + bootargs-append = " root=/dev/mmcblk0p3"; }; aliases { diff --git a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-db-A.dts b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-db-A.dts new file mode 100644 index 000000000..cd844552d --- /dev/null +++ b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-db-A.dts @@ -0,0 +1,565 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2019 Marvell International Ltd. + * + * Device tree for the CN9132-DB board. + */ + +#include "cn9130.dtsi" + +#include +#include + +/ { + model = "QNAP QHora-322"; + compatible = "qnap,qhora-322", + "marvell,armada-ap807-quad", "marvell,armada-ap807"; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-append = " root=/dev/mmcblk0p3"; + }; + + aliases { + i2c0 = &cp1_i2c0; + i2c1 = &cp0_i2c0; + gpio1 = &cp0_gpio1; + gpio2 = &cp0_gpio2; + gpio3 = &cp1_gpio1; + gpio4 = &cp1_gpio2; + gpio5 = &cp2_gpio1; + gpio6 = &cp2_gpio2; + ethernet0 = &cp0_eth0; + ethernet1 = &cp0_eth1; + ethernet2 = &cp0_eth2; + ethernet3 = &cp1_eth0; + ethernet4 = &cp1_eth1; + ethernet5 = &cp1_eth2; + ethernet6 = &cp2_eth0; + ethernet7 = &cp2_eth1; + ethernet8 = &cp2_eth2; + spi1 = &cp0_spi0; + spi2 = &cp0_spi1; + led-boot = &led_power; + led-failsafe = &led_info; + led-running = &led_power; + led-upgrade = &led_info; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + gpio_keys { + compatible = "gpio-keys"; + + reset { + label = "Reset"; + linux,code = ; + gpios = <&cp0_gpio2 4 GPIO_ACTIVE_LOW>; + }; + }; + + cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 { + compatible = "regulator-fixed"; + regulator-name = "cp2-xhci0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + cp2_usb3_0_phy0: cp2_usb3_phy0 { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cp2_reg_usb3_vbus0>; + }; + + cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 { + compatible = "regulator-fixed"; + regulator-name = "cp2-xhci1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>; + }; + + cp2_usb3_0_phy1: cp2_usb3_phy1 { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cp2_reg_usb3_vbus1>; + }; + + cp2_sfp_eth0: sfp-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&cp2_sfpp0_i2c>; + los-gpio = <&cp2_module_expander1 11 GPIO_ACTIVE_HIGH>; + mod-def0-gpio = <&cp2_module_expander1 10 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&cp2_module_expander1 9 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&cp2_module_expander1 8 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&cp0_uart0 { + status = "okay"; + + puzzle-mcu { + compatible = "iei,wt61p803-puzzle"; + #address-cells = <1>; + #size-cells = <1>; + current-speed = <115200>; + enable-beep; + status = "okay"; + + leds { + compatible = "iei,wt61p803-puzzle-leds"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + led@0 { + reg = <0>; + label = "white:network"; + active-low; + }; + + led@1 { + reg = <1>; + label = "green:cloud"; + active-low; + }; + + led_info: led@2 { + reg = <2>; + label = "orange:info"; + active-low; + }; + + led_power: led@3 { + reg = <3>; + label = "yellow:power"; + active-low; + default-state = "on"; + }; + }; + + hwmon { + compatible = "iei,wt61p803-puzzle-hwmon"; + #address-cells = <1>; + #size-cells = <0>; + + chassis_fan_group0: fan-group@0 { + #cooling-cells = <2>; + reg = <0x00>; + cooling-levels = <64 102 170 230 250>; + }; + }; + }; +}; + +&ap_thermal_cpu1 { + trips { + cpu_active: cpu-active { + temperature = <44000>; + hysteresis = <2000>; + type = "active"; + }; + }; + cooling-maps { + fan-map { + trip = <&cpu_active>; + cooling-device = <&chassis_fan_group0 64 THERMAL_NO_LIMIT>; + }; + }; +}; + +/* on-board eMMC - U9 */ +&ap_sdhci0 { + pinctrl-names = "default"; + bus-width = <8>; + status = "okay"; + mmc-ddr-1_8v; + mmc-hs400-1_8v; +}; + +&cp0_crypto { + status = "okay"; +}; + +&cp0_xmdio { + status = "okay"; + cp0_nbaset_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + cp0_nbaset_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + cp0_nbaset_phy2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cp0_ethernet { + status = "okay"; +}; + +/* SLM-1521-V2, CON9 */ +&cp0_eth0 { + status = "okay"; + phy-mode = "10gbase-kr"; + phys = <&cp0_comphy2 0>; + phy = <&cp0_nbaset_phy0>; +}; + +&cp0_eth1 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp0_comphy4 1>; + phy = <&cp0_nbaset_phy1>; +}; + +&cp0_eth2 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp0_comphy1 2>; + phy = <&cp0_nbaset_phy2>; +}; + +&cp0_gpio1 { + status = "okay"; +}; + +&cp0_gpio2 { + status = "okay"; +}; + +&cp0_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + wakeup-source; + }; +}; + +&cp0_i2c1 { + clock-frequency = <100000>; +}; + +/* SLM-1521-V2, CON6 */ +&cp0_sata0 { + status = "okay"; + sata-port@1 { + status = "okay"; + phys = <&cp0_comphy0 1>; + }; +}; + +&cp0_pcie2 { + status = "okay"; + num-lanes = <1>; + num-viewport = <8>; + phys = <&cp0_comphy5 2>; +}; + +/* U55 */ +&cp0_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_spi0_pins>; + reg = <0x700680 0x50>, /* control */ + <0x2000000 0x1000000>; /* CS0 */ + status = "okay"; + spi-flash@0 { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <40000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "U-Boot"; + reg = <0x0 0x1f0000>; + }; + partition@1f0000 { + label = "U-Boot ENV Factory"; + reg = <0x1f0000 0x10000>; + }; + partition@200000 { + label = "Reserved"; + reg = <0x200000 0x1f0000>; + }; + partition@3f0000 { + label = "U-Boot ENV"; + reg = <0x3f0000 0x10000>; + }; + }; + }; +}; + +&cp0_syscon0 { + cp0_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + cp0_i2c0_pins: cp0-i2c-pins-0 { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cp0_i2c1_pins: cp0-i2c-pins-1 { + marvell,pins = "mpp35", "mpp36"; + marvell,function = "i2c1"; + }; + cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { + marvell,pins = "mpp0", "mpp1", "mpp2", + "mpp3", "mpp4", "mpp5", + "mpp6", "mpp7", "mpp8", + "mpp9", "mpp10", "mpp11"; + marvell,function = "ge0"; + }; + cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { + marvell,pins = "mpp44", "mpp45", "mpp46", + "mpp47", "mpp48", "mpp49", + "mpp50", "mpp51", "mpp52", + "mpp53", "mpp54", "mpp55"; + marvell,function = "ge1"; + }; + cp0_spi0_pins: cp0-spi-pins-0 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; + }; +}; + +&cp0_usb3_1 { + status = "okay"; + phys = <&cp0_comphy3 1>; + phy-names = "usb"; +}; + +/* + * Instantiate the first connected CP115 + */ + +#define CP11X_NAME cp1 +#define CP11X_BASE f4000000 +#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000)) +#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000 +#define CP11X_PCIE0_BASE f4600000 +#define CP11X_PCIE1_BASE f4620000 +#define CP11X_PCIE2_BASE f4640000 + +#include "armada-cp115.dtsi" + +#undef CP11X_NAME +#undef CP11X_BASE +#undef CP11X_PCIEx_MEM_BASE +#undef CP11X_PCIEx_MEM_SIZE +#undef CP11X_PCIE0_BASE +#undef CP11X_PCIE1_BASE +#undef CP11X_PCIE2_BASE + +&cp1_crypto { + status = "okay"; +}; + +&cp1_xmdio { + status = "okay"; + cp1_nbaset_phy0: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + cp1_nbaset_phy1: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + cp1_nbaset_phy2: ethernet-phy@5 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cp1_ethernet { + status = "okay"; +}; + +/* CON50 */ +&cp1_eth0 { + status = "okay"; + phy-mode = "10gbase-kr"; + phys = <&cp1_comphy2 0>; + phy = <&cp1_nbaset_phy0>; +}; + +&cp1_eth1 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp1_comphy4 1>; + phy = <&cp1_nbaset_phy1>; +}; + +&cp1_eth2 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp1_comphy1 2>; + phy = <&cp1_nbaset_phy2>; +}; + +&cp1_gpio1 { + status = "okay"; +}; + +&cp1_gpio2 { + status = "okay"; +}; + +&cp1_i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&cp1_i2c0_pins>; + clock-frequency = <100000>; +}; + +&cp1_syscon0 { + cp1_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + cp1_i2c0_pins: cp1-i2c-pins-0 { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cp1_spi0_pins: cp1-spi-pins-0 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; + cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins { + marvell,pins = "mpp3"; + marvell,function = "gpio"; + }; + }; +}; + +/* + * Instantiate the second connected CP115 + */ + +#define CP11X_NAME cp2 +#define CP11X_BASE f6000000 +#define CP11X_PCIEx_MEM_BASE(iface) (0xe5000000 + (iface * 0x1000000)) +#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000 +#define CP11X_PCIE0_BASE f6600000 +#define CP11X_PCIE1_BASE f6620000 +#define CP11X_PCIE2_BASE f6640000 + +#include "armada-cp115.dtsi" + +#undef CP11X_NAME +#undef CP11X_BASE +#undef CP11X_PCIEx_MEM_BASE +#undef CP11X_PCIEx_MEM_SIZE +#undef CP11X_PCIE0_BASE +#undef CP11X_PCIE1_BASE +#undef CP11X_PCIE2_BASE + +&cp2_crypto { + status = "okay"; +}; + +&cp2_ethernet { + status = "okay"; +}; + +&cp2_xmdio { + status = "okay"; + cp2_nbaset_phy0: ethernet-phy@6 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + cp2_nbaset_phy1: ethernet-phy@7 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + cp2_nbaset_phy2: ethernet-phy@8 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +/* SLM-1521-V2, CON9 */ +&cp2_eth0 { + status = "okay"; + phy-mode = "10gbase-kr"; + phys = <&cp2_comphy2 0>; + phy = <&cp2_nbaset_phy0>; +}; + +&cp2_eth1 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp2_comphy4 1>; + phy = <&cp2_nbaset_phy1>; +}; + +&cp2_eth2 { + status = "okay"; + phy-mode = "2500base-x"; + phys = <&cp2_comphy1 2>; + phy = <&cp2_nbaset_phy2>; +}; + +&cp2_gpio1 { + status = "okay"; +}; + +&cp2_gpio2 { + status = "okay"; +}; + +&cp2_i2c0 { + clock-frequency = <100000>; + /* SLM-1521-V2 - U3 */ + i2c-mux@72 { + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72>; + cp2_sfpp0_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* U12 */ + cp2_module_expander1: pca9555@21 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x21>; + }; + }; + }; +}; + +&cp2_syscon0 { + cp2_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + cp2_i2c0_pins: cp2-i2c-pins-0 { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + }; +}; diff --git a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-puzzle-m902.dts b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-puzzle-m902.dts index fd99eb2d1..c54fb960e 100644 --- a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-puzzle-m902.dts +++ b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/cn9132-puzzle-m902.dts @@ -17,6 +17,7 @@ chosen { stdout-path = "serial0:115200n8"; + bootargs-append = " root=/dev/mmcblk0p3"; }; aliases { diff --git a/target/linux/mvebu/image/Makefile b/target/linux/mvebu/image/Makefile index b0498d34c..09f8d9635 100644 --- a/target/linux/mvebu/image/Makefile +++ b/target/linux/mvebu/image/Makefile @@ -39,6 +39,16 @@ define Build/boot-img-ext4 $@.bootimg $@.boot endef +define Build/boot-qnap-img-ext4 + rm -fR $@.boot + mkdir -p $@.boot + $(foreach dts,$(DEVICE_DTS), $(CP) $(KDIR)/image-$(dts).dtb $@.boot/$(dts).dtb;) + $(CP) $(KDIR)/vmlinux $@.boot/Image + make_ext4fs -J -L kernel -l $(CONFIG_TARGET_KERNEL_PARTSIZE)M \ + $(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \ + $@.bootimg $@.boot +endef + define Build/buffalo-kernel-jffs2 rm -rf $(KDIR)/kernel_jffs2 $@.fakerd mkdir -p $(KDIR)/kernel_jffs2 diff --git a/target/linux/mvebu/image/cortexa72.mk b/target/linux/mvebu/image/cortexa72.mk index 47d958b2f..4ef5a4705 100644 --- a/target/linux/mvebu/image/cortexa72.mk +++ b/target/linux/mvebu/image/cortexa72.mk @@ -78,3 +78,15 @@ define Device/iei_puzzle-m902 SOC := cn9132 endef TARGET_DEVICES += iei_puzzle-m902 + +define Device/qnap_qhora-32x + $(call Device/Default-arm64) + SOC := cn9132 + DEVICE_VENDOR := QNAP + DEVICE_MODEL := QHora-321/322 + DEVICE_PACKAGES += kmod-rtc-ds1307 + DEVICE_DTS := cn9131-db-A cn9131-puzzle-m901 cn9132-db-A cn9132-puzzle-m902 + SUPPORTED_DEVICES := qnap,qhora-321 qnap,qhora-322 iei,puzzle-m901 iei,puzzle-m902 + IMAGE/sdcard.img.gz := boot-scr | boot-qnap-img-ext4 | sdcard-img-ext4 | gzip | append-metadata +endef +TARGET_DEVICES += qnap_qhora-32x diff --git a/target/linux/mvebu/patches-5.10/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.10/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch index c220e906c..ba9c5685a 100644 --- a/target/linux/mvebu/patches-5.10/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/mvebu/patches-5.10/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch @@ -187,7 +187,7 @@ Signed-off-by: Michael Gray static int kernel_init(void *); extern void init_IRQ(void); -@@ -901,6 +905,18 @@ asmlinkage __visible void __init __no_sa +@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa page_alloc_init(); pr_notice("Kernel command line: %s\n", saved_command_line); diff --git a/target/linux/mvebu/patches-5.15/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/mvebu/patches-5.15/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch index 72041e000..5d42762e7 100644 --- a/target/linux/mvebu/patches-5.15/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/mvebu/patches-5.15/300-mvebu-Mangle-bootloader-s-kernel-arguments.patch @@ -176,7 +176,7 @@ Signed-off-by: Michael Gray } --- a/init/main.c +++ b/init/main.c -@@ -112,6 +112,10 @@ +@@ -113,6 +113,10 @@ #include @@ -187,7 +187,7 @@ Signed-off-by: Michael Gray static int kernel_init(void *); extern void init_IRQ(void); -@@ -992,6 +996,18 @@ asmlinkage __visible void __init __no_sa +@@ -995,6 +999,18 @@ asmlinkage __visible void __init __no_sa page_alloc_init(); pr_notice("Kernel command line: %s\n", saved_command_line); diff --git a/target/linux/octeontx/patches-5.4/0004-PCI-add-quirk-for-Gateworks-PLX-PEX860x-switch-with-.patch b/target/linux/octeontx/patches-5.4/0004-PCI-add-quirk-for-Gateworks-PLX-PEX860x-switch-with-.patch index 8a0283e39..16d321d2b 100644 --- a/target/linux/octeontx/patches-5.4/0004-PCI-add-quirk-for-Gateworks-PLX-PEX860x-switch-with-.patch +++ b/target/linux/octeontx/patches-5.4/0004-PCI-add-quirk-for-Gateworks-PLX-PEX860x-switch-with-.patch @@ -22,7 +22,7 @@ Signed-off-by: Tim Harvey #include #include #include -@@ -5863,3 +5864,34 @@ static void nvidia_ion_ahci_fixup(struct +@@ -5864,3 +5865,34 @@ static void nvidia_ion_ahci_fixup(struct pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING; } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup); diff --git a/target/linux/oxnas/patches-5.10/996-generic-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/oxnas/patches-5.10/996-generic-Mangle-bootloader-s-kernel-arguments.patch index de2868ce9..9cc33f5a4 100644 --- a/target/linux/oxnas/patches-5.10/996-generic-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/oxnas/patches-5.10/996-generic-Mangle-bootloader-s-kernel-arguments.patch @@ -168,7 +168,7 @@ Signed-off-by: Adrian Panella static int kernel_init(void *); extern void init_IRQ(void); -@@ -901,6 +905,18 @@ asmlinkage __visible void __init __no_sa +@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa page_alloc_init(); pr_notice("Kernel command line: %s\n", saved_command_line); diff --git a/target/linux/phytium/patches-5.10/001-add-phytium-support.patch b/target/linux/phytium/patches-5.10/001-add-phytium-support.patch index 2884de2ba..4de812ae3 100644 --- a/target/linux/phytium/patches-5.10/001-add-phytium-support.patch +++ b/target/linux/phytium/patches-5.10/001-add-phytium-support.patch @@ -1,6 +1,6 @@ --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -3898,6 +3898,10 @@ +@@ -3919,6 +3919,10 @@ force Enable ASPM even on devices that claim not to support it. WARNING: Forcing ASPM on may cause system lockups. @@ -1849,7 +1849,7 @@ +obj-$(CONFIG_PHYTIUM_IXIC) += irq-phytium-ixic.o --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -4792,6 +4792,7 @@ static void its_restore_enable(void) +@@ -4787,6 +4787,7 @@ static void its_restore_enable(void) { struct its_node *its; int ret; @@ -1857,7 +1857,7 @@ raw_spin_lock(&its_lock); list_for_each_entry(its, &its_nodes, entry) { -@@ -4845,6 +4846,23 @@ static void its_restore_enable(void) +@@ -4840,6 +4841,23 @@ static void its_restore_enable(void) GITS_TYPER_HCC(gic_read_typer(base + GITS_TYPER))) its_cpu_init_collection(its); } @@ -4404,7 +4404,7 @@ return 0; --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c -@@ -30,6 +30,7 @@ +@@ -31,6 +31,7 @@ #include #include #include /* isa_dma_bridge_buggy */ @@ -4412,7 +4412,7 @@ #include "pci.h" static ktime_t fixup_debug_start(struct pci_dev *dev, -@@ -3901,12 +3902,12 @@ static int nvme_disable_and_flr(struct p +@@ -3902,12 +3903,12 @@ static int nvme_disable_and_flr(struct p void __iomem *bar; u16 cmd; u32 cfg; @@ -4427,7 +4427,7 @@ return 0; bar = pci_iomap(dev, 0, NVME_REG_CC + sizeof(cfg)); -@@ -3960,7 +3961,7 @@ static int nvme_disable_and_flr(struct p +@@ -3961,7 +3962,7 @@ static int nvme_disable_and_flr(struct p pci_iounmap(dev, bar); pcie_flr(dev); @@ -4436,7 +4436,7 @@ return 0; } -@@ -4056,6 +4057,7 @@ static const struct pci_dev_reset_method +@@ -4057,6 +4058,7 @@ static const struct pci_dev_reset_method { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA, reset_ivb_igd }, { PCI_VENDOR_ID_SAMSUNG, 0xa804, nvme_disable_and_flr }, @@ -4444,7 +4444,7 @@ { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr }, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, reset_chelsio_generic_dev }, -@@ -4995,6 +4997,10 @@ static const struct pci_dev_acs_enabled +@@ -4996,6 +4998,10 @@ static const struct pci_dev_acs_enabled { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, /* Wangxun nics */ { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, @@ -4455,7 +4455,7 @@ { 0 } }; -@@ -5378,6 +5384,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE +@@ -5380,6 +5386,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0144, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); diff --git a/target/linux/qualcommax/Makefile b/target/linux/qualcommax/Makefile index 87f919085..e35f55a46 100644 --- a/target/linux/qualcommax/Makefile +++ b/target/linux/qualcommax/Makefile @@ -14,8 +14,10 @@ include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES += \ kmod-usb3 kmod-usb-dwc3 kmod-usb-dwc3-qcom \ kmod-leds-gpio kmod-gpio-button-hotplug \ - kmod-qca-nss-dp kmod-ath11k-ahb \ - wpad-openssl uboot-envtools \ - e2fsprogs kmod-fs-ext4 losetup + kmod-qca-nss-dp kmod-qca-nss-drv kmod-qca-ssdk \ + kmod-qca-nss-ecm kmod-qca-nss-drv-bridge-mgr \ + kmod-qca-nss-drv-vlan kmod-qca-nss-drv-pppoe \ + kmod-ath11k-ahb wpad-openssl uboot-envtools \ + e2fsprogs kmod-fs-ext4 losetup autocore-arm $(eval $(call BuildTarget)) diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/mmc.sh b/target/linux/qualcommax/base-files/lib/upgrade/mmc.sh similarity index 100% rename from target/linux/qualcommax/ipq807x/base-files/lib/upgrade/mmc.sh rename to target/linux/qualcommax/base-files/lib/upgrade/mmc.sh diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-360v6.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-360v6.dts index 74d54f094..e8872c86f 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-360v6.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-360v6.dts @@ -4,7 +4,8 @@ #include "ipq6018-512m.dtsi" #include "ipq6018-ess.dtsi" -#include "ipq6018-opp.dtsi" +#include "ipq6018-mp5496.dtsi" +#include "ipq6018-nss.dtsi" #include #include @@ -86,6 +87,10 @@ status = "okay"; }; +&qpic_bam { + status = "okay"; +}; + &qpic_nand { status = "okay"; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-ax18.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-ax18.dts index 91ccf1cff..e887ff87a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-ax18.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-ax18.dts @@ -4,7 +4,7 @@ #include "ipq6018-256m.dtsi" #include "ipq6018-ess.dtsi" -#include "ipq6000-opp.dtsi" +#include "ipq6018-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-ax1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-ax1800.dts index a9e42dca8..70b4b80a0 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-ax1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-ax1800.dts @@ -49,3 +49,7 @@ phy-handle = <&qca8075_4>; label = "lan4"; }; + +&wifi { + qcom,ath11k-calibration-variant = "GL-iNet-GL-AX1800"; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-axt1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-axt1800.dts index 6afdfa31d..5e93c862d 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-axt1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-gl-axt1800.dts @@ -115,3 +115,7 @@ phy-handle = <&qca8075_2>; label = "lan1"; }; + +&wifi { + qcom,ath11k-calibration-variant = "GL-iNet-GL-AXT1800"; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-glinet.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-glinet.dtsi index 4538f75c1..6c2a8e7f5 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-glinet.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-glinet.dtsi @@ -2,7 +2,7 @@ #include "ipq6018-512m.dtsi" #include "ipq6018-ess.dtsi" -#include "ipq6000-opp.dtsi" +#include "ipq6018-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-mr7350.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-mr7350.dts index 6767d775a..284f9356a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-mr7350.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-mr7350.dts @@ -4,7 +4,8 @@ #include "ipq6018-512m.dtsi" #include "ipq6018-ess.dtsi" -#include "ipq6018-opp.dtsi" +#include "ipq6018-mp5496.dtsi" +#include "ipq6018-nss.dtsi" #include #include @@ -294,5 +295,6 @@ &wifi { status = "okay"; + qcom,ath11k-calibration-variant = "Linksys-MR7350"; qcom,ath11k-fw-memory-mode = <1>; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-re-ss-01.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-re-ss-01.dts new file mode 100644 index 000000000..3a4ec3caa --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-re-ss-01.dts @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; + +#include "ipq6018-512m.dtsi" +#include "ipq6018-ess.dtsi" +#include "ipq6018-nss.dtsi" + +#include +#include + +/ { + model = "JDCloud RE-SS-01"; + compatible = "jdcloud,re-ss-01", "qcom,ipq6018"; + + aliases { + serial0 = &blsp1_uart3; + led-boot = &led_status_green; + led-failsafe = &led_status_red; + led-running = &led_status_blue; + led-upgrade = &led_status_red; + + ethernet1 = "/soc/dp2"; + ethernet2 = "/soc/dp3"; + ethernet3 = "/soc/dp4"; + ethernet4 = "/soc/dp5"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps { + label = "wps"; + linux,code = ; + gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; + }; + + reset { + label = "reset"; + linux,code = ; + gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_status_red: red { + label = "red:status"; + gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; + }; + + led_status_blue: blue { + label = "blue:status"; + gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>; + }; + + led_status_green: green { + label = "green:status"; + gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&tlmm { + gpio-reserved-ranges = <20 1>; + + button_pins: button_pins { + mux { + pins = "gpio8", "gpio9"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + mdio_pins: mdio-pins { + mdc { + pins = "gpio64"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio { + pins = "gpio65"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; +}; + +&blsp1_uart3 { + pinctrl-0 = <&serial_3_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&qusb_phy_0 { + status = "okay"; +}; + +&rpm { + status = "disabled"; +}; + +&sdhc { + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&ssphy_0 { + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; + +&mdio { + status = "okay"; + + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>; + + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; + + qca8075_4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; +}; + +&switch { + status = "okay"; + + switch_cpu_bmp = <0x1>; /* cpu port bitmap */ + switch_lan_bmp = <0x1e>; /* lan port bitmap */ + switch_wan_bmp = <0x20>; /* wan port bitmap */ + switch_inner_bmp = <0xc0>; /*inner port bitmap*/ + switch_mac_mode = <0x0>; /* mac mode for uniphy 0*/ + switch_mac_mode1 = <0xff>; /* mac mode for uniphy 1*/ + switch_mac_mode2 = <0xff>; /* mac mode for uniphy 2*/ + + qcom,port_phyinfo { + port@2 { + port_id = <2>; + phy_address = <1>; + }; + port@3 { + port_id = <3>; + phy_address = <2>; + }; + port@4 { + port_id = <4>; + phy_address = <3>; + }; + port@5 { + port_id = <5>; + phy_address = <4>; + }; + }; +}; + +&edma { + status = "okay"; +}; + +&dp2 { + status = "okay"; + phy-handle = <&qca8075_1>; + label = "lan1"; +}; + +&dp3 { + status = "okay"; + phy-handle = <&qca8075_2>; + label = "lan2"; +}; + +&dp4 { + status = "okay"; + phy-handle = <&qca8075_3>; + label = "lan3"; +}; + +&dp5 { + status = "okay"; + phy-handle = <&qca8075_4>; + label = "wan"; +}; + +&wifi { + status = "okay"; + qcom,ath11k-calibration-variant = "JDC-AX1800-Pro"; + qcom,ath11k-fw-memory-mode = <1>; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-xiaomi.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-xiaomi.dtsi index f8d6e47fb..884f19858 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-xiaomi.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6000-xiaomi.dtsi @@ -4,7 +4,8 @@ #include "ipq6018-512m.dtsi" #include "ipq6018-ess.dtsi" -#include "ipq6018-opp.dtsi" +#include "ipq6018-mp5496.dtsi" +#include "ipq6018-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-re-cs-02.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-re-cs-02.dts new file mode 100644 index 000000000..a7ec1be5f --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-re-cs-02.dts @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; + +#include "ipq6018.dtsi" +#include "ipq6018-ess.dtsi" +#include "ipq6018-nss.dtsi" + +#include +#include + +/ { + model = "JDCloud RE-CS-02"; + compatible = "jdcloud,re-cs-02", "qcom,ipq6018"; + + aliases { + serial0 = &blsp1_uart3; + serial1 = &blsp1_uart6; + led-boot = &led_status_green; + led-failsafe = &led_status_red; + led-running = &led_status_blue; + led-upgrade = &led_status_red; + + ethernet0 = "/soc/dp1"; + ethernet1 = "/soc/dp2"; + ethernet2 = "/soc/dp3"; + ethernet3 = "/soc/dp4"; + ethernet4 = "/soc/dp5"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wps { + label = "wps"; + linux,code = ; + gpios = <&tlmm 72 GPIO_ACTIVE_LOW>; + }; + + reset { + label = "reset"; + linux,code = ; + gpios = <&tlmm 56 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_status_red: red { + label = "red:status"; + gpios = <&tlmm 57 GPIO_ACTIVE_HIGH>; + }; + + led_status_blue: blue { + label = "blue:status"; + gpios = <&tlmm 79 GPIO_ACTIVE_HIGH>; + }; + + led_status_green: green { + label = "green:status"; + gpios = <&tlmm 58 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&tlmm { + gpio-reserved-ranges = <20 1>; + + button_pins: button_pins { + mux { + pins = "gpio56", "gpio72"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + btuart_pins: btuart_pins { + mux { + pins = "gpio48", "gpio49"; + function = "blsp5_uart"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + mdio_pins: mdio-pins { + mdc { + pins = "gpio64"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio { + pins = "gpio65"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; +}; + +&blsp1_uart3 { + pinctrl-0 = <&serial_3_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&blsp1_uart6 { + pinctrl-0 = <&btuart_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + perst-gpio = <&tlmm 53 GPIO_ACTIVE_LOW>; + status = "okay"; + + bridge@0,0 { + reg = <0x00000000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + wifi@1,0 { + compatible = "pci17cb,1104"; + reg = <0x00010000 0 0 0 0>; + }; + }; +}; + +&qusb_phy_0 { + status = "okay"; +}; + +&rpm { + status = "disabled"; +}; + +&sdhc { + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&ssphy_0 { + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; + +&mdio { + status = "okay"; + + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>; + + qca8075_0: ethernet-phy@24 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <24>; + }; + + qca8075_1: ethernet-phy@25 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <25>; + }; + + qca8075_2: ethernet-phy@26 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <26>; + }; + + qca8075_3: ethernet-phy@27 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <27>; + }; + + qca8081: ethernet-phy@12 { + compatible = "ethernet-phy-id004d.d101"; + reg = <12>; + reset-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>; + }; +}; + +&switch { + status = "okay"; + + switch_cpu_bmp = <0x1>; /* cpu port bitmap */ + switch_lan_bmp = <0x1e>; /* lan port bitmap */ + switch_wan_bmp = <0x20>; /* wan port bitmap */ + switch_inner_bmp = <0xc0>; /*inner port bitmap*/ + switch_mac_mode = <0x0>; /* mac mode for uniphy 0*/ + switch_mac_mode1 = <0xf>; /* mac mode for uniphy 1*/ + switch_mac_mode2 = <0xff>; /* mac mode for uniphy 2*/ + + qcom,port_phyinfo { + port@1 { + port_id = <1>; + phy_address = <24>; + }; + port@2 { + port_id = <2>; + phy_address = <25>; + }; + port@3 { + port_id = <3>; + phy_address = <26>; + }; + port@4 { + port_id = <4>; + phy_address = <27>; + }; + port@5 { + port_id = <5>; + phy_address = <12>; + port_mac_sel = "QGMAC_PORT"; + }; + }; +}; + +&edma { + status = "okay"; +}; + +&dp1 { + status = "okay"; + phy-handle = <&qca8075_0>; + label = "lan1"; +}; + +&dp2 { + status = "okay"; + phy-handle = <&qca8075_1>; + label = "lan2"; +}; + +&dp3 { + status = "okay"; + phy-handle = <&qca8075_2>; + label = "lan3"; +}; + +&dp4 { + status = "okay"; + phy-handle = <&qca8075_3>; + label = "lan4"; +}; + +&dp5 { + status = "okay"; + phy-handle = <&qca8081>; + label = "wan"; +}; + +&wifi { + status = "okay"; + qcom,ath11k-calibration-variant = "JDC-AX1800-Pro"; + qcom,ath11k-fw-memory-mode = <1>; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-nss.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-nss.dtsi new file mode 100644 index 000000000..2d04ac140 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-nss.dtsi @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/ { + nss_dummy_reg: nss-regulator { + compatible = "regulator-fixed"; + regulator-name = "nss-reg"; + regulator-min-microvolt = <848000>; + regulator-max-microvolt = <848000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&soc { + nss-common { + compatible = "qcom,nss-common"; + reg = <0x0 0x01868010 0x0 0x1000>, <0x0 0x40000000 0x0 0x1000>; + reg-names = "nss-misc-reset", "nss-misc-reset-flag"; + memory-region = <&nss_region>; + }; + + nss0: nss@40000000 { + compatible = "qcom,nss"; + interrupts = <0 402 0x1>, <0 401 0x1>, <0 400 0x1>, + <0 399 0x1>, <0 398 0x1>, <0 397 0x1>, + <0 396 0x1>, <0 395 0x1>, <0 394 0x1>, + <0 393 0x1>; + reg = <0x0 0x39000000 0x0 0x1000>, <0x0 0x0b111000 0x0 0x1000>; + reg-names = "nphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_MEM_NOC_UBI32_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_CORE_CLK>, + <&gcc GCC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_AXI_CLK>, + <&gcc GCC_UBI0_NC_AXI_CLK>, + <&gcc GCC_UBI0_UTCM_CLK>, + <&gcc GCC_SNOC_NSSNOC_CLK>; + clock-names = "nss-noc-clk", "nss-ptp-ref-clk", + "nss-csr-clk", "nss-cfg-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-mem-noc-ubi32-clk", + "nss-ce-axi-clk", "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", "nss-ahb-clk", + "nss-axi-clk", "nss-nc-axi-clk", + "nss-utcm-clk", "nss-snoc-nssnoc-clk"; + qcom,id = <0>; + qcom,num-queue = <4>; + qcom,num-irq = <10>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40000000>; + qcom,low-frequency = <187200000>; + qcom,mid-frequency = <748800000>; + qcom,max-frequency = <1497600000>; + qcom,bridge-enabled; + qcom,ipv4-enabled; + qcom,ipv4-reasm-enabled; + qcom,ipv6-enabled; + qcom,ipv6-reasm-enabled; + qcom,wlanredirect-enabled; + qcom,tun6rd-enabled; + qcom,l2tpv2-enabled; + qcom,gre-enabled; + qcom,gre-redir-enabled; + qcom,gre-redir-mark-enabled; + qcom,map-t-enabled; + qcom,portid-enabled; + qcom,ppe-enabled; + qcom,pppoe-enabled; + qcom,pptp-enabled; + qcom,tunipip6-enabled; + qcom,shaping-enabled; + qcom,wlan-dataplane-offload-enabled; + qcom,vlan-enabled; + qcom,capwap-enabled; + qcom,dtls-enabled; + qcom,tls-enabled; + qcom,crypto-enabled; + qcom,ipsec-enabled; + qcom,qvpn-enabled; + qcom,pvxlan-enabled; + qcom,clmap-enabled; + qcom,vxlan-enabled; + qcom,match-enabled; + qcom,mirror-enabled; + mx-supply = <&nss_dummy_reg>; + npu-supply = <&nss_dummy_reg>; + }; + + nss_crypto: qcom,nss_crypto { + compatible = "qcom,nss-crypto"; + #address-cells = <1>; + #size-cells = <1>; + qcom,max-contexts = <64>; + qcom,max-context-size = <32>; + ranges; + + eip197_node { + compatible = "qcom,eip197"; + reg-names = "crypto_pbase"; + reg = <0x39800000 0x7ffff>; + clocks = <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSSNOC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_PPE_CLK>; + clock-names = "crypto_clk", "crypto_nocclk", + "crypto_ppeclk"; + clock-frequency = /bits/ 64 <300000000 300000000 300000000>; + qcom,dma-mask = <0xff>; + qcom,transform-enabled; + qcom,aes128-cbc; + qcom,aes192-cbc; + qcom,aes256-cbc; + qcom,aes128-ctr; + qcom,aes192-ctr; + qcom,aes256-ctr; + qcom,aes128-ecb; + qcom,aes192-ecb; + qcom,aes256-ecb; + qcom,3des-cbc; + qcom,md5-hash; + qcom,sha160-hash; + qcom,sha224-hash; + qcom,sha256-hash; + qcom,sha384-hash; + qcom,sha512-hash; + qcom,md5-hmac; + qcom,sha160-hmac; + qcom,sha224-hmac; + qcom,sha256-hmac; + qcom,sha384-hmac; + qcom,sha512-hmac; + qcom,aes128-gcm-gmac; + qcom,aes192-gcm-gmac; + qcom,aes256-gcm-gmac; + qcom,aes128-cbc-md5-hmac; + qcom,aes128-cbc-sha160-hmac; + qcom,aes192-cbc-md5-hmac; + qcom,aes192-cbc-sha160-hmac; + qcom,aes256-cbc-md5-hmac; + qcom,aes256-cbc-sha160-hmac; + qcom,aes128-ctr-sha160-hmac; + qcom,aes192-ctr-sha160-hmac; + qcom,aes256-ctr-sha160-hmac; + qcom,aes128-ctr-md5-hmac; + qcom,aes192-ctr-md5-hmac; + qcom,aes256-ctr-md5-hmac; + qcom,3des-cbc-md5-hmac; + qcom,3des-cbc-sha160-hmac; + qcom,aes128-cbc-sha256-hmac; + qcom,aes192-cbc-sha256-hmac; + qcom,aes256-cbc-sha256-hmac; + qcom,aes128-ctr-sha256-hmac; + qcom,aes192-ctr-sha256-hmac; + qcom,aes256-ctr-sha256-hmac; + qcom,3des-cbc-sha256-hmac; + qcom,aes128-cbc-sha384-hmac; + qcom,aes192-cbc-sha384-hmac; + qcom,aes256-cbc-sha384-hmac; + qcom,aes128-ctr-sha384-hmac; + qcom,aes192-ctr-sha384-hmac; + qcom,aes256-ctr-sha384-hmac; + qcom,aes128-cbc-sha512-hmac; + qcom,aes192-cbc-sha512-hmac; + qcom,aes256-cbc-sha512-hmac; + qcom,aes128-ctr-sha512-hmac; + qcom,aes192-ctr-sha512-hmac; + qcom,aes256-ctr-sha512-hmac; + + engine0 { + reg_offset = <0x80000>; + qcom,ifpp-enabled; + qcom,ipue-enabled; + qcom,ofpp-enabled; + qcom,opue-enabled; + }; + }; + }; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts index 3415426a9..092781e87 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts @@ -6,6 +6,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts index ee9d23e09..5e94ad3fe 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-rm2-6.dts @@ -5,6 +5,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi index f4ebfc8f4..2a8368cbe 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi @@ -4,6 +4,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts index 357b6368d..17e94dc22 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts index 628f1c627..c34957bd9 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-mf269.dts @@ -5,6 +5,7 @@ #include "ipq8074-512m.dtsi" #include "ipq8074-ac-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts index d15b9f5b0..8124e2d1a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts index 715398518..c57002982 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-aw1000.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts index fd1f32ada..a3119490e 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts index 5468e9e1f..44845bfee 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts index 3aa2e8878..bc4841da6 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts index 5bfcdcc8c..e2e5d764a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts @@ -3,7 +3,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" - +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts index 0cd20cc1e..8257877b8 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wax620.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts index 2de34af8e..e625581b1 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts @@ -6,6 +6,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts index 2924ac3a9..1f9c3d398 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts @@ -9,6 +9,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi new file mode 100644 index 000000000..d85a37230 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/ { + nss_dummy_reg: nss-regulator { + compatible = "regulator-fixed"; + regulator-name = "nss-reg"; + regulator-min-microvolt = <848000>; + regulator-max-microvolt = <848000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&soc { + nss-common { + compatible = "qcom,nss-common"; + reg = <0x01868010 0x1000>; + reg-names = "nss-misc-reset"; + memory-region = <&nss_region>; + }; + + nss0: nss@40000000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + , + ; + reg = <0x39000000 0x1000>, + <0x38000000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_CORE_CLK>, + <&gcc GCC_UBI0_AHB_CLK>, + <&gcc GCC_UBI0_AXI_CLK>, + <&gcc GCC_UBI0_MPT_CLK>, + <&gcc GCC_UBI0_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <0>; + qcom,num-queue = <4>; + qcom,num-irq = <10>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40000000>; + qcom,low-frequency = <187200000>; + qcom,mid-frequency = <748800000>; + qcom,max-frequency = <1689600000>; + qcom,bridge-enabled; + qcom,ipv4-enabled; + qcom,ipv4-reasm-enabled; + qcom,ipv6-enabled; + qcom,ipv6-reasm-enabled; + qcom,wlanredirect-enabled; + qcom,tun6rd-enabled; + qcom,l2tpv2-enabled; + qcom,gre-enabled; + qcom,gre-redir-enabled; + qcom,gre-redir-mark-enabled; + qcom,map-t-enabled; + qcom,portid-enabled; + qcom,ppe-enabled; + qcom,pppoe-enabled; + qcom,pptp-enabled; + qcom,tunipip6-enabled; + qcom,shaping-enabled; + qcom,wlan-dataplane-offload-enabled; + qcom,vlan-enabled; + qcom,igs-enabled; + qcom,vxlan-enabled; + qcom,match-enabled; + qcom,mirror-enabled; + qcom,udp-st-enabled; + mx-supply = <&nss_dummy_reg>; + npu-supply = <&nss_dummy_reg>; + }; + + nss1: nss@40800000 { + compatible = "qcom,nss"; + interrupts = , + , + , + , + , + , + , + , + ; + reg = <0x39400000 0x1000>, + <0x38030000 0x30000>, + <0x0b111000 0x1000>; + reg-names = "nphys", "vphys", "qgic-phys"; + clocks = <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_CSR_CLK>, + <&gcc GCC_NSS_CFG_CLK>, + <&gcc GCC_NSS_IMEM_CLK>, + <&gcc GCC_NSSNOC_QOSGEN_REF_CLK>, + <&gcc GCC_MEM_NOC_NSS_AXI_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSSNOC_TIMEOUT_REF_CLK>, + <&gcc GCC_NSS_CE_AXI_CLK>, + <&gcc GCC_NSS_CE_APB_CLK>, + <&gcc GCC_NSSNOC_CE_AXI_CLK>, + <&gcc GCC_NSSNOC_CE_APB_CLK>, + <&gcc GCC_NSSNOC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_CORE_CLK>, + <&gcc GCC_UBI1_AHB_CLK>, + <&gcc GCC_UBI1_AXI_CLK>, + <&gcc GCC_UBI1_MPT_CLK>, + <&gcc GCC_UBI1_NC_AXI_CLK>; + clock-names = "nss-noc-clk", + "nss-ptp-ref-clk", + "nss-csr-clk", + "nss-cfg-clk", + "nss-imem-clk", + "nss-nssnoc-qosgen-ref-clk", + "nss-mem-noc-nss-axi-clk", + "nss-nssnoc-snoc-clk", + "nss-nssnoc-timeout-ref-clk", + "nss-ce-axi-clk", + "nss-ce-apb-clk", + "nss-nssnoc-ce-axi-clk", + "nss-nssnoc-ce-apb-clk", + "nss-nssnoc-ahb-clk", + "nss-core-clk", + "nss-ahb-clk", + "nss-axi-clk", + "nss-mpt-clk", + "nss-nc-axi-clk"; + qcom,id = <1>; + qcom,num-queue = <4>; + qcom,num-irq = <9>; + qcom,num-pri = <4>; + qcom,load-addr = <0x40800000>; + qcom,capwap-enabled; + qcom,dtls-enabled; + qcom,tls-enabled; + qcom,crypto-enabled; + qcom,ipsec-enabled; + qcom,qvpn-enabled; + qcom,pvxlan-enabled; + qcom,clmap-enabled; + qcom,rmnet_rx-enabled; + }; + + nss_crypto: qcom,nss_crypto { + compatible = "qcom,nss-crypto"; + #address-cells = <1>; + #size-cells = <1>; + qcom,max-contexts = <64>; + qcom,max-context-size = <32>; + ranges; + + eip197_node { + compatible = "qcom,eip197"; + reg-names = "crypto_pbase"; + reg = <0x39800000 0x7ffff>; + clocks = <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSSNOC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_PPE_CLK>; + clock-names = "crypto_clk", + "crypto_nocclk", + "crypto_ppeclk"; + clock-frequency = /bits/ 64 <600000000 600000000 300000000>; + qcom,dma-mask = <0xff>; + qcom,transform-enabled; + qcom,aes128-cbc; + qcom,aes192-cbc; + qcom,aes256-cbc; + qcom,aes128-ctr; + qcom,aes192-ctr; + qcom,aes256-ctr; + qcom,aes128-ecb; + qcom,aes192-ecb; + qcom,aes256-ecb; + qcom,3des-cbc; + qcom,md5-hash; + qcom,sha160-hash; + qcom,sha224-hash; + qcom,sha384-hash; + qcom,sha512-hash; + qcom,sha256-hash; + qcom,md5-hmac; + qcom,sha160-hmac; + qcom,sha224-hmac; + qcom,sha256-hmac; + qcom,sha384-hmac; + qcom,sha512-hmac; + qcom,aes128-gcm-gmac; + qcom,aes192-gcm-gmac; + qcom,aes256-gcm-gmac; + qcom,aes128-cbc-md5-hmac; + qcom,aes128-cbc-sha160-hmac; + qcom,aes192-cbc-md5-hmac; + qcom,aes192-cbc-sha160-hmac; + qcom,aes256-cbc-md5-hmac; + qcom,aes256-cbc-sha160-hmac; + qcom,aes128-ctr-sha160-hmac; + qcom,aes192-ctr-sha160-hmac; + qcom,aes256-ctr-sha160-hmac; + qcom,aes128-ctr-md5-hmac; + qcom,aes192-ctr-md5-hmac; + qcom,aes256-ctr-md5-hmac; + qcom,3des-cbc-md5-hmac; + qcom,3des-cbc-sha160-hmac; + qcom,aes128-cbc-sha256-hmac; + qcom,aes192-cbc-sha256-hmac; + qcom,aes256-cbc-sha256-hmac; + qcom,aes128-ctr-sha256-hmac; + qcom,aes192-ctr-sha256-hmac; + qcom,aes256-ctr-sha256-hmac; + qcom,3des-cbc-sha256-hmac; + qcom,aes128-cbc-sha384-hmac; + qcom,aes192-cbc-sha384-hmac; + qcom,aes256-cbc-sha384-hmac; + qcom,aes128-ctr-sha384-hmac; + qcom,aes192-ctr-sha384-hmac; + qcom,aes256-ctr-sha384-hmac; + qcom,aes128-cbc-sha512-hmac; + qcom,aes192-cbc-sha512-hmac; + qcom,aes256-cbc-sha512-hmac; + qcom,aes128-ctr-sha512-hmac; + qcom,aes192-ctr-sha512-hmac; + qcom,aes256-ctr-sha512-hmac; + + engine0 { + reg_offset = <0x80000>; + qcom,ifpp-enabled; + qcom,ipue-enabled; + qcom,ofpp-enabled; + qcom,opue-enabled; + }; + }; + }; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts index 4034c326f..730424197 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-ess.dtsi" #include "ipq8074-hk-cpu.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts index 5e7b32801..b1f2447d8 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index 32386dc93..6173f22cc 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -5,6 +5,7 @@ #include "ipq8074.dtsi" #include "ipq8074-hk-cpu.dtsi" #include "ipq8074-ess.dtsi" +#include "ipq8074-nss.dtsi" #include #include #include diff --git a/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h new file mode 100644 index 000000000..dc6a5004e --- /dev/null +++ b/target/linux/qualcommax/files/include/net/netfilter/nf_conntrack_dscpremark_ext.h @@ -0,0 +1,95 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark conntrack extension APIs. */ + +#ifndef _NF_CONNTRACK_DSCPREMARK_H +#define _NF_CONNTRACK_DSCPREMARK_H + +#include +#include + +/* Rule flags */ +#define NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID 0x1 + +/* Rule validity */ +#define NF_CT_DSCPREMARK_EXT_RULE_VALID 0x1 +#define NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID 0x0 + +/* Which QoS features are set flags */ +#define NF_CT_DSCPREMARK_EXT_PRIO 0x1 +#define NF_CT_DSCPREMARK_EXT_DSCP 0x2 +#define NF_CT_DSCPREMARK_EXT_IGS_QOS 0x4 +#define NF_CT_DSCPREMARK_EXT_MARK 0x8 + +/* + * DSCP remark conntrack extension structure. + */ +struct nf_ct_dscpremark_ext { + __u32 flow_priority; /* Original direction packet priority */ + __u32 reply_priority; /* Reply direction packet priority */ + __u32 flow_mark; /* Original direction packet mark */ + __u32 reply_mark; /* Reply direction packet mark */ + __u16 igs_flow_qos_tag; /* Original direction ingress packet priority */ + __u16 igs_reply_qos_tag; /* Reply direction ingress packet priority */ + __u8 flow_dscp; /* IP DSCP value for original direction */ + __u8 reply_dscp; /* IP DSCP value for reply direction */ + __u16 rule_flags; /* Rule Validity flags */ + __u16 flow_set_flags; /* Original direction set flags */ + __u16 return_set_flags; /* Reply direction set flags */ +}; + +/* + * nf_ct_dscpremark_ext_find() + * Finds the extension data of the conntrack entry if it exists. + */ +static inline struct nf_ct_dscpremark_ext * +nf_ct_dscpremark_ext_find(const struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + return nf_ct_ext_find(ct, NF_CT_EXT_DSCPREMARK); +#else + return NULL; +#endif +} + +/* + * nf_ct_dscpremark_ext_add() + * Adds the extension data to the conntrack entry. + */ +static inline +struct nf_ct_dscpremark_ext *nf_ct_dscpremark_ext_add(struct nf_conn *ct, + gfp_t gfp) +{ +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_ext_add(ct, NF_CT_EXT_DSCPREMARK, gfp); + if (!ncde) + return NULL; + + return ncde; +#else + return NULL; +#endif +}; + +#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT +extern int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct); +extern int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct); +#endif /* CONFIG_NF_CONNTRACK_DSCPREMARK_EXT */ +#endif /* _NF_CONNTRACK_DSCPREMARK_H */ diff --git a/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h new file mode 100644 index 000000000..3a368fcc8 --- /dev/null +++ b/target/linux/qualcommax/files/include/uapi/linux/tc_act/tc_nss_mirred.h @@ -0,0 +1,36 @@ +#ifndef __LINUX_TC_NSS_MIRRED_H +#define __LINUX_TC_NSS_MIRRED_H + +#include + +/* + * Type of nss mirred action. + */ +#define TCA_ACT_MIRRED_NSS 17 + +/* + * Types of parameters for nss mirred action. + */ +enum { + TC_NSS_MIRRED_UNSPEC, + TC_NSS_MIRRED_TM, + TC_NSS_MIRRED_PARMS, + __TC_NSS_MIRRED_MAX +}; +#define TC_NSS_MIRRED_MAX (__TC_NSS_MIRRED_MAX - 1) + +/* + * tc_nss_mirred + * tc command structure for nss mirred action. + */ +struct tc_nss_mirred { + tc_gen; /* General tc structure. */ + __u32 from_ifindex; /* ifindex of the port from which traffic + * will be redirected. + */ + __u32 to_ifindex; /* ifindex of the port to which traffic + * will be redirected. + */ +}; + +#endif /* __LINUX_TC_NSS_MIRRED_H */ diff --git a/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c new file mode 100644 index 000000000..678d27ac9 --- /dev/null +++ b/target/linux/qualcommax/files/net/netfilter/nf_conntrack_dscpremark_ext.c @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* DSCP remark handling conntrack extension registration. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* nf_conntrack_dscpremark_ext_set_dscp_rule_valid() + * Set DSCP rule validity flag in the extension + */ +int nf_conntrack_dscpremark_ext_set_dscp_rule_valid(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return -1; + + ncde->rule_flags = NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID; + return 0; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_set_dscp_rule_valid); + +/* nf_conntrack_dscpremark_ext_get_dscp_rule_validity() + * Check if the DSCP rule flag is valid from the extension + */ +int nf_conntrack_dscpremark_ext_get_dscp_rule_validity(struct nf_conn *ct) +{ + struct nf_ct_dscpremark_ext *ncde; + + ncde = nf_ct_dscpremark_ext_find(ct); + if (!ncde) + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; + + if (ncde->rule_flags & NF_CT_DSCPREMARK_EXT_DSCP_RULE_VALID) + return NF_CT_DSCPREMARK_EXT_RULE_VALID; + + return NF_CT_DSCPREMARK_EXT_RULE_NOT_VALID; +} +EXPORT_SYMBOL(nf_conntrack_dscpremark_ext_get_dscp_rule_validity); diff --git a/target/linux/qualcommax/image/ipq60xx.mk b/target/linux/qualcommax/image/ipq60xx.mk index 6ef006faf..ef05a150b 100644 --- a/target/linux/qualcommax/image/ipq60xx.mk +++ b/target/linux/qualcommax/image/ipq60xx.mk @@ -18,9 +18,9 @@ define Device/UbiFit endef define Device/EmmcImage - IMAGES += factory.bin sysupgrade.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata + IMAGES := factory.bin recovery.bin sysupgrade.bin + IMAGE/factory.bin := append-kernel | pad-to 12288k | append-rootfs | append-metadata + IMAGE/recovery.bin := append-kernel | pad-to 6144k | append-rootfs | append-metadata endef define Device/cmiot_ax18 @@ -61,6 +61,32 @@ define Device/glinet_gl-axt1800 endef TARGET_DEVICES += glinet_gl-axt1800 +define Device/jdcloud_re-cs-02 + $(call Device/FitImage) + $(call Device/EmmcImage) + DEVICE_VENDOR := JDCloud + DEVICE_MODEL := AX6600 + SOC := ipq6010 + BLOCKSIZE := 64k + KERNEL_SIZE := 6144k + DEVICE_DTS_CONFIG := config@cp03-c3 + DEVICE_PACKAGES := ipq-wifi-jdcloud_ax6600 kmod-ath11k-pci ath11k-firmware-qcn9074 +endef +TARGET_DEVICES += jdcloud_re-cs-02 + +define Device/jdcloud_re-ss-01 + $(call Device/FitImage) + $(call Device/EmmcImage) + DEVICE_VENDOR := JDCloud + DEVICE_MODEL := AX1800 Pro + SOC := ipq6000 + BLOCKSIZE := 64k + KERNEL_SIZE := 6144k + DEVICE_DTS_CONFIG := config@cp03-c2 + DEVICE_PACKAGES := ipq-wifi-jdcloud_ax1800pro +endef +TARGET_DEVICES += jdcloud_re-ss-01 + define Device/linksys_mr7350 $(call Device/FitImage) DEVICE_VENDOR := Linksys diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network index ead1fb8f0..fc123c9a1 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network +++ b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network @@ -12,12 +12,14 @@ ipq60xx_setup_interfaces() case "$board" in cmiot,ax18|\ + jdcloud,re-ss-01|\ qihoo,360v6|\ redmi,ax5-*|\ xiaomi,rm1800) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan" ;; glinet,gl-ax1800|\ + jdcloud,re-cs-02|\ linksys,mr7350) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" ;; diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata index f148438b3..b82946cdc 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata +++ b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata @@ -12,14 +12,24 @@ case "$FIRMWARE" in glinet,gl-ax1800|\ glinet,gl-axt1800|\ linksys,mr7350|\ - qihoo,360v6) + qihoo,360v6|\ + xiaomi,rm1800) caldata_extract "0:art" 0x1000 0x10000 ;; + jdcloud,re-cs-02|\ + jdcloud,re-ss-01|\ redmi,ax5-jdcloud) caldata_extract_mmc "0:ART" 0x1000 0x10000 ;; esac ;; +"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin") + case "$board" in + jdcloud,re-cs-02) + caldata_extract_mmc "0:ART" 0x26800 0x20000 + ;; + esac + ;; *) exit 1 ;; diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/81_fix_eeprom b/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/81_fix_eeprom new file mode 100644 index 000000000..34b91f4df --- /dev/null +++ b/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/81_fix_eeprom @@ -0,0 +1,19 @@ +. /lib/functions/caldata.sh + +preinit_fix_eeprom() { + case $(board_name) in + jdcloud,re-cs-02|\ + jdcloud,re-ss-01|\ + redmi,ax5-jdcloud) + mmc_part=$(find_mmc_part 0:ART) + FIRMWARE=""ath11k/IPQ6018/hw1.0/cal-ahb-c000000.wifi.bin"" + [ ! -e /lib/firmware/"$FIRMWARE" ] && \ + export FIRMWARE="$FIRMWARE" && \ + caldata_extract_mmc "0:ART" 0x1000 0x10000 + ;; + *) + ;; + esac +} + +boot_hook_add preinit_main preinit_fix_eeprom diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh index b04d230c4..e199c33c1 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh @@ -17,6 +17,13 @@ platform_do_upgrade() { xiaomi,rm1800) nand_do_upgrade "$1" ;; + jdcloud,re-cs-02|\ + jdcloud,re-ss-01|\ + redmi,ax5-jdcloud) + kernelname="0:HLOS" + rootfsname="rootfs" + mmc_do_upgrade "$1" + ;; linksys,mr7350) boot_part="$(fw_printenv -n boot_part)" if [ "$boot_part" -eq "1" ]; then @@ -31,11 +38,6 @@ platform_do_upgrade() { fw_setenv auto_recovery yes nand_do_upgrade "$1" ;; - redmi,ax5-jdcloud) - kernelname="0:HLOS" - rootfsname="rootfs" - mmc_do_upgrade "$1" - ;; *) default_do_upgrade "$1" ;; diff --git a/target/linux/qualcommax/ipq60xx/target.mk b/target/linux/qualcommax/ipq60xx/target.mk index 06a85ab5e..7f20467f8 100644 --- a/target/linux/qualcommax/ipq60xx/target.mk +++ b/target/linux/qualcommax/ipq60xx/target.mk @@ -1,6 +1,6 @@ SUBTARGET:=ipq60xx BOARDNAME:=Qualcomm Atheros IPQ60xx -DEFAULT_PACKAGES += ath11k-firmware-ipq6018 +DEFAULT_PACKAGES += ath11k-firmware-ipq6018 nss-firmware-ipq6018 define Target/Description Build firmware images for Qualcomm Atheros IPQ60xx based boards. diff --git a/target/linux/qualcommax/ipq807x/target.mk b/target/linux/qualcommax/ipq807x/target.mk index d5aff23ef..a2111ce59 100644 --- a/target/linux/qualcommax/ipq807x/target.mk +++ b/target/linux/qualcommax/ipq807x/target.mk @@ -1,6 +1,6 @@ SUBTARGET:=ipq807x BOARDNAME:=Qualcomm Atheros IPQ807x -DEFAULT_PACKAGES += ath11k-firmware-ipq8074 +DEFAULT_PACKAGES += ath11k-firmware-ipq8074 nss-firmware-ipq8074 define Target/Description Build firmware images for Qualcomm Atheros IPQ807x based boards. diff --git a/target/linux/qualcommax/patches-6.1/0007-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch b/target/linux/qualcommax/patches-6.1/0007-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch index c209adbc0..20245698b 100644 --- a/target/linux/qualcommax/patches-6.1/0007-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch +++ b/target/linux/qualcommax/patches-6.1/0007-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch @@ -808,8 +808,8 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -975,6 +647,18 @@ static const struct freq_tbl ftbl_pcie_a - F(19200000, P_XO, 1, 0, 0), +@@ -976,6 +648,18 @@ static const struct freq_tbl ftbl_pcie_a + { } }; +static const struct clk_parent_data gcc_xo_gpll0_sleep_clk[] = { @@ -827,7 +827,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 pcie0_aux_clk_src = { .cmd_rcgr = 0x75024, .freq_tbl = ftbl_pcie_aux_clk_src, -@@ -983,12 +667,22 @@ static struct clk_rcg2 pcie0_aux_clk_src +@@ -984,12 +668,22 @@ static struct clk_rcg2 pcie0_aux_clk_src .parent_map = gcc_xo_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "pcie0_aux_clk_src", @@ -852,7 +852,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_regmap_mux pcie0_pipe_clk_src = { .reg = 0x7501c, .shift = 8, -@@ -997,8 +691,8 @@ static struct clk_regmap_mux pcie0_pipe_ +@@ -998,8 +692,8 @@ static struct clk_regmap_mux pcie0_pipe_ .clkr = { .hw.init = &(struct clk_init_data){ .name = "pcie0_pipe_clk_src", @@ -863,7 +863,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_regmap_mux_closest_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1013,7 +707,7 @@ static struct clk_rcg2 pcie1_axi_clk_src +@@ -1014,7 +708,7 @@ static struct clk_rcg2 pcie1_axi_clk_src .clkr.hw.init = &(struct clk_init_data){ .name = "pcie1_axi_clk_src", .parent_data = gcc_xo_gpll0, @@ -872,7 +872,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1026,12 +720,22 @@ static struct clk_rcg2 pcie1_aux_clk_src +@@ -1027,12 +721,22 @@ static struct clk_rcg2 pcie1_aux_clk_src .parent_map = gcc_xo_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "pcie1_aux_clk_src", @@ -897,7 +897,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_regmap_mux pcie1_pipe_clk_src = { .reg = 0x7601c, .shift = 8, -@@ -1040,8 +744,8 @@ static struct clk_regmap_mux pcie1_pipe_ +@@ -1041,8 +745,8 @@ static struct clk_regmap_mux pcie1_pipe_ .clkr = { .hw.init = &(struct clk_init_data){ .name = "pcie1_pipe_clk_src", @@ -908,7 +908,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_regmap_mux_closest_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1060,6 +764,20 @@ static const struct freq_tbl ftbl_sdcc_a +@@ -1061,6 +765,20 @@ static const struct freq_tbl ftbl_sdcc_a { } }; @@ -929,7 +929,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 sdcc1_apps_clk_src = { .cmd_rcgr = 0x42004, .freq_tbl = ftbl_sdcc_apps_clk_src, -@@ -1068,8 +786,8 @@ static struct clk_rcg2 sdcc1_apps_clk_sr +@@ -1069,8 +787,8 @@ static struct clk_rcg2 sdcc1_apps_clk_sr .parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc1_apps_clk_src", @@ -940,8 +940,8 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_floor_ops, }, }; -@@ -1080,6 +798,20 @@ static const struct freq_tbl ftbl_sdcc_i - F(308570000, P_GPLL6, 3.5, 0, 0), +@@ -1082,6 +800,20 @@ static const struct freq_tbl ftbl_sdcc_i + { } }; +static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = { @@ -961,7 +961,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 sdcc1_ice_core_clk_src = { .cmd_rcgr = 0x5d000, .freq_tbl = ftbl_sdcc_ice_core_clk_src, -@@ -1088,8 +820,8 @@ static struct clk_rcg2 sdcc1_ice_core_cl +@@ -1090,8 +822,8 @@ static struct clk_rcg2 sdcc1_ice_core_cl .parent_map = gcc_xo_gpll0_gpll6_gpll0_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc1_ice_core_clk_src", @@ -972,7 +972,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1102,8 +834,8 @@ static struct clk_rcg2 sdcc2_apps_clk_sr +@@ -1104,8 +836,8 @@ static struct clk_rcg2 sdcc2_apps_clk_sr .parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc2_apps_clk_src", @@ -983,7 +983,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_floor_ops, }, }; -@@ -1115,6 +847,18 @@ static const struct freq_tbl ftbl_usb_ma +@@ -1117,6 +849,18 @@ static const struct freq_tbl ftbl_usb_ma { } }; @@ -1002,7 +1002,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 usb0_master_clk_src = { .cmd_rcgr = 0x3e00c, .freq_tbl = ftbl_usb_master_clk_src, -@@ -1123,8 +867,8 @@ static struct clk_rcg2 usb0_master_clk_s +@@ -1125,8 +869,8 @@ static struct clk_rcg2 usb0_master_clk_s .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb0_master_clk_src", @@ -1013,7 +1013,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1142,8 +886,8 @@ static struct clk_rcg2 usb0_aux_clk_src +@@ -1144,8 +888,8 @@ static struct clk_rcg2 usb0_aux_clk_src .parent_map = gcc_xo_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb0_aux_clk_src", @@ -1024,7 +1024,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1155,6 +899,20 @@ static const struct freq_tbl ftbl_usb_mo +@@ -1157,6 +901,20 @@ static const struct freq_tbl ftbl_usb_mo { } }; @@ -1045,7 +1045,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 usb0_mock_utmi_clk_src = { .cmd_rcgr = 0x3e020, .freq_tbl = ftbl_usb_mock_utmi_clk_src, -@@ -1163,12 +921,22 @@ static struct clk_rcg2 usb0_mock_utmi_cl +@@ -1165,12 +923,22 @@ static struct clk_rcg2 usb0_mock_utmi_cl .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb0_mock_utmi_clk_src", @@ -1070,7 +1070,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_regmap_mux usb0_pipe_clk_src = { .reg = 0x3e048, .shift = 8, -@@ -1177,8 +945,8 @@ static struct clk_regmap_mux usb0_pipe_c +@@ -1179,8 +947,8 @@ static struct clk_regmap_mux usb0_pipe_c .clkr = { .hw.init = &(struct clk_init_data){ .name = "usb0_pipe_clk_src", @@ -1081,7 +1081,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_regmap_mux_closest_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1193,8 +961,8 @@ static struct clk_rcg2 usb1_master_clk_s +@@ -1195,8 +963,8 @@ static struct clk_rcg2 usb1_master_clk_s .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb1_master_clk_src", @@ -1092,7 +1092,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1207,8 +975,8 @@ static struct clk_rcg2 usb1_aux_clk_src +@@ -1209,8 +977,8 @@ static struct clk_rcg2 usb1_aux_clk_src .parent_map = gcc_xo_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb1_aux_clk_src", @@ -1103,7 +1103,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1221,12 +989,22 @@ static struct clk_rcg2 usb1_mock_utmi_cl +@@ -1223,12 +991,22 @@ static struct clk_rcg2 usb1_mock_utmi_cl .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "usb1_mock_utmi_clk_src", @@ -1128,7 +1128,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_regmap_mux usb1_pipe_clk_src = { .reg = 0x3f048, .shift = 8, -@@ -1235,8 +1013,8 @@ static struct clk_regmap_mux usb1_pipe_c +@@ -1237,8 +1015,8 @@ static struct clk_regmap_mux usb1_pipe_c .clkr = { .hw.init = &(struct clk_init_data){ .name = "usb1_pipe_clk_src", @@ -1139,7 +1139,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_regmap_mux_closest_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1250,8 +1028,9 @@ static struct clk_branch gcc_xo_clk_src +@@ -1252,8 +1030,9 @@ static struct clk_branch gcc_xo_clk_src .enable_mask = BIT(1), .hw.init = &(struct clk_init_data){ .name = "gcc_xo_clk_src", @@ -1151,7 +1151,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, -@@ -1265,9 +1044,8 @@ static struct clk_fixed_factor gcc_xo_di +@@ -1267,9 +1046,8 @@ static struct clk_fixed_factor gcc_xo_di .div = 4, .hw.init = &(struct clk_init_data){ .name = "gcc_xo_div4_clk_src", @@ -1163,7 +1163,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_fixed_factor_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1285,6 +1063,20 @@ static const struct freq_tbl ftbl_system +@@ -1287,6 +1065,20 @@ static const struct freq_tbl ftbl_system { } }; @@ -1184,7 +1184,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 system_noc_bfdcd_clk_src = { .cmd_rcgr = 0x26004, .freq_tbl = ftbl_system_noc_bfdcd_clk_src, -@@ -1292,8 +1084,8 @@ static struct clk_rcg2 system_noc_bfdcd_ +@@ -1294,8 +1086,8 @@ static struct clk_rcg2 system_noc_bfdcd_ .parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "system_noc_bfdcd_clk_src", @@ -1195,7 +1195,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, .flags = CLK_IS_CRITICAL, }, -@@ -1304,9 +1096,8 @@ static struct clk_fixed_factor system_no +@@ -1306,9 +1098,8 @@ static struct clk_fixed_factor system_no .div = 1, .hw.init = &(struct clk_init_data){ .name = "system_noc_clk_src", @@ -1207,7 +1207,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_fixed_factor_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1327,7 +1118,7 @@ static struct clk_rcg2 nss_ce_clk_src = +@@ -1329,7 +1120,7 @@ static struct clk_rcg2 nss_ce_clk_src = .clkr.hw.init = &(struct clk_init_data){ .name = "nss_ce_clk_src", .parent_data = gcc_xo_gpll0, @@ -1216,7 +1216,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1338,6 +1129,20 @@ static const struct freq_tbl ftbl_nss_no +@@ -1340,6 +1131,20 @@ static const struct freq_tbl ftbl_nss_no { } }; @@ -1237,7 +1237,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_noc_bfdcd_clk_src = { .cmd_rcgr = 0x68088, .freq_tbl = ftbl_nss_noc_bfdcd_clk_src, -@@ -1345,8 +1150,8 @@ static struct clk_rcg2 nss_noc_bfdcd_clk +@@ -1347,8 +1152,8 @@ static struct clk_rcg2 nss_noc_bfdcd_clk .parent_map = gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_noc_bfdcd_clk_src", @@ -1248,7 +1248,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1356,9 +1161,8 @@ static struct clk_fixed_factor nss_noc_c +@@ -1358,9 +1163,8 @@ static struct clk_fixed_factor nss_noc_c .div = 1, .hw.init = &(struct clk_init_data){ .name = "nss_noc_clk_src", @@ -1260,7 +1260,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_fixed_factor_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1371,6 +1175,18 @@ static const struct freq_tbl ftbl_nss_cr +@@ -1373,6 +1177,18 @@ static const struct freq_tbl ftbl_nss_cr { } }; @@ -1279,7 +1279,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_crypto_clk_src = { .cmd_rcgr = 0x68144, .freq_tbl = ftbl_nss_crypto_clk_src, -@@ -1379,8 +1195,8 @@ static struct clk_rcg2 nss_crypto_clk_sr +@@ -1381,8 +1197,8 @@ static struct clk_rcg2 nss_crypto_clk_sr .parent_map = gcc_xo_nss_crypto_pll_gpll0_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_crypto_clk_src", @@ -1290,7 +1290,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1394,6 +1210,24 @@ static const struct freq_tbl ftbl_nss_ub +@@ -1396,6 +1212,24 @@ static const struct freq_tbl ftbl_nss_ub { } }; @@ -1315,7 +1315,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_ubi0_clk_src = { .cmd_rcgr = 0x68104, .freq_tbl = ftbl_nss_ubi_clk_src, -@@ -1401,8 +1235,8 @@ static struct clk_rcg2 nss_ubi0_clk_src +@@ -1403,8 +1237,8 @@ static struct clk_rcg2 nss_ubi0_clk_src .parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_ubi0_clk_src", @@ -1326,7 +1326,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1415,9 +1249,8 @@ static struct clk_regmap_div nss_ubi0_di +@@ -1417,9 +1251,8 @@ static struct clk_regmap_div nss_ubi0_di .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_ubi0_div_clk_src", @@ -1338,7 +1338,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ro_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1432,8 +1265,8 @@ static struct clk_rcg2 nss_ubi1_clk_src +@@ -1434,8 +1267,8 @@ static struct clk_rcg2 nss_ubi1_clk_src .parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_ubi1_clk_src", @@ -1349,7 +1349,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, .flags = CLK_SET_RATE_PARENT, }, -@@ -1446,9 +1279,8 @@ static struct clk_regmap_div nss_ubi1_di +@@ -1448,9 +1281,8 @@ static struct clk_regmap_div nss_ubi1_di .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_ubi1_div_clk_src", @@ -1361,7 +1361,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ro_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1462,6 +1294,16 @@ static const struct freq_tbl ftbl_ubi_mp +@@ -1464,6 +1296,16 @@ static const struct freq_tbl ftbl_ubi_mp { } }; @@ -1378,7 +1378,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 ubi_mpt_clk_src = { .cmd_rcgr = 0x68090, .freq_tbl = ftbl_ubi_mpt_clk_src, -@@ -1469,8 +1311,8 @@ static struct clk_rcg2 ubi_mpt_clk_src = +@@ -1471,8 +1313,8 @@ static struct clk_rcg2 ubi_mpt_clk_src = .parent_map = gcc_xo_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "ubi_mpt_clk_src", @@ -1389,7 +1389,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1481,6 +1323,18 @@ static const struct freq_tbl ftbl_nss_im +@@ -1483,6 +1325,18 @@ static const struct freq_tbl ftbl_nss_im { } }; @@ -1408,7 +1408,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_imem_clk_src = { .cmd_rcgr = 0x68158, .freq_tbl = ftbl_nss_imem_clk_src, -@@ -1488,8 +1342,8 @@ static struct clk_rcg2 nss_imem_clk_src +@@ -1490,8 +1344,8 @@ static struct clk_rcg2 nss_imem_clk_src .parent_map = gcc_xo_gpll0_gpll4_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_imem_clk_src", @@ -1419,7 +1419,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1500,6 +1354,24 @@ static const struct freq_tbl ftbl_nss_pp +@@ -1502,6 +1356,24 @@ static const struct freq_tbl ftbl_nss_pp { } }; @@ -1444,7 +1444,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_ppe_clk_src = { .cmd_rcgr = 0x68080, .freq_tbl = ftbl_nss_ppe_clk_src, -@@ -1507,8 +1379,8 @@ static struct clk_rcg2 nss_ppe_clk_src = +@@ -1509,8 +1381,8 @@ static struct clk_rcg2 nss_ppe_clk_src = .parent_map = gcc_xo_bias_gpll0_gpll4_nss_ubi32_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_ppe_clk_src", @@ -1455,7 +1455,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1518,9 +1390,8 @@ static struct clk_fixed_factor nss_ppe_c +@@ -1520,9 +1392,8 @@ static struct clk_fixed_factor nss_ppe_c .div = 4, .hw.init = &(struct clk_init_data){ .name = "nss_ppe_cdiv_clk_src", @@ -1467,7 +1467,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_fixed_factor_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1534,6 +1405,22 @@ static const struct freq_tbl ftbl_nss_po +@@ -1536,6 +1407,22 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1490,7 +1490,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port1_rx_clk_src = { .cmd_rcgr = 0x68020, .freq_tbl = ftbl_nss_port1_rx_clk_src, -@@ -1541,8 +1428,8 @@ static struct clk_rcg2 nss_port1_rx_clk_ +@@ -1543,8 +1430,8 @@ static struct clk_rcg2 nss_port1_rx_clk_ .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port1_rx_clk_src", @@ -1501,7 +1501,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1554,9 +1441,8 @@ static struct clk_regmap_div nss_port1_r +@@ -1556,9 +1443,8 @@ static struct clk_regmap_div nss_port1_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port1_rx_div_clk_src", @@ -1513,7 +1513,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1571,6 +1457,22 @@ static const struct freq_tbl ftbl_nss_po +@@ -1573,6 +1459,22 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1536,7 +1536,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port1_tx_clk_src = { .cmd_rcgr = 0x68028, .freq_tbl = ftbl_nss_port1_tx_clk_src, -@@ -1578,8 +1480,8 @@ static struct clk_rcg2 nss_port1_tx_clk_ +@@ -1580,8 +1482,8 @@ static struct clk_rcg2 nss_port1_tx_clk_ .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port1_tx_clk_src", @@ -1547,7 +1547,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1591,9 +1493,8 @@ static struct clk_regmap_div nss_port1_t +@@ -1593,9 +1495,8 @@ static struct clk_regmap_div nss_port1_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port1_tx_div_clk_src", @@ -1559,7 +1559,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1608,8 +1509,8 @@ static struct clk_rcg2 nss_port2_rx_clk_ +@@ -1610,8 +1511,8 @@ static struct clk_rcg2 nss_port2_rx_clk_ .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port2_rx_clk_src", @@ -1570,7 +1570,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1621,9 +1522,8 @@ static struct clk_regmap_div nss_port2_r +@@ -1623,9 +1524,8 @@ static struct clk_regmap_div nss_port2_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port2_rx_div_clk_src", @@ -1582,7 +1582,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1638,8 +1538,8 @@ static struct clk_rcg2 nss_port2_tx_clk_ +@@ -1640,8 +1540,8 @@ static struct clk_rcg2 nss_port2_tx_clk_ .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port2_tx_clk_src", @@ -1593,7 +1593,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1651,9 +1551,8 @@ static struct clk_regmap_div nss_port2_t +@@ -1653,9 +1553,8 @@ static struct clk_regmap_div nss_port2_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port2_tx_div_clk_src", @@ -1605,7 +1605,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1668,8 +1567,8 @@ static struct clk_rcg2 nss_port3_rx_clk_ +@@ -1670,8 +1569,8 @@ static struct clk_rcg2 nss_port3_rx_clk_ .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port3_rx_clk_src", @@ -1616,7 +1616,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1681,9 +1580,8 @@ static struct clk_regmap_div nss_port3_r +@@ -1683,9 +1582,8 @@ static struct clk_regmap_div nss_port3_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port3_rx_div_clk_src", @@ -1628,7 +1628,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1698,8 +1596,8 @@ static struct clk_rcg2 nss_port3_tx_clk_ +@@ -1700,8 +1598,8 @@ static struct clk_rcg2 nss_port3_tx_clk_ .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port3_tx_clk_src", @@ -1639,7 +1639,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1711,9 +1609,8 @@ static struct clk_regmap_div nss_port3_t +@@ -1713,9 +1611,8 @@ static struct clk_regmap_div nss_port3_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port3_tx_div_clk_src", @@ -1651,7 +1651,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1728,8 +1625,8 @@ static struct clk_rcg2 nss_port4_rx_clk_ +@@ -1730,8 +1627,8 @@ static struct clk_rcg2 nss_port4_rx_clk_ .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port4_rx_clk_src", @@ -1662,7 +1662,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1741,9 +1638,8 @@ static struct clk_regmap_div nss_port4_r +@@ -1743,9 +1640,8 @@ static struct clk_regmap_div nss_port4_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port4_rx_div_clk_src", @@ -1674,7 +1674,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1758,8 +1654,8 @@ static struct clk_rcg2 nss_port4_tx_clk_ +@@ -1760,8 +1656,8 @@ static struct clk_rcg2 nss_port4_tx_clk_ .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port4_tx_clk_src", @@ -1685,7 +1685,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1771,9 +1667,8 @@ static struct clk_regmap_div nss_port4_t +@@ -1773,9 +1669,8 @@ static struct clk_regmap_div nss_port4_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port4_tx_div_clk_src", @@ -1697,7 +1697,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1793,6 +1688,27 @@ static const struct freq_tbl ftbl_nss_po +@@ -1795,6 +1690,27 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1725,7 +1725,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port5_rx_clk_src = { .cmd_rcgr = 0x68060, .freq_tbl = ftbl_nss_port5_rx_clk_src, -@@ -1800,8 +1716,8 @@ static struct clk_rcg2 nss_port5_rx_clk_ +@@ -1802,8 +1718,8 @@ static struct clk_rcg2 nss_port5_rx_clk_ .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_rx_clk_src", @@ -1736,7 +1736,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1813,9 +1729,8 @@ static struct clk_regmap_div nss_port5_r +@@ -1815,9 +1731,8 @@ static struct clk_regmap_div nss_port5_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port5_rx_div_clk_src", @@ -1748,7 +1748,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1835,6 +1750,27 @@ static const struct freq_tbl ftbl_nss_po +@@ -1837,6 +1752,27 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1776,7 +1776,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port5_tx_clk_src = { .cmd_rcgr = 0x68068, .freq_tbl = ftbl_nss_port5_tx_clk_src, -@@ -1842,8 +1778,8 @@ static struct clk_rcg2 nss_port5_tx_clk_ +@@ -1844,8 +1780,8 @@ static struct clk_rcg2 nss_port5_tx_clk_ .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_tx_clk_src", @@ -1787,7 +1787,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1855,9 +1791,8 @@ static struct clk_regmap_div nss_port5_t +@@ -1857,9 +1793,8 @@ static struct clk_regmap_div nss_port5_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port5_tx_div_clk_src", @@ -1799,7 +1799,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1877,6 +1812,22 @@ static const struct freq_tbl ftbl_nss_po +@@ -1879,6 +1814,22 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1822,7 +1822,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port6_rx_clk_src = { .cmd_rcgr = 0x68070, .freq_tbl = ftbl_nss_port6_rx_clk_src, -@@ -1884,8 +1835,8 @@ static struct clk_rcg2 nss_port6_rx_clk_ +@@ -1886,8 +1837,8 @@ static struct clk_rcg2 nss_port6_rx_clk_ .parent_map = gcc_xo_uniphy2_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_rx_clk_src", @@ -1833,7 +1833,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1897,9 +1848,8 @@ static struct clk_regmap_div nss_port6_r +@@ -1899,9 +1850,8 @@ static struct clk_regmap_div nss_port6_r .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port6_rx_div_clk_src", @@ -1845,7 +1845,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1919,6 +1869,22 @@ static const struct freq_tbl ftbl_nss_po +@@ -1921,6 +1871,22 @@ static const struct freq_tbl ftbl_nss_po { } }; @@ -1868,7 +1868,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 nss_port6_tx_clk_src = { .cmd_rcgr = 0x68078, .freq_tbl = ftbl_nss_port6_tx_clk_src, -@@ -1926,8 +1892,8 @@ static struct clk_rcg2 nss_port6_tx_clk_ +@@ -1928,8 +1894,8 @@ static struct clk_rcg2 nss_port6_tx_clk_ .parent_map = gcc_xo_uniphy2_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port6_tx_clk_src", @@ -1879,7 +1879,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1939,9 +1905,8 @@ static struct clk_regmap_div nss_port6_t +@@ -1941,9 +1907,8 @@ static struct clk_regmap_div nss_port6_t .clkr = { .hw.init = &(struct clk_init_data){ .name = "nss_port6_tx_div_clk_src", @@ -1891,7 +1891,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .ops = &clk_regmap_div_ops, .flags = CLK_SET_RATE_PARENT, -@@ -1964,8 +1929,8 @@ static struct clk_rcg2 crypto_clk_src = +@@ -1966,8 +1931,8 @@ static struct clk_rcg2 crypto_clk_src = .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, .clkr.hw.init = &(struct clk_init_data){ .name = "crypto_clk_src", @@ -1902,7 +1902,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1975,6 +1940,22 @@ static struct freq_tbl ftbl_gp_clk_src[] +@@ -1977,6 +1942,22 @@ static struct freq_tbl ftbl_gp_clk_src[] { } }; @@ -1925,7 +1925,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com static struct clk_rcg2 gp1_clk_src = { .cmd_rcgr = 0x08004, .freq_tbl = ftbl_gp_clk_src, -@@ -1983,8 +1964,8 @@ static struct clk_rcg2 gp1_clk_src = { +@@ -1985,8 +1966,8 @@ static struct clk_rcg2 gp1_clk_src = { .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "gp1_clk_src", @@ -1936,7 +1936,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -1997,8 +1978,8 @@ static struct clk_rcg2 gp2_clk_src = { +@@ -1999,8 +1980,8 @@ static struct clk_rcg2 gp2_clk_src = { .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "gp2_clk_src", @@ -1947,7 +1947,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -2011,8 +1992,8 @@ static struct clk_rcg2 gp3_clk_src = { +@@ -2013,8 +1994,8 @@ static struct clk_rcg2 gp3_clk_src = { .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, .clkr.hw.init = &(struct clk_init_data){ .name = "gp3_clk_src", @@ -1958,7 +1958,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .ops = &clk_rcg2_ops, }, }; -@@ -2024,9 +2005,8 @@ static struct clk_branch gcc_blsp1_ahb_c +@@ -2026,9 +2007,8 @@ static struct clk_branch gcc_blsp1_ahb_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_ahb_clk", @@ -1970,7 +1970,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2041,9 +2021,8 @@ static struct clk_branch gcc_blsp1_qup1_ +@@ -2043,9 +2023,8 @@ static struct clk_branch gcc_blsp1_qup1_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup1_i2c_apps_clk", @@ -1982,7 +1982,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2058,9 +2037,8 @@ static struct clk_branch gcc_blsp1_qup1_ +@@ -2060,9 +2039,8 @@ static struct clk_branch gcc_blsp1_qup1_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup1_spi_apps_clk", @@ -1994,7 +1994,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2075,9 +2053,8 @@ static struct clk_branch gcc_blsp1_qup2_ +@@ -2077,9 +2055,8 @@ static struct clk_branch gcc_blsp1_qup2_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup2_i2c_apps_clk", @@ -2006,7 +2006,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2092,9 +2069,8 @@ static struct clk_branch gcc_blsp1_qup2_ +@@ -2094,9 +2071,8 @@ static struct clk_branch gcc_blsp1_qup2_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup2_spi_apps_clk", @@ -2018,7 +2018,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2109,9 +2085,8 @@ static struct clk_branch gcc_blsp1_qup3_ +@@ -2111,9 +2087,8 @@ static struct clk_branch gcc_blsp1_qup3_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup3_i2c_apps_clk", @@ -2030,7 +2030,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2126,9 +2101,8 @@ static struct clk_branch gcc_blsp1_qup3_ +@@ -2128,9 +2103,8 @@ static struct clk_branch gcc_blsp1_qup3_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup3_spi_apps_clk", @@ -2042,7 +2042,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2143,9 +2117,8 @@ static struct clk_branch gcc_blsp1_qup4_ +@@ -2145,9 +2119,8 @@ static struct clk_branch gcc_blsp1_qup4_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup4_i2c_apps_clk", @@ -2054,7 +2054,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2160,9 +2133,8 @@ static struct clk_branch gcc_blsp1_qup4_ +@@ -2162,9 +2135,8 @@ static struct clk_branch gcc_blsp1_qup4_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup4_spi_apps_clk", @@ -2066,7 +2066,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2177,9 +2149,8 @@ static struct clk_branch gcc_blsp1_qup5_ +@@ -2179,9 +2151,8 @@ static struct clk_branch gcc_blsp1_qup5_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup5_i2c_apps_clk", @@ -2078,7 +2078,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2194,9 +2165,8 @@ static struct clk_branch gcc_blsp1_qup5_ +@@ -2196,9 +2167,8 @@ static struct clk_branch gcc_blsp1_qup5_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup5_spi_apps_clk", @@ -2090,7 +2090,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2211,9 +2181,8 @@ static struct clk_branch gcc_blsp1_qup6_ +@@ -2213,9 +2183,8 @@ static struct clk_branch gcc_blsp1_qup6_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup6_i2c_apps_clk", @@ -2102,7 +2102,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2228,9 +2197,8 @@ static struct clk_branch gcc_blsp1_qup6_ +@@ -2230,9 +2199,8 @@ static struct clk_branch gcc_blsp1_qup6_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup6_spi_apps_clk", @@ -2114,7 +2114,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2245,9 +2213,8 @@ static struct clk_branch gcc_blsp1_uart1 +@@ -2247,9 +2215,8 @@ static struct clk_branch gcc_blsp1_uart1 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart1_apps_clk", @@ -2126,7 +2126,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2262,9 +2229,8 @@ static struct clk_branch gcc_blsp1_uart2 +@@ -2264,9 +2231,8 @@ static struct clk_branch gcc_blsp1_uart2 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart2_apps_clk", @@ -2138,7 +2138,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2279,9 +2245,8 @@ static struct clk_branch gcc_blsp1_uart3 +@@ -2281,9 +2247,8 @@ static struct clk_branch gcc_blsp1_uart3 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart3_apps_clk", @@ -2150,7 +2150,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2296,9 +2261,8 @@ static struct clk_branch gcc_blsp1_uart4 +@@ -2298,9 +2263,8 @@ static struct clk_branch gcc_blsp1_uart4 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart4_apps_clk", @@ -2162,7 +2162,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2313,9 +2277,8 @@ static struct clk_branch gcc_blsp1_uart5 +@@ -2315,9 +2279,8 @@ static struct clk_branch gcc_blsp1_uart5 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart5_apps_clk", @@ -2174,7 +2174,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2330,9 +2293,8 @@ static struct clk_branch gcc_blsp1_uart6 +@@ -2332,9 +2295,8 @@ static struct clk_branch gcc_blsp1_uart6 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart6_apps_clk", @@ -2186,7 +2186,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2348,9 +2310,8 @@ static struct clk_branch gcc_prng_ahb_cl +@@ -2350,9 +2312,8 @@ static struct clk_branch gcc_prng_ahb_cl .enable_mask = BIT(8), .hw.init = &(struct clk_init_data){ .name = "gcc_prng_ahb_clk", @@ -2198,7 +2198,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2365,9 +2326,8 @@ static struct clk_branch gcc_qpic_ahb_cl +@@ -2367,9 +2328,8 @@ static struct clk_branch gcc_qpic_ahb_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_qpic_ahb_clk", @@ -2210,7 +2210,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2382,9 +2342,8 @@ static struct clk_branch gcc_qpic_clk = +@@ -2384,9 +2344,8 @@ static struct clk_branch gcc_qpic_clk = .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_qpic_clk", @@ -2222,7 +2222,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2399,9 +2358,8 @@ static struct clk_branch gcc_pcie0_ahb_c +@@ -2401,9 +2360,8 @@ static struct clk_branch gcc_pcie0_ahb_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie0_ahb_clk", @@ -2234,7 +2234,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2416,9 +2374,8 @@ static struct clk_branch gcc_pcie0_aux_c +@@ -2418,9 +2376,8 @@ static struct clk_branch gcc_pcie0_aux_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie0_aux_clk", @@ -2246,7 +2246,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2433,9 +2390,8 @@ static struct clk_branch gcc_pcie0_axi_m +@@ -2435,9 +2392,8 @@ static struct clk_branch gcc_pcie0_axi_m .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie0_axi_m_clk", @@ -2258,7 +2258,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2450,9 +2406,8 @@ static struct clk_branch gcc_pcie0_axi_s +@@ -2452,9 +2408,8 @@ static struct clk_branch gcc_pcie0_axi_s .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie0_axi_s_clk", @@ -2270,7 +2270,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2468,9 +2423,8 @@ static struct clk_branch gcc_pcie0_pipe_ +@@ -2470,9 +2425,8 @@ static struct clk_branch gcc_pcie0_pipe_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie0_pipe_clk", @@ -2282,7 +2282,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2485,9 +2439,8 @@ static struct clk_branch gcc_sys_noc_pci +@@ -2487,9 +2441,8 @@ static struct clk_branch gcc_sys_noc_pci .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sys_noc_pcie0_axi_clk", @@ -2294,7 +2294,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2502,9 +2455,8 @@ static struct clk_branch gcc_pcie1_ahb_c +@@ -2504,9 +2457,8 @@ static struct clk_branch gcc_pcie1_ahb_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie1_ahb_clk", @@ -2306,7 +2306,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2519,9 +2471,8 @@ static struct clk_branch gcc_pcie1_aux_c +@@ -2521,9 +2473,8 @@ static struct clk_branch gcc_pcie1_aux_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie1_aux_clk", @@ -2318,7 +2318,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2536,9 +2487,8 @@ static struct clk_branch gcc_pcie1_axi_m +@@ -2538,9 +2489,8 @@ static struct clk_branch gcc_pcie1_axi_m .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie1_axi_m_clk", @@ -2330,7 +2330,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2553,9 +2503,8 @@ static struct clk_branch gcc_pcie1_axi_s +@@ -2555,9 +2505,8 @@ static struct clk_branch gcc_pcie1_axi_s .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie1_axi_s_clk", @@ -2342,7 +2342,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2571,9 +2520,8 @@ static struct clk_branch gcc_pcie1_pipe_ +@@ -2573,9 +2522,8 @@ static struct clk_branch gcc_pcie1_pipe_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie1_pipe_clk", @@ -2354,7 +2354,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2588,9 +2536,8 @@ static struct clk_branch gcc_sys_noc_pci +@@ -2590,9 +2538,8 @@ static struct clk_branch gcc_sys_noc_pci .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sys_noc_pcie1_axi_clk", @@ -2366,7 +2366,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2605,9 +2552,8 @@ static struct clk_branch gcc_usb0_aux_cl +@@ -2607,9 +2554,8 @@ static struct clk_branch gcc_usb0_aux_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_aux_clk", @@ -2378,7 +2378,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2622,9 +2568,8 @@ static struct clk_branch gcc_sys_noc_usb +@@ -2624,9 +2570,8 @@ static struct clk_branch gcc_sys_noc_usb .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sys_noc_usb0_axi_clk", @@ -2390,7 +2390,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2639,9 +2584,8 @@ static struct clk_branch gcc_usb0_master +@@ -2641,9 +2586,8 @@ static struct clk_branch gcc_usb0_master .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_master_clk", @@ -2402,7 +2402,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2656,9 +2600,8 @@ static struct clk_branch gcc_usb0_mock_u +@@ -2658,9 +2602,8 @@ static struct clk_branch gcc_usb0_mock_u .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_mock_utmi_clk", @@ -2414,7 +2414,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2673,9 +2616,8 @@ static struct clk_branch gcc_usb0_phy_cf +@@ -2675,9 +2618,8 @@ static struct clk_branch gcc_usb0_phy_cf .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_phy_cfg_ahb_clk", @@ -2426,7 +2426,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2691,9 +2633,8 @@ static struct clk_branch gcc_usb0_pipe_c +@@ -2693,9 +2635,8 @@ static struct clk_branch gcc_usb0_pipe_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_pipe_clk", @@ -2438,7 +2438,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2708,9 +2649,8 @@ static struct clk_branch gcc_usb0_sleep_ +@@ -2710,9 +2651,8 @@ static struct clk_branch gcc_usb0_sleep_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb0_sleep_clk", @@ -2450,7 +2450,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2725,9 +2665,8 @@ static struct clk_branch gcc_usb1_aux_cl +@@ -2727,9 +2667,8 @@ static struct clk_branch gcc_usb1_aux_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_aux_clk", @@ -2462,7 +2462,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2742,9 +2681,8 @@ static struct clk_branch gcc_sys_noc_usb +@@ -2744,9 +2683,8 @@ static struct clk_branch gcc_sys_noc_usb .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sys_noc_usb1_axi_clk", @@ -2474,7 +2474,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2759,9 +2697,8 @@ static struct clk_branch gcc_usb1_master +@@ -2761,9 +2699,8 @@ static struct clk_branch gcc_usb1_master .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_master_clk", @@ -2486,7 +2486,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2776,9 +2713,8 @@ static struct clk_branch gcc_usb1_mock_u +@@ -2778,9 +2715,8 @@ static struct clk_branch gcc_usb1_mock_u .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_mock_utmi_clk", @@ -2498,7 +2498,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2793,9 +2729,8 @@ static struct clk_branch gcc_usb1_phy_cf +@@ -2795,9 +2731,8 @@ static struct clk_branch gcc_usb1_phy_cf .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_phy_cfg_ahb_clk", @@ -2510,7 +2510,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2811,9 +2746,8 @@ static struct clk_branch gcc_usb1_pipe_c +@@ -2813,9 +2748,8 @@ static struct clk_branch gcc_usb1_pipe_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_pipe_clk", @@ -2522,7 +2522,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2828,9 +2762,8 @@ static struct clk_branch gcc_usb1_sleep_ +@@ -2830,9 +2764,8 @@ static struct clk_branch gcc_usb1_sleep_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb1_sleep_clk", @@ -2534,7 +2534,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2845,9 +2778,8 @@ static struct clk_branch gcc_sdcc1_ahb_c +@@ -2847,9 +2780,8 @@ static struct clk_branch gcc_sdcc1_ahb_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc1_ahb_clk", @@ -2546,7 +2546,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2862,9 +2794,8 @@ static struct clk_branch gcc_sdcc1_apps_ +@@ -2864,9 +2796,8 @@ static struct clk_branch gcc_sdcc1_apps_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc1_apps_clk", @@ -2558,7 +2558,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2879,9 +2810,8 @@ static struct clk_branch gcc_sdcc1_ice_c +@@ -2881,9 +2812,8 @@ static struct clk_branch gcc_sdcc1_ice_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc1_ice_core_clk", @@ -2570,7 +2570,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2896,9 +2826,8 @@ static struct clk_branch gcc_sdcc2_ahb_c +@@ -2898,9 +2828,8 @@ static struct clk_branch gcc_sdcc2_ahb_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_ahb_clk", @@ -2582,7 +2582,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2913,9 +2842,8 @@ static struct clk_branch gcc_sdcc2_apps_ +@@ -2915,9 +2844,8 @@ static struct clk_branch gcc_sdcc2_apps_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_apps_clk", @@ -2594,7 +2594,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2930,9 +2858,8 @@ static struct clk_branch gcc_mem_noc_nss +@@ -2932,9 +2860,8 @@ static struct clk_branch gcc_mem_noc_nss .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mem_noc_nss_axi_clk", @@ -2606,7 +2606,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2947,9 +2874,8 @@ static struct clk_branch gcc_nss_ce_apb_ +@@ -2949,9 +2876,8 @@ static struct clk_branch gcc_nss_ce_apb_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ce_apb_clk", @@ -2618,7 +2618,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2964,9 +2890,8 @@ static struct clk_branch gcc_nss_ce_axi_ +@@ -2966,9 +2892,8 @@ static struct clk_branch gcc_nss_ce_axi_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ce_axi_clk", @@ -2630,7 +2630,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2981,9 +2906,8 @@ static struct clk_branch gcc_nss_cfg_clk +@@ -2983,9 +2908,8 @@ static struct clk_branch gcc_nss_cfg_clk .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_cfg_clk", @@ -2642,7 +2642,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -2998,9 +2922,8 @@ static struct clk_branch gcc_nss_crypto_ +@@ -3000,9 +2924,8 @@ static struct clk_branch gcc_nss_crypto_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_crypto_clk", @@ -2654,7 +2654,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3015,9 +2938,8 @@ static struct clk_branch gcc_nss_csr_clk +@@ -3017,9 +2940,8 @@ static struct clk_branch gcc_nss_csr_clk .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_csr_clk", @@ -2666,7 +2666,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3032,9 +2954,8 @@ static struct clk_branch gcc_nss_edma_cf +@@ -3034,9 +2956,8 @@ static struct clk_branch gcc_nss_edma_cf .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_edma_cfg_clk", @@ -2678,7 +2678,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3049,9 +2970,8 @@ static struct clk_branch gcc_nss_edma_cl +@@ -3051,9 +2972,8 @@ static struct clk_branch gcc_nss_edma_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_edma_clk", @@ -2690,7 +2690,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3066,9 +2986,8 @@ static struct clk_branch gcc_nss_imem_cl +@@ -3068,9 +2988,8 @@ static struct clk_branch gcc_nss_imem_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_imem_clk", @@ -2702,7 +2702,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3083,9 +3002,8 @@ static struct clk_branch gcc_nss_noc_clk +@@ -3085,9 +3004,8 @@ static struct clk_branch gcc_nss_noc_clk .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_noc_clk", @@ -2714,7 +2714,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3100,9 +3018,8 @@ static struct clk_branch gcc_nss_ppe_btq +@@ -3102,9 +3020,8 @@ static struct clk_branch gcc_nss_ppe_btq .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ppe_btq_clk", @@ -2726,7 +2726,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3117,9 +3034,8 @@ static struct clk_branch gcc_nss_ppe_cfg +@@ -3119,9 +3036,8 @@ static struct clk_branch gcc_nss_ppe_cfg .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ppe_cfg_clk", @@ -2738,7 +2738,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3134,9 +3050,8 @@ static struct clk_branch gcc_nss_ppe_clk +@@ -3136,9 +3052,8 @@ static struct clk_branch gcc_nss_ppe_clk .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ppe_clk", @@ -2750,7 +2750,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3151,9 +3066,8 @@ static struct clk_branch gcc_nss_ppe_ipe +@@ -3153,9 +3068,8 @@ static struct clk_branch gcc_nss_ppe_ipe .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ppe_ipe_clk", @@ -2762,7 +2762,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3168,9 +3082,8 @@ static struct clk_branch gcc_nss_ptp_ref +@@ -3170,9 +3084,8 @@ static struct clk_branch gcc_nss_ptp_ref .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_ptp_ref_clk", @@ -2774,7 +2774,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3186,9 +3099,8 @@ static struct clk_branch gcc_crypto_ppe_ +@@ -3188,9 +3101,8 @@ static struct clk_branch gcc_crypto_ppe_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_ppe_clk", @@ -2786,7 +2786,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3203,9 +3115,8 @@ static struct clk_branch gcc_nssnoc_ce_a +@@ -3205,9 +3117,8 @@ static struct clk_branch gcc_nssnoc_ce_a .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ce_apb_clk", @@ -2798,7 +2798,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3220,9 +3131,8 @@ static struct clk_branch gcc_nssnoc_ce_a +@@ -3222,9 +3133,8 @@ static struct clk_branch gcc_nssnoc_ce_a .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ce_axi_clk", @@ -2810,7 +2810,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3237,9 +3147,8 @@ static struct clk_branch gcc_nssnoc_cryp +@@ -3239,9 +3149,8 @@ static struct clk_branch gcc_nssnoc_cryp .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_crypto_clk", @@ -2822,7 +2822,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3254,9 +3163,8 @@ static struct clk_branch gcc_nssnoc_ppe_ +@@ -3256,9 +3165,8 @@ static struct clk_branch gcc_nssnoc_ppe_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ppe_cfg_clk", @@ -2834,7 +2834,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3271,9 +3179,8 @@ static struct clk_branch gcc_nssnoc_ppe_ +@@ -3273,9 +3181,8 @@ static struct clk_branch gcc_nssnoc_ppe_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ppe_clk", @@ -2846,7 +2846,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3288,9 +3195,8 @@ static struct clk_branch gcc_nssnoc_qosg +@@ -3290,9 +3197,8 @@ static struct clk_branch gcc_nssnoc_qosg .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_qosgen_ref_clk", @@ -2858,7 +2858,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3305,9 +3211,8 @@ static struct clk_branch gcc_nssnoc_snoc +@@ -3307,9 +3213,8 @@ static struct clk_branch gcc_nssnoc_snoc .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_snoc_clk", @@ -2870,7 +2870,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3322,9 +3227,8 @@ static struct clk_branch gcc_nssnoc_time +@@ -3324,9 +3229,8 @@ static struct clk_branch gcc_nssnoc_time .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_timeout_ref_clk", @@ -2882,7 +2882,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3339,9 +3243,8 @@ static struct clk_branch gcc_nssnoc_ubi0 +@@ -3341,9 +3245,8 @@ static struct clk_branch gcc_nssnoc_ubi0 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ubi0_ahb_clk", @@ -2894,7 +2894,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3356,9 +3259,8 @@ static struct clk_branch gcc_nssnoc_ubi1 +@@ -3358,9 +3261,8 @@ static struct clk_branch gcc_nssnoc_ubi1 .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nssnoc_ubi1_ahb_clk", @@ -2906,7 +2906,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3374,9 +3276,8 @@ static struct clk_branch gcc_ubi0_ahb_cl +@@ -3376,9 +3278,8 @@ static struct clk_branch gcc_ubi0_ahb_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi0_ahb_clk", @@ -2918,7 +2918,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3392,9 +3293,8 @@ static struct clk_branch gcc_ubi0_axi_cl +@@ -3394,9 +3295,8 @@ static struct clk_branch gcc_ubi0_axi_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi0_axi_clk", @@ -2930,7 +2930,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3410,9 +3310,8 @@ static struct clk_branch gcc_ubi0_nc_axi +@@ -3412,9 +3312,8 @@ static struct clk_branch gcc_ubi0_nc_axi .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi0_nc_axi_clk", @@ -2942,7 +2942,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3428,9 +3327,8 @@ static struct clk_branch gcc_ubi0_core_c +@@ -3430,9 +3329,8 @@ static struct clk_branch gcc_ubi0_core_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi0_core_clk", @@ -2954,7 +2954,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3446,9 +3344,8 @@ static struct clk_branch gcc_ubi0_mpt_cl +@@ -3448,9 +3346,8 @@ static struct clk_branch gcc_ubi0_mpt_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi0_mpt_clk", @@ -2966,7 +2966,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3464,9 +3361,8 @@ static struct clk_branch gcc_ubi1_ahb_cl +@@ -3466,9 +3363,8 @@ static struct clk_branch gcc_ubi1_ahb_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi1_ahb_clk", @@ -2978,7 +2978,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3482,9 +3378,8 @@ static struct clk_branch gcc_ubi1_axi_cl +@@ -3484,9 +3380,8 @@ static struct clk_branch gcc_ubi1_axi_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi1_axi_clk", @@ -2990,7 +2990,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3500,9 +3395,8 @@ static struct clk_branch gcc_ubi1_nc_axi +@@ -3502,9 +3397,8 @@ static struct clk_branch gcc_ubi1_nc_axi .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi1_nc_axi_clk", @@ -3002,7 +3002,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3518,9 +3412,8 @@ static struct clk_branch gcc_ubi1_core_c +@@ -3520,9 +3414,8 @@ static struct clk_branch gcc_ubi1_core_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi1_core_clk", @@ -3014,7 +3014,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3536,9 +3429,8 @@ static struct clk_branch gcc_ubi1_mpt_cl +@@ -3538,9 +3431,8 @@ static struct clk_branch gcc_ubi1_mpt_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ubi1_mpt_clk", @@ -3026,7 +3026,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3553,9 +3445,8 @@ static struct clk_branch gcc_cmn_12gpll_ +@@ -3555,9 +3447,8 @@ static struct clk_branch gcc_cmn_12gpll_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_cmn_12gpll_ahb_clk", @@ -3038,7 +3038,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3570,9 +3461,8 @@ static struct clk_branch gcc_cmn_12gpll_ +@@ -3572,9 +3463,8 @@ static struct clk_branch gcc_cmn_12gpll_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_cmn_12gpll_sys_clk", @@ -3050,7 +3050,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3587,9 +3477,8 @@ static struct clk_branch gcc_mdio_ahb_cl +@@ -3589,9 +3479,8 @@ static struct clk_branch gcc_mdio_ahb_cl .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mdio_ahb_clk", @@ -3062,7 +3062,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3604,9 +3493,8 @@ static struct clk_branch gcc_uniphy0_ahb +@@ -3606,9 +3495,8 @@ static struct clk_branch gcc_uniphy0_ahb .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_ahb_clk", @@ -3074,7 +3074,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3621,9 +3509,8 @@ static struct clk_branch gcc_uniphy0_sys +@@ -3623,9 +3511,8 @@ static struct clk_branch gcc_uniphy0_sys .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_sys_clk", @@ -3086,7 +3086,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3638,9 +3525,8 @@ static struct clk_branch gcc_uniphy1_ahb +@@ -3640,9 +3527,8 @@ static struct clk_branch gcc_uniphy1_ahb .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy1_ahb_clk", @@ -3098,7 +3098,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3655,9 +3541,8 @@ static struct clk_branch gcc_uniphy1_sys +@@ -3657,9 +3543,8 @@ static struct clk_branch gcc_uniphy1_sys .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy1_sys_clk", @@ -3110,7 +3110,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3672,9 +3557,8 @@ static struct clk_branch gcc_uniphy2_ahb +@@ -3674,9 +3559,8 @@ static struct clk_branch gcc_uniphy2_ahb .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy2_ahb_clk", @@ -3122,7 +3122,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3689,9 +3573,8 @@ static struct clk_branch gcc_uniphy2_sys +@@ -3691,9 +3575,8 @@ static struct clk_branch gcc_uniphy2_sys .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy2_sys_clk", @@ -3134,7 +3134,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3706,9 +3589,8 @@ static struct clk_branch gcc_nss_port1_r +@@ -3708,9 +3591,8 @@ static struct clk_branch gcc_nss_port1_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port1_rx_clk", @@ -3146,7 +3146,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3723,9 +3605,8 @@ static struct clk_branch gcc_nss_port1_t +@@ -3725,9 +3607,8 @@ static struct clk_branch gcc_nss_port1_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port1_tx_clk", @@ -3158,7 +3158,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3740,9 +3621,8 @@ static struct clk_branch gcc_nss_port2_r +@@ -3742,9 +3623,8 @@ static struct clk_branch gcc_nss_port2_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port2_rx_clk", @@ -3170,7 +3170,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3757,9 +3637,8 @@ static struct clk_branch gcc_nss_port2_t +@@ -3759,9 +3639,8 @@ static struct clk_branch gcc_nss_port2_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port2_tx_clk", @@ -3182,7 +3182,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3774,9 +3653,8 @@ static struct clk_branch gcc_nss_port3_r +@@ -3776,9 +3655,8 @@ static struct clk_branch gcc_nss_port3_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port3_rx_clk", @@ -3194,7 +3194,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3791,9 +3669,8 @@ static struct clk_branch gcc_nss_port3_t +@@ -3793,9 +3671,8 @@ static struct clk_branch gcc_nss_port3_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port3_tx_clk", @@ -3206,7 +3206,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3808,9 +3685,8 @@ static struct clk_branch gcc_nss_port4_r +@@ -3810,9 +3687,8 @@ static struct clk_branch gcc_nss_port4_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port4_rx_clk", @@ -3218,7 +3218,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3825,9 +3701,8 @@ static struct clk_branch gcc_nss_port4_t +@@ -3827,9 +3703,8 @@ static struct clk_branch gcc_nss_port4_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port4_tx_clk", @@ -3230,7 +3230,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3842,9 +3717,8 @@ static struct clk_branch gcc_nss_port5_r +@@ -3844,9 +3719,8 @@ static struct clk_branch gcc_nss_port5_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port5_rx_clk", @@ -3242,7 +3242,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3859,9 +3733,8 @@ static struct clk_branch gcc_nss_port5_t +@@ -3861,9 +3735,8 @@ static struct clk_branch gcc_nss_port5_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port5_tx_clk", @@ -3254,7 +3254,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3876,9 +3749,8 @@ static struct clk_branch gcc_nss_port6_r +@@ -3878,9 +3751,8 @@ static struct clk_branch gcc_nss_port6_r .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port6_rx_clk", @@ -3266,7 +3266,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3893,9 +3765,8 @@ static struct clk_branch gcc_nss_port6_t +@@ -3895,9 +3767,8 @@ static struct clk_branch gcc_nss_port6_t .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_nss_port6_tx_clk", @@ -3278,7 +3278,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3910,9 +3781,8 @@ static struct clk_branch gcc_port1_mac_c +@@ -3912,9 +3783,8 @@ static struct clk_branch gcc_port1_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port1_mac_clk", @@ -3290,7 +3290,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3927,9 +3797,8 @@ static struct clk_branch gcc_port2_mac_c +@@ -3929,9 +3799,8 @@ static struct clk_branch gcc_port2_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port2_mac_clk", @@ -3302,7 +3302,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3944,9 +3813,8 @@ static struct clk_branch gcc_port3_mac_c +@@ -3946,9 +3815,8 @@ static struct clk_branch gcc_port3_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port3_mac_clk", @@ -3314,7 +3314,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3961,9 +3829,8 @@ static struct clk_branch gcc_port4_mac_c +@@ -3963,9 +3831,8 @@ static struct clk_branch gcc_port4_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port4_mac_clk", @@ -3326,7 +3326,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3978,9 +3845,8 @@ static struct clk_branch gcc_port5_mac_c +@@ -3980,9 +3847,8 @@ static struct clk_branch gcc_port5_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port5_mac_clk", @@ -3338,7 +3338,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -3995,9 +3861,8 @@ static struct clk_branch gcc_port6_mac_c +@@ -3997,9 +3863,8 @@ static struct clk_branch gcc_port6_mac_c .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_port6_mac_clk", @@ -3350,7 +3350,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4012,9 +3877,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4014,9 +3879,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port1_rx_clk", @@ -3362,7 +3362,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4029,9 +3893,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4031,9 +3895,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port1_tx_clk", @@ -3374,7 +3374,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4046,9 +3909,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4048,9 +3911,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port2_rx_clk", @@ -3386,7 +3386,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4063,9 +3925,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4065,9 +3927,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port2_tx_clk", @@ -3398,7 +3398,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4080,9 +3941,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4082,9 +3943,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port3_rx_clk", @@ -3410,7 +3410,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4097,9 +3957,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4099,9 +3959,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port3_tx_clk", @@ -3422,7 +3422,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4114,9 +3973,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4116,9 +3975,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port4_rx_clk", @@ -3434,7 +3434,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4131,9 +3989,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4133,9 +3991,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port4_tx_clk", @@ -3446,7 +3446,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4148,9 +4005,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4150,9 +4007,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port5_rx_clk", @@ -3458,7 +3458,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4165,9 +4021,8 @@ static struct clk_branch gcc_uniphy0_por +@@ -4167,9 +4023,8 @@ static struct clk_branch gcc_uniphy0_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy0_port5_tx_clk", @@ -3470,7 +3470,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4182,9 +4037,8 @@ static struct clk_branch gcc_uniphy1_por +@@ -4184,9 +4039,8 @@ static struct clk_branch gcc_uniphy1_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy1_port5_rx_clk", @@ -3482,7 +3482,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4199,9 +4053,8 @@ static struct clk_branch gcc_uniphy1_por +@@ -4201,9 +4055,8 @@ static struct clk_branch gcc_uniphy1_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy1_port5_tx_clk", @@ -3494,7 +3494,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4216,9 +4069,8 @@ static struct clk_branch gcc_uniphy2_por +@@ -4218,9 +4071,8 @@ static struct clk_branch gcc_uniphy2_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy2_port6_rx_clk", @@ -3506,7 +3506,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4233,9 +4085,8 @@ static struct clk_branch gcc_uniphy2_por +@@ -4235,9 +4087,8 @@ static struct clk_branch gcc_uniphy2_por .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_uniphy2_port6_tx_clk", @@ -3518,7 +3518,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4251,9 +4102,8 @@ static struct clk_branch gcc_crypto_ahb_ +@@ -4253,9 +4104,8 @@ static struct clk_branch gcc_crypto_ahb_ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_ahb_clk", @@ -3530,7 +3530,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4269,9 +4119,8 @@ static struct clk_branch gcc_crypto_axi_ +@@ -4271,9 +4121,8 @@ static struct clk_branch gcc_crypto_axi_ .enable_mask = BIT(1), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_axi_clk", @@ -3542,7 +3542,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4287,9 +4136,8 @@ static struct clk_branch gcc_crypto_clk +@@ -4289,9 +4138,8 @@ static struct clk_branch gcc_crypto_clk .enable_mask = BIT(2), .hw.init = &(struct clk_init_data){ .name = "gcc_crypto_clk", @@ -3554,7 +3554,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4304,9 +4152,8 @@ static struct clk_branch gcc_gp1_clk = { +@@ -4306,9 +4154,8 @@ static struct clk_branch gcc_gp1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp1_clk", @@ -3566,7 +3566,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4321,9 +4168,8 @@ static struct clk_branch gcc_gp2_clk = { +@@ -4323,9 +4170,8 @@ static struct clk_branch gcc_gp2_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp2_clk", @@ -3578,7 +3578,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4338,9 +4184,8 @@ static struct clk_branch gcc_gp3_clk = { +@@ -4340,9 +4186,8 @@ static struct clk_branch gcc_gp3_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp3_clk", @@ -3590,7 +3590,7 @@ Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, -@@ -4362,7 +4207,7 @@ static struct clk_rcg2 pcie0_rchng_clk_s +@@ -4364,7 +4209,7 @@ static struct clk_rcg2 pcie0_rchng_clk_s .clkr.hw.init = &(struct clk_init_data){ .name = "pcie0_rchng_clk_src", .parent_data = gcc_xo_gpll0, diff --git a/target/linux/qualcommax/patches-6.1/0010-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch b/target/linux/qualcommax/patches-6.1/0010-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch index 81014ab24..182fbe7f0 100644 --- a/target/linux/qualcommax/patches-6.1/0010-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch +++ b/target/linux/qualcommax/patches-6.1/0010-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch @@ -18,7 +18,7 @@ Link: https://lore.kernel.org/r/20221107132901.489240-3-robimarko@gmail.com --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -4665,6 +4665,20 @@ static const struct qcom_reset_map gcc_i +@@ -4667,6 +4667,20 @@ static const struct qcom_reset_map gcc_i [GCC_PCIE1_AXI_SLAVE_ARES] = { 0x76040, 4 }, [GCC_PCIE1_AHB_ARES] = { 0x76040, 5 }, [GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 }, diff --git a/target/linux/qualcommax/patches-6.1/0011-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch b/target/linux/qualcommax/patches-6.1/0011-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch index 35a0a07c7..a55df15c6 100644 --- a/target/linux/qualcommax/patches-6.1/0011-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch +++ b/target/linux/qualcommax/patches-6.1/0011-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch @@ -22,7 +22,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -674,7 +674,7 @@ static struct clk_rcg2 pcie0_aux_clk_src +@@ -675,7 +675,7 @@ static struct clk_rcg2 pcie0_aux_clk_src }; static const struct clk_parent_data gcc_pcie20_phy0_pipe_clk_xo[] = { @@ -31,7 +31,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com { .fw_name = "xo", .name = "xo" }, }; -@@ -727,7 +727,7 @@ static struct clk_rcg2 pcie1_aux_clk_src +@@ -728,7 +728,7 @@ static struct clk_rcg2 pcie1_aux_clk_src }; static const struct clk_parent_data gcc_pcie20_phy1_pipe_clk_xo[] = { @@ -40,7 +40,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com { .fw_name = "xo", .name = "xo" }, }; -@@ -1131,7 +1131,7 @@ static const struct freq_tbl ftbl_nss_no +@@ -1133,7 +1133,7 @@ static const struct freq_tbl ftbl_nss_no static const struct clk_parent_data gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2[] = { { .fw_name = "xo", .name = "xo" }, @@ -49,7 +49,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com { .hw = &gpll0.clkr.hw }, { .hw = &gpll2.clkr.hw }, }; -@@ -1356,7 +1356,7 @@ static const struct freq_tbl ftbl_nss_pp +@@ -1358,7 +1358,7 @@ static const struct freq_tbl ftbl_nss_pp static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = { { .fw_name = "xo", .name = "xo" }, @@ -58,7 +58,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com { .hw = &gpll0.clkr.hw }, { .hw = &gpll4.clkr.hw }, { .hw = &nss_crypto_pll.clkr.hw }, -@@ -1407,10 +1407,10 @@ static const struct freq_tbl ftbl_nss_po +@@ -1409,10 +1409,10 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, @@ -72,7 +72,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com }; static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = { -@@ -1459,10 +1459,10 @@ static const struct freq_tbl ftbl_nss_po +@@ -1461,10 +1461,10 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, @@ -86,7 +86,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com }; static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = { -@@ -1690,12 +1690,12 @@ static const struct freq_tbl ftbl_nss_po +@@ -1692,12 +1692,12 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, @@ -104,7 +104,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com }; static const struct parent_map -@@ -1752,12 +1752,12 @@ static const struct freq_tbl ftbl_nss_po +@@ -1754,12 +1754,12 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, @@ -122,7 +122,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com }; static const struct parent_map -@@ -1814,10 +1814,10 @@ static const struct freq_tbl ftbl_nss_po +@@ -1816,10 +1816,10 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy2_rx_tx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, @@ -136,7 +136,7 @@ Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com }; static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = { -@@ -1871,10 +1871,10 @@ static const struct freq_tbl ftbl_nss_po +@@ -1873,10 +1873,10 @@ static const struct freq_tbl ftbl_nss_po static const struct clk_parent_data gcc_xo_uniphy2_tx_rx_ubi32_bias[] = { { .fw_name = "xo", .name = "xo" }, diff --git a/target/linux/qualcommax/patches-6.1/0020-v6.3-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch b/target/linux/qualcommax/patches-6.1/0020-v6.3-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch index 3d5c2182e..61e56a7db 100644 --- a/target/linux/qualcommax/patches-6.1/0020-v6.3-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch +++ b/target/linux/qualcommax/patches-6.1/0020-v6.3-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch @@ -16,7 +16,7 @@ Signed-off-by: Bjorn Helgaas --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -1762,6 +1762,7 @@ static const struct of_device_id qcom_pc +@@ -1771,6 +1771,7 @@ static const struct of_device_id qcom_pc { .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 }, { .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 }, { .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 }, diff --git a/target/linux/qualcommax/patches-6.1/0021-v6.3-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch b/target/linux/qualcommax/patches-6.1/0021-v6.3-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch index e0e8125ba..2fe6a1a42 100644 --- a/target/linux/qualcommax/patches-6.1/0021-v6.3-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch +++ b/target/linux/qualcommax/patches-6.1/0021-v6.3-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch @@ -18,7 +18,7 @@ Signed-off-by: Robert Marko --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -928,7 +928,7 @@ static struct clk_rcg2 usb0_mock_utmi_cl +@@ -930,7 +930,7 @@ static struct clk_rcg2 usb0_mock_utmi_cl }; static const struct clk_parent_data gcc_usb3phy_0_cc_pipe_clk_xo[] = { @@ -27,7 +27,7 @@ Signed-off-by: Robert Marko { .fw_name = "xo", .name = "xo" }, }; -@@ -996,7 +996,7 @@ static struct clk_rcg2 usb1_mock_utmi_cl +@@ -998,7 +998,7 @@ static struct clk_rcg2 usb1_mock_utmi_cl }; static const struct clk_parent_data gcc_usb3phy_1_cc_pipe_clk_xo[] = { diff --git a/target/linux/qualcommax/patches-6.1/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch b/target/linux/qualcommax/patches-6.1/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch index 63e2f22db..8f3e28ac2 100644 --- a/target/linux/qualcommax/patches-6.1/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch +++ b/target/linux/qualcommax/patches-6.1/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch @@ -35,7 +35,7 @@ Signed-off-by: Viresh Kumar { .compatible = "qcom,msm8974", }, --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -31,6 +31,8 @@ +@@ -30,6 +30,8 @@ #include @@ -44,7 +44,7 @@ Signed-off-by: Viresh Kumar struct qcom_cpufreq_drv; struct qcom_cpufreq_match_data { -@@ -204,6 +206,57 @@ len_error: +@@ -203,6 +205,57 @@ len_error: return ret; } @@ -102,7 +102,7 @@ Signed-off-by: Viresh Kumar static const struct qcom_cpufreq_match_data match_data_kryo = { .get_version = qcom_cpufreq_kryo_name_version, }; -@@ -218,6 +271,10 @@ static const struct qcom_cpufreq_match_d +@@ -217,6 +270,10 @@ static const struct qcom_cpufreq_match_d .genpd_names = qcs404_genpd_names, }; @@ -113,7 +113,7 @@ Signed-off-by: Viresh Kumar static int qcom_cpufreq_probe(struct platform_device *pdev) { struct qcom_cpufreq_drv *drv; -@@ -362,6 +419,7 @@ static const struct of_device_id qcom_cp +@@ -361,6 +418,7 @@ static const struct of_device_id qcom_cp { .compatible = "qcom,apq8096", .data = &match_data_kryo }, { .compatible = "qcom,msm8996", .data = &match_data_kryo }, { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, diff --git a/target/linux/qualcommax/patches-6.1/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch b/target/linux/qualcommax/patches-6.1/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch index cbd7b770f..245c5c4d5 100644 --- a/target/linux/qualcommax/patches-6.1/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch +++ b/target/linux/qualcommax/patches-6.1/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch @@ -35,7 +35,7 @@ Signed-off-by: Viresh Kumar { .compatible = "qcom,msm8960", }, --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -33,6 +33,11 @@ +@@ -32,6 +32,11 @@ #define IPQ6000_VERSION BIT(2) @@ -47,7 +47,7 @@ Signed-off-by: Viresh Kumar struct qcom_cpufreq_drv; struct qcom_cpufreq_match_data { -@@ -257,6 +262,44 @@ static int qcom_cpufreq_ipq6018_name_ver +@@ -256,6 +261,44 @@ static int qcom_cpufreq_ipq6018_name_ver return 0; } @@ -92,7 +92,7 @@ Signed-off-by: Viresh Kumar static const struct qcom_cpufreq_match_data match_data_kryo = { .get_version = qcom_cpufreq_kryo_name_version, }; -@@ -275,6 +318,10 @@ static const struct qcom_cpufreq_match_d +@@ -274,6 +317,10 @@ static const struct qcom_cpufreq_match_d .get_version = qcom_cpufreq_ipq6018_name_version, }; @@ -103,7 +103,7 @@ Signed-off-by: Viresh Kumar static int qcom_cpufreq_probe(struct platform_device *pdev) { struct qcom_cpufreq_drv *drv; -@@ -421,6 +468,7 @@ static const struct of_device_id qcom_cp +@@ -420,6 +467,7 @@ static const struct of_device_id qcom_cp { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, { .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 }, { .compatible = "qcom,ipq8064", .data = &match_data_krait }, diff --git a/target/linux/qualcommax/patches-6.1/0046-v6.6-clk-qcom-gcc-ipq6018-Use-floor-ops-for-sdcc-clocks.patch b/target/linux/qualcommax/patches-6.1/0046-v6.6-clk-qcom-gcc-ipq6018-Use-floor-ops-for-sdcc-clocks.patch index 9ae72730d..8cd52b818 100644 --- a/target/linux/qualcommax/patches-6.1/0046-v6.6-clk-qcom-gcc-ipq6018-Use-floor-ops-for-sdcc-clocks.patch +++ b/target/linux/qualcommax/patches-6.1/0046-v6.6-clk-qcom-gcc-ipq6018-Use-floor-ops-for-sdcc-clocks.patch @@ -16,7 +16,7 @@ Link: https://lore.kernel.org/r/1682413909-24927-1-git-send-email-mantas@8device --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c -@@ -1702,7 +1702,7 @@ static struct clk_rcg2 usb0_mock_utmi_cl +@@ -1703,7 +1703,7 @@ static struct clk_rcg2 usb0_mock_utmi_cl .name = "usb0_mock_utmi_clk_src", .parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2, .num_parents = 4, diff --git a/target/linux/qualcommax/patches-6.1/0048-v6.6-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch b/target/linux/qualcommax/patches-6.1/0048-v6.6-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch index e38b40278..f7326069b 100644 --- a/target/linux/qualcommax/patches-6.1/0048-v6.6-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch +++ b/target/linux/qualcommax/patches-6.1/0048-v6.6-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch @@ -15,7 +15,7 @@ Link: https://lore.kernel.org/r/20230526190855.2941291-1-robimarko@gmail.com --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c -@@ -4143,15 +4143,20 @@ static struct clk_branch gcc_dcc_clk = { +@@ -4145,15 +4145,20 @@ static struct clk_branch gcc_dcc_clk = { static const struct alpha_pll_config ubi32_pll_config = { .l = 0x3e, diff --git a/target/linux/qualcommax/patches-6.1/0049-v6.6-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch b/target/linux/qualcommax/patches-6.1/0049-v6.6-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch index e4faac1b6..396558b4a 100644 --- a/target/linux/qualcommax/patches-6.1/0049-v6.6-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch +++ b/target/linux/qualcommax/patches-6.1/0049-v6.6-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch @@ -27,7 +27,7 @@ Link: https://lore.kernel.org/r/20230601213416.3373599-1-arnd@kernel.org --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c -@@ -4144,8 +4144,6 @@ static struct clk_branch gcc_dcc_clk = { +@@ -4146,8 +4146,6 @@ static struct clk_branch gcc_dcc_clk = { static const struct alpha_pll_config ubi32_pll_config = { .l = 0x3e, .alpha = 0x6667, diff --git a/target/linux/qualcommax/patches-6.1/0053-v6.7-clk-qcom-gcc-ipq6018-add-QUP6-I2C-clock.patch b/target/linux/qualcommax/patches-6.1/0053-v6.7-clk-qcom-gcc-ipq6018-add-QUP6-I2C-clock.patch index 085852893..0c1576c4f 100644 --- a/target/linux/qualcommax/patches-6.1/0053-v6.7-clk-qcom-gcc-ipq6018-add-QUP6-I2C-clock.patch +++ b/target/linux/qualcommax/patches-6.1/0053-v6.7-clk-qcom-gcc-ipq6018-add-QUP6-I2C-clock.patch @@ -20,7 +20,7 @@ Signed-off-by: Bjorn Andersson --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c -@@ -2120,6 +2120,26 @@ static struct clk_branch gcc_blsp1_qup5_ +@@ -2122,6 +2122,26 @@ static struct clk_branch gcc_blsp1_qup5_ }, }; @@ -47,7 +47,7 @@ Signed-off-by: Bjorn Andersson static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { .halt_reg = 0x0700c, .clkr = { -@@ -4276,6 +4296,7 @@ static struct clk_regmap *gcc_ipq6018_cl +@@ -4278,6 +4298,7 @@ static struct clk_regmap *gcc_ipq6018_cl [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, diff --git a/target/linux/qualcommax/patches-6.1/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch b/target/linux/qualcommax/patches-6.1/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch index 62a30bbb2..1cd614761 100644 --- a/target/linux/qualcommax/patches-6.1/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch +++ b/target/linux/qualcommax/patches-6.1/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch @@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -1676,13 +1676,21 @@ static struct clk_regmap_div nss_port4_t +@@ -1678,13 +1678,21 @@ static struct clk_regmap_div nss_port4_t }, }; @@ -49,7 +49,7 @@ Signed-off-by: Christian Marangi F(156250000, P_UNIPHY1_RX, 2, 0, 0), F(312500000, P_UNIPHY1_RX, 1, 0, 0), { } -@@ -1738,13 +1746,21 @@ static struct clk_regmap_div nss_port5_r +@@ -1740,13 +1748,21 @@ static struct clk_regmap_div nss_port5_r }, }; @@ -75,7 +75,7 @@ Signed-off-by: Christian Marangi F(156250000, P_UNIPHY1_TX, 2, 0, 0), F(312500000, P_UNIPHY1_TX, 1, 0, 0), { } -@@ -1800,13 +1816,21 @@ static struct clk_regmap_div nss_port5_t +@@ -1802,13 +1818,21 @@ static struct clk_regmap_div nss_port5_t }, }; @@ -101,7 +101,7 @@ Signed-off-by: Christian Marangi F(156250000, P_UNIPHY2_RX, 2, 0, 0), F(312500000, P_UNIPHY2_RX, 1, 0, 0), { } -@@ -1857,13 +1881,21 @@ static struct clk_regmap_div nss_port6_r +@@ -1859,13 +1883,21 @@ static struct clk_regmap_div nss_port6_r }, }; diff --git a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch index 3996d15d9..8fe58e798 100644 --- a/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.1/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch @@ -23,7 +23,7 @@ Signed-off-by: Robert Marko #size-cells = <2>; ranges; -+ nss@40000000 { ++ nss_region: nss@40000000 { + no-map; + reg = <0x0 0x40000000 0x0 0x01000000>; + }; diff --git a/target/linux/qualcommax/patches-6.1/0118-clk-qcom-Add-WCSSAON-reset.patch b/target/linux/qualcommax/patches-6.1/0118-clk-qcom-Add-WCSSAON-reset.patch index be0524338..ec366fd42 100644 --- a/target/linux/qualcommax/patches-6.1/0118-clk-qcom-Add-WCSSAON-reset.patch +++ b/target/linux/qualcommax/patches-6.1/0118-clk-qcom-Add-WCSSAON-reset.patch @@ -15,7 +15,7 @@ Acked-by: Stephen Boyd --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -4711,6 +4711,7 @@ static const struct qcom_reset_map gcc_i +@@ -4713,6 +4713,7 @@ static const struct qcom_reset_map gcc_i [GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | GENMASK(9, 8) }, [GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | GENMASK(11, 10) }, [GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | GENMASK(13, 12) }, diff --git a/target/linux/qualcommax/patches-6.1/0133-arm64-dts-ipq6018-add-reserved-memory-nodes.patch b/target/linux/qualcommax/patches-6.1/0133-arm64-dts-ipq6018-add-reserved-memory-nodes.patch index 5ec7ec9ce..b6790f02e 100644 --- a/target/linux/qualcommax/patches-6.1/0133-arm64-dts-ipq6018-add-reserved-memory-nodes.patch +++ b/target/linux/qualcommax/patches-6.1/0133-arm64-dts-ipq6018-add-reserved-memory-nodes.patch @@ -1,10 +1,15 @@ --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -212,6 +212,16 @@ +@@ -212,6 +212,21 @@ reg = <0x0 0x4ab00000 0x0 0x5500000>; no-map; }; + ++ nss_region: nss@40000000 { ++ no-map; ++ reg = <0x0 0x40000000 0x0 0x01000000>; ++ }; ++ + q6_etr_region: q6_etr_dump@50000000 { + reg = <0x0 0x50000000 0x0 0x100000>; + no-map; diff --git a/target/linux/qualcommax/patches-6.1/0134-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch b/target/linux/qualcommax/patches-6.1/0134-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch deleted file mode 100644 index dfcce21e8..000000000 --- a/target/linux/qualcommax/patches-6.1/0134-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -173,6 +173,12 @@ - regulator-max-microvolt = <1062500>; - regulator-always-on; - }; -+ -+ ipq6018_l2: l2 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; - }; - }; - }; diff --git a/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-enable-sdhci-node.patch b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-enable-sdhci-node.patch index c9b6e9e13..8a2ed48d0 100644 --- a/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-enable-sdhci-node.patch +++ b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-enable-sdhci-node.patch @@ -1,6 +1,6 @@ --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -477,6 +477,26 @@ +@@ -476,6 +476,26 @@ }; }; diff --git a/target/linux/qualcommax/patches-6.1/0136-arm64-dts-qcom-ipq6018-add-thermal-nodes.patch b/target/linux/qualcommax/patches-6.1/0136-arm64-dts-qcom-ipq6018-add-thermal-nodes.patch index b5b994559..14d0c3044 100644 --- a/target/linux/qualcommax/patches-6.1/0136-arm64-dts-qcom-ipq6018-add-thermal-nodes.patch +++ b/target/linux/qualcommax/patches-6.1/0136-arm64-dts-qcom-ipq6018-add-thermal-nodes.patch @@ -13,7 +13,7 @@ Signed-off-by: Robert Marko --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -358,6 +358,16 @@ +@@ -357,6 +357,16 @@ clock-names = "core"; }; @@ -30,7 +30,7 @@ Signed-off-by: Robert Marko cryptobam: dma-controller@704000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0 0x00704000 0x0 0x20000>; -@@ -1043,6 +1053,113 @@ +@@ -1042,6 +1052,113 @@ }; }; diff --git a/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-rework-cpufreq.patch b/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-rework-cpufreq.patch index 540dbb3ce..667fdce2c 100644 --- a/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-rework-cpufreq.patch +++ b/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-rework-cpufreq.patch @@ -1,184 +1,55 @@ --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -41,8 +41,6 @@ - next-level-cache = <&L2_0>; +@@ -42,7 +42,6 @@ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; clock-names = "cpu"; -- operating-points-v2 = <&cpu_opp_table>; + operating-points-v2 = <&cpu_opp_table>; - cpu-supply = <&ipq6018_s2>; }; CPU1: cpu@1 { -@@ -53,8 +51,6 @@ - next-level-cache = <&L2_0>; +@@ -54,7 +53,6 @@ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; clock-names = "cpu"; -- operating-points-v2 = <&cpu_opp_table>; + operating-points-v2 = <&cpu_opp_table>; - cpu-supply = <&ipq6018_s2>; }; CPU2: cpu@2 { -@@ -65,8 +61,6 @@ - next-level-cache = <&L2_0>; +@@ -66,7 +64,6 @@ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; clock-names = "cpu"; -- operating-points-v2 = <&cpu_opp_table>; + operating-points-v2 = <&cpu_opp_table>; - cpu-supply = <&ipq6018_s2>; }; CPU3: cpu@3 { -@@ -77,8 +71,6 @@ - next-level-cache = <&L2_0>; +@@ -78,7 +75,6 @@ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; clock-names = "cpu"; -- operating-points-v2 = <&cpu_opp_table>; + operating-points-v2 = <&cpu_opp_table>; - cpu-supply = <&ipq6018_s2>; }; L2_0: l2-cache { -@@ -94,54 +86,6 @@ +@@ -113,6 +109,13 @@ + clock-latency-ns = <200000>; }; - }; -- cpu_opp_table: opp-table-cpu { -- compatible = "operating-points-v2-kryo-cpu"; -- nvmem-cells = <&cpu_speed_bin>; -- opp-shared; -- -- opp-864000000 { -- opp-hz = /bits/ 64 <864000000>; -- opp-microvolt = <725000>; -- opp-supported-hw = <0xf>; -- clock-latency-ns = <200000>; -- }; -- -- opp-1056000000 { -- opp-hz = /bits/ 64 <1056000000>; -- opp-microvolt = <787500>; -- opp-supported-hw = <0xf>; -- clock-latency-ns = <200000>; -- }; -- -- opp-1320000000 { -- opp-hz = /bits/ 64 <1320000000>; -- opp-microvolt = <862500>; -- opp-supported-hw = <0x3>; -- clock-latency-ns = <200000>; -- }; -- -- opp-1440000000 { -- opp-hz = /bits/ 64 <1440000000>; -- opp-microvolt = <925000>; -- opp-supported-hw = <0x3>; -- clock-latency-ns = <200000>; -- }; -- -- opp-1608000000 { -- opp-hz = /bits/ 64 <1608000000>; -- opp-microvolt = <987500>; -- opp-supported-hw = <0x1>; -- clock-latency-ns = <200000>; -- }; -- -- opp-1800000000 { -- opp-hz = /bits/ 64 <1800000000>; -- opp-microvolt = <1062500>; -- opp-supported-hw = <0x1>; -- clock-latency-ns = <200000>; -- }; -- }; -- - pmuv8: pmu { - compatible = "arm,cortex-a53-pmu"; - interrupts = ; ---- /dev/null -+++ b/arch/arm64/boot/dts/qcom/ipq6000-opp.dtsi -@@ -0,0 +1,46 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/ { -+ cpu_opp_table: opp-table-cpu { -+ compatible = "operating-points-v2-kryo-cpu"; -+ nvmem-cells = <&cpu_speed_bin>; -+ opp-shared; -+ -+ opp-864000000 { -+ opp-hz = /bits/ 64 <864000000>; -+ opp-microvolt = <725000>; -+ opp-supported-hw = <0xf>; -+ clock-latency-ns = <200000>; -+ }; -+ -+ opp-1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <787500>; -+ opp-supported-hw = <0xf>; -+ clock-latency-ns = <200000>; -+ }; -+ + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <850000>; + opp-supported-hw = <0x4>; + clock-latency-ns = <200000>; + }; -+ }; -+}; -+ -+&CPU0 { -+ operating-points-v2 = <&cpu_opp_table>; -+}; -+ -+&CPU1 { -+ operating-points-v2 = <&cpu_opp_table>; -+}; -+ -+&CPU2 { -+ operating-points-v2 = <&cpu_opp_table>; -+}; -+ -+&CPU3 { -+ operating-points-v2 = <&cpu_opp_table>; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/qcom/ipq6018-opp.dtsi -@@ -0,0 +1,78 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/ { -+ cpu_opp_table: opp-table-cpu { -+ compatible = "operating-points-v2-kryo-cpu"; -+ nvmem-cells = <&cpu_speed_bin>; -+ opp-shared; -+ -+ opp-864000000 { -+ opp-hz = /bits/ 64 <864000000>; -+ opp-microvolt = <725000>; -+ opp-supported-hw = <0xf>; -+ clock-latency-ns = <200000>; -+ }; -+ -+ opp-1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <787500>; -+ opp-supported-hw = <0xf>; -+ clock-latency-ns = <200000>; -+ }; -+ -+ opp-1320000000 { -+ opp-hz = /bits/ 64 <1320000000>; -+ opp-microvolt = <862500>; -+ opp-supported-hw = <0x3>; -+ clock-latency-ns = <200000>; -+ }; -+ -+ opp-1440000000 { -+ opp-hz = /bits/ 64 <1440000000>; -+ opp-microvolt = <925000>; -+ opp-supported-hw = <0x3>; -+ clock-latency-ns = <200000>; -+ }; + + opp-1320000000 { + opp-hz = /bits/ 64 <1320000000>; + opp-microvolt = <862500>; +@@ -127,6 +130,13 @@ + clock-latency-ns = <200000>; + }; + + opp-1512000000 { + opp-hz = /bits/ 64 <1512000000>; + opp-microvolt = <937500>; @@ -186,38 +57,65 @@ + clock-latency-ns = <200000>; + }; + -+ opp-1608000000 { -+ opp-hz = /bits/ 64 <1608000000>; -+ opp-microvolt = <987500>; -+ opp-supported-hw = <0x1>; -+ clock-latency-ns = <200000>; + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <987500>; +@@ -164,16 +174,6 @@ + rpm_requests: rpm-requests { + compatible = "qcom,rpm-ipq6018"; + qcom,glink-channels = "rpm_requests"; +- +- regulators { +- compatible = "qcom,rpm-mp5496-regulators"; +- +- ipq6018_s2: s2 { +- regulator-min-microvolt = <725000>; +- regulator-max-microvolt = <1062500>; +- regulator-always-on; +- }; +- }; + }; + }; + }; +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/ipq6018-mp5496.dtsi +@@ -0,0 +1,39 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++&rpm_requests { ++ regulators { ++ compatible = "qcom,rpm-mp5496-regulators"; ++ ++ ipq6018_s2: s2 { ++ regulator-min-microvolt = <725000>; ++ regulator-max-microvolt = <1062500>; ++ regulator-always-on; + }; + -+ opp-1800000000 { -+ opp-hz = /bits/ 64 <1800000000>; -+ opp-microvolt = <1062500>; -+ opp-supported-hw = <0x1>; -+ clock-latency-ns = <200000>; ++ ipq6018_l2: l2 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; + }; + }; +}; + ++&sdhc { ++ vqmmc-supply = <&ipq6018_l2>; ++}; ++ +&CPU0 { -+ operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; +}; + +&CPU1 { -+ operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; +}; + +&CPU2 { -+ operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; +}; + +&CPU3 { -+ operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; +}; diff --git a/target/linux/qualcommax/patches-6.1/0139-clk-ipq6018-Add-missing-clocks.patch b/target/linux/qualcommax/patches-6.1/0139-clk-ipq6018-Add-missing-clocks.patch index 1d092e7ca..bac6be098 100644 --- a/target/linux/qualcommax/patches-6.1/0139-clk-ipq6018-Add-missing-clocks.patch +++ b/target/linux/qualcommax/patches-6.1/0139-clk-ipq6018-Add-missing-clocks.patch @@ -51,7 +51,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { F(24000000, P_XO, 1, 0, 0), F(25000000, P_GPLL0_DIV2, 16, 0, 0), -@@ -1891,6 +1917,19 @@ static struct clk_rcg2 system_noc_bfdcd_ +@@ -1893,6 +1919,19 @@ static struct clk_rcg2 system_noc_bfdcd_ }, }; @@ -71,7 +71,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static const struct freq_tbl ftbl_ubi32_mem_noc_bfdcd_clk_src[] = { F(24000000, P_XO, 1, 0, 0), F(307670000, P_BIAS_PLL_NSS_NOC, 1.5, 0, 0), -@@ -1926,6 +1965,19 @@ static struct clk_rcg2 ubi32_mem_noc_bfd +@@ -1928,6 +1967,19 @@ static struct clk_rcg2 ubi32_mem_noc_bfd }, }; @@ -91,7 +91,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static struct clk_branch gcc_apss_axi_clk = { .halt_reg = 0x46020, .halt_check = BRANCH_HALT_VOTED, -@@ -2683,6 +2735,454 @@ static struct clk_rcg2 lpass_q6_axim_clk +@@ -2685,6 +2737,454 @@ static struct clk_rcg2 lpass_q6_axim_clk }, }; @@ -546,7 +546,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static struct freq_tbl ftbl_rbcpr_wcss_clk_src[] = { F(24000000, P_XO, 1, 0, 0), F(50000000, P_GPLL0, 16, 0, 0), -@@ -2702,6 +3202,22 @@ static struct clk_rcg2 rbcpr_wcss_clk_sr +@@ -2704,6 +3204,22 @@ static struct clk_rcg2 rbcpr_wcss_clk_sr }, }; @@ -569,7 +569,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static struct clk_branch gcc_lpass_core_axim_clk = { .halt_reg = 0x1F028, .clkr = { -@@ -3523,6 +4039,22 @@ static struct clk_branch gcc_prng_ahb_cl +@@ -3525,6 +4041,22 @@ static struct clk_branch gcc_prng_ahb_cl }, }; @@ -592,7 +592,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 static struct clk_branch gcc_qdss_dap_clk = { .halt_reg = 0x29084, .clkr = { -@@ -3533,7 +4065,7 @@ static struct clk_branch gcc_qdss_dap_cl +@@ -3535,7 +4067,7 @@ static struct clk_branch gcc_qdss_dap_cl .parent_hws = (const struct clk_hw *[]){ &qdss_dap_sync_clk_src.hw }, .num_parents = 1, @@ -601,7 +601,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 .ops = &clk_branch2_ops, }, }, -@@ -4199,6 +4731,9 @@ static struct clk_hw *gcc_ipq6018_hws[] +@@ -4201,6 +4733,9 @@ static struct clk_hw *gcc_ipq6018_hws[] &gpll6_out_main_div2.hw, &qdss_dap_sync_clk_src.hw, &qdss_tsctr_div2_clk_src.hw, @@ -611,7 +611,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 }; static struct clk_regmap *gcc_ipq6018_clks[] = { -@@ -4362,6 +4897,7 @@ static struct clk_regmap *gcc_ipq6018_cl +@@ -4364,6 +4899,7 @@ static struct clk_regmap *gcc_ipq6018_cl [GCC_SYS_NOC_PCIE0_AXI_CLK] = &gcc_sys_noc_pcie0_axi_clk.clkr, [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr, [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, @@ -619,7 +619,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, -@@ -4403,9 +4939,35 @@ static struct clk_regmap *gcc_ipq6018_cl +@@ -4405,9 +4941,35 @@ static struct clk_regmap *gcc_ipq6018_cl [PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr, [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, [PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, @@ -655,7 +655,7 @@ Change-Id: I85bb1c127a4794ae9347d5babbbfd6490f6abcc7 [GCC_LPASS_CORE_AXIM_CLK] = &gcc_lpass_core_axim_clk.clkr, [LPASS_CORE_AXIM_CLK_SRC] = &lpass_core_axim_clk_src.clkr, [GCC_LPASS_SNOC_CFG_CLK] = &gcc_lpass_snoc_cfg_clk.clkr, -@@ -4421,6 +4983,9 @@ static struct clk_regmap *gcc_ipq6018_cl +@@ -4423,6 +4985,9 @@ static struct clk_regmap *gcc_ipq6018_cl [GCC_MEM_NOC_UBI32_CLK] = &gcc_mem_noc_ubi32_clk.clkr, [GCC_MEM_NOC_LPASS_CLK] = &gcc_mem_noc_lpass_clk.clkr, [GCC_SNOC_LPASS_CFG_CLK] = &gcc_snoc_lpass_cfg_clk.clkr, diff --git a/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch new file mode 100644 index 000000000..b2b3575b7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-1-qca-nss-ecm-support-CORE.patch @@ -0,0 +1,781 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -70,6 +70,9 @@ void brioctl_set(int (*hook)(struct net + void __user *uarg)); + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, + struct ifreq *ifr, void __user *uarg); ++/* extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); */ ++extern bool br_is_hairpin_enabled(struct net_device *dev); + + extern void br_dev_update_stats(struct net_device *dev, + struct rtnl_link_stats64 *nlstats); +@@ -215,4 +218,42 @@ static inline clock_t br_get_ageing_time + } + #endif + ++/* QCA NSS ECM support - Start */ ++extern struct net_device *br_port_dev_get(struct net_device *dev, ++ unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie); ++extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr); ++extern void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid); ++extern struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, ++ __u16 vid); ++extern void br_fdb_update_register_notify(struct notifier_block *nb); ++extern void br_fdb_update_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_port_dev_get_hook_t(struct net_device *dev, ++ struct sk_buff *skb, ++ unsigned char *addr, ++ unsigned int cookie); ++extern br_port_dev_get_hook_t __rcu *br_port_dev_get_hook; ++ ++#define BR_FDB_EVENT_ADD 0x01 ++#define BR_FDB_EVENT_DEL 0x02 ++ ++struct br_fdb_event { ++ struct net_device *dev; ++ unsigned char addr[6]; ++ unsigned char is_local; ++ struct net_bridge *br; ++ struct net_device *orig_dev; ++}; ++extern void br_fdb_register_notify(struct notifier_block *nb); ++extern void br_fdb_unregister_notify(struct notifier_block *nb); ++ ++typedef struct net_bridge_port *br_get_dst_hook_t( ++ const struct net_bridge_port *src, ++ struct sk_buff **skb); ++extern br_get_dst_hook_t __rcu *br_get_dst_hook; ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -235,7 +235,28 @@ extern void vlan_vids_del_by_dev(struct + + extern bool vlan_uses_dev(const struct net_device *dev); + ++/* QCA NSS ECM support - Start */ ++extern void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); ++extern u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio); ++extern struct net_device *vlan_dev_next_dev(const struct net_device *dev); ++/* QCA NSS ECM support - End */ ++ + #else ++/* QCA NSS ECM support - Start */ ++static inline void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *stats) ++{ ++ ++} ++ ++static inline u16 vlan_dev_get_egress_prio(struct net_device *dev, ++ u32 skb_prio) ++{ ++ return 0; ++} ++/* QCA NSS ECM support - End */ ++ + static inline struct net_device * + __vlan_find_dev_deep_rcu(struct net_device *real_dev, + __be16 vlan_proto, u16 vlan_id) +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2831,6 +2831,10 @@ enum netdev_cmd { + NETDEV_OFFLOAD_XSTATS_DISABLE, + NETDEV_OFFLOAD_XSTATS_REPORT_USED, + NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, ++ /* QCA NSS ECM Support - Start */ ++ NETDEV_BR_JOIN, ++ NETDEV_BR_LEAVE, ++ /* QCA NSS ECM Support - End */ + }; + const char *netdev_cmd_to_name(enum netdev_cmd cmd); + +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -518,4 +518,9 @@ int if6_proc_init(void); + void if6_proc_exit(void); + #endif + ++/* QCA NSS ECM support - Start */ ++struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, ++ int strict); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -211,6 +211,11 @@ void rt6_multipath_rebalance(struct fib6 + void rt6_uncached_list_add(struct rt6_info *rt); + void rt6_uncached_list_del(struct rt6_info *rt); + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb); ++int rt6_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) + { + const struct dst_entry *dst = skb_dst(skb); +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -602,4 +602,15 @@ static inline void neigh_update_is_route + *notify = 1; + } + } ++ ++/* QCA NSS ECM support - Start */ ++struct neigh_mac_update { ++ unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++ unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ++}; ++ ++extern void neigh_mac_update_register_notify(struct notifier_block *nb); ++extern void neigh_mac_update_unregister_notify(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -240,6 +240,11 @@ struct rtable *rt_dst_alloc(struct net_d + unsigned int flags, u16 type, bool noxfrm); + struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb); ++int ip_rt_unregister_notifier(struct notifier_block *nb); ++/* QCA NSS ECM support - End */ ++ + struct in_ifaddr; + void fib_add_ifaddr(struct in_ifaddr *); + void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -2193,4 +2193,9 @@ void br_do_proxy_suppress_arp(struct sk_ + void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br, + u16 vid, struct net_bridge_port *p, struct nd_msg *msg); + struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m); ++ ++/* QCA NSS ECM support - Start */ ++#define __br_get(__hook, __default, __args ...) \ ++ (__hook ? (__hook(__args)) : (__default)) ++/* QCA NSS ECM support - End */ + #endif +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -555,4 +555,52 @@ static int __init vlan_offload_init(void + return 0; + } + ++/* QCA NSS ECM support - Start */ ++/* Update the VLAN device with statistics from network offload engines */ ++void __vlan_dev_update_accel_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct vlan_pcpu_stats *stats; ++ ++ if (!is_vlan_dev(dev)) ++ return; ++ ++ stats = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, 0); ++ ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL(__vlan_dev_update_accel_stats); ++ ++/* Lookup the 802.1p egress_map table and return the 802.1p value */ ++u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio) ++{ ++ struct vlan_priority_tci_mapping *mp; ++ ++ mp = vlan_dev_priv(dev)->egress_priority_map[(skb_prio & 0xf)]; ++ while (mp) { ++ if (mp->priority == skb_prio) { ++ /* This should already be shifted ++ * to mask correctly with the ++ * VLAN's TCI ++ */ ++ return mp->vlan_qos; ++ } ++ mp = mp->next; ++ } ++ return 0; ++} ++EXPORT_SYMBOL(vlan_dev_get_egress_prio); ++ ++struct net_device *vlan_dev_next_dev(const struct net_device *dev) ++{ ++ return vlan_dev_priv(dev)->real_dev; ++} ++EXPORT_SYMBOL(vlan_dev_next_dev); ++/* QCA NSS ECM support - End */ ++ + fs_initcall(vlan_offload_init); +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -34,6 +34,35 @@ static const struct rhashtable_params br + + static struct kmem_cache *br_fdb_cache __read_mostly; + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list); ++ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list); ++ ++void br_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_register_notify); ++ ++void br_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_unregister_notify); ++ ++void br_fdb_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_register_notify); ++ ++void br_fdb_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -188,7 +217,26 @@ static void fdb_notify(struct net_bridge + + br_offload_fdb_update(fdb); + +- if (swdev_notify) ++ /* QCA NSS ECM support - Start */ ++ if (fdb->dst) { ++ int event; ++ struct br_fdb_event fdb_event; ++ ++ if (type == RTM_NEWNEIGH) ++ event = BR_FDB_EVENT_ADD; ++ else ++ event = BR_FDB_EVENT_DEL; ++ ++ fdb_event.dev = fdb->dst->dev; ++ ether_addr_copy(fdb_event.addr, fdb->key.addr.addr); ++ fdb_event.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags); ++ atomic_notifier_call_chain(&br_fdb_notifier_list, ++ event, ++ (void *)&fdb_event); ++ } ++ /* QCA NSS ECM support - End */ ++ ++ if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); + + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); +@@ -525,6 +573,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; ++ u8 mac_addr[6]; /* QCA NSS ECM support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -551,8 +600,15 @@ void br_fdb_cleanup(struct work_struct * + work_delay = min(work_delay, this_timer - now); + } else { + spin_lock_bh(&br->hash_lock); +- if (!hlist_unhashed(&f->fdb_node)) ++ if (!hlist_unhashed(&f->fdb_node)) { ++ ether_addr_copy(mac_addr, f->key.addr.addr); + fdb_delete(br, f, true); ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, 0, ++ (void *)mac_addr); ++ /* QCA NSS ECM support - End */ ++ } + spin_unlock_bh(&br->hash_lock); + } + } +@@ -884,6 +940,12 @@ void br_fdb_update(struct net_bridge *br + &fdb->flags))) + clear_bit(BR_FDB_ADDED_BY_EXT_LEARN, + &fdb->flags); ++ ++ /* QCA NSS ECM support - Start */ ++ atomic_notifier_call_chain( ++ &br_fdb_update_notifier_list, ++ 0, (void *)addr); ++ /* QCA NSS ECM support - End */ + } + + if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) +@@ -1471,3 +1533,62 @@ void br_fdb_clear_offload(const struct n + spin_unlock_bh(&p->br->hash_lock); + } + EXPORT_SYMBOL_GPL(br_fdb_clear_offload); ++ ++/* QCA NSS ECM support - Start */ ++/* Refresh FDB entries for bridge packets being forwarded by offload engines */ ++void br_refresh_fdb_entry(struct net_device *dev, const char *addr) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ if (!is_valid_ether_addr(addr)) { ++ pr_info("bridge: Attempt to refresh with invalid ether address %pM\n", ++ addr); ++ return; ++ } ++ ++ rcu_read_lock(); ++ br_fdb_update(p->br, p, addr, 0, true); ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_refresh_fdb_entry); ++ ++/* Update timestamp of FDB entries for bridge packets being forwarded by offload engines */ ++void br_fdb_entry_refresh(struct net_device *dev, const char *addr, __u16 vid) ++{ ++ struct net_bridge_fdb_entry *fdb; ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ if (likely(fdb)) { ++ fdb->updated = jiffies; ++ } ++ rcu_read_unlock(); ++} ++EXPORT_SYMBOL_GPL(br_fdb_entry_refresh); ++ ++/* Look up the MAC address in the device's bridge fdb table */ ++struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev, ++ const char *addr, __u16 vid) ++{ ++ struct net_bridge_port *p = br_port_get_rcu(dev); ++ struct net_bridge_fdb_entry *fdb; ++ ++ if (!p || p->state == BR_STATE_DISABLED) ++ return NULL; ++ ++ rcu_read_lock(); ++ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid); ++ rcu_read_unlock(); ++ ++ return fdb; ++} ++EXPORT_SYMBOL_GPL(br_fdb_has_entry); ++/* QCA NSS ECM support - End */ ++ +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -27,6 +27,12 @@ + #include "br_private.h" + #include "br_private_offload.h" + ++/* QCA NSS ECM support - Start */ ++/* Hook for external forwarding logic */ ++br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly; ++EXPORT_SYMBOL_GPL(br_port_dev_get_hook); ++/* QCA NSS ECM support - End */ ++ + /* + * Determine initial path cost based on speed. + * using recommendations from 802.1d standard +@@ -698,6 +704,8 @@ int br_add_if(struct net_bridge *br, str + + kobject_uevent(&p->kobj, KOBJ_ADD); + ++ call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */ ++ + return 0; + + err6: +@@ -733,6 +741,8 @@ int br_del_if(struct net_bridge *br, str + if (!p || p->br != br) + return -EINVAL; + ++ call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */ ++ + /* Since more than one interface can be attached to a bridge, + * there still maybe an alternate path for netconsole to use; + * therefore there is no reason for a NETDEV_RELEASE event. +@@ -801,3 +811,96 @@ bool br_port_flag_is_set(const struct ne + return p->flags & flag; + } + EXPORT_SYMBOL_GPL(br_port_flag_is_set); ++ ++/* QCA NSS ECM support - Start */ ++/* API to know if hairpin feature is enabled/disabled on this bridge port */ ++bool br_is_hairpin_enabled(struct net_device *dev) ++{ ++ struct net_bridge_port *port = br_port_get_check_rcu(dev); ++ ++ if (likely(port)) ++ return port->flags & BR_HAIRPIN_MODE; ++ return false; ++} ++EXPORT_SYMBOL_GPL(br_is_hairpin_enabled); ++ ++/* br_port_dev_get() ++ * If a skb is provided, and the br_port_dev_get_hook_t hook exists, ++ * use that to try and determine the egress port for that skb. ++ * If not, or no egress port could be determined, use the given addr ++ * to identify the port to which it is reachable, ++ * returing a reference to the net device associated with that port. ++ * ++ * NOTE: Return NULL if given dev is not a bridge or the mac has no ++ * associated port. ++ */ ++struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr, ++ struct sk_buff *skb, ++ unsigned int cookie) ++{ ++ struct net_bridge_fdb_entry *fdbe; ++ struct net_bridge *br; ++ struct net_device *netdev = NULL; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return NULL; ++ ++ rcu_read_lock(); ++ ++ /* If the hook exists and the skb isn't NULL, try and get the port */ ++ if (skb) { ++ br_port_dev_get_hook_t *port_dev_get_hook; ++ ++ port_dev_get_hook = rcu_dereference(br_port_dev_get_hook); ++ if (port_dev_get_hook) { ++ struct net_bridge_port *pdst = ++ __br_get(port_dev_get_hook, NULL, dev, skb, ++ addr, cookie); ++ if (pdst) { ++ dev_hold(pdst->dev); ++ netdev = pdst->dev; ++ goto out; ++ } ++ } ++ } ++ ++ /* Either there is no hook, or can't ++ * determine the port to use - fall back to using FDB ++ */ ++ ++ br = netdev_priv(dev); ++ ++ /* Lookup the fdb entry and get reference to the port dev */ ++ fdbe = br_fdb_find_rcu(br, addr, 0); ++ if (fdbe && fdbe->dst) { ++ netdev = fdbe->dst->dev; /* port device */ ++ dev_hold(netdev); ++ } ++out: ++ rcu_read_unlock(); ++ return netdev; ++} ++EXPORT_SYMBOL_GPL(br_port_dev_get); ++ ++/* Update bridge statistics for bridge packets processed by offload engines */ ++/* void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct pcpu_sw_netstats *tstats; ++ ++ // Is this a bridge? ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ tstats = this_cpu_ptr(dev->tstats); ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->rx_packets, nlstats->rx_packets); ++ u64_stats_add(&tstats->rx_bytes, nlstats->rx_bytes); ++ u64_stats_add(&tstats->tx_packets, nlstats->tx_packets); ++ u64_stats_add(&tstats->tx_bytes, nlstats->tx_bytes); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); */ ++/* QCA NSS ECM support - End */ +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1275,6 +1275,22 @@ static void neigh_update_hhs(struct neig + } + } + ++/* QCA NSS ECM support - Start */ ++ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); ++ ++void neigh_mac_update_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify); ++ ++void neigh_mac_update_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify); ++/* QCA NSS ECM support - End */ ++ + /* Generic update routine. + -- lladdr is new lladdr or NULL, if it is not supplied. + -- new is new state. +@@ -1303,6 +1319,7 @@ static int __neigh_update(struct neighbo + struct net_device *dev; + int err, notify = 0; + u8 old; ++ struct neigh_mac_update nmu; /* QCA NSS ECM support */ + + trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid); + +@@ -1317,6 +1334,9 @@ static int __neigh_update(struct neighbo + new = old; + goto out; + } ++ ++ memset(&nmu, 0, sizeof(struct neigh_mac_update)); /* QCA NSS ECM support */ ++ + if (!(flags & NEIGH_UPDATE_F_ADMIN) && + (old & (NUD_NOARP | NUD_PERMANENT))) + goto out; +@@ -1354,6 +1374,11 @@ static int __neigh_update(struct neighbo + - compare new & old + - if they are different, check override flag + */ ++ /* QCA NSS ECM update - Start */ ++ memcpy(nmu.old_mac, neigh->ha, dev->addr_len); ++ memcpy(nmu.update_mac, lladdr, dev->addr_len); ++ /* QCA NSS ECM update - End */ ++ + if ((old & NUD_VALID) && + !memcmp(lladdr, neigh->ha, dev->addr_len)) + lladdr = neigh->ha; +@@ -1476,8 +1501,11 @@ out: + neigh_update_gc_list(neigh); + if (managed_update) + neigh_update_managed_list(neigh); +- if (notify) ++ if (notify) { + neigh_update_notify(neigh, nlmsg_pid); ++ atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0, ++ (struct neigh_mac_update *)&nmu); /* QCA NSS ECM support */ ++ } + trace_neigh_update_done(neigh, err); + return err; + } +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1211,6 +1211,9 @@ static bool fib_valid_key_len(u32 key, u + static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old); + ++/* Define route change notification chain. */ ++static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */ ++ + /* Caller must hold RTNL. */ + int fib_table_insert(struct net *net, struct fib_table *tb, + struct fib_config *cfg, struct netlink_ext_ack *extack) +@@ -1404,6 +1407,9 @@ int fib_table_insert(struct net *net, st + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id, + &cfg->fc_nlinfo, nlflags); + succeeded: ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_NEWROUTE, fi); ++ + return 0; + + out_remove_new_fa: +@@ -1775,6 +1781,9 @@ int fib_table_delete(struct net *net, st + if (fa_to_delete->fa_state & FA_S_ACCESSED) + rt_cache_flush(cfg->fc_nlinfo.nl_net); + ++ blocking_notifier_call_chain(&iproute_chain, ++ RTM_DELROUTE, fa_to_delete->fa_info); ++ + fib_release_info(fa_to_delete->fa_info); + alias_free_mem_rcu(fa_to_delete); + return 0; +@@ -2407,6 +2416,20 @@ void __init fib_trie_init(void) + 0, SLAB_PANIC | SLAB_ACCOUNT, NULL); + } + ++/* QCA NSS ECM support - Start */ ++int ip_rt_register_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_register_notifier); ++ ++int ip_rt_unregister_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&iproute_chain, nb); ++} ++EXPORT_SYMBOL(ip_rt_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + struct fib_table *fib_trie_table(u32 id, struct fib_table *alias) + { + struct fib_table *tb; +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -666,6 +666,7 @@ void ndisc_send_ns(struct net_device *de + if (skb) + ndisc_send_skb(skb, daddr, saddr); + } ++EXPORT_SYMBOL(ndisc_send_ns); + + void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, + const struct in6_addr *daddr) +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3856,6 +3856,9 @@ out_free: + return ERR_PTR(err); + } + ++/* Define route change notification chain. */ ++ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */ ++ + int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, + struct netlink_ext_ack *extack) + { +@@ -3867,6 +3870,10 @@ int ip6_route_add(struct fib6_config *cf + return PTR_ERR(rt); + + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack); ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_NEWROUTE, rt); ++ + fib6_info_release(rt); + + return err; +@@ -3888,6 +3895,9 @@ static int __ip6_del_rt(struct fib6_info + err = fib6_del(rt, info); + spin_unlock_bh(&table->tb6_lock); + ++ if (!err) ++ atomic_notifier_call_chain(&ip6route_chain, ++ RTM_DELROUTE, rt); + out: + fib6_info_release(rt); + return err; +@@ -6337,6 +6347,20 @@ static int ip6_route_dev_notify(struct n + return NOTIFY_OK; + } + ++/* QCA NSS ECM support - Start */ ++int rt6_register_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_register_notifier); ++ ++int rt6_unregister_notifier(struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&ip6route_chain, nb); ++} ++EXPORT_SYMBOL(rt6_unregister_notifier); ++/* QCA NSS ECM support - End */ ++ + /* + * /proc + */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1654,6 +1654,7 @@ const char *netdev_cmd_to_name(enum netd + N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) + N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) + N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) ++ N(BR_JOIN) N(BR_LEAVE) + } + #undef N + return "UNKNOWN_NETDEV_EVENT"; +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1002,6 +1002,7 @@ void inet6_ifa_finish_destroy(struct ine + + kfree_rcu(ifp, rcu); + } ++EXPORT_SYMBOL(inet6_ifa_finish_destroy); + + static void + ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) +@@ -2061,6 +2062,36 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str + + return result; + } ++EXPORT_SYMBOL(ipv6_get_ifaddr); ++ ++/* ipv6_dev_find_and_hold() ++ * Find (and hold) net device that has the given address. ++ * Or NULL on failure. ++ */ ++struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr, ++ int strict) ++{ ++ struct inet6_ifaddr *ifp; ++ struct net_device *dev; ++ ++ ifp = ipv6_get_ifaddr(net, addr, NULL, strict); ++ if (!ifp) ++ return NULL; ++ ++ if (!ifp->idev) { ++ in6_ifa_put(ifp); ++ return NULL; ++ } ++ ++ dev = ifp->idev->dev; ++ if (dev) ++ dev_hold(dev); ++ ++ in6_ifa_put(ifp); ++ ++ return dev; ++} ++EXPORT_SYMBOL(ipv6_dev_find_and_hold); + + /* Gets referenced address, destroys ifaddr */ + +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -432,6 +432,15 @@ static inline __be32 vxlan_compute_rco(u + return vni_field; + } + ++/* ++ * vxlan_get_vni() ++ * Returns the vni corresponding to tunnel ++ */ ++static inline u32 vxlan_get_vni(struct vxlan_dev *vxlan_tun) ++{ ++ return be32_to_cpu(vxlan_tun->cfg.vni); ++} ++ + static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs) + { + return vs->sock->sk->sk_family; diff --git a/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch new file mode 100644 index 000000000..505b71382 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-2-qca-nss-ecm-support-PPPOE-offload.patch @@ -0,0 +1,588 @@ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -254,6 +255,25 @@ struct ppp_net { + #define seq_before(a, b) ((s32)((a) - (b)) < 0) + #define seq_after(a, b) ((s32)((a) - (b)) > 0) + ++ ++/* ++ * Registration/Unregistration methods ++ * for PPP channel connect and disconnect event notifications. ++ */ ++RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list); ++ ++void ppp_channel_connection_register_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify); ++ ++void ppp_channel_connection_unregister_notify(struct notifier_block *nb) ++{ ++ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb); ++} ++EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify); ++ + /* Prototypes. */ + static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, + struct file *file, unsigned int cmd, unsigned long arg); +@@ -3453,7 +3473,10 @@ ppp_connect_channel(struct channel *pch, + struct ppp_net *pn; + int ret = -ENXIO; + int hdrlen; ++ int ppp_proto; ++ int version; + ++ int notify = 0; + pn = ppp_pernet(pch->chan_net); + + mutex_lock(&pn->all_ppp_mutex); +@@ -3485,13 +3508,40 @@ ppp_connect_channel(struct channel *pch, + ++ppp->n_channels; + pch->ppp = ppp; + refcount_inc(&ppp->file.refcnt); ++ ++ /* Set the netdev priv flag if the prototype ++ * is L2TP or PPTP. Return success in all cases ++ */ ++ if (!pch->chan) ++ goto out2; ++ ++ ppp_proto = ppp_channel_get_protocol(pch->chan); ++ if (ppp_proto == PX_PROTO_PPTP) { ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP; ++ } else if (ppp_proto == PX_PROTO_OL2TP) { ++ version = ppp_channel_get_proto_version(pch->chan); ++ if (version == 2) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2; ++ else if (version == 3) ++ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3; ++ } ++ notify = 1; ++ ++ out2: + ppp_unlock(ppp); + ret = 0; +- + outl: + write_unlock_bh(&pch->upl); + out: + mutex_unlock(&pn->all_ppp_mutex); ++ ++ if (notify && ppp && ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_CONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + return ret; + } + +@@ -3509,6 +3559,13 @@ ppp_disconnect_channel(struct channel *p + pch->ppp = NULL; + write_unlock_bh(&pch->upl); + if (ppp) { ++ if (ppp->dev) { ++ dev_hold(ppp->dev); ++ raw_notifier_call_chain(&ppp_channel_connection_notifier_list, ++ PPP_CHANNEL_DISCONNECT, ppp->dev); ++ dev_put(ppp->dev); ++ } ++ + /* remove it from the ppp unit's list */ + ppp_lock(ppp); + list_del(&pch->clist); +@@ -3588,6 +3645,222 @@ static void *unit_find(struct idr *p, in + return idr_find(p, n); + } + ++/* Updates the PPP interface statistics. */ ++void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return; ++ ++ if (dev->type != ARPHRD_PPP) ++ return; ++ ++ ppp = netdev_priv(dev); ++ ++ ppp_xmit_lock(ppp); ++ ppp->stats64.tx_packets += tx_packets; ++ ppp->stats64.tx_bytes += tx_bytes; ++ ppp->dev->stats.tx_errors += tx_errors; ++ ppp->dev->stats.tx_dropped += tx_dropped; ++ if (tx_packets) ++ ppp->last_xmit = jiffies; ++ ppp_xmit_unlock(ppp); ++ ++ ppp_recv_lock(ppp); ++ ppp->stats64.rx_packets += rx_packets; ++ ppp->stats64.rx_bytes += rx_bytes; ++ ppp->dev->stats.rx_errors += rx_errors; ++ ppp->dev->stats.rx_dropped += rx_dropped; ++ if (rx_packets) ++ ppp->last_recv = jiffies; ++ ppp_recv_unlock(ppp); ++} ++ ++/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if ++ * the device is not PPP. ++ */ ++int ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flags = ppp->flags; ++ ppp_unlock(ppp); ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(ppp_is_multilink); ++ ++/* ppp_channel_get_protocol() ++ * Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ * ++ * NOTE: Some channels do not use PX sockets so the protocol value may be very ++ * different for them. ++ * NOTE: -1 indicates failure. ++ * NOTE: Once you know the channel protocol you may then either cast 'chan' to ++ * its sub-class or use the channel protocol specific API's as provided by that ++ * channel sub type. ++ */ ++int ppp_channel_get_protocol(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol) ++ return -1; ++ ++ return chan->ops->get_channel_protocol(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_protocol); ++ ++/* ppp_channel_get_proto_version() ++ * Call this to get channel protocol version ++ */ ++int ppp_channel_get_proto_version(struct ppp_channel *chan) ++{ ++ if (!chan->ops->get_channel_protocol_ver) ++ return -1; ++ ++ return chan->ops->get_channel_protocol_ver(chan); ++} ++EXPORT_SYMBOL(ppp_channel_get_proto_version); ++ ++/* ppp_channel_hold() ++ * Call this to hold a channel. ++ * ++ * Returns true on success or false if the hold could not happen. ++ * ++ * NOTE: chan must be protected against destruction during this call - ++ * either by correct locking etc. or because you already have an implicit ++ * or explicit hold to the channel already and this is an additional hold. ++ */ ++bool ppp_channel_hold(struct ppp_channel *chan) ++{ ++ if (!chan->ops->hold) ++ return false; ++ ++ chan->ops->hold(chan); ++ return true; ++} ++EXPORT_SYMBOL(ppp_channel_hold); ++ ++/* ppp_channel_release() ++ * Call this to release a hold you have upon a channel ++ */ ++void ppp_channel_release(struct ppp_channel *chan) ++{ ++ chan->ops->release(chan); ++} ++EXPORT_SYMBOL(ppp_channel_release); ++ ++/* Check if ppp xmit lock is on hold */ ++bool ppp_is_xmit_locked(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ if (!ppp) ++ return false; ++ ++ if (spin_is_locked(&(ppp)->wlock)) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL(ppp_is_xmit_locked); ++ ++/* ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ ppp_lock(ppp); ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ ppp_unlock(ppp); ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ ppp_unlock(ppp); ++ return c; ++} ++EXPORT_SYMBOL(ppp_hold_channels); ++ ++/* ppp_release_channels() ++ * Releases channels ++ */ ++void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz) ++{ ++ unsigned int c; ++ ++ for (c = 0; c < chan_sz; ++c) { ++ struct ppp_channel *chan; ++ ++ chan = channels[c]; ++ chan->ops->release(chan); ++ } ++} ++EXPORT_SYMBOL(ppp_release_channels); ++ + /* Module/initialization stuff */ + + module_init(ppp_init); +@@ -3604,6 +3877,7 @@ EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); + EXPORT_SYMBOL(ppp_register_compressor); + EXPORT_SYMBOL(ppp_unregister_compressor); ++EXPORT_SYMBOL(ppp_update_stats); + MODULE_LICENSE("GPL"); + MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0); + MODULE_ALIAS_RTNL_LINK("ppp"); +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -62,6 +62,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -87,7 +88,7 @@ + static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); + + static const struct proto_ops pppoe_ops; +-static const struct ppp_channel_ops pppoe_chan_ops; ++static const struct pppoe_channel_ops pppoe_chan_ops; + + /* per-net private data for this module */ + static unsigned int pppoe_net_id __read_mostly; +@@ -692,7 +693,7 @@ static int pppoe_connect(struct socket * + + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; + po->chan.private = sk; +- po->chan.ops = &pppoe_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops; + + error = ppp_register_net_channel(dev_net(dev), &po->chan); + if (error) { +@@ -995,9 +996,80 @@ static int pppoe_fill_forward_path(struc + return 0; + } + +-static const struct ppp_channel_ops pppoe_chan_ops = { +- .start_xmit = pppoe_xmit, +- .fill_forward_path = pppoe_fill_forward_path, ++/************************************************************************ ++ * ++ * function called by generic PPP driver to hold channel ++ * ++ ***********************************************************************/ ++static void pppoe_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called by generic PPP driver to release channel ++ * ++ ***********************************************************************/ ++static void pppoe_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/************************************************************************ ++ * ++ * function called to get the channel protocol type ++ * ++ ***********************************************************************/ ++static int pppoe_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OE; ++} ++ ++/************************************************************************ ++ * ++ * function called to get the PPPoE channel addressing ++ * NOTE: This function returns a HOLD to the netdevice ++ * ++ ***********************************************************************/ ++static int pppoe_get_addressing(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct pppox_sock *po = pppox_sk(sk); ++ int err = 0; ++ ++ *addressing = po->proto.pppoe; ++ if (!addressing->dev) ++ return -ENODEV; ++ ++ dev_hold(addressing->dev); ++ return err; ++} ++ ++/* pppoe_channel_addressing_get() ++ * Return PPPoE channel specific addressing information. ++ */ ++int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing) ++{ ++ return pppoe_get_addressing(chan, addressing); ++} ++EXPORT_SYMBOL(pppoe_channel_addressing_get); ++ ++static const struct pppoe_channel_ops pppoe_chan_ops = { ++ /* PPPoE specific channel ops */ ++ .get_addressing = pppoe_get_addressing, ++ /* General ppp channel ops */ ++ .ops.start_xmit = pppoe_xmit, ++ .ops.get_channel_protocol = pppoe_get_channel_protocol, ++ .ops.hold = pppoe_hold_chan, ++ .ops.release = pppoe_release_chan, ++ .ops.fill_forward_path = pppoe_fill_forward_path, + }; + + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -91,4 +91,17 @@ enum { + PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/ + }; + ++/* ++ * PPPoE Channel specific operations ++ */ ++struct pppoe_channel_ops { ++ /* Must be first - general to all PPP channels */ ++ struct ppp_channel_ops ops; ++ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); ++}; ++ ++/* Return PPPoE channel specific addressing information */ ++extern int pppoe_channel_addressing_get(struct ppp_channel *chan, ++ struct pppoe_opt *addressing); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1710,6 +1710,24 @@ enum netdev_priv_flags { + IFF_NO_IP_ALIGN = BIT_ULL(33), + }; + ++ ++/** ++ * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext ++ * ++ * These flags are used to check for device type and can be ++ * set and used by the drivers ++ * ++ */ ++enum netdev_priv_flags_ext { ++ IFF_EXT_TUN_TAP = 1<<0, ++ IFF_EXT_PPP_L2TPV2 = 1<<1, ++ IFF_EXT_PPP_L2TPV3 = 1<<2, ++ IFF_EXT_PPP_PPTP = 1<<3, ++ IFF_EXT_GRE_V4_TAP = 1<<4, ++ IFF_EXT_GRE_V6_TAP = 1<<5, ++ IFF_EXT_IFB = 1<<6, ++}; ++ + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN + #define IFF_EBRIDGE IFF_EBRIDGE + #define IFF_BONDING IFF_BONDING +@@ -2053,6 +2071,7 @@ struct net_device { + /* Read-mostly cache-line for fast-path access */ + unsigned int flags; + unsigned long long priv_flags; ++ unsigned int priv_flags_ext; + const struct net_device_ops *netdev_ops; + int ifindex; + unsigned short gflags; +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -19,6 +19,10 @@ + #include + #include + #include ++#include ++ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 + + struct net_device_path; + struct net_device_path_ctx; +@@ -30,9 +34,19 @@ struct ppp_channel_ops { + int (*start_xmit)(struct ppp_channel *, struct sk_buff *); + /* Handle an ioctl call that has come in via /dev/ppp. */ + int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); ++ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to ++ * the channel subtype ++ */ ++ int (*get_channel_protocol)(struct ppp_channel *); ++ /* Get channel protocol version */ ++ int (*get_channel_protocol_ver)(struct ppp_channel *); ++ /* Hold the channel from being destroyed */ ++ void (*hold)(struct ppp_channel *); ++ /* Release hold on the channel */ ++ void (*release)(struct ppp_channel *); + int (*fill_forward_path)(struct net_device_path_ctx *, +- struct net_device_path *, +- const struct ppp_channel *); ++ struct net_device_path *, ++ const struct ppp_channel *); + }; + + struct ppp_channel { +@@ -76,6 +90,51 @@ extern int ppp_unit_number(struct ppp_ch + /* Get the device name associated with a channel, or NULL if none */ + extern char *ppp_dev_name(struct ppp_channel *); + ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ ++ + /* + * SMP locking notes: + * The channel code must ensure that when it calls ppp_unregister_channel, diff --git a/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch new file mode 100644 index 000000000..982ac9d4f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-3-qca-nss-ecm-support-net-bonding.patch @@ -0,0 +1,81 @@ +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -252,6 +252,8 @@ static const struct flow_dissector_key f + }, + }; + ++static unsigned long bond_id_mask = 0xFFFFFFF0; /* QCA NSS ECM bonding support */ ++ + static struct flow_dissector flow_keys_bonding __read_mostly; + + /*-------------------------- Forward declarations ---------------------------*/ +@@ -4383,6 +4385,24 @@ static int bond_get_lowest_level_rcu(str + } + #endif + ++/* QCA NSS ECM bonding support */ ++int bond_get_id(struct net_device *bond_dev) ++{ ++ struct bonding *bond; ++ int bond_id = 0; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return -EINVAL; ++ ++ bond = netdev_priv(bond_dev); ++ bond_id = bond->id; ++ ++ return bond_id; ++} ++EXPORT_SYMBOL(bond_get_id); ++/* QCA NSS ECM bonding support */ ++ + static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 *stats) + { +@@ -5795,6 +5815,11 @@ static void bond_destructor(struct net_d + + if (bond->rr_tx_counter) + free_percpu(bond->rr_tx_counter); ++ ++ /* QCA NSS ECM bonding support */ ++ if (bond->id != (~0U)) ++ clear_bit(bond->id, &bond_id_mask); ++ /* QCA NSS ECM bonding support */ + } + + void bond_setup(struct net_device *bond_dev) +@@ -6358,6 +6383,14 @@ int bond_create(struct net *net, const c + + bond_work_init_all(bond); + ++ /* QCA NSS ECM bonding support - Start */ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + out: + rtnl_unlock(); + return res; +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -265,6 +265,7 @@ struct bonding { + spinlock_t ipsec_lock; + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; ++ u32 id; /* QCA NSS ECM bonding support */ + }; + + #define bond_slave_get_rcu(dev) \ +@@ -658,6 +659,7 @@ struct bond_net { + + int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); ++int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); diff --git a/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG.patch b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG.patch new file mode 100644 index 000000000..6c289599d --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-4-qca-nss-ecm-support-net-bonding-over-LAG.patch @@ -0,0 +1,668 @@ +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -114,7 +114,40 @@ static void ad_marker_info_received(stru + static void ad_marker_response_received(struct bond_marker *marker, + struct port *port); + static void ad_update_actor_keys(struct port *port, bool reset); ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb __rcu *bond_cb; + ++int bond_register_cb(struct bond_cb *cb) ++{ ++ struct bond_cb *lag_cb; ++ ++ lag_cb = kzalloc(sizeof(*lag_cb), GFP_ATOMIC | __GFP_NOWARN); ++ if (!lag_cb) { ++ return -1; ++ } ++ ++ memcpy((void *)lag_cb, (void *)cb, sizeof(*cb)); ++ ++ rcu_read_lock(); ++ rcu_assign_pointer(bond_cb, lag_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(bond_register_cb); ++ ++void bond_unregister_cb(void) ++{ ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ rcu_assign_pointer(bond_cb, NULL); ++ rcu_read_unlock(); ++ ++ kfree(lag_cb_main); ++} ++EXPORT_SYMBOL(bond_unregister_cb); ++/* QCA NSS ECM bonding support - End */ + + /* ================= api to bonding and kernel code ================== */ + +@@ -424,7 +457,6 @@ static u16 __ad_timer_to_ticks(u16 timer + return retval; + } + +- + /* ================= ad_rx_machine helper functions ================== */ + + /** +@@ -1064,7 +1096,30 @@ static void ad_mux_machine(struct port * + ad_disable_collecting_distributing(port, + update_slave_arr); + port->ntt = true; +- break; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ /* Send a notificaton about change in state of this ++ * port. We only want to handle case where port moves ++ * from AD_MUX_COLLECTING_DISTRIBUTING -> ++ * AD_MUX_ATTACHED. ++ */ ++ if (bond_slave_is_up(port->slave) && ++ (last_state == AD_MUX_COLLECTING_DISTRIBUTING)) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_down) { ++ struct net_device *dev; ++ ++ dev = port->slave->dev; ++ lag_cb_main->bond_cb_link_down(dev); ++ } ++ rcu_read_unlock(); ++ } ++ ++ break; /* QCA NSS ECM bonding support - End */ + case AD_MUX_COLLECTING_DISTRIBUTING: + port->actor_oper_port_state |= LACP_STATE_COLLECTING; + port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; +@@ -1908,6 +1963,7 @@ static void ad_enable_collecting_distrib + bool *update_slave_arr) + { + if (port->aggregator->is_active) { ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + slave_dbg(port->slave->bond->dev, port->slave->dev, + "Enabling port %d (LAG %d)\n", + port->actor_port_number, +@@ -1915,6 +1971,16 @@ static void ad_enable_collecting_distrib + __enable_port(port); + /* Slave array needs update */ + *update_slave_arr = true; ++ ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(port->slave->dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ + } + } + +@@ -2674,6 +2740,104 @@ int bond_3ad_get_active_agg_info(struct + return ret; + } + ++/* QCA NSS ECM bonding support - Start */ ++/* bond_3ad_get_tx_dev - Calculate egress interface for a given packet, ++ * for a LAG that is configured in 802.3AD mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address ++ * @dst: pointer to destination L3 address ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash is used to calculate hash using L2/L3 ++ * addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, u8 *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct aggregator *agg; ++ struct ad_info ad_info; ++ struct list_head *iter; ++ struct slave *slave; ++ struct slave *first_ok_slave = NULL; ++ u32 hash = 0; ++ int slaves_in_agg; ++ int slave_agg_no = 0; ++ int agg_id; ++ ++ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { ++ pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ slaves_in_agg = ad_info.ports; ++ agg_id = ad_info.aggregator_id; ++ ++ if (slaves_in_agg == 0) { ++ pr_debug("%s: Error: active aggregator is empty\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_agg_no = hash % slaves_in_agg; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for 802.3AD fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ slave_agg_no = hash % slaves_in_agg; ++ } ++ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ agg = SLAVE_AD_INFO(slave)->port.aggregator; ++ if (!agg || agg->aggregator_identifier != agg_id) ++ continue; ++ ++ if (slave_agg_no >= 0) { ++ if (!first_ok_slave && bond_slave_can_tx(slave)) ++ first_ok_slave = slave; ++ slave_agg_no--; ++ continue; ++ } ++ ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ if (slave_agg_no >= 0) { ++ pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", ++ bond_dev->name, agg_id); ++ return NULL; ++ } ++ ++ /* we couldn't find any suitable slave after the agg_no, so use the ++ * first suitable found, if found. ++ */ ++ if (first_ok_slave) ++ return first_ok_slave->dev; ++ ++ return NULL; ++} ++/* QCA NSS ECM bonding support - End */ ++ + int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, + struct slave *slave) + { +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1186,6 +1186,23 @@ void bond_change_active_slave(struct bon + if (BOND_MODE(bond) == BOND_MODE_8023AD) + bond_3ad_handle_link_change(new_active, BOND_LINK_UP); + ++ /* QCA NSS ECM bonding support - Start */ ++ if (bond->params.mode == BOND_MODE_XOR) { ++ struct bond_cb *lag_cb_main; ++ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && ++ lag_cb_main->bond_cb_link_up) { ++ struct net_device *dev; ++ ++ dev = new_active->dev; ++ lag_cb_main->bond_cb_link_up(dev); ++ } ++ rcu_read_unlock(); ++ } ++ /* QCA NSS ECM bonding support - End */ ++ + if (bond_is_lb(bond)) + bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); + } else { +@@ -1809,6 +1826,7 @@ int bond_enslave(struct net_device *bond + const struct net_device_ops *slave_ops = slave_dev->netdev_ops; + struct slave *new_slave = NULL, *prev_slave; + struct sockaddr_storage ss; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + int link_reporting; + int res = 0, i; + +@@ -2252,6 +2270,15 @@ int bond_enslave(struct net_device *bond + bond_is_active_slave(new_slave) ? "an active" : "a backup", + new_slave->link != BOND_LINK_DOWN ? "an up" : "a down"); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + /* enslave is successful */ + bond_queue_slave_event(new_slave); + return 0; +@@ -2317,6 +2344,15 @@ err_undo_flags: + } + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_enslave) ++ lag_cb_main->bond_cb_enslave(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + return res; + } + +@@ -2339,6 +2375,7 @@ static int __bond_release_one(struct net + struct slave *slave, *oldcurrent; + struct sockaddr_storage ss; + int old_flags = bond_dev->flags; ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + netdev_features_t old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2360,6 +2397,15 @@ static int __bond_release_one(struct net + + bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW); + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ if (lag_cb_main && lag_cb_main->bond_cb_release) ++ lag_cb_main->bond_cb_release(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_sysfs_slave_del(slave); + + /* recompute stats just before removing the slave */ +@@ -2679,6 +2725,8 @@ static void bond_miimon_commit(struct bo + struct slave *slave, *primary, *active; + bool do_failover = false; + struct list_head *iter; ++ struct net_device *slave_dev = NULL; /* QCA NSS ECM bonding support */ ++ struct bond_cb *lag_cb_main; /* QCA NSS ECM bonding support */ + + ASSERT_RTNL(); + +@@ -2718,6 +2766,12 @@ static void bond_miimon_commit(struct bo + bond_set_active_slave(slave); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ if ((bond->params.mode == BOND_MODE_XOR) && ++ (!slave_dev)) ++ slave_dev = slave->dev; ++ /* QCA NSS ECM bonding support - End */ ++ + slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", + slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, + slave->duplex ? "full" : "half"); +@@ -2766,6 +2820,16 @@ static void bond_miimon_commit(struct bo + unblock_netpoll_tx(); + } + ++ /* QCA NSS ECM bonding support - Start */ ++ rcu_read_lock(); ++ lag_cb_main = rcu_dereference(bond_cb); ++ ++ if (slave_dev && lag_cb_main && lag_cb_main->bond_cb_link_up) ++ lag_cb_main->bond_cb_link_up(slave_dev); ++ ++ rcu_read_unlock(); ++ /* QCA NSS ECM bonding support - End */ ++ + bond_set_carrier(bond); + } + +@@ -4013,9 +4077,220 @@ static inline u32 bond_eth_hash(struct s + return 0; + + ep = (struct ethhdr *)(data + mhoff); +- return ep->h_dest[5] ^ ep->h_source[5] ^ be16_to_cpu(ep->h_proto); ++ return ep->h_dest[5] ^ ep->h_source[5]; /* QCA NSS ECM bonding support */ + } + ++/* QCA NSS ECM bonding support - Start */ ++/* Extract the appropriate headers based on bond's xmit policy */ ++static bool bond_flow_dissect_without_skb(struct bonding *bond, ++ u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, ++ u16 protocol, __be16 *layer4hdr, ++ struct flow_keys *fk) ++{ ++ u32 *src = NULL; ++ u32 *dst = NULL; ++ ++ fk->ports.ports = 0; ++ src = (uint32_t *)psrc; ++ dst = (uint32_t *)pdst; ++ ++ if (protocol == htons(ETH_P_IP)) { ++ /* V4 addresses and address type*/ ++ fk->addrs.v4addrs.src = src[0]; ++ fk->addrs.v4addrs.dst = dst[0]; ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; ++ } else if (protocol == htons(ETH_P_IPV6)) { ++ /* V6 addresses and address type*/ ++ memcpy(&fk->addrs.v6addrs.src, src, sizeof(struct in6_addr)); ++ memcpy(&fk->addrs.v6addrs.dst, dst, sizeof(struct in6_addr)); ++ fk->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; ++ } else { ++ return false; ++ } ++ if ((bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) && ++ (layer4hdr)) ++ fk->ports.ports = *layer4hdr; ++ ++ return true; ++} ++ ++/* bond_xmit_hash_without_skb - Applies load balancing algorithm for a packet, ++ * to calculate hash for a given set of L2/L3 addresses. Does not ++ * calculate egress interface. ++ */ ++uint32_t bond_xmit_hash_without_skb(u8 *src_mac, u8 *dst_mac, ++ void *psrc, void *pdst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ struct flow_keys flow; ++ u32 hash = 0; ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || ++ !bond_flow_dissect_without_skb(bond, src_mac, dst_mac, psrc, ++ pdst, protocol, layer4hdr, &flow)) ++ return (dst_mac[5] ^ src_mac[5]); ++ ++ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23) ++ hash = dst_mac[5] ^ src_mac[5]; ++ else if (layer4hdr) ++ hash = (__force u32)flow.ports.ports; ++ ++ hash ^= (__force u32)flow_get_u32_dst(&flow) ^ ++ (__force u32)flow_get_u32_src(&flow); ++ hash ^= (hash >> 16); ++ hash ^= (hash >> 8); ++ ++ return hash; ++} ++ ++/* bond_xor_get_tx_dev - Calculate egress interface for a given packet for a LAG ++ * that is configured in balance-xor mode ++ * @skb: pointer to skb to be egressed ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol ++ * @bond_dev: pointer to bond master device ++ * ++ * If @skb is NULL, bond_xmit_hash_without_skb is used to calculate hash using ++ * L2/L3 addresses. ++ * ++ * Returns: Either valid slave device, or NULL otherwise ++ */ ++static struct net_device *bond_xor_get_tx_dev(struct sk_buff *skb, ++ u8 *src_mac, u8 *dst_mac, ++ void *src, void *dst, ++ u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ int slave_cnt = READ_ONCE(bond->slave_cnt); ++ int slave_id = 0, i = 0; ++ u32 hash; ++ struct list_head *iter; ++ struct slave *slave; ++ ++ if (slave_cnt == 0) { ++ pr_debug("%s: Error: No slave is attached to the interface\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ if (skb) { ++ hash = bond_xmit_hash(bond, skb); ++ slave_id = hash % slave_cnt; ++ } else { ++ if (bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER23 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER2 && ++ bond->params.xmit_policy != BOND_XMIT_POLICY_LAYER34) { ++ pr_debug("%s: Error: Unsupported hash policy for balance-XOR fast path\n", ++ bond_dev->name); ++ return NULL; ++ } ++ ++ hash = bond_xmit_hash_without_skb(src_mac, dst_mac, src, ++ dst, protocol, bond_dev, ++ layer4hdr); ++ slave_id = hash % slave_cnt; ++ } ++ ++ i = slave_id; ++ ++ /* Here we start from the slave with slave_id */ ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) { ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ } ++ ++ /* Here we start from the first slave up to slave_id */ ++ i = slave_id; ++ bond_for_each_slave_rcu(bond, slave, iter) { ++ if (--i < 0) ++ break; ++ if (bond_slave_can_tx(slave)) ++ return slave->dev; ++ } ++ ++ return NULL; ++} ++ ++/* bond_get_tx_dev - Calculate egress interface for a given packet. ++ * ++ * Supports 802.3AD and balance-xor modes ++ * ++ * @skb: pointer to skb to be egressed, if valid ++ * @src_mac: pointer to source L2 address ++ * @dst_mac: pointer to destination L2 address ++ * @src: pointer to source L3 address in network order ++ * @dst: pointer to destination L3 address in network order ++ * @protocol: L3 protocol id from L2 header ++ * @bond_dev: pointer to bond master device ++ * ++ * Returns: Either valid slave device, or NULL for un-supported LAG modes ++ */ ++struct net_device *bond_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ u8 *dst_mac, void *src, ++ void *dst, u16 protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr) ++{ ++ struct bonding *bond; ++ ++ if (!bond_dev) ++ return NULL; ++ ++ if (!((bond_dev->priv_flags & IFF_BONDING) && ++ (bond_dev->flags & IFF_MASTER))) ++ return NULL; ++ ++ bond = netdev_priv(bond_dev); ++ ++ switch (bond->params.mode) { ++ case BOND_MODE_XOR: ++ return bond_xor_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ case BOND_MODE_8023AD: ++ return bond_3ad_get_tx_dev(skb, src_mac, dst_mac, ++ src, dst, protocol, ++ bond_dev, layer4hdr); ++ default: ++ return NULL; ++ } ++} ++EXPORT_SYMBOL(bond_get_tx_dev); ++ ++/* In bond_xmit_xor() , we determine the output device by using a pre- ++ * determined xmit_hash_policy(), If the selected device is not enabled, ++ * find the next active slave. ++ */ ++static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct bonding *bond = netdev_priv(dev); ++ struct net_device *outdev; ++ ++ outdev = bond_xor_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); ++ if (!outdev) ++ goto out; ++ ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++out: ++ /* no suitable interface, frame not sent */ ++ dev_kfree_skb(skb); ++final: ++ return NETDEV_TX_OK; ++} ++/* QCA NSS ECM bonding support - End */ ++ + static bool bond_flow_ip(struct sk_buff *skb, struct flow_keys *fk, const void *data, + int hlen, __be16 l2_proto, int *nhoff, int *ip_proto, bool l34) + { +@@ -5211,15 +5486,23 @@ static netdev_tx_t bond_3ad_xor_xmit(str + struct net_device *dev) + { + struct bonding *bond = netdev_priv(dev); +- struct bond_up_slave *slaves; +- struct slave *slave; ++ /* QCA NSS ECM bonding support - Start */ ++ struct net_device *outdev = NULL; ++ outdev = bond_3ad_get_tx_dev(skb, NULL, NULL, NULL, ++ NULL, 0, dev, NULL); + +- slaves = rcu_dereference(bond->usable_slaves); +- slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); +- if (likely(slave)) +- return bond_dev_queue_xmit(bond, skb, slave->dev); ++ if (!outdev) ++ goto out; + +- return bond_tx_drop(dev, skb); ++ bond_dev_queue_xmit(bond, skb, outdev); ++ goto final; ++ ++out: ++ dev_kfree_skb(skb); ++ ++final: ++ return NETDEV_TX_OK; ++/* QCA NSS ECM bonding support - End */ + } + + /* in broadcast mode, we send everything to all usable interfaces. */ +@@ -5469,8 +5752,9 @@ static netdev_tx_t __bond_start_xmit(str + return bond_xmit_roundrobin(skb, dev); + case BOND_MODE_ACTIVEBACKUP: + return bond_xmit_activebackup(skb, dev); +- case BOND_MODE_8023AD: + case BOND_MODE_XOR: ++ return bond_xmit_xor(skb, dev); /* QCA NSS ECM bonding support */ ++ case BOND_MODE_8023AD: + return bond_3ad_xor_xmit(skb, dev); + case BOND_MODE_BROADCAST: + return bond_xmit_broadcast(skb, dev); +--- a/include/net/bond_3ad.h ++++ b/include/net/bond_3ad.h +@@ -303,8 +303,15 @@ int bond_3ad_lacpdu_recv(const struct sk + int bond_3ad_set_carrier(struct bonding *bond); + void bond_3ad_update_lacp_active(struct bonding *bond); + void bond_3ad_update_lacp_rate(struct bonding *bond); ++/* QCA NSS ECM bonding support */ ++struct net_device *bond_3ad_get_tx_dev(struct sk_buff *skb, uint8_t *src_mac, ++ uint8_t *dst_mac, void *src, ++ void *dst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support */ ++ + void bond_3ad_update_ad_actor_settings(struct bonding *bond); + int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats); + size_t bond_3ad_stats_size(void); + #endif /* _NET_BOND_3AD_H */ +- +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -85,6 +85,8 @@ + #define bond_for_each_slave(bond, pos, iter) \ + netdev_for_each_lower_private((bond)->dev, pos, iter) + ++extern struct bond_cb __rcu *bond_cb; /* QCA NSS ECM bonding support */ ++ + /* Caller must have rcu_read_lock */ + #define bond_for_each_slave_rcu(bond, pos, iter) \ + netdev_for_each_lower_private_rcu((bond)->dev, pos, iter) +@@ -690,6 +692,12 @@ struct bond_vlan_tag *bond_verify_device + int level); + int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); + void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); ++/* QCA NSS ECM bonding support - Start */ ++uint32_t bond_xmit_hash_without_skb(uint8_t *src_mac, uint8_t *dst_mac, ++ void *psrc, void *pdst, uint16_t protocol, ++ struct net_device *bond_dev, ++ __be16 *layer4hdr); ++/* QCA NSS ECM bonding support - End */ + void bond_work_init_all(struct bonding *bond); + + #ifdef CONFIG_PROC_FS +@@ -794,4 +802,18 @@ static inline netdev_tx_t bond_tx_drop(s + return NET_XMIT_DROP; + } + ++/* QCA NSS ECM bonding support - Start */ ++struct bond_cb { ++ void (*bond_cb_link_up)(struct net_device *slave); ++ void (*bond_cb_link_down)(struct net_device *slave); ++ void (*bond_cb_enslave)(struct net_device *slave); ++ void (*bond_cb_release)(struct net_device *slave); ++ void (*bond_cb_delete_by_slave)(struct net_device *slave); ++ void (*bond_cb_delete_by_mac)(uint8_t *mac_addr); ++}; ++ ++extern int bond_register_cb(struct bond_cb *cb); ++extern void bond_unregister_cb(void); ++/* QCA NSS ECM bonding support - End */ ++ + #endif /* _NET_BONDING_H */ diff --git a/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch new file mode 100644 index 000000000..5f18c6be7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-5-qca-nss-ecm-support-macvlan.patch @@ -0,0 +1,96 @@ +--- a/include/linux/if_macvlan.h ++++ b/include/linux/if_macvlan.h +@@ -15,6 +15,13 @@ struct macvlan_port; + #define MACVLAN_MC_FILTER_BITS 8 + #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) + ++/* QCA NSS ECM Support - Start */ ++/* ++ * Callback for updating interface statistics for macvlan flows offloaded from host CPU. ++ */ ++typedef void (*macvlan_offload_stats_update_cb_t)(struct net_device *dev, struct rtnl_link_stats64 *stats, bool update_mcast_rx_stats); ++/* QCA NSS ECM Support - End */ ++ + struct macvlan_dev { + struct net_device *dev; + struct list_head list; +@@ -35,6 +42,7 @@ struct macvlan_dev { + #ifdef CONFIG_NET_POLL_CONTROLLER + struct netpoll *netpoll; + #endif ++ macvlan_offload_stats_update_cb_t offload_stats_update; /* QCA NSS ECM support */ + }; + + static inline void macvlan_count_rx(const struct macvlan_dev *vlan, +@@ -107,4 +115,26 @@ static inline int macvlan_release_l2fw_o + macvlan->accel_priv = NULL; + return dev_uc_add(macvlan->lowerdev, dev->dev_addr); + } ++ ++/* QCA NSS ECM Support - Start */ ++#if IS_ENABLED(CONFIG_MACVLAN) ++static inline void ++macvlan_offload_stats_update(struct net_device *dev, ++ struct rtnl_link_stats64 *stats, ++ bool update_mcast_rx_stats) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ macvlan->offload_stats_update(dev, stats, update_mcast_rx_stats); ++} ++ ++static inline enum ++macvlan_mode macvlan_get_mode(struct net_device *dev) ++{ ++ struct macvlan_dev *macvlan = netdev_priv(dev); ++ ++ return macvlan->mode; ++} ++#endif ++/* QCA NSS ECM Support - End */ + #endif /* _LINUX_IF_MACVLAN_H */ +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -933,6 +933,34 @@ static void macvlan_uninit(struct net_de + macvlan_port_destroy(port->dev); + } + ++/* QCA NSS ECM Support - Start */ ++/* Update macvlan statistics processed by offload engines */ ++static void macvlan_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *offl_stats, ++ bool update_mcast_rx_stats) ++{ ++ struct vlan_pcpu_stats *stats; ++ struct macvlan_dev *macvlan; ++ ++ /* Is this a macvlan? */ ++ if (!netif_is_macvlan(dev)) ++ return; ++ ++ macvlan = netdev_priv(dev); ++ stats = this_cpu_ptr(macvlan->pcpu_stats); ++ u64_stats_update_begin(&stats->syncp); ++ u64_stats_add(&stats->rx_packets, offl_stats->rx_packets); ++ u64_stats_add(&stats->rx_bytes, offl_stats->rx_bytes); ++ u64_stats_add(&stats->tx_packets, offl_stats->tx_packets); ++ u64_stats_add(&stats->tx_bytes, offl_stats->tx_bytes); ++ /* Update multicast statistics */ ++ if (unlikely(update_mcast_rx_stats)) { ++ u64_stats_add(&stats->rx_multicast, offl_stats->rx_packets); ++ } ++ u64_stats_update_end(&stats->syncp); ++} ++/* QCA NSS ECM Support - End */ ++ + static void macvlan_dev_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -1477,6 +1505,7 @@ int macvlan_common_newlink(struct net *s + vlan->dev = dev; + vlan->port = port; + vlan->set_features = MACVLAN_FEATURES; ++ vlan->offload_stats_update = macvlan_dev_update_stats; /* QCA NSS ECM Support */ + + vlan->mode = MACVLAN_MODE_VEPA; + if (data && data[IFLA_MACVLAN_MODE]) diff --git a/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch new file mode 100644 index 000000000..6f030d52c --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-6-qca-nss-ecm-support-netfilter-DSCPREMARK.patch @@ -0,0 +1,69 @@ +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -179,6 +179,13 @@ config NF_CONNTRACK_TIMEOUT + + If unsure, say `N'. + ++config NF_CONNTRACK_DSCPREMARK_EXT ++ bool 'Connection tracking extension for dscp remark target' ++ depends on NETFILTER_ADVANCED ++ help ++ This option enables support for connection tracking extension ++ for dscp remark. ++ + config NF_CONNTRACK_TIMESTAMP + bool 'Connection tracking timestamping' + depends on NETFILTER_ADVANCED +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -31,6 +31,10 @@ enum nf_ct_ext_id { + #if IS_ENABLED(CONFIG_NET_ACT_CT) + NF_CT_EXT_ACT_CT, + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ NF_CT_EXT_DSCPREMARK, /* QCA NSS ECM support */ ++#endif ++ + NF_CT_EXT_NUM, + }; + +--- a/net/netfilter/nf_conntrack_extend.c ++++ b/net/netfilter/nf_conntrack_extend.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + #define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ +@@ -54,6 +55,9 @@ static const u8 nf_ct_ext_type_len[NF_CT + #if IS_ENABLED(CONFIG_NET_ACT_CT) + [NF_CT_EXT_ACT_CT] = sizeof(struct nf_conn_act_ct_ext), + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ [NF_CT_EXT_DSCPREMARK] = sizeof(struct nf_ct_dscpremark_ext), ++#endif + }; + + static __always_inline unsigned int total_extension_size(void) +@@ -86,6 +90,9 @@ static __always_inline unsigned int tota + #if IS_ENABLED(CONFIG_NET_ACT_CT) + + sizeof(struct nf_conn_act_ct_ext) + #endif ++#ifdef CONFIG_NF_CONNTRACK_DSCPREMARK_EXT ++ + sizeof(struct nf_ct_dscpremark_ext) ++#endif + ; + } + +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -14,6 +14,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_LABEL + nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o + nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o ++nf_conntrack-$(CONFIG_NF_CONNTRACK_DSCPREMARK_EXT) += nf_conntrack_dscpremark_ext.o + ifeq ($(CONFIG_NF_CONNTRACK),m) + nf_conntrack-$(CONFIG_DEBUG_INFO_BTF_MODULES) += nf_conntrack_bpf.o + else ifeq ($(CONFIG_NF_CONNTRACK),y) diff --git a/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-add-missing-net-defines.patch b/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-add-missing-net-defines.patch new file mode 100644 index 000000000..2c63b46c3 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-7-qca-nss-ecm-add-missing-net-defines.patch @@ -0,0 +1,35 @@ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1725,7 +1725,9 @@ enum netdev_priv_flags_ext { + IFF_EXT_PPP_PPTP = 1<<3, + IFF_EXT_GRE_V4_TAP = 1<<4, + IFF_EXT_GRE_V6_TAP = 1<<5, +- IFF_EXT_IFB = 1<<6, ++ IFF_EXT_IFB = 1<<6, ++ IFF_EXT_MAPT = 1<<7, ++ IFF_EXT_HW_NO_OFFLOAD = 1<<8, + }; + + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ +--- a/tools/include/uapi/linux/in.h ++++ b/tools/include/uapi/linux/in.h +@@ -63,6 +63,8 @@ enum { + #define IPPROTO_MTP IPPROTO_MTP + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ + #define IPPROTO_BEETPH IPPROTO_BEETPH ++ IPPROTO_ETHERIP = 97, /* ETHERIP protocol number */ ++#define IPPROTO_ETHERIP IPPROTO_ETHERIP + IPPROTO_ENCAP = 98, /* Encapsulation Header */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast */ diff --git a/target/linux/qualcommax/patches-6.1/0600-8-qca-nss-ecm-support-MLO-bonding.patch b/target/linux/qualcommax/patches-6.1/0600-8-qca-nss-ecm-support-MLO-bonding.patch new file mode 100644 index 000000000..ad9e20553 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0600-8-qca-nss-ecm-support-MLO-bonding.patch @@ -0,0 +1,536 @@ +From 0403eceee14bb6eb4e417102cae830b7509b1554 Mon Sep 17 00:00:00 2001 +From: Shivani Soni +Date: Thu, 17 Nov 2022 00:16:38 +0530 +Subject: [PATCH] arm/arm64: Add support for MLO bonding + +1. Introduced BOND_MODE_MLO to support MLO bonding +2. Transmit handling according to new mode + +Change-Id: Ib272e77cce56ee50b0a13305fac8fae76743c206 +Signed-off-by: Shivani Soni +--- + drivers/net/bonding/bond_main.c | 212 ++++++++++++++++++++++++----- + drivers/net/bonding/bond_options.c | 1 + + include/net/bonding.h | 30 +++- + include/uapi/linux/if_bonding.h | 1 + + 4 files changed, 210 insertions(+), 34 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1439,6 +1439,10 @@ static netdev_features_t bond_fix_featur + return features; + } + ++#define BOND_MLO_VLAN_FEATURES (NETIF_F_SG | \ ++ NETIF_F_FRAGLIST | \ ++ NETIF_F_HIGHDMA | NETIF_F_LRO) ++ + #define BOND_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ + NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ + NETIF_F_HIGHDMA | NETIF_F_LRO) +@@ -1469,13 +1473,25 @@ static void bond_compute_features(struct + + if (!bond_has_slaves(bond)) + goto done; ++ ++ /* ++ * Use features specific to bond MLO ++ */ ++ if (BOND_MODE(bond) == BOND_MODE_MLO) { ++ vlan_features = BOND_MLO_VLAN_FEATURES; ++ } ++ + vlan_features &= NETIF_F_ALL_FOR_ALL; + mpls_features &= NETIF_F_ALL_FOR_ALL; + + bond_for_each_slave(bond, slave, iter) { +- vlan_features = netdev_increment_features(vlan_features, +- slave->dev->vlan_features, BOND_VLAN_FEATURES); +- ++ if (BOND_MODE(bond) == BOND_MODE_MLO) { ++ vlan_features = netdev_increment_features(vlan_features, ++ slave->dev->vlan_features, BOND_MLO_VLAN_FEATURES); ++ } else { ++ vlan_features = netdev_increment_features(vlan_features, ++ slave->dev->vlan_features, BOND_VLAN_FEATURES); ++ } + enc_features = netdev_increment_features(enc_features, + slave->dev->hw_enc_features, + BOND_ENC_FEATURES); +@@ -1620,6 +1636,16 @@ static rx_handler_result_t bond_handle_f + bond->dev->addr_len); + } + ++ /* ++ * Set the PACKET_HOST for MLO mode as ++ * MLO bond netdevice needs to support routing ++ */ ++ if (BOND_MODE(bond) == BOND_MODE_MLO) { ++ if (ether_addr_equal(bond->dev->dev_addr, eth_hdr(skb)->h_dest)) { ++ skb->pkt_type = PACKET_HOST; ++ } ++ } ++ + return ret; + } + +@@ -1837,6 +1863,8 @@ int bond_enslave(struct net_device *bond + return -EPERM; + } + ++ ASSERT_RTNL(); ++ + if (!bond->params.use_carrier && + slave_dev->ethtool_ops->get_link == NULL && + slave_ops->ndo_eth_ioctl == NULL) { +@@ -1950,13 +1978,17 @@ int bond_enslave(struct net_device *bond + call_netdevice_notifiers(NETDEV_JOIN, slave_dev); + + /* If this is the first slave, then we need to set the master's hardware +- * address to be the same as the slave's. ++ * address to be the same as the slave's except for BOND_MODE_MLO. ++ * For BOND_MODE_MLO, master's mac address is MLD address which should ++ * not be same as slave's address. + */ +- if (!bond_has_slaves(bond) && +- bond->dev->addr_assign_type == NET_ADDR_RANDOM) { +- res = bond_set_dev_addr(bond->dev, slave_dev); +- if (res) +- goto err_undo_flags; ++ if (BOND_MODE(bond) != BOND_MODE_MLO) { ++ if (!bond_has_slaves(bond) && ++ bond->dev->addr_assign_type == NET_ADDR_RANDOM) { ++ res = bond_set_dev_addr(bond->dev, slave_dev); ++ if (res) ++ goto err_undo_flags; ++ } + } + + new_slave = bond_alloc_slave(bond, slave_dev); +@@ -1985,18 +2017,21 @@ int bond_enslave(struct net_device *bond + bond_hw_addr_copy(new_slave->perm_hwaddr, slave_dev->dev_addr, + slave_dev->addr_len); + +- if (!bond->params.fail_over_mac || +- BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { +- /* Set slave to master's mac address. The application already +- * set the master's mac address to that of the first slave +- */ +- memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len); +- ss.ss_family = slave_dev->type; +- res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, +- extack); +- if (res) { +- slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res); +- goto err_restore_mtu; ++ /* Set slave to master's mac address except for BOND_MODE_MLO ++ * as for MLO mode master's mac address is not same as slave's mac address. ++ * The application already set the master's mac address to that of the first slave ++ */ ++ if (BOND_MODE(bond) != BOND_MODE_MLO) { ++ if (!bond->params.fail_over_mac || ++ BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { ++ memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len); ++ ss.ss_family = slave_dev->type; ++ res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, ++ extack); ++ if (res) { ++ slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res); ++ goto err_restore_mtu; ++ } + } + } + +@@ -2355,6 +2390,7 @@ err_undo_flags: + + return res; + } ++EXPORT_SYMBOL(bond_enslave); + + /* Try to release the slave device from the bond device + * It is legal to access curr_active_slave without a lock because all the function +@@ -2476,13 +2512,23 @@ static int __bond_release_one(struct net + } + + bond_set_carrier(bond); +- if (!bond_has_slaves(bond)) +- eth_hw_addr_random(bond_dev); ++ ++ /* ++ * Avoid changing the mac address of bond netdevice for MLO case, ++ * This will only be supported from wifi driver. ++ */ ++ if (BOND_MODE(bond) != BOND_MODE_MLO) { ++ if (!bond_has_slaves(bond)) ++ eth_hw_addr_random(bond_dev); ++ } + + unblock_netpoll_tx(); + synchronize_rcu(); + bond->slave_cnt--; + ++ /* ++ * TODO: Avoid MAC address change notification for BOND_MODE_MLO ++ */ + if (!bond_has_slaves(bond)) { + call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); + call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); +@@ -2549,6 +2595,7 @@ int bond_release(struct net_device *bond + { + return __bond_release_one(bond_dev, slave_dev, false, false); + } ++EXPORT_SYMBOL(bond_release); + + /* First release a slave and then destroy the bond if no more slaves are left. + * Must be under rtnl_lock when this function is called. +@@ -2570,6 +2617,29 @@ static int bond_release_and_destroy(stru + return ret; + } + ++/* Destroy the bond for BOND_MODE_MLO if no more slaves are left. ++ * Must be under rtnl_lock when this function is called. ++ */ ++bool bond_destroy_mlo(struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ ++ ASSERT_RTNL(); ++ ++ if (!bond_has_slaves(bond)) { ++ bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; ++ netdev_info(bond_dev, "Destroying bond as no slaves are present\n"); ++ bond_remove_proc_entry(bond); ++ unregister_netdevice(bond_dev); ++ return true; ++ } ++ ++ pr_err("%p: Not able to destroy bond netdevice: %s as slaves are present\n", bond_dev, bond_dev->name); ++ ++ return false; ++} ++EXPORT_SYMBOL(bond_destroy_mlo); ++ + static void bond_info_query(struct net_device *bond_dev, struct ifbond *info) + { + struct bonding *bond = netdev_priv(bond_dev); +@@ -4221,6 +4291,24 @@ static struct net_device *bond_xor_get_t + return NULL; + } + ++/* Transmit function for BOND_MODE_MLO. ++ * Get transmit link interface from registered callback. ++ */ ++struct net_device *bond_mlo_get_tx_dev(struct net_device *bond_dev, u8 *dst_mac) ++{ ++ struct net_device *slave_dev = NULL; ++ struct mlo_bond_info *mlo_info = NULL; ++ void *bond_mlo_ctx; ++ ++ mlo_info = bond_get_mlo_priv(bond_dev); ++ if (mlo_info->bond_get_mlo_tx_netdev) { ++ bond_mlo_ctx = bond_get_mlo_ctx(bond_dev); ++ slave_dev = mlo_info->bond_get_mlo_tx_netdev(bond_mlo_ctx, dst_mac); ++ } ++ ++ return slave_dev; ++} ++ + /* bond_get_tx_dev - Calculate egress interface for a given packet. + * + * Supports 802.3AD and balance-xor modes +@@ -4261,6 +4349,9 @@ struct net_device *bond_get_tx_dev(struc + return bond_3ad_get_tx_dev(skb, src_mac, dst_mac, + src, dst, protocol, + bond_dev, layer4hdr); ++ case BOND_MODE_MLO: ++ return bond_mlo_get_tx_dev(bond_dev, dst_mac); ++ + default: + return NULL; + } +@@ -5057,20 +5148,26 @@ static int bond_set_mac_address(struct n + if (!is_valid_ether_addr(ss->__data)) + return -EADDRNOTAVAIL; + +- bond_for_each_slave(bond, slave, iter) { +- slave_dbg(bond_dev, slave->dev, "%s: slave=%p\n", +- __func__, slave); +- res = dev_set_mac_address(slave->dev, addr, NULL); +- if (res) { +- /* TODO: consider downing the slave +- * and retry ? +- * User should expect communications +- * breakage anyway until ARP finish +- * updating, so... +- */ +- slave_dbg(bond_dev, slave->dev, "%s: err %d\n", +- __func__, res); +- goto unwind; ++ /* ++ * Do not allow mac address change for slave netdevice for BOND_MODE_MLO ++ * as master's mac address is not same as slave's mac address. ++ */ ++ if (BOND_MODE(bond) != BOND_MODE_MLO) { ++ bond_for_each_slave(bond, slave, iter) { ++ slave_dbg(bond_dev, slave->dev, "%s: slave=%p\n", ++ __func__, slave); ++ res = dev_set_mac_address(slave->dev, addr, NULL); ++ if (res) { ++ /* TODO: consider downing the slave ++ * and retry ? ++ * User should expect communications ++ * breakage anyway until ARP finish ++ * updating, so... ++ */ ++ slave_dbg(bond_dev, slave->dev, "%s: err %d\n", ++ __func__, res); ++ goto unwind; ++ } + } + } + +@@ -5734,6 +5831,27 @@ static netdev_tx_t bond_tls_device_xmit( + } + #endif + ++/* In bond_xmit_mlo(), we send the packet and bond netdevice ++ * to registered callback for final xmit. ++ */ ++static netdev_tx_t bond_xmit_mlo(struct sk_buff *skb, struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ int slave_cnt, ret; ++ struct mlo_bond_info *mlo_info = bond_get_mlo_priv(bond_dev); ++ ++ slave_cnt = READ_ONCE(bond->slave_cnt); ++ if (unlikely(slave_cnt == 0) || unlikely(!mlo_info->bond_mlo_xmit_netdev)) { ++ bond_tx_drop(bond_dev, skb); ++ } else { ++ ret = mlo_info->bond_mlo_xmit_netdev(skb, bond_dev); ++ if (ret != NET_XMIT_SUCCESS) ++ netdev_err(bond_dev, "Xmit failed with mode %d %p\n", BOND_MODE(bond), skb); ++ } ++ ++ return NETDEV_TX_OK; ++} ++ + static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct bonding *bond = netdev_priv(dev); +@@ -5762,6 +5880,8 @@ static netdev_tx_t __bond_start_xmit(str + return bond_alb_xmit(skb, dev); + case BOND_MODE_TLB: + return bond_tlb_xmit(skb, dev); ++ case BOND_MODE_MLO: ++ return bond_xmit_mlo(skb, dev); + default: + /* Should never happen, mode already checked */ + netdev_err(dev, "Unknown bonding mode %d\n", BOND_MODE(bond)); +@@ -6104,6 +6224,15 @@ static void bond_destructor(struct net_d + if (bond->id != (~0U)) + clear_bit(bond->id, &bond_id_mask); + /* QCA NSS ECM bonding support */ ++ ++ /* ++ * Wifi driver registered callback to destroy wiphy for MLO bond netdevice ++ */ ++ if (bond_is_mlo_device(bond_dev)) { ++ if (bond->mlo_info.bond_mlo_netdev_priv_destructor) { ++ bond->mlo_info.bond_mlo_netdev_priv_destructor(bond_dev); ++ } ++ } + } + + void bond_setup(struct net_device *bond_dev) +@@ -6680,6 +6809,76 @@ out: + return res; + } + ++/* bond_create_mlo() ++ * Create bond netdevice for BOND_MODE_MLO with MLO specific callback and context. ++ */ ++struct net_device *bond_create_mlo(struct net *net, const char *name, struct mlo_bond_info *mlo_info) ++{ ++ struct net_device *bond_dev; ++ struct bonding *bond; ++ int res; ++ ++ ASSERT_RTNL(); ++ ++ bond_dev = alloc_netdev_mq(sizeof(struct bonding), ++ name ? name : "bond%d", NET_NAME_UNKNOWN, ++ bond_setup, tx_queues); ++ if (!bond_dev) { ++ pr_err("%s: eek! can't alloc netdev!\n", name); ++ return NULL; ++ } ++ ++ bond = netdev_priv(bond_dev); ++ ++ dev_net_set(bond_dev, net); ++ bond_dev->rtnl_link_ops = &bond_link_ops; ++ ++ /* ++ * MLO specific initialization. ++ */ ++ bond_dev->ieee80211_ptr = mlo_info->wdev; ++ bond->params.mode = BOND_MODE_MLO; ++ mlo_info->wdev->netdev = bond_dev; ++ ++ memcpy((void *)&bond->mlo_info, (void *)mlo_info, sizeof(*mlo_info)); ++ eth_hw_addr_random(bond_dev); ++ ++ /* ++ * Disable HW CSUM as wlan driver doesn't support ++ */ ++ bond_dev->hw_features &= ~(NETIF_F_HW_CSUM); ++ bond_dev->features &= ~(NETIF_F_HW_CSUM); ++ ++ res = register_netdevice(bond_dev); ++ if (res < 0) { ++ free_netdev(bond_dev); ++ return NULL; ++ } ++ ++ netif_carrier_off(bond_dev); ++ bond_work_init_all(bond); ++ ++ bond->id = ~0U; ++ if (bond_id_mask != (~0UL)) { ++ bond->id = (u32)ffz(bond_id_mask); ++ set_bit(bond->id, &bond_id_mask); ++ } ++ ++ return bond_dev; ++} ++EXPORT_SYMBOL(bond_create_mlo); ++ ++/* bond_get_mlo_ctx ++ * Returns MLO context stored in netdev priv of bond netdevice ++ */ ++void *bond_get_mlo_ctx(struct net_device *bond_dev) ++{ ++ struct mlo_bond_info *mlo_info = bond_get_mlo_priv(bond_dev); ++ ++ return mlo_info->bond_mlo_ctx; ++} ++EXPORT_SYMBOL(bond_get_mlo_ctx); ++ + static int __net_init bond_net_init(struct net *net) + { + struct bond_net *bn = net_generic(net, bond_net_id); +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -94,6 +94,7 @@ static const struct bond_opt_value bond_ + { "802.3ad", BOND_MODE_8023AD, 0}, + { "balance-tlb", BOND_MODE_TLB, 0}, + { "balance-alb", BOND_MODE_ALB, 0}, ++ { "mode mlo", BOND_MODE_MLO, 0}, + { NULL, -1, 0}, + }; + +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -203,6 +204,22 @@ struct bond_up_slave { + struct slave *arr[]; + }; + ++/** ++ * mlo_bond_info - mlo_bond_info structure maintains members corresponding to wifi 7 ++ * @bond_mlo_xmit_netdev: Callback function to provide skb to wifi driver for xmit ++ * @bond_get_mlo_tx_netdev: Callback function to get link interface from wifi driver for transmit ++ * @bond_mlo_ctx: Private member for wifi driver ++ * @wdev: ieee80211_ptr for wifi VAP ++ * @bond_mlo_netdev_priv_destructor: Callback function to remove wiphy instance from wifi driver ++ */ ++struct mlo_bond_info { ++ int (*bond_mlo_xmit_netdev)(struct sk_buff *skb, struct net_device *bond_dev); ++ struct net_device *(*bond_get_mlo_tx_netdev)(void *bond_mlo_ctx, void *dst); ++ void *bond_mlo_ctx; ++ struct wireless_dev *wdev; ++ void (*bond_mlo_netdev_priv_destructor)(struct net_device *bond_dev); ++}; ++ + /* + * Link pseudo-state only used internally by monitors + */ +@@ -268,6 +285,8 @@ struct bonding { + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; + u32 id; /* QCA NSS ECM bonding support */ ++ /* MLO mode info */ ++ struct mlo_bond_info mlo_info; + }; + + #define bond_slave_get_rcu(dev) \ +@@ -287,6 +306,19 @@ struct bond_vlan_tag { + bool bond_sk_check(struct bonding *bond); + + /** ++ * Returns False if the net_device is not MLO bond netdvice ++ * ++ */ ++static inline bool bond_is_mlo_device(struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ if (BOND_MODE(bond) == BOND_MODE_MLO) ++ return true; ++ ++ return false; ++} ++ ++/** + * Returns NULL if the net_device does not belong to any of the bond's slaves + * + * Caller must hold bond lock for read +@@ -650,6 +682,12 @@ static inline __be32 bond_confirm_addr(s + return addr; + } + ++static inline struct mlo_bond_info *bond_get_mlo_priv(struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ return &bond->mlo_info; ++} ++ + struct bond_net { + struct net *net; /* Associated network namespace */ + struct list_head dev_list; +@@ -663,14 +701,17 @@ int bond_rcv_validate(const struct sk_bu + netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); + int bond_get_id(struct net_device *bond_dev); /* QCA NSS ECM bonding support */ + int bond_create(struct net *net, const char *name); ++extern struct net_device *bond_create_mlo(struct net *net, const char *name, struct mlo_bond_info *mlo_info); ++extern void *bond_get_mlo_ctx(struct net_device *bond_dev); ++extern bool bond_destroy_mlo(struct net_device *bond_dev); + int bond_create_sysfs(struct bond_net *net); + void bond_destroy_sysfs(struct bond_net *net); + void bond_prepare_sysfs_group(struct bonding *bond); + int bond_sysfs_slave_add(struct slave *slave); + void bond_sysfs_slave_del(struct slave *slave); +-int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, ++extern int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, + struct netlink_ext_ack *extack); +-int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); ++extern int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); + u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb); + int bond_set_carrier(struct bonding *bond); + void bond_select_active_slave(struct bonding *bond); +--- a/include/uapi/linux/if_bonding.h ++++ b/include/uapi/linux/if_bonding.h +@@ -71,6 +71,7 @@ + #define BOND_MODE_8023AD 4 + #define BOND_MODE_TLB 5 + #define BOND_MODE_ALB 6 /* TLB + RLB (receive load balancing) */ ++#define BOND_MODE_MLO 7 /* MLO (Multi link) mode for Wi-Fi 7 AP links */ + + /* each slave's link has 4 states */ + #define BOND_LINK_UP 0 /* link is up and running */ diff --git a/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch b/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch new file mode 100644 index 000000000..08c0d4a0f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0601-qca-add-nss-bridge-mgr-support.patch @@ -0,0 +1,94 @@ +From 3c17a0e1112be70071e98d5208da5b55dcec20a6 Mon Sep 17 00:00:00 2001 +From: Simon Casey +Date: Wed, 2 Feb 2022 19:37:29 +0100 +Subject: [PATCH] Update 607-qca-add-add-nss-bridge-mgr-support.patch for kernel 5.15 + +--- + include/linux/if_bridge.h | 4 ++++ + net/bridge/br_fdb.c | 25 +++++++++++++++++++++---- + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -256,4 +256,8 @@ typedef struct net_bridge_port *br_get_d + extern br_get_dst_hook_t __rcu *br_get_dst_hook; + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br); ++/* QCA NSS bridge-mgr support - End */ ++ + #endif +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -63,6 +63,15 @@ void br_fdb_update_unregister_notify(str + EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify); + /* QCA NSS ECM support - End */ + ++/* QCA NSS bridge-mgr support - Start */ ++struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br) ++{ ++ dev_hold(br->dev); ++ return br->dev; ++} ++EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold); ++/* QCA NSS bridge-mgr support - End */ ++ + int __init br_fdb_init(void) + { + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", +@@ -573,7 +582,7 @@ void br_fdb_cleanup(struct work_struct * + unsigned long delay = hold_time(br); + unsigned long work_delay = delay; + unsigned long now = jiffies; +- u8 mac_addr[6]; /* QCA NSS ECM support */ ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* this part is tricky, in order to avoid blocking learning and + * consequently forwarding, we rely on rcu to delete objects with +@@ -601,12 +610,13 @@ void br_fdb_cleanup(struct work_struct * + } else { + spin_lock_bh(&br->hash_lock); + if (!hlist_unhashed(&f->fdb_node)) { +- ether_addr_copy(mac_addr, f->key.addr.addr); ++ memset(&fdb_event, 0, sizeof(fdb_event)); ++ ether_addr_copy(fdb_event.addr, f->key.addr.addr); + fdb_delete(br, f, true); + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, 0, +- (void *)mac_addr); ++ (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + spin_unlock_bh(&br->hash_lock); +@@ -908,6 +918,7 @@ void br_fdb_update(struct net_bridge *br + const unsigned char *addr, u16 vid, unsigned long flags) + { + struct net_bridge_fdb_entry *fdb; ++ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */ + + /* some users want to always flood. */ + if (hold_time(br) == 0) +@@ -933,6 +944,12 @@ void br_fdb_update(struct net_bridge *br + if (unlikely(source != READ_ONCE(fdb->dst) && + !test_bit(BR_FDB_STICKY, &fdb->flags))) { + br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); ++ /* QCA NSS bridge-mgr support - Start */ ++ ether_addr_copy(fdb_event.addr, addr); ++ fdb_event.br = br; ++ fdb_event.orig_dev = READ_ONCE(fdb->dst->dev); ++ fdb_event.dev = source->dev; ++ /* QCA NSS bridge-mgr support - End */ + WRITE_ONCE(fdb->dst, source); + fdb_modified = true; + /* Take over HW learned entry */ +@@ -944,7 +961,7 @@ void br_fdb_update(struct net_bridge *br + /* QCA NSS ECM support - Start */ + atomic_notifier_call_chain( + &br_fdb_update_notifier_list, +- 0, (void *)addr); ++ 0, (void *)&fdb_event); + /* QCA NSS ECM support - End */ + } + diff --git a/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch new file mode 100644 index 000000000..662edd190 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0602-qca-nss-drv-add-qdisc-support.patch @@ -0,0 +1,44 @@ +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -771,6 +771,7 @@ typedef unsigned char *sk_buff_data_t; + * @offload_fwd_mark: Packet was L2-forwarded in hardware + * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware + * @tc_skip_classify: do not classify packet. set by IFB device ++ * @tc_skip_classify_offload: do not classify packet set by offload IFB device + * @tc_at_ingress: used within tc_classify to distinguish in/egress + * @redirected: packet was redirected by packet classifier + * @from_ingress: packet was redirected from the ingress path +@@ -963,6 +964,8 @@ struct sk_buff { + #ifdef CONFIG_NET_CLS_ACT + __u8 tc_skip_classify:1; + __u8 tc_at_ingress:1; /* See TC_AT_INGRESS_MASK */ ++ __u8 tc_skip_classify_offload:1; ++ __u16 tc_verd_qca_nss; /* QCA NSS Qdisc Support */ + #endif + #ifdef CONFIG_IPV6_NDISC_NODETYPE + __u8 ndisc_nodetype:2; +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -139,6 +139,7 @@ enum tca_id { + TCA_ID_MPLS, + TCA_ID_CT, + TCA_ID_GATE, ++ TCA_ID_MIRRED_NSS, /* QCA NSS Qdisc IGS Support */ + /* other actions go here */ + __TCA_ID_MAX = 255 + }; +@@ -801,4 +802,14 @@ enum { + TCF_EM_OPND_LT + }; + ++/* QCA NSS Qdisc Support - Start */ ++#define _TC_MAKE32(x) ((x)) ++#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) ++ ++#define TC_NCLS _TC_MAKEMASK1(8) ++#define TC_NCLS_NSS _TC_MAKEMASK1(12) ++#define SET_TC_NCLS_NSS(v) ( TC_NCLS_NSS | ((v) & ~TC_NCLS_NSS)) ++#define CLR_TC_NCLS_NSS(v) ( (v) & ~TC_NCLS_NSS) ++/* QCA NSS Qdisc Support - End */ ++ + #endif diff --git a/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch new file mode 100644 index 000000000..4d74750f2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-1-qca-nss-clients-add-qdisc-support.patch @@ -0,0 +1,444 @@ +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -17,10 +17,7 @@ struct timer_list { + unsigned long expires; + void (*function)(struct timer_list *); + u32 flags; +- +-#ifdef CONFIG_SHORTCUT_FE + unsigned long cust_data; +-#endif + + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -151,6 +151,31 @@ resched: + + } + ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats) ++{ ++ struct ifb_dev_private *dp; ++ struct ifb_q_private *txp; ++ ++ if (!dev || !offload_stats) { ++ return; ++ } ++ ++ if (!(dev->priv_flags_ext & IFF_EXT_IFB)) { ++ return; ++ } ++ ++ dp = netdev_priv(dev); ++ txp = dp->tx_private; ++ ++ u64_stats_update_begin(&txp->rx_stats.sync); ++ txp->rx_stats.packets += u64_stats_read(&offload_stats->rx_packets); ++ txp->rx_stats.bytes += u64_stats_read(&offload_stats->rx_bytes); ++ txp->tx_stats.packets += u64_stats_read(&offload_stats->tx_packets); ++ txp->tx_stats.bytes += u64_stats_read(&offload_stats->tx_bytes); ++ u64_stats_update_end(&txp->rx_stats.sync); ++} ++EXPORT_SYMBOL(ifb_update_offload_stats); ++ + static void ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) + { +@@ -326,6 +351,7 @@ static void ifb_setup(struct net_device + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; ++ dev->priv_flags_ext |= IFF_EXT_IFB; /* Mark the device as an IFB device. */ + netif_keep_dst(dev); + eth_hw_addr_random(dev); + dev->needs_free_netdev = true; +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4590,6 +4590,15 @@ void dev_uc_flush(struct net_device *dev + void dev_uc_init(struct net_device *dev); + + /** ++ * ifb_update_offload_stats - Update the IFB interface stats ++ * @dev: IFB device to update the stats ++ * @offload_stats: per CPU stats structure ++ * ++ * Allows update of IFB stats when flows are offloaded to an accelerator. ++ **/ ++void ifb_update_offload_stats(struct net_device *dev, struct pcpu_sw_netstats *offload_stats); ++ ++/** + * __dev_uc_sync - Synchonize device's unicast list + * @dev: device to sync + * @sync: function to call if address should be added +@@ -5135,6 +5144,11 @@ static inline bool netif_is_failover_sla + return dev->priv_flags & IFF_FAILOVER_SLAVE; + } + ++static inline bool netif_is_ifb_dev(const struct net_device *dev) ++{ ++ return dev->priv_flags_ext & IFF_EXT_IFB; ++} ++ + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ + static inline void netif_keep_dst(struct net_device *dev) + { +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -1278,4 +1278,248 @@ enum { + + #define TCA_ETS_MAX (__TCA_ETS_MAX - 1) + ++/* QCA NSS Clients Support - Start */ ++enum { ++ TCA_NSS_ACCEL_MODE_NSS_FW, ++ TCA_NSS_ACCEL_MODE_PPE, ++ TCA_NSS_ACCEL_MODE_MAX ++}; ++ ++/* NSSFIFO section */ ++ ++enum { ++ TCA_NSSFIFO_UNSPEC, ++ TCA_NSSFIFO_PARMS, ++ __TCA_NSSFIFO_MAX ++}; ++ ++#define TCA_NSSFIFO_MAX (__TCA_NSSFIFO_MAX - 1) ++ ++struct tc_nssfifo_qopt { ++ __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRED section */ ++ ++enum { ++ TCA_NSSWRED_UNSPEC, ++ TCA_NSSWRED_PARMS, ++ __TCA_NSSWRED_MAX ++}; ++ ++#define TCA_NSSWRED_MAX (__TCA_NSSWRED_MAX - 1) ++#define NSSWRED_CLASS_MAX 6 ++struct tc_red_alg_parameter { ++ __u32 min; /* qlen_avg < min: pkts are all enqueued */ ++ __u32 max; /* qlen_avg > max: pkts are all dropped */ ++ __u32 probability;/* Drop probability at qlen_avg = max */ ++ __u32 exp_weight_factor;/* exp_weight_factor for calculate qlen_avg */ ++}; ++ ++struct tc_nsswred_traffic_class { ++ __u32 limit; /* Queue length */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* Parameters for RED alg */ ++}; ++ ++/* ++ * Weight modes for WRED ++ */ ++enum tc_nsswred_weight_modes { ++ TC_NSSWRED_WEIGHT_MODE_DSCP = 0,/* Weight mode is DSCP */ ++ TC_NSSWRED_WEIGHT_MODES, /* Must be last */ ++}; ++ ++struct tc_nsswred_qopt { ++ __u32 limit; /* Queue length */ ++ enum tc_nsswred_weight_modes weight_mode; ++ /* Weight mode */ ++ __u32 traffic_classes; /* How many traffic classes: DPs */ ++ __u32 def_traffic_class; /* Default traffic if no match: def_DP */ ++ __u32 traffic_id; /* The traffic id to be configured: DP */ ++ __u32 weight_mode_value; /* Weight mode value */ ++ struct tc_red_alg_parameter rap;/* RED algorithm parameters */ ++ struct tc_nsswred_traffic_class tntc[NSSWRED_CLASS_MAX]; ++ /* Traffic settings for dumpping */ ++ __u8 ecn; /* Setting ECN bit or dropping */ ++ __u8 set_default; /* Sets qdisc to be the default for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSCODEL section */ ++ ++enum { ++ TCA_NSSCODEL_UNSPEC, ++ TCA_NSSCODEL_PARMS, ++ __TCA_NSSCODEL_MAX ++}; ++ ++#define TCA_NSSCODEL_MAX (__TCA_NSSCODEL_MAX - 1) ++ ++struct tc_nsscodel_qopt { ++ __u32 target; /* Acceptable queueing delay */ ++ __u32 limit; /* Max number of packets that can be held in the queue */ ++ __u32 interval; /* Monitoring interval */ ++ __u32 flows; /* Number of flow buckets */ ++ __u32 quantum; /* Weight (in bytes) used for DRR of flow buckets */ ++ __u8 ecn; /* 0 - disable ECN, 1 - enable ECN */ ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++struct tc_nsscodel_xstats { ++ __u32 peak_queue_delay; /* Peak delay experienced by a dequeued packet */ ++ __u32 peak_drop_delay; /* Peak delay experienced by a dropped packet */ ++}; ++ ++/* NSSFQ_CODEL section */ ++ ++struct tc_nssfq_codel_xstats { ++ __u32 new_flow_count; /* Total number of new flows seen */ ++ __u32 new_flows_len; /* Current number of new flows */ ++ __u32 old_flows_len; /* Current number of old flows */ ++ __u32 ecn_mark; /* Number of packets marked with ECN */ ++ __u32 drop_overlimit; /* Number of packets dropped due to overlimit */ ++ __u32 maxpacket; /* The largest packet seen so far in the queue */ ++}; ++ ++/* NSSTBL section */ ++ ++enum { ++ TCA_NSSTBL_UNSPEC, ++ TCA_NSSTBL_PARMS, ++ __TCA_NSSTBL_MAX ++}; ++ ++#define TCA_NSSTBL_MAX (__TCA_NSSTBL_MAX - 1) ++ ++struct tc_nsstbl_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Limiting rate of TBF */ ++ __u32 peakrate; /* Maximum rate at which TBF is allowed to send */ ++ __u32 mtu; /* Max size of packet, or minumim burst size */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSPRIO section */ ++ ++#define TCA_NSSPRIO_MAX_BANDS 256 ++ ++enum { ++ TCA_NSSPRIO_UNSPEC, ++ TCA_NSSPRIO_PARMS, ++ __TCA_NSSPRIO_MAX ++}; ++ ++#define TCA_NSSPRIO_MAX (__TCA_NSSPRIO_MAX - 1) ++ ++struct tc_nssprio_qopt { ++ __u32 bands; /* Number of bands */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBF section */ ++ ++enum { ++ TCA_NSSBF_UNSPEC, ++ TCA_NSSBF_CLASS_PARMS, ++ TCA_NSSBF_QDISC_PARMS, ++ __TCA_NSSBF_MAX ++}; ++ ++#define TCA_NSSBF_MAX (__TCA_NSSBF_MAX - 1) ++ ++struct tc_nssbf_class_qopt { ++ __u32 burst; /* Maximum burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 mtu; /* MTU of the associated interface */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++}; ++ ++struct tc_nssbf_qopt { ++ __u16 defcls; /* Default class value */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWRR section */ ++ ++enum { ++ TCA_NSSWRR_UNSPEC, ++ TCA_NSSWRR_CLASS_PARMS, ++ TCA_NSSWRR_QDISC_PARMS, ++ __TCA_NSSWRR_MAX ++}; ++ ++#define TCA_NSSWRR_MAX (__TCA_NSSWRR_MAX - 1) ++ ++struct tc_nsswrr_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswrr_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSWFQ section */ ++ ++enum { ++ TCA_NSSWFQ_UNSPEC, ++ TCA_NSSWFQ_CLASS_PARMS, ++ TCA_NSSWFQ_QDISC_PARMS, ++ __TCA_NSSWFQ_MAX ++}; ++ ++#define TCA_NSSWFQ_MAX (__TCA_NSSWFQ_MAX - 1) ++ ++struct tc_nsswfq_class_qopt { ++ __u32 quantum; /* Weight associated to this class */ ++}; ++ ++struct tc_nsswfq_qopt { ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSHTB section */ ++ ++enum { ++ TCA_NSSHTB_UNSPEC, ++ TCA_NSSHTB_CLASS_PARMS, ++ TCA_NSSHTB_QDISC_PARMS, ++ __TCA_NSSHTB_MAX ++}; ++ ++#define TCA_NSSHTB_MAX (__TCA_NSSHTB_MAX - 1) ++ ++struct tc_nsshtb_class_qopt { ++ __u32 burst; /* Allowed burst size */ ++ __u32 rate; /* Allowed bandwidth for this class */ ++ __u32 cburst; /* Maximum burst size */ ++ __u32 crate; /* Maximum bandwidth for this class */ ++ __u32 quantum; /* Quantum allocation for DRR */ ++ __u32 priority; /* Priority value associated with this class */ ++ __u32 overhead; /* Overhead in bytes per packet */ ++}; ++ ++struct tc_nsshtb_qopt { ++ __u32 r2q; /* Rate to quantum ratio */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++ ++/* NSSBLACKHOLE section */ ++ ++enum { ++ TCA_NSSBLACKHOLE_UNSPEC, ++ TCA_NSSBLACKHOLE_PARMS, ++ __TCA_NSSBLACKHOLE_MAX ++}; ++ ++#define TCA_NSSBLACKHOLE_MAX (__TCA_NSSBLACKHOLE_MAX - 1) ++ ++struct tc_nssblackhole_qopt { ++ __u8 set_default; /* Sets qdisc to be the default qdisc for enqueue */ ++ __u8 accel_mode; /* Dictates which data plane offloads the qdisc */ ++}; ++/* QCA NSS Clients Support - End */ + #endif +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -313,6 +313,7 @@ struct Qdisc *qdisc_lookup(struct net_de + out: + return q; + } ++EXPORT_SYMBOL(qdisc_lookup); + + struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle) + { +@@ -2386,4 +2387,26 @@ static int __init pktsched_init(void) + return 0; + } + ++/* QCA NSS Qdisc Support - Start */ ++bool tcf_destroy(struct tcf_proto *tp, bool force) ++{ ++ tp->ops->destroy(tp, force, NULL); ++ module_put(tp->ops->owner); ++ kfree_rcu(tp, rcu); ++ ++ return true; ++} ++ ++void tcf_destroy_chain(struct tcf_proto __rcu **fl) ++{ ++ struct tcf_proto *tp; ++ ++ while ((tp = rtnl_dereference(*fl)) != NULL) { ++ RCU_INIT_POINTER(*fl, tp->next); ++ tcf_destroy(tp, true); ++ } ++} ++EXPORT_SYMBOL(tcf_destroy_chain); ++/* QCA NSS Qdisc Support - End */ ++ + subsys_initcall(pktsched_init); +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -1069,6 +1069,7 @@ static void __qdisc_destroy(struct Qdisc + + call_rcu(&qdisc->rcu, qdisc_free_cb); + } ++EXPORT_SYMBOL(qdisc_destroy); + + void qdisc_destroy(struct Qdisc *qdisc) + { +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -94,6 +94,7 @@ struct Qdisc { + #define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ + #define TCQ_F_NOLOCK 0x100 /* qdisc does not require locking */ + #define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */ ++#define TCQ_F_NSS 0x1000 /* NSS qdisc flag. */ + u32 limit; + const struct Qdisc_ops *ops; + struct qdisc_size_table __rcu *stab; +@@ -719,6 +720,40 @@ static inline bool skb_skip_tc_classify( + return false; + } + ++/* ++ * Set skb classify bit field. ++ */ ++static inline void skb_set_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 1; ++#endif ++} ++ ++/* ++ * Clear skb classify bit field. ++ */ ++static inline void skb_clear_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ skb->tc_skip_classify_offload = 0; ++#endif ++} ++ ++/* ++ * Skip skb processing if sent from ifb dev. ++ */ ++static inline bool skb_skip_tc_classify_offload(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NET_CLS_ACT ++ if (skb->tc_skip_classify_offload) { ++ skb_clear_tc_classify_offload(skb); ++ return true; ++ } ++#endif ++ return false; ++} ++ + /* Reset all TX qdiscs greater than index of a device. */ + static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) + { +@@ -1305,4 +1340,9 @@ static inline void qdisc_synchronize(con + msleep(1); + } + ++/* QCA NSS Qdisc Support - Start */ ++void qdisc_destroy(struct Qdisc *qdisc); ++void tcf_destroy_chain(struct tcf_proto __rcu **fl); ++/* QCA NSS Qdisc Support - End */ ++ + #endif diff --git a/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch new file mode 100644 index 000000000..7fa9184df --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-2-qca-nss-clients-add-l2tp-support.patch @@ -0,0 +1,46 @@ +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -398,6 +398,31 @@ err_tlock: + } + EXPORT_SYMBOL_GPL(l2tp_session_register); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, ++ struct l2tp_session *session, ++ struct l2tp_stats *stats) ++{ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &tunnel->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &tunnel->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &tunnel->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &tunnel->stats.tx_bytes); ++ ++ atomic_long_add(atomic_long_read(&stats->rx_packets), ++ &session->stats.rx_packets); ++ atomic_long_add(atomic_long_read(&stats->rx_bytes), ++ &session->stats.rx_bytes); ++ atomic_long_add(atomic_long_read(&stats->tx_packets), ++ &session->stats.tx_packets); ++ atomic_long_add(atomic_long_read(&stats->tx_bytes), ++ &session->stats.tx_bytes); ++} ++EXPORT_SYMBOL_GPL(l2tp_stats_update); ++ ++ + /***************************************************************************** + * Receive data handling + *****************************************************************************/ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -232,6 +232,9 @@ struct l2tp_session *l2tp_session_get_nt + struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch new file mode 100644 index 000000000..5fb9917bc --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-3-qca-nss-clients-add-PPTP-support.patch @@ -0,0 +1,478 @@ +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -36,6 +36,7 @@ struct pptp_opt { + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; ++ bool pptp_offload_mode; + }; + #include + +@@ -100,8 +101,40 @@ struct pppoe_channel_ops { + int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *); + }; + ++/* PPTP client callback */ ++typedef int (*pptp_gre_seq_offload_callback_t)(struct sk_buff *skb, ++ struct net_device *pptp_dev); ++ + /* Return PPPoE channel specific addressing information */ + extern int pppoe_channel_addressing_get(struct ppp_channel *chan, + struct pppoe_opt *addressing); + ++/* Lookup PPTP session info and return PPTP session using sip, dip and local call id */ ++extern int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr); ++ ++/* Lookup PPTP session info and return PPTP session using dip and peer call id */ ++extern int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Return PPTP session information given the channel */ ++extern void pptp_channel_addressing_get(struct pptp_opt *opt, ++ struct ppp_channel *chan); ++ ++/* Enable the PPTP session offload flag */ ++extern int pptp_session_enable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Disable the PPTP session offload flag */ ++extern int pptp_session_disable_offload_mode(__be16 peer_call_id, ++ __be32 peer_ip_addr); ++ ++/* Register the PPTP GRE packets sequence number offload callback */ ++extern int ++pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_client_cb); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++extern void pptp_unregister_gre_seq_offload_callback(void); ++ + #endif /* !(__LINUX_IF_PPPOX_H) */ +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2973,6 +2973,20 @@ char *ppp_dev_name(struct ppp_channel *c + return name; + } + ++/* Return the PPP net device index */ ++int ppp_dev_index(struct ppp_channel *chan) ++{ ++ struct channel *pch = chan->ppp; ++ int ifindex = 0; ++ ++ if (pch) { ++ read_lock_bh(&pch->upl); ++ if (pch->ppp && pch->ppp->dev) ++ ifindex = pch->ppp->dev->ifindex; ++ read_unlock_bh(&pch->upl); ++ } ++ return ifindex; ++} + + /* + * Disconnect a channel from the generic layer. +@@ -3681,6 +3695,28 @@ void ppp_update_stats(struct net_device + ppp_recv_unlock(ppp); + } + ++/* Returns true if Compression is enabled on PPP device ++ */ ++bool ppp_is_cp_enabled(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ bool flag = false; ++ ++ if (!dev) ++ return false; ++ ++ if (dev->type != ARPHRD_PPP) ++ return false; ++ ++ ppp = netdev_priv(dev); ++ ppp_lock(ppp); ++ flag = !!(ppp->xstate & SC_COMP_RUN) || !!(ppp->rstate & SC_DECOMP_RUN); ++ ppp_unlock(ppp); ++ ++ return flag; ++} ++EXPORT_SYMBOL(ppp_is_cp_enabled); ++ + /* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if + * the device is not PPP. + */ +@@ -3872,6 +3908,7 @@ EXPORT_SYMBOL(ppp_unregister_channel); + EXPORT_SYMBOL(ppp_channel_index); + EXPORT_SYMBOL(ppp_unit_number); + EXPORT_SYMBOL(ppp_dev_name); ++EXPORT_SYMBOL(ppp_dev_index); + EXPORT_SYMBOL(ppp_input); + EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -84,6 +84,9 @@ extern void ppp_unregister_channel(struc + /* Get the channel number for a channel */ + extern int ppp_channel_index(struct ppp_channel *); + ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ + /* Get the unit number associated with a channel, or -1 if none */ + extern int ppp_unit_number(struct ppp_channel *); + +@@ -116,6 +119,7 @@ extern int ppp_hold_channels(struct net_ + /* Test if ppp xmit lock is locked */ + extern bool ppp_is_xmit_locked(struct net_device *dev); + ++bool ppp_is_cp_enabled(struct net_device *dev); + /* Test if the ppp device is a multi-link ppp device */ + extern int ppp_is_multilink(struct net_device *dev); + +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -50,6 +50,8 @@ static struct proto pptp_sk_proto __read + static const struct ppp_channel_ops pptp_chan_ops; + static const struct proto_ops pptp_ops; + ++static pptp_gre_seq_offload_callback_t __rcu pptp_gre_offload_xmit_cb; ++ + static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) + { + struct pppox_sock *sock; +@@ -91,6 +93,79 @@ static int lookup_chan_dst(u16 call_id, + return i < MAX_CALLID; + } + ++/* Search a pptp session based on local call id, local and remote ip address */ ++static int lookup_session_src(struct pptp_opt *opt, u16 call_id, __be32 daddr, __be32 saddr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.src_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == daddr && ++ sock->proto.pptp.src_addr.sin_addr.s_addr == saddr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Search a pptp session based on peer call id and peer ip address */ ++static int lookup_session_dst(struct pptp_opt *opt, u16 call_id, __be32 d_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == d_addr) { ++ sock_hold(sk_pppox(sock)); ++ memcpy(opt, &sock->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* If offload mode set then this function sends all packets to ++ * offload module instead of network stack ++ */ ++static int pptp_client_skb_xmit(struct sk_buff *skb, ++ struct net_device *pptp_dev) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ int ret; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (!pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ ret = pptp_gre_offload_cb_f(skb, pptp_dev); ++ rcu_read_unlock(); ++ return ret; ++} ++ + static int add_chan(struct pppox_sock *sock, + struct pptp_addr *sa) + { +@@ -136,7 +211,7 @@ static struct rtable *pptp_route_output( + struct net *net; + + net = sock_net(sk); +- flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0, ++ flowi4_init_output(fl4, 0, sk->sk_mark, 0, + RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0, + po->proto.pptp.dst_addr.sin_addr.s_addr, + po->proto.pptp.src_addr.sin_addr.s_addr, +@@ -163,8 +238,11 @@ static int pptp_xmit(struct ppp_channel + + struct rtable *rt; + struct net_device *tdev; ++ struct net_device *pptp_dev; + struct iphdr *iph; + int max_headroom; ++ int pptp_ifindex; ++ int ret; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; +@@ -258,7 +336,32 @@ static int pptp_xmit(struct ppp_channel + ip_select_ident(net, skb, NULL); + ip_send_check(iph); + +- ip_local_out(net, skb->sk, skb); ++ pptp_ifindex = ppp_dev_index(chan); ++ ++ /* set incoming interface as the ppp interface */ ++ if (skb->skb_iif) ++ skb->skb_iif = pptp_ifindex; ++ ++ /* If the PPTP GRE seq number offload module is not enabled yet ++ * then sends all PPTP GRE packets through linux network stack ++ */ ++ if (!opt->pptp_offload_mode) { ++ ip_local_out(net, skb->sk, skb); ++ return 1; ++ } ++ ++ pptp_dev = dev_get_by_index(&init_net, pptp_ifindex); ++ if (!pptp_dev) ++ goto tx_error; ++ ++ /* If PPTP offload module is enabled then forward all PPTP GRE ++ * packets to PPTP GRE offload module ++ */ ++ ret = pptp_client_skb_xmit(skb, pptp_dev); ++ dev_put(pptp_dev); ++ if (ret < 0) ++ goto tx_error; ++ + return 1; + + tx_error: +@@ -314,6 +417,13 @@ static int pptp_rcv_core(struct sock *sk + goto drop; + + payload = skb->data + headersize; ++ ++ /* If offload is enabled, we expect the offload module ++ * to handle PPTP GRE sequence number checks ++ */ ++ if (opt->pptp_offload_mode) ++ goto allow_packet; ++ + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && +@@ -371,6 +481,7 @@ static int pptp_rcv(struct sk_buff *skb) + if (po) { + skb_dst_drop(skb); + nf_reset_ct(skb); ++ skb->skb_iif = ppp_dev_index(&po->chan); + return sk_receive_skb(sk_pppox(po), skb, 0); + } + drop: +@@ -473,7 +584,7 @@ static int pptp_connect(struct socket *s + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state |= PPPOX_CONNECTED; +- ++ opt->pptp_offload_mode = false; + end: + release_sock(sk); + return error; +@@ -603,9 +714,169 @@ static int pptp_ppp_ioctl(struct ppp_cha + return err; + } + ++/* pptp_channel_addressing_get() ++ * Return PPTP channel specific addressing information. ++ */ ++void pptp_channel_addressing_get(struct pptp_opt *opt, struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct pppox_sock *po; ++ ++ if (!opt) ++ return; ++ ++ sk = (struct sock *)chan->private; ++ if (!sk) ++ return; ++ ++ sock_hold(sk); ++ ++ /* This is very unlikely, but check the socket is connected state */ ++ if (unlikely(sock_flag(sk, SOCK_DEAD) || ++ !(sk->sk_state & PPPOX_CONNECTED))) { ++ sock_put(sk); ++ return; ++ } ++ ++ po = pppox_sk(sk); ++ memcpy(opt, &po->proto.pptp, sizeof(struct pptp_opt)); ++ sock_put(sk); ++} ++EXPORT_SYMBOL(pptp_channel_addressing_get); ++ ++/* pptp_session_find() ++ * Search and return a PPTP session info based on peer callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find(struct pptp_opt *opt, __be16 peer_call_id, ++ __be32 peer_ip_addr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_dst(opt, ntohs(peer_call_id), peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_find); ++ ++/* pptp_session_find_by_src_callid() ++ * Search and return a PPTP session info based on src callid and IP ++ * address. The function accepts the parameters in network byte order. ++ */ ++int pptp_session_find_by_src_callid(struct pptp_opt *opt, __be16 src_call_id, ++ __be32 daddr, __be32 saddr) ++{ ++ if (!opt) ++ return -EINVAL; ++ ++ return lookup_session_src(opt, ntohs(src_call_id), daddr, saddr); ++} ++EXPORT_SYMBOL(pptp_session_find_by_src_callid); ++ ++ /* Function to change the offload mode true/false for a PPTP session */ ++static int pptp_set_offload_mode(bool accel_mode, ++ __be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ struct pppox_sock *sock; ++ int i = 1; ++ ++ rcu_read_lock(); ++ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) { ++ sock = rcu_dereference(callid_sock[i]); ++ if (!sock) ++ continue; ++ ++ if (sock->proto.pptp.dst_addr.call_id == peer_call_id && ++ sock->proto.pptp.dst_addr.sin_addr.s_addr == peer_ip_addr) { ++ sock_hold(sk_pppox(sock)); ++ sock->proto.pptp.pptp_offload_mode = accel_mode; ++ sock_put(sk_pppox(sock)); ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ return -EINVAL; ++} ++ ++/* Enable the PPTP session offload flag */ ++int pptp_session_enable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(true, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_enable_offload_mode); ++ ++/* Disable the PPTP session offload flag */ ++int pptp_session_disable_offload_mode(__be16 peer_call_id, __be32 peer_ip_addr) ++{ ++ return pptp_set_offload_mode(false, peer_call_id, peer_ip_addr); ++} ++EXPORT_SYMBOL(pptp_session_disable_offload_mode); ++ ++/* Register the offload callback function on behalf of the module which ++ * will own the sequence and acknowledgment number updates for all ++ * PPTP GRE packets. All PPTP GRE packets are then transmitted to this ++ * module after encapsulation in order to ensure the correct seq/ack ++ * fields are set in the packets before transmission. This is required ++ * when PPTP flows are offloaded to acceleration engines, in-order to ++ * ensure consistency in sequence and ack numbers between PPTP control ++ * (PPP LCP) and data packets ++ */ ++int pptp_register_gre_seq_offload_callback(pptp_gre_seq_offload_callback_t ++ pptp_gre_offload_cb) ++{ ++ pptp_gre_seq_offload_callback_t pptp_gre_offload_cb_f; ++ ++ rcu_read_lock(); ++ pptp_gre_offload_cb_f = rcu_dereference(pptp_gre_offload_xmit_cb); ++ ++ if (pptp_gre_offload_cb_f) { ++ rcu_read_unlock(); ++ return -1; ++ } ++ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, pptp_gre_offload_cb); ++ rcu_read_unlock(); ++ return 0; ++} ++EXPORT_SYMBOL(pptp_register_gre_seq_offload_callback); ++ ++/* Unregister the PPTP GRE packets sequence number offload callback */ ++void pptp_unregister_gre_seq_offload_callback(void) ++{ ++ rcu_assign_pointer(pptp_gre_offload_xmit_cb, NULL); ++} ++EXPORT_SYMBOL(pptp_unregister_gre_seq_offload_callback); ++ ++/* pptp_hold_chan() */ ++static void pptp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pptp_release_chan() */ ++static void pptp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pptp_get_channel_protocol() ++ * Return the protocol type of the PPTP over PPP protocol ++ */ ++static int pptp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_PPTP; ++} ++ + static const struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, ++ .get_channel_protocol = pptp_get_channel_protocol, ++ .hold = pptp_hold_chan, ++ .release = pptp_release_chan, + }; + + static struct proto pptp_sk_proto __read_mostly = { diff --git a/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch new file mode 100644 index 000000000..df57fbd6c --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-4-qca-nss-clients-add-iptunnel-support.patch @@ -0,0 +1,77 @@ +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -36,6 +36,7 @@ struct __ip6_tnl_parm { + __u8 proto; /* tunnel protocol */ + __u8 encap_limit; /* encapsulation limit for tunnel */ + __u8 hop_limit; /* hop limit for tunnel */ ++ __u8 draft03; /* FMR using draft03 of map-e - QCA NSS Clients Support */ + bool collect_md; + __be32 flowinfo; /* traffic class and flowlabel for tunnel */ + __u32 flags; /* tunnel flags */ +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -587,4 +587,9 @@ static inline void ip_tunnel_info_opts_s + + #endif /* CONFIG_INET */ + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr); ++void ip6_update_offload_stats(struct net_device *dev, void *ptr); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __NET_IP_TUNNELS_H */ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2413,6 +2413,26 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Client Support - Start */ ++/* ++ * Update offload stats ++ */ ++void ip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ip6_update_offload_stats); ++/* QCA NSS Client Support - End */ ++ + struct net *ip6_tnl_get_link_net(const struct net_device *dev) + { + struct ip6_tnl *tunnel = netdev_priv(dev); +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1733,6 +1733,23 @@ nla_put_failure: + return -EMSGSIZE; + } + ++/* QCA NSS Clients Support - Start */ ++void ipip6_update_offload_stats(struct net_device *dev, void *ptr) ++{ ++ struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ const struct pcpu_sw_netstats *offload_stats = ++ (struct pcpu_sw_netstats *)ptr; ++ ++ u64_stats_update_begin(&tstats->syncp); ++ u64_stats_add(&tstats->tx_packets, u64_stats_read(&offload_stats->tx_packets)); ++ u64_stats_add(&tstats->tx_bytes, u64_stats_read(&offload_stats->tx_bytes)); ++ u64_stats_add(&tstats->rx_packets, u64_stats_read(&offload_stats->rx_packets)); ++ u64_stats_add(&tstats->rx_bytes, u64_stats_read(&offload_stats->rx_bytes)); ++ u64_stats_update_end(&tstats->syncp); ++} ++EXPORT_SYMBOL(ipip6_update_offload_stats); ++/* QCA NSS Clients Support - End */ ++ + static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, diff --git a/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch new file mode 100644 index 000000000..94b6201c7 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-5-qca-nss-clients-add-vxlan-support.patch @@ -0,0 +1,103 @@ +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -71,6 +71,20 @@ static inline bool vxlan_collect_metadat + ip_tunnel_collect_metadata(); + } + ++ATOMIC_NOTIFIER_HEAD(vxlan_fdb_notifier_list); ++ ++void vxlan_fdb_register_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_register(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_register_notify); ++ ++void vxlan_fdb_unregister_notify(struct notifier_block *nb) ++{ ++ atomic_notifier_chain_unregister(&vxlan_fdb_notifier_list, nb); ++} ++EXPORT_SYMBOL(vxlan_fdb_unregister_notify); ++ + #if IS_ENABLED(CONFIG_IPV6) + static int vxlan_nla_get_addr(union vxlan_addr *ip, struct nlattr *nla) + { +@@ -307,6 +321,7 @@ static void __vxlan_fdb_notify(struct vx + { + struct net *net = dev_net(vxlan->dev); + struct sk_buff *skb; ++ struct vxlan_fdb_event vfe; + int err = -ENOBUFS; + + skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC); +@@ -322,6 +337,10 @@ static void __vxlan_fdb_notify(struct vx + } + + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); ++ vfe.dev = vxlan->dev; ++ vfe.rdst = rd; ++ ether_addr_copy(vfe.eth_addr, fdb->eth_addr); ++ atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe); + return; + errout: + if (err < 0) +@@ -488,6 +507,18 @@ static struct vxlan_fdb *vxlan_find_mac( + return f; + } + ++/* Find and update age of fdb entry corresponding to MAC. */ ++void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni) ++{ ++ u32 hash_index; ++ ++ hash_index = fdb_head_index(vxlan, mac, vni); ++ spin_lock_bh(&vxlan->hash_lock[hash_index]); ++ vxlan_find_mac(vxlan, mac, vni); ++ spin_unlock_bh(&vxlan->hash_lock[hash_index]); ++} ++EXPORT_SYMBOL(vxlan_fdb_update_mac); ++ + /* caller should hold vxlan->hash_lock */ + static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f, + union vxlan_addr *ip, __be16 port, +@@ -2675,6 +2706,9 @@ static void vxlan_xmit_one(struct sk_buf + goto out_unlock; + } + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); + ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); + err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr), +@@ -2746,6 +2780,9 @@ static void vxlan_xmit_one(struct sk_buf + if (err < 0) + goto tx_error; + ++ /* Reset the skb_iif to Tunnels interface index */ ++ skb->skb_iif = dev->ifindex; ++ + udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, + &local_ip.sin6.sin6_addr, + &dst->sin6.sin6_addr, tos, ttl, +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -344,6 +344,19 @@ struct vxlan_dev { + VXLAN_F_COLLECT_METADATA | \ + VXLAN_F_VNIFILTER) + ++/* ++ * Application data for fdb notifier event ++ */ ++struct vxlan_fdb_event { ++ struct net_device *dev; ++ struct vxlan_rdst *rdst; ++ u8 eth_addr[ETH_ALEN]; ++}; ++ ++extern void vxlan_fdb_register_notify(struct notifier_block *nb); ++extern void vxlan_fdb_unregister_notify(struct notifier_block *nb); ++extern void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni); ++ + struct net_device *vxlan_dev_create(struct net *net, const char *name, + u8 name_assign_type, struct vxlan_config *conf); + diff --git a/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch b/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch new file mode 100644 index 000000000..4032eb3c2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-6-qca-nss-clients-add-l2tp-offloading-support.patch @@ -0,0 +1,368 @@ +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -61,6 +61,51 @@ struct ppp_channel { + }; + + #ifdef __KERNEL__ ++/* Call this to obtain the underlying protocol of the PPP channel, ++ * e.g. PX_PROTO_OE ++ */ ++extern int ppp_channel_get_protocol(struct ppp_channel *); ++ ++/* Call this to hold a channel */ ++extern bool ppp_channel_hold(struct ppp_channel *); ++ ++/* Call this to release a hold you have upon a channel */ ++extern void ppp_channel_release(struct ppp_channel *); ++ ++/* Release hold on PPP channels */ ++extern void ppp_release_channels(struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if ppp xmit lock is locked */ ++extern bool ppp_is_xmit_locked(struct net_device *dev); ++ ++/* Call this get protocol version */ ++extern int ppp_channel_get_proto_version(struct ppp_channel *); ++ ++/* Get the device index associated with a channel, or 0, if none */ ++extern int ppp_dev_index(struct ppp_channel *); ++ ++/* Hold PPP channels for the PPP device */ ++extern int ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++extern int __ppp_hold_channels(struct net_device *dev, ++ struct ppp_channel *channels[], ++ unsigned int chan_sz); ++ ++/* Test if the ppp device is a multi-link ppp device */ ++extern int ppp_is_multilink(struct net_device *dev); ++extern int __ppp_is_multilink(struct net_device *dev); ++ ++/* Update statistics of the PPP net_device by incrementing related ++ * statistics field value with corresponding parameter ++ */ ++extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets, ++ unsigned long rx_bytes, unsigned long tx_packets, ++ unsigned long tx_bytes, unsigned long rx_errors, ++ unsigned long tx_errors, unsigned long rx_dropped, ++ unsigned long tx_dropped); ++ + /* Called by the channel when it can send some more data. */ + extern void ppp_output_wakeup(struct ppp_channel *); + +@@ -148,5 +193,17 @@ extern void ppp_update_stats(struct net_ + * that ppp_unregister_channel returns. + */ + ++/* QCA NSS Clients Support - Start */ ++/* PPP channel connection event types */ ++#define PPP_CHANNEL_DISCONNECT 0 ++#define PPP_CHANNEL_CONNECT 1 ++ ++/* Register the PPP channel connect notifier */ ++extern void ppp_channel_connection_register_notify(struct notifier_block *nb); ++ ++/* Unregister the PPP channel connect notifier */ ++extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb); ++/* QCA NSS Clients Support - End */ ++ + #endif /* __KERNEL__ */ + #endif +--- a/include/linux/if_pppol2tp.h ++++ b/include/linux/if_pppol2tp.h +@@ -12,4 +12,30 @@ + #include + #include + ++/* QCA NSS ECM support - Start */ ++/* ++ * Holds L2TP channel info ++ */ ++struct pppol2tp_common_addr { ++ int tunnel_version; /* v2 or v3 */ ++ __u32 local_tunnel_id, remote_tunnel_id; /* tunnel id */ ++ __u32 local_session_id, remote_session_id; /* session id */ ++ struct sockaddr_in local_addr, remote_addr; /* ip address and port */ ++}; ++ ++/* ++ * L2TP channel operations ++ */ ++struct pppol2tp_channel_ops { ++ struct ppp_channel_ops ops; /* ppp channel ops */ ++}; ++ ++/* ++ * exported function which calls pppol2tp channel's get addressing ++ * function ++ */ ++extern int pppol2tp_channel_addressing_get(struct ppp_channel *, ++ struct pppol2tp_common_addr *); ++/* QCA NSS ECM support - End */ ++ + #endif +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -123,9 +123,17 @@ struct pppol2tp_session { + }; + + static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); +- +-static const struct ppp_channel_ops pppol2tp_chan_ops = { +- .start_xmit = pppol2tp_xmit, ++static int pppol2tp_get_channel_protocol(struct ppp_channel *); ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *); ++static void pppol2tp_hold_chan(struct ppp_channel *); ++static void pppol2tp_release_chan(struct ppp_channel *); ++ ++static const struct pppol2tp_channel_ops pppol2tp_chan_ops = { ++ .ops.start_xmit = pppol2tp_xmit, ++ .ops.get_channel_protocol = pppol2tp_get_channel_protocol, ++ .ops.get_channel_protocol_ver = pppol2tp_get_channel_protocol_ver, ++ .ops.hold = pppol2tp_hold_chan, ++ .ops.release = pppol2tp_release_chan, + }; + + static const struct proto_ops pppol2tp_ops; +@@ -373,6 +381,13 @@ static int pppol2tp_xmit(struct ppp_chan + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + ++ /* QCA NSS ECM support - start */ ++ /* set incoming interface as the ppp interface */ ++ if ((skb->protocol == htons(ETH_P_IP)) || ++ (skb->protocol == htons(ETH_P_IPV6))) ++ skb->skb_iif = ppp_dev_index(chan); ++ /* QCA NSS ECM support - End */ ++ + local_bh_disable(); + l2tp_xmit_skb(session, skb); + local_bh_enable(); +@@ -818,7 +833,7 @@ static int pppol2tp_connect(struct socke + po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; + + po->chan.private = sk; +- po->chan.ops = &pppol2tp_chan_ops; ++ po->chan.ops = (struct ppp_channel_ops *)&pppol2tp_chan_ops.ops; + po->chan.mtu = pppol2tp_tunnel_mtu(tunnel); + + error = ppp_register_net_channel(sock_net(sk), &po->chan); +@@ -1732,6 +1747,109 @@ static void __exit pppol2tp_exit(void) + unregister_pernet_device(&pppol2tp_net_ops); + } + ++/* QCA NSS ECM support - Start */ ++/* pppol2tp_hold_chan() */ ++static void pppol2tp_hold_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_hold(sk); ++} ++ ++/* pppol2tp_release_chan() */ ++static void pppol2tp_release_chan(struct ppp_channel *chan) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ ++ sock_put(sk); ++} ++ ++/* pppol2tp_get_channel_protocol() ++ * Return the protocol type of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol(struct ppp_channel *chan) ++{ ++ return PX_PROTO_OL2TP; ++} ++ ++/* pppol2tp_get_channel_protocol_ver() ++ * Return the protocol version of the L2TP over PPP protocol ++ */ ++static int pppol2tp_get_channel_protocol_ver(struct ppp_channel *chan) ++{ ++ struct sock *sk; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ int version = 0; ++ ++ if (chan && chan->private) ++ sk = (struct sock *)chan->private; ++ else ++ return -1; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return -1; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return -1; ++ } ++ ++ version = tunnel->version; ++ ++ sock_put(sk); ++ ++ return version; ++} ++ ++/* pppol2tp_get_addressing() */ ++static int pppol2tp_get_addressing(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ struct sock *sk = (struct sock *)chan->private; ++ struct l2tp_session *session; ++ struct l2tp_tunnel *tunnel; ++ struct inet_sock *isk = NULL; ++ int err = -ENXIO; ++ ++ /* Get session and tunnel contexts from the socket */ ++ session = pppol2tp_sock_to_session(sk); ++ if (!session) ++ return err; ++ ++ tunnel = session->tunnel; ++ if (!tunnel) { ++ sock_put(sk); ++ return err; ++ } ++ isk = inet_sk(tunnel->sock); ++ ++ addr->local_tunnel_id = tunnel->tunnel_id; ++ addr->remote_tunnel_id = tunnel->peer_tunnel_id; ++ addr->local_session_id = session->session_id; ++ addr->remote_session_id = session->peer_session_id; ++ ++ addr->local_addr.sin_port = isk->inet_sport; ++ addr->remote_addr.sin_port = isk->inet_dport; ++ addr->local_addr.sin_addr.s_addr = isk->inet_saddr; ++ addr->remote_addr.sin_addr.s_addr = isk->inet_daddr; ++ ++ sock_put(sk); ++ return 0; ++} ++ ++/* pppol2tp_channel_addressing_get() */ ++int pppol2tp_channel_addressing_get(struct ppp_channel *chan, ++ struct pppol2tp_common_addr *addr) ++{ ++ return pppol2tp_get_addressing(chan, addr); ++} ++EXPORT_SYMBOL(pppol2tp_channel_addressing_get); ++/* QCA NSS ECM support - End */ ++ + module_init(pppol2tp_init); + module_exit(pppol2tp_exit); + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -3743,6 +3743,32 @@ int ppp_is_multilink(struct net_device * + } + EXPORT_SYMBOL(ppp_is_multilink); + ++/* __ppp_is_multilink() ++ * Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 ++ * if the device is not PPP. Caller should acquire ppp_lock before calling ++ * this function ++ */ ++int __ppp_is_multilink(struct net_device *dev) ++{ ++ struct ppp *ppp; ++ unsigned int flags; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ flags = ppp->flags; ++ ++ if (flags & SC_MULTILINK) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL(__ppp_is_multilink); ++ + /* ppp_channel_get_protocol() + * Call this to obtain the underlying protocol of the PPP channel, + * e.g. PX_PROTO_OE +@@ -3881,6 +3907,59 @@ int ppp_hold_channels(struct net_device + } + EXPORT_SYMBOL(ppp_hold_channels); + ++/* __ppp_hold_channels() ++ * Returns the PPP channels of the PPP device, storing each one into ++ * channels[]. ++ * ++ * channels[] has chan_sz elements. ++ * This function returns the number of channels stored, up to chan_sz. ++ * It will return < 0 if the device is not PPP. ++ * ++ * You MUST release the channels using ppp_release_channels(). ++ */ ++int __ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[], ++ unsigned int chan_sz) ++{ ++ struct ppp *ppp; ++ int c; ++ struct channel *pch; ++ ++ if (!dev) ++ return -1; ++ ++ if (dev->type != ARPHRD_PPP) ++ return -1; ++ ++ ppp = netdev_priv(dev); ++ ++ c = 0; ++ list_for_each_entry(pch, &ppp->channels, clist) { ++ struct ppp_channel *chan; ++ ++ if (!pch->chan) { ++ /* Channel is going / gone away */ ++ continue; ++ } ++ ++ if (c == chan_sz) { ++ /* No space to record channel */ ++ return c; ++ } ++ ++ /* Hold the channel, if supported */ ++ chan = pch->chan; ++ if (!chan->ops->hold) ++ continue; ++ ++ chan->ops->hold(chan); ++ ++ /* Record the channel */ ++ channels[c++] = chan; ++ } ++ return c; ++} ++EXPORT_SYMBOL(__ppp_hold_channels); ++ + /* ppp_release_channels() + * Releases channels + */ +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -235,6 +235,9 @@ struct l2tp_session *l2tp_session_get_by + void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, + struct l2tp_stats *stats); + ++void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session, ++ struct l2tp_stats *stats); ++ + /* Tunnel and session lifetime management. + * Creation of a new instance is a two-step process: create, then register. + * Destruction is triggered using the *_delete functions, and completes asynchronously. diff --git a/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch new file mode 100644 index 000000000..17c0fe3c9 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-7-qca-nss-clients-iptunnel-lock-this-cpu.patch @@ -0,0 +1,22 @@ +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -2419,7 +2419,7 @@ nla_put_failure: + */ + void ip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1736,7 +1736,7 @@ nla_put_failure: + /* QCA NSS Clients Support - Start */ + void ipip6_update_offload_stats(struct net_device *dev, void *ptr) + { +- struct pcpu_sw_netstats *tstats = per_cpu_ptr(dev->tstats, 0); ++ struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + const struct pcpu_sw_netstats *offload_stats = + (struct pcpu_sw_netstats *)ptr; + diff --git a/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch b/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch new file mode 100644 index 000000000..0499e237f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0603-8-qca-nss-clients-add-tls-mgr-support.patch @@ -0,0 +1,24 @@ +--- /dev/null ++++ b/include/uapi/linux/tlshdr.h +@@ -0,0 +1,21 @@ ++#ifndef _UAPI_LINUX_TLSHDR_H ++#define _UAPI_LINUX_TLSHDR_H ++ ++#include ++ ++struct tlshdr { ++ __u8 type; ++ __be16 version; ++ __be16 len; ++} __attribute__((packed)); ++ ++#define TLSHDR_REC_TYPE_CCS 20 /* TLS packet is change cipher specification */ ++#define TLSHDR_REC_TYPE_ALERT 21 /* TLS packet is Alert */ ++#define TLSHDR_REC_TYPE_HANDSHAKE 22 /* TLS packet is Handshake */ ++#define TLSHDR_REC_TYPE_DATA 23 /* TLS packet is Application data */ ++ ++#define TLSHDR_VERSION_1_1 0x0302 /* TLS Header Version(tls 1.1) */ ++#define TLSHDR_VERSION_1_2 0x0303 /* TLS Header Version(tls 1.2) */ ++#define TLSHDR_VERSION_1_3 0x0304 /* TLS Header Version(tls 1.3) */ ++ ++#endif /* _UAPI_LINUX_TLSHDR_H */ diff --git a/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch new file mode 100644 index 000000000..67e85a18f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0605-qca-nss-cfi-support.patch @@ -0,0 +1,111 @@ +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -417,6 +417,8 @@ static int crypto_authenc_create(struct + enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + ++ inst->alg.base.cra_flags |= (auth_base->cra_flags | ++ enc->base.cra_flags) & CRYPTO_ALG_NOSUPP_SG; + inst->alg.base.cra_priority = enc->base.cra_priority * 10 + + auth_base->cra_priority; + inst->alg.base.cra_blocksize = enc->base.cra_blocksize; +--- a/include/linux/crypto.h ++++ b/include/linux/crypto.h +@@ -101,6 +101,11 @@ + #define CRYPTO_NOLOAD 0x00008000 + + /* ++ * Set this flag if algorithm does not support SG list transforms ++ */ ++#define CRYPTO_ALG_NOSUPP_SG 0x0000c000 ++ ++/* + * The algorithm may allocate memory during request processing, i.e. during + * encryption, decryption, or hashing. Users can request an algorithm with this + * flag unset if they can't handle memory allocation failures. +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -658,6 +658,7 @@ static int esp_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -669,6 +670,11 @@ static int esp_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -890,6 +896,7 @@ static int esp_input(struct xfrm_state * + u8 *iv; + struct scatterlist *sg; + int err = -EINVAL; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) + goto out; +@@ -897,6 +904,12 @@ static int esp_input(struct xfrm_state * + if (elen <= 0) + goto out; + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ err = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -696,6 +696,7 @@ static int esp6_output(struct xfrm_state + struct ip_esp_hdr *esph; + struct crypto_aead *aead; + struct esp_info esp; ++ bool nosupp_sg; + + esp.inplace = true; + +@@ -707,6 +708,11 @@ static int esp6_output(struct xfrm_state + aead = x->data; + alen = crypto_aead_authsize(aead); + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ return -ENOMEM; ++ } ++ + esp.tfclen = 0; + if (x->tfcpad) { + struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb); +@@ -934,6 +940,7 @@ static int esp6_input(struct xfrm_state + __be32 *seqhi; + u8 *iv; + struct scatterlist *sg; ++ bool nosupp_sg; + + if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + ivlen)) { + ret = -EINVAL; +@@ -945,6 +952,12 @@ static int esp6_input(struct xfrm_state + goto out; + } + ++ nosupp_sg = crypto_tfm_alg_type(&aead->base) & CRYPTO_ALG_NOSUPP_SG; ++ if (nosupp_sg && skb_linearize(skb)) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ + assoclen = sizeof(struct ip_esp_hdr); + seqhilen = 0; + diff --git a/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch new file mode 100644 index 000000000..25f99fc4a --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0611-ipv6-Fix-null-pointer-dereference-in-ipv6-output.patch @@ -0,0 +1,80 @@ +From eee3a7956b943dd3e23a74fbb5bfe89405eb0782 Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Mon, 6 Dec 2021 17:34:47 +0100 +Subject: UBUNTU: SAUCE: ipv6: fix NULL pointer dereference in ip6_output() + +It is possible to trigger a NULL pointer dereference by running the srv6 +net kselftest (tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh): + +[ 249.051216] BUG: kernel NULL pointer dereference, address: 0000000000000378 +[ 249.052331] #PF: supervisor read access in kernel mode +[ 249.053137] #PF: error_code(0x0000) - not-present page +[ 249.053960] PGD 0 P4D 0 +[ 249.054376] Oops: 0000 [#1] PREEMPT SMP NOPTI +[ 249.055083] CPU: 1 PID: 21 Comm: ksoftirqd/1 Tainted: G E 5.16.0-rc4 #2 +[ 249.056328] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 +[ 249.057632] RIP: 0010:ip6_forward+0x53c/0xab0 +[ 249.058354] Code: 49 c7 44 24 20 00 00 00 00 48 83 e0 fe 48 8b 40 30 48 3d 70 b2 b5 81 0f 85 b5 04 00 00 e8 7c f2 ff ff 41 89 c5 e9 17 01 00 00 <44> 8b 93 78 03 00 00 45 85 d2 0f 85 92 fb ff ff 49 8b 54 24 10 48 +[ 249.061274] RSP: 0018:ffffc900000cbb30 EFLAGS: 00010246 +[ 249.062042] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff8881051d3400 +[ 249.063141] RDX: ffff888104bda000 RSI: 00000000000002c0 RDI: 0000000000000000 +[ 249.064264] RBP: ffffc900000cbbc8 R08: 0000000000000000 R09: 0000000000000000 +[ 249.065376] R10: 0000000000000040 R11: 0000000000000000 R12: ffff888103409800 +[ 249.066498] R13: ffff8881051d3410 R14: ffff888102725280 R15: ffff888103525000 +[ 249.067619] FS: 0000000000000000(0000) GS:ffff88813bc80000(0000) knlGS:0000000000000000 +[ 249.068881] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 249.069777] CR2: 0000000000000378 CR3: 0000000104980000 CR4: 0000000000750ee0 +[ 249.070907] PKRU: 55555554 +[ 249.071337] Call Trace: +[ 249.071730] +[ 249.072070] ? debug_smp_processor_id+0x17/0x20 +[ 249.072807] seg6_input_core+0x2bb/0x2d0 +[ 249.073436] ? _raw_spin_unlock_irqrestore+0x29/0x40 +[ 249.074225] seg6_input+0x3b/0x130 +[ 249.074768] lwtunnel_input+0x5e/0xa0 +[ 249.075357] ip_rcv+0x17b/0x190 +[ 249.075867] ? update_load_avg+0x82/0x600 +[ 249.076514] __netif_receive_skb_one_core+0x86/0xa0 +[ 249.077231] __netif_receive_skb+0x15/0x60 +[ 249.077843] process_backlog+0x97/0x160 +[ 249.078389] __napi_poll+0x31/0x170 +[ 249.078912] net_rx_action+0x229/0x270 +[ 249.079506] __do_softirq+0xef/0x2ed +[ 249.080085] run_ksoftirqd+0x37/0x50 +[ 249.080663] smpboot_thread_fn+0x193/0x230 +[ 249.081312] kthread+0x17a/0x1a0 +[ 249.081847] ? smpboot_register_percpu_thread+0xe0/0xe0 +[ 249.082677] ? set_kthread_struct+0x50/0x50 +[ 249.083340] ret_from_fork+0x22/0x30 +[ 249.083926] +[ 249.090295] ---[ end trace 1998d7ba5965a365 ]--- + +It looks like commit 0857d6f8c759 ("ipv6: When forwarding count rx stats +on the orig netdev") tries to determine the right netdev to account the +rx stats, but in this particular case it's failing and the netdev is +NULL. + +Fallback to the previous method of determining the netdev interface (via +skb->dev) to account the rx stats when the orig netdev can't be +determined. + +Fixes: 0857d6f8c759 ("ipv6: When forwarding count rx stats on the orig netdev") +Signed-off-by: Andrea Righi +(cherry picked from https://lore.kernel.org/lkml/20211206163447.991402-1-andrea.righi@canonical.com/T/#u) +Signed-off-by: Andrea Righi +--- + net/ipv6/ip6_output.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -498,6 +498,9 @@ int ip6_forward(struct sk_buff *skb) + u32 mtu; + + idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); ++ if (unlikely(!idev)) ++ idev = __in6_dev_get_safely(skb->dev); ++ + if (net->ipv6.devconf_all->forwarding == 0) + goto error; + diff --git a/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts b/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts index 20f63902a..a9659a6e8 100644 --- a/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts +++ b/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts @@ -67,8 +67,8 @@ flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <80000000>; - m25p,fast-read; + spi-max-frequency = <50000000>; + broken-flash-reset; partitions { compatible = "fixed-partitions"; diff --git a/target/linux/ramips/dts/mt7621_h3c_tx1800-plus.dts b/target/linux/ramips/dts/mt7621_h3c_tx1800-plus.dts new file mode 100644 index 000000000..f763dd14d --- /dev/null +++ b/target/linux/ramips/dts/mt7621_h3c_tx1800-plus.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621_h3c_tx180x.dtsi" + +/ { + compatible = "h3c,tx1800-plus", "mediatek,mt7621-soc"; + model = "H3C TX1800 Plus"; +}; diff --git a/target/linux/ramips/dts/mt7621_h3c_tx1801-plus.dts b/target/linux/ramips/dts/mt7621_h3c_tx1801-plus.dts new file mode 100644 index 000000000..4588b142c --- /dev/null +++ b/target/linux/ramips/dts/mt7621_h3c_tx1801-plus.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621_h3c_tx180x.dtsi" + +/ { + compatible = "h3c,tx1801-plus", "mediatek,mt7621-soc"; + model = "H3C TX1801 Plus"; +}; diff --git a/target/linux/ramips/dts/mt7621_h3c_tx1806.dts b/target/linux/ramips/dts/mt7621_h3c_tx1806.dts new file mode 100644 index 000000000..1e9b6456e --- /dev/null +++ b/target/linux/ramips/dts/mt7621_h3c_tx1806.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621_h3c_tx180x.dtsi" + +/ { + compatible = "h3c,tx1806", "mediatek,mt7621-soc"; + model = "H3C TX1806"; +}; diff --git a/target/linux/ramips/dts/mt7621_h3c_tx180x.dtsi b/target/linux/ramips/dts/mt7621_h3c_tx180x.dtsi new file mode 100644 index 000000000..25773b971 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_h3c_tx180x.dtsi @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + aliases { + led-boot = &led_status_amber; + led-failsafe = &led_status_green; + led-running = &led_status_green; + led-upgrade = &led_status_amber; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + bootargs-override = "console=ttyS0,115200"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + wps { + label = "wps"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_status_amber: led-0 { + label = "amber:status"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led_status_green: led-1 { + label = "green:status"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gmac1 { + status = "okay"; +}; + +&nand { + status = "okay"; + + mediatek,nmbm; + mediatek,bmt-max-ratio = <1>; + mediatek,bmt-max-reserved-blocks = <64>; + mediatek,bmt-remap-range = <0x0000000 0x0a00000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "u-boot-env"; + reg = <0x0080000 0x0080000>; + }; + + partition@100000 { + label = "exp"; + reg = <0x0100000 0x0080000>; + read-only; + }; + + factory: partition@180000 { + label = "factory"; + reg = <0x0180000 0x0080000>; + read-only; + }; + + partition@200000 { + label = "firmware"; + reg = <0x0200000 0x7600000>; + + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "kernel"; + reg = <0x0000000 0x0800000>; + }; + + partition@800000 { + label = "ubi"; + reg = <0x0800000 0x6e00000>; + }; + }; + + /* last 8 MiB is reserved for NMBM bad block table */ + }; +}; + +&pcie { + status = "okay"; +}; + +&pcie1 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0>; + mediatek,disable-radar-background; + }; +}; + +&pcie2 { + status = "disabled"; +}; + +&state_default { + gpio { + groups = "jtag"; + function = "gpio"; + }; +}; + +&switch0 { + ports { + port@1 { + status = "okay"; + label = "lan1"; + }; + + port@2 { + status = "okay"; + label = "lan2"; + }; + + port@3 { + status = "okay"; + label = "lan3"; + }; + + port@4 { + status = "okay"; + label = "wan"; + }; + }; +}; + +&xhci { + status = "disabled"; +}; diff --git a/target/linux/ramips/dts/mt7621_jdcloud_re-cp-02.dts b/target/linux/ramips/dts/mt7621_jdcloud_re-cp-02.dts new file mode 100644 index 000000000..09330fc1a --- /dev/null +++ b/target/linux/ramips/dts/mt7621_jdcloud_re-cp-02.dts @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "mt7621.dtsi" + +#include +#include + +/ { + compatible = "jdcloud,re-cp-02", "mediatek,mt7621-soc"; + model = "JDCloud RE-CP-02"; + + aliases { + label-mac-device = &gmac0; + led-boot = &led_status_blue; + led-failsafe = &led_status_red; + led-running = &led_status_green; + led-upgrade = &led_status_blue; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led_status_red: red { + label = "red:status"; + gpios = <&gpio 6 GPIO_ACTIVE_LOW>; + }; + + led_status_blue: blue { + label = "blue:status"; + gpios = <&gpio 7 GPIO_ACTIVE_LOW>; + }; + + led_status_green: green { + label = "green:status"; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + }; + }; + + keys { + compatible = "gpio-keys"; + + wps { + label = "wps"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset { + label = "reset"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0x0 0x40000>; + read-only; + }; + + partition@40000 { + compatible = "u-boot,env"; + label = "Config"; + reg = <0x40000 0x10000>; + }; + + factory: partition@50000 { + label = "Factory"; + reg = <0x50000 0x40000>; + read-only; + }; + + partition@90000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x90000 0xf70000>; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "uart3", "jtag", "wdt"; + function = "gpio"; + }; +}; + +&sdhci { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +&pcie1 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0>; + mediatek,disable-radar-background; + }; +}; + +&gmac0 { + mtd-mac-address = <&factory 0x3fff4>; +}; + +&gmac1 { + mtd-mac-address = <&factory 0x3fffa>; + status = "okay"; +}; + +&switch0 { + ports { + port@1 { + status = "okay"; + label = "lan1"; + }; + + port@2 { + status = "okay"; + label = "lan2"; + }; + + port@3 { + status = "okay"; + label = "lan3"; + }; + + port@4 { + status = "okay"; + label = "wan"; + mtd-mac-address = <&factory 0x3fffa>; + }; + }; +}; + +&xhci { + status = "disabled"; +}; diff --git a/target/linux/ramips/dts/mt7621_leigod_a7000.dts b/target/linux/ramips/dts/mt7621_leigod_a7000.dts index 292d22f71..a7b08d527 100644 --- a/target/linux/ramips/dts/mt7621_leigod_a7000.dts +++ b/target/linux/ramips/dts/mt7621_leigod_a7000.dts @@ -88,10 +88,10 @@ reg = <0x50000 0x1e00000>; }; - partition@1f00000 { - label = "sysinfo"; - reg = <0x1f00000 0x10000>; - }; + partition@1f00000 { + label = "sysinfo"; + reg = <0x1f00000 0x10000>; + }; }; }; }; @@ -137,7 +137,7 @@ &state_default { gpio { - groups = "jtag", "wdt"; + groups = "jtag", "uart3", "wdt"; function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts b/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts index 811b02fe0..ce1931d9d 100644 --- a/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts +++ b/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts @@ -3,6 +3,18 @@ / { compatible = "mediatek,ap-mt7621a-v60", "mediatek,mt7621-soc"; model = "Mediatek AP-MT7621A-V60 EVB"; + + chosen { + bootargs = "console=ttyS0,57600"; + }; + + watchdog: watchdog { + compatible = "linux,wdt-gpio"; + gpios = <&gpio 27 0>; + hw_algo = "toggle"; + hw_margin_ms = <3000>; + always-running; + }; sound { compatible = "simple-audio-card"; @@ -38,6 +50,12 @@ }; &pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "rgmii2", "jtag"; + ralink,function = "gpio"; + }; + }; i2s_pins: i2s { i2s { groups = "uart3"; @@ -72,9 +90,10 @@ status = "okay"; flash@0 { - compatible = "mx25l6405d","jedec,spi-nor"; + compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <10000000>; + spi-max-frequency = <45000000>; + broken-flash-reset; partitions { compatible = "fixed-partitions"; @@ -102,7 +121,7 @@ partition@50000 { compatible = "denx,uimage"; label = "firmware"; - reg = <0x50000 0x7b0000>; + reg = <0x50000 0x1fb0000>; }; }; }; diff --git a/target/linux/ramips/dts/mt7621_openfi_5pro.dts b/target/linux/ramips/dts/mt7621_openfi_5pro.dts new file mode 100644 index 000000000..1ef292a78 --- /dev/null +++ b/target/linux/ramips/dts/mt7621_openfi_5pro.dts @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7621.dtsi" + +#include +#include +#include + +/ { + compatible = "openfi,5pro", "mediatek,mt7621-soc"; + model = "OpenFi 5Pro"; + + aliases { + led-boot = &led_system_blue; + led-failsafe = &led_system_blue; + led-running = &led_system_blue; + led-upgrade = &led_system_blue; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + wps { + label = "wps"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_system_blue: led-0 { + label = "blue:system"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + led_internet_blue: led-1 { + label = "blue:internet"; + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + + led_wifi_blue: led-2 { + label = "blue:wifi"; + color = ; + linux,default-trigger = "phy0tpt"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <45000000>; + broken-flash-reset; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bootloader"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "config"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x50000 0x3f00000>; + }; + }; + }; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + mt76@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0>; + ieee80211-freq-limit = <2400000 2500000>; + }; +}; + +&pcie1 { + mt76@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&gmac0 { + mtd-mac-address = <&factory 0xe000>; +}; + +&switch0 { + ports { + port@0 { + status = "okay"; + label = "wan"; + mtd-mac-address = <&factory 0xe006>; + }; + + port@1 { + status = "okay"; + label = "lan"; + }; + }; +}; + +&state_default { + gpio { + groups = "wdt", "jtag"; + function = "gpio"; + }; +}; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index f759d4857..cb3382f7f 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -40,6 +40,12 @@ define Build/hatlab-gateboard-combined 256 endef +define Build/h3c-blank-header + dd if=/dev/zero of=$@.blank bs=160 count=1 + cat $@ >> $@.blank + mv $@.blank $@ +endef + define Build/hatlab-gateboard-kernel rm -fR $@.initrd rm -fR $@.initrd.cpio @@ -733,7 +739,7 @@ define Device/glinet_gl-mt1300 DEVICE_MODEL := GL-MT1300 DEVICE_PACKAGES := kmod-mt7615-firmware kmod-usb3 -uboot-envtools endef -#TARGET_DEVICES += glinet_gl-mt1300 +TARGET_DEVICES += glinet_gl-mt1300 define Device/gnubee_gb-pc1 $(Device/dsa-migration) @@ -755,6 +761,40 @@ define Device/gnubee_gb-pc2 endef TARGET_DEVICES += gnubee_gb-pc2 +define Device/h3c_tx180x + $(Device/dsa-migration) + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 8192k + IMAGE_SIZE := 120832k + UBINIZE_OPTS := -E 5 + KERNEL_LOADADDR := 0x82000000 + KERNEL_INITRAMFS := kernel-bin | relocate-kernel 0x80001000 | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb + KERNEL := $$(KERNEL_INITRAMFS) | h3c-blank-header + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata + DEVICE_VENDOR := H3C + DEVICE_PACKAGES := kmod-mt7915e uboot-envtools +endef + +define Device/h3c_tx1800-plus + $(Device/h3c_tx180x) + DEVICE_MODEL := TX1800 Plus +endef +TARGET_DEVICES += h3c_tx1800-plus + +define Device/h3c_tx1801-plus + $(Device/h3c_tx180x) + DEVICE_MODEL := TX1801 Plus +endef +TARGET_DEVICES += h3c_tx1801-plus + +define Device/h3c_tx1806 + $(Device/h3c_tx180x) + DEVICE_MODEL := TX1806 +endef +TARGET_DEVICES += h3c_tx1806 + define Device/hatlab_gateboard-one $(Device/dsa-migration) DEVICE_VENDOR := HATLab @@ -990,6 +1030,15 @@ define Device/jcg_y2 endef TARGET_DEVICES += jcg_y2 +define Device/jdcloud_re-cp-02 + $(Device/dsa-migration) + IMAGE_SIZE := 16000k + DEVICE_VENDOR := JD-Cloud + DEVICE_MODEL := RE-CP-02 + DEVICE_PACKAGES := kmod-mt7915-firmware kmod-sdhci-mt7620 +endef +TARGET_DEVICES += jdcloud_re-cp-02 + define Device/jdcloud_re-sp-01b $(Device/dsa-migration) IMAGE_SIZE := 27328k @@ -1102,10 +1151,11 @@ TARGET_DEVICES += linksys_re6500 define Device/mediatek_ap-mt7621a-v60 $(Device/dsa-migration) - IMAGE_SIZE := 7872k + $(Device/uimage-lzma-loader) + IMAGE_SIZE := 32448k DEVICE_VENDOR := Mediatek DEVICE_MODEL := AP-MT7621A-V60 EVB - DEVICE_PACKAGES := kmod-usb3 kmod-sdhci-mt7620 kmod-sound-mt7620 -wpad-openssl + DEVICE_PACKAGES := kmod-usb3 kmod-i2c-gpio kmod-rtc-pcf8563 kmod-sdhci-mt7620 kmod-sound-mt7620 kmod-mt76x2 endef TARGET_DEVICES += mediatek_ap-mt7621a-v60 @@ -1360,6 +1410,15 @@ define Device/netis_wf2881 endef TARGET_DEVICES += netis_wf2881 +define Device/openfi_5pro + $(Device/dsa-migration) + IMAGE_SIZE := 63448k + DEVICE_VENDOR := OpenFi + DEVICE_MODEL := 5Pro + DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap kmod-usb3 +endef +TARGET_DEVICES += openfi_5pro + define Device/oraybox_x3a $(Device/dsa-migration) $(Device/uimage-lzma-loader) @@ -1376,7 +1435,7 @@ define Device/phicomm_k2p DEVICE_MODEL := K2P SUPPORTED_DEVICES += k2p DEVICE_COMPAT_VERSION := 1.1 - DEVICE_PACKAGES := -luci-newapi -wpad-openssl kmod-mt7615d_dbdc wireless-tools + DEVICE_PACKAGES := -wpad-openssl kmod-mt7615d_dbdc wireless-tools luci-oldapi endef TARGET_DEVICES += phicomm_k2p diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network index a8461319a..6d5d8265d 100644 --- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network @@ -22,11 +22,16 @@ ramips_setup_interfaces() ucidef_set_interface_lan "lan" ;; ampedwireless,ally-r1900k|\ + h3c,tx1800-plus|\ + h3c,tx1801-plus|\ + h3c,tx1806|\ hiwifi,hc5962|\ + jdcloud,re-cp-02|\ xiaomi,mi-router-3-pro) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan" ;; asiarf,ap7621-001|\ + openfi,5pro|\ winstars,ws-wn583a6) ucidef_set_interfaces_lan_wan "lan" "wan" ;; @@ -180,6 +185,13 @@ ramips_setup_macs() wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr) label_mac=$wan_mac ;; + h3c,tx1800-plus|\ + h3c,tx1801-plus|\ + h3c,tx1806) + label_mac=$(mtd_get_mac_ascii u-boot-env ethaddr) + lan_mac=$(macaddr_add "$label_mac" 1) + wan_mac=$label_mac + ;; hiwifi,hc5962) lan_mac=$(mtd_get_mac_ascii bdinfo "Vfac_mac ") label_mac=$lan_mac diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index 052081209..979950370 100644 --- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -31,6 +31,13 @@ case "$board" in [ "$PHYNBR" = "1" ] && \ macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1 > /sys${DEVPATH}/macaddress ;; + h3c,tx1800-plus|\ + h3c,tx1801-plus|\ + h3c,tx1806) + addr=$(macaddr_setbit $(macaddr_add $(mtd_get_mac_ascii u-boot-env ethaddr) 2) 7) + [ "$PHYNBR" = "0" ] && echo -n ${addr:0:9}'1'${addr:10:7} > /sys${DEVPATH}/macaddress + [ "$PHYNBR" = "1" ] && echo -n ${addr:0:9}'7'${addr:10:7} > /sys${DEVPATH}/macaddress + ;; jcg,q20) [ "$PHYNBR" = "1" ] && \ macaddr_setbit_la "$(mtd_get_mac_binary Factory 0x4)" > /sys${DEVPATH}/macaddress diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount index 276d8bccc..1db873387 100755 --- a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount +++ b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount @@ -13,6 +13,9 @@ boot() { $((0xFF)) ]] || printf '\xff' | dd of=/dev/mtdblock3 count=1 \ bs=1 seek=$((0x20001)) ;; + jdcloud,re-cp-02) + echo -e "bootcount 0\nbootlimit 5\nupgrade_available 1" | /usr/sbin/fw_setenv -s - + ;; linksys,e5600|\ linksys,ea7300-v1|\ linksys,ea7300-v2|\ diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh index 427c39c06..0df5e8cde 100755 --- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh @@ -82,6 +82,9 @@ platform_do_upgrade() { dlink,dir-2640-a1|\ dlink,dir-2660-a1|\ dlink,dir-853-a3|\ + h3c,tx1800-plus|\ + h3c,tx1801-plus|\ + h3c,tx1806|\ hiwifi,hc5962|\ jcg,q20|\ linksys,e5600|\ @@ -106,7 +109,8 @@ platform_do_upgrade() { xiaomi,mi-router-4|\ xiaomi,mi-router-ac2100|\ xiaomi,mi-router-cr660x|\ - xiaomi,redmi-router-ac2100) + xiaomi,redmi-router-ac2100|\ + zte,e8820s) nand_do_upgrade "$1" ;; hatlab,gateboard-one) diff --git a/target/linux/ramips/patches-5.10/902-mtkhnat-fix-pskb-expand-head-limitation.patch b/target/linux/ramips/patches-5.10/902-mtkhnat-fix-pskb-expand-head-limitation.patch index 9bd7432de..53b3b1b5b 100644 --- a/target/linux/ramips/patches-5.10/902-mtkhnat-fix-pskb-expand-head-limitation.patch +++ b/target/linux/ramips/patches-5.10/902-mtkhnat-fix-pskb-expand-head-limitation.patch @@ -1,6 +1,6 @@ --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -70,6 +70,7 @@ +@@ -71,6 +71,7 @@ #include #include #include @@ -8,7 +8,7 @@ #include #include -@@ -1686,6 +1687,9 @@ int pskb_expand_head(struct sk_buff *skb +@@ -1693,6 +1694,9 @@ int pskb_expand_head(struct sk_buff *skb skb_shinfo(skb), offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); diff --git a/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch index cd3c3e262..fa1906c22 100644 --- a/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch +++ b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch @@ -14,7 +14,7 @@ Signed-off-by: René van Dorst --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4618,6 +4618,7 @@ static const struct net_device_ops mtk_n +@@ -4555,6 +4555,7 @@ static const struct net_device_ops mtk_n static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) { @@ -22,7 +22,7 @@ Signed-off-by: René van Dorst const __be32 *_id = of_get_property(np, "reg", NULL); phy_interface_t phy_mode; struct phylink *phylink; -@@ -4787,6 +4788,9 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4726,6 +4727,9 @@ static int mtk_add_mac(struct mtk_eth *e register_netdevice_notifier(&mac->device_notifier); } diff --git a/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch index f04a264a0..25737eb8a 100644 --- a/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch +++ b/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch @@ -71,7 +71,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c break; --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1032,14 +1032,16 @@ struct phy_device *phy_find_first(struct +@@ -1035,14 +1035,16 @@ struct phy_device *phy_find_first(struct } EXPORT_SYMBOL(phy_find_first); @@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c phydev->mii_ts->link_state(phydev->mii_ts, phydev); --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -1334,7 +1334,8 @@ void phylink_destroy(struct phylink *pl) +@@ -1381,7 +1381,8 @@ void phylink_destroy(struct phylink *pl) } EXPORT_SYMBOL_GPL(phylink_destroy); @@ -107,7 +107,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c bool tx_pause, rx_pause; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -703,7 +703,7 @@ struct phy_device { +@@ -706,7 +706,7 @@ struct phy_device { u8 mdix; u8 mdix_ctrl; diff --git a/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch index d80877b41..5205a8f93 100644 --- a/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch +++ b/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch @@ -37,7 +37,7 @@ Signed-off-by: John Crispin break; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -620,6 +620,7 @@ struct phy_device { +@@ -622,6 +622,7 @@ struct phy_device { unsigned downshifted_rate:1; unsigned is_on_sfp_module:1; unsigned mac_managed_pm:1; diff --git a/target/linux/ramips/patches-5.4/993-spi-nor-w25q512jv.patch b/target/linux/ramips/patches-5.4/993-spi-nor-w25q512jv.patch new file mode 100644 index 000000000..c02f4e533 --- /dev/null +++ b/target/linux/ramips/patches-5.4/993-spi-nor-w25q512jv.patch @@ -0,0 +1,25 @@ +From: David Bauer +Date: Thu, 11 Feb 2021 19:57:26 +0100 +Subject: [PATCH] mtd: spi-nor: add support for Winbond W25Q512 + +The Winbond W25Q512 is a 512mb SPI-NOR chip. It supports 4K sectors as +well as block protection and Dual-/Quad-read. + +Tested on: Ubiquiti UniFi 6 LR + +Signed-off-by: David Bauer + +Ref: https://patchwork.ozlabs.org/project/linux-mtd/patch/20210213151047.11700-1-mail@david-bauer.net/ + +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -2567,6 +2567,9 @@ static const struct flash_info spi_nor_i + .fixups = &w25q256_fixups }, + { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, ++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ | ++ SPI_NOR_HAS_TB | SPI_NOR_HAS_LOCK) }, + { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, + diff --git a/target/linux/sifiveu/patches-5.15/0002-riscv-sifive-unmatched-update-regulators-values.patch b/target/linux/sifiveu/patches-5.15/0002-riscv-sifive-unmatched-update-regulators-values.patch index ac316e9d9..13df2e613 100644 --- a/target/linux/sifiveu/patches-5.15/0002-riscv-sifive-unmatched-update-regulators-values.patch +++ b/target/linux/sifiveu/patches-5.15/0002-riscv-sifive-unmatched-update-regulators-values.patch @@ -20,7 +20,7 @@ Signed-off-by: David Abdurachmanov --- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts +++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -@@ -73,16 +73,16 @@ +@@ -74,16 +74,16 @@ regulators { vdd_bcore1: bcore1 { @@ -41,7 +41,7 @@ Signed-off-by: David Abdurachmanov regulator-min-microamp = <5000000>; regulator-max-microamp = <5000000>; regulator-always-on; -@@ -137,48 +137,48 @@ +@@ -138,48 +138,48 @@ }; vdd_ldo3: ldo3 { diff --git a/target/linux/sunxi/Makefile b/target/linux/sunxi/Makefile index 74caebd7b..5a0f80029 100644 --- a/target/linux/sunxi/Makefile +++ b/target/linux/sunxi/Makefile @@ -7,10 +7,11 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=sunxi BOARDNAME:=Allwinner ARM SoCs -FEATURES:=fpu usb ext4 display rootfs-part rtc squashfs -SUBTARGETS:=cortexa8 cortexa7 cortexa53 +FEATURES:=usb ext4 display rootfs-part rtc squashfs +SUBTARGETS:=cortexa8 cortexa7 cortexa53 arm926ejs KERNEL_PATCHVER:=6.1 +KERNEL_TESTING_PATCHVER:=6.6 KERNELNAME:=zImage dtbs diff --git a/target/linux/sunxi/arm926ejs/config-6.1 b/target/linux/sunxi/arm926ejs/config-6.1 new file mode 100644 index 000000000..b1320ee2e --- /dev/null +++ b/target/linux/sunxi/arm926ejs/config-6.1 @@ -0,0 +1,54 @@ +# CONFIG_ARCH_MULTI_V4 is not set +# CONFIG_ARCH_MULTI_V4T is not set +CONFIG_ARCH_MULTI_V4_V5=y +CONFIG_ARCH_MULTI_V5=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_CPU_AUTO=y +CONFIG_ARCH_NR_GPIO=416 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_COMPAT_32BIT_TIME=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_MACH_SUNIV=y +# CONFIG_MACH_SUN4I is not set +# CONFIG_MACH_SUN5I is not set +# CONFIG_MACH_SUN6I is not set +# CONFIG_MACH_SUN7I is not set +# CONFIG_MACH_SUN8I is not set +# CONFIG_MACH_SUN9I is not set +CONFIG_MDIO_BUS_MUX=y +CONFIG_MUSB_PIO_ONLY=y +# CONFIG_PHY_SUN9I_USB is not set +# CONFIG_PINCTRL_SUN4I_A10 is not set +# CONFIG_PINCTRL_SUN50I_A64 is not set +# CONFIG_PINCTRL_SUN50I_A64_R is not set +# CONFIG_PINCTRL_SUN50I_H5 is not set +# CONFIG_PINCTRL_SUN50I_H6 is not set +# CONFIG_PINCTRL_SUN50I_H6_R is not set +# CONFIG_PINCTRL_SUN5I is not set +# CONFIG_PINCTRL_SUN6I_A31 is not set +# CONFIG_PINCTRL_SUN6I_A31_R is not set +# CONFIG_PINCTRL_SUN8I_A23 is not set +# CONFIG_PINCTRL_SUN8I_A23_R is not set +# CONFIG_PINCTRL_SUN8I_A33 is not set +# CONFIG_PINCTRL_SUN8I_A83T is not set +# CONFIG_PINCTRL_SUN8I_A83T_R is not set +# CONFIG_PINCTRL_SUN8I_H3 is not set +# CONFIG_PINCTRL_SUN8I_H3_R is not set +# CONFIG_PINCTRL_SUN8I_V3S is not set +# CONFIG_PINCTRL_SUN9I_A80 is not set +# CONFIG_PINCTRL_SUN9I_A80_R is not set +CONFIG_PINCTRL_SUNIV_F1C100S=y +CONFIG_PINCTRL_SUNXI=y +CONFIG_SUNIV_F1C100S_CCU=y +CONFIG_UNWINDER_ARM=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_DUAL_ROLE=y +CONFIG_USB_MUSB_SUNXI=y diff --git a/target/linux/sunxi/arm926ejs/target.mk b/target/linux/sunxi/arm926ejs/target.mk new file mode 100644 index 000000000..f37aa30d7 --- /dev/null +++ b/target/linux/sunxi/arm926ejs/target.mk @@ -0,0 +1,11 @@ +# +# Copyright (C) 2024 Zoltan HERPAI +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +BOARDNAME:=Allwinner F1C100/200s +CPU_TYPE:=arm926ej-s diff --git a/target/linux/sunxi/base-files/etc/board.d/02_network b/target/linux/sunxi/base-files/etc/board.d/02_network index b295dc7da..073565d4e 100644 --- a/target/linux/sunxi/base-files/etc/board.d/02_network +++ b/target/linux/sunxi/base-files/etc/board.d/02_network @@ -17,7 +17,7 @@ sunxi_setup_interfaces() lamobo,lamobo-r1) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" wan ;; - olimex,a20-olinuxino-micro) + olimex,a13-olinuxino-micro) ucidef_set_interface_lan "wlan0" ;; xunlong,orangepi-r1) diff --git a/target/linux/sunxi/config-6.1 b/target/linux/sunxi/config-6.1 index a76834c13..661c511ee 100644 --- a/target/linux/sunxi/config-6.1 +++ b/target/linux/sunxi/config-6.1 @@ -7,8 +7,6 @@ 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_NR_GPIO=416 CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y diff --git a/target/linux/sunxi/config-6.6 b/target/linux/sunxi/config-6.6 new file mode 100644 index 000000000..3e73f44c9 --- /dev/null +++ b/target/linux/sunxi/config-6.6 @@ -0,0 +1,526 @@ +# CONFIG_AHCI_SUNXI is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_FORCE_MAX_ORDER=11 +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=416 +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_SUNXI=y +CONFIG_ARCH_SUNXI_MC_SMP=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +CONFIG_ARM_CCI=y +CONFIG_ARM_CCI400_COMMON=y +CONFIG_ARM_CCI400_PORT_CTRL=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARM_CRYPTO=y +CONFIG_ARM_ERRATA_643719=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_LPAE=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_ARM_PSCI=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATA=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_AXP20X_POWER=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +CONFIG_CACHE_L2X0=y +CONFIG_CAN=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_SUNXI=y +CONFIG_CLK_SUNXI_CLOCKS=y +CONFIG_CLK_SUNXI_PRCM_SUN6I=y +CONFIG_CLK_SUNXI_PRCM_SUN8I=y +CONFIG_CLK_SUNXI_PRCM_SUN9I=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=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_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +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_HAS_ASID=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRCT10DIF_ARM_CE=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_DEV_ALLWINNER=y +CONFIG_CRYPTO_DEV_SUN4I_SS=y +# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set +CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y +# CONFIG_CRYPTO_DEV_SUN8I_CE is not set +# CONFIG_CRYPTO_DEV_SUN8I_SS is not set +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SHA1=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SUN4I=y +CONFIG_DMA_SUN6I=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DNOTIFY=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_CORE=y +CONFIG_DWMAC_GENERIC=y +# CONFIG_DWMAC_SUN8I is not set +CONFIG_DWMAC_SUNXI=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_ELF_CORE=y +CONFIG_EXT4_FS=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FAT_FS=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_LITTLE_ENDIAN=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_SIMPLE=y +CONFIG_FB_TILEBLITTING=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FRAME_WARN=2048 +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=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_CHIP=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_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_GLOB=y +CONFIG_GPIO_CDEV=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_MV64XXX=y +CONFIG_I2C_SUN6I_P2WI=y +CONFIG_IIO=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_INPUT_AXP20X_PEK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_KEYBOARD_SUN4I_LRADC=y +CONFIG_KMAP_LOCAL=y +CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y +CONFIG_KSM=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_LEDS_GPIO=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_MACH_SUN4I=y +CONFIG_MACH_SUN5I=y +CONFIG_MACH_SUN6I=y +CONFIG_MACH_SUN7I=y +CONFIG_MACH_SUN8I=y +CONFIG_MACH_SUN9I=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_SUN4I=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_TEST_SUPPORT=y +CONFIG_MEDIA_TUNER=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_AXP20X=y +CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_AXP20X_RSB=y +CONFIG_MFD_CORE=y +CONFIG_MFD_SUN6I_PRCM=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_SUNXI=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_VENDOR_ALLWINNER=y +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=8 +CONFIG_NVMEM=y +CONFIG_NVMEM_SUNXI_SID=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_PCS_XPCS=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_SUN4I_USB=y +# CONFIG_PHY_SUN50I_USB3 is not set +# CONFIG_PHY_SUN6I_MIPI_DPHY is not set +CONFIG_PHY_SUN9I_USB=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_AXP209=y +# CONFIG_PINCTRL_SUN20I_D1 is not set +CONFIG_PINCTRL_SUN4I_A10=y +# CONFIG_PINCTRL_SUN50I_A100 is not set +# CONFIG_PINCTRL_SUN50I_A100_R is not set +# CONFIG_PINCTRL_SUN50I_A64 is not set +# CONFIG_PINCTRL_SUN50I_A64_R is not set +# CONFIG_PINCTRL_SUN50I_H5 is not set +# CONFIG_PINCTRL_SUN50I_H6 is not set +# CONFIG_PINCTRL_SUN50I_H616 is not set +# CONFIG_PINCTRL_SUN50I_H616_R is not set +# CONFIG_PINCTRL_SUN50I_H6_R is not set +CONFIG_PINCTRL_SUN5I=y +CONFIG_PINCTRL_SUN6I_A31=y +CONFIG_PINCTRL_SUN6I_A31_R=y +CONFIG_PINCTRL_SUN8I_A23=y +CONFIG_PINCTRL_SUN8I_A23_R=y +CONFIG_PINCTRL_SUN8I_A33=y +CONFIG_PINCTRL_SUN8I_A83T=y +CONFIG_PINCTRL_SUN8I_A83T_R=y +CONFIG_PINCTRL_SUN8I_H3=y +CONFIG_PINCTRL_SUN8I_H3_R=y +CONFIG_PINCTRL_SUN8I_V3S=y +CONFIG_PINCTRL_SUN9I_A80=y +CONFIG_PINCTRL_SUN9I_A80_R=y +CONFIG_PINCTRL_SUNXI=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PRINTK_TIME=y +CONFIG_PROC_EVENTS=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +CONFIG_PWM_SUN4I=y +CONFIG_PWM_SYSFS=y +CONFIG_RATIONAL=y +CONFIG_REALTEK_PHY=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_SY8106A=y +CONFIG_RELAY=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_SIMPLE=y +CONFIG_RESET_SUNXI=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SATA_HOST=y +CONFIG_SATA_PMP=y +CONFIG_SCSI=y +CONFIG_SCSI_COMMON=y +CONFIG_SDIO_UART=y +CONFIG_SECURITYFS=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_SND=y +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +CONFIG_SND_PCM=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SUN4I_I2S is not set +# CONFIG_SND_SUN4I_SPDIF is not set +# CONFIG_SND_SUN50I_DMIC is not set +# CONFIG_SND_SUN8I_CODEC is not set +# CONFIG_SND_SUN8I_CODEC_ANALOG is not set +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_SUN4I=y +CONFIG_SPI_SUN6I=y +CONFIG_SRCU=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +# CONFIG_SUN20I_GPADC is not set +# CONFIG_SUN20I_PPU is not set +CONFIG_SUN4I_A10_CCU=y +# CONFIG_SUN4I_EMAC is not set +CONFIG_SUN4I_TIMER=y +CONFIG_SUN5I_CCU=y +CONFIG_SUN5I_HSTIMER=y +CONFIG_SUN6I_A31_CCU=y +# CONFIG_SUN6I_RTC_CCU is not set +CONFIG_SUN8I_A23_CCU=y +CONFIG_SUN8I_A33_CCU=y +CONFIG_SUN8I_A83T_CCU=y +CONFIG_SUN8I_DE2_CCU=y +CONFIG_SUN8I_H3_CCU=y +CONFIG_SUN8I_R40_CCU=y +CONFIG_SUN8I_R_CCU=y +CONFIG_SUN8I_THERMAL=y +CONFIG_SUN8I_V3S_CCU=y +CONFIG_SUN9I_A80_CCU=y +CONFIG_SUNXI_CCU=y +CONFIG_SUNXI_MBUS=y +CONFIG_SUNXI_RSB=y +CONFIG_SUNXI_SRAM=y +CONFIG_SUNXI_WATCHDOG=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=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_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TOUCHSCREEN_SUN4I=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_COMMON=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_GADGET=y +CONFIG_USB_NET_DRIVERS=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USERIO=y +CONFIG_USE_OF=y +CONFIG_VFAT_FS=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VHOST=y +CONFIG_VHOST_IOTLB=y +CONFIG_VHOST_NET=y +# CONFIG_VIDEO_SUN4I_CSI is not set +# CONFIG_VIDEO_SUN6I_CSI is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +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 diff --git a/target/linux/sunxi/cortexa53/config-6.1 b/target/linux/sunxi/cortexa53/config-6.1 index f57c66454..cac7fff4d 100644 --- a/target/linux/sunxi/cortexa53/config-6.1 +++ b/target/linux/sunxi/cortexa53/config-6.1 @@ -53,6 +53,7 @@ CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_MDIO_BUS_MUX=y CONFIG_MICREL_PHY=y CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MOTORCOMM_PHY=y CONFIG_MUSB_PIO_ONLY=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NOP_USB_XCEIV=y diff --git a/target/linux/sunxi/cortexa53/config-6.6 b/target/linux/sunxi/cortexa53/config-6.6 new file mode 100644 index 000000000..cac7fff4d --- /dev/null +++ b/target/linux/sunxi/cortexa53/config-6.6 @@ -0,0 +1,108 @@ +CONFIG_64BIT=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_STACKWALK=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +CONFIG_ARM64_CRYPTO=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_2051678=y +CONFIG_ARM64_ERRATUM_2077057=y +CONFIG_ARM64_ERRATUM_2658417=y +CONFIG_ARM64_ERRATUM_2054223=y +CONFIG_ARM64_ERRATUM_2067961=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_VA_BITS_39=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_BLAKE2S=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SIMD=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DWMAC_SUN8I=y +CONFIG_EEPROM_AT24=y +CONFIG_FRAME_POINTER=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_MDIO_BUS_MUX=y +CONFIG_MICREL_PHY=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MOTORCOMM_PHY=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_IOPORT_MAP=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PHY_SUN50I_USB3=y +CONFIG_PINCTRL_SUN50I_A100=y +CONFIG_PINCTRL_SUN50I_A100_R=y +CONFIG_PINCTRL_SUN50I_A64=y +CONFIG_PINCTRL_SUN50I_A64_R=y +CONFIG_PINCTRL_SUN50I_H5=y +CONFIG_PINCTRL_SUN50I_H6=y +CONFIG_PINCTRL_SUN50I_H6_R=y +CONFIG_PINCTRL_SUN50I_H616=y +CONFIG_PINCTRL_SUN50I_H616_R=y +# CONFIG_PREEMPT_DYNAMIC is not set +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_SCHED_CLUSTER is not set +# CONFIG_SHADOW_CALL_STACK is not set +# CONFIG_SND_SUN50I_CODEC_ANALOG is not set +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SUN50I_A100_CCU=y +CONFIG_SUN50I_A100_R_CCU=y +CONFIG_SUN50I_A64_CCU=y +CONFIG_SUN50I_DE2_BUS=y +CONFIG_SUN50I_ERRATUM_UNKNOWN1=y +CONFIG_SUN50I_H616_CCU=y +CONFIG_SUN50I_H6_CCU=y +CONFIG_SUN50I_H6_R_CCU=y +# CONFIG_SUN6I_RTC_CCU is not set +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_USB_MUSB_DUAL_ROLE=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_PHY=y +CONFIG_VMAP_STACK=y +CONFIG_ZONE_DMA32=y +CONFIG_SURFACE_PLATFORMS=y +# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set +# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set +# CONFIG_PAGE_TABLE_CHECK is not set +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_ARCH_NXP is not set diff --git a/target/linux/sunxi/cortexa53/target.mk b/target/linux/sunxi/cortexa53/target.mk index 771e07d29..02b31702b 100644 --- a/target/linux/sunxi/cortexa53/target.mk +++ b/target/linux/sunxi/cortexa53/target.mk @@ -8,3 +8,4 @@ ARCH:=aarch64 BOARDNAME:=Allwinner A64/H5/H6/H616 CPU_TYPE:=cortex-a53 KERNELNAME:=Image dtbs +FEATURES+=fpu \ No newline at end of file diff --git a/target/linux/sunxi/cortexa7/config-6.1 b/target/linux/sunxi/cortexa7/config-6.1 index e911da4c3..76fdc0dff 100644 --- a/target/linux/sunxi/cortexa7/config-6.1 +++ b/target/linux/sunxi/cortexa7/config-6.1 @@ -1,3 +1,5 @@ +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y CONFIG_B53=y CONFIG_B53_MDIO_DRIVER=y CONFIG_CRYPTO_BLAKE2S_ARM=y diff --git a/target/linux/sunxi/cortexa7/config-6.6 b/target/linux/sunxi/cortexa7/config-6.6 new file mode 100644 index 000000000..105c09089 --- /dev/null +++ b/target/linux/sunxi/cortexa7/config-6.6 @@ -0,0 +1,28 @@ +CONFIG_B53=y +CONFIG_B53_MDIO_DRIVER=y +CONFIG_CRYPTO_BLAKE2S_ARM=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_DWMAC_SUN8I=y +CONFIG_GRO_CELLS=y +# CONFIG_HARDEN_BRANCH_HISTORY is not set +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +# CONFIG_MACH_SUN4I is not set +# CONFIG_MACH_SUN5I is not set +CONFIG_MDIO_BUS_MUX=y +CONFIG_MICREL_PHY=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_TAG_BRCM=y +CONFIG_NET_DSA_TAG_BRCM_COMMON=y +CONFIG_NET_DSA_TAG_BRCM_LEGACY=y +CONFIG_NET_DSA_TAG_BRCM_PREPEND=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_RTC_DRV_SUN6I=y +CONFIG_SUN20I_D1_CCU=y +CONFIG_SUN20I_D1_R_CCU=y +CONFIG_USB_MUSB_DUAL_ROLE=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_PHY=y diff --git a/target/linux/sunxi/cortexa7/target.mk b/target/linux/sunxi/cortexa7/target.mk index 95315fd4a..52a89e910 100644 --- a/target/linux/sunxi/cortexa7/target.mk +++ b/target/linux/sunxi/cortexa7/target.mk @@ -7,3 +7,4 @@ include $(TOPDIR)/rules.mk BOARDNAME:=Allwinner A20/A3x/H3/R40 CPU_TYPE:=cortex-a7 CPU_SUBTYPE:=neon-vfpv4 +FEATURES+=fpu diff --git a/target/linux/sunxi/cortexa8/config-6.1 b/target/linux/sunxi/cortexa8/config-6.1 index b893b3142..274778dd0 100644 --- a/target/linux/sunxi/cortexa8/config-6.1 +++ b/target/linux/sunxi/cortexa8/config-6.1 @@ -1,3 +1,5 @@ +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y # CONFIG_ARM_LPAE is not set CONFIG_CRYPTO_BLAKE2S_ARM=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/target/linux/sunxi/cortexa8/config-6.6 b/target/linux/sunxi/cortexa8/config-6.6 new file mode 100644 index 000000000..b893b3142 --- /dev/null +++ b/target/linux/sunxi/cortexa8/config-6.6 @@ -0,0 +1,12 @@ +# CONFIG_ARM_LPAE is not set +CONFIG_CRYPTO_BLAKE2S_ARM=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +# CONFIG_MACH_SUN6I is not set +# CONFIG_MACH_SUN7I is not set +# CONFIG_MACH_SUN8I is not set +# CONFIG_MACH_SUN9I is not set +CONFIG_PGTABLE_LEVELS=2 +# CONFIG_PHY_SUN9I_USB is not set +# CONFIG_SPI_SUN6I is not set +# CONFIG_SUN8I_A83T_CCU is not set +# CONFIG_SUN8I_THERMAL is not set diff --git a/target/linux/sunxi/cortexa8/target.mk b/target/linux/sunxi/cortexa8/target.mk index cf30ca787..7f34cc8ea 100644 --- a/target/linux/sunxi/cortexa8/target.mk +++ b/target/linux/sunxi/cortexa8/target.mk @@ -7,3 +7,4 @@ include $(TOPDIR)/rules.mk BOARDNAME:=Allwinner A1x CPU_TYPE:=cortex-a8 CPU_SUBTYPE:=vfpv3 +FEATURES+=fpu diff --git a/target/linux/sunxi/image/Makefile b/target/linux/sunxi/image/Makefile index 738585acc..fc1359d17 100644 --- a/target/linux/sunxi/image/Makefile +++ b/target/linux/sunxi/image/Makefile @@ -10,7 +10,6 @@ FAT32_BLOCK_SIZE=1024 FAT32_BLOCKS=$(shell echo $$(($(CONFIG_SUNXI_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) DEVICE_VARS := SUNXI_DTS SUNXI_DTS_DIR -KERNEL_LOADADDR:=0x40008000 define Build/sunxi-sdcard rm -f $@.boot @@ -35,7 +34,9 @@ define Device/Default KERNEL := kernel-bin | uImage none IMAGES := sdcard.img.gz IMAGE/sdcard.img.gz := sunxi-sdcard | append-metadata | gzip - SUNXI_DTS_DIR := +ifdef CONFIG_LINUX_6_6 + SUNXI_DTS_DIR :=allwinner/ +endif SUNXI_DTS = $$(SUNXI_DTS_DIR)$$(SOC)-$(lastword $(subst _, ,$(1))) endef diff --git a/target/linux/sunxi/image/arm926ejs.mk b/target/linux/sunxi/image/arm926ejs.mk new file mode 100644 index 000000000..1ce230feb --- /dev/null +++ b/target/linux/sunxi/image/arm926ejs.mk @@ -0,0 +1,24 @@ +# +# Copyright (C) 2013-2024 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +KERNEL_LOADADDR=0x81000000 + +define Device/licheepi-nano + DEVICE_VENDOR := LicheePi + DEVICE_MODEL := Nano + DEVICE_PACKAGES := kmod-rtc-sunxi + SOC := suniv-f1c100s +endef +TARGET_DEVICES += licheepi-nano + +define Device/popstick-v1.1 + DEVICE_VENDOR := PopStick + DEVICE_MODEL := v1.1 + DEVICE_PACKAGES := kmod-rtc-sunxi + SOC := suniv-f1c200s +endef +TARGET_DEVICES += popstick-v1.1 diff --git a/target/linux/sunxi/image/cortexa53.mk b/target/linux/sunxi/image/cortexa53.mk index 80718b34b..06b409deb 100644 --- a/target/linux/sunxi/image/cortexa53.mk +++ b/target/linux/sunxi/image/cortexa53.mk @@ -3,6 +3,8 @@ # Copyright (C) 2013-2016 OpenWrt.org # Copyright (C) 2016 Yousong Zhou +KERNEL_LOADADDR:=0x40008000 + define Device/sun50i SUNXI_DTS_DIR := allwinner/ KERNEL_NAME := Image @@ -29,6 +31,11 @@ define Device/sun50i-h616 $(Device/sun50i) endef +define Device/sun50i-h618 + SOC := sun50i-h618 + $(Device/sun50i) +endef + define Device/friendlyarm_nanopi-neo-plus2 DEVICE_VENDOR := FriendlyARM DEVICE_MODEL := NanoPi NEO Plus2 @@ -120,6 +127,13 @@ define Device/xunlong_orangepi-zero2 endef TARGET_DEVICES += xunlong_orangepi-zero2 +define Device/xunlong_orangepi-zero3 + DEVICE_VENDOR := Xunlong + DEVICE_MODEL := Orange Pi Zero 3 + $(Device/sun50i-h618) +endef +TARGET_DEVICES += xunlong_orangepi-zero3 + define Device/xunlong_orangepi-zero-plus DEVICE_VENDOR := Xunlong DEVICE_MODEL := Orange Pi Zero Plus diff --git a/target/linux/sunxi/image/cortexa7.mk b/target/linux/sunxi/image/cortexa7.mk index 3191cec4f..a85b20531 100644 --- a/target/linux/sunxi/image/cortexa7.mk +++ b/target/linux/sunxi/image/cortexa7.mk @@ -3,6 +3,8 @@ # Copyright (C) 2013-2019 OpenWrt.org # Copyright (C) 2016 Yousong Zhou +KERNEL_LOADADDR:=0x40008000 + define Device/cubietech_cubieboard2 DEVICE_VENDOR := Cubietech DEVICE_MODEL := Cubieboard2 diff --git a/target/linux/sunxi/image/cortexa8.mk b/target/linux/sunxi/image/cortexa8.mk index eafc2187e..e27db1ee1 100644 --- a/target/linux/sunxi/image/cortexa8.mk +++ b/target/linux/sunxi/image/cortexa8.mk @@ -3,6 +3,8 @@ # Copyright (C) 2013-2016 OpenWrt.org # Copyright (C) 2016 Yousong Zhou +KERNEL_LOADADDR:=0x40008000 + define Device/cubietech_a10-cubieboard DEVICE_VENDOR := Cubietech DEVICE_MODEL := Cubieboard @@ -43,7 +45,7 @@ define Device/olimex_a13-olimex-som DEVICE_PACKAGES:=kmod-rtl8192cu SUPPORTED_DEVICES:=olimex,a13-olinuxino SOC := sun5i-a13 - SUNXI_DTS := sun5i-a13-olinuxino + SUNXI_DTS := $$(SUNXI_DTS_DIR)sun5i-a13-olinuxino endef TARGET_DEVICES += olimex_a13-olimex-som diff --git a/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch b/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch new file mode 100644 index 000000000..0747e6a8e --- /dev/null +++ b/target/linux/sunxi/patches-6.1/005-v6.6-arm64-dts-allwinner-h616-Split-Orange-Pi-Zero-2-DT.patch @@ -0,0 +1,305 @@ +From 322bf103204b8f786547acbeed85569254e7088f Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 4 Aug 2023 18:08:54 +0100 +Subject: [PATCH] arm64: dts: allwinner: h616: Split Orange Pi Zero 2 DT + +The Orange Pi Zero 2 got a successor (Zero 3), which shares quite some +DT nodes with the Zero 2, but comes with a different PMIC. + +Move the common parts (except the PMIC) into a new shared file, and +include that from the existing board .dts file. + +No functional change, the generated DTB is the same, except for some +phandle numbering differences. + +Signed-off-by: Andre Przywara +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230804170856.1237202-2-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + .../allwinner/sun50i-h616-orangepi-zero.dtsi | 134 ++++++++++++++++++ + .../allwinner/sun50i-h616-orangepi-zero2.dts | 119 +--------------- + 2 files changed, 135 insertions(+), 118 deletions(-) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi + +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi +@@ -0,0 +1,134 @@ ++// SPDX-License-Identifier: (GPL-2.0+ or MIT) ++/* ++ * Copyright (C) 2020 Arm Ltd. ++ * ++ * DT nodes common between Orange Pi Zero 2 and Orange Pi Zero 3. ++ * Excludes PMIC nodes and properties, since they are different between the two. ++ */ ++ ++#include "sun50i-h616.dtsi" ++ ++#include ++#include ++#include ++ ++/ { ++ aliases { ++ ethernet0 = &emac0; ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ function = LED_FUNCTION_POWER; ++ color = ; ++ gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */ ++ default-state = "on"; ++ }; ++ ++ led-1 { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ ++ }; ++ }; ++ ++ reg_vcc5v: vcc5v { ++ /* board wide 5V supply directly from the USB-C socket */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++ ++ reg_usb1_vbus: regulator-usb1-vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb1-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <®_vcc5v>; ++ enable-active-high; ++ gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */ ++ }; ++}; ++ ++&ehci1 { ++ status = "okay"; ++}; ++ ++/* USB 2 & 3 are on headers only. */ ++ ++&emac0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ext_rgmii_pins>; ++ phy-mode = "rgmii"; ++ phy-handle = <&ext_rgmii_phy>; ++ allwinner,rx-delay-ps = <3100>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&mdio0 { ++ ext_rgmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ }; ++}; ++ ++&mmc0 { ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&ohci1 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>; ++ ++ flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <40000000>; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ph_pins>; ++ status = "okay"; ++}; ++ ++&usbotg { ++ /* ++ * PHY0 pins are connected to a USB-C socket, but a role switch ++ * is not implemented: both CC pins are pulled to GND. ++ * The VBUS pins power the device, so a fixed peripheral mode ++ * is the best choice. ++ * The board can be powered via GPIOs, in this case port0 *can* ++ * act as a host (with a cable/adapter ignoring CC), as VBUS is ++ * then provided by the GPIOs. Any user of this setup would ++ * need to adjust the DT accordingly: dr_mode set to "host", ++ * enabling OHCI0 and EHCI0. ++ */ ++ dr_mode = "peripheral"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ usb1_vbus-supply = <®_usb1_vbus>; ++ status = "okay"; ++}; +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +@@ -5,95 +5,19 @@ + + /dts-v1/; + +-#include "sun50i-h616.dtsi" +- +-#include +-#include +-#include ++#include "sun50i-h616-orangepi-zero.dtsi" + + / { + model = "OrangePi Zero2"; + compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616"; +- +- aliases { +- ethernet0 = &emac0; +- serial0 = &uart0; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +- +- leds { +- compatible = "gpio-leds"; +- +- led-0 { +- function = LED_FUNCTION_POWER; +- color = ; +- gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */ +- default-state = "on"; +- }; +- +- led-1 { +- function = LED_FUNCTION_STATUS; +- color = ; +- gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ +- }; +- }; +- +- reg_vcc5v: vcc5v { +- /* board wide 5V supply directly from the USB-C socket */ +- compatible = "regulator-fixed"; +- regulator-name = "vcc-5v"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- regulator-always-on; +- }; +- +- reg_usb1_vbus: regulator-usb1-vbus { +- compatible = "regulator-fixed"; +- regulator-name = "usb1-vbus"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- vin-supply = <®_vcc5v>; +- enable-active-high; +- gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */ +- }; +-}; +- +-&ehci1 { +- status = "okay"; + }; + +-/* USB 2 & 3 are on headers only. */ +- + &emac0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&ext_rgmii_pins>; +- phy-mode = "rgmii"; +- phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_dcdce>; +- allwinner,rx-delay-ps = <3100>; +- allwinner,tx-delay-ps = <700>; +- status = "okay"; +-}; +- +-&mdio0 { +- ext_rgmii_phy: ethernet-phy@1 { +- compatible = "ethernet-phy-ieee802.3-c22"; +- reg = <1>; +- }; + }; + + &mmc0 { + vmmc-supply = <®_dcdce>; +- cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ +- bus-width = <4>; +- status = "okay"; +-}; +- +-&ohci1 { +- status = "okay"; + }; + + &r_rsb { +@@ -211,44 +135,3 @@ + vcc-ph-supply = <®_aldo1>; + vcc-pi-supply = <®_aldo1>; + }; +- +-&spi0 { +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>; +- +- flash@0 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "jedec,spi-nor"; +- reg = <0>; +- spi-max-frequency = <40000000>; +- }; +-}; +- +-&uart0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart0_ph_pins>; +- status = "okay"; +-}; +- +-&usbotg { +- /* +- * PHY0 pins are connected to a USB-C socket, but a role switch +- * is not implemented: both CC pins are pulled to GND. +- * The VBUS pins power the device, so a fixed peripheral mode +- * is the best choice. +- * The board can be powered via GPIOs, in this case port0 *can* +- * act as a host (with a cable/adapter ignoring CC), as VBUS is +- * then provided by the GPIOs. Any user of this setup would +- * need to adjust the DT accordingly: dr_mode set to "host", +- * enabling OHCI0 and EHCI0. +- */ +- dr_mode = "peripheral"; +- status = "okay"; +-}; +- +-&usbphy { +- usb1_vbus-supply = <®_usb1_vbus>; +- status = "okay"; +-}; diff --git a/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch b/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch new file mode 100644 index 000000000..4081a82d5 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/006-v6.6-arm64-dts-allwinner-h616-Add-OrangePi-Zero-3-board.patch @@ -0,0 +1,140 @@ +From f1b3ddb3ecc2eec1f912383e01156c226daacfab Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 4 Aug 2023 18:08:56 +0100 +Subject: [PATCH] arm64: dts: allwinner: h616: Add OrangePi Zero 3 board + support + +The OrangePi Zero 3 is a development board based on the Allwinner H618 SoC, +which seems to be just an H616 with more L2 cache. The board itself is a +slightly updated version of the Orange Pi Zero 2. It features: +- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU +- 1/1.5/2/4 GiB LPDDR4 DRAM SKUs (only up to 1GB on the Zero2) +- AXP313a PMIC (more capable AXP305 on the Zero2) +- Raspberry-Pi-1 compatible GPIO header +- extra 13 pin expansion header, exposing pins for 2x USB 2.0 ports +- 1 USB 2.0 host port +- 1 USB 2.0 type C port (power supply + OTG) +- MicroSD slot +- on-board 16MiB bootable SPI NOR flash (only 2MB on the Zero2) +- 1Gbps Ethernet port (via Motorcomm YT8531 PHY) (RTL8211 on the Zero2) +- micro-HDMI port +- (yet) unsupported Allwinner WiFi/BT chip + +Add the devicetree file describing the currently supported features, +namely LEDs, SD card, PMIC, SPI flash, USB. Ethernet seems unstable at +the moment, though the basic functionality works. + +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230804170856.1237202-4-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + arch/arm64/boot/dts/allwinner/Makefile | 1 + + .../allwinner/sun50i-h618-orangepi-zero3.dts | 94 +++++++++++++++++++ + 2 files changed, 95 insertions(+) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts + +--- a/arch/arm64/boot/dts/allwinner/Makefile ++++ b/arch/arm64/boot/dts/allwinner/Makefile +@@ -40,3 +40,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-ta + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb ++dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts +@@ -0,0 +1,94 @@ ++// SPDX-License-Identifier: (GPL-2.0+ or MIT) ++/* ++ * Copyright (C) 2023 Arm Ltd. ++ */ ++ ++/dts-v1/; ++ ++#include "sun50i-h616-orangepi-zero.dtsi" ++ ++/ { ++ model = "OrangePi Zero3"; ++ compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618"; ++}; ++ ++&emac0 { ++ phy-supply = <®_dldo1>; ++}; ++ ++&ext_rgmii_phy { ++ motorcomm,clk-out-frequency-hz = <125000000>; ++}; ++ ++&mmc0 { ++ /* ++ * The schematic shows the card detect pin wired up to PF6, via an ++ * inverter, but it just doesn't work. ++ */ ++ broken-cd; ++ vmmc-supply = <®_dldo1>; ++}; ++ ++&r_i2c { ++ status = "okay"; ++ ++ axp313: pmic@36 { ++ compatible = "x-powers,axp313a"; ++ reg = <0x36>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ interrupt-parent = <&pio>; ++ interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>; /* PC9 */ ++ ++ vin1-supply = <®_vcc5v>; ++ vin2-supply = <®_vcc5v>; ++ vin3-supply = <®_vcc5v>; ++ ++ regulators { ++ /* Supplies VCC-PLL, so needs to be always on. */ ++ reg_aldo1: aldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8"; ++ }; ++ ++ /* Supplies VCC-IO, so needs to be always on. */ ++ reg_dldo1: dldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc3v3"; ++ }; ++ ++ reg_dcdc1: dcdc1 { ++ regulator-always-on; ++ regulator-min-microvolt = <810000>; ++ regulator-max-microvolt = <990000>; ++ regulator-name = "vdd-gpu-sys"; ++ }; ++ ++ reg_dcdc2: dcdc2 { ++ regulator-always-on; ++ regulator-min-microvolt = <810000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-name = "vdd-cpu"; ++ }; ++ ++ reg_dcdc3: dcdc3 { ++ regulator-always-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-name = "vdd-dram"; ++ }; ++ }; ++ }; ++}; ++ ++&pio { ++ vcc-pc-supply = <®_dldo1>; ++ vcc-pf-supply = <®_dldo1>; ++ vcc-pg-supply = <®_aldo1>; ++ vcc-ph-supply = <®_dldo1>; ++ vcc-pi-supply = <®_dldo1>; ++}; diff --git a/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch b/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch new file mode 100644 index 000000000..fe32cfc3e --- /dev/null +++ b/target/linux/sunxi/patches-6.1/007-v6.7-arm64-dts-allwinner-h616-update-emac-for-Orange-Pi.patch @@ -0,0 +1,36 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi +@@ -68,10 +68,7 @@ + &emac0 { + pinctrl-names = "default"; + pinctrl-0 = <&ext_rgmii_pins>; +- phy-mode = "rgmii"; + phy-handle = <&ext_rgmii_phy>; +- allwinner,rx-delay-ps = <3100>; +- allwinner,tx-delay-ps = <700>; + status = "okay"; + }; + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +@@ -13,6 +13,9 @@ + }; + + &emac0 { ++ allwinner,rx-delay-ps = <3100>; ++ allwinner,tx-delay-ps = <700>; ++ phy-mode = "rgmii"; + phy-supply = <®_dcdce>; + }; + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts +@@ -13,6 +13,8 @@ + }; + + &emac0 { ++ allwinner,tx-delay-ps = <700>; ++ phy-mode = "rgmii-rxid"; + phy-supply = <®_dldo1>; + }; + diff --git a/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch b/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch new file mode 100644 index 000000000..ce8add18a --- /dev/null +++ b/target/linux/sunxi/patches-6.1/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch @@ -0,0 +1,31 @@ +From 951992797378a2177946400438f4d23c9fceae5b Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Tue, 12 Sep 2023 14:25:13 +0200 +Subject: [PATCH] arm64: dts: allwinner: h616: Add SID controller node + +Add node for the H616 SID controller + +Signed-off-by: Martin Botka +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230912-sid-h616-v3-2-ee18e1c5bbb5@somainline.org +Signed-off-by: Jernej Skrabec +--- + arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -133,6 +133,13 @@ + #reset-cells = <1>; + }; + ++ sid: efuse@3006000 { ++ compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid"; ++ reg = <0x03006000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++ + watchdog: watchdog@30090a0 { + compatible = "allwinner,sun50i-h616-wdt", + "allwinner,sun6i-a31-wdt"; diff --git a/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch b/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch new file mode 100644 index 000000000..3453e2aa5 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch @@ -0,0 +1,98 @@ +From 898d96c5464b69af44f6407c5de81ebc349d574b Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:33 +0000 +Subject: [PATCH] soc: sunxi: sram: export register 0 for THS on H616 + +The Allwinner H616 SoC contains a mysterious bit at register offset 0x0 +in the SRAM control block. If bit 16 is set (the reset value), the +temperature readings of the THS are way off, leading to reports about +200C, at normal ambient temperatures. Clearing this bits brings the +reported values down to the expected values. +The BSP code clears this bit in firmware (U-Boot), and has an explicit +comment about this, but offers no real explanation. + +Experiments in U-Boot show that register 0x0 has no effect on the SRAM C +visibility: all tested bit settings still allow full read and write +access by the CPU to the whole of SRAM C. Only bit 24 of the register at +offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling +the THS switch functionality as an SRAM region would not reflect reality. + +Since we should not rely on firmware settings, allow other code (the THS +driver) to access this register, by exporting it through the already +existing regmap. This mimics what we already do for the LDO control and +the EMAC register. + +To avoid concurrent accesses to the same register at the same time, by +the SRAM switch code and the regmap code, use the same lock to protect +the access. The regmap subsystem allows to use an existing lock, so we +just need to hook in there. + +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-2-andre.przywara@arm.com +--- + drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -284,6 +284,7 @@ EXPORT_SYMBOL(sunxi_sram_release); + struct sunxi_sramc_variant { + int num_emac_clocks; + bool has_ldo_ctrl; ++ bool has_ths_offset; + }; + + static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { +@@ -305,8 +306,10 @@ static const struct sunxi_sramc_variant + + static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { + .num_emac_clocks = 2, ++ .has_ths_offset = true, + }; + ++#define SUNXI_SRAM_THS_OFFSET_REG 0x0 + #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 + #define SUNXI_SYS_LDO_CTRL_REG 0x150 + +@@ -315,6 +318,8 @@ static bool sunxi_sram_regmap_accessible + { + const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev); + ++ if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset) ++ return true; + if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG && + reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) + return true; +@@ -324,6 +329,20 @@ static bool sunxi_sram_regmap_accessible + return false; + } + ++static void sunxi_sram_lock(void *_lock) ++{ ++ spinlock_t *lock = _lock; ++ ++ spin_lock(lock); ++} ++ ++static void sunxi_sram_unlock(void *_lock) ++{ ++ spinlock_t *lock = _lock; ++ ++ spin_unlock(lock); ++} ++ + static struct regmap_config sunxi_sram_regmap_config = { + .reg_bits = 32, + .val_bits = 32, +@@ -333,6 +352,9 @@ static struct regmap_config sunxi_sram_r + /* other devices have no business accessing other registers */ + .readable_reg = sunxi_sram_regmap_accessible_reg, + .writeable_reg = sunxi_sram_regmap_accessible_reg, ++ .lock = sunxi_sram_lock, ++ .unlock = sunxi_sram_unlock, ++ .lock_arg = &sram_lock, + }; + + static int __init sunxi_sram_probe(struct platform_device *pdev) diff --git a/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch b/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch new file mode 100644 index 000000000..8b1998911 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch @@ -0,0 +1,47 @@ +From ebbf19e36d021f253425344b4d4b987f3b7d9be5 Mon Sep 17 00:00:00 2001 +From: Maxim Kiselev +Date: Mon, 18 Dec 2023 00:06:23 +0300 +Subject: [PATCH] thermal/drivers/sun8i: Add D1/T113s THS controller support + +This patch adds a thermal sensor controller support for the D1/T113s, +which is similar to the one on H6, but with only one sensor and +different scale and offset values. + +Signed-off-by: Maxim Kiselev +Acked-by: Jernej Skrabec +Reviewed-by: Andre Przywara +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231217210629.131486-3-bigunclemax@gmail.com +--- + drivers/thermal/sun8i_thermal.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -610,6 +610,18 @@ static const struct ths_thermal_chip sun + .calc_temp = sun8i_ths_calc_temp, + }; + ++static const struct ths_thermal_chip sun20i_d1_ths = { ++ .sensor_num = 1, ++ .has_bus_clk_reset = true, ++ .offset = 188552, ++ .scale = 673, ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, ++ .calibrate = sun50i_h6_ths_calibrate, ++ .init = sun50i_h6_thermal_init, ++ .irq_ack = sun50i_h6_irq_ack, ++ .calc_temp = sun8i_ths_calc_temp, ++}; ++ + static const struct of_device_id of_ths_match[] = { + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, +@@ -618,6 +630,7 @@ static const struct of_device_id of_ths_ + { .compatible = "allwinner,sun50i-a100-ths", .data = &sun50i_a100_ths }, + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths }, + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, ++ { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, of_ths_match); diff --git a/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch b/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch new file mode 100644 index 000000000..b8138a387 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch @@ -0,0 +1,79 @@ +From 14f118aa50fe7c7c7330f56d007ecacca487cea8 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:35 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Explain unknown H6 register value + +So far we were ORing in some "unknown" value into the THS control +register on the Allwinner H6. This part of the register is not explained +in the H6 manual, but the H616 manual details those bits, and on closer +inspection the THS IP blocks in both SoCs seem very close: +- The BSP code for both SoCs writes the same values into THS_CTRL. +- The reset values of at least the first three registers are the same. + +Replace the "unknown" value with its proper meaning: "acquire time", +most probably the sample part of the sample & hold circuit of the ADC, +according to its explanation in the H616 manual. + +No functional change, just a macro rename and adjustment. + +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-4-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -50,7 +50,8 @@ + #define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16) + #define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8) + +-#define SUN50I_THS_CTRL0_T_ACQ(x) ((GENMASK(15, 0) & (x)) << 16) ++#define SUN50I_THS_CTRL0_T_ACQ(x) (GENMASK(15, 0) & ((x) - 1)) ++#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x) ((GENMASK(15, 0) & ((x) - 1)) << 16) + #define SUN50I_THS_FILTER_EN BIT(2) + #define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x)) + #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12) +@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct + return 0; + } + +-/* +- * Without this undocumented value, the returned temperatures would +- * be higher than real ones by about 20C. +- */ +-#define SUN50I_H6_CTRL0_UNK 0x0000002f +- + static int sun50i_h6_thermal_init(struct ths_device *tmdev) + { + int val; + + /* +- * T_acq = 20us +- * clkin = 24MHz +- * +- * x = T_acq * clkin - 1 +- * = 479 ++ * The manual recommends an overall sample frequency of 50 KHz (20us, ++ * 480 cycles at 24 MHz), which provides plenty of time for both the ++ * acquisition time (>24 cycles) and the actual conversion time ++ * (>14 cycles). ++ * The lower half of the CTRL register holds the "acquire time", in ++ * clock cycles, which the manual recommends to be 2us: ++ * 24MHz * 2us = 48 cycles. ++ * The high half of THS_CTRL encodes the sample frequency, in clock ++ * cycles: 24MHz * 20us = 480 cycles. ++ * This is explained in the H616 manual, but apparently wrongly ++ * described in the H6 manual, although the BSP code does the same ++ * for both SoCs. + */ + regmap_write(tmdev->regmap, SUN50I_THS_CTRL0, +- SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479)); ++ SUN50I_THS_CTRL0_T_ACQ(48) | ++ SUN50I_THS_CTRL0_T_SAMPLE_PER(480)); + /* average over 4 samples */ + regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC, + SUN50I_THS_FILTER_EN | diff --git a/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch b/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch new file mode 100644 index 000000000..3d01a507f --- /dev/null +++ b/target/linux/sunxi/patches-6.1/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch @@ -0,0 +1,74 @@ +From 6c04a419a4c5fb18edefc44dd676fb95c7f6c55d Mon Sep 17 00:00:00 2001 +From: Maksim Kiselev +Date: Mon, 19 Feb 2024 15:36:36 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Extend H6 calibration to support 4 + sensors + +The H616 SoC resembles the H6 thermal sensor controller, with a few +changes like four sensors. + +Extend sun50i_h6_ths_calibrate() function to support calibration of +these sensors. + +Co-developed-by: Martin Botka +Signed-off-by: Martin Botka +Signed-off-by: Maksim Kiselev +Reviewed-by: Andre Przywara +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-5-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++-------- + 1 file changed, 20 insertions(+), 8 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -224,16 +224,21 @@ static int sun50i_h6_ths_calibrate(struc + struct device *dev = tmdev->dev; + int i, ft_temp; + +- if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num) ++ if (!caldata[0]) + return -EINVAL; + + /* + * efuse layout: + * +- * 0 11 16 32 +- * +-------+-------+-------+ +- * |temp| |sensor0|sensor1| +- * +-------+-------+-------+ ++ * 0 11 16 27 32 43 48 57 ++ * +----------+-----------+-----------+-----------+ ++ * | temp | |sensor0| |sensor1| |sensor2| | ++ * +----------+-----------+-----------+-----------+ ++ * ^ ^ ^ ++ * | | | ++ * | | sensor3[11:8] ++ * | sensor3[7:4] ++ * sensor3[3:0] + * + * The calibration data on the H6 is the ambient temperature and + * sensor values that are filled during the factory test stage. +@@ -246,9 +251,16 @@ static int sun50i_h6_ths_calibrate(struc + ft_temp = (caldata[0] & FT_TEMP_MASK) * 100; + + for (i = 0; i < tmdev->chip->sensor_num; i++) { +- int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK; +- int cdata, offset; +- int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); ++ int sensor_reg, sensor_temp, cdata, offset; ++ ++ if (i == 3) ++ sensor_reg = (caldata[1] >> 12) ++ | ((caldata[2] >> 12) << 4) ++ | ((caldata[3] >> 12) << 8); ++ else ++ sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK; ++ ++ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); + + /* + * Calibration data is CALIBRATE_DEFAULT - (calculated diff --git a/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch b/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch new file mode 100644 index 000000000..6db1e32cf --- /dev/null +++ b/target/linux/sunxi/patches-6.1/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch @@ -0,0 +1,126 @@ +From f8b54d1120b81ed57bed96cc8e814ba08886d1e5 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:37 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Add SRAM register access code + +The Allwinner H616 SoC needs to clear a bit in one register in the SRAM +controller, to report reasonable temperature values. On reset, bit 16 in +register 0x3000000 is set, which leads to the driver reporting +temperatures around 200C. Clearing this bit brings the values down to the +expected range. The BSP code does a one-time write in U-Boot, with a +comment just mentioning the effect on the THS, but offering no further +explanation. + +To not rely on firmware to set things up for us, add code that queries +the SRAM controller device via a DT phandle link, then clear just this +single bit. + +Signed-off-by: Andre Przywara +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-6-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -68,6 +69,7 @@ struct tsensor { + struct ths_thermal_chip { + bool has_mod_clk; + bool has_bus_clk_reset; ++ bool needs_sram; + int sensor_num; + int offset; + int scale; +@@ -85,12 +87,16 @@ struct ths_device { + const struct ths_thermal_chip *chip; + struct device *dev; + struct regmap *regmap; ++ struct regmap_field *sram_regmap_field; + struct reset_control *reset; + struct clk *bus_clk; + struct clk *mod_clk; + struct tsensor sensor[MAX_SENSOR_NUM]; + }; + ++/* The H616 needs to have a bit 16 in the SRAM control register cleared. */ ++static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16); ++ + /* Temp Unit: millidegree Celsius */ + static int sun8i_ths_calc_temp(struct ths_device *tmdev, + int id, int reg) +@@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_asse + reset_control_assert(data); + } + ++static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node) ++{ ++ struct device_node *sram_node; ++ struct platform_device *sram_pdev; ++ struct regmap *regmap = NULL; ++ ++ sram_node = of_parse_phandle(node, "allwinner,sram", 0); ++ if (!sram_node) ++ return ERR_PTR(-ENODEV); ++ ++ sram_pdev = of_find_device_by_node(sram_node); ++ if (!sram_pdev) { ++ /* platform device might not be probed yet */ ++ regmap = ERR_PTR(-EPROBE_DEFER); ++ goto out_put_node; ++ } ++ ++ /* If no regmap is found then the other device driver is at fault */ ++ regmap = dev_get_regmap(&sram_pdev->dev, NULL); ++ if (!regmap) ++ regmap = ERR_PTR(-EINVAL); ++ ++ platform_device_put(sram_pdev); ++out_put_node: ++ of_node_put(sram_node); ++ return regmap; ++} ++ + static int sun8i_ths_resource_init(struct ths_device *tmdev) + { + struct device *dev = tmdev->dev; +@@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struc + if (ret) + return ret; + ++ if (tmdev->chip->needs_sram) { ++ struct regmap *regmap; ++ ++ regmap = sun8i_ths_get_sram_regmap(dev->of_node); ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ tmdev->sram_regmap_field = devm_regmap_field_alloc(dev, ++ regmap, ++ sun8i_ths_sram_reg_field); ++ if (IS_ERR(tmdev->sram_regmap_field)) ++ return PTR_ERR(tmdev->sram_regmap_field); ++ } ++ + ret = sun8i_ths_calibrate(tmdev); + if (ret) + return ret; +@@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct + { + int val; + ++ /* The H616 needs to have a bit in the SRAM control register cleared. */ ++ if (tmdev->sram_regmap_field) ++ regmap_field_write(tmdev->sram_regmap_field, 0); ++ + /* + * The manual recommends an overall sample frequency of 50 KHz (20us, + * 480 cycles at 24 MHz), which provides plenty of time for both the diff --git a/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch b/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch new file mode 100644 index 000000000..e743d344c --- /dev/null +++ b/target/linux/sunxi/patches-6.1/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch @@ -0,0 +1,50 @@ +From e7dbfa19572a1440a2e67ef70f94ff204849a0a8 Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Mon, 19 Feb 2024 15:36:38 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Add support for H616 THS controller + +Add support for the thermal sensor found in H616 SoCs, is the same as +the H6 thermal sensor controller, but with four sensors. +Also the registers readings are wrong, unless a bit in the first SYS_CFG +register cleared, so set exercise the SRAM regmap to take care of that. + +Signed-off-by: Martin Botka +Signed-off-by: Andre Przywara +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-7-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -688,6 +688,20 @@ static const struct ths_thermal_chip sun + .calc_temp = sun8i_ths_calc_temp, + }; + ++static const struct ths_thermal_chip sun50i_h616_ths = { ++ .sensor_num = 4, ++ .has_bus_clk_reset = true, ++ .needs_sram = true, ++ .ft_deviation = 8000, ++ .offset = 263655, ++ .scale = 810, ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, ++ .calibrate = sun50i_h6_ths_calibrate, ++ .init = sun50i_h6_thermal_init, ++ .irq_ack = sun50i_h6_irq_ack, ++ .calc_temp = sun8i_ths_calc_temp, ++}; ++ + static const struct of_device_id of_ths_match[] = { + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, +@@ -697,6 +711,7 @@ static const struct of_device_id of_ths_ + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths }, + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, + { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths }, ++ { .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, of_ths_match); diff --git a/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch b/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch new file mode 100644 index 000000000..384bf5508 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch @@ -0,0 +1,68 @@ +From 9ac53d5532cc4bb595bbee86ccba2172ccc336c3 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Tue, 23 Jan 2024 23:33:07 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Don't fail probe due to zone + registration failure + +Currently the sun8i thermal driver will fail to probe if any of the +thermal zones it is registering fails to register with the thermal core. +Since we currently do not define any trip points for the GPU thermal +zones on at least A64 or H5 this means that we have no thermal support +on these platforms: + +[ 1.698703] thermal_sys: Failed to find 'trips' node +[ 1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1 + +even though the main CPU thermal zone on both SoCs is fully configured. +This does not seem ideal, while we may not be able to use all the zones +it seems better to have those zones which are usable be operational. +Instead just carry on registering zones if we get any non-deferral +error, allowing use of those zones which are usable. + +This means that we also need to update the interrupt handler to not +attempt to notify the core for events on zones which we have not +registered, I didn't see an ability to mask individual interrupts and +I would expect that interrupts would still be indicated in the ISR even +if they were masked. + +Reviewed-by: Vasily Khoruzhick +Acked-by: Jernej Skrabec +Signed-off-by: Mark Brown +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org +--- + drivers/thermal/sun8i_thermal.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -197,6 +197,9 @@ static irqreturn_t sun8i_irq_thread(int + int i; + + for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) { ++ /* We allow some zones to not register. */ ++ if (IS_ERR(tmdev->sensor[i].tzd)) ++ continue; + thermal_zone_device_update(tmdev->sensor[i].tzd, + THERMAL_EVENT_UNSPECIFIED); + } +@@ -531,8 +534,17 @@ static int sun8i_ths_register(struct ths + i, + &tmdev->sensor[i], + &ths_ops); +- if (IS_ERR(tmdev->sensor[i].tzd)) +- return PTR_ERR(tmdev->sensor[i].tzd); ++ ++ /* ++ * If an individual zone fails to register for reasons ++ * other than probe deferral (eg, a bad DT) then carry ++ * on, other zones might register successfully. ++ */ ++ if (IS_ERR(tmdev->sensor[i].tzd)) { ++ if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER) ++ return PTR_ERR(tmdev->sensor[i].tzd); ++ continue; ++ } + + if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd)) + dev_warn(tmdev->dev, diff --git a/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch b/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch new file mode 100644 index 000000000..cd6542bf1 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch @@ -0,0 +1,138 @@ +From f4318af40544b8e7ff5a6b667ede60e6cf808262 Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Mon, 19 Feb 2024 15:36:39 +0000 +Subject: [PATCH] arm64: dts: allwinner: h616: Add thermal sensor and zones + +There are four thermal sensors: +- CPU +- GPU +- VE +- DRAM + +Add the thermal sensor configuration and the thermal zones. + +Signed-off-by: Martin Botka +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20240219153639.179814-8-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++ + 1 file changed, 88 insertions(+) + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + / { + interrupt-parent = <&gic>; +@@ -138,6 +139,10 @@ + reg = <0x03006000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ ths_calibration: thermal-sensor-calibration@14 { ++ reg = <0x14 0x8>; ++ }; + }; + + watchdog: watchdog@30090a0 { +@@ -511,6 +516,19 @@ + }; + }; + ++ ths: thermal-sensor@5070400 { ++ compatible = "allwinner,sun50i-h616-ths"; ++ reg = <0x05070400 0x400>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_THS>; ++ clock-names = "bus"; ++ resets = <&ccu RST_BUS_THS>; ++ nvmem-cells = <&ths_calibration>; ++ nvmem-cell-names = "calibration"; ++ allwinner,sram = <&syscon>; ++ #thermal-sensor-cells = <1>; ++ }; ++ + usbotg: usb@5100000 { + compatible = "allwinner,sun50i-h616-musb", + "allwinner,sun8i-h3-musb"; +@@ -755,4 +773,74 @@ + #size-cells = <0>; + }; + }; ++ ++ thermal-zones { ++ cpu-thermal { ++ polling-delay-passive = <500>; ++ polling-delay = <1000>; ++ thermal-sensors = <&ths 2>; ++ sustainable-power = <1000>; ++ ++ trips { ++ cpu_threshold: cpu-trip-0 { ++ temperature = <60000>; ++ type = "passive"; ++ hysteresis = <0>; ++ }; ++ cpu_target: cpu-trip-1 { ++ temperature = <70000>; ++ type = "passive"; ++ hysteresis = <0>; ++ }; ++ cpu_critical: cpu-trip-2 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ gpu-thermal { ++ polling-delay-passive = <500>; ++ polling-delay = <1000>; ++ thermal-sensors = <&ths 0>; ++ sustainable-power = <1100>; ++ ++ trips { ++ gpu_temp_critical: gpu-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ ve-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&ths 1>; ++ ++ trips { ++ ve_temp_critical: ve-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ ddr-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&ths 3>; ++ ++ trips { ++ ddr_temp_critical: ddr-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ }; + }; diff --git a/target/linux/sunxi/patches-6.1/101-sunxi-add-get_soc_chipid-and-sunxi_get_serial.patch b/target/linux/sunxi/patches-6.1/101-sunxi-add-get_soc_chipid-and-sunxi_get_serial.patch new file mode 100644 index 000000000..a3abf98e2 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/101-sunxi-add-get_soc_chipid-and-sunxi_get_serial.patch @@ -0,0 +1,53 @@ +From caaa7def76801cbe9937602603f6b471f776e6f6 Mon Sep 17 00:00:00 2001 +From: The-going <48602507+The-going@users.noreply.github.com> +Date: Sat, 16 Apr 2022 11:19:05 +0300 +Subject: [PATCH] nvmem: sunxi_sid: add sunxi_get_soc_chipid, sunxi_get_serial + +--- + drivers/nvmem/sunxi_sid.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +--- a/drivers/nvmem/sunxi_sid.c ++++ b/drivers/nvmem/sunxi_sid.c +@@ -37,6 +37,25 @@ struct sunxi_sid { + u32 value_offset; + }; + ++static unsigned int sunxi_soc_chipid[4]; ++static unsigned int sunxi_serial[4]; ++ ++int sunxi_get_soc_chipid(unsigned char *chipid) ++{ ++ memcpy(chipid, sunxi_soc_chipid, 16); ++ ++ return 0; ++} ++EXPORT_SYMBOL(sunxi_get_soc_chipid); ++ ++int sunxi_get_serial(unsigned char *serial) ++{ ++ memcpy(serial, sunxi_serial, 16); ++ ++ return 0; ++} ++EXPORT_SYMBOL(sunxi_get_serial); ++ + static int sunxi_sid_read(void *context, unsigned int offset, + void *val, size_t bytes) + { +@@ -180,6 +199,15 @@ static int sunxi_sid_probe(struct platfo + + platform_set_drvdata(pdev, nvmem); + ++ nvmem_cfg->reg_read(sid, 0, &sunxi_soc_chipid[0], sizeof(int)); ++ nvmem_cfg->reg_read(sid, 4, &sunxi_soc_chipid[1], sizeof(int)); ++ nvmem_cfg->reg_read(sid, 8, &sunxi_soc_chipid[2], sizeof(int)); ++ nvmem_cfg->reg_read(sid, 12, &sunxi_soc_chipid[3], sizeof(int)); ++ ++ sunxi_serial[0] = sunxi_soc_chipid[3]; ++ sunxi_serial[1] = sunxi_soc_chipid[2]; ++ sunxi_serial[2] = (sunxi_soc_chipid[1] >> 16) & 0x0ffff; ++ + return 0; + } + diff --git a/target/linux/sunxi/patches-6.1/460-ARM-dts-suniv-add-USB-related-device-nodes.patch b/target/linux/sunxi/patches-6.1/460-ARM-dts-suniv-add-USB-related-device-nodes.patch new file mode 100644 index 000000000..86bc2e25f --- /dev/null +++ b/target/linux/sunxi/patches-6.1/460-ARM-dts-suniv-add-USB-related-device-nodes.patch @@ -0,0 +1,35 @@ +--- a/arch/arm/boot/dts/suniv-f1c100s.dtsi ++++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi +@@ -133,6 +133,32 @@ + #size-cells = <0>; + }; + ++ usb_otg: usb@1c13000 { ++ compatible = "allwinner,suniv-f1c100s-musb"; ++ reg = <0x01c13000 0x0400>; ++ clocks = <&ccu CLK_BUS_OTG>; ++ resets = <&ccu RST_BUS_OTG>; ++ interrupts = <26>; ++ interrupt-names = "mc"; ++ phys = <&usbphy 0>; ++ phy-names = "usb"; ++ extcon = <&usbphy 0>; ++ allwinner,sram = <&otg_sram 1>; ++ status = "disabled"; ++ }; ++ ++ usbphy: phy@1c13400 { ++ compatible = "allwinner,suniv-f1c100s-usb-phy"; ++ reg = <0x01c13400 0x10>; ++ reg-names = "phy_ctrl"; ++ clocks = <&ccu CLK_USB_PHY0>; ++ clock-names = "usb0_phy"; ++ resets = <&ccu RST_USB_PHY0>; ++ reset-names = "usb0_reset"; ++ #phy-cells = <1>; ++ status = "disabled"; ++ }; ++ + ccu: clock@1c20000 { + compatible = "allwinner,suniv-f1c100s-ccu"; + reg = <0x01c20000 0x400>; diff --git a/target/linux/sunxi/patches-6.1/461-ARM-dts-suniv-add-device-tree-for-PopStick-v1_1.patch b/target/linux/sunxi/patches-6.1/461-ARM-dts-suniv-add-device-tree-for-PopStick-v1_1.patch new file mode 100644 index 000000000..1030494ce --- /dev/null +++ b/target/linux/sunxi/patches-6.1/461-ARM-dts-suniv-add-device-tree-for-PopStick-v1_1.patch @@ -0,0 +1,123 @@ +From 7452d4799c5b352d6987cff3db8b1e415466586e Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Sun, 19 Mar 2023 21:29:35 +0000 +Subject: ARM: dts: suniv: add device tree for PopStick v1.1 + +PopStick is a minimal Allwinner F1C200s dongle, with its USB controller +wired to a USB Type-A plug, a SD slot and a SPI NAND flash on board, and +an on-board CH340 USB-UART converted connected to F1C200s's UART0. + +Add a device tree for it. As F1C200s is just F1C100s with a different +DRAM chip co-packaged, directly use F1C100s DTSI here. + +This commit covers the v1.1 version of this board, which is now shipped. +v1.0 is some internal sample that have not been shipped at all. + +Signed-off-by: Icenowy Zheng +Signed-off-by: Andre Przywara +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230319212936.26649-6-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + arch/arm/boot/dts/suniv-f1c200s-popstick-v1.1.dts | 81 +++++++++++++++++++++++ + 1 file changed, 81 insertions(+) + create mode 100644 arch/arm/boot/dts/suniv-f1c200s-popstick-v1.1.dts + +(limited to 'arch/arm/boot/dts/suniv-f1c200s-popstick-v1.1.dts') + +--- /dev/null ++++ b/arch/arm/boot/dts/suniv-f1c200s-popstick-v1.1.dts +@@ -0,0 +1,81 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright 2022 Icenowy Zheng ++ */ ++ ++/dts-v1/; ++#include "suniv-f1c100s.dtsi" ++ ++#include ++#include ++ ++/ { ++ model = "Popcorn Computer PopStick v1.1"; ++ compatible = "sourceparts,popstick-v1.1", "sourceparts,popstick", ++ "allwinner,suniv-f1c200s", "allwinner,suniv-f1c100s"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led { ++ function = LED_FUNCTION_STATUS; ++ color = ; ++ gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>; /* PE6 */ ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ reg_vcc3v3: regulator-3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++}; ++ ++&mmc0 { ++ cd-gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */ ++ bus-width = <4>; ++ disable-wp; ++ vmmc-supply = <®_vcc3v3>; ++ status = "okay"; ++}; ++ ++&otg_sram { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pc_pins>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <40000000>; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pe_pins>; ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "peripheral"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1396,7 +1396,8 @@ dtb-$(CONFIG_MACH_SUN9I) += \ + sun9i-a80-optimus.dtb \ + sun9i-a80-cubieboard4.dtb + dtb-$(CONFIG_MACH_SUNIV) += \ +- suniv-f1c100s-licheepi-nano.dtb ++ suniv-f1c100s-licheepi-nano.dtb \ ++ suniv-f1c200s-popstick-v1.1.dtb + dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \ + tegra20-acer-a500-picasso.dtb \ + tegra20-asus-tf101.dtb \ diff --git a/target/linux/sunxi/patches-6.1/462-ARM-dts-suniv-licheepi-nano-enable-USB.patch b/target/linux/sunxi/patches-6.1/462-ARM-dts-suniv-licheepi-nano-enable-USB.patch new file mode 100644 index 000000000..f925d6de3 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/462-ARM-dts-suniv-licheepi-nano-enable-USB.patch @@ -0,0 +1,55 @@ +From bedc7c5490fce4e57b55e025b4adfbd31f25623d Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Sun, 19 Mar 2023 21:29:32 +0000 +Subject: ARM: dts: suniv: licheepi-nano: enable USB + +Lichee Pi Nano has a Micro-USB connector, with its D+, D- pins connected +to the USB pins of the SoC and ID pin connected to PE2 GPIO. + +Enable the USB functionality. + +Signed-off-by: Icenowy Zheng +Acked-by: Jernej Skrabec +Signed-off-by: Andre Przywara +Link: https://lore.kernel.org/r/20230319212936.26649-3-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +(limited to 'arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts') + +--- a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts ++++ b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts +@@ -6,6 +6,8 @@ + /dts-v1/; + #include "suniv-f1c100s.dtsi" + ++#include ++ + / { + model = "Lichee Pi Nano"; + compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s"; +@@ -50,8 +52,22 @@ + }; + }; + ++&otg_sram { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pe_pins>; + status = "okay"; + }; ++ ++&usb_otg { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ usb0_id_det-gpios = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */ ++ status = "okay"; ++}; diff --git a/target/linux/sunxi/patches-6.1/463-f1c100s-sram-driver.patch b/target/linux/sunxi/patches-6.1/463-f1c100s-sram-driver.patch new file mode 100644 index 000000000..5a6750cd0 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/463-f1c100s-sram-driver.patch @@ -0,0 +1,33 @@ +Allwinner ARMv5 F1C100s has similar sram controller to sun4i A10 +Add compatible strings for it. + +Signed-off-by: Mesih Kilinc +Acked-by: Maxime Ripard +--- + drivers/soc/sunxi/sunxi_sram.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -99,6 +99,10 @@ static const struct of_device_id sunxi_s + .compatible = "allwinner,sun50i-a64-sram-c", + .data = &sun50i_a64_sram_c.data, + }, ++ { ++ .compatible = "allwinner,suniv-f1c100s-sram-d", ++ .data = &sun4i_a10_sram_d.data, ++ }, + {} + }; + +@@ -429,6 +433,10 @@ static const struct of_device_id sunxi_s + .compatible = "allwinner,sun50i-h616-system-control", + .data = &sun50i_h616_sramc_variant, + }, ++ { ++ .compatible = "allwinner,suniv-f1c100s-system-control", ++ .data = &sun4i_a10_sramc_variant, ++ }, + { }, + }; + MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); diff --git a/target/linux/sunxi/patches-6.1/464-f1c100s-watchdog-compat.patch b/target/linux/sunxi/patches-6.1/464-f1c100s-watchdog-compat.patch new file mode 100644 index 000000000..0bd090636 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/464-f1c100s-watchdog-compat.patch @@ -0,0 +1,18 @@ +Allwinner ARMv5 F1C100s has similar watchdog timer to sun6i A31. +Add compatible string for it. + +Signed-off-by: Mesih Kilinc +--- + drivers/watchdog/sunxi_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/watchdog/sunxi_wdt.c ++++ b/drivers/watchdog/sunxi_wdt.c +@@ -241,6 +241,7 @@ static const struct of_device_id sunxi_w + { .compatible = "allwinner,sun4i-a10-wdt", .data = &sun4i_wdt_reg }, + { .compatible = "allwinner,sun6i-a31-wdt", .data = &sun6i_wdt_reg }, + { .compatible = "allwinner,sun20i-d1-wdt", .data = &sun20i_wdt_reg }, ++ { .compatible = "allwinner,suniv-f1c100s-wdt", .data = &sun6i_wdt_reg }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); diff --git a/target/linux/sunxi/patches-6.1/501-h616-Add-cpu-frequency-scaling-support.patch b/target/linux/sunxi/patches-6.1/501-h616-Add-cpu-frequency-scaling-support.patch new file mode 100644 index 000000000..71e8b7eae --- /dev/null +++ b/target/linux/sunxi/patches-6.1/501-h616-Add-cpu-frequency-scaling-support.patch @@ -0,0 +1,270 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AGM1968 +Date: Tue, 23 May 2023 16:43:00 +0000 +Subject: arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-frequency-scaling + +Signed-off-by: AGM1968 +--- + arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi | 75 ++++++++ + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + drivers/cpufreq/sun50i-cpufreq-nvmem.c | 91 +++++++--- + 3 files changed, 143 insertions(+), 24 deletions(-) + +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi +@@ -0,0 +1,75 @@ ++//SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++//Testing Version 1 from: AGM1968 ++//Noted: PLL_CPUX = 24 MHz*N/P (WIP) ++ ++/ { ++ cpu_opp_table: opp-table-cpu { ++ compatible = "allwinner,sun50i-h616-operating-points"; ++ nvmem-cells = <&cpu_speed_grade>; ++ opp-shared; ++ ++ opp-480000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <480000000>; ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-600000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-792000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <792000000>; ++ opp-microvolt-speed0 = <860000 860000 1100000>; ++ opp-microvolt-speed1 = <940000 940000 1100000>; ++ opp-microvolt-speed2 = <940000 940000 1100000>; ++ }; ++ ++ opp-1008000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt-speed0 = <900000 900000 1100000>; ++ opp-microvolt-speed1 = <1020000 1020000 1100000>; ++ opp-microvolt-speed2 = <1020000 1020000 1100000>; ++ }; ++ ++ opp-1200000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt-speed0 = <960000 960000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ ++ opp-1512000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt-speed0 = <1100000 1100000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu1 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu2 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu3 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -102,6 +102,8 @@ static const struct of_device_id allowli + */ + static const struct of_device_id blocklist[] __initconst = { + { .compatible = "allwinner,sun50i-h6", }, ++ { .compatible = "allwinner,sun50i-h616", }, ++ { .compatible = "allwinner,sun50i-h618", }, + + { .compatible = "arm,vexpress", }, + +--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c ++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c +@@ -6,6 +6,9 @@ + * provide the OPP framework with required information. + * + * Copyright (C) 2019 Yangtao Li ++ * ++ * ADD efuse_xlate to extract SoC version so that h6 and h616 can coexist. ++ * Version 1 AGM1968 + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +@@ -19,25 +22,62 @@ + + #define MAX_NAME_LEN 7 + +-#define NVMEM_MASK 0x7 +-#define NVMEM_SHIFT 5 ++#define SUN50I_H616_NVMEM_MASK 0x22 ++#define SUN50I_H616_NVMEM_SHIFT 5 ++#define SUN50I_H6_NVMEM_MASK 0x7 ++#define SUN50I_H6_NVMEM_SHIFT 5 ++ ++struct sunxi_cpufreq_soc_data { ++ u32 (*efuse_xlate) (void *efuse); ++}; + + static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev; + ++static u32 sun50i_h616_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H616_NVMEM_SHIFT) & ++ SUN50I_H616_NVMEM_MASK; ++ ++ /* Tested as V1 h616 soc. Expected efuse values are 1 - 3, ++ slowest to fastest */ ++ if (efuse_value >=1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++}; ++ ++static u32 sun50i_h6_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H6_NVMEM_SHIFT) & ++ SUN50I_H6_NVMEM_MASK; ++ ++ /* ++ * We treat unexpected efuse values as if the SoC was from ++ * the slowest bin. Expected efuse values are 1 - 3, slowest ++ * to fastest. ++ */ ++ if (efuse_value >= 1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++}; ++ ++ + /** + * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value ++ * @soc_data: pointer to sunxi_cpufreq_soc_data context + * @versions: Set to the value parsed from efuse + * + * Returns 0 if success. + */ +-static int sun50i_cpufreq_get_efuse(u32 *versions) ++static int sun50i_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data *soc_data, ++ u32 *versions) + { + struct nvmem_cell *speedbin_nvmem; + struct device_node *np; + struct device *cpu_dev; +- u32 *speedbin, efuse_value; ++ u32 *speedbin; + size_t len; +- int ret; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) +@@ -46,10 +86,9 @@ static int sun50i_cpufreq_get_efuse(u32 + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) + return -ENOENT; +- +- ret = of_device_is_compatible(np, +- "allwinner,sun50i-h6-operating-points"); +- if (!ret) { ++ if (of_device_is_compatible(np, "allwinner,sun50i-h6-operating-points")) {} ++ else if (of_device_is_compatible(np, "allwinner,sun50i-h616-operating-points")) {} ++ else { + of_node_put(np); + return -ENOENT; + } +@@ -65,17 +104,7 @@ static int sun50i_cpufreq_get_efuse(u32 + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + +- efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK; +- +- /* +- * We treat unexpected efuse values as if the SoC was from +- * the slowest bin. Expected efuse values are 1-3, slowest +- * to fastest. +- */ +- if (efuse_value >= 1 && efuse_value <= 3) +- *versions = efuse_value - 1; +- else +- *versions = 0; ++ *versions = soc_data->efuse_xlate(speedbin); + + kfree(speedbin); + return 0; +@@ -83,18 +112,23 @@ static int sun50i_cpufreq_get_efuse(u32 + + static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) + { ++ const struct of_device_id *match; + int *opp_tokens; + char name[MAX_NAME_LEN]; + unsigned int cpu; + u32 speed = 0; + int ret; + ++ match = dev_get_platdata(&pdev->dev); ++ if (!match) ++ return -EINVAL; ++ + opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens), + GFP_KERNEL); + if (!opp_tokens) + return -ENOMEM; + +- ret = sun50i_cpufreq_get_efuse(&speed); ++ ret = sun50i_cpufreq_get_efuse(match-> data, &speed); + if (ret) { + kfree(opp_tokens); + return ret; +@@ -159,8 +193,18 @@ static struct platform_driver sun50i_cpu + }, + }; + ++static const struct sunxi_cpufreq_soc_data sun50i_h616_data = { ++ .efuse_xlate = sun50i_h616_efuse_xlate, ++}; ++ ++static const struct sunxi_cpufreq_soc_data sun50i_h6_data = { ++ .efuse_xlate = sun50i_h6_efuse_xlate, ++}; ++ + static const struct of_device_id sun50i_cpufreq_match_list[] = { +- { .compatible = "allwinner,sun50i-h6" }, ++ { .compatible = "allwinner,sun50i-h6", .data = &sun50i_h6_data }, ++ { .compatible = "allwinner,sun50i-h616", .data = &sun50i_h616_data }, ++ { .compatible = "allwinner,sun50i-h618", .data = &sun50i_h616_data }, + {} + }; + MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list); +@@ -196,8 +240,8 @@ static int __init sun50i_cpufreq_init(vo + return ret; + + sun50i_cpufreq_pdev = +- platform_device_register_simple("sun50i-cpufreq-nvmem", +- -1, NULL, 0); ++ platform_device_register_data(NULL, ++ "sun50i-cpufreq-nvmem", -1, match, sizeof(*match)); + ret = PTR_ERR_OR_ZERO(sun50i_cpufreq_pdev); + if (ret == 0) + return 0; diff --git a/target/linux/sunxi/patches-6.1/502-arm64-dts-allwinner-h616-Add-cpufreq.patch b/target/linux/sunxi/patches-6.1/502-arm64-dts-allwinner-h616-Add-cpufreq.patch new file mode 100644 index 000000000..d7554e106 --- /dev/null +++ b/target/linux/sunxi/patches-6.1/502-arm64-dts-allwinner-h616-Add-cpufreq.patch @@ -0,0 +1,53 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -143,6 +143,10 @@ + ths_calibration: thermal-sensor-calibration@14 { + reg = <0x14 0x8>; + }; ++ ++ cpu_speed_grade: cpu_speed_grade@0 { ++ reg = <0x0 0x2>; ++ }; + }; + + watchdog: watchdog@30090a0 { +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +@@ -6,12 +6,17 @@ + /dts-v1/; + + #include "sun50i-h616-orangepi-zero.dtsi" ++#include "sun50i-h616-cpu-opp.dtsi" + + / { + model = "OrangePi Zero2"; + compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616"; + }; + ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++}; ++ + &emac0 { + allwinner,rx-delay-ps = <3100>; + allwinner,tx-delay-ps = <700>; +--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts +@@ -6,12 +6,17 @@ + /dts-v1/; + + #include "sun50i-h616-orangepi-zero.dtsi" ++#include "sun50i-h616-cpu-opp.dtsi" + + / { + model = "OrangePi Zero3"; + compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618"; + }; + ++&cpu0 { ++ cpu-supply = <®_dcdc2>; ++}; ++ + &emac0 { + allwinner,tx-delay-ps = <700>; + phy-mode = "rgmii-rxid"; diff --git a/target/linux/sunxi/patches-6.6/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch b/target/linux/sunxi/patches-6.6/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch new file mode 100644 index 000000000..ce8add18a --- /dev/null +++ b/target/linux/sunxi/patches-6.6/008-v6.7-arm64-dts-allwinner-h616-Add-SID-controller-node.patch @@ -0,0 +1,31 @@ +From 951992797378a2177946400438f4d23c9fceae5b Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Tue, 12 Sep 2023 14:25:13 +0200 +Subject: [PATCH] arm64: dts: allwinner: h616: Add SID controller node + +Add node for the H616 SID controller + +Signed-off-by: Martin Botka +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230912-sid-h616-v3-2-ee18e1c5bbb5@somainline.org +Signed-off-by: Jernej Skrabec +--- + arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -133,6 +133,13 @@ + #reset-cells = <1>; + }; + ++ sid: efuse@3006000 { ++ compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid"; ++ reg = <0x03006000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++ + watchdog: watchdog@30090a0 { + compatible = "allwinner,sun50i-h616-wdt", + "allwinner,sun6i-a31-wdt"; diff --git a/target/linux/sunxi/patches-6.6/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch b/target/linux/sunxi/patches-6.6/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch new file mode 100644 index 000000000..5f9cb0273 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/009-v6.9-soc-sunxi-sram-export-register-0-for-THS-on-H616.patch @@ -0,0 +1,98 @@ +From 898d96c5464b69af44f6407c5de81ebc349d574b Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:33 +0000 +Subject: [PATCH] soc: sunxi: sram: export register 0 for THS on H616 + +The Allwinner H616 SoC contains a mysterious bit at register offset 0x0 +in the SRAM control block. If bit 16 is set (the reset value), the +temperature readings of the THS are way off, leading to reports about +200C, at normal ambient temperatures. Clearing this bits brings the +reported values down to the expected values. +The BSP code clears this bit in firmware (U-Boot), and has an explicit +comment about this, but offers no real explanation. + +Experiments in U-Boot show that register 0x0 has no effect on the SRAM C +visibility: all tested bit settings still allow full read and write +access by the CPU to the whole of SRAM C. Only bit 24 of the register at +offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling +the THS switch functionality as an SRAM region would not reflect reality. + +Since we should not rely on firmware settings, allow other code (the THS +driver) to access this register, by exporting it through the already +existing regmap. This mimics what we already do for the LDO control and +the EMAC register. + +To avoid concurrent accesses to the same register at the same time, by +the SRAM switch code and the regmap code, use the same lock to protect +the access. The regmap subsystem allows to use an existing lock, so we +just need to hook in there. + +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-2-andre.przywara@arm.com +--- + drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release); + struct sunxi_sramc_variant { + int num_emac_clocks; + bool has_ldo_ctrl; ++ bool has_ths_offset; + }; + + static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { +@@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant + + static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { + .num_emac_clocks = 2, ++ .has_ths_offset = true, + }; + ++#define SUNXI_SRAM_THS_OFFSET_REG 0x0 + #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 + #define SUNXI_SYS_LDO_CTRL_REG 0x150 + +@@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible + { + const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev); + ++ if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset) ++ return true; + if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG && + reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) + return true; +@@ -327,6 +332,20 @@ static bool sunxi_sram_regmap_accessible + return false; + } + ++static void sunxi_sram_lock(void *_lock) ++{ ++ spinlock_t *lock = _lock; ++ ++ spin_lock(lock); ++} ++ ++static void sunxi_sram_unlock(void *_lock) ++{ ++ spinlock_t *lock = _lock; ++ ++ spin_unlock(lock); ++} ++ + static struct regmap_config sunxi_sram_regmap_config = { + .reg_bits = 32, + .val_bits = 32, +@@ -336,6 +355,9 @@ static struct regmap_config sunxi_sram_r + /* other devices have no business accessing other registers */ + .readable_reg = sunxi_sram_regmap_accessible_reg, + .writeable_reg = sunxi_sram_regmap_accessible_reg, ++ .lock = sunxi_sram_lock, ++ .unlock = sunxi_sram_unlock, ++ .lock_arg = &sram_lock, + }; + + static int __init sunxi_sram_probe(struct platform_device *pdev) diff --git a/target/linux/sunxi/patches-6.6/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch b/target/linux/sunxi/patches-6.6/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch new file mode 100644 index 000000000..66f576eb3 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/010-v6.8-thermal-drivers-sun8i-Add-D1-T113s-THS-controller-support.patch @@ -0,0 +1,47 @@ +From ebbf19e36d021f253425344b4d4b987f3b7d9be5 Mon Sep 17 00:00:00 2001 +From: Maxim Kiselev +Date: Mon, 18 Dec 2023 00:06:23 +0300 +Subject: [PATCH] thermal/drivers/sun8i: Add D1/T113s THS controller support + +This patch adds a thermal sensor controller support for the D1/T113s, +which is similar to the one on H6, but with only one sensor and +different scale and offset values. + +Signed-off-by: Maxim Kiselev +Acked-by: Jernej Skrabec +Reviewed-by: Andre Przywara +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231217210629.131486-3-bigunclemax@gmail.com +--- + drivers/thermal/sun8i_thermal.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -606,6 +606,18 @@ static const struct ths_thermal_chip sun + .calc_temp = sun8i_ths_calc_temp, + }; + ++static const struct ths_thermal_chip sun20i_d1_ths = { ++ .sensor_num = 1, ++ .has_bus_clk_reset = true, ++ .offset = 188552, ++ .scale = 673, ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, ++ .calibrate = sun50i_h6_ths_calibrate, ++ .init = sun50i_h6_thermal_init, ++ .irq_ack = sun50i_h6_irq_ack, ++ .calc_temp = sun8i_ths_calc_temp, ++}; ++ + static const struct of_device_id of_ths_match[] = { + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, +@@ -614,6 +626,7 @@ static const struct of_device_id of_ths_ + { .compatible = "allwinner,sun50i-a100-ths", .data = &sun50i_a100_ths }, + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths }, + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, ++ { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, of_ths_match); diff --git a/target/linux/sunxi/patches-6.6/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch b/target/linux/sunxi/patches-6.6/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch new file mode 100644 index 000000000..b8138a387 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/011-v6.9-thermal-drivers-sun8i-Explain-unknown-H6-register-value.patch @@ -0,0 +1,79 @@ +From 14f118aa50fe7c7c7330f56d007ecacca487cea8 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:35 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Explain unknown H6 register value + +So far we were ORing in some "unknown" value into the THS control +register on the Allwinner H6. This part of the register is not explained +in the H6 manual, but the H616 manual details those bits, and on closer +inspection the THS IP blocks in both SoCs seem very close: +- The BSP code for both SoCs writes the same values into THS_CTRL. +- The reset values of at least the first three registers are the same. + +Replace the "unknown" value with its proper meaning: "acquire time", +most probably the sample part of the sample & hold circuit of the ADC, +according to its explanation in the H616 manual. + +No functional change, just a macro rename and adjustment. + +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-4-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -50,7 +50,8 @@ + #define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16) + #define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8) + +-#define SUN50I_THS_CTRL0_T_ACQ(x) ((GENMASK(15, 0) & (x)) << 16) ++#define SUN50I_THS_CTRL0_T_ACQ(x) (GENMASK(15, 0) & ((x) - 1)) ++#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x) ((GENMASK(15, 0) & ((x) - 1)) << 16) + #define SUN50I_THS_FILTER_EN BIT(2) + #define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x)) + #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12) +@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct + return 0; + } + +-/* +- * Without this undocumented value, the returned temperatures would +- * be higher than real ones by about 20C. +- */ +-#define SUN50I_H6_CTRL0_UNK 0x0000002f +- + static int sun50i_h6_thermal_init(struct ths_device *tmdev) + { + int val; + + /* +- * T_acq = 20us +- * clkin = 24MHz +- * +- * x = T_acq * clkin - 1 +- * = 479 ++ * The manual recommends an overall sample frequency of 50 KHz (20us, ++ * 480 cycles at 24 MHz), which provides plenty of time for both the ++ * acquisition time (>24 cycles) and the actual conversion time ++ * (>14 cycles). ++ * The lower half of the CTRL register holds the "acquire time", in ++ * clock cycles, which the manual recommends to be 2us: ++ * 24MHz * 2us = 48 cycles. ++ * The high half of THS_CTRL encodes the sample frequency, in clock ++ * cycles: 24MHz * 20us = 480 cycles. ++ * This is explained in the H616 manual, but apparently wrongly ++ * described in the H6 manual, although the BSP code does the same ++ * for both SoCs. + */ + regmap_write(tmdev->regmap, SUN50I_THS_CTRL0, +- SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479)); ++ SUN50I_THS_CTRL0_T_ACQ(48) | ++ SUN50I_THS_CTRL0_T_SAMPLE_PER(480)); + /* average over 4 samples */ + regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC, + SUN50I_THS_FILTER_EN | diff --git a/target/linux/sunxi/patches-6.6/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch b/target/linux/sunxi/patches-6.6/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch new file mode 100644 index 000000000..a0dbad48c --- /dev/null +++ b/target/linux/sunxi/patches-6.6/012-v6.9-thermal-drivers-sun8i-Extend-H6-calibration-to-support-4.patch @@ -0,0 +1,74 @@ +From 6c04a419a4c5fb18edefc44dd676fb95c7f6c55d Mon Sep 17 00:00:00 2001 +From: Maksim Kiselev +Date: Mon, 19 Feb 2024 15:36:36 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Extend H6 calibration to support 4 + sensors + +The H616 SoC resembles the H6 thermal sensor controller, with a few +changes like four sensors. + +Extend sun50i_h6_ths_calibrate() function to support calibration of +these sensors. + +Co-developed-by: Martin Botka +Signed-off-by: Martin Botka +Signed-off-by: Maksim Kiselev +Reviewed-by: Andre Przywara +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-5-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++-------- + 1 file changed, 20 insertions(+), 8 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -222,16 +222,21 @@ static int sun50i_h6_ths_calibrate(struc + struct device *dev = tmdev->dev; + int i, ft_temp; + +- if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num) ++ if (!caldata[0]) + return -EINVAL; + + /* + * efuse layout: + * +- * 0 11 16 32 +- * +-------+-------+-------+ +- * |temp| |sensor0|sensor1| +- * +-------+-------+-------+ ++ * 0 11 16 27 32 43 48 57 ++ * +----------+-----------+-----------+-----------+ ++ * | temp | |sensor0| |sensor1| |sensor2| | ++ * +----------+-----------+-----------+-----------+ ++ * ^ ^ ^ ++ * | | | ++ * | | sensor3[11:8] ++ * | sensor3[7:4] ++ * sensor3[3:0] + * + * The calibration data on the H6 is the ambient temperature and + * sensor values that are filled during the factory test stage. +@@ -244,9 +249,16 @@ static int sun50i_h6_ths_calibrate(struc + ft_temp = (caldata[0] & FT_TEMP_MASK) * 100; + + for (i = 0; i < tmdev->chip->sensor_num; i++) { +- int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK; +- int cdata, offset; +- int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); ++ int sensor_reg, sensor_temp, cdata, offset; ++ ++ if (i == 3) ++ sensor_reg = (caldata[1] >> 12) ++ | ((caldata[2] >> 12) << 4) ++ | ((caldata[3] >> 12) << 8); ++ else ++ sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK; ++ ++ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); + + /* + * Calibration data is CALIBRATE_DEFAULT - (calculated diff --git a/target/linux/sunxi/patches-6.6/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch b/target/linux/sunxi/patches-6.6/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch new file mode 100644 index 000000000..9b5e9d374 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/013-v6.9-thermal-drivers-sun8i-Add-SRAM-register-access-code.patch @@ -0,0 +1,126 @@ +From f8b54d1120b81ed57bed96cc8e814ba08886d1e5 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Mon, 19 Feb 2024 15:36:37 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Add SRAM register access code + +The Allwinner H616 SoC needs to clear a bit in one register in the SRAM +controller, to report reasonable temperature values. On reset, bit 16 in +register 0x3000000 is set, which leads to the driver reporting +temperatures around 200C. Clearing this bit brings the values down to the +expected range. The BSP code does a one-time write in U-Boot, with a +comment just mentioning the effect on the THS, but offering no further +explanation. + +To not rely on firmware to set things up for us, add code that queries +the SRAM controller device via a DT phandle link, then clear just this +single bit. + +Signed-off-by: Andre Przywara +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-6-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -66,6 +67,7 @@ struct tsensor { + struct ths_thermal_chip { + bool has_mod_clk; + bool has_bus_clk_reset; ++ bool needs_sram; + int sensor_num; + int offset; + int scale; +@@ -83,12 +85,16 @@ struct ths_device { + const struct ths_thermal_chip *chip; + struct device *dev; + struct regmap *regmap; ++ struct regmap_field *sram_regmap_field; + struct reset_control *reset; + struct clk *bus_clk; + struct clk *mod_clk; + struct tsensor sensor[MAX_SENSOR_NUM]; + }; + ++/* The H616 needs to have a bit 16 in the SRAM control register cleared. */ ++static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16); ++ + /* Temp Unit: millidegree Celsius */ + static int sun8i_ths_calc_temp(struct ths_device *tmdev, + int id, int reg) +@@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_asse + reset_control_assert(data); + } + ++static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node) ++{ ++ struct device_node *sram_node; ++ struct platform_device *sram_pdev; ++ struct regmap *regmap = NULL; ++ ++ sram_node = of_parse_phandle(node, "allwinner,sram", 0); ++ if (!sram_node) ++ return ERR_PTR(-ENODEV); ++ ++ sram_pdev = of_find_device_by_node(sram_node); ++ if (!sram_pdev) { ++ /* platform device might not be probed yet */ ++ regmap = ERR_PTR(-EPROBE_DEFER); ++ goto out_put_node; ++ } ++ ++ /* If no regmap is found then the other device driver is at fault */ ++ regmap = dev_get_regmap(&sram_pdev->dev, NULL); ++ if (!regmap) ++ regmap = ERR_PTR(-EINVAL); ++ ++ platform_device_put(sram_pdev); ++out_put_node: ++ of_node_put(sram_node); ++ return regmap; ++} ++ + static int sun8i_ths_resource_init(struct ths_device *tmdev) + { + struct device *dev = tmdev->dev; +@@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struc + if (ret) + return ret; + ++ if (tmdev->chip->needs_sram) { ++ struct regmap *regmap; ++ ++ regmap = sun8i_ths_get_sram_regmap(dev->of_node); ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ tmdev->sram_regmap_field = devm_regmap_field_alloc(dev, ++ regmap, ++ sun8i_ths_sram_reg_field); ++ if (IS_ERR(tmdev->sram_regmap_field)) ++ return PTR_ERR(tmdev->sram_regmap_field); ++ } ++ + ret = sun8i_ths_calibrate(tmdev); + if (ret) + return ret; +@@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct + { + int val; + ++ /* The H616 needs to have a bit in the SRAM control register cleared. */ ++ if (tmdev->sram_regmap_field) ++ regmap_field_write(tmdev->sram_regmap_field, 0); ++ + /* + * The manual recommends an overall sample frequency of 50 KHz (20us, + * 480 cycles at 24 MHz), which provides plenty of time for both the diff --git a/target/linux/sunxi/patches-6.6/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch b/target/linux/sunxi/patches-6.6/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch new file mode 100644 index 000000000..187bc0dd7 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/014-v6.9-thermal-drivers-sun8i-Add-support-for-H616-THS-controller.patch @@ -0,0 +1,50 @@ +From e7dbfa19572a1440a2e67ef70f94ff204849a0a8 Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Mon, 19 Feb 2024 15:36:38 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Add support for H616 THS controller + +Add support for the thermal sensor found in H616 SoCs, is the same as +the H6 thermal sensor controller, but with four sensors. +Also the registers readings are wrong, unless a bit in the first SYS_CFG +register cleared, so set exercise the SRAM regmap to take care of that. + +Signed-off-by: Martin Botka +Signed-off-by: Andre Przywara +Acked-by: Vasily Khoruzhick +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240219153639.179814-7-andre.przywara@arm.com +--- + drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -684,6 +684,20 @@ static const struct ths_thermal_chip sun + .calc_temp = sun8i_ths_calc_temp, + }; + ++static const struct ths_thermal_chip sun50i_h616_ths = { ++ .sensor_num = 4, ++ .has_bus_clk_reset = true, ++ .needs_sram = true, ++ .ft_deviation = 8000, ++ .offset = 263655, ++ .scale = 810, ++ .temp_data_base = SUN50I_H6_THS_TEMP_DATA, ++ .calibrate = sun50i_h6_ths_calibrate, ++ .init = sun50i_h6_thermal_init, ++ .irq_ack = sun50i_h6_irq_ack, ++ .calc_temp = sun8i_ths_calc_temp, ++}; ++ + static const struct of_device_id of_ths_match[] = { + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, +@@ -693,6 +707,7 @@ static const struct of_device_id of_ths_ + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths }, + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, + { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths }, ++ { .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, of_ths_match); diff --git a/target/linux/sunxi/patches-6.6/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch b/target/linux/sunxi/patches-6.6/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch new file mode 100644 index 000000000..dd18cd953 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/015-v6.9-thermal-drivers-sun8i-Dont-fail-probe-due-to-zone-registra.patch @@ -0,0 +1,68 @@ +From 9ac53d5532cc4bb595bbee86ccba2172ccc336c3 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Tue, 23 Jan 2024 23:33:07 +0000 +Subject: [PATCH] thermal/drivers/sun8i: Don't fail probe due to zone + registration failure + +Currently the sun8i thermal driver will fail to probe if any of the +thermal zones it is registering fails to register with the thermal core. +Since we currently do not define any trip points for the GPU thermal +zones on at least A64 or H5 this means that we have no thermal support +on these platforms: + +[ 1.698703] thermal_sys: Failed to find 'trips' node +[ 1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1 + +even though the main CPU thermal zone on both SoCs is fully configured. +This does not seem ideal, while we may not be able to use all the zones +it seems better to have those zones which are usable be operational. +Instead just carry on registering zones if we get any non-deferral +error, allowing use of those zones which are usable. + +This means that we also need to update the interrupt handler to not +attempt to notify the core for events on zones which we have not +registered, I didn't see an ability to mask individual interrupts and +I would expect that interrupts would still be indicated in the ISR even +if they were masked. + +Reviewed-by: Vasily Khoruzhick +Acked-by: Jernej Skrabec +Signed-off-by: Mark Brown +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org +--- + drivers/thermal/sun8i_thermal.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/thermal/sun8i_thermal.c ++++ b/drivers/thermal/sun8i_thermal.c +@@ -195,6 +195,9 @@ static irqreturn_t sun8i_irq_thread(int + int i; + + for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) { ++ /* We allow some zones to not register. */ ++ if (IS_ERR(tmdev->sensor[i].tzd)) ++ continue; + thermal_zone_device_update(tmdev->sensor[i].tzd, + THERMAL_EVENT_UNSPECIFIED); + } +@@ -531,8 +534,17 @@ static int sun8i_ths_register(struct ths + i, + &tmdev->sensor[i], + &ths_ops); +- if (IS_ERR(tmdev->sensor[i].tzd)) +- return PTR_ERR(tmdev->sensor[i].tzd); ++ ++ /* ++ * If an individual zone fails to register for reasons ++ * other than probe deferral (eg, a bad DT) then carry ++ * on, other zones might register successfully. ++ */ ++ if (IS_ERR(tmdev->sensor[i].tzd)) { ++ if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER) ++ return PTR_ERR(tmdev->sensor[i].tzd); ++ continue; ++ } + + devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd); + } diff --git a/target/linux/sunxi/patches-6.6/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch b/target/linux/sunxi/patches-6.6/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch new file mode 100644 index 000000000..cd6542bf1 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/016-v6.9-arm64-dts-allwinner-h616-Add-thermal-sensor-and-zones.patch @@ -0,0 +1,138 @@ +From f4318af40544b8e7ff5a6b667ede60e6cf808262 Mon Sep 17 00:00:00 2001 +From: Martin Botka +Date: Mon, 19 Feb 2024 15:36:39 +0000 +Subject: [PATCH] arm64: dts: allwinner: h616: Add thermal sensor and zones + +There are four thermal sensors: +- CPU +- GPU +- VE +- DRAM + +Add the thermal sensor configuration and the thermal zones. + +Signed-off-by: Martin Botka +Signed-off-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20240219153639.179814-8-andre.przywara@arm.com +Signed-off-by: Jernej Skrabec +--- + .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++ + 1 file changed, 88 insertions(+) + +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + / { + interrupt-parent = <&gic>; +@@ -138,6 +139,10 @@ + reg = <0x03006000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ ths_calibration: thermal-sensor-calibration@14 { ++ reg = <0x14 0x8>; ++ }; + }; + + watchdog: watchdog@30090a0 { +@@ -511,6 +516,19 @@ + }; + }; + ++ ths: thermal-sensor@5070400 { ++ compatible = "allwinner,sun50i-h616-ths"; ++ reg = <0x05070400 0x400>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_THS>; ++ clock-names = "bus"; ++ resets = <&ccu RST_BUS_THS>; ++ nvmem-cells = <&ths_calibration>; ++ nvmem-cell-names = "calibration"; ++ allwinner,sram = <&syscon>; ++ #thermal-sensor-cells = <1>; ++ }; ++ + usbotg: usb@5100000 { + compatible = "allwinner,sun50i-h616-musb", + "allwinner,sun8i-h3-musb"; +@@ -755,4 +773,74 @@ + #size-cells = <0>; + }; + }; ++ ++ thermal-zones { ++ cpu-thermal { ++ polling-delay-passive = <500>; ++ polling-delay = <1000>; ++ thermal-sensors = <&ths 2>; ++ sustainable-power = <1000>; ++ ++ trips { ++ cpu_threshold: cpu-trip-0 { ++ temperature = <60000>; ++ type = "passive"; ++ hysteresis = <0>; ++ }; ++ cpu_target: cpu-trip-1 { ++ temperature = <70000>; ++ type = "passive"; ++ hysteresis = <0>; ++ }; ++ cpu_critical: cpu-trip-2 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ gpu-thermal { ++ polling-delay-passive = <500>; ++ polling-delay = <1000>; ++ thermal-sensors = <&ths 0>; ++ sustainable-power = <1100>; ++ ++ trips { ++ gpu_temp_critical: gpu-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ ve-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&ths 1>; ++ ++ trips { ++ ve_temp_critical: ve-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ ++ ddr-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&ths 3>; ++ ++ trips { ++ ddr_temp_critical: ddr-trip-0 { ++ temperature = <110000>; ++ type = "critical"; ++ hysteresis = <0>; ++ }; ++ }; ++ }; ++ }; + }; diff --git a/target/linux/sunxi/patches-6.6/102-sunxi-add-OF-node-for-USB-eth-on-NanoPi-R1S-H5.patch b/target/linux/sunxi/patches-6.6/102-sunxi-add-OF-node-for-USB-eth-on-NanoPi-R1S-H5.patch new file mode 100644 index 000000000..df4ef1d43 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/102-sunxi-add-OF-node-for-USB-eth-on-NanoPi-R1S-H5.patch @@ -0,0 +1,16 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts +@@ -116,6 +116,13 @@ + + &ehci1 { + status = "okay"; ++ ++ usb-eth@1 { ++ compatible = "realtek,rtl8153"; ++ reg = <1>; ++ ++ realtek,led-data = <0x78>; ++ }; + }; + + &ehci2 { diff --git a/target/linux/sunxi/patches-6.6/301-orangepi_pc2_usb_otg_to_host_key_power.patch b/target/linux/sunxi/patches-6.6/301-orangepi_pc2_usb_otg_to_host_key_power.patch new file mode 100644 index 000000000..eea47737f --- /dev/null +++ b/target/linux/sunxi/patches-6.6/301-orangepi_pc2_usb_otg_to_host_key_power.patch @@ -0,0 +1,20 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +@@ -60,7 +60,7 @@ + + key-sw4 { + label = "sw4"; +- linux,code = ; ++ linux,code = ; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + wakeup-source; + }; +@@ -221,7 +221,7 @@ + }; + + &usb_otg { +- dr_mode = "otg"; ++ dr_mode = "host"; + status = "okay"; + }; + diff --git a/target/linux/sunxi/patches-6.6/400-arm64-allwinner-a64-sopine-Add-Sopine-flash-partitio.patch b/target/linux/sunxi/patches-6.6/400-arm64-allwinner-a64-sopine-Add-Sopine-flash-partitio.patch new file mode 100644 index 000000000..a8dfcd9db --- /dev/null +++ b/target/linux/sunxi/patches-6.6/400-arm64-allwinner-a64-sopine-Add-Sopine-flash-partitio.patch @@ -0,0 +1,46 @@ +From 7d87d3dafc4b1ea5659eb71ee6c5fd5308490d1f Mon Sep 17 00:00:00 2001 +From: Oskari Lemmela +Date: Mon, 31 Dec 2018 07:44:49 +0200 +Subject: [PATCH] arm64: allwinner: a64-sopine: Add Sopine flash partitions. + +First 896kB to u-boot. Enough space for SPL, u-boot and ATF. +Next 128kB to u-boot environment and rest to firmware. + +Firmware partition is compatible FIT image dynamic splitting. + +Signed-off-by: Oskari Lemmela +--- + .../boot/dts/allwinner/sun50i-a64-sopine.dtsi | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi +@@ -58,6 +58,28 @@ + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "u-boot"; ++ reg = <0x000000 0x0E0000>; ++ }; ++ ++ partition@e0000 { ++ label = "u-boot-env"; ++ reg = <0x0E0000 0x020000>; ++ }; ++ ++ partition@100000 { ++ compatible = "denx,fit"; ++ label = "firmware"; ++ reg = <0x100000 0xF00000>; ++ }; ++ }; + }; + }; + diff --git a/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch new file mode 100644 index 000000000..01044fef4 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch @@ -0,0 +1,292 @@ +--- a/arch/arm/boot/dts/allwinner/Makefile ++++ b/arch/arm/boot/dts/allwinner/Makefile +@@ -280,6 +280,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ + sun8i-a83t-cubietruck-plus.dtb \ + sun8i-a83t-tbs-a711.dtb \ + sun8i-h2-plus-bananapi-m2-zero.dtb \ ++ sun8i-h2-plus-bananapi-p2-zero.dtb \ + sun8i-h2-plus-libretech-all-h3-cc.dtb \ + sun8i-h2-plus-orangepi-r1.dtb \ + sun8i-h2-plus-orangepi-zero.dtb \ +--- /dev/null ++++ b/arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-p2-zero.dts +@@ -0,0 +1,279 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (C) 2023 Zoltan HERPAI ++ * ++ * Based on sun8i-h2-plus-bananapi-m2-zero.dts, which is: ++ * Copyright (C) 2017 Icenowy Zheng ++ */ ++ ++/dts-v1/; ++#include "sun8i-h3.dtsi" ++#include "sunxi-common-regulators.dtsi" ++ ++#include ++#include ++ ++/ { ++ model = "Banana Pi BPI-P2-Zero"; ++ compatible = "sinovoip,bpi-p2-zero", "allwinner,sun8i-h2-plus"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ connector { ++ compatible = "hdmi-connector"; ++ type = "c"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ pwr_led { ++ label = "bananapi-p2-zero:red:pwr"; ++ gpios = <&r_pio 0 10 GPIO_ACTIVE_LOW>; /* PL10 */ ++ default-state = "on"; ++ }; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ ++ sw4 { ++ label = "power"; ++ linux,code = ; ++ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ reg_vdd_cpux: vdd-cpux-regulator { ++ compatible = "regulator-gpio"; ++ regulator-name = "vdd-cpux"; ++ regulator-type = "voltage"; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-ramp-delay = <50>; /* 4ms */ ++ ++ gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */ ++ enable-active-high; ++ gpios-states = <0x1>; ++ states = <1100000 0>, <1300000 1>; ++ }; ++ ++ reg_vcc_dram: vcc-dram { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-dram"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */ ++ vin-supply = <®_vcc5v0>; ++ }; ++ ++ reg_vcc1v2: vcc1v2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-always-on; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ ++ vin-supply = <®_vcc5v0>; ++ }; ++ ++ poweroff { ++ compatible = "regulator-poweroff"; ++ cpu-supply = <®_vcc1v2>; ++ }; ++ ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */ ++ clocks = <&rtc 1>; ++ clock-names = "ext_clock"; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_vdd_cpux>; ++}; ++ ++&de { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&emac { ++ phy-handle = <&int_mii_phy>; ++ phy-mode = "mii"; ++ allwinner,leds-active-low; ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <4>; ++ /* ++ * On the production batch of this board the card detect GPIO is ++ * high active (card inserted), although on the early samples it's ++ * low active. ++ */ ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ ++ status = "okay"; ++}; ++ ++&mmc1 { ++ vmmc-supply = <®_vcc3v3>; ++ vqmmc-supply = <®_vcc3v3>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&pio>; ++ interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pa_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <1500000>; ++ clocks = <&rtc 1>; ++ clock-names = "lpo"; ++ vbat-supply = <®_vcc3v3>; ++ vddio-supply = <®_vcc3v3>; ++ device-wakeup-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */ ++ host-wakeup-gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ ++ shutdown-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ ++ }; ++ ++}; ++ ++&pio { ++ gpio-line-names = ++ /* PA */ ++ "CON2-P13", "CON2-P11", "CON2-P22", "CON2-P15", ++ "CON3-P03", "CON3-P02", "CON2-P07", "CON2-P29", ++ "CON2-P31", "CON2-P33", "CON2-P35", "CON2-P05", ++ "CON2-P03", "CON2-P08", "CON2-P10", "CON2-P16", ++ "CON2-P12", "CON2-P37", "CON2-P28", "CON2-P27", ++ "CON2-P40", "CON2-P38", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PB */ ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PC */ ++ "CON2-P19", "CON2-P21", "CON2-P23", "CON2-P24", ++ "CON2-P18", "", "", "CON2-P26", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PD */ ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "CSI-PWR-EN", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PE */ ++ "CN3-P17", "CN3-P13", "CN3-P09", "CN3-P07", ++ "CN3-P19", "CN3-P21", "CN3-P22", "CN3-P20", ++ "CN3-P18", "CN3-P16", "CN3-P14", "CN3-P12", ++ "CN3-P05", "CN3-P03", "CN3-P06", "CN3-P08", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PF */ ++ "SDC0-D1", "SDC0-D0", "SDC0-CLK", "SDC0-CMD", "SDC0-D3", ++ "SDC0-D2", "SDC0-DET", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ ++ /* PG */ ++ "WL-SDIO-CLK", "WL-SDIO-CMD", "WL-SDIO-D0", "WL-SDIO-D1", ++ "WL-SDIO-D2", "WL-SDIO-D3", "BT-UART-TX", "BT-UART-RX", ++ "BT-UART-RTS", "BT-UART-CTS", "WL-WAKE-AP", "BT-WAKE-AP", ++ "BT-RST-N", "AP-WAKE-BT", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", ""; ++}; ++ ++&r_pio { ++ gpio-line-names = ++ /* PL */ ++ "", "CPUX-SET", "CON2-P32", "POWER-KEY", "CON2-P36", ++ "VCC-IO-EN", "USB0-ID", "WL-PWR-EN", ++ "PWR-STB", "PWR-DRAM", "PWR-LED", "IR-RX", "", "", "", "", ++ "", "", "", "", "", "", "", "", ++ "", "", "", "", "", "", "", ""; ++}; ++ ++&usb_otg { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ ++ /* ++ * There're two micro-USB connectors, one is power-only and another is ++ * OTG. The Vbus of these two connectors are connected together, so ++ * the external USB device will be powered just by the power input ++ * from the power-only USB port. ++ */ ++ status = "okay"; ++}; diff --git a/target/linux/sunxi/patches-6.6/430-arm64-dts-allwinner-a64-olinuxino-add-status-LED-ali.patch b/target/linux/sunxi/patches-6.6/430-arm64-dts-allwinner-a64-olinuxino-add-status-LED-ali.patch new file mode 100644 index 000000000..68ec333e3 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/430-arm64-dts-allwinner-a64-olinuxino-add-status-LED-ali.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20=C5=A0tetiar?= +Date: Thu, 26 Mar 2020 10:09:19 +0100 +Subject: [PATCH] arm64: dts: allwinner: a64: olinuxino: add status LED aliases +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Petr Štetiar + +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +@@ -15,6 +15,10 @@ + aliases { + ethernet0 = &emac; + serial0 = &uart0; ++ led-boot = &led_user; ++ led-failsafe = &led_user; ++ led-running = &led_user; ++ led-upgrade = &led_user; + }; + + chosen { +@@ -35,7 +39,7 @@ + leds { + compatible = "gpio-leds"; + +- led-0 { ++ led_user: led-0 { + label = "a64-olinuxino:red:user"; + gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */ + }; diff --git a/target/linux/sunxi/patches-6.6/442-arm64-dts-orangepi-one-plus-enable-PWM.patch b/target/linux/sunxi/patches-6.6/442-arm64-dts-orangepi-one-plus-enable-PWM.patch new file mode 100644 index 000000000..76a73ee1f --- /dev/null +++ b/target/linux/sunxi/patches-6.6/442-arm64-dts-orangepi-one-plus-enable-PWM.patch @@ -0,0 +1,10 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts +@@ -41,3 +41,7 @@ + reg = <1>; + }; + }; ++ ++&pwm { ++ status = "okay"; ++}; diff --git a/target/linux/sunxi/patches-6.6/450-arm64-dts-enable-wifi-on-pine64-boards.patch b/target/linux/sunxi/patches-6.6/450-arm64-dts-enable-wifi-on-pine64-boards.patch new file mode 100644 index 000000000..3876852c2 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/450-arm64-dts-enable-wifi-on-pine64-boards.patch @@ -0,0 +1,72 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +@@ -42,6 +42,11 @@ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; ++ ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ ++ }; + }; + + &ac_power_supply { +@@ -102,6 +107,21 @@ + reg = <1>; + }; + }; ++ ++&mmc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; ++ vmmc-supply = <®_dldo4>; ++ vqmmc-supply = <®_eldo1>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ rtl8723cs: wifi@1 { ++ reg = <1>; ++ }; ++}; + + &mmc2 { + pinctrl-names = "default"; +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +@@ -35,6 +35,11 @@ + }; + }; + }; ++ ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ ++ }; + }; + + &codec { +@@ -124,6 +129,21 @@ + status = "okay"; + }; + ++&mmc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; ++ vmmc-supply = <®_dldo4>; ++ vqmmc-supply = <®_eldo1>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ rtl8723cs: wifi@1 { ++ reg = <1>; ++ }; ++}; ++ + &ohci0 { + status = "okay"; + }; diff --git a/target/linux/sunxi/patches-6.6/501-h616-Add-cpu-frequency-scaling-support.patch b/target/linux/sunxi/patches-6.6/501-h616-Add-cpu-frequency-scaling-support.patch new file mode 100644 index 000000000..62e88a091 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/501-h616-Add-cpu-frequency-scaling-support.patch @@ -0,0 +1,270 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AGM1968 +Date: Tue, 23 May 2023 16:43:00 +0000 +Subject: arm64-dts-allwinner-h616-Add-efuse_xlate-cpu-frequency-scaling + +Signed-off-by: AGM1968 +--- + arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi | 75 ++++++++ + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + drivers/cpufreq/sun50i-cpufreq-nvmem.c | 91 +++++++--- + 3 files changed, 143 insertions(+), 24 deletions(-) + +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi +@@ -0,0 +1,75 @@ ++//SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++//Testing Version 1 from: AGM1968 ++//Noted: PLL_CPUX = 24 MHz*N/P (WIP) ++ ++/ { ++ cpu_opp_table: opp-table-cpu { ++ compatible = "allwinner,sun50i-h616-operating-points"; ++ nvmem-cells = <&cpu_speed_grade>; ++ opp-shared; ++ ++ opp-480000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <480000000>; ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-600000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt-speed0 = <820000 820000 1100000>; ++ opp-microvolt-speed1 = <880000 880000 1100000>; ++ opp-microvolt-speed2 = <880000 880000 1100000>; ++ }; ++ ++ opp-792000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <792000000>; ++ opp-microvolt-speed0 = <860000 860000 1100000>; ++ opp-microvolt-speed1 = <940000 940000 1100000>; ++ opp-microvolt-speed2 = <940000 940000 1100000>; ++ }; ++ ++ opp-1008000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt-speed0 = <900000 900000 1100000>; ++ opp-microvolt-speed1 = <1020000 1020000 1100000>; ++ opp-microvolt-speed2 = <1020000 1020000 1100000>; ++ }; ++ ++ opp-1200000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt-speed0 = <960000 960000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ ++ opp-1512000000 { ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt-speed0 = <1100000 1100000 1100000>; ++ opp-microvolt-speed1 = <1100000 1100000 1100000>; ++ opp-microvolt-speed2 = <1100000 1100000 1100000>; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu1 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu2 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; ++ ++&cpu3 { ++ operating-points-v2 = <&cpu_opp_table>; ++}; +--- 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 + */ + static const struct of_device_id blocklist[] __initconst = { + { .compatible = "allwinner,sun50i-h6", }, ++ { .compatible = "allwinner,sun50i-h616", }, ++ { .compatible = "allwinner,sun50i-h618", }, + + { .compatible = "apple,arm-platform", }, + +--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c ++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c +@@ -6,6 +6,9 @@ + * provide the OPP framework with required information. + * + * Copyright (C) 2019 Yangtao Li ++ * ++ * ADD efuse_xlate to extract SoC version so that h6 and h616 can coexist. ++ * Version 1 AGM1968 + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +@@ -20,25 +23,62 @@ + + #define MAX_NAME_LEN 7 + +-#define NVMEM_MASK 0x7 +-#define NVMEM_SHIFT 5 ++#define SUN50I_H616_NVMEM_MASK 0x22 ++#define SUN50I_H616_NVMEM_SHIFT 5 ++#define SUN50I_H6_NVMEM_MASK 0x7 ++#define SUN50I_H6_NVMEM_SHIFT 5 ++ ++struct sunxi_cpufreq_soc_data { ++ u32 (*efuse_xlate) (void *efuse); ++}; + + static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev; + ++static u32 sun50i_h616_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H616_NVMEM_SHIFT) & ++ SUN50I_H616_NVMEM_MASK; ++ ++ /* Tested as V1 h616 soc. Expected efuse values are 1 - 3, ++ slowest to fastest */ ++ if (efuse_value >=1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++}; ++ ++static u32 sun50i_h6_efuse_xlate(void *efuse) ++{ ++ u32 efuse_value = (*(u32 *)efuse >> SUN50I_H6_NVMEM_SHIFT) & ++ SUN50I_H6_NVMEM_MASK; ++ ++ /* ++ * We treat unexpected efuse values as if the SoC was from ++ * the slowest bin. Expected efuse values are 1 - 3, slowest ++ * to fastest. ++ */ ++ if (efuse_value >= 1 && efuse_value <= 3) ++ return efuse_value - 1; ++ else ++ return 0; ++}; ++ ++ + /** + * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value ++ * @soc_data: pointer to sunxi_cpufreq_soc_data context + * @versions: Set to the value parsed from efuse + * + * Returns 0 if success. + */ +-static int sun50i_cpufreq_get_efuse(u32 *versions) ++static int sun50i_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data *soc_data, ++ u32 *versions) + { + struct nvmem_cell *speedbin_nvmem; + struct device_node *np; + struct device *cpu_dev; +- u32 *speedbin, efuse_value; ++ u32 *speedbin; + size_t len; +- int ret; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) +@@ -47,10 +87,9 @@ static int sun50i_cpufreq_get_efuse(u32 + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) + return -ENOENT; +- +- ret = of_device_is_compatible(np, +- "allwinner,sun50i-h6-operating-points"); +- if (!ret) { ++ if (of_device_is_compatible(np, "allwinner,sun50i-h6-operating-points")) {} ++ else if (of_device_is_compatible(np, "allwinner,sun50i-h616-operating-points")) {} ++ else { + of_node_put(np); + return -ENOENT; + } +@@ -66,17 +105,7 @@ static int sun50i_cpufreq_get_efuse(u32 + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + +- efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK; +- +- /* +- * We treat unexpected efuse values as if the SoC was from +- * the slowest bin. Expected efuse values are 1-3, slowest +- * to fastest. +- */ +- if (efuse_value >= 1 && efuse_value <= 3) +- *versions = efuse_value - 1; +- else +- *versions = 0; ++ *versions = soc_data->efuse_xlate(speedbin); + + kfree(speedbin); + return 0; +@@ -84,18 +113,23 @@ static int sun50i_cpufreq_get_efuse(u32 + + static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) + { ++ const struct of_device_id *match; + int *opp_tokens; + char name[MAX_NAME_LEN]; + unsigned int cpu; + u32 speed = 0; + int ret; + ++ match = dev_get_platdata(&pdev->dev); ++ if (!match) ++ return -EINVAL; ++ + opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens), + GFP_KERNEL); + if (!opp_tokens) + return -ENOMEM; + +- ret = sun50i_cpufreq_get_efuse(&speed); ++ ret = sun50i_cpufreq_get_efuse(match-> data, &speed); + if (ret) { + kfree(opp_tokens); + return ret; +@@ -158,8 +192,18 @@ static struct platform_driver sun50i_cpu + }, + }; + ++static const struct sunxi_cpufreq_soc_data sun50i_h616_data = { ++ .efuse_xlate = sun50i_h616_efuse_xlate, ++}; ++ ++static const struct sunxi_cpufreq_soc_data sun50i_h6_data = { ++ .efuse_xlate = sun50i_h6_efuse_xlate, ++}; ++ + static const struct of_device_id sun50i_cpufreq_match_list[] = { +- { .compatible = "allwinner,sun50i-h6" }, ++ { .compatible = "allwinner,sun50i-h6", .data = &sun50i_h6_data }, ++ { .compatible = "allwinner,sun50i-h616", .data = &sun50i_h616_data }, ++ { .compatible = "allwinner,sun50i-h618", .data = &sun50i_h616_data }, + {} + }; + MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list); +@@ -195,8 +239,8 @@ static int __init sun50i_cpufreq_init(vo + return ret; + + sun50i_cpufreq_pdev = +- platform_device_register_simple("sun50i-cpufreq-nvmem", +- -1, NULL, 0); ++ platform_device_register_data(NULL, ++ "sun50i-cpufreq-nvmem", -1, match, sizeof(*match)); + ret = PTR_ERR_OR_ZERO(sun50i_cpufreq_pdev); + if (ret == 0) + return 0; diff --git a/target/linux/sunxi/patches-6.6/502-arm64-dts-allwinner-h616-Add-cpufreq.patch b/target/linux/sunxi/patches-6.6/502-arm64-dts-allwinner-h616-Add-cpufreq.patch new file mode 100644 index 000000000..d7554e106 --- /dev/null +++ b/target/linux/sunxi/patches-6.6/502-arm64-dts-allwinner-h616-Add-cpufreq.patch @@ -0,0 +1,53 @@ +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -143,6 +143,10 @@ + ths_calibration: thermal-sensor-calibration@14 { + reg = <0x14 0x8>; + }; ++ ++ cpu_speed_grade: cpu_speed_grade@0 { ++ reg = <0x0 0x2>; ++ }; + }; + + watchdog: watchdog@30090a0 { +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts +@@ -6,12 +6,17 @@ + /dts-v1/; + + #include "sun50i-h616-orangepi-zero.dtsi" ++#include "sun50i-h616-cpu-opp.dtsi" + + / { + model = "OrangePi Zero2"; + compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616"; + }; + ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++}; ++ + &emac0 { + allwinner,rx-delay-ps = <3100>; + allwinner,tx-delay-ps = <700>; +--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts +@@ -6,12 +6,17 @@ + /dts-v1/; + + #include "sun50i-h616-orangepi-zero.dtsi" ++#include "sun50i-h616-cpu-opp.dtsi" + + / { + model = "OrangePi Zero3"; + compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618"; + }; + ++&cpu0 { ++ cpu-supply = <®_dcdc2>; ++}; ++ + &emac0 { + allwinner,tx-delay-ps = <700>; + phy-mode = "rgmii-rxid"; diff --git a/target/linux/x86/64/config-6.6 b/target/linux/x86/64/config-6.6 index 5de48cc8a..a04a3649b 100644 --- a/target/linux/x86/64/config-6.6 +++ b/target/linux/x86/64/config-6.6 @@ -175,6 +175,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_DEVICE=y CONFIG_FB_EFI=y CONFIG_FB_HYPERV=y # CONFIG_FB_INTEL is not set diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile index 59a868b63..2c8592915 100644 --- a/target/linux/x86/Makefile +++ b/target/linux/x86/Makefile @@ -21,7 +21,7 @@ DEFAULT_PACKAGES += partx-utils mkf2fs e2fsprogs kmod-button-hotplug kmod-usb-hi kmod-alx kmod-e1000e kmod-igb kmod-igc kmod-igbvf kmod-iavf kmod-bnx2x kmod-pcnet32 kmod-tulip kmod-via-velocity kmod-vmxnet3 kmod-i40e kmod-i40evf \ kmod-sound-hda-core kmod-sound-hda-codec-realtek kmod-sound-hda-codec-via kmod-sound-via82xx kmod-sound-hda-intel kmod-sound-hda-codec-hdmi kmod-sound-i8x0 \ kmod-usb-net kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8150 kmod-usb-net-aqc111 kmod-mlx4-core kmod-mlx5-core kmod-drm-i915 kmod-drm-amdgpu kmod-usb-audio \ -kmod-usb-net-rtl8152-vendor kmod-r8125 kmod-r8168 kmod-8139cp kmod-8139too kmod-tg3 htop lm-sensors autocore-x86 automount autosamba ca-bundle +kmod-usb-net-rtl8152-vendor kmod-r8125 kmod-r8126 kmod-r8168 kmod-8139cp kmod-8139too kmod-tg3 htop lm-sensors autocore-x86 automount autosamba ca-bundle $(eval $(call BuildTarget)) diff --git a/target/linux/x86/config-5.10 b/target/linux/x86/config-5.10 index c77903aa1..6aec019ad 100644 --- a/target/linux/x86/config-5.10 +++ b/target/linux/x86/config-5.10 @@ -83,7 +83,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_IBPB_ENTRY=y CONFIG_CPU_IBRS_ENTRY=y -# CONFIG_SLS is not set CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_RMAP=y @@ -101,8 +100,8 @@ CONFIG_CRC16=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y # CONFIG_CRYPTO_CRC32_PCLMUL is not set -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1 CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_RNG2=y @@ -435,6 +434,7 @@ CONFIG_SERIO_I8042=y CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_SERPORT=y CONFIG_SG_POOL=y +# CONFIG_SLS is not set CONFIG_SMP=y # CONFIG_SMSC37B787_WDT is not set # CONFIG_SMSC_SCH311X_WDT is not set diff --git a/target/linux/x86/config-5.15 b/target/linux/x86/config-5.15 index fd864b0ee..102da2f64 100644 --- a/target/linux/x86/config-5.15 +++ b/target/linux/x86/config-5.15 @@ -364,8 +364,8 @@ CONFIG_POWER_SUPPLY=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_PID_ARCH_STATUS=y # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set -CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y # CONFIG_PUNIT_ATOM_DEBUG is not set # CONFIG_QCOM_QMI_HELPERS is not set CONFIG_RATIONAL=y diff --git a/target/linux/x86/config-5.4 b/target/linux/x86/config-5.4 index 01367cc53..e0fef1002 100644 --- a/target/linux/x86/config-5.4 +++ b/target/linux/x86/config-5.4 @@ -80,8 +80,8 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_USERSPACE is not set CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y # CONFIG_CPU_IDLE_GOV_HALTPOLL is not set +CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_CENTAUR=y CONFIG_CPU_SUP_CYRIX_32=y @@ -179,8 +179,8 @@ CONFIG_GENERIC_VDSO_32=y # CONFIG_GEOS is not set CONFIG_GLOB=y # CONFIG_HABANA_AI is not set -# CONFIG_HANGCHECK_TIMER is not set # CONFIG_HALTPOLL_CPUIDLE is not set +# CONFIG_HANGCHECK_TIMER is not set CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y diff --git a/target/linux/x86/config-6.1 b/target/linux/x86/config-6.1 index 89852a8d4..9cfbb38e2 100644 --- a/target/linux/x86/config-6.1 +++ b/target/linux/x86/config-6.1 @@ -203,8 +203,6 @@ CONFIG_HWMON=y CONFIG_HW_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIA=y -# CONFIG_HYPERVISOR_GUEST is not set -CONFIG_HZ_PERIODIC=y CONFIG_HYPERV=y CONFIG_HYPERVISOR_GUEST=y CONFIG_HYPERV_BALLOON=y @@ -214,9 +212,8 @@ CONFIG_HYPERV_STORAGE=y # CONFIG_HYPERV_TESTING is not set CONFIG_HYPERV_TIMER=y CONFIG_HYPERV_UTILS=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PTP_1588_CLOCK=y # CONFIG_HYPERV_VSOCKETS is not set +CONFIG_HZ_PERIODIC=y CONFIG_I2C=y CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD_MP2 is not set @@ -403,6 +400,8 @@ CONFIG_PREEMPT_RCU=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_PID_ARCH_STATUS=y # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y # CONFIG_PUNIT_ATOM_DEBUG is not set CONFIG_RANDOMIZE_KSTACK_OFFSET=y CONFIG_RANDSTRUCT_NONE=y diff --git a/target/linux/x86/config-6.6 b/target/linux/x86/config-6.6 index 89852a8d4..6b8876e8b 100644 --- a/target/linux/x86/config-6.6 +++ b/target/linux/x86/config-6.6 @@ -203,8 +203,6 @@ CONFIG_HWMON=y CONFIG_HW_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIA=y -# CONFIG_HYPERVISOR_GUEST is not set -CONFIG_HZ_PERIODIC=y CONFIG_HYPERV=y CONFIG_HYPERVISOR_GUEST=y CONFIG_HYPERV_BALLOON=y @@ -214,9 +212,8 @@ CONFIG_HYPERV_STORAGE=y # CONFIG_HYPERV_TESTING is not set CONFIG_HYPERV_TIMER=y CONFIG_HYPERV_UTILS=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PTP_1588_CLOCK=y # CONFIG_HYPERV_VSOCKETS is not set +CONFIG_HZ_PERIODIC=y CONFIG_I2C=y CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD_MP2 is not set @@ -320,9 +317,12 @@ CONFIG_NEED_PER_CPU_KM=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_NEED_SG_DMA_LENGTH=y # CONFIG_NET5501 is not set +CONFIG_NET_EGRESS=y +CONFIG_NET_INGRESS=y # CONFIG_NET_NS is not set CONFIG_NET_VENDOR_DAVICOM=y CONFIG_NET_VENDOR_FUNGIBLE=y +CONFIG_NET_XGRESS=y CONFIG_NLS=y # CONFIG_NOHIGHMEM is not set CONFIG_NR_CPUS=1 @@ -340,6 +340,7 @@ CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_PAGE_POOL=y CONFIG_PAGE_SIZE_LESS_THAN_256KB=y CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PAHOLE_VERSION=0 CONFIG_PC104=y # CONFIG_PC8736x_GPIO is not set @@ -403,6 +404,8 @@ CONFIG_PREEMPT_RCU=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_PID_ARCH_STATUS=y # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y # CONFIG_PUNIT_ATOM_DEBUG is not set CONFIG_RANDOMIZE_KSTACK_OFFSET=y CONFIG_RANDSTRUCT_NONE=y @@ -444,6 +447,9 @@ CONFIG_SG_POOL=y # CONFIG_SMSC_SCH311X_WDT is not set CONFIG_SPARSEMEM_STATIC=y CONFIG_SPARSE_IRQ=y +# CONFIG_SPECTRE_BHI_AUTO is not set +# CONFIG_SPECTRE_BHI_OFF is not set +CONFIG_SPECTRE_BHI_ON=y CONFIG_SPECULATION_MITIGATIONS=y CONFIG_SRCU=y # CONFIG_STATIC_CALL_SELFTEST is not set diff --git a/target/linux/x86/generic/config-6.6 b/target/linux/x86/generic/config-6.6 index e46fc01ee..5b2ca91dd 100644 --- a/target/linux/x86/generic/config-6.6 +++ b/target/linux/x86/generic/config-6.6 @@ -136,6 +136,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_DEVICE=y CONFIG_FB_EFI=y CONFIG_FB_HYPERV=y # CONFIG_FB_I810 is not set diff --git a/target/linux/x86/legacy/config-6.6 b/target/linux/x86/legacy/config-6.6 index f159d79c4..cd324aaf4 100644 --- a/target/linux/x86/legacy/config-6.6 +++ b/target/linux/x86/legacy/config-6.6 @@ -98,6 +98,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_DEVICE=y # CONFIG_FB_I810 is not set CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_FILLRECT=y diff --git a/target/linux/x86/patches-5.15/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch b/target/linux/x86/patches-5.15/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch index 5ca127c49..d46e27b47 100644 --- a/target/linux/x86/patches-5.15/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch +++ b/target/linux/x86/patches-5.15/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch @@ -140,7 +140,7 @@ and performance for all other cases. * and hopefully then we'll have sufficient space. --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c -@@ -3211,6 +3211,8 @@ static int __net_init tcp_sk_init(struct +@@ -3226,6 +3226,8 @@ static int __net_init tcp_sk_init(struct else net->ipv4.tcp_congestion_control = &tcp_reno; diff --git a/target/linux/x86/patches-6.1/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch b/target/linux/x86/patches-6.1/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch index 562a61b45..df453d5ef 100644 --- a/target/linux/x86/patches-6.1/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch +++ b/target/linux/x86/patches-6.1/998-add-a-sysctl-to-enable-disable-tcp_collapse-logic.patch @@ -140,7 +140,7 @@ and performance for all other cases. * and hopefully then we'll have sufficient space. --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c -@@ -3225,6 +3225,8 @@ static int __net_init tcp_sk_init(struct +@@ -3240,6 +3240,8 @@ static int __net_init tcp_sk_init(struct net->ipv4.sysctl_tcp_shrink_window = 0; diff --git a/toolchain/gcc/Config.version b/toolchain/gcc/Config.version index 8670f49b4..9ffe34066 100644 --- a/toolchain/gcc/Config.version +++ b/toolchain/gcc/Config.version @@ -16,5 +16,5 @@ config GCC_VERSION string default "8.4.0" if GCC_VERSION_8 default "12.2.0" if GCC_VERSION_12 - default "13.2.0" if GCC_VERSION_13 + default "13.3.0" if GCC_VERSION_13 default "11.3.0" diff --git a/toolchain/gcc/common.mk b/toolchain/gcc/common.mk index a87cf8cca..55be62280 100644 --- a/toolchain/gcc/common.mk +++ b/toolchain/gcc/common.mk @@ -41,8 +41,8 @@ ifeq ($(PKG_VERSION),12.2.0) PKG_HASH:=e549cf9cf3594a00e27b6589d4322d70e0720cdd213f39beb4181e06926230ff endif -ifeq ($(PKG_VERSION),13.2.0) - PKG_HASH:=e275e76442a6067341a27f04c5c6b83d8613144004c0413528863dc6b5c743da +ifeq ($(PKG_VERSION),13.3.0) + PKG_HASH:=0845e9621c9543a13f484e94584a49ffc0129970e9914624235fc1d061a0c083 endif PATCH_DIR=../patches-$(GCC_MAJOR_VERSION).x diff --git a/toolchain/gcc/patches-13.x/300-mips_Os_cpu_rtx_cost_model.patch b/toolchain/gcc/patches-13.x/300-mips_Os_cpu_rtx_cost_model.patch index ce21e0433..2ca42ad77 100644 --- a/toolchain/gcc/patches-13.x/300-mips_Os_cpu_rtx_cost_model.patch +++ b/toolchain/gcc/patches-13.x/300-mips_Os_cpu_rtx_cost_model.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc -@@ -20213,7 +20213,7 @@ mips_option_override (void) +@@ -20219,7 +20219,7 @@ mips_option_override (void) flag_pcc_struct_return = 0; /* Decide which rtx_costs structure to use. */ diff --git a/toolchain/gcc/patches-13.x/970-macos_arm64-building-fix.patch b/toolchain/gcc/patches-13.x/970-macos_arm64-building-fix.patch index 7844268e7..a0470b139 100644 --- a/toolchain/gcc/patches-13.x/970-macos_arm64-building-fix.patch +++ b/toolchain/gcc/patches-13.x/970-macos_arm64-building-fix.patch @@ -17,7 +17,7 @@ Date: Mon Aug 16 13:16:21 2021 +0100 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h -@@ -1185,7 +1185,7 @@ extern enum aarch64_code_model aarch64_c +@@ -1195,7 +1195,7 @@ extern enum aarch64_code_model aarch64_c /* Extra specs when building a native AArch64-hosted compiler. Option rewriting rules based on host system. */ diff --git a/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch b/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch new file mode 100644 index 000000000..167769360 --- /dev/null +++ b/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch @@ -0,0 +1,61 @@ +From dc651fe2e6b16087c519c0bd0bf943cb7c53c807 Mon Sep 17 00:00:00 2001 +In-Reply-To: <20240423234355.2414567-1-Tony.Ambardar@gmail.com> +References: <20240423234355.2414567-1-Tony.Ambardar@gmail.com> +From: Tony Ambardar +Date: Sat, 20 Apr 2024 21:30:13 -0700 +Subject: [PATCH v3] add renameat2 linux syscall wrapper +To: musl@lists.openwall.com +Cc: Rich Felker + +This syscall is available since Linux 3.15 and also implemented in glibc +from version 2.28. It is commonly used in filesystem or security contexts. + +Constants RENAME_NOREPLACE, RENAME_EXCHANGE, RENAME_WHITEOUT are guarded by +_GNU_SOURCE as with glibc. + +Signed-off-by: Tony Ambardar +--- +v2 -> v3: + * call SYS_renameat first if applicable + * drop unneeded error code handling + +v1 -> v2: + * align related constants + * drop 'int' from 'unsigned int' + * add fallback to SYS_renameat where applicable +--- + include/stdio.h | 7 +++++++ + src/linux/renameat2.c | 11 +++++++++++ + 2 files changed, 18 insertions(+) + create mode 100644 src/linux/renameat2.c + +--- a/include/stdio.h ++++ b/include/stdio.h +@@ -158,6 +158,13 @@ char *ctermid(char *); + #define L_ctermid 20 + #endif + ++#if defined(_GNU_SOURCE) ++#define RENAME_NOREPLACE (1 << 0) ++#define RENAME_EXCHANGE (1 << 1) ++#define RENAME_WHITEOUT (1 << 2) ++ ++int renameat2(int, const char *, int, const char *, unsigned); ++#endif + + #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ + || defined(_BSD_SOURCE) +--- /dev/null ++++ b/src/linux/renameat2.c +@@ -0,0 +1,11 @@ ++#define _GNU_SOURCE ++#include ++#include "syscall.h" ++ ++int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned flags) ++{ ++#ifdef SYS_renameat ++ if (!flags) return syscall(SYS_renameat, oldfd, old, newfd, new); ++#endif ++ return syscall(SYS_renameat2, oldfd, old, newfd, new, flags); ++} diff --git a/tools/autoconf-archive/patches/001-fix_ax_c_float_words_bigendian.patch b/tools/autoconf-archive/patches/001-fix_ax_c_float_words_bigendian.patch new file mode 100644 index 000000000..521cb9786 --- /dev/null +++ b/tools/autoconf-archive/patches/001-fix_ax_c_float_words_bigendian.patch @@ -0,0 +1,90 @@ +--- a/m4/ax_c_float_words_bigendian.m4 ++++ b/m4/ax_c_float_words_bigendian.m4 +@@ -27,32 +27,81 @@ + # If neither value is found, the user is instructed to specify the + # ordering. + # ++# Early versions of this macro (i.e., before serial 12) would not work ++# when interprocedural optimization (via link-time optimization) was ++# enabled. This would happen when, say, the GCC/clang "-flto" flag, or the ++# ICC "-ipo" flag was used, for example. The problem was that under these ++# conditions, the compiler did not allocate for and write the special ++# float value in the data segment of the object file, since doing so might ++# not prove optimal once more context was available. Thus, the special ++# value (in platform-dependent binary form) could not be found in the ++# object file, and the macro would fail. ++# ++# The solution to the above problem was to: ++# ++# 1) Compile and link a whole test program rather than just compile an ++# object file. This ensures that we reach the point where even an ++# interprocedural optimizing compiler writes values to the data segment. ++# ++# 2) Add code that requires the compiler to write the special value to ++# the data segment, as opposed to "optimizing away" the variable's ++# allocation. This could be done via compiler keywords or options, but ++# it's tricky to make this work for all versions of all compilers with ++# all optimization settings. The chosen solution was to make the exit ++# code of the test program depend on the storing of the special value ++# in memory (in the data segment). Because the exit code can be ++# verified, any compiler that aspires to be correct will produce a ++# program binary that contains the value, which the macro can then find. ++# ++# How does the exit code depend on the special value residing in memory? ++# Memory, unlike variables and registers, can be addressed indirectly at ++# run time. The exit code of this test program is a result of indirectly ++# reading and writing to the memory region where the special value is ++# supposed to reside. The actual memory addresses used and the values to ++# be written are derived from the the program input ("argv") and are ++# therefore not known at compile or link time. The compiler has no choice ++# but to defer the computation to run time, and to prepare by allocating ++# and populating the data segment with the special value. For further ++# details, refer to the source code of the test program. ++# ++# Note that the test program is never meant to be run. It only exists to ++# host a double float value in a given platform's binary format. Thus, ++# error handling is not included. ++# + # LICENSE + # +-# Copyright (c) 2008 Daniel Amelang ++# Copyright (c) 2008, 2023 Daniel Amelang + # + # Copying and distribution of this file, with or without modification, are + # permitted in any medium without royalty provided the copyright notice + # and this notice are preserved. This file is offered as-is, without any + # warranty. + +-#serial 11 ++#serial 13 + + AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], + [AC_CACHE_CHECK(whether float word ordering is bigendian, + ax_cv_c_float_words_bigendian, [ + + ax_cv_c_float_words_bigendian=unknown +-AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ ++AC_LINK_IFELSE([AC_LANG_SOURCE([[ ++ ++#include ++ ++static double m[] = {9.090423496703681e+223, 0.0}; + +-double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; ++int main (int argc, char *argv[]) ++{ ++ m[atoi (argv[1])] += atof (argv[2]); ++ return m[atoi (argv[3])] > 0.0; ++} + + ]])], [ + +-if grep noonsees conftest.$ac_objext >/dev/null ; then ++if grep noonsees conftest$EXEEXT >/dev/null ; then + ax_cv_c_float_words_bigendian=yes + fi +-if grep seesnoon conftest.$ac_objext >/dev/null ; then ++if grep seesnoon conftest$EXEEXT >/dev/null ; then + if test "$ax_cv_c_float_words_bigendian" = unknown; then + ax_cv_c_float_words_bigendian=no + else diff --git a/tools/automake/Makefile b/tools/automake/Makefile index 85ccc0ded..7f129c1d8 100644 --- a/tools/automake/Makefile +++ b/tools/automake/Makefile @@ -8,16 +8,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=automake PKG_CPE_ID:=cpe:/a:gnu:automake -PKG_VERSION:=1.15.1 +PKG_VERSION:=1.16.5 +PKG_API_VERSION:=$(word 2,$(subst ., ,$(PKG_VERSION))) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/automake -PKG_HASH:=af6ba39142220687c500f79b4aa2f181d9b24e4f8d8ec497cea4ba26c64bedaf +PKG_HASH:=07bd24ad08a64bc17250ce09ec56e921d6343903943e99ccf63bbf0705e34605 include $(INCLUDE_DIR)/host-build.mk HOST_CONFIGURE_ARGS += \ - --datarootdir=$(STAGING_DIR_HOST)/share \ --disable-silent-rules HOST_CONFIGURE_VARS += \ @@ -31,20 +31,23 @@ endef define Host/Install # remove old automake resources to avoid version conflicts - rm -rf $(STAGING_DIR_HOST)/share/aclocal-[0-9]* - rm -rf $(STAGING_DIR_HOST)/share/automake-[0-9]* - $(MAKE) -C $(HOST_BUILD_DIR) install + $(call Host/Uninstall) + $(call Host/Compile/Default,install) mv $(STAGING_DIR_HOST)/bin/aclocal $(STAGING_DIR_HOST)/bin/aclocal.real $(INSTALL_BIN) ./files/aclocal $(STAGING_DIR_HOST)/bin - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.9 - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.10 - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11 - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11.6 - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.15 + ( \ + api=$(PKG_API_VERSION); \ + while [ "$$$$api" -ge 11 ]; do \ + ln -sf aclocal "$(STAGING_DIR_HOST)/bin/aclocal-1.$$$$api"; \ + api=$$$$(($$$$api - 1)); \ + done; \ + ) endef define Host/Uninstall -$(call Host/Compile/Default,uninstall) + rm -rf $(STAGING_DIR_HOST)/share/aclocal-[0-9]* + rm -rf $(STAGING_DIR_HOST)/share/automake-[0-9]* endef $(eval $(call HostBuild)) diff --git a/tools/automake/patches/000-relocatable.patch b/tools/automake/patches/000-relocatable.patch index 02382ba8c..0b61eaeb4 100644 --- a/tools/automake/patches/000-relocatable.patch +++ b/tools/automake/patches/000-relocatable.patch @@ -1,44 +1,34 @@ --- a/lib/Automake/Config.in +++ b/lib/Automake/Config.in -@@ -32,7 +32,7 @@ our $PACKAGE = '@PACKAGE@'; +@@ -34,7 +34,7 @@ our $PACKAGE = '@PACKAGE@'; our $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@'; our $VERSION = '@VERSION@'; our $RELEASE_YEAR = '@RELEASE_YEAR@'; --our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@'; +-our $libdir = $ENV{"AUTOMAKE_LIBDIR"} || '@datadir@/@PACKAGE@-@APIVERSION@'; +our $libdir = $ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@'; our $perl_threads = 0; # We need at least this version for CLONE support. --- a/bin/aclocal.in +++ b/bin/aclocal.in -@@ -1,10 +1,12 @@ --#!@PERL@ -w -+#!@PERL@ - # -*- perl -*- - # @configure_input@ - - eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; +@@ -23,9 +23,11 @@ use 5.006; + use strict; + use warnings FATAL => 'all'; +$^W = 1; + - # aclocal - create aclocal.m4 by scanning configure.ac - - # Copyright (C) 1996-2017 Free Software Foundation, Inc. -@@ -27,7 +29,7 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; - BEGIN { -- @Aclocal::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@') -+ @Aclocal::perl_libdirs = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@') - unless @Aclocal::perl_libdirs; - unshift @INC, @Aclocal::perl_libdirs; +- unshift (@INC, '@datadir@/@PACKAGE@-@APIVERSION@') ++ unshift (@INC, ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@')) + unless $ENV{AUTOMAKE_UNINSTALLED}; } -@@ -69,8 +71,8 @@ $perl_threads = 0; + +@@ -65,8 +67,8 @@ $perl_threads = 0; # ACLOCAL_PATH environment variable, and reset with the '--system-acdir' # option. my @user_includes = (); --my @automake_includes = ("@datadir@/aclocal-$APIVERSION"); +-my @automake_includes = ('@datadir@/aclocal-' . $APIVERSION); -my @system_includes = ('@datadir@/aclocal'); +my @automake_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . "/share/aclocal-$APIVERSION" : "@datadir@/aclocal-$APIVERSION"); +my @system_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/aclocal' : '@datadir@/aclocal'); @@ -47,50 +37,16 @@ my $install = 0; --- a/bin/automake.in +++ b/bin/automake.in -@@ -1,10 +1,12 @@ --#!@PERL@ -w -+#!@PERL@ - # -*- perl -*- - # @configure_input@ - - eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; +@@ -26,9 +26,11 @@ use 5.006; + use strict; + use warnings FATAL => 'all'; +$^W = 1; + - # automake - create Makefile.in from Makefile.am - # Copyright (C) 1994-2017 Free Software Foundation, Inc. - -@@ -31,7 +33,7 @@ use strict; - BEGIN { -- @Automake::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@') -+ @Automake::perl_libdirs = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@') - unless @Automake::perl_libdirs; - unshift @INC, @Automake::perl_libdirs; +- unshift (@INC, '@datadir@/@PACKAGE@-@APIVERSION@') ++ unshift (@INC, ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@')) + unless $ENV{AUTOMAKE_UNINSTALLED}; ---- a/t/wrap/aclocal.in -+++ b/t/wrap/aclocal.in -@@ -1,6 +1,8 @@ --#!@PERL@ -w -+#!@PERL@ - # @configure_input@ - -+$^W = 1; -+ - # Copyright (C) 2012-2017 Free Software Foundation, Inc. - - # This program is free software; you can redistribute it and/or modify ---- a/t/wrap/automake.in -+++ b/t/wrap/automake.in -@@ -1,6 +1,8 @@ --#!@PERL@ -w -+#!@PERL@ - # @configure_input@ - -+$^W = 1; -+ - # Copyright (C) 2012-2017 Free Software Foundation, Inc. - - # This program is free software; you can redistribute it and/or modify + # Override SHELL. This is required on DJGPP so that system() uses diff --git a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch index ad019ddd1..a0d04e21e 100644 --- a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch +++ b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch @@ -1,6 +1,6 @@ --- a/bin/aclocal.in +++ b/bin/aclocal.in -@@ -356,6 +356,12 @@ sub scan_m4_dirs ($$@) +@@ -371,6 +371,12 @@ sub scan_m4_dirs ($$@) foreach my $m4dir (@dirlist) { diff --git a/tools/automake/patches/101-do-not-require-files.patch b/tools/automake/patches/101-do-not-require-files.patch new file mode 100644 index 000000000..3a8c9fcb4 --- /dev/null +++ b/tools/automake/patches/101-do-not-require-files.patch @@ -0,0 +1,29 @@ +--- a/bin/automake.in ++++ b/bin/automake.in +@@ -4513,7 +4513,7 @@ sub handle_gettext () + && grep ($_ eq 'intl', @subdirs)); + } + +- require_file ($ac_gettext_location, GNU, 'ABOUT-NLS'); ++ require_file ($ac_gettext_location, GNITS, 'ABOUT-NLS'); + } + + # Emit makefile footer. +@@ -5641,7 +5641,7 @@ sub check_gnu_standards () + # otherwise require non-.md. + my $required + = (! -f $file && -f "$file.md") ? "$file.md" : $file; +- require_file ("$am_file.am", GNU, $required); ++ require_file ("$am_file.am", GNITS, $required); + } + + # Accept one of these three licenses; default to COPYING. +@@ -5655,7 +5655,7 @@ sub check_gnu_standards () + last; + } + } +- require_file ("$am_file.am", GNU, 'COPYING') ++ require_file ("$am_file.am", GNITS, 'COPYING') + unless $license; + } + diff --git a/tools/automake/patches/200-other-V-values-for-verbosity.patch b/tools/automake/patches/200-other-V-values-for-verbosity.patch new file mode 100644 index 000000000..1ea9d38b0 --- /dev/null +++ b/tools/automake/patches/200-other-V-values-for-verbosity.patch @@ -0,0 +1,59 @@ +From: Bogdan Drozdowski +Date: Sat, 31 Dec 2022 20:17:35 +0100 +Subject: [PATCH] Allow other V values for verbosity + +--- + m4/silent.m4 | 2 +- + t/silent-gen.sh | 24 ++++++++++++++++++++++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +--- a/m4/silent.m4 ++++ b/m4/silent.m4 +@@ -43,7 +43,7 @@ else + fi]) + if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. +- AM_V='$(V)' ++ AM_V='$(shell if ( test "x$(V)" = "x0" ); then echo 0; elif ( test "x$(V)" = "x" ); then echo $(AM_DEFAULT_VERBOSITY); else echo 1; fi)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' + else + AM_V=$AM_DEFAULT_VERBOSITY +--- a/t/silent-gen.sh ++++ b/t/silent-gen.sh +@@ -54,6 +54,18 @@ grep 'cp ' stdout + grep 'echo ' stdout + + $MAKE clean ++run_make -O V=99 ++grep 'GEN ' stdout && exit 1 ++grep 'cp ' stdout ++grep 'echo ' stdout ++ ++$MAKE clean ++run_make -O V=vvv ++grep 'GEN ' stdout && exit 1 ++grep 'cp ' stdout ++grep 'echo ' stdout ++ ++$MAKE clean + run_make -O V=0 + grep 'GEN .*foo' stdout + grep 'cp ' stdout && exit 1 +@@ -78,5 +90,17 @@ run_make -O V=1 + grep 'GEN ' stdout && exit 1 + grep 'cp ' stdout + grep 'echo ' stdout ++ ++$MAKE clean ++run_make -O V=99 ++grep 'GEN ' stdout && exit 1 ++grep 'cp ' stdout ++grep 'echo ' stdout ++ ++$MAKE clean ++run_make -O V=v ++grep 'GEN ' stdout && exit 1 ++grep 'cp ' stdout ++grep 'echo ' stdout + + : diff --git a/tools/b43-tools/Makefile b/tools/b43-tools/Makefile index bae498c78..19918efde 100644 --- a/tools/b43-tools/Makefile +++ b/tools/b43-tools/Makefile @@ -23,7 +23,7 @@ define Host/Compile $(HOST_MAKE_FLAGS) \ $(1) QUIET_SPARSE=: +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/assembler \ - CFLAGS="$(HOST_CFLAGS) -include endian.h" \ + CFLAGS="$(HOST_CFLAGS) -include endian.h -Wno-error=int-conversion" \ $(HOST_MAKE_FLAGS) \ LDFLAGS= \ $(1) QUIET_SPARSE=: diff --git a/tools/coreutils/Makefile b/tools/coreutils/Makefile index c64210c5a..f799e83c5 100644 --- a/tools/coreutils/Makefile +++ b/tools/coreutils/Makefile @@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=coreutils PKG_CPE_ID:=cpe:/a:gnu:coreutils -PKG_VERSION:=8.32 +PKG_VERSION:=9.3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/coreutils -PKG_HASH:=4458d8de7849df44ccab15e16b1548b285224dbba5f08fac070c1c0e0bcc4cfa +PKG_HASH:=adbcfcfe899235b71e8768dcf07cd532520b7f54f9a8064843f8d199a904bbaa HOST_BUILD_PARALLEL := 1 diff --git a/tools/cpio/Makefile b/tools/cpio/Makefile index 82b5aa836..bd6e25898 100644 --- a/tools/cpio/Makefile +++ b/tools/cpio/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=cpio PKG_CPE_ID:=cpe:/a:gnu:cpio -PKG_VERSION:=2.13 +PKG_VERSION:=2.15 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=@GNU/cpio -PKG_HASH:=eab5bdc5ae1df285c59f2a4f140a98fc33678a0bf61bdba67d9436ae26b46f6d +PKG_HASH:=937610b97c329a1ec9268553fb780037bcfff0dcffe9725ebc4fd9c1aa9075db include $(INCLUDE_DIR)/host-build.mk diff --git a/tools/cpio/patches/001-duplicate-program-name.patch b/tools/cpio/patches/001-duplicate-program-name.patch deleted file mode 100644 index a7c3fbc8a..000000000 --- a/tools/cpio/patches/001-duplicate-program-name.patch +++ /dev/null @@ -1,18 +0,0 @@ -author Sergey Poznyakoff - -https://git.savannah.gnu.org/cgit/cpio.git/commit/?id=641d3f489cf6238bb916368d4ba0d9325a235afb - -* src/global.c: Remove superfluous declaration of program_name - ---- a/src/global.c -+++ b/src/global.c -@@ -184,9 +184,6 @@ unsigned int warn_option = 0; - /* Extract to standard output? */ - bool to_stdout_option = false; - --/* The name this program was run with. */ --char *program_name; -- - /* A pointer to either lstat or stat, depending on whether - dereferencing of symlinks is done for input files. */ - int (*xstat) (); diff --git a/tools/cpio/patches/010-clang.patch b/tools/cpio/patches/010-clang.patch deleted file mode 100644 index 89c7a8149..000000000 --- a/tools/cpio/patches/010-clang.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/gnu/xalloc-oversized.h -+++ b/gnu/xalloc-oversized.h -@@ -52,7 +52,7 @@ typedef size_t __xalloc_count_type; - #elif ((5 <= __GNUC__ \ - || (__has_builtin (__builtin_mul_overflow) \ - && __has_builtin (__builtin_constant_p))) \ -- && !__STRICT_ANSI__) -+ && !__STRICT_ANSI__) && !defined(__clang__) - # define xalloc_oversized(n, s) \ - (__builtin_constant_p (n) && __builtin_constant_p (s) \ - ? __xalloc_oversized (n, s) \ diff --git a/tools/xz/Makefile b/tools/xz/Makefile index a90cec86b..9084cb08f 100644 --- a/tools/xz/Makefile +++ b/tools/xz/Makefile @@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=xz -PKG_VERSION:=5.4.6 +PKG_VERSION:=5.4.1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=@SF/lzmautils \ http://tukaani.org/xz -PKG_HASH:=913851b274e8e1d31781ec949f1c23e8dbcf0ecf6e73a2436dc21769dd3e6f49 +PKG_HASH:=dd172acb53867a68012f94c17389401b2f274a1aa5ae8f84cbfb8b7e383ea8d3 PKG_CPE_ID:=cpe:/a:tukaani:xz HOST_BUILD_PARALLEL:=1

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 y1@XYZfd2h@WcSMM6}UQY;bZ>6RDuA8i`b+ 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 D=&jCpwqxhMk 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